1 /******************************************************************************
3 * Copyright (C) 1997-2015 by Dimitri van Heesch.
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
21 #include "memberdef.h"
22 #include "membername.h"
29 #include "outputlist.h"
31 #include "membergroup.h"
34 #include "docparser.h"
36 #include "searchindex.h"
37 #include "parserintf.h"
41 #include "vhdldocgen.h"
42 #include "arguments.h"
43 #include "memberlist.h"
44 #include "namespacedef.h"
48 //-----------------------------------------------------------------------------
50 int MemberDef::s_indentLevel = 0;
52 //-----------------------------------------------------------------------------
54 static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
57 QCString clRealName=n;
59 if ((i=clRealName.find('<'))!=-1)
61 clRealName=clRealName.left(i); // strip template specialization
63 if ((i=clRealName.findRev("::"))!=-1)
65 clRealName=clRealName.right(clRealName.length()-i-2);
67 while ((i=s.find(clRealName,p))!=-1)
70 uint j=clRealName.length()+i;
71 if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
72 { // add template names
73 //printf("Adding %s+%s\n",clRealName.data(),t.data());
77 { // template names already present
78 //printf("Adding %s\n",clRealName.data());
81 p=i+clRealName.length();
83 result+=s.right(s.length()-p);
84 //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
88 // ol.startMemberDocName has already been done before this is called.
89 // when this function returns TRUE, ol.endParameterList will be called.
93 // ol.startMemberDocName
94 // --- enter writeDefArgumentList
95 // ol.endMemberDocName
96 // ol.startParameterList
98 // ol.startParameterType(first=TRUE)
99 // ol.endParameterType
100 // ol.startParameterName
101 // ol.endParameterName(last==FALSE)
103 // ol.startParameterType(first=FALSE)
104 // ol.endParamtereType
105 // ol.startParameterName
106 // ol.endParameterName(last==TRUE)
108 // --- leave writeDefArgumentList with return value TRUE
109 // ol.endParameterList
110 // ol.endMemberDoc(hasArgs=TRUE)
112 // For an empty list the function should return FALSE, the sequence is
114 // ol.startMemberDocName
115 // --- enter writeDefArgumentList
116 // --- leave writeDefArgumentList with return value FALSE
117 // ol.endMemberDocName
118 // ol.endMemberDoc(hasArgs=FALSE);
121 static bool writeDefArgumentList(OutputList &ol,Definition *scope,MemberDef *md)
123 ArgumentList *defArgList=(md->isDocsForDefinition()) ?
124 md->argumentList() : md->declArgumentList();
125 //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
126 if (defArgList==0 || md->isProperty())
128 return FALSE; // member has no function like argument list
131 // simple argument list for tcl
132 if (md->getLanguage()==SrcLangExt_Tcl)
134 if (defArgList->count()==0) return FALSE;
135 ArgumentListIterator ali(*defArgList);
137 ol.endMemberDocName();
138 ol.startParameterList(FALSE);
139 ol.startParameterType(TRUE,0);
140 ol.endParameterType();
141 ol.startParameterName(FALSE);
142 for (;(a=ali.current());++ali)
144 if (a->defval.isEmpty())
146 ol.docify(a->name+" ");
150 ol.docify("?"+a->name+"? ");
153 ol.endParameterName(TRUE,FALSE,FALSE);
157 if (!md->isDefine()) ol.docify(" ");
159 //printf("writeDefArgList(%d)\n",defArgList->count());
160 ol.pushGeneratorState();
161 //ol.disableAllBut(OutputGenerator::Html);
162 bool htmlOn = ol.isEnabled(OutputGenerator::Html);
163 bool latexOn = ol.isEnabled(OutputGenerator::Latex);
166 if (htmlOn) ol.enable(OutputGenerator::Html);
167 if (latexOn) ol.enable(OutputGenerator::Latex);
169 ol.endMemberDocName();
170 ol.startParameterList(!md->isObjCMethod());
173 ol.disable(OutputGenerator::Html);
174 ol.disable(OutputGenerator::Latex);
177 if (!md->isObjCMethod()) ol.docify("("); // start argument list
178 ol.endMemberDocName();
180 ol.popGeneratorState();
181 //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
187 int il=cName.find('<');
188 int ir=cName.findRev('>');
189 if (il!=-1 && ir!=-1 && ir>il)
191 cName=cName.mid(il,ir-il+1);
192 //printf("1. cName=%s\n",cName.data());
194 else if (scope->definitionType()==Definition::TypeClass && ((ClassDef*)scope)->templateArguments())
196 cName=tempArgListToString(((ClassDef*)scope)->templateArguments(),scope->getLanguage());
197 //printf("2. cName=%s\n",cName.data());
199 else // no template specifier
204 //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
207 bool paramTypeStarted=FALSE;
208 bool isDefine = md->isDefine();
209 ArgumentListIterator ali(*defArgList);
210 Argument *a=ali.current();
213 if (isDefine || first)
215 ol.startParameterType(first,0);
216 paramTypeStarted=TRUE;
219 ol.endParameterType();
220 ol.startParameterName(TRUE);
223 QRegExp re(")("),res("(.*\\*");
224 int vp=a->type.find(re);
225 int wp=a->type.find(res);
227 // use the following to put the function pointer type before the name
228 bool hasFuncPtrType=FALSE;
230 if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
232 ol.docify(a->attrib+" ");
234 if (hasFuncPtrType) // argument type is a function pointer
236 //printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data());
237 QCString n=a->type.left(vp);
238 if (hasFuncPtrType) n=a->type.left(wp);
239 if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
240 if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
241 linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n);
243 else // non-function pointer type
246 if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
249 if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
250 linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n);
255 if (paramTypeStarted)
257 ol.endParameterType();
258 paramTypeStarted=FALSE;
260 ol.startParameterName(defArgList->count()<2);
264 ol.docify(a->type.mid(wp,vp-wp));
266 if (!a->name.isEmpty() || a->type=="...") // argument has a name
268 //if (!hasFuncPtrType)
272 ol.disable(OutputGenerator::Latex);
273 ol.disable(OutputGenerator::Html);
274 ol.docify(" "); /* man page */
275 if (htmlOn) ol.enable(OutputGenerator::Html);
276 ol.disable(OutputGenerator::Man);
278 ol.enable(OutputGenerator::Man);
279 if (latexOn) ol.enable(OutputGenerator::Latex);
280 if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name);
281 ol.disable(OutputGenerator::Man);
282 ol.disable(OutputGenerator::Latex);
284 ol.enable(OutputGenerator::Man);
285 if (latexOn) ol.enable(OutputGenerator::Latex);
287 if (!a->array.isEmpty())
291 if (hasFuncPtrType) // write the part of the argument type
292 // that comes after the name
294 linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),
295 md,a->type.right(a->type.length()-vp));
297 if (!a->defval.isEmpty()) // write the default value
299 QCString n=a->defval;
300 if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
303 ol.startTypewriter();
304 linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n,FALSE,TRUE,TRUE);
312 if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
316 if (md->isObjCMethod() && a->attrib.length()>=2)
318 //printf("Found parameter keyword %s\n",a->attrib.data());
320 key=a->attrib.mid(1,a->attrib.length()-2);
321 if (key!=",") key+=":"; // for normal keywords add colon
323 ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
324 if (paramTypeStarted)
326 ol.endParameterType();
328 ol.startParameterType(FALSE,key);
329 paramTypeStarted=TRUE;
333 ol.endParameterName(FALSE,FALSE,TRUE);
338 ol.pushGeneratorState();
339 ol.disable(OutputGenerator::Html);
340 ol.disable(OutputGenerator::Latex);
341 if (!md->isObjCMethod()) ol.docify(")"); // end argument list
343 if (htmlOn) ol.enable(OutputGenerator::Html);
344 if (latexOn) ol.enable(OutputGenerator::Latex);
345 if (first) ol.startParameterName(defArgList->count()<2);
346 ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
347 ol.popGeneratorState();
348 if (md->extraTypeChars())
350 ol.docify(md->extraTypeChars());
352 if (defArgList->constSpecifier)
356 if (defArgList->volatileSpecifier)
358 ol.docify(" volatile");
360 if (defArgList->refQualifier==RefQualifierLValue)
364 else if (defArgList->refQualifier==RefQualifierRValue)
368 if (!defArgList->trailingReturnType.isEmpty())
370 linkifyText(TextGeneratorOLImpl(ol), // out
372 md->getBodyDef(), // fileScope
374 defArgList->trailingReturnType, // text
382 static void writeExceptionListImpl(
383 OutputList &ol, ClassDef *cd, MemberDef *md, QCString const& exception)
385 // this is ordinary exception spec - there must be a '('
386 //printf("exception='%s'\n",exception.data());
387 int index = exception.find('(');
390 ol.exceptionEntry(exception.left(index),false);
391 ++index; // paren in second column so skip it here
392 for (int comma = exception.find(',', index); comma!=-1; )
394 ++comma; // include comma
395 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,
396 exception.mid(index,comma-index));
397 ol.exceptionEntry(0,false);
399 comma = exception.find(',', index);
401 int close = exception.find(')', index);
404 QCString type=removeRedundantWhiteSpace(exception.mid(index,close-index));
405 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,type);
406 ol.exceptionEntry(0,true);
410 warn(md->getDefFileName(),md->getDefLine(),
411 "missing ) in exception list on member %s",qPrint(md->name()));
414 else // Java Exception
417 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,exception);
421 static void writeExceptionList(OutputList &ol, ClassDef *cd, MemberDef *md)
423 QCString exception(QCString(md->excpString()).stripWhiteSpace());
424 if ('{'==exception.at(0))
426 // this is an UNO IDL attribute - need special handling
427 int index = exception.find(';');
429 while (-1 != index) // there should be no more than 2 (set / get)
431 // omit '{' and ';' -> "set raises (...)"
432 writeExceptionListImpl(ol,cd,md,exception.mid(oldIndex,index-oldIndex));
434 index = exception.find(';',oldIndex);
436 // the rest is now just '}' - omit that
440 writeExceptionListImpl(ol,cd,md,exception);
444 static void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
446 ol.docify("template<");
447 ArgumentListIterator ali(*al);
448 Argument *a = ali.current();
454 if (a->defval.length()!=0)
457 ol.docify(a->defval);
461 if (a) ol.docify(", ");
466 //-----------------------------------------------------------------------------
467 //-----------------------------------------------------------------------------
468 //-----------------------------------------------------------------------------
475 void init(Definition *def,const char *t,const char *a,const char *e,
476 Protection p,Specifier v,bool s,Relationship r,
477 MemberType mt,const ArgumentList *tal,
478 const ArgumentList *al
481 ClassDef *classDef; // member of or related to
482 FileDef *fileDef; // member of file definition
483 NamespaceDef *nspace; // the namespace this member is in.
485 MemberDef *enumScope; // the enclosing scope, if this is an enum field
486 bool livesInsideEnum;
487 MemberDef *annEnumType; // the anonymous enum that is the type of this member
488 MemberList *enumFields; // enumeration fields
490 MemberDef *redefines; // the members that this member redefines
491 MemberList *redefinedBy; // the list of members that redefine this one
493 MemberDef *memDef; // member definition for this declaration
494 MemberDef *memDec; // member declaration for this definition
495 ClassDef *relatedAlso; // points to class marked by relatedAlso
497 ExampleSDict *exampleSDict; // a dictionary of all examples for quick access
499 QCString type; // return actual type
500 QCString accessorType; // return type that tell how to get to this member
501 ClassDef *accessorClass; // class that this member accesses (for anonymous types)
502 QCString args; // function arguments/variable array specifiers
503 QCString def; // member definition in code (fully qualified name)
504 QCString anc; // HTML anchor name
505 Specifier virt; // normal/virtual/pure virtual
506 Protection prot; // protection type [Public/Protected/Private]
507 QCString decl; // member declaration in class
509 QCString bitfields; // struct member bitfields
510 QCString read; // property read accessor
511 QCString write; // property write accessor
512 QCString exception; // exceptions that can be thrown
513 QCString initializer; // initializer
514 QCString extraTypeChars; // extra type info found after the argument list
515 QCString enumBaseType; // base type of the enum (C++11)
516 int initLines; // number of lines in the initializer
518 uint64 memSpec; // The specifiers present for this member
519 MemberType mtype; // returns the kind of member
520 int maxInitLines; // when the initializer will be displayed
521 int userInitLines; // result of explicit \hideinitializer or \showinitializer
524 ArgumentList *defArgList; // argument list of this member definition
525 ArgumentList *declArgList; // argument list of this member declaration
527 ArgumentList *tArgList; // template argument list of function template
528 ArgumentList *typeConstraints; // type constraints for template parameters
529 MemberDef *templateMaster;
530 QList<ArgumentList> *defTmpArgLists; // lists of template argument lists
531 // (for template functions in nested template classes)
533 ClassDef *cachedAnonymousType; // if the member has an anonymous compound
534 // as its type then this is computed by
535 // getClassDefOfAnonymousType() and
537 SDict<MemberList> *classSectionSDict; // not accessible
539 MemberDef *groupAlias; // Member containing the definition
540 int grpId; // group id
541 MemberGroup *memberGroup; // group's member definition
542 GroupDef *group; // group in which this member is in
543 Grouping::GroupPri_t grouppri; // priority of this definition
544 QCString groupFileName; // file where this grouping was defined
545 int groupStartLine; // line " " " " "
546 MemberDef *groupMember;
548 bool isTypedefValCached;
549 ClassDef *cachedTypedefValue;
550 QCString cachedTypedefTemplSpec;
551 QCString cachedResolvedType;
553 // inbody documentation
555 //QCString inbodyFile;
556 //QCString inbodyDocs;
558 // documentation inheritance
559 MemberDef *docProvider;
561 // to store the output file base from tag files
562 QCString explicitOutputFileBase;
565 bool implOnly; // function found in implementation but not
567 bool hasDocumentedParams;
568 bool hasDocumentedReturnType;
570 Relationship related; // relationship of this to the class
571 bool stat; // is it a static function?
572 bool proto; // is it a prototype;
573 bool docEnumValues; // is an enum with documented enum values.
574 bool annScope; // member is part of an annoymous scope
578 bool explExt; // member was explicitly declared external
579 bool tspec; // member is a template specialization
580 bool groupHasDocs; // true if the entry that caused the grouping was documented
581 bool docsForDefinition; // TRUE => documentation block is put before
583 // FALSE => block is put before declaration.
585 MemberDef *categoryRelation;
588 MemberDefImpl::MemberDefImpl() :
597 classSectionSDict(0),
603 MemberDefImpl::~MemberDefImpl()
610 delete typeConstraints;
611 delete defTmpArgLists;
612 delete classSectionSDict;
616 void MemberDefImpl::init(Definition *def,
617 const char *t,const char *a,const char *e,
618 Protection p,Specifier v,bool s,Relationship r,
619 MemberType mt,const ArgumentList *tal,
620 const ArgumentList *al
637 livesInsideEnum=FALSE;
639 hasCallGraph = FALSE;
640 hasCallerGraph = FALSE;
643 if (mt==MemberType_Typedef) type.stripPrefix("typedef ");
644 // type.stripPrefix("struct ");
645 // type.stripPrefix("class " );
646 // type.stripPrefix("union " );
647 type=removeRedundantWhiteSpace(type);
649 args=removeRedundantWhiteSpace(args);
650 if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args;
668 cachedAnonymousType=0;
669 maxInitLines=Config_getInt(MAX_INITIALIZER_LINES);
672 // copy function template arguments (if any)
675 tArgList = tal->deepCopy();
681 //printf("new member al=%p\n",al);
682 // copy function definition arguments (if any)
685 defArgList = al->deepCopy();
691 // convert function declaration arguments (if any)
694 declArgList = new ArgumentList;
695 stringToArgumentList(args,declArgList,&extraTypeChars);
696 //printf("setDeclArgList %s to %s const=%d\n",args.data(),
697 // argListToString(declArgList).data(),declArgList->constSpecifier);
704 classSectionSDict = 0;
705 docsForDefinition = TRUE;
706 isTypedefValCached = FALSE;
707 cachedTypedefValue = 0;
711 hasDocumentedParams = FALSE;
712 hasDocumentedReturnType = FALSE;
714 isDMember = def->getDefFileName().right(2).lower()==".d";
718 //-----------------------------------------------------------------------------
719 //-----------------------------------------------------------------------------
720 //-----------------------------------------------------------------------------
722 /*! Creates a new member definition.
724 * \param df File containing the definition of this member.
725 * \param dl Line at which the member definition was found.
726 * \param dc Column at which the member definition was found.
727 * \param t A string representing the type of the member.
728 * \param na A string representing the name of the member.
729 * \param a A string representing the arguments of the member.
730 * \param e A string representing the throw clause of the members.
731 * \param p The protection context of the member, possible values are:
732 * \c Public, \c Protected, \c Private.
733 * \param v The degree of `virtualness' of the member, possible values are:
734 * \c Normal, \c Virtual, \c Pure.
735 * \param s A boolean that is true iff the member is static.
736 * \param r The relationship between the class and the member.
737 * \param mt The kind of member. See #MemberType for a list of
739 * \param tal The template arguments of this member.
740 * \param al The arguments of this member. This is a structured form of
741 * the string past as argument \a a.
744 MemberDef::MemberDef(const char *df,int dl,int dc,
745 const char *t,const char *na,const char *a,const char *e,
746 Protection p,Specifier v,bool s,Relationship r,MemberType mt,
747 const ArgumentList *tal,const ArgumentList *al
748 ) : Definition(df,dl,dc,removeRedundantWhiteSpace(na)), visited(FALSE)
750 //printf("MemberDef::MemberDef(%s)\n",na);
751 m_impl = new MemberDefImpl;
752 m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al);
753 number_of_flowkw = 1;
754 m_isLinkableCached = 0;
755 m_isConstructorCached = 0;
756 m_isDestructorCached = 0;
759 MemberDef::MemberDef(const MemberDef &md) : Definition(md), visited(FALSE)
761 m_impl = new MemberDefImpl;
762 m_isLinkableCached = 0;
763 m_isConstructorCached = 0;
764 m_isDestructorCached = 0;
767 MemberDef *MemberDef::deepCopy() const
769 //MemberDef *result = new MemberDef(getDefFileName(),getDefLine(),name());
770 MemberDef *result = new MemberDef(*this);
771 // first copy everything by reference
772 *result->m_impl = *m_impl;
773 // clear pointers owned by object
774 result->m_impl->redefinedBy= 0;
775 result->m_impl->exampleSDict=0;
776 result->m_impl->enumFields=0;
777 result->m_impl->defArgList=0;
778 result->m_impl->tArgList=0;
779 result->m_impl->typeConstraints=0;
780 result->m_impl->defTmpArgLists=0;
781 result->m_impl->classSectionSDict=0;
782 result->m_impl->declArgList=0;
783 // replace pointers owned by the object by deep copies
784 if (m_impl->redefinedBy)
786 MemberListIterator mli(*m_impl->redefinedBy);
788 for (mli.toFirst();(md=mli.current());++mli)
790 result->insertReimplementedBy(md);
793 if (m_impl->exampleSDict)
795 ExampleSDict::Iterator it(*m_impl->exampleSDict);
797 for (it.toFirst();(e=it.current());++it)
799 result->addExample(e->anchor,e->name,e->file);
802 if (m_impl->enumFields)
804 MemberListIterator mli(*m_impl->enumFields);
806 for (mli.toFirst();(md=mli.current());++mli)
808 result->insertEnumField(md);
811 if (m_impl->defArgList)
813 result->m_impl->defArgList = m_impl->defArgList->deepCopy();
815 if (m_impl->tArgList)
817 result->m_impl->tArgList = m_impl->tArgList->deepCopy();
819 if (m_impl->typeConstraints)
821 result->m_impl->typeConstraints = m_impl->typeConstraints->deepCopy();
823 result->setDefinitionTemplateParameterLists(m_impl->defTmpArgLists);
824 if (m_impl->classSectionSDict)
826 result->m_impl->classSectionSDict = new SDict<MemberList>(7);
827 SDict<MemberList>::IteratorDict it(*m_impl->classSectionSDict);
829 for (it.toFirst();(ml=it.current());++it)
831 result->m_impl->classSectionSDict->append(it.currentKey(),ml);
834 if (m_impl->declArgList)
836 result->m_impl->declArgList = m_impl->declArgList->deepCopy();
841 void MemberDef::moveTo(Definition *scope)
843 setOuterScope(scope);
844 if (scope->definitionType()==Definition::TypeClass)
846 m_impl->classDef = (ClassDef*)scope;
848 else if (scope->definitionType()==Definition::TypeFile)
850 m_impl->fileDef = (FileDef*)scope;
852 else if (scope->definitionType()==Definition::TypeNamespace)
854 m_impl->nspace = (NamespaceDef*)scope;
856 m_isLinkableCached = 0;
857 m_isConstructorCached = 0;
861 /*! Destroys the member definition. */
862 MemberDef::~MemberDef()
865 //printf("%p: ~MemberDef()\n",this);
869 void MemberDef::setReimplements(MemberDef *md)
871 m_impl->redefines = md;
874 void MemberDef::insertReimplementedBy(MemberDef *md)
876 if (m_impl->templateMaster)
878 m_impl->templateMaster->insertReimplementedBy(md);
880 if (m_impl->redefinedBy==0) m_impl->redefinedBy = new MemberList(MemberListType_redefinedBy);
881 if (m_impl->redefinedBy->findRef(md)==-1)
883 m_impl->redefinedBy->inSort(md);
887 MemberDef *MemberDef::reimplements() const
889 return m_impl->redefines;
892 MemberList *MemberDef::reimplementedBy() const
894 return m_impl->redefinedBy;
897 bool MemberDef::isReimplementedBy(ClassDef *cd) const
899 if (cd && m_impl->redefinedBy)
901 MemberListIterator mi(*m_impl->redefinedBy);
903 for (mi.toFirst();(md=mi.current());++mi)
905 ClassDef *mcd = md->getClassDef();
908 if (cd==mcd || cd->isBaseClass(mcd,TRUE))
918 void MemberDef::insertEnumField(MemberDef *md)
920 if (m_impl->enumFields==0) m_impl->enumFields=new MemberList(MemberListType_enumFields);
921 m_impl->enumFields->append(md);
924 bool MemberDef::addExample(const char *anchor,const char *nameStr,
927 //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
928 if (m_impl->exampleSDict==0) m_impl->exampleSDict = new ExampleSDict;
929 if (m_impl->exampleSDict->find(nameStr)==0)
931 //printf("Add reference to example %s to member %s\n",nameStr,name.data());
932 Example *e=new Example;
936 m_impl->exampleSDict->inSort(nameStr,e);
942 bool MemberDef::hasExamples()
944 if (m_impl->exampleSDict==0)
947 return m_impl->exampleSDict->count()>0;
950 QCString MemberDef::getOutputFileBase() const
952 static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES);
953 static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS);
956 //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
957 // name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
958 // m_impl->nspace,m_impl->fileDef);
959 if (!m_impl->explicitOutputFileBase.isEmpty())
961 return m_impl->explicitOutputFileBase;
963 else if (m_impl->templateMaster)
965 return m_impl->templateMaster->getOutputFileBase();
967 else if (m_impl->group)
969 baseName=m_impl->group->getOutputFileBase();
971 else if (m_impl->classDef)
973 baseName=m_impl->classDef->getOutputFileBase();
974 if (inlineSimpleClasses && m_impl->classDef->isSimple())
979 else if (m_impl->nspace && m_impl->nspace->isLinkableInProject())
981 baseName=m_impl->nspace->getOutputFileBase();
983 else if (m_impl->fileDef)
985 baseName=m_impl->fileDef->getOutputFileBase();
988 if (baseName.isEmpty())
990 warn(getDefFileName(),getDefLine(),
991 "Internal inconsistency: member %s does not belong to any"
992 " container!",qPrint(name())
996 else if (separateMemberPages && isDetailedSectionLinkable())
998 if (getEnumScope()) // enum value, which is part of enum's documentation
1000 baseName+="_"+getEnumScope()->anchor();
1004 baseName+="_"+anchor();
1010 QCString MemberDef::getReference() const
1012 QCString ref = Definition::getReference();
1017 if (m_impl->templateMaster)
1019 return m_impl->templateMaster->getReference();
1021 else if (m_impl->group)
1023 return m_impl->group->getReference();
1025 else if (m_impl->classDef)
1027 return m_impl->classDef->getReference();
1029 else if (m_impl->nspace)
1031 return m_impl->nspace->getReference();
1033 else if (m_impl->fileDef)
1035 return m_impl->fileDef->getReference();
1040 QCString MemberDef::anchor() const
1042 QCString result=m_impl->anc;
1043 if (m_impl->groupAlias) return m_impl->groupAlias->anchor();
1044 if (m_impl->templateMaster) return m_impl->templateMaster->anchor();
1045 if (m_impl->enumScope && m_impl->enumScope!=this) // avoid recursion for C#'s public enum E { E, F }
1047 result.prepend(m_impl->enumScope->anchor());
1051 if (m_impl->groupMember)
1053 result=m_impl->groupMember->anchor();
1055 else if (getReference().isEmpty())
1057 result.prepend("g");
1063 void MemberDef::_computeLinkableInProject()
1065 static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1066 m_isLinkableCached = 2; // linkable
1067 //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
1070 //printf("is hidden\n");
1071 m_isLinkableCached = 1;
1074 if (m_impl->templateMaster)
1076 //printf("has template master\n");
1077 m_isLinkableCached = m_impl->templateMaster->isLinkableInProject() ? 2 : 1;
1080 if (name().isEmpty() || name().at(0)=='@')
1082 //printf("name invalid\n");
1083 m_isLinkableCached = 1; // not a valid or a dummy name
1086 if (!hasDocumentation() || isReference())
1088 //printf("no docs or reference\n");
1089 m_isLinkableCached = 1; // no documentation
1092 if (m_impl->group && !m_impl->group->isLinkableInProject())
1094 //printf("group but group not linkable!\n");
1095 m_isLinkableCached = 1; // group but group not linkable
1098 if (!m_impl->group && m_impl->classDef && !m_impl->classDef->isLinkableInProject())
1100 //printf("in a class but class not linkable!\n");
1101 m_isLinkableCached = 1; // in class but class not linkable
1104 if (!m_impl->group && m_impl->nspace && !m_impl->related && !m_impl->nspace->isLinkableInProject()
1105 && (m_impl->fileDef==0 || !m_impl->fileDef->isLinkableInProject()))
1107 //printf("in a namespace but namespace not linkable!\n");
1108 m_isLinkableCached = 1; // in namespace but namespace not linkable
1111 if (!m_impl->group && !m_impl->nspace &&
1112 !m_impl->related && !m_impl->classDef &&
1113 m_impl->fileDef && !m_impl->fileDef->isLinkableInProject())
1115 //printf("in a file but file not linkable!\n");
1116 m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable
1119 if (!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=MemberType_Friend)
1121 //printf("private and invisible!\n");
1122 m_isLinkableCached = 1; // hidden due to protection
1125 if (m_impl->stat && m_impl->classDef==0 && !extractStatic)
1127 //printf("static and invisible!\n");
1128 m_isLinkableCached = 1; // hidden due to staticness
1131 //printf("linkable!\n");
1132 return; // linkable!
1135 void MemberDef::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
1137 Definition::setDocumentation(d,docFile,docLine,stripWhiteSpace);
1138 m_isLinkableCached = 0;
1141 void MemberDef::setBriefDescription(const char *b,const char *briefFile,int briefLine)
1143 Definition::setBriefDescription(b,briefFile,briefLine);
1144 m_isLinkableCached = 0;
1147 void MemberDef::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine)
1149 Definition::setInbodyDocumentation(d,inbodyFile,inbodyLine);
1150 m_isLinkableCached = 0;
1153 void MemberDef::setHidden(bool b)
1155 Definition::setHidden(b);
1156 m_isLinkableCached = 0;
1159 bool MemberDef::isLinkableInProject() const
1161 if (m_isLinkableCached==0)
1163 MemberDef *that = (MemberDef*)this;
1164 that->_computeLinkableInProject();
1166 ASSERT(m_isLinkableCached>0);
1167 return m_isLinkableCached==2;
1170 bool MemberDef::isLinkable() const
1172 if (m_impl->templateMaster)
1174 return m_impl->templateMaster->isLinkable();
1178 return isLinkableInProject() || isReference();
1183 void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists)
1187 if (m_impl->defTmpArgLists) delete m_impl->defTmpArgLists;
1188 m_impl->defTmpArgLists = copyArgumentLists(lists);
1192 void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *,
1193 FileDef *fd,GroupDef *gd,bool onlyText)
1195 SrcLangExt lang = getLanguage();
1196 static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
1197 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
1198 QCString n = name();
1199 if (!hideScopeNames)
1201 if (m_impl->enumScope && m_impl->livesInsideEnum)
1203 n.prepend(m_impl->enumScope->displayName()+sep);
1205 if (m_impl->classDef && gd && !isRelated())
1207 n.prepend(m_impl->classDef->displayName()+sep);
1209 else if (m_impl->nspace && (gd || fd))
1211 n.prepend(m_impl->nspace->displayName()+sep);
1217 if (isStatic()) ol.docify("+ "); else ol.docify("- ");
1219 if (!onlyText && isLinkable()) // write link
1221 if (m_impl->mtype==MemberType_EnumValue && getGroupDef()==0 && // enum value is not grouped
1222 getEnumScope() && getEnumScope()->getGroupDef()) // but its container is
1224 GroupDef *enumValGroup = getEnumScope()->getGroupDef();
1225 ol.writeObjectLink(enumValGroup->getReference(),
1226 enumValGroup->getOutputFileBase(),
1231 ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),n);
1234 else // write only text
1242 /*! If this member has an anonymous class/struct/union as its type, then
1243 * this method will return the ClassDef that describes this return type.
1245 ClassDef *MemberDef::getClassDefOfAnonymousType()
1247 if (m_impl->cachedAnonymousType) return m_impl->cachedAnonymousType;
1250 if (getClassDef()!=0)
1252 cname=getClassDef()->name().copy();
1254 else if (getNamespaceDef()!=0)
1256 cname=getNamespaceDef()->name().copy();
1258 QCString ltype(m_impl->type);
1259 // strip `static' keyword from ltype
1260 //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
1261 // strip `friend' keyword from ltype
1262 ltype.stripPrefix("friend ");
1263 static QRegExp r("@[0-9]+");
1264 int l,i=r.match(ltype,0,&l);
1265 //printf("ltype=`%s' i=%d\n",ltype.data(),i);
1266 // search for the last anonymous scope in the member type
1267 ClassDef *annoClassDef=0;
1268 if (i!=-1) // found anonymous scope in type
1271 // extract anonymous scope
1272 while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
1273 if (il>0) il++; else if (il<0) il=0;
1274 while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;
1276 QCString annName = ltype.mid(il,ir-il);
1278 // if inside a class or namespace try to prepend the scope name
1279 if (!cname.isEmpty() && annName.left(cname.length()+2)!=cname+"::")
1281 QCString ts=stripAnonymousNamespaceScope(cname+"::"+annName);
1282 annoClassDef=getClass(ts);
1284 // if not found yet, try without scope name
1285 if (annoClassDef==0)
1287 QCString ts=stripAnonymousNamespaceScope(annName);
1288 annoClassDef=getClass(ts);
1291 m_impl->cachedAnonymousType = annoClassDef;
1292 return annoClassDef;
1295 /*! This methods returns TRUE iff the brief section (also known as
1296 * declaration section) is visible in the documentation.
1298 bool MemberDef::isBriefSectionVisible() const
1300 static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1301 static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
1302 static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
1303 static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1304 static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
1306 //printf("Member %s grpId=%d docs=%s file=%s args=%s\n",
1308 // 0,"", //grpId,grpId==-1?"<none>":Doxygen::memberDocDict[grpId]->data(),
1309 // "", //getFileDef()->name().data(),
1312 MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId];
1313 //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
1314 //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
1315 bool hasDocs = hasDocumentation() ||
1316 // part of a documented member group
1317 (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
1319 // only include static members with file/namespace scope if
1320 // explicitly enabled in the config file
1321 bool visibleIfStatic = !(getClassDef()==0 &&
1326 // only include members is the are documented or
1327 // HIDE_UNDOC_MEMBERS is NO in the config file
1328 bool visibleIfDocumented = (!hideUndocMembers ||
1330 isDocumentedFriendClass()
1333 // hide members with no detailed description and brief descriptions
1334 // explicitly disabled.
1335 bool visibleIfEnabled = !(hideUndocMembers &&
1336 documentation().isEmpty() &&
1341 // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true
1342 bool visibleIfFriendCompound = !(hideFriendCompounds &&
1344 (m_impl->type=="friend class" ||
1345 m_impl->type=="friend struct" ||
1346 m_impl->type=="friend union"
1350 // only include members that are non-private unless EXTRACT_PRIVATE is
1351 // set to YES or the member is part of a group
1352 bool visibleIfPrivate = (protectionLevelVisible(protection()) ||
1353 m_impl->mtype==MemberType_Friend
1356 // hide member if it overrides a member in a superclass and has no
1357 // documentation of its own
1358 //bool visibleIfDocVirtual = !reimplements() ||
1359 // !Config_getBool(INHERIT_DOCS) ||
1362 // true if this member is a constructor or destructor
1363 bool cOrDTor = isConstructor() || isDestructor();
1365 // hide default constructors or destructors (no args) without
1367 bool visibleIfNotDefaultCDTor = !(cOrDTor &&
1368 m_impl->defArgList &&
1369 (m_impl->defArgList->isEmpty() ||
1370 m_impl->defArgList->getFirst()->type == "void"
1376 //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d "
1377 // "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d "
1378 // "visibleIfFriendCompound=%d !annScope=%d\n",
1379 // visibleIfStatic,visibleIfDocumented,
1380 // visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
1381 // visibleIfFriendCompound,!m_impl->annScope);
1383 bool visible = visibleIfStatic && visibleIfDocumented &&
1384 visibleIfEnabled && visibleIfPrivate &&
1385 /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor &&
1386 visibleIfFriendCompound &&
1387 !m_impl->annScope && !isHidden();
1388 //printf("MemberDef::isBriefSectionVisible() %d\n",visible);
1392 QCString MemberDef::getDeclType() const
1394 QCString ltype(m_impl->type);
1395 if (m_impl->mtype==MemberType_Typedef)
1397 ltype.prepend("typedef ");
1403 // strip `friend' keyword from ltype
1404 ltype.stripPrefix("friend ");
1405 if (ltype=="@") // rename type from enum values
1420 void MemberDef::writeDeclaration(OutputList &ol,
1421 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
1422 bool inGroup, ClassDef *inheritedFrom,const char *inheritId)
1424 //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",qualifiedName().data(),inGroup);
1426 // hide enum value, since they appear already as part of the enum, unless they
1427 // are explicitly grouped.
1428 if (!inGroup && m_impl->mtype==MemberType_EnumValue) return;
1432 ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
1433 if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
1434 if (d==gd) // see bug 753608
1436 if (getClassDef()) d = getClassDef();
1437 else if (getNamespaceDef()) d = getNamespaceDef();
1438 else if (getFileDef()) d = getFileDef();
1441 //_writeTagData(compoundType);
1442 _addToSearchIndex();
1444 QCString cname = d->name();
1445 QCString cdname = d->displayName();
1446 QCString cfname = getOutputFileBase();
1448 // search for the last anonymous scope in the member type
1449 ClassDef *annoClassDef=getClassDefOfAnonymousType();
1451 ol.startMemberDeclaration();
1453 // start a new member declaration
1454 bool isAnonymous = annoClassDef || m_impl->annMemb || m_impl->annEnumType;
1455 ///printf("startMemberItem for %s\n",name().data());
1456 ol.startMemberItem(anchor(),
1457 isAnonymous ? 1 : m_impl->tArgList ? 3 : 0,
1461 // If there is no detailed description we need to write the anchor here.
1462 bool detailsVisible = isDetailedSectionLinkable();
1463 bool writeAnchor = (inGroup || m_impl->group==0) && // only write anchors for member that have no details and are
1464 !detailsVisible && !m_impl->annMemb; // rendered inside the group page or are not grouped at all
1467 QCString doxyArgs=argsString();
1468 QCString doxyName=name();
1469 if (!cname.isEmpty())
1471 doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage()));
1473 ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs);
1476 if (!detailsVisible)
1478 ol.pushGeneratorState();
1479 ol.disable(OutputGenerator::Man);
1480 ol.disable(OutputGenerator::Latex);
1482 ol.popGeneratorState();
1485 if (annoClassDef || m_impl->annMemb)
1488 for (j=0;j<s_indentLevel;j++)
1490 ol.writeNonBreakableSpace(3);
1494 // *** write template lists
1495 if (m_impl->tArgList && getLanguage()==SrcLangExt_Cpp)
1497 if (!isAnonymous) ol.startMemberTemplateParams();
1498 writeTemplatePrefix(ol,m_impl->tArgList);
1499 if (!isAnonymous) ol.endMemberTemplateParams(anchor(),inheritId);
1503 QCString ltype(m_impl->type);
1504 if (m_impl->mtype==MemberType_Typedef) ltype.prepend("typedef ");
1509 // strip `friend' keyword from ltype
1510 ltype.stripPrefix("friend ");
1511 static QRegExp r("@[0-9]+");
1513 bool endAnonScopeNeeded=FALSE;
1514 int l,i=r.match(ltype,0,&l);
1515 if (i!=-1) // member has an anonymous type
1517 //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n",
1518 // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());
1520 if (annoClassDef) // type is an anonymous compound
1523 //printf("<<<<<<<<<<<<<<\n");
1524 ol.startAnonTypeScope(s_indentLevel++);
1525 annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup,inheritedFrom,inheritId);
1526 //printf(">>>>>>>>>>>>>> startMemberItem(2)\n");
1527 ol.startMemberItem(anchor(),2,inheritId);
1529 for (j=0;j< s_indentLevel-1;j++)
1531 ol.writeNonBreakableSpace(3);
1533 QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
1534 //printf(">>>>>> ltype=`%s' varName=`%s'\n",ltype.data(),varName.data());
1536 if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@'))
1540 else if (!varName.isEmpty() && (varName.at(0)=='*' || varName.at(0)=='&'))
1545 endAnonScopeNeeded=TRUE;
1549 if (getAnonymousEnumType()) // type is an anonymous enum
1551 linkifyText(TextGeneratorOLImpl(ol), // out
1553 getBodyDef(), // fileScope
1555 ltype.left(i), // text
1558 getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd);
1559 //ol+=*getAnonymousEnumType()->enumDecl();
1560 linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,this,ltype.right(ltype.length()-i-l),TRUE);
1564 ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
1565 linkifyText(TextGeneratorOLImpl(ol), // out
1567 getBodyDef(), // fileScope
1575 else if (ltype=="@") // rename type from enum values
1586 linkifyText(TextGeneratorOLImpl(ol), // out
1588 getBodyDef(), // fileScope
1594 bool htmlOn = ol.isEnabled(OutputGenerator::Html);
1595 if (htmlOn && !ltype.isEmpty())
1597 ol.disable(OutputGenerator::Html);
1599 if (!ltype.isEmpty()) ol.docify(" ");
1602 ol.enable(OutputGenerator::Html);
1605 if (m_impl->annMemb)
1607 ol.pushGeneratorState();
1608 ol.disableAllBut(OutputGenerator::Html);
1609 ol.writeNonBreakableSpace(3);
1610 ol.popGeneratorState();
1614 ol.insertMemberAlign(m_impl->tArgList!=0);
1618 if (!name().isEmpty() && name().at(0)!='@') // hide anonymous stuff
1620 static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1621 static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1622 //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d hasDocumentation=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable(),hasDocumentation());
1623 if (!(name().isEmpty() || name().at(0)=='@') && // name valid
1624 (hasDocumentation() || isReference()) && // has docs
1625 !(m_impl->prot==Private && !extractPrivate && m_impl->mtype!=MemberType_Friend) && // hidden due to protection
1626 !(isStatic() && m_impl->classDef==0 && !extractStatic) // hidden due to static-ness
1629 if (m_impl->annMemb)
1631 //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
1632 m_impl->annMemb->writeLink(ol,
1633 m_impl->annMemb->getClassDef(),
1634 m_impl->annMemb->getNamespaceDef(),
1635 m_impl->annMemb->getFileDef(),
1636 m_impl->annMemb->getGroupDef()
1638 m_impl->annMemb->setAnonymousUsed();
1643 //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
1645 if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
1646 writeLink(ol,rcd,nd,fd,gd);
1649 else if (isDocumentedFriendClass())
1650 // if the member is an undocumented friend declaration for some class,
1651 // then maybe we can link to the class
1653 writeLink(ol,getClass(name()),0,0,0);
1656 // there is a brief member description and brief member
1657 // descriptions are enabled or there is no detailed description.
1659 if (m_impl->annMemb)
1661 m_impl->annMemb->setAnonymousUsed();
1665 if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
1666 writeLink(ol,rcd,nd,fd,gd,TRUE);
1671 if (isEnumerate() && name().at(0)=='@')
1673 // don't add to index
1675 else // index member
1677 //static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1678 //QCString cfname = getOutputFileBase();
1679 //QCString cfiname = d->getOutputFileBase();
1680 //Doxygen::indexList->addIndexItem(
1682 // name(), // level2
1683 // separateMemPages ? cfname : cfiname, // contRef
1684 // cfname, // memRef
1685 // anchor(), // anchor
1686 // this); // memberdef
1687 Doxygen::indexList->addIndexItem(d,this);
1690 // *** write arguments
1691 if (argsString() && !isObjCMethod())
1693 if (!isDefine() && !isTypedef()) ol.writeString(" ");
1694 linkifyText(TextGeneratorOLImpl(ol), // out
1696 getBodyDef(), // fileScope
1699 (const char*)substitute(argsString(),",",", ") :
1701 (const char*)substitute(argsString(),")(",") (") :
1702 argsString(), // text
1703 m_impl->annMemb, // autoBreak
1705 FALSE, // keepSpaces
1709 // *** write exceptions
1712 ol.writeString(" ");
1713 ol.docify(excpString());
1716 // *** write bitfields
1717 if (!m_impl->bitfields.isEmpty()) // add bitfields
1719 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->bitfields);
1721 else if (hasOneLineInitializer()
1722 //!init.isEmpty() && initLines==0 && // one line initializer
1723 //((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
1724 ) // add initializer
1728 //ol.writeString(" = ");
1729 ol.writeString(" ");
1730 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer.simplifyWhiteSpace());
1734 ol.writeNonBreakableSpace(3);
1735 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer);
1738 else if (isAlias()) // using template alias
1740 ol.writeString(" = ");
1741 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->type);
1745 if ((isObjCMethod() || isObjCProperty()) && isImplementation())
1747 ol.startTypewriter();
1748 ol.docify(" [implementation]");
1752 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1754 if (isProperty() && (isSettable() || isGettable() ||
1755 isPrivateSettable() || isPrivateGettable() ||
1756 isProtectedSettable() || isProtectedGettable()))
1758 ol.writeLatexSpacing();
1759 ol.startTypewriter();
1763 if (isGettable()) sl.append("get");
1764 if (isProtectedGettable()) sl.append("protected get");
1765 if (isSettable()) sl.append("set");
1766 if (isProtectedSettable()) sl.append("protected set");
1769 if (isPrivateGettable()) sl.append("private get");
1770 if (isPrivateSettable()) sl.append("private set");
1772 const char *s=sl.first();
1777 if (s) ol.docify(", ");
1783 if (isEvent() && (isAddable() || isRemovable() || isRaisable()))
1785 ol.writeLatexSpacing();
1786 ol.startTypewriter();
1789 if (isAddable()) sl.append("add");
1790 if (isRemovable()) sl.append("remove");
1791 if (isRaisable()) sl.append("raise");
1792 const char *s=sl.first();
1797 if (s) ol.docify(", ");
1805 ol.endDoxyAnchor(cfname,anchor());
1808 //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
1809 // name().data(),annoClassDef,annEnumType);
1811 if (endAnonScopeNeeded)
1813 ol.endAnonTypeScope(--s_indentLevel);
1816 // write brief description
1817 if (!briefDescription().isEmpty() &&
1818 Config_getBool(BRIEF_MEMBER_DESC)
1822 DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),
1823 getOuterScope()?getOuterScope():d,this,briefDescription(),
1824 TRUE,FALSE,0,TRUE,FALSE);
1826 if (rootNode && !rootNode->isEmpty())
1828 ol.startMemberDescription(anchor(),inheritId);
1829 ol.writeDoc(rootNode,getOuterScope()?getOuterScope():d,this);
1832 static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1833 ol.pushGeneratorState();
1834 ol.disableAllBut(OutputGenerator::Html);
1837 if (inheritedFrom ||
1838 separateMemberPages ||
1839 (m_impl->group!=0 && gd==0) ||
1840 (m_impl->nspace!=0 && nd==0)
1841 ) // forward link to the page or group or namespace
1843 ol.startTextLink(getOutputFileBase(),anchor());
1847 ol.startTextLink(0,anchor());
1849 ol.parseText(theTranslator->trMore());
1851 //ol.startEmphasis();
1852 ol.popGeneratorState();
1854 // for RTF we need to add an extra empty paragraph
1855 ol.pushGeneratorState();
1856 ol.disableAllBut(OutputGenerator::RTF);
1857 ol.startParagraph();
1859 ol.popGeneratorState();
1860 ol.endMemberDescription();
1865 ol.endMemberDeclaration(anchor(),inheritId);
1867 warnIfUndocumented();
1870 bool MemberDef::isDetailedSectionLinkable() const
1872 static bool extractAll = Config_getBool(EXTRACT_ALL);
1873 static bool alwaysDetailedSec = Config_getBool(ALWAYS_DETAILED_SEC);
1874 static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1875 static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
1876 static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
1877 static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1879 // the member has details documentation for any of the following reasons
1881 // treat everything as documented
1883 // has detailed docs
1884 !documentation().isEmpty() ||
1886 !inbodyDocumentation().isEmpty() ||
1887 // is an enum with values that are documented
1888 (m_impl->mtype==MemberType_Enumeration && m_impl->docEnumValues) ||
1889 // is documented enum value
1890 (m_impl->mtype==MemberType_EnumValue && !briefDescription().isEmpty()) ||
1891 // has brief description that is part of the detailed description
1892 (!briefDescription().isEmpty() && // has brief docs
1893 (alwaysDetailedSec && // they are visible in
1894 (repeatBrief || // detailed section or
1895 !briefMemberDesc // they are explicitly not
1896 ) // shown in brief section
1899 // has a multi-line initialization block
1900 //(initLines>0 && initLines<maxInitLines) ||
1901 (hasMultiLineInitializer() && !hideUndocMembers) ||
1902 // has one or more documented arguments
1903 (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()) ||
1904 // is an attribute or property - need to display that tag
1905 (m_impl->memSpec & (Entry::Attribute|Entry::Property)) ||
1906 // has user comments
1907 Doxygen::userComments
1910 // this is not a global static or global statics should be extracted
1911 bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic;
1913 // only include members that are non-private unless EXTRACT_PRIVATE is
1914 // set to YES or the member is part of a group
1915 bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend;
1917 // member is part of an anonymous scope that is the type of
1918 // another member in the list.
1920 //bool inAnonymousScope = !briefDescription().isEmpty() && annUsed;
1922 // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS
1924 bool friendCompoundFilter = !(Config_getBool(HIDE_FRIEND_COMPOUNDS) &&
1926 (m_impl->type=="friend class" ||
1927 m_impl->type=="friend struct" ||
1928 m_impl->type=="friend union"
1933 bool result = ((docFilter && staticFilter && privateFilter && friendCompoundFilter && !isHidden()));
1934 //printf("%s::isDetailedSectionLinkable: %d\n",name().data(),result);
1938 bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const
1940 static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1941 static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS);
1942 static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
1943 bool groupFilter = getGroupDef()==0 || inGroup || separateMemPages;
1944 bool fileFilter = getNamespaceDef()==0 || !getNamespaceDef()->isLinkable() || !inFile;
1945 bool simpleFilter = (hasBriefDescription() || !hideUndocMembers) && inlineSimpleStructs &&
1946 getClassDef()!=0 && getClassDef()->isSimple();
1948 bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter &&
1950 bool result = visible || simpleFilter;
1951 //printf("%s::isDetailedSectionVisble: %d groupFilter=%d fileFilter=%d\n",
1952 // name().data(),result,groupFilter,fileFilter);
1956 void MemberDef::getLabels(QStrList &sl,Definition *container) const
1958 static bool inlineInfo = Config_getBool(INLINE_INFO);
1960 Specifier lvirt=virtualness();
1961 if ((!isObjCMethod() || isOptional() || isRequired()) &&
1962 (protection()!=Public || lvirt!=Normal ||
1963 isFriend() || isRelated() ||
1964 (isInline() && inlineInfo) ||
1965 isSignal() || isSlot() ||
1967 (m_impl->classDef && m_impl->classDef!=container && container->definitionType()==TypeClass) ||
1968 (m_impl->memSpec & ~Entry::Inline)!=0
1972 // write the member specifier list
1973 //ol.writeLatexSpacing();
1974 //ol.startTypewriter();
1976 SrcLangExt lang = getLanguage();
1977 bool optVhdl = lang==SrcLangExt_VHDL;
1978 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1981 sl.append(VhdlDocGen::trTypeString(getMemberSpecifiers()));
1985 if (isFriend()) sl.append("friend");
1986 else if (isRelated()) sl.append("related");
1989 if (Config_getBool(INLINE_INFO) && isInline()) sl.append("inline");
1990 if (isExplicit()) sl.append("explicit");
1991 if (isMutable()) sl.append("mutable");
1992 if (isStatic()) sl.append("static");
1993 if (isGettable()) sl.append("get");
1994 if (isProtectedGettable()) sl.append("protected get");
1995 if (isSettable()) sl.append("set");
1996 if (isProtectedSettable()) sl.append("protected set");
1999 if (isPrivateGettable()) sl.append("private get");
2000 if (isPrivateSettable()) sl.append("private set");
2002 if (isAddable()) sl.append("add");
2003 if (!isUNOProperty() && isRemovable()) sl.append("remove");
2004 if (isRaisable()) sl.append("raise");
2005 if (isReadable()) sl.append("read");
2006 if (isWritable()) sl.append("write");
2007 if (isFinal()) sl.append("final");
2008 if (isAbstract()) sl.append("abstract");
2009 if (isOverride()) sl.append("override");
2010 if (isInitonly()) sl.append("initonly");
2011 if (isSealed()) sl.append("sealed");
2012 if (isNew()) sl.append("new");
2013 if (isOptional()) sl.append("optional");
2014 if (isRequired()) sl.append("required");
2016 if (isNonAtomic()) sl.append("nonatomic");
2017 else if (isObjCProperty()) sl.append("atomic");
2019 // mutual exclusive Objective 2.0 property attributes
2020 if (isAssign()) sl.append("assign");
2021 else if (isCopy()) sl.append("copy");
2022 else if (isRetain()) sl.append("retain");
2023 else if (isWeak()) sl.append("weak");
2024 else if (isStrong()) sl.append("strong");
2025 else if (isUnretained()) sl.append("unsafe_unretained");
2027 if (!isObjCMethod())
2029 if (protection()==Protected) sl.append("protected");
2030 else if (protection()==Private) sl.append("private");
2031 else if (protection()==Package) sl.append("package");
2033 if (lvirt==Virtual) sl.append("virtual");
2034 else if (lvirt==Pure) sl.append("pure virtual");
2035 if (isSignal()) sl.append("signal");
2036 if (isSlot()) sl.append("slot");
2037 if (isDefault()) sl.append("default");
2038 if (isDelete()) sl.append("delete");
2039 if (isNoExcept()) sl.append("noexcept");
2040 if (isAttribute()) sl.append("attribute");
2041 if (isUNOProperty()) sl.append("property");
2042 if (isReadonly()) sl.append("readonly");
2043 if (isBound()) sl.append("bound");
2044 if (isUNOProperty() && isRemovable()) sl.append("removable");
2045 if (isConstrained()) sl.append("constrained");
2046 if (isTransient()) sl.append("transient");
2047 if (isMaybeVoid()) sl.append("maybevoid");
2048 if (isMaybeDefault()) sl.append("maybedefault");
2049 if (isMaybeAmbiguous()) sl.append("maybeambiguous");
2050 if (isPublished()) sl.append("published"); // enum
2052 if (isObjCProperty() && isImplementation())
2054 sl.append("implementation");
2057 if (m_impl->classDef &&
2058 container->definitionType()==TypeClass &&
2059 m_impl->classDef!=container &&
2063 sl.append("inherited");
2067 else if (isObjCMethod() && isImplementation())
2069 sl.append("implementation");
2073 void MemberDef::_writeCallGraph(OutputList &ol)
2076 if (m_impl->hasCallGraph
2077 && (isFunction() || isSlot() || isSignal()) && Config_getBool(HAVE_DOT)
2080 DotCallGraph callGraph(this,FALSE);
2081 if (callGraph.isTooBig())
2083 warn_uncond("Call graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
2085 else if (!callGraph.isTrivial())
2087 msg("Generating call graph for function %s\n",qPrint(qualifiedName()));
2088 ol.disable(OutputGenerator::Man);
2089 ol.startCallGraph();
2090 ol.parseText(theTranslator->trCallGraph());
2091 ol.endCallGraph(callGraph);
2097 void MemberDef::_writeCallerGraph(OutputList &ol)
2099 if (m_impl->hasCallerGraph
2100 && (isFunction() || isSlot() || isSignal()) && Config_getBool(HAVE_DOT)
2103 DotCallGraph callerGraph(this, TRUE);
2104 if (callerGraph.isTooBig())
2106 warn_uncond("Caller graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
2108 else if (!callerGraph.isTrivial() && !callerGraph.isTooBig())
2110 msg("Generating caller graph for function %s\n",qPrint(qualifiedName()));
2111 ol.disable(OutputGenerator::Man);
2112 ol.startCallGraph();
2113 ol.parseText(theTranslator->trCallerGraph());
2114 ol.endCallGraph(callerGraph);
2120 void MemberDef::_writeReimplements(OutputList &ol)
2122 MemberDef *bmd=reimplements();
2124 if (bmd && (bcd=bmd->getClassDef()))
2126 // write class that contains a member that is reimplemented by this one
2127 if (bcd->isLinkable())
2129 ol.startParagraph();
2130 QCString reimplFromLine;
2131 if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
2133 reimplFromLine = theTranslator->trReimplementedFromList(1);
2137 reimplFromLine = theTranslator->trImplementedFromList(1);
2139 int markerPos = reimplFromLine.find("@0");
2140 if (markerPos!=-1) // should always pass this.
2142 ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
2143 if (bmd->isLinkable()) // replace marker with link
2145 //Definition *bd=bmd->group;
2146 //if (bd==0) bd=bcd;
2147 ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
2148 bmd->anchor(),bcd->displayName());
2150 //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2151 // bmd->anchor(),bcd->name());
2152 if ( bmd->isLinkableInProject() )
2154 writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
2159 ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2160 0,bcd->displayName());
2161 if (bcd->isLinkableInProject()/* && !Config_getBool(PDF_HYPERLINKS)*/ )
2163 writePageRef(ol,bcd->getOutputFileBase(),bcd->anchor());
2166 ol.parseText(reimplFromLine.right(
2167 reimplFromLine.length()-markerPos-2)); // text right from marker
2172 err("translation error: no marker in trReimplementsFromList()\n");
2179 void MemberDef::_writeReimplementedBy(OutputList &ol)
2181 MemberList *bml=reimplementedBy();
2184 MemberListIterator mli(*bml);
2188 for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
2190 // count the members that directly inherit from md and for
2191 // which the member and class are visible in the docs.
2192 if ( bmd->isLinkable() && bcd->isLinkable() )
2200 // write the list of classes that overwrite this member
2201 ol.startParagraph();
2203 QCString reimplInLine;
2204 if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface))
2206 reimplInLine = theTranslator->trImplementedInList(count);
2210 reimplInLine = theTranslator->trReimplementedInList(count);
2212 static QRegExp marker("@[0-9]+");
2213 int index=0,newIndex,matchLen;
2214 // now replace all markers in reimplInLine with links to the classes
2215 while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
2217 ol.parseText(reimplInLine.mid(index,newIndex-index));
2219 uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
2220 //bmd=bml->at(entryIndex);
2223 // find the entryIndex-th documented entry in the inheritance list.
2224 for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
2226 if ( bmd->isLinkable() && bcd->isLinkable())
2228 if (count==entryIndex) break;
2233 if (ok && bcd && bmd) // write link for marker
2235 //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2236 // bmd->anchor(),bcd->name());
2237 ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
2238 bmd->anchor(),bcd->displayName());
2240 if (bmd->isLinkableInProject() )
2242 writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
2246 index=newIndex+matchLen;
2248 ol.parseText(reimplInLine.right(reimplInLine.length()-index));
2254 void MemberDef::_writeCategoryRelation(OutputList &ol)
2256 if (m_impl->classDef) // this should be a member of a class/category
2258 //printf("%s: category %s relation %s class=%s categoryOf=%s\n",
2260 // m_impl->category ? m_impl->category->name().data() : "<none>",
2261 // m_impl->categoryRelation ? m_impl->categoryRelation->name().data() : "<none>",
2262 // m_impl->classDef->name().data(),
2263 // m_impl->classDef->categoryOf() ? m_impl->classDef->categoryOf()->name().data() : "<none>"
2271 if (m_impl->categoryRelation && m_impl->categoryRelation->isLinkable())
2273 if (m_impl->category)
2275 // this member is in a normal class and implements method categoryRelation from category
2276 // so link to method 'categoryRelation' with 'provided by category 'category' text.
2277 text = theTranslator->trProvidedByCategory();
2278 name = m_impl->category->displayName();
2280 else if (m_impl->classDef->categoryOf())
2282 // this member is part of a category so link to the corresponding class member of the class we extend
2283 // so link to method 'categoryRelation' with 'extends class 'classDef->categoryOf()'
2284 text = theTranslator->trExtendsClass();
2285 name = m_impl->classDef->categoryOf()->displayName();
2290 MemberDef *md = m_impl->categoryRelation;
2291 ref = md->getReference();
2292 file = md->getOutputFileBase();
2296 if (i!=-1 && !name.isEmpty())
2298 ol.startParagraph();
2299 ol.parseText(text.left(i));
2300 ol.writeObjectLink(ref,file,anc,name);
2301 ol.parseText(text.mid(i+2));
2307 void MemberDef::_writeExamples(OutputList &ol)
2309 // write the list of examples that use this member
2312 ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
2313 ol.startDescForItem();
2314 writeExample(ol,m_impl->exampleSDict);
2315 ol.endDescForItem();
2320 void MemberDef::_writeTypeConstraints(OutputList &ol)
2322 if (m_impl->typeConstraints)
2324 writeTypeConstraints(ol,this,m_impl->typeConstraints);
2328 void MemberDef::_writeEnumValues(OutputList &ol,Definition *container,
2329 const QCString &cfname,const QCString &ciname,
2330 const QCString &cname)
2332 // For enum, we also write the documented enum values
2336 MemberList *fmdl=enumFieldList();
2337 //printf("** %s: enum values=%d\n",name().data(),fmdl!=0 ? fmdl->count() : 0);
2340 MemberListIterator it(*fmdl);
2342 for (;(fmd=it.current());++it)
2344 //printf("Enum %p: isLinkable()=%d\n",fmd,fmd->isLinkable());
2345 if (fmd->isLinkable())
2349 //ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": ");
2350 //ol.startDescForItem();
2351 ol.startDescTable(theTranslator->trEnumerationValues());
2354 ol.startDescTableRow();
2355 ol.addIndexItem(fmd->name(),ciname);
2356 ol.addIndexItem(ciname,fmd->name());
2358 //Doxygen::indexList->addIndexItem(
2359 // ciname, // level1
2360 // fmd->name(), // level2
2361 // separateMemPages ? cfname : cfiname, // contRef
2362 // cfname, // memRef
2363 // fmd->anchor(), // anchor
2364 // fmd); // memberdef
2365 Doxygen::indexList->addIndexItem(container,fmd);
2367 //ol.writeListItem();
2368 ol.startDescTableTitle();
2369 ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString());
2371 //ol.startEmphasis();
2372 ol.docify(fmd->name());
2374 ol.disableAllBut(OutputGenerator::Man);
2375 ol.writeString(" ");
2377 ol.endDoxyAnchor(cfname,fmd->anchor());
2378 ol.endDescTableTitle();
2379 //ol.newParagraph();
2380 ol.startDescTableData();
2382 bool hasBrief = !fmd->briefDescription().isEmpty();
2383 bool hasDetails = !fmd->documentation().isEmpty();
2387 ol.generateDoc(fmd->briefFile(),fmd->briefLine(),
2388 getOuterScope()?getOuterScope():container,
2389 fmd,fmd->briefDescription(),TRUE,FALSE);
2392 //if (!fmd->briefDescription().isEmpty() &&
2393 // !fmd->documentation().isEmpty())
2395 // ol.newParagraph();
2399 ol.generateDoc(fmd->docFile(),fmd->docLine(),
2400 getOuterScope()?getOuterScope():container,
2401 fmd,fmd->documentation()+"\n",TRUE,FALSE);
2403 ol.endDescTableData();
2404 ol.endDescTableRow();
2412 //ol.endDescForItem();
2413 //ol.endSimpleSect();
2414 //ol.writeChar('\n');
2419 QCString MemberDef::displayDefinition() const
2421 QCString ldef = definition();
2422 QCString title = name();
2425 if (title.at(0)=='@')
2427 ldef = title = "anonymous enum";
2428 if (!m_impl->enumBaseType.isEmpty())
2430 ldef+=" : "+m_impl->enumBaseType;
2435 ldef.prepend("enum ");
2438 else if (isEnumValue())
2440 if (ldef.at(0)=='@')
2445 static QRegExp r("@[0-9]+");
2446 int l,i=r.match(ldef,0,&l);
2447 if (i!=-1) // replace anonymous parts with { ... }
2449 int si=ldef.find(' '),pi,ei=i+l;
2451 while ((pi=r.match(ldef,i+l,&l))!=-1)
2456 int ni=ldef.find("::",si);
2457 if (ni>=ei) ei=ni+2;
2458 ldef = ldef.left(si) + " { ... } " + ldef.right(ldef.length()-ei);
2460 ClassDef *cd=getClassDef();
2461 if (cd && cd->isObjectiveC())
2464 int ep = ldef.find("::");
2467 int sp=ldef.findRev(' ',ep);
2470 ldef=ldef.left(sp+1)+ldef.mid(ep+2);
2474 int dp = ldef.find(':');
2477 ldef=ldef.left(dp+1);
2480 //printf("start >%s<\n",ldef.data());
2482 while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
2483 while (i>=0 && isspace((uchar)ldef.at(i))) i--;
2486 // insert braches around the type
2487 QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
2490 //printf("end >%s< i=%d\n",ldef.data(),i);
2491 if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
2493 SrcLangExt lang = getLanguage();
2494 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
2495 return substitute(ldef,"::",sep);
2498 void MemberDef::_writeGroupInclude(OutputList &ol,bool inGroup)
2500 // only write out the include file if this is not part of a class or file
2502 static bool showGroupedMembInc = Config_getBool(SHOW_GROUPED_MEMB_INC);
2503 FileDef *fd = getFileDef();
2505 if (fd) nm = getFileDef()->docName();
2506 if (inGroup && fd && showGroupedMembInc && !nm.isEmpty())
2508 ol.startParagraph();
2509 ol.startTypewriter();
2510 SrcLangExt lang = getLanguage();
2511 bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
2514 ol.docify("import ");
2518 ol.docify("#include ");
2521 if (isIDLorJava) ol.docify("\""); else ol.docify("<");
2523 if (fd->isLinkable())
2525 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),fd->anchor(),nm);
2532 if (isIDLorJava) ol.docify("\""); else ol.docify(">");
2539 /*! Writes the "detailed documentation" section of this member to
2540 * all active output formats.
2542 void MemberDef::writeDocumentation(MemberList *ml,
2543 int memCount,int memTotal,
2546 Definition *container,
2548 bool showEnumValues,
2552 // if this member is in a group find the real scope name.
2553 bool hasParameterList = FALSE;
2554 bool inFile = container->definitionType()==Definition::TypeFile;
2555 bool hasDocs = isDetailedSectionVisible(inGroup,inFile);
2557 //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d sectionLinkable=%d\n",
2558 // name().data(),hasDocs,container->definitionType(),inGroup,isDetailedSectionLinkable());
2560 //if ( !hasDocs ) return;
2561 //if (isEnumValue() && !showEnumValues) return;
2563 SrcLangExt lang = getLanguage();
2564 //printf("member=%s lang=%d\n",name().data(),lang);
2565 bool optVhdl = lang==SrcLangExt_VHDL;
2566 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
2568 QCString scopeName = scName;
2569 QCString memAnchor = anchor();
2570 QCString ciname = container->name();
2571 Definition *scopedContainer = container; // see bug 753608
2572 if (container->definitionType()==TypeGroup)
2574 if (getClassDef()) { scopeName=getClassDef()->displayName(); scopedContainer=getClassDef(); }
2575 else if (getNamespaceDef()) { scopeName=getNamespaceDef()->displayName(); scopedContainer=getNamespaceDef(); }
2576 else if (getFileDef()) { scopeName=getFileDef()->displayName(); scopedContainer=getFileDef(); }
2577 ciname = ((GroupDef *)container)->groupTitle();
2579 else if (container->definitionType()==TypeFile && getNamespaceDef())
2580 { // member is in a namespace, but is written as part of the file documentation
2581 // as well, so we need to make sure its label is unique.
2582 memAnchor.prepend("file_");
2585 QCString cname = container->name();
2586 QCString cfname = getOutputFileBase();
2589 QCString doxyName=name();
2590 // prepend scope if there is any. TODO: make this optional for C only docs
2591 if (!scopeName.isEmpty())
2593 doxyName.prepend(scopeName+sep);
2595 QCString doxyArgs=argsString();
2597 QCString ldef = definition();
2598 QCString title = name();
2599 //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
2602 if (title.at(0)=='@')
2604 ldef = title = "anonymous enum";
2605 if (!m_impl->enumBaseType.isEmpty())
2607 ldef+=" : "+m_impl->enumBaseType;
2612 ldef.prepend("enum ");
2615 else if (isEnumValue())
2617 if (ldef.at(0)=='@')
2622 else if (isFunction())
2627 static QRegExp r("@[0-9]+");
2629 //----------------------------------------
2631 ol.pushGeneratorState();
2633 bool htmlEndLabelTable=FALSE;
2635 getLabels(sl,scopedContainer);
2637 if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
2639 // find enum type and insert it in the definition
2640 MemberListIterator vmli(*ml);
2643 for ( ; (vmd=vmli.current()) && !found ; ++vmli)
2645 if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
2647 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2648 ol.startMemberDoc(ciname,name(),memAnchor,name(),memCount,memTotal,showInline);
2649 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.left(i));
2650 vmd->writeEnumDeclaration(ol,getClassDef(),getNamespaceDef(),getFileDef(),getGroupDef());
2651 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.right(ldef.length()-i-l));
2656 if (!found) // anonymous compound
2658 //printf("Anonymous compound `%s'\n",cname.data());
2659 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2660 ol.startMemberDoc(ciname,name(),memAnchor,name(),memCount,memTotal,showInline);
2661 // search for the last anonymous compound name in the definition
2662 int si=ldef.find(' '),pi,ei=i+l;
2664 while ((pi=r.match(ldef,i+l,&l))!=-1)
2669 // first si characters of ldef contain compound type name
2670 ol.startMemberDocName(isObjCMethod());
2671 ol.docify(ldef.left(si));
2672 ol.docify(" { ... } ");
2673 // last ei characters of ldef contain pointer/reference specifiers
2674 int ni=ldef.find("::",si);
2675 if (ni>=ei) ei=ni+2;
2676 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.right(ldef.length()-ei));
2679 else // not an enum value or anonymous compound
2681 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2682 ol.startMemberDoc(ciname,name(),memAnchor,title,memCount,memTotal,showInline);
2684 ClassDef *cd=getClassDef();
2685 NamespaceDef *nd=getNamespaceDef();
2686 if (!Config_getBool(HIDE_SCOPE_NAMES))
2689 SrcLangExt lang = getLanguage();
2690 if (m_impl->defTmpArgLists && lang==SrcLangExt_Cpp)
2691 // definition has explicit template parameter declarations
2693 QListIterator<ArgumentList> ali(*m_impl->defTmpArgLists);
2695 for (ali.toFirst();(tal=ali.current());++ali)
2699 if (!first) ol.docify(" ");
2700 ol.startMemberDocPrefixItem();
2701 writeTemplatePrefix(ol,tal);
2702 ol.endMemberDocPrefixItem();
2706 else // definition gets it template parameters from its class
2707 // (since no definition was found)
2709 if (cd && lang==SrcLangExt_Cpp && !isTemplateSpecialization())
2711 QList<ArgumentList> tempParamLists;
2712 cd->getTemplateParameterLists(tempParamLists);
2713 //printf("#tempParamLists=%d\n",tempParamLists.count());
2714 QListIterator<ArgumentList> ali(tempParamLists);
2716 for (ali.toFirst();(tal=ali.current());++ali)
2720 if (!first) ol.docify(" ");
2721 ol.startMemberDocPrefixItem();
2722 writeTemplatePrefix(ol,tal);
2723 ol.endMemberDocPrefixItem();
2727 if (m_impl->tArgList && lang==SrcLangExt_Cpp) // function template prefix
2729 ol.startMemberDocPrefixItem();
2730 writeTemplatePrefix(ol,m_impl->tArgList);
2731 ol.endMemberDocPrefixItem();
2738 ol.pushGeneratorState();
2740 ol.enable(OutputGenerator::Html);
2741 ol.writeString("<table class=\"mlabels\">\n");
2742 ol.writeString(" <tr>\n");
2743 ol.writeString(" <td class=\"mlabels-left\">\n");
2744 ol.popGeneratorState();
2745 htmlEndLabelTable=TRUE;
2748 ol.startMemberDocName(isObjCMethod());
2749 if (cd && cd->isObjectiveC())
2752 int ep = ldef.find("::");
2755 int sp=ldef.findRev(' ',ep);
2758 ldef=ldef.left(sp+1)+ldef.mid(ep+2);
2760 ldef=ldef.mid(ep+2);
2764 int dp = ldef.find(':');
2767 ldef=ldef.left(dp+1);
2769 int l=ldef.length();
2770 //printf("start >%s<\n",ldef.data());
2772 while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
2773 while (i>=0 && isspace((uchar)ldef.at(i))) i--;
2776 // insert braches around the type
2777 QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
2780 //printf("end >%s< i=%d\n",ldef.data(),i);
2781 if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
2786 hasParameterList=VhdlDocGen::writeVHDLTypeDocumentation(this,scopedContainer,ol);
2790 linkifyText(TextGeneratorOLImpl(ol),
2794 substitute(ldef,"::",sep)
2796 Definition *scope = cd;
2797 if (scope==0) scope = nd;
2798 hasParameterList=writeDefArgumentList(ol,scope,this);
2801 if (hasOneLineInitializer()) // add initializer
2807 QCString init = m_impl->initializer.simplifyWhiteSpace();
2808 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,init);
2812 ol.writeNonBreakableSpace(3);
2813 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,m_impl->initializer);
2816 if (excpString()) // add exception list
2818 writeExceptionList(ol,cd,this);
2819 hasParameterList=true; // call endParameterList below
2823 ol.pushGeneratorState();
2824 ol.disable(OutputGenerator::Html);
2828 const char *s=sl.first();
2831 const char *ns = sl.next();
2832 ol.writeLabel(s,ns==0);
2837 ol.popGeneratorState();
2839 if (hasParameterList)
2841 ol.endParameterList();
2842 ol.endMemberDoc(TRUE);
2846 ol.endMemberDocName();
2847 ol.endMemberDoc(FALSE);
2850 // for HTML write the labels here
2851 ol.pushGeneratorState();
2853 ol.enable(OutputGenerator::Html);
2854 if (htmlEndLabelTable)
2856 ol.writeString(" </td>\n");
2857 ol.writeString(" <td class=\"mlabels-right\">\n");
2859 const char *s=sl.first();
2862 const char *ns = sl.next();
2863 ol.writeLabel(s,ns==0);
2867 ol.writeString(" </td>\n");
2868 ol.writeString(" </tr>\n");
2869 ol.writeString("</table>\n");
2871 ol.writeString("</div>");
2872 ol.popGeneratorState();
2875 ol.endDoxyAnchor(cfname,memAnchor);
2878 _writeGroupInclude(ol,inGroup);
2880 /* write multi-line initializer (if any) */
2881 if (hasMultiLineInitializer()
2882 //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
2883 // || initLines<userInitLines // explicitly enabled
2887 //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
2889 if (m_impl->mtype==MemberType_Define)
2890 ol.parseText(theTranslator->trDefineValue());
2892 ol.parseText(theTranslator->trInitialValue());
2894 ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
2895 pIntf->resetCodeParserState();
2896 ol.startCodeFragment();
2897 pIntf->parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,getFileDef(),
2898 -1,-1,TRUE,this,FALSE,this);
2899 ol.endCodeFragment();
2902 QCString brief = briefDescription();
2903 QCString detailed = documentation();
2904 ArgumentList *docArgList = m_impl->defArgList;
2905 if (m_impl->templateMaster)
2907 brief = m_impl->templateMaster->briefDescription();
2908 detailed = m_impl->templateMaster->documentation();
2909 docArgList = m_impl->templateMaster->argumentList();
2912 /* write brief description */
2913 if (!brief.isEmpty() &&
2914 (Config_getBool(REPEAT_BRIEF) ||
2915 !Config_getBool(BRIEF_MEMBER_DESC)
2919 ol.startParagraph();
2920 ol.generateDoc(briefFile(),briefLine(),
2921 scopedContainer,this,
2922 brief,FALSE,FALSE,0,TRUE,FALSE);
2926 /* write detailed description */
2927 if (!detailed.isEmpty() ||
2928 !inbodyDocumentation().isEmpty())
2930 // write vhdl inline code with or without option INLINE_SOURCE
2931 if (optVhdl && VhdlDocGen::isMisc(this))
2933 VhdlDocGen::writeSource(this,ol,cname);
2938 ol.generateDoc(docFile(),docLine(),scopedContainer,this,detailed+"\n",TRUE,FALSE);
2941 if (!inbodyDocumentation().isEmpty())
2943 ol.generateDoc(inbodyFile(),inbodyLine(),
2944 scopedContainer,this,
2945 inbodyDocumentation()+"\n",TRUE,FALSE);
2948 else if (!brief.isEmpty() && (Config_getBool(REPEAT_BRIEF) ||
2949 !Config_getBool(BRIEF_MEMBER_DESC)))
2951 if (!inbodyDocumentation().isEmpty())
2953 ol.generateDoc(inbodyFile(),inbodyLine(),scopedContainer,this,inbodyDocumentation()+"\n",TRUE,FALSE);
2958 //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
2960 // defArgList?defArgList->hasDocumentation():-1);
2961 if (docArgList!=0 && docArgList->hasDocumentation())
2964 ArgumentListIterator ali(*docArgList);
2966 // convert the parameter documentation into a list of @param commands
2967 for (ali.toFirst();(a=ali.current());++ali)
2969 if (a->hasDocumentation())
2971 QCString direction = extractDirection(a->docs);
2972 paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
2975 // feed the result to the documentation parser
2977 docFile(),docLine(),
2980 paramDocs, // docStr
2987 _writeEnumValues(ol,scopedContainer,cfname,ciname,cname);
2988 _writeReimplements(ol);
2989 _writeReimplementedBy(ol);
2990 _writeCategoryRelation(ol);
2992 _writeTypeConstraints(ol);
2993 writeSourceDef(ol,cname);
2994 writeSourceRefs(ol,cname);
2995 writeSourceReffedBy(ol,cname);
2996 writeInlineCode(ol,cname);
2997 _writeCallGraph(ol);
2998 _writeCallerGraph(ol);
3000 if (Doxygen::userComments)
3002 ol.pushGeneratorState();
3003 ol.disableAllBut(OutputGenerator::Html);
3004 QCString cmd = "<? $root=$_SERVER['DOCUMENT_ROOT']; "
3005 "passthru(\"$root/doxynotes --lookup "+
3006 getOutputFileBase()+":"+anchor()+"\") ?>";
3007 ol.writeString(cmd);
3008 ol.popGeneratorState();
3013 // enable LaTeX again
3014 //if (Config_getBool(EXTRACT_ALL) && !hasDocs) ol.enable(OutputGenerator::Latex);
3015 ol.popGeneratorState();
3017 warnIfUndocumentedParams();
3020 // strip scope and field name from the type
3021 // example: "struct N::S.v.c" will become "struct v"
3022 static QCString simplifyTypeForTable(const QCString &s)
3024 QCString ts=removeAnonymousScopes(s);
3025 if (ts.right(2)=="::") ts = ts.left(ts.length()-2);
3026 static QRegExp re("[A-Z_a-z0-9]+::");
3028 while ((i=re.match(ts,0,&l))!=-1)
3030 ts=ts.left(i)+ts.mid(i+l);
3033 if (i!=-1) ts = ts.left(i);
3035 if (i!=-1) ts = ts.right(ts.length()-i-1);
3036 //printf("simplifyTypeForTable(%s)->%s\n",s.data(),ts.data());
3041 /** Returns the type definition corresponding to a member's return type.
3042 * @param[in] scope The scope in which to search for the class definition.
3043 * @param[in] type The string representing the member's return type.
3044 * @param[in] lang The programming language in which the class is defined.
3045 * @param[out] start The string position where the class definition name was found.
3046 * @param[out] length The length of the class definition's name.
3048 static Definition *getClassFromType(Definition *scope,const QCString &type,SrcLangExt lang,int &start,int &length)
3054 while ((i=extractClassNameFromType(type,pos,name,templSpec,lang))!=-1)
3058 int l = name.length()+templSpec.length();
3059 if (!templSpec.isEmpty())
3061 cd = getResolvedClass(scope,0,name+templSpec,&md);
3063 cd = getResolvedClass(scope,0,name);
3068 printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
3075 printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
3084 QCString MemberDef::fieldType() const
3086 QCString type = m_impl->accessorType;
3089 type = m_impl->type;
3092 if (isTypedef()) type.prepend("typedef ");
3093 return simplifyTypeForTable(type);
3096 void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container)
3098 Definition *scope = getOuterScope();
3099 QCString doxyName = name();
3100 QCString doxyArgs = argsString();
3101 QCString memAnchor = anchor();
3102 QCString cfname = getOutputFileBase();
3104 if (scope) cname = scope->name();
3105 if (doxyName.at(0)=='@')
3107 doxyName="__unnamed__";
3110 ClassDef *cd = m_impl->accessorClass;
3111 //printf("===> %s::anonymous: %s\n",name().data(),cd?cd->name().data():"<none>");
3113 if (container && container->definitionType()==Definition::TypeClass &&
3114 !((ClassDef*)container)->isJavaEnum())
3116 ol.startInlineMemberType();
3117 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
3119 QCString ts = fieldType();
3121 if (cd) // cd points to an anonymous struct pointed to by this member
3122 // so we add a link to it from the type column.
3125 const char *prefixes[] = { "struct ","union ","class ", 0 };
3126 const char **p = prefixes;
3137 ol.writeObjectLink(cd->getReference(),
3138 cd->getOutputFileBase(),
3139 cd->anchor(),ts.mid(i));
3141 else // use standard auto linking
3143 linkifyText(TextGeneratorOLImpl(ol), // out
3145 getBodyDef(), // fileScope
3150 ol.endDoxyAnchor(cfname,memAnchor);
3151 ol.endInlineMemberType();
3154 ol.startInlineMemberName();
3155 ol.docify(doxyName);
3156 if (isVariable() && argsString() && !isObjCMethod())
3158 linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,argsString());
3160 if (!m_impl->bitfields.isEmpty()) // add bitfields
3162 linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,m_impl->bitfields);
3164 ol.endInlineMemberName();
3166 ol.startInlineMemberDoc();
3168 QCString brief = briefDescription();
3169 QCString detailed = documentation();
3171 /* write brief description */
3172 if (!brief.isEmpty())
3174 ol.generateDoc(briefFile(),briefLine(),
3175 getOuterScope()?getOuterScope():container,this,
3176 brief,FALSE,FALSE,0,TRUE,FALSE);
3179 /* write detailed description */
3180 if (!detailed.isEmpty())
3182 ol.generateDoc(docFile(),docLine(),
3183 getOuterScope()?getOuterScope():container,this,
3184 detailed+"\n",FALSE,FALSE,0,FALSE,FALSE);
3188 ol.endInlineMemberDoc();
3191 QCString MemberDef::memberTypeName() const
3193 switch (m_impl->mtype)
3195 case MemberType_Define: return "macro definition";
3196 case MemberType_Function: return "function";
3197 case MemberType_Variable: return "variable";
3198 case MemberType_Typedef: return "typedef";
3199 case MemberType_Enumeration: return "enumeration";
3200 case MemberType_EnumValue: return "enumvalue";
3201 case MemberType_Signal: return "signal";
3202 case MemberType_Slot: return "slot";
3203 case MemberType_Friend: return "friend";
3204 case MemberType_DCOP: return "dcop";
3205 case MemberType_Property: return "property";
3206 case MemberType_Event: return "event";
3207 case MemberType_Interface: return "interface";
3208 case MemberType_Service: return "service";
3209 default: return "unknown";
3213 void MemberDef::warnIfUndocumented()
3215 if (m_impl->memberGroup) return;
3216 ClassDef *cd = getClassDef();
3217 NamespaceDef *nd = getNamespaceDef();
3218 FileDef *fd = getFileDef();
3219 GroupDef *gd = getGroupDef();
3227 if (d->getLanguage() == SrcLangExt_Fortran)
3236 static bool extractAll = Config_getBool(EXTRACT_ALL);
3238 //printf("%s:warnIfUndoc: hasUserDocs=%d isFriendClass=%d protection=%d isRef=%d isDel=%d\n",
3240 // hasUserDocumentation(),isFriendClass(),protectionLevelVisible(m_impl->prot),isReference(),isDeleted());
3241 if ((!hasUserDocumentation() && !extractAll) &&
3243 name().find('@')==-1 && d && d->name().find('@')==-1 &&
3244 protectionLevelVisible(m_impl->prot) &&
3245 !isReference() && !isDeleted()
3248 warn_undoc(getDefFileName(),getDefLine(),"Member %s%s (%s) of %s %s is not documented.",
3249 qPrint(name()),qPrint(argsString()),qPrint(memberTypeName()),t,qPrint(d->name()));
3251 else if (!isDetailedSectionLinkable())
3253 warnIfUndocumentedParams();
3258 void MemberDef::warnIfUndocumentedParams()
3260 if (!Config_getBool(EXTRACT_ALL) &&
3261 Config_getBool(WARN_IF_UNDOCUMENTED) &&
3262 Config_getBool(WARN_NO_PARAMDOC) &&
3264 !Doxygen::suppressDocWarnings)
3266 if (!hasDocumentedParams())
3268 warn_doc_error(getDefFileName(),getDefLine(),
3269 "parameters of member %s are not (all) documented",
3270 qPrint(qualifiedName()));
3272 if (!hasDocumentedReturnType() &&
3273 isFunction() && hasDocumentation())
3275 warn_doc_error(getDefFileName(),getDefLine(),
3276 "return type of member %s is not documented",
3277 qPrint(qualifiedName()));
3282 bool MemberDef::isFriendClass() const
3284 return (isFriend() &&
3285 (m_impl->type=="friend class" || m_impl->type=="friend struct" ||
3286 m_impl->type=="friend union"));
3289 bool MemberDef::isDocumentedFriendClass() const
3292 QCString baseName=name();
3293 int i=baseName.find('<');
3294 if (i!=-1) baseName=baseName.left(i);
3295 return (isFriendClass() &&
3296 (fcd=getClass(baseName)) && fcd->isLinkable());
3299 bool MemberDef::isDeleted() const
3301 return m_impl->defArgList && m_impl->defArgList->isDeleted;
3304 bool MemberDef::hasDocumentation() const
3306 return Definition::hasDocumentation() ||
3307 (m_impl->mtype==MemberType_Enumeration && m_impl->docEnumValues) || // has enum values
3308 (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments
3312 bool MemberDef::hasUserDocumentation() const
3314 bool hasDocs = Definition::hasUserDocumentation();
3320 void MemberDef::setMemberGroup(MemberGroup *grp)
3322 m_impl->memberGroup = grp;
3325 bool MemberDef::visibleMemberGroup(bool hideNoHeader)
3327 return m_impl->memberGroup!=0 &&
3328 (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]");
3331 QCString MemberDef::getScopeString() const
3334 if (getClassDef()) result=getClassDef()->displayName();
3335 else if (getNamespaceDef()) result=getNamespaceDef()->displayName();
3340 static QCString escapeAnchor(const QCString &anchor)
3343 int l = anchor.length(),i;
3346 char c = anchor.at(i);
3347 if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
3353 static char hexStr[]="0123456789ABCDEF";
3354 char escChar[]={ '_', 0, 0, 0 };
3355 escChar[1]=hexStr[c>>4];
3356 escChar[2]=hexStr[c&0xf];
3364 void MemberDef::setAnchor()
3366 QCString memAnchor = name();
3367 if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
3369 memAnchor.prepend(definition()); // actually the method name is now included
3370 // twice, which is silly, but we keep it this way for backward
3373 // include number of template arguments as well,
3374 // to distinguish between two template
3375 // specializations that only differ in the template parameters.
3376 if (m_impl->tArgList)
3379 qsnprintf(buf,20,"%d:",m_impl->tArgList->count());
3381 memAnchor.prepend(buf);
3384 // convert to md5 hash
3386 QCString sigStr(33);
3387 MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig);
3388 //printf("memAnchor=%s\n",memAnchor.data());
3389 MD5SigToString(md5_sig,sigStr.rawData(),33);
3390 m_impl->anc = "a"+sigStr;
3393 void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri,
3394 const QCString &fileName,int startLine,
3395 bool hasDocs,MemberDef *member)
3397 //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data());
3399 m_impl->grouppri=pri;
3400 m_impl->groupFileName=fileName;
3401 m_impl->groupStartLine=startLine;
3402 m_impl->groupHasDocs=hasDocs;
3403 m_impl->groupMember=member;
3404 m_isLinkableCached = 0;
3407 void MemberDef::setEnumScope(MemberDef *md,bool livesInsideEnum)
3409 m_impl->enumScope=md;
3410 m_impl->livesInsideEnum=livesInsideEnum;
3411 if (md->getGroupDef())
3413 m_impl->group=md->getGroupDef();
3414 m_impl->grouppri=md->getGroupPri();
3415 m_impl->groupFileName=md->getGroupFileName();
3416 m_impl->groupStartLine=md->getGroupStartLine();
3417 m_impl->groupHasDocs=md->getGroupHasDocs();
3418 m_isLinkableCached = 0;
3422 void MemberDef::setMemberClass(ClassDef *cd)
3424 m_impl->classDef=cd;
3425 m_isLinkableCached = 0;
3426 m_isConstructorCached = 0;
3430 void MemberDef::setNamespace(NamespaceDef *nd)
3436 MemberDef *MemberDef::createTemplateInstanceMember(
3437 ArgumentList *formalArgs,ArgumentList *actualArgs)
3439 //printf(" Member %s %s %s\n",typeString(),name().data(),argsString());
3440 ArgumentList *actualArgList = 0;
3441 if (m_impl->defArgList)
3443 actualArgList = m_impl->defArgList->deepCopy();
3445 // replace formal arguments with actuals
3446 ArgumentListIterator ali(*actualArgList);
3448 for (;(arg=ali.current());++ali)
3450 arg->type = substituteTemplateArgumentsInString(arg->type,formalArgs,actualArgs);
3452 actualArgList->trailingReturnType =
3453 substituteTemplateArgumentsInString(actualArgList->trailingReturnType,formalArgs,actualArgs);
3456 QCString methodName=name();
3457 if (methodName.left(9)=="operator ") // conversion operator
3459 methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs);
3462 MemberDef *imd = new MemberDef(
3463 getDefFileName(),getDefLine(),getDefColumn(),
3464 substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs),
3466 substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs),
3467 m_impl->exception, m_impl->prot,
3468 m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0
3470 imd->setArgumentList(actualArgList);
3471 imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs));
3472 imd->setBodyDef(getBodyDef());
3473 imd->setBodySegment(getStartBodyLine(),getEndBodyLine());
3474 //imd->setBodyMember(this);
3476 // TODO: init other member variables (if needed).
3477 // TODO: reimplemented info
3481 bool MemberDef::hasOneLineInitializer() const
3483 //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
3484 // name().data(),m_impl->initializer.data(),m_impl->initLines,
3485 // m_impl->maxInitLines,m_impl->userInitLines);
3486 return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
3487 ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
3490 bool MemberDef::hasMultiLineInitializer() const
3492 //printf("initLines=%d userInitLines=%d maxInitLines=%d\n",
3493 // initLines,userInitLines,maxInitLines);
3494 return m_impl->initLines>0 &&
3495 ((m_impl->initLines<m_impl->maxInitLines && m_impl->userInitLines==-1) // implicitly enabled
3496 || m_impl->initLines<m_impl->userInitLines // explicitly enabled
3500 void MemberDef::setInitializer(const char *initializer)
3502 m_impl->initializer=initializer;
3503 int l=m_impl->initializer.length();
3505 while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
3506 m_impl->initializer=m_impl->initializer.left(p+1);
3507 m_impl->initLines=m_impl->initializer.contains('\n');
3508 //printf("%s::setInitializer(%s)\n",name().data(),m_impl->initializer.data());
3511 void MemberDef::addListReference(Definition *)
3513 static bool optimizeOutputForC = Config_getBool(OPTIMIZE_OUTPUT_FOR_C);
3514 //static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
3515 //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
3516 //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
3517 SrcLangExt lang = getLanguage();
3519 if (!isLinkableInProject()) return;
3521 if (optimizeOutputForC)
3523 memLabel=theTranslator->trGlobal(TRUE,TRUE);
3525 else if (lang==SrcLangExt_Fortran)
3527 memLabel=theTranslator->trSubprogram(TRUE,TRUE);
3531 memLabel=theTranslator->trMember(TRUE,TRUE);
3533 QCString memName = name();
3534 Definition *pd=getOuterScope();
3535 QCString pdName = pd->definitionType()==Definition::TypeClass ?
3536 ((ClassDef*)pd)->displayName() : pd->name();
3537 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
3540 /* && commented out as a result of bug 597016
3542 (!hideScopeNames && // there is a scope
3543 pd && pd!=Doxygen::globalScope) // and we can show it
3545 (pd=getClassDef()) // it's a class so we
3546 // show the scope anyway
3553 memName = "[" + pd->name() + " " + name() + "]";
3557 if (pd!=Doxygen::globalScope) memName.prepend(pdName+sep);
3558 memArgs = argsString();
3561 QList<ListItemInfo> *xrefItems = xrefListItems();
3564 addRefItem(xrefItems,
3565 qualifiedName()+argsString(), // argsString is needed for overloaded functions (see bug 609624)
3567 getOutputFileBase()+"#"+anchor(),memName,memArgs,pd);
3571 MemberList *MemberDef::getSectionList(Definition *d) const
3574 sprintf(key,"%p",d);
3575 return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0;
3578 void MemberDef::setSectionList(Definition *d, MemberList *sl)
3580 //printf("MemberDef::setSectionList(%p,%p) name=%s\n",d,sl,name().data());
3582 sprintf(key,"%p",d);
3583 if (m_impl->classSectionSDict==0)
3585 m_impl->classSectionSDict = new SDict<MemberList>(7);
3587 m_impl->classSectionSDict->append(key,sl);
3590 Specifier MemberDef::virtualness(int count) const
3594 warn(getDefFileName(),getDefLine(),
3595 "Internal inconsistency: recursion detected in overload relation for member %s!"
3600 Specifier v = m_impl->virt;
3601 MemberDef *rmd = reimplements();
3602 while (rmd && v==Normal)
3604 v = rmd->virtualness(count+1)==Normal ? Normal : Virtual;
3605 rmd = rmd->reimplements();
3610 void MemberDef::writeTagFile(FTextStream &tagFile)
3612 if (!isLinkableInProject()) return;
3613 tagFile << " <member kind=\"";
3614 switch (m_impl->mtype)
3616 case MemberType_Define: tagFile << "define"; break;
3617 case MemberType_EnumValue: tagFile << "enumvalue"; break;
3618 case MemberType_Property: tagFile << "property"; break;
3619 case MemberType_Event: tagFile << "event"; break;
3620 case MemberType_Variable: tagFile << "variable"; break;
3621 case MemberType_Typedef: tagFile << "typedef"; break;
3622 case MemberType_Enumeration: tagFile << "enumeration"; break;
3623 case MemberType_Function: tagFile << "function"; break;
3624 case MemberType_Signal: tagFile << "signal"; break;
3625 case MemberType_Friend: tagFile << "friend"; break;
3626 case MemberType_DCOP: tagFile << "dcop"; break;
3627 case MemberType_Slot: tagFile << "slot"; break;
3628 case MemberType_Interface: tagFile << "interface"; break;
3629 case MemberType_Service: tagFile << "service"; break;
3631 if (m_impl->prot!=Public)
3633 tagFile << "\" protection=\"";
3634 if (m_impl->prot==Protected) tagFile << "protected";
3635 else if (m_impl->prot==Package) tagFile << "package";
3636 else /* Private */ tagFile << "private";
3638 if (m_impl->virt!=Normal)
3640 tagFile << "\" virtualness=\"";
3641 if (m_impl->virt==Virtual) tagFile << "virtual";
3642 else /* Pure */ tagFile << "pure";
3646 tagFile << "\" static=\"yes";
3648 tagFile << "\">" << endl;
3649 if (typeString()!=QCString("@"))
3651 tagFile << " <type>" << convertToXML(typeString()) << "</type>" << endl;
3653 tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
3654 tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
3655 tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
3656 QCString idStr = id();
3657 if (!idStr.isEmpty())
3659 tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
3661 tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
3664 MemberList *fmdl=m_impl->enumFields;
3667 MemberListIterator mli(*fmdl);
3669 for (mli.toFirst();(fmd=mli.current());++mli)
3671 if (!fmd->isReference())
3673 tagFile << " <enumvalue file=\"" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension);
3674 tagFile << "\" anchor=\"" << convertToXML(fmd->anchor());
3675 QCString idStr = fmd->id();
3676 if (!idStr.isEmpty())
3678 tagFile << "\" clangid=\"" << convertToXML(idStr);
3680 tagFile << "\">" << convertToXML(fmd->name()) << "</enumvalue>" << endl;
3685 writeDocAnchorsToTagFile(tagFile);
3686 tagFile << " </member>" << endl;
3689 void MemberDef::_computeIsConstructor()
3691 m_isConstructorCached=1; // FALSE
3692 if (m_impl->classDef)
3694 if (m_impl->isDMember) // for D
3696 m_isConstructorCached = name()=="this" ? 2 : 1;
3699 else if (getLanguage()==SrcLangExt_PHP) // for PHP
3701 m_isConstructorCached = name()=="__construct" ? 2 : 1;
3704 else if (name()=="__init__" &&
3705 getLanguage()==SrcLangExt_Python) // for Python
3707 m_isConstructorCached = 2; // TRUE
3710 else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
3712 m_isConstructorCached = name()=="constructor" ? 2 : 1;
3715 else // for other languages
3717 QCString locName = m_impl->classDef->localName();
3718 int i=locName.find('<');
3719 if (i==-1) // not a template class
3721 m_isConstructorCached = name()==locName ? 2 : 1;
3725 m_isConstructorCached = name()==locName.left(i) ? 2 : 1;
3732 bool MemberDef::isConstructor() const
3734 if (m_isConstructorCached==0)
3736 MemberDef *that = (MemberDef*)this;
3737 that->_computeIsConstructor();
3739 ASSERT(m_isConstructorCached>0);
3740 return m_isConstructorCached==2;
3744 void MemberDef::_computeIsDestructor()
3747 if (m_impl->isDMember) // for D
3749 isDestructor = name()=="~this";
3751 else if (getLanguage()==SrcLangExt_PHP) // for PHP
3753 isDestructor = name()=="__destruct";
3755 else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
3757 isDestructor = name()=="destructor";
3759 else if (name()=="__del__" &&
3760 getLanguage()==SrcLangExt_Python) // for Python
3764 else // other languages
3767 (name().find('~')!=-1 || name().find('!')!=-1) // The ! is for C++/CLI
3768 && name().find("operator")==-1;
3770 m_isDestructorCached = isDestructor ? 2 : 1;
3773 bool MemberDef::isDestructor() const
3775 if (m_isDestructorCached==0)
3777 MemberDef *that=(MemberDef*)this;
3778 that->_computeIsDestructor();
3780 ASSERT(m_isDestructorCached>0);
3781 return m_isDestructorCached==2;
3784 void MemberDef::writeEnumDeclaration(OutputList &typeDecl,
3785 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd)
3789 MemberList *fmdl=m_impl->enumFields;
3790 uint numVisibleEnumValues=0;
3793 MemberListIterator mli(*fmdl);
3795 for (mli.toFirst();(fmd=mli.current());++mli)
3797 if (fmd->isBriefSectionVisible()) numVisibleEnumValues++;
3800 if (numVisibleEnumValues==0 && !isBriefSectionVisible())
3805 QCString n = name();
3806 int i=n.findRev("::");
3807 if (i!=-1) n=n.right(n.length()-i-2); // strip scope (TODO: is this needed?)
3808 if (n[0]!='@') // not an anonymous enum
3810 if (isLinkableInProject() || hasDocumentedEnumValues())
3812 //_writeTagData(compoundType);
3813 _addToSearchIndex();
3814 writeLink(typeDecl,cd,nd,fd,gd);
3818 typeDecl.startBold();
3822 typeDecl.writeChar(' ');
3824 if (!m_impl->enumBaseType.isEmpty())
3826 typeDecl.writeChar(':');
3827 typeDecl.writeChar(' ');
3828 typeDecl.docify(m_impl->enumBaseType);
3829 typeDecl.writeChar(' ');
3832 uint enumValuesPerLine = (uint)Config_getInt(ENUM_VALUES_PER_LINE);
3833 if (numVisibleEnumValues>0 && enumValuesPerLine>0)
3835 typeDecl.docify("{ ");
3838 MemberListIterator mli(*fmdl);
3839 MemberDef *fmd=mli.current();
3840 bool fmdVisible = fmd ? fmd->isBriefSectionVisible() : TRUE;
3845 /* in html we start a new line after a number of items */
3846 if (numVisibleEnumValues>enumValuesPerLine
3847 && (enumMemCount%enumValuesPerLine)==0
3850 typeDecl.pushGeneratorState();
3851 typeDecl.disableAllBut(OutputGenerator::Html);
3852 typeDecl.enable(OutputGenerator::Latex);
3853 typeDecl.lineBreak();
3854 typeDecl.disable(OutputGenerator::Latex);
3855 typeDecl.writeString("  ");
3856 typeDecl.popGeneratorState();
3859 if (fmd->hasDocumentation()) // enum value has docs
3861 //fmd->_writeTagData(compoundType);
3862 fmd->_addToSearchIndex();
3863 fmd->writeLink(typeDecl,cd,nd,fd,gd);
3865 else // no docs for this enum value
3867 typeDecl.startBold();
3868 typeDecl.docify(fmd->name());
3871 if (fmd->hasOneLineInitializer()) // enum value has initializer
3873 //typeDecl.writeString(" = ");
3874 typeDecl.writeString(" ");
3875 typeDecl.parseText(fmd->initializer());
3879 bool prevVisible = fmdVisible;
3882 if (fmd && (fmdVisible=fmd->isBriefSectionVisible()))
3884 typeDecl.writeString(", ");
3888 typeDecl.disable(OutputGenerator::Man);
3889 typeDecl.writeString("\n"); // to prevent too long lines in LaTeX
3890 typeDecl.enable(OutputGenerator::Man);
3894 if (numVisibleEnumValues>enumValuesPerLine)
3896 typeDecl.pushGeneratorState();
3897 typeDecl.disableAllBut(OutputGenerator::Html);
3898 typeDecl.lineBreak();
3899 typeDecl.popGeneratorState();
3902 typeDecl.docify(" }");
3906 void MemberDef::setArgumentList(ArgumentList *al)
3908 if (m_impl->defArgList) delete m_impl->defArgList;
3909 m_impl->defArgList = al;
3912 void MemberDef::setDeclArgumentList(ArgumentList *al)
3914 if (m_impl->declArgList) delete m_impl->declArgList;
3915 m_impl->declArgList = al;
3918 void MemberDef::setTypeConstraints(ArgumentList *al)
3921 if (m_impl->typeConstraints) delete m_impl->typeConstraints;
3922 m_impl->typeConstraints = new ArgumentList;
3923 m_impl->typeConstraints->setAutoDelete(TRUE);
3924 ArgumentListIterator ali(*al);
3926 for (;(a=ali.current());++ali)
3928 m_impl->typeConstraints->append(new Argument(*a));
3932 void MemberDef::setType(const char *t)
3937 void MemberDef::setAccessorType(ClassDef *cd,const char *t)
3939 m_impl->accessorClass = cd;
3940 m_impl->accessorType = t;
3943 ClassDef *MemberDef::accessorClass() const
3945 return m_impl->accessorClass;
3948 void MemberDef::findSectionsInDocumentation()
3950 docFindSections(documentation(),this,0,docFile());
3953 void MemberDef::enableCallGraph(bool e)
3955 m_impl->hasCallGraph=e;
3956 if (e) Doxygen::parseSourcesNeeded = TRUE;
3959 void MemberDef::enableCallerGraph(bool e)
3961 m_impl->hasCallerGraph=e;
3962 if (e) Doxygen::parseSourcesNeeded = TRUE;
3966 bool MemberDef::protectionVisible() const
3968 return m_impl->prot==Public ||
3969 (m_impl->prot==Private && Config_getBool(EXTRACT_PRIVATE)) ||
3970 (m_impl->prot==Protected && Config_getBool(EXTRACT_PROTECTED)) ||
3971 (m_impl->prot==Package && Config_getBool(EXTRACT_PACKAGE));
3976 void MemberDef::setInbodyDocumentation(const char *docs,
3977 const char *docFile,int docLine)
3979 m_impl->inbodyDocs = docs;
3980 m_impl->inbodyDocs = m_impl->inbodyDocs.stripWhiteSpace();
3981 m_impl->inbodyLine = docLine;
3982 m_impl->inbodyFile = docFile;
3986 bool MemberDef::isObjCMethod() const
3988 if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE;
3992 bool MemberDef::isObjCProperty() const
3994 if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isProperty()) return TRUE;
3998 QCString MemberDef::qualifiedName() const
4003 if (isStatic()) qm="+"; else qm="-";
4005 qm+=m_impl->classDef->name()+" ";
4010 else if (m_impl->enumScope && m_impl->enumScope->isStrong())
4012 return m_impl->enumScope->qualifiedName()+
4013 getLanguageSpecificSeparator(getLanguage())+
4018 return Definition::qualifiedName();
4022 void MemberDef::setTagInfo(TagInfo *ti)
4026 //printf("%s: Setting tag name=%s anchor=%s\n",name().data(),ti->tagName.data(),ti->anchor.data());
4027 m_impl->anc=ti->anchor;
4028 setReference(ti->tagName);
4029 m_impl->explicitOutputFileBase = stripExtension(ti->fileName);
4033 QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const
4038 if (isStatic()) qm="+ "; else qm="- ";
4041 if (!localLink) // link to method of same class
4044 qm+=m_impl->classDef->name();
4050 const char *MemberDef::declaration() const
4052 return m_impl->decl;
4055 const char *MemberDef::definition() const
4060 const char *MemberDef::extraTypeChars() const
4062 return m_impl->extraTypeChars;
4065 const char *MemberDef::typeString() const
4067 return m_impl->type;
4070 const char *MemberDef::argsString() const
4072 return m_impl->args;
4075 const char *MemberDef::excpString() const
4077 return m_impl->exception;
4080 const char *MemberDef::bitfieldString() const
4082 return m_impl->bitfields;
4085 const QCString &MemberDef::initializer() const
4087 return m_impl->initializer;
4090 int MemberDef::initializerLines() const
4092 return m_impl->initLines;
4095 uint64 MemberDef::getMemberSpecifiers() const
4097 return m_impl->memSpec;
4100 ClassDef *MemberDef::getClassDef() const
4102 return m_impl->classDef;
4105 FileDef *MemberDef::getFileDef() const
4107 return m_impl->fileDef;
4110 NamespaceDef* MemberDef::getNamespaceDef() const
4112 return m_impl->nspace;
4115 const char *MemberDef::getReadAccessor() const
4117 return m_impl->read;
4120 const char *MemberDef::getWriteAccessor() const
4122 return m_impl->write;
4125 GroupDef *MemberDef::getGroupDef() const
4127 return m_impl->group;
4130 Grouping::GroupPri_t MemberDef::getGroupPri() const
4132 return m_impl->grouppri;
4135 const char *MemberDef::getGroupFileName() const
4137 return m_impl->groupFileName;
4140 int MemberDef::getGroupStartLine() const
4142 return m_impl->groupStartLine;
4145 bool MemberDef::getGroupHasDocs() const
4147 return m_impl->groupHasDocs;
4150 Protection MemberDef::protection() const
4152 return m_impl->prot;
4155 MemberType MemberDef::memberType() const
4157 return m_impl->mtype;
4160 bool MemberDef::isSignal() const
4162 return m_impl->mtype==MemberType_Signal;
4165 bool MemberDef::isSlot() const
4167 return m_impl->mtype==MemberType_Slot;
4170 bool MemberDef::isVariable() const
4172 return m_impl->mtype==MemberType_Variable;
4175 bool MemberDef::isEnumerate() const
4177 return m_impl->mtype==MemberType_Enumeration;
4180 bool MemberDef::isEnumValue() const
4182 return m_impl->mtype==MemberType_EnumValue;
4185 bool MemberDef::isTypedef() const
4187 return m_impl->mtype==MemberType_Typedef;
4190 bool MemberDef::isFunction() const
4192 return m_impl->mtype==MemberType_Function;
4195 bool MemberDef::isFunctionPtr() const
4197 return m_impl->mtype==MemberType_Variable && QCString(argsString()).find(")(")!=-1;
4200 bool MemberDef::isDefine() const
4202 return m_impl->mtype==MemberType_Define;
4205 bool MemberDef::isFriend() const
4207 return m_impl->mtype==MemberType_Friend;
4210 bool MemberDef::isDCOP() const
4212 return m_impl->mtype==MemberType_DCOP;
4215 bool MemberDef::isProperty() const
4217 return m_impl->mtype==MemberType_Property;
4220 bool MemberDef::isEvent() const
4222 return m_impl->mtype==MemberType_Event;
4225 bool MemberDef::isRelated() const
4227 return m_impl->related == Related;
4230 bool MemberDef::isForeign() const
4232 return m_impl->related == Foreign;
4235 bool MemberDef::isStatic() const
4237 return m_impl->stat;
4240 bool MemberDef::isInline() const
4242 return (m_impl->memSpec&Entry::Inline)!=0;
4245 bool MemberDef::isExplicit() const
4247 return (m_impl->memSpec&Entry::Explicit)!=0;
4250 bool MemberDef::isMutable() const
4252 return (m_impl->memSpec&Entry::Mutable)!=0;
4255 bool MemberDef::isGettable() const
4257 return (m_impl->memSpec&Entry::Gettable)!=0;
4260 bool MemberDef::isPrivateGettable() const
4262 return (m_impl->memSpec&Entry::PrivateGettable)!=0;
4265 bool MemberDef::isProtectedGettable() const
4267 return (m_impl->memSpec&Entry::ProtectedGettable)!=0;
4270 bool MemberDef::isSettable() const
4272 return (m_impl->memSpec&Entry::Settable)!=0;
4275 bool MemberDef::isPrivateSettable() const
4277 return (m_impl->memSpec&Entry::PrivateSettable)!=0;
4280 bool MemberDef::isProtectedSettable() const
4282 return (m_impl->memSpec&Entry::ProtectedSettable)!=0;
4285 bool MemberDef::isAddable() const
4287 return (m_impl->memSpec&Entry::Addable)!=0;
4290 bool MemberDef::isRemovable() const
4292 return (m_impl->memSpec&Entry::Removable)!=0;
4295 bool MemberDef::isRaisable() const
4297 return (m_impl->memSpec&Entry::Raisable)!=0;
4300 bool MemberDef::isReadable() const
4302 return (m_impl->memSpec&Entry::Readable)!=0;
4305 bool MemberDef::isWritable() const
4307 return (m_impl->memSpec&Entry::Writable)!=0;
4310 bool MemberDef::isFinal() const
4312 return (m_impl->memSpec&Entry::Final)!=0;
4315 bool MemberDef::isNew() const
4317 return (m_impl->memSpec&Entry::New)!=0;
4320 bool MemberDef::isSealed() const
4322 return (m_impl->memSpec&Entry::Sealed)!=0;
4325 bool MemberDef::isOverride() const
4327 return (m_impl->memSpec&Entry::Override)!=0;
4330 bool MemberDef::isInitonly() const
4332 return (m_impl->memSpec&Entry::Initonly)!=0;
4335 bool MemberDef::isAbstract() const
4337 return (m_impl->memSpec&Entry::Abstract)!=0;
4340 bool MemberDef::isOptional() const
4342 return (m_impl->memSpec&Entry::Optional)!=0;
4345 bool MemberDef::isRequired() const
4347 return (m_impl->memSpec&Entry::Required)!=0;
4350 bool MemberDef::isNonAtomic() const
4352 return (m_impl->memSpec&Entry::NonAtomic)!=0;
4355 bool MemberDef::isCopy() const
4357 return (m_impl->memSpec&Entry::Copy)!=0;
4360 bool MemberDef::isAssign() const
4362 return (m_impl->memSpec&Entry::Assign)!=0;
4365 bool MemberDef::isRetain() const
4367 return (m_impl->memSpec&Entry::Retain)!=0;
4370 bool MemberDef::isWeak() const
4372 return (m_impl->memSpec&Entry::Weak)!=0;
4375 bool MemberDef::isStrong() const
4377 return (m_impl->memSpec&Entry::Strong)!=0;
4380 bool MemberDef::isStrongEnumValue() const
4382 return m_impl->mtype==MemberType_EnumValue &&
4383 m_impl->enumScope &&
4384 m_impl->enumScope->isStrong();
4387 bool MemberDef::isUnretained() const
4389 return (m_impl->memSpec&Entry::Unretained)!=0;
4392 bool MemberDef::isAlias() const
4394 return (m_impl->memSpec&Entry::Alias)!=0;
4397 bool MemberDef::isDefault() const
4399 return (m_impl->memSpec&Entry::Default)!=0;
4402 bool MemberDef::isDelete() const
4404 return (m_impl->memSpec&Entry::Delete)!=0;
4407 bool MemberDef::isNoExcept() const
4409 return (m_impl->memSpec&Entry::NoExcept)!=0;
4412 bool MemberDef::isAttribute() const
4414 return (m_impl->memSpec&Entry::Attribute)!=0;
4417 bool MemberDef::isUNOProperty() const
4419 return (m_impl->memSpec&Entry::Property)!=0;
4422 bool MemberDef::isReadonly() const
4424 return (m_impl->memSpec&Entry::Readonly)!=0;
4427 bool MemberDef::isBound() const
4429 return (m_impl->memSpec&Entry::Bound)!=0;
4432 bool MemberDef::isConstrained() const
4434 return (m_impl->memSpec&Entry::Constrained)!=0;
4437 bool MemberDef::isTransient() const
4439 return (m_impl->memSpec&Entry::Transient)!=0;
4442 bool MemberDef::isMaybeVoid() const
4444 return (m_impl->memSpec&Entry::MaybeVoid)!=0;
4447 bool MemberDef::isMaybeDefault() const
4449 return (m_impl->memSpec&Entry::MaybeDefault)!=0;
4452 bool MemberDef::isMaybeAmbiguous() const
4454 return (m_impl->memSpec&Entry::MaybeAmbiguous)!=0;
4457 bool MemberDef::isPublished() const
4459 return (m_impl->memSpec&Entry::Published)!=0;
4463 bool MemberDef::isImplementation() const
4465 return m_impl->implOnly;
4468 bool MemberDef::isExternal() const
4470 return m_impl->explExt;
4473 bool MemberDef::isTemplateSpecialization() const
4475 return m_impl->tspec;
4478 bool MemberDef::hasDocumentedParams() const
4480 return m_impl->hasDocumentedParams;
4483 bool MemberDef::hasDocumentedReturnType() const
4485 return m_impl->hasDocumentedReturnType;
4488 bool MemberDef::showInCallGraph() const
4490 return isFunction() ||
4497 ClassDef *MemberDef::relatedAlso() const
4499 return m_impl->relatedAlso;
4502 bool MemberDef::hasDocumentedEnumValues() const
4504 return m_impl->docEnumValues;
4507 MemberDef *MemberDef::getAnonymousEnumType() const
4509 return m_impl->annEnumType;
4512 bool MemberDef::isDocsForDefinition() const
4514 return m_impl->docsForDefinition;
4517 MemberDef *MemberDef::getEnumScope() const
4519 return m_impl->enumScope;
4522 bool MemberDef::livesInsideEnum() const
4524 return m_impl->livesInsideEnum;
4527 MemberList *MemberDef::enumFieldList() const
4529 return m_impl->enumFields;
4532 ExampleSDict *MemberDef::getExamples() const
4534 return m_impl->exampleSDict;
4537 bool MemberDef::isPrototype() const
4539 return m_impl->proto;
4542 ArgumentList *MemberDef::argumentList() const
4544 return m_impl->defArgList;
4547 ArgumentList *MemberDef::declArgumentList() const
4549 return m_impl->declArgList;
4552 ArgumentList *MemberDef::templateArguments() const
4554 return m_impl->tArgList;
4557 QList<ArgumentList> *MemberDef::definitionTemplateParameterLists() const
4559 return m_impl->defTmpArgLists;
4562 int MemberDef::getMemberGroupId() const
4564 return m_impl->grpId;
4567 MemberGroup *MemberDef::getMemberGroup() const
4569 return m_impl->memberGroup;
4572 bool MemberDef::fromAnonymousScope() const
4574 return m_impl->annScope;
4577 bool MemberDef::anonymousDeclShown() const
4579 return m_impl->annUsed;
4582 void MemberDef::setAnonymousUsed()
4584 m_impl->annUsed = TRUE;
4587 bool MemberDef::hasCallGraph() const
4589 return m_impl->hasCallGraph;
4592 bool MemberDef::hasCallerGraph() const
4594 return m_impl->hasCallerGraph;
4597 MemberDef *MemberDef::templateMaster() const
4599 return m_impl->templateMaster;
4602 bool MemberDef::isTypedefValCached() const
4604 return m_impl->isTypedefValCached;
4607 ClassDef *MemberDef::getCachedTypedefVal() const
4609 return m_impl->cachedTypedefValue;
4612 QCString MemberDef::getCachedTypedefTemplSpec() const
4614 return m_impl->cachedTypedefTemplSpec;
4617 QCString MemberDef::getCachedResolvedTypedef() const
4619 //printf("MemberDef::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
4620 return m_impl->cachedResolvedType;
4623 MemberDef *MemberDef::memberDefinition() const
4625 return m_impl->memDef;
4628 MemberDef *MemberDef::memberDeclaration() const
4630 return m_impl->memDec;
4633 MemberDef *MemberDef::inheritsDocsFrom() const
4635 return m_impl->docProvider;
4638 MemberDef *MemberDef::getGroupAlias() const
4640 return m_impl->groupAlias;
4643 void MemberDef::setMemberType(MemberType t)
4646 m_isLinkableCached = 0;
4649 void MemberDef::setDefinition(const char *d)
4654 void MemberDef::setFileDef(FileDef *fd)
4657 m_isLinkableCached = 0;
4658 m_isConstructorCached = 0;
4659 m_isDestructorCached = 0;
4662 void MemberDef::setProtection(Protection p)
4665 m_isLinkableCached = 0;
4668 void MemberDef::setMemberSpecifiers(uint64 s)
4673 void MemberDef::mergeMemberSpecifiers(uint64 s)
4678 void MemberDef::setBitfields(const char *s)
4680 m_impl->bitfields = QCString(s).simplifyWhiteSpace();
4683 void MemberDef::setMaxInitLines(int lines)
4687 m_impl->userInitLines=lines;
4691 void MemberDef::setExplicitExternal(bool b)
4696 void MemberDef::setReadAccessor(const char *r)
4701 void MemberDef::setWriteAccessor(const char *w)
4706 void MemberDef::setTemplateSpecialization(bool b)
4711 void MemberDef::makeRelated()
4713 m_impl->related = Related;
4714 m_isLinkableCached = 0;
4717 void MemberDef::makeForeign()
4719 m_impl->related = Foreign;
4720 m_isLinkableCached = 0;
4723 void MemberDef::setHasDocumentedParams(bool b)
4725 m_impl->hasDocumentedParams = b;
4728 void MemberDef::setHasDocumentedReturnType(bool b)
4730 m_impl->hasDocumentedReturnType = b;
4733 void MemberDef::setInheritsDocsFrom(MemberDef *md)
4735 m_impl->docProvider = md;
4738 void MemberDef::setArgsString(const char *as)
4743 void MemberDef::setRelatedAlso(ClassDef *cd)
4745 m_impl->relatedAlso=cd;
4748 void MemberDef::setEnumClassScope(ClassDef *cd)
4750 m_impl->classDef = cd;
4751 m_isLinkableCached = 0;
4752 m_isConstructorCached = 0;
4755 void MemberDef::setDocumentedEnumValues(bool value)
4757 m_impl->docEnumValues=value;
4760 void MemberDef::setAnonymousEnumType(MemberDef *md)
4762 m_impl->annEnumType = md;
4765 void MemberDef::setPrototype(bool p)
4770 void MemberDef::setMemberGroupId(int id)
4775 void MemberDef::makeImplementationDetail()
4777 m_impl->implOnly=TRUE;
4780 void MemberDef::setFromAnonymousScope(bool b)
4785 void MemberDef::setFromAnonymousMember(MemberDef *m)
4790 MemberDef *MemberDef::fromAnonymousMember() const
4792 return m_impl->annMemb;
4795 void MemberDef::setTemplateMaster(MemberDef *mt)
4797 m_impl->templateMaster=mt;
4798 m_isLinkableCached = 0;
4801 void MemberDef::setDocsForDefinition(bool b)
4803 m_impl->docsForDefinition = b;
4806 void MemberDef::setGroupAlias(MemberDef *md)
4808 m_impl->groupAlias = md;
4811 void MemberDef::invalidateTypedefValCache()
4813 m_impl->isTypedefValCached=FALSE;
4816 void MemberDef::setMemberDefinition(MemberDef *md)
4821 void MemberDef::setMemberDeclaration(MemberDef *md)
4826 ClassDef *MemberDef::category() const
4828 return m_impl->category;
4831 void MemberDef::setCategory(ClassDef *def)
4833 m_impl->category = def;
4836 MemberDef *MemberDef::categoryRelation() const
4838 return m_impl->categoryRelation;
4841 void MemberDef::setCategoryRelation(MemberDef *md)
4843 m_impl->categoryRelation = md;
4846 void MemberDef::setEnumBaseType(const QCString &type)
4848 m_impl->enumBaseType = type;
4851 QCString MemberDef::enumBaseType() const
4853 return m_impl->enumBaseType;
4857 void MemberDef::cacheTypedefVal(ClassDef*val, const QCString & templSpec, const QCString &resolvedType)
4859 m_impl->isTypedefValCached=TRUE;
4860 m_impl->cachedTypedefValue=val;
4861 m_impl->cachedTypedefTemplSpec=templSpec;
4862 m_impl->cachedResolvedType=resolvedType;
4863 //printf("MemberDef::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
4866 void MemberDef::copyArgumentNames(MemberDef *bmd)
4869 ArgumentList *arguments = bmd->argumentList();
4870 if (m_impl->defArgList && arguments)
4872 ArgumentListIterator aliDst(*m_impl->defArgList);
4873 ArgumentListIterator aliSrc(*arguments);
4874 Argument *argDst, *argSrc;
4875 for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
4877 argDst->name = argSrc->name;
4882 ArgumentList *arguments = bmd->declArgumentList();
4883 if (m_impl->declArgList && arguments)
4885 ArgumentListIterator aliDst(*m_impl->declArgList);
4886 ArgumentListIterator aliSrc(*arguments);
4887 Argument *argDst, *argSrc;
4888 for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
4890 argDst->name = argSrc->name;
4896 static void invalidateCachedTypesInArgumentList(ArgumentList *al)
4900 ArgumentListIterator ali(*al);
4902 for (ali.toFirst();(a=ali.current());++ali)
4904 a->canType.resize(0);
4909 void MemberDef::invalidateCachedArgumentTypes()
4911 invalidateCachedTypesInArgumentList(m_impl->defArgList);
4912 invalidateCachedTypesInArgumentList(m_impl->declArgList);
4915 void MemberDef::addFlowKeyWord()
4920 int MemberDef::numberOfFlowKeyWords()
4922 return number_of_flowkw;
4927 QCString MemberDef::displayName(bool) const
4929 return Definition::name();
4932 void MemberDef::_addToSearchIndex()
4934 // write search index info
4935 if (Doxygen::searchIndex && isLinkableInProject())
4937 Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
4938 QCString ln=localName(),qn=qualifiedName();
4939 Doxygen::searchIndex->addWord(ln,TRUE);
4942 Doxygen::searchIndex->addWord(qn,TRUE);
4945 Doxygen::searchIndex->addWord(getClassDef()->displayName(),TRUE);
4947 else if (getNamespaceDef())
4949 Doxygen::searchIndex->addWord(getNamespaceDef()->displayName(),TRUE);
4959 static void transferArgumentDocumentation(ArgumentList *decAl,ArgumentList *defAl)
4963 ArgumentListIterator decAli(*decAl);
4964 ArgumentListIterator defAli(*defAl);
4965 Argument *decA,*defA;
4966 for (decAli.toFirst(),defAli.toFirst();
4967 (decA=decAli.current()) && (defA=defAli.current());
4970 //printf("Argument decA->name=%s (doc=%s) defA->name=%s (doc=%s)\n",
4971 // decA->name.data(),decA->docs.data(),
4972 // defA->name.data(),defA->docs.data()
4974 if (decA->docs.isEmpty() && !defA->docs.isEmpty())
4976 decA->docs = defA->docs.copy();
4978 else if (defA->docs.isEmpty() && !decA->docs.isEmpty())
4980 defA->docs = decA->docs.copy();
4986 void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef)
4988 //printf("mdec=%s isPrototype()=%d\n",mdec->name().data(),mdec->isPrototype());
4990 (mdef->isFunction() && !mdef->isStatic() && !mdef->isPrototype()) ||
4991 (mdef->isVariable() && !mdef->isExternal() && !mdef->isStatic())
4994 //printf("mdef=(%p,%s) mdec=(%p,%s)\n",
4995 // mdef, mdef ? mdef->name().data() : "",
4996 // mdec, mdec ? mdec->name().data() : "");
4998 ArgumentList *mdefAl = mdef->argumentList();
4999 ArgumentList *mdecAl = mdec->argumentList();
5000 if (matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl,
5001 mdec->getOuterScope(),mdec->getFileDef(),mdecAl,
5006 //printf("Found member %s: definition in %s (doc=`%s') and declaration in %s (doc=`%s')\n",
5007 // mn->memberName(),
5008 // mdef->getFileDef()->name().data(),mdef->documentation().data(),
5009 // mdec->getFileDef()->name().data(),mdec->documentation().data()
5012 // first merge argument documentation
5013 transferArgumentDocumentation(mdecAl,mdefAl);
5015 /* copy documentation between function definition and declaration */
5016 if (!mdec->briefDescription().isEmpty())
5018 mdef->setBriefDescription(mdec->briefDescription(),mdec->briefFile(),mdec->briefLine());
5020 else if (!mdef->briefDescription().isEmpty())
5022 mdec->setBriefDescription(mdef->briefDescription(),mdef->briefFile(),mdef->briefLine());
5024 if (!mdef->documentation().isEmpty())
5026 //printf("transferring docs mdef->mdec (%s->%s)\n",mdef->argsString(),mdec->argsString());
5027 mdec->setDocumentation(mdef->documentation(),mdef->docFile(),mdef->docLine());
5028 mdec->setDocsForDefinition(mdef->isDocsForDefinition());
5031 ArgumentList *mdefAlComb = new ArgumentList;
5032 stringToArgumentList(mdef->argsString(),mdefAlComb);
5033 transferArgumentDocumentation(mdefAl,mdefAlComb);
5034 mdec->setArgumentList(mdefAlComb);
5037 else if (!mdec->documentation().isEmpty())
5039 //printf("transferring docs mdec->mdef (%s->%s)\n",mdec->argsString(),mdef->argsString());
5040 mdef->setDocumentation(mdec->documentation(),mdec->docFile(),mdec->docLine());
5041 mdef->setDocsForDefinition(mdec->isDocsForDefinition());
5044 ArgumentList *mdecAlComb = new ArgumentList;
5045 stringToArgumentList(mdec->argsString(),mdecAlComb);
5046 transferArgumentDocumentation(mdecAl,mdecAlComb);
5047 mdef->setDeclArgumentList(mdecAlComb);
5050 if (!mdef->inbodyDocumentation().isEmpty())
5052 mdec->setInbodyDocumentation(mdef->inbodyDocumentation(),mdef->inbodyFile(),mdef->inbodyLine());
5054 else if (!mdec->inbodyDocumentation().isEmpty())
5056 mdef->setInbodyDocumentation(mdec->inbodyDocumentation(),mdec->inbodyFile(),mdec->inbodyLine());
5058 if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
5060 //printf("body mdec->mdef %d-%d\n",mdec->getStartBodyLine(),mdef->getEndBodyLine());
5061 mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine());
5062 mdef->setBodyDef(mdec->getBodyDef());
5063 //mdef->setBodyMember(mdec);
5065 else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
5067 //printf("body mdef->mdec %d-%d\n",mdef->getStartBodyLine(),mdec->getEndBodyLine());
5068 mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine());
5069 mdec->setBodyDef(mdef->getBodyDef());
5070 //mdec->setBodyMember(mdef);
5072 mdec->mergeMemberSpecifiers(mdef->getMemberSpecifiers());
5073 mdef->mergeMemberSpecifiers(mdec->getMemberSpecifiers());
5077 if (mdec->getGroupDef()==0 && mdef->getGroupDef()!=0)
5079 mdec->setGroupDef(mdef->getGroupDef(),
5080 mdef->getGroupPri(),
5083 mdef->hasDocumentation(),
5087 else if (mdef->getGroupDef()==0 && mdec->getGroupDef()!=0)
5089 mdef->setGroupDef(mdec->getGroupDef(),
5090 mdec->getGroupPri(),
5093 mdec->hasDocumentation(),
5099 mdec->mergeRefItems(mdef);
5100 mdef->mergeRefItems(mdec);
5102 mdef->setMemberDeclaration(mdec);
5103 mdec->setMemberDefinition(mdef);
5105 mdef->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
5106 mdef->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
5107 mdec->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
5108 mdec->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
5113 QCString MemberDef::briefDescription(bool abbr) const
5115 if (m_impl->templateMaster)
5117 return m_impl->templateMaster->briefDescription(abbr);
5121 return Definition::briefDescription(abbr);
5125 QCString MemberDef::documentation() const
5127 if (m_impl->templateMaster)
5129 return m_impl->templateMaster->documentation();
5133 return Definition::documentation();
5137 const ArgumentList *MemberDef::typeConstraints() const
5139 return m_impl->typeConstraints;
5142 bool MemberDef::isFriendToHide() const
5144 static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
5145 bool isFriendToHide = hideFriendCompounds &&
5146 (m_impl->type=="friend class" ||
5147 m_impl->type=="friend struct" ||
5148 m_impl->type=="friend union");
5149 return isFriendToHide;
5152 bool MemberDef::isNotFriend() const
5154 return !(isFriend() && isFriendToHide());
5157 bool MemberDef::isFunctionOrSignalSlot() const
5159 return isFunction() || isSlot() || isSignal();
5162 bool MemberDef::isRelatedOrFriend() const
5164 return isRelated() || isForeign() || (isFriend() && !isFriendToHide());
5167 bool MemberDef::isReference() const
5169 return Definition::isReference() ||
5170 (m_impl->templateMaster && m_impl->templateMaster->isReference());