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.endParameterType
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);
164 bool docbookOn = ol.isEnabled(OutputGenerator::Docbook);
167 if (htmlOn) ol.enable(OutputGenerator::Html);
168 if (latexOn) ol.enable(OutputGenerator::Latex);
169 if (docbookOn) ol.enable(OutputGenerator::Docbook);
171 ol.endMemberDocName();
172 ol.startParameterList(!md->isObjCMethod());
175 ol.disable(OutputGenerator::Html);
176 ol.disable(OutputGenerator::Latex);
177 ol.disable(OutputGenerator::Docbook);
180 if (!md->isObjCMethod()) ol.docify("("); // start argument list
181 ol.endMemberDocName();
183 ol.popGeneratorState();
184 //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
190 int il=cName.find('<');
191 int ir=cName.findRev('>');
192 if (il!=-1 && ir!=-1 && ir>il)
194 cName=cName.mid(il,ir-il+1);
195 //printf("1. cName=%s\n",cName.data());
197 else if (scope->definitionType()==Definition::TypeClass && ((ClassDef*)scope)->templateArguments())
199 cName=tempArgListToString(((ClassDef*)scope)->templateArguments(),scope->getLanguage());
200 //printf("2. cName=%s\n",cName.data());
202 else // no template specifier
207 //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
210 bool paramTypeStarted=FALSE;
211 bool isDefine = md->isDefine();
212 ArgumentListIterator ali(*defArgList);
213 Argument *a=ali.current();
216 if (isDefine || first)
218 ol.startParameterType(first,0);
219 paramTypeStarted=TRUE;
222 ol.endParameterType();
223 ol.startParameterName(TRUE);
226 QRegExp re(")("),res("(.*\\*");
227 int vp=a->type.find(re);
228 int wp=a->type.find(res);
230 // use the following to put the function pointer type before the name
231 bool hasFuncPtrType=FALSE;
233 if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
235 ol.docify(a->attrib+" ");
237 if (hasFuncPtrType) // argument type is a function pointer
239 //printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data());
240 QCString n=a->type.left(vp);
241 if (hasFuncPtrType) n=a->type.left(wp);
242 if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
243 if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
244 linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n);
246 else // non-function pointer type
249 if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
252 if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
253 linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n);
258 if (paramTypeStarted)
260 ol.endParameterType();
261 paramTypeStarted=FALSE;
263 ol.startParameterName(defArgList->count()<2);
267 ol.docify(a->type.mid(wp,vp-wp));
269 if (!a->name.isEmpty() || a->type=="...") // argument has a name
271 //if (!hasFuncPtrType)
275 ol.disable(OutputGenerator::Latex);
276 ol.disable(OutputGenerator::Docbook);
277 ol.disable(OutputGenerator::Html);
278 ol.docify(" "); /* man page */
279 if (htmlOn) ol.enable(OutputGenerator::Html);
280 ol.disable(OutputGenerator::Man);
282 ol.enable(OutputGenerator::Man);
283 if (latexOn) ol.enable(OutputGenerator::Latex);
284 if (docbookOn) ol.enable(OutputGenerator::Docbook);
285 if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name);
286 ol.disable(OutputGenerator::Man);
287 ol.disable(OutputGenerator::Latex);
288 ol.disable(OutputGenerator::Docbook);
290 ol.enable(OutputGenerator::Man);
291 if (latexOn) ol.enable(OutputGenerator::Latex);
292 if (docbookOn) ol.enable(OutputGenerator::Docbook);
294 if (!a->array.isEmpty())
298 if (hasFuncPtrType) // write the part of the argument type
299 // that comes after the name
301 linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),
302 md,a->type.right(a->type.length()-vp));
304 if (!a->defval.isEmpty()) // write the default value
306 QCString n=a->defval;
307 if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
310 ol.startTypewriter();
311 linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n,FALSE,TRUE,TRUE);
319 if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
323 if (md->isObjCMethod() && a->attrib.length()>=2)
325 //printf("Found parameter keyword %s\n",a->attrib.data());
327 key=a->attrib.mid(1,a->attrib.length()-2);
328 if (key!=",") key+=":"; // for normal keywords add colon
330 ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
331 if (paramTypeStarted)
333 ol.endParameterType();
335 ol.startParameterType(FALSE,key);
336 paramTypeStarted=TRUE;
340 ol.endParameterName(FALSE,FALSE,TRUE);
345 ol.pushGeneratorState();
346 ol.disable(OutputGenerator::Html);
347 ol.disable(OutputGenerator::Latex);
348 ol.disable(OutputGenerator::Docbook);
349 if (!md->isObjCMethod()) ol.docify(")"); // end argument list
351 if (htmlOn) ol.enable(OutputGenerator::Html);
352 if (latexOn) ol.enable(OutputGenerator::Latex);
353 if (docbookOn) ol.enable(OutputGenerator::Docbook);
354 if (first) ol.startParameterName(defArgList->count()<2);
355 ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
356 ol.popGeneratorState();
357 if (md->extraTypeChars())
359 ol.docify(md->extraTypeChars());
361 if (defArgList->constSpecifier)
365 if (defArgList->volatileSpecifier)
367 ol.docify(" volatile");
369 if (defArgList->refQualifier==RefQualifierLValue)
373 else if (defArgList->refQualifier==RefQualifierRValue)
377 if (!defArgList->trailingReturnType.isEmpty())
379 linkifyText(TextGeneratorOLImpl(ol), // out
381 md->getBodyDef(), // fileScope
383 defArgList->trailingReturnType, // text
391 static void writeExceptionListImpl(
392 OutputList &ol, ClassDef *cd, MemberDef *md, QCString const& exception)
394 // this is ordinary exception spec - there must be a '('
395 //printf("exception='%s'\n",exception.data());
396 int index = exception.find('(');
399 ol.exceptionEntry(exception.left(index),false);
400 ++index; // paren in second column so skip it here
401 for (int comma = exception.find(',', index); comma!=-1; )
403 ++comma; // include comma
404 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,
405 exception.mid(index,comma-index));
406 ol.exceptionEntry(0,false);
408 comma = exception.find(',', index);
410 int close = exception.find(')', index);
413 QCString type=removeRedundantWhiteSpace(exception.mid(index,close-index));
414 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,type);
415 ol.exceptionEntry(0,true);
419 warn(md->getDefFileName(),md->getDefLine(),
420 "missing ) in exception list on member %s",qPrint(md->name()));
423 else // Java Exception
426 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,exception);
430 static void writeExceptionList(OutputList &ol, ClassDef *cd, MemberDef *md)
432 QCString exception(QCString(md->excpString()).stripWhiteSpace());
433 if ('{'==exception.at(0))
435 // this is an UNO IDL attribute - need special handling
436 int index = exception.find(';');
438 while (-1 != index) // there should be no more than 2 (set / get)
440 // omit '{' and ';' -> "set raises (...)"
441 writeExceptionListImpl(ol,cd,md,exception.mid(oldIndex,index-oldIndex));
443 index = exception.find(';',oldIndex);
445 // the rest is now just '}' - omit that
449 writeExceptionListImpl(ol,cd,md,exception);
453 static void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
455 ol.docify("template<");
456 ArgumentListIterator ali(*al);
457 Argument *a = ali.current();
463 if (a->defval.length()!=0)
466 ol.docify(a->defval);
470 if (a) ol.docify(", ");
475 //-----------------------------------------------------------------------------
476 //-----------------------------------------------------------------------------
477 //-----------------------------------------------------------------------------
484 void init(Definition *def,const char *t,const char *a,const char *e,
485 Protection p,Specifier v,bool s,Relationship r,
486 MemberType mt,const ArgumentList *tal,
487 const ArgumentList *al,const char *meta
490 ClassDef *classDef; // member of or related to
491 FileDef *fileDef; // member of file definition
492 NamespaceDef *nspace; // the namespace this member is in.
494 MemberDef *enumScope; // the enclosing scope, if this is an enum field
495 bool livesInsideEnum;
496 MemberDef *annEnumType; // the anonymous enum that is the type of this member
497 MemberList *enumFields; // enumeration fields
499 MemberDef *redefines; // the members that this member redefines
500 MemberList *redefinedBy; // the list of members that redefine this one
502 MemberDef *memDef; // member definition for this declaration
503 MemberDef *memDec; // member declaration for this definition
504 ClassDef *relatedAlso; // points to class marked by relatedAlso
506 ExampleSDict *exampleSDict; // a dictionary of all examples for quick access
508 QCString type; // return actual type
509 QCString accessorType; // return type that tell how to get to this member
510 ClassDef *accessorClass; // class that this member accesses (for anonymous types)
511 QCString args; // function arguments/variable array specifiers
512 QCString def; // member definition in code (fully qualified name)
513 QCString anc; // HTML anchor name
514 Specifier virt; // normal/virtual/pure virtual
515 Protection prot; // protection type [Public/Protected/Private]
516 QCString decl; // member declaration in class
518 QCString bitfields; // struct member bitfields
519 QCString read; // property read accessor
520 QCString write; // property write accessor
521 QCString exception; // exceptions that can be thrown
522 QCString initializer; // initializer
523 QCString extraTypeChars; // extra type info found after the argument list
524 QCString enumBaseType; // base type of the enum (C++11)
525 int initLines; // number of lines in the initializer
527 uint64 memSpec; // The specifiers present for this member
528 MemberType mtype; // returns the kind of member
529 int maxInitLines; // when the initializer will be displayed
530 int userInitLines; // result of explicit \hideinitializer or \showinitializer
533 ArgumentList *defArgList; // argument list of this member definition
534 ArgumentList *declArgList; // argument list of this member declaration
536 ArgumentList *tArgList; // template argument list of function template
537 ArgumentList *typeConstraints; // type constraints for template parameters
538 MemberDef *templateMaster;
539 QList<ArgumentList> *defTmpArgLists; // lists of template argument lists
540 // (for template functions in nested template classes)
542 QCString metaData; // Slice metadata.
544 ClassDef *cachedAnonymousType; // if the member has an anonymous compound
545 // as its type then this is computed by
546 // getClassDefOfAnonymousType() and
548 SDict<MemberList> *classSectionSDict; // not accessible
550 MemberDef *groupAlias; // Member containing the definition
551 int grpId; // group id
552 MemberGroup *memberGroup; // group's member definition
553 GroupDef *group; // group in which this member is in
554 Grouping::GroupPri_t grouppri; // priority of this definition
555 QCString groupFileName; // file where this grouping was defined
556 int groupStartLine; // line " " " " "
557 MemberDef *groupMember;
559 bool isTypedefValCached;
560 ClassDef *cachedTypedefValue;
561 QCString cachedTypedefTemplSpec;
562 QCString cachedResolvedType;
564 // inbody documentation
566 //QCString inbodyFile;
567 //QCString inbodyDocs;
569 // documentation inheritance
570 MemberDef *docProvider;
572 // to store the output file base from tag files
573 QCString explicitOutputFileBase;
576 bool implOnly; // function found in implementation but not
578 bool hasDocumentedParams;
579 bool hasDocumentedReturnType;
581 Relationship related; // relationship of this to the class
582 bool stat; // is it a static function?
583 bool proto; // is it a prototype;
584 bool docEnumValues; // is an enum with documented enum values.
585 bool annScope; // member is part of an anonymous scope
589 bool hasReferencedByRelation;
590 bool hasReferencesRelation;
591 bool explExt; // member was explicitly declared external
592 bool tspec; // member is a template specialization
593 bool groupHasDocs; // true if the entry that caused the grouping was documented
594 bool docsForDefinition; // TRUE => documentation block is put before
596 // FALSE => block is put before declaration.
598 MemberDef *categoryRelation;
601 MemberDefImpl::MemberDefImpl() :
610 classSectionSDict(0),
616 MemberDefImpl::~MemberDefImpl()
623 delete typeConstraints;
624 delete defTmpArgLists;
625 delete classSectionSDict;
629 void MemberDefImpl::init(Definition *def,
630 const char *t,const char *a,const char *e,
631 Protection p,Specifier v,bool s,Relationship r,
632 MemberType mt,const ArgumentList *tal,
633 const ArgumentList *al,const char *meta
650 livesInsideEnum=FALSE;
652 hasCallGraph = FALSE;
653 hasCallerGraph = FALSE;
654 hasReferencedByRelation = FALSE;
655 hasReferencesRelation = FALSE;
658 if (mt==MemberType_Typedef) type.stripPrefix("typedef ");
659 // type.stripPrefix("struct ");
660 // type.stripPrefix("class " );
661 // type.stripPrefix("union " );
662 type=removeRedundantWhiteSpace(type);
664 args=removeRedundantWhiteSpace(args);
665 if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args;
683 cachedAnonymousType=0;
684 maxInitLines=Config_getInt(MAX_INITIALIZER_LINES);
687 // copy function template arguments (if any)
690 tArgList = tal->deepCopy();
696 //printf("new member al=%p\n",al);
697 // copy function definition arguments (if any)
700 defArgList = al->deepCopy();
706 // convert function declaration arguments (if any)
709 declArgList = new ArgumentList;
710 stringToArgumentList(args,declArgList,&extraTypeChars);
711 //printf("setDeclArgList %s to %s const=%d\n",args.data(),
712 // argListToString(declArgList).data(),declArgList->constSpecifier);
720 classSectionSDict = 0;
721 docsForDefinition = TRUE;
722 isTypedefValCached = FALSE;
723 cachedTypedefValue = 0;
727 hasDocumentedParams = FALSE;
728 hasDocumentedReturnType = FALSE;
730 isDMember = def->getDefFileName().right(2).lower()==".d";
734 //-----------------------------------------------------------------------------
735 //-----------------------------------------------------------------------------
736 //-----------------------------------------------------------------------------
738 /*! Creates a new member definition.
740 * \param df File containing the definition of this member.
741 * \param dl Line at which the member definition was found.
742 * \param dc Column at which the member definition was found.
743 * \param t A string representing the type of the member.
744 * \param na A string representing the name of the member.
745 * \param a A string representing the arguments of the member.
746 * \param e A string representing the throw clause of the members.
747 * \param p The protection context of the member, possible values are:
748 * \c Public, \c Protected, \c Private.
749 * \param v The degree of `virtualness' of the member, possible values are:
750 * \c Normal, \c Virtual, \c Pure.
751 * \param s A boolean that is true iff the member is static.
752 * \param r The relationship between the class and the member.
753 * \param mt The kind of member. See #MemberType for a list of
755 * \param tal The template arguments of this member.
756 * \param al The arguments of this member. This is a structured form of
757 * the string past as argument \a a.
758 * \param meta Slice metadata.
761 MemberDef::MemberDef(const char *df,int dl,int dc,
762 const char *t,const char *na,const char *a,const char *e,
763 Protection p,Specifier v,bool s,Relationship r,MemberType mt,
764 const ArgumentList *tal,const ArgumentList *al,const char *meta
765 ) : Definition(df,dl,dc,removeRedundantWhiteSpace(na)), visited(FALSE)
767 //printf("MemberDef::MemberDef(%s)\n",na);
768 m_impl = new MemberDefImpl;
769 m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al,meta);
770 number_of_flowkw = 1;
771 m_isLinkableCached = 0;
772 m_isConstructorCached = 0;
773 m_isDestructorCached = 0;
776 MemberDef::MemberDef(const MemberDef &md) : Definition(md), visited(FALSE)
778 m_impl = new MemberDefImpl;
779 m_isLinkableCached = 0;
780 m_isConstructorCached = 0;
781 m_isDestructorCached = 0;
784 MemberDef *MemberDef::deepCopy() const
786 //MemberDef *result = new MemberDef(getDefFileName(),getDefLine(),name());
787 MemberDef *result = new MemberDef(*this);
788 // first copy everything by reference
789 *result->m_impl = *m_impl;
790 // clear pointers owned by object
791 result->m_impl->redefinedBy= 0;
792 result->m_impl->exampleSDict=0;
793 result->m_impl->enumFields=0;
794 result->m_impl->defArgList=0;
795 result->m_impl->tArgList=0;
796 result->m_impl->typeConstraints=0;
797 result->m_impl->defTmpArgLists=0;
798 result->m_impl->classSectionSDict=0;
799 result->m_impl->declArgList=0;
800 // replace pointers owned by the object by deep copies
801 if (m_impl->redefinedBy)
803 MemberListIterator mli(*m_impl->redefinedBy);
805 for (mli.toFirst();(md=mli.current());++mli)
807 result->insertReimplementedBy(md);
810 if (m_impl->exampleSDict)
812 ExampleSDict::Iterator it(*m_impl->exampleSDict);
814 for (it.toFirst();(e=it.current());++it)
816 result->addExample(e->anchor,e->name,e->file);
819 if (m_impl->enumFields)
821 MemberListIterator mli(*m_impl->enumFields);
823 for (mli.toFirst();(md=mli.current());++mli)
825 result->insertEnumField(md);
828 if (m_impl->defArgList)
830 result->m_impl->defArgList = m_impl->defArgList->deepCopy();
832 if (m_impl->tArgList)
834 result->m_impl->tArgList = m_impl->tArgList->deepCopy();
836 if (m_impl->typeConstraints)
838 result->m_impl->typeConstraints = m_impl->typeConstraints->deepCopy();
840 result->setDefinitionTemplateParameterLists(m_impl->defTmpArgLists);
841 if (m_impl->classSectionSDict)
843 result->m_impl->classSectionSDict = new SDict<MemberList>(7);
844 SDict<MemberList>::IteratorDict it(*m_impl->classSectionSDict);
846 for (it.toFirst();(ml=it.current());++it)
848 result->m_impl->classSectionSDict->append(it.currentKey(),ml);
851 if (m_impl->declArgList)
853 result->m_impl->declArgList = m_impl->declArgList->deepCopy();
858 void MemberDef::moveTo(Definition *scope)
860 setOuterScope(scope);
861 if (scope->definitionType()==Definition::TypeClass)
863 m_impl->classDef = (ClassDef*)scope;
865 else if (scope->definitionType()==Definition::TypeFile)
867 m_impl->fileDef = (FileDef*)scope;
869 else if (scope->definitionType()==Definition::TypeNamespace)
871 m_impl->nspace = (NamespaceDef*)scope;
873 m_isLinkableCached = 0;
874 m_isConstructorCached = 0;
878 /*! Destroys the member definition. */
879 MemberDef::~MemberDef()
882 //printf("%p: ~MemberDef()\n",this);
886 void MemberDef::setReimplements(MemberDef *md)
888 m_impl->redefines = md;
891 void MemberDef::insertReimplementedBy(MemberDef *md)
893 if (m_impl->templateMaster)
895 m_impl->templateMaster->insertReimplementedBy(md);
897 if (m_impl->redefinedBy==0) m_impl->redefinedBy = new MemberList(MemberListType_redefinedBy);
898 if (m_impl->redefinedBy->findRef(md)==-1)
900 m_impl->redefinedBy->inSort(md);
904 MemberDef *MemberDef::reimplements() const
906 return m_impl->redefines;
909 MemberList *MemberDef::reimplementedBy() const
911 return m_impl->redefinedBy;
914 bool MemberDef::isReimplementedBy(ClassDef *cd) const
916 if (cd && m_impl->redefinedBy)
918 MemberListIterator mi(*m_impl->redefinedBy);
920 for (mi.toFirst();(md=mi.current());++mi)
922 ClassDef *mcd = md->getClassDef();
925 if (cd==mcd || cd->isBaseClass(mcd,TRUE))
935 void MemberDef::insertEnumField(MemberDef *md)
937 if (m_impl->enumFields==0) m_impl->enumFields=new MemberList(MemberListType_enumFields);
938 m_impl->enumFields->append(md);
941 bool MemberDef::addExample(const char *anchor,const char *nameStr,
944 //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
945 if (m_impl->exampleSDict==0) m_impl->exampleSDict = new ExampleSDict;
946 if (m_impl->exampleSDict->find(nameStr)==0)
948 //printf("Add reference to example %s to member %s\n",nameStr,name.data());
949 Example *e=new Example;
953 m_impl->exampleSDict->inSort(nameStr,e);
959 bool MemberDef::hasExamples()
961 if (m_impl->exampleSDict==0)
964 return m_impl->exampleSDict->count()>0;
967 QCString MemberDef::getOutputFileBase() const
969 static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES);
970 static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS);
973 //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
974 // name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
975 // m_impl->nspace,m_impl->fileDef);
976 if (!m_impl->explicitOutputFileBase.isEmpty())
978 return m_impl->explicitOutputFileBase;
980 else if (m_impl->templateMaster)
982 return m_impl->templateMaster->getOutputFileBase();
984 else if (m_impl->group)
986 baseName=m_impl->group->getOutputFileBase();
988 else if (m_impl->classDef)
990 baseName=m_impl->classDef->getOutputFileBase();
991 if (inlineSimpleClasses && m_impl->classDef->isSimple())
996 else if (m_impl->nspace && m_impl->nspace->isLinkableInProject())
998 baseName=m_impl->nspace->getOutputFileBase();
1000 else if (m_impl->fileDef)
1002 baseName=m_impl->fileDef->getOutputFileBase();
1005 if (baseName.isEmpty())
1007 warn(getDefFileName(),getDefLine(),
1008 "Internal inconsistency: member %s does not belong to any"
1009 " container!",qPrint(name())
1013 else if (separateMemberPages && isDetailedSectionLinkable())
1015 if (getEnumScope()) // enum value, which is part of enum's documentation
1017 baseName+="_"+getEnumScope()->anchor();
1021 baseName+="_"+anchor();
1027 QCString MemberDef::getReference() const
1029 QCString ref = Definition::getReference();
1034 if (m_impl->templateMaster)
1036 return m_impl->templateMaster->getReference();
1038 else if (m_impl->group)
1040 return m_impl->group->getReference();
1042 else if (m_impl->classDef)
1044 return m_impl->classDef->getReference();
1046 else if (m_impl->nspace)
1048 return m_impl->nspace->getReference();
1050 else if (m_impl->fileDef)
1052 return m_impl->fileDef->getReference();
1057 QCString MemberDef::anchor() const
1059 QCString result=m_impl->anc;
1060 if (m_impl->groupAlias) return m_impl->groupAlias->anchor();
1061 if (m_impl->templateMaster) return m_impl->templateMaster->anchor();
1062 if (m_impl->enumScope && m_impl->enumScope!=this) // avoid recursion for C#'s public enum E { E, F }
1064 result.prepend(m_impl->enumScope->anchor());
1068 if (m_impl->groupMember)
1070 result=m_impl->groupMember->anchor();
1072 else if (getReference().isEmpty())
1074 result.prepend("g");
1080 void MemberDef::_computeLinkableInProject()
1082 static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1083 m_isLinkableCached = 2; // linkable
1084 //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
1087 //printf("is hidden\n");
1088 m_isLinkableCached = 1;
1091 if (m_impl->templateMaster)
1093 //printf("has template master\n");
1094 m_isLinkableCached = m_impl->templateMaster->isLinkableInProject() ? 2 : 1;
1097 if (name().isEmpty() || name().at(0)=='@')
1099 //printf("name invalid\n");
1100 m_isLinkableCached = 1; // not a valid or a dummy name
1103 if (!hasDocumentation() || isReference())
1105 //printf("no docs or reference\n");
1106 m_isLinkableCached = 1; // no documentation
1109 if (m_impl->group && !m_impl->group->isLinkableInProject())
1111 //printf("group but group not linkable!\n");
1112 m_isLinkableCached = 1; // group but group not linkable
1115 if (!m_impl->group && m_impl->classDef && !m_impl->classDef->isLinkableInProject())
1117 //printf("in a class but class not linkable!\n");
1118 m_isLinkableCached = 1; // in class but class not linkable
1121 if (!m_impl->group && m_impl->nspace && !m_impl->related && !m_impl->nspace->isLinkableInProject()
1122 && (m_impl->fileDef==0 || !m_impl->fileDef->isLinkableInProject()))
1124 //printf("in a namespace but namespace not linkable!\n");
1125 m_isLinkableCached = 1; // in namespace but namespace not linkable
1128 if (!m_impl->group && !m_impl->nspace &&
1129 !m_impl->related && !m_impl->classDef &&
1130 m_impl->fileDef && !m_impl->fileDef->isLinkableInProject())
1132 //printf("in a file but file not linkable!\n");
1133 m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable
1136 if (!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=MemberType_Friend)
1138 //printf("private and invisible!\n");
1139 m_isLinkableCached = 1; // hidden due to protection
1142 if (m_impl->stat && m_impl->classDef==0 && !extractStatic)
1144 //printf("static and invisible!\n");
1145 m_isLinkableCached = 1; // hidden due to staticness
1148 //printf("linkable!\n");
1149 return; // linkable!
1152 void MemberDef::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
1154 Definition::setDocumentation(d,docFile,docLine,stripWhiteSpace);
1155 m_isLinkableCached = 0;
1158 void MemberDef::setBriefDescription(const char *b,const char *briefFile,int briefLine)
1160 Definition::setBriefDescription(b,briefFile,briefLine);
1161 m_isLinkableCached = 0;
1164 void MemberDef::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine)
1166 Definition::setInbodyDocumentation(d,inbodyFile,inbodyLine);
1167 m_isLinkableCached = 0;
1170 void MemberDef::setHidden(bool b)
1172 Definition::setHidden(b);
1173 m_isLinkableCached = 0;
1176 bool MemberDef::isLinkableInProject() const
1178 if (m_isLinkableCached==0)
1180 MemberDef *that = (MemberDef*)this;
1181 that->_computeLinkableInProject();
1183 ASSERT(m_isLinkableCached>0);
1184 return m_isLinkableCached==2;
1187 bool MemberDef::isLinkable() const
1189 if (m_impl->templateMaster)
1191 return m_impl->templateMaster->isLinkable();
1195 return isLinkableInProject() || isReference();
1200 void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists)
1204 if (m_impl->defTmpArgLists) delete m_impl->defTmpArgLists;
1205 m_impl->defTmpArgLists = copyArgumentLists(lists);
1209 void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *,
1210 FileDef *fd,GroupDef *gd,bool onlyText)
1212 SrcLangExt lang = getLanguage();
1213 static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
1214 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
1215 QCString n = name();
1216 if (!hideScopeNames)
1218 if (m_impl->enumScope && m_impl->livesInsideEnum)
1220 n.prepend(m_impl->enumScope->displayName()+sep);
1222 if (m_impl->classDef && gd && !isRelated())
1224 n.prepend(m_impl->classDef->displayName()+sep);
1226 else if (m_impl->nspace && (gd || fd))
1228 n.prepend(m_impl->nspace->displayName()+sep);
1234 if (isStatic()) ol.docify("+ "); else ol.docify("- ");
1236 if (!onlyText && isLinkable()) // write link
1238 if (m_impl->mtype==MemberType_EnumValue && getGroupDef()==0 && // enum value is not grouped
1239 getEnumScope() && getEnumScope()->getGroupDef()) // but its container is
1241 GroupDef *enumValGroup = getEnumScope()->getGroupDef();
1242 ol.writeObjectLink(enumValGroup->getReference(),
1243 enumValGroup->getOutputFileBase(),
1248 ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),n);
1251 else // write only text
1259 /*! If this member has an anonymous class/struct/union as its type, then
1260 * this method will return the ClassDef that describes this return type.
1262 ClassDef *MemberDef::getClassDefOfAnonymousType()
1264 if (m_impl->cachedAnonymousType) return m_impl->cachedAnonymousType;
1267 if (getClassDef()!=0)
1269 cname=getClassDef()->name().copy();
1271 else if (getNamespaceDef()!=0)
1273 cname=getNamespaceDef()->name().copy();
1275 QCString ltype(m_impl->type);
1276 // strip `static' keyword from ltype
1277 //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
1278 // strip `friend' keyword from ltype
1279 ltype.stripPrefix("friend ");
1280 static QRegExp r("@[0-9]+");
1281 int l,i=r.match(ltype,0,&l);
1282 //printf("ltype=`%s' i=%d\n",ltype.data(),i);
1283 // search for the last anonymous scope in the member type
1284 ClassDef *annoClassDef=0;
1285 if (i!=-1) // found anonymous scope in type
1288 // extract anonymous scope
1289 while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
1290 if (il>0) il++; else if (il<0) il=0;
1291 while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;
1293 QCString annName = ltype.mid(il,ir-il);
1295 // if inside a class or namespace try to prepend the scope name
1296 if (!cname.isEmpty() && annName.left(cname.length()+2)!=cname+"::")
1298 QCString ts=stripAnonymousNamespaceScope(cname+"::"+annName);
1299 annoClassDef=getClass(ts);
1301 // if not found yet, try without scope name
1302 if (annoClassDef==0)
1304 QCString ts=stripAnonymousNamespaceScope(annName);
1305 annoClassDef=getClass(ts);
1308 m_impl->cachedAnonymousType = annoClassDef;
1309 return annoClassDef;
1312 /*! This methods returns TRUE iff the brief section (also known as
1313 * declaration section) is visible in the documentation.
1315 bool MemberDef::isBriefSectionVisible() const
1317 static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1318 static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
1319 static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
1320 static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1321 static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
1323 //printf("Member %s grpId=%d docs=%s file=%s args=%s\n",
1325 // 0,"", //grpId,grpId==-1?"<none>":Doxygen::memberDocDict[grpId]->data(),
1326 // "", //getFileDef()->name().data(),
1329 MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId];
1330 //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
1331 //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
1332 bool hasDocs = hasDocumentation() ||
1333 // part of a documented member group
1334 (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
1336 // only include static members with file/namespace scope if
1337 // explicitly enabled in the config file
1338 bool visibleIfStatic = !(getClassDef()==0 &&
1343 // only include members is the are documented or
1344 // HIDE_UNDOC_MEMBERS is NO in the config file
1345 bool visibleIfDocumented = (!hideUndocMembers ||
1347 isDocumentedFriendClass()
1350 // hide members with no detailed description and brief descriptions
1351 // explicitly disabled.
1352 bool visibleIfEnabled = !(hideUndocMembers &&
1353 documentation().isEmpty() &&
1358 // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true
1359 bool visibleIfFriendCompound = !(hideFriendCompounds &&
1361 (m_impl->type=="friend class" ||
1362 m_impl->type=="friend struct" ||
1363 m_impl->type=="friend union"
1367 // only include members that are non-private unless EXTRACT_PRIVATE is
1368 // set to YES or the member is part of a group
1369 bool visibleIfPrivate = (protectionLevelVisible(protection()) ||
1370 m_impl->mtype==MemberType_Friend
1373 // hide member if it overrides a member in a superclass and has no
1374 // documentation of its own
1375 //bool visibleIfDocVirtual = !reimplements() ||
1376 // !Config_getBool(INHERIT_DOCS) ||
1379 // true if this member is a constructor or destructor
1380 bool cOrDTor = isConstructor() || isDestructor();
1382 // hide default constructors or destructors (no args) without
1384 bool visibleIfNotDefaultCDTor = !(cOrDTor &&
1385 m_impl->defArgList &&
1386 (m_impl->defArgList->isEmpty() ||
1387 m_impl->defArgList->getFirst()->type == "void"
1393 //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d "
1394 // "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d "
1395 // "visibleIfFriendCompound=%d !annScope=%d\n",
1396 // visibleIfStatic,visibleIfDocumented,
1397 // visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
1398 // visibleIfFriendCompound,!m_impl->annScope);
1400 bool visible = visibleIfStatic && visibleIfDocumented &&
1401 visibleIfEnabled && visibleIfPrivate &&
1402 /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor &&
1403 visibleIfFriendCompound &&
1404 !m_impl->annScope && !isHidden();
1405 //printf("MemberDef::isBriefSectionVisible() %d\n",visible);
1409 QCString MemberDef::getDeclType() const
1411 QCString ltype(m_impl->type);
1412 if (isTypedef() && getLanguage() != SrcLangExt_Slice)
1414 ltype.prepend("typedef ");
1420 // strip `friend' keyword from ltype
1421 ltype.stripPrefix("friend ");
1422 if (ltype=="@") // rename type from enum values
1437 void MemberDef::writeDeclaration(OutputList &ol,
1438 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
1439 bool inGroup, ClassDef *inheritedFrom,const char *inheritId)
1441 //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",qualifiedName().data(),inGroup);
1443 // hide enum value, since they appear already as part of the enum, unless they
1444 // are explicitly grouped.
1445 if (!inGroup && m_impl->mtype==MemberType_EnumValue) return;
1449 ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
1450 if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
1451 if (d==gd) // see bug 753608
1453 if (getClassDef()) d = getClassDef();
1454 else if (getNamespaceDef()) d = getNamespaceDef();
1455 else if (getFileDef()) d = getFileDef();
1458 //_writeTagData(compoundType);
1459 _addToSearchIndex();
1461 QCString cname = d->name();
1462 QCString cdname = d->displayName();
1463 QCString cfname = getOutputFileBase();
1465 // search for the last anonymous scope in the member type
1466 ClassDef *annoClassDef=getClassDefOfAnonymousType();
1468 ol.startMemberDeclaration();
1470 // start a new member declaration
1471 bool isAnonymous = annoClassDef || m_impl->annMemb || m_impl->annEnumType;
1472 ///printf("startMemberItem for %s\n",name().data());
1473 ol.startMemberItem(anchor(),
1474 isAnonymous ? 1 : m_impl->tArgList ? 3 : 0,
1478 // If there is no detailed description we need to write the anchor here.
1479 bool detailsVisible = isDetailedSectionLinkable();
1480 bool writeAnchor = (inGroup || m_impl->group==0) && // only write anchors for member that have no details and are
1481 !detailsVisible && !m_impl->annMemb; // rendered inside the group page or are not grouped at all
1484 QCString doxyArgs=argsString();
1485 QCString doxyName=name();
1486 if (!cname.isEmpty())
1488 doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage()));
1490 ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs);
1493 if (!detailsVisible)
1495 ol.pushGeneratorState();
1496 ol.disable(OutputGenerator::Man);
1497 ol.disable(OutputGenerator::Latex);
1498 ol.disable(OutputGenerator::Docbook);
1500 ol.popGeneratorState();
1503 if (annoClassDef || m_impl->annMemb)
1506 for (j=0;j<s_indentLevel;j++)
1508 ol.writeNonBreakableSpace(3);
1512 // *** write template lists
1513 if (m_impl->tArgList && getLanguage()==SrcLangExt_Cpp)
1515 if (!isAnonymous) ol.startMemberTemplateParams();
1516 writeTemplatePrefix(ol,m_impl->tArgList);
1517 if (!isAnonymous) ol.endMemberTemplateParams(anchor(),inheritId);
1521 QCString ltype(m_impl->type);
1522 if (isTypedef() && getLanguage() != SrcLangExt_Slice)
1524 ltype.prepend("typedef ");
1530 // strip `friend' keyword from ltype
1531 ltype.stripPrefix("friend ");
1532 static QRegExp r("@[0-9]+");
1534 bool endAnonScopeNeeded=FALSE;
1535 int l,i=r.match(ltype,0,&l);
1536 if (i!=-1) // member has an anonymous type
1538 //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n",
1539 // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());
1541 if (annoClassDef) // type is an anonymous compound
1544 //printf("<<<<<<<<<<<<<<\n");
1545 ol.startAnonTypeScope(s_indentLevel++);
1546 annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup,inheritedFrom,inheritId);
1547 //printf(">>>>>>>>>>>>>> startMemberItem(2)\n");
1548 ol.startMemberItem(anchor(),2,inheritId);
1550 for (j=0;j< s_indentLevel-1;j++)
1552 ol.writeNonBreakableSpace(3);
1554 QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
1555 //printf(">>>>>> ltype=`%s' varName=`%s'\n",ltype.data(),varName.data());
1557 if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@'))
1561 else if (!varName.isEmpty() && (varName.at(0)=='*' || varName.at(0)=='&'))
1566 endAnonScopeNeeded=TRUE;
1570 if (getAnonymousEnumType()) // type is an anonymous enum
1572 linkifyText(TextGeneratorOLImpl(ol), // out
1574 getBodyDef(), // fileScope
1576 ltype.left(i), // text
1579 getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd);
1580 //ol+=*getAnonymousEnumType()->enumDecl();
1581 linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,this,ltype.right(ltype.length()-i-l),TRUE);
1585 ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
1586 linkifyText(TextGeneratorOLImpl(ol), // out
1588 getBodyDef(), // fileScope
1596 else if (ltype=="@") // rename type from enum values
1607 linkifyText(TextGeneratorOLImpl(ol), // out
1609 getBodyDef(), // fileScope
1615 bool htmlOn = ol.isEnabled(OutputGenerator::Html);
1616 if (htmlOn && !ltype.isEmpty())
1618 ol.disable(OutputGenerator::Html);
1620 if (!ltype.isEmpty()) ol.docify(" ");
1623 ol.enable(OutputGenerator::Html);
1626 if (m_impl->annMemb)
1628 ol.pushGeneratorState();
1629 ol.disableAllBut(OutputGenerator::Html);
1630 ol.writeNonBreakableSpace(3);
1631 ol.popGeneratorState();
1635 ol.insertMemberAlign(m_impl->tArgList!=0);
1639 if (!name().isEmpty() && name().at(0)!='@') // hide anonymous stuff
1641 static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1642 static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1643 //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d hasDocumentation=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable(),hasDocumentation());
1644 if (!(name().isEmpty() || name().at(0)=='@') && // name valid
1645 (hasDocumentation() || isReference()) && // has docs
1646 !(m_impl->prot==Private && !extractPrivate && m_impl->mtype!=MemberType_Friend) && // hidden due to protection
1647 !(isStatic() && m_impl->classDef==0 && !extractStatic) // hidden due to static-ness
1650 if (m_impl->annMemb)
1652 //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
1653 m_impl->annMemb->writeLink(ol,
1654 m_impl->annMemb->getClassDef(),
1655 m_impl->annMemb->getNamespaceDef(),
1656 m_impl->annMemb->getFileDef(),
1657 m_impl->annMemb->getGroupDef()
1659 m_impl->annMemb->setAnonymousUsed();
1664 //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
1666 if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
1667 writeLink(ol,rcd,nd,fd,gd);
1670 else if (isDocumentedFriendClass())
1671 // if the member is an undocumented friend declaration for some class,
1672 // then maybe we can link to the class
1674 writeLink(ol,getClass(name()),0,0,0);
1677 // there is a brief member description and brief member
1678 // descriptions are enabled or there is no detailed description.
1680 if (m_impl->annMemb)
1682 m_impl->annMemb->setAnonymousUsed();
1686 if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
1687 writeLink(ol,rcd,nd,fd,gd,TRUE);
1692 if (isEnumerate() && name().at(0)=='@')
1694 // don't add to index
1696 else // index member
1698 //static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1699 //QCString cfname = getOutputFileBase();
1700 //QCString cfiname = d->getOutputFileBase();
1701 //Doxygen::indexList->addIndexItem(
1703 // name(), // level2
1704 // separateMemPages ? cfname : cfiname, // contRef
1705 // cfname, // memRef
1706 // anchor(), // anchor
1707 // this); // memberdef
1708 Doxygen::indexList->addIndexItem(d,this);
1711 // *** write arguments
1712 if (argsString() && !isObjCMethod())
1714 if (!isDefine() && !isTypedef()) ol.writeString(" ");
1715 linkifyText(TextGeneratorOLImpl(ol), // out
1717 getBodyDef(), // fileScope
1720 (const char*)substitute(argsString(),",",", ") :
1722 (const char*)substitute(argsString(),")(",") (") :
1723 argsString(), // text
1724 m_impl->annMemb, // autoBreak
1726 FALSE, // keepSpaces
1730 // *** write exceptions
1733 ol.writeString(" ");
1734 ol.docify(excpString());
1737 // *** write bitfields
1738 if (!m_impl->bitfields.isEmpty()) // add bitfields
1740 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->bitfields);
1742 else if (hasOneLineInitializer()
1743 //!init.isEmpty() && initLines==0 && // one line initializer
1744 //((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
1745 ) // add initializer
1749 //ol.writeString(" = ");
1750 ol.writeString(" ");
1751 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer.simplifyWhiteSpace());
1755 ol.writeNonBreakableSpace(3);
1756 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer);
1759 else if (isAlias()) // using template alias
1761 ol.writeString(" = ");
1762 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->type);
1766 if ((isObjCMethod() || isObjCProperty()) && isImplementation())
1768 ol.startTypewriter();
1769 ol.docify(" [implementation]");
1773 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1775 if (isProperty() && (isSettable() || isGettable() ||
1776 isPrivateSettable() || isPrivateGettable() ||
1777 isProtectedSettable() || isProtectedGettable()))
1779 ol.writeLatexSpacing();
1780 ol.startTypewriter();
1784 if (isGettable()) sl.append("get");
1785 if (isProtectedGettable()) sl.append("protected get");
1786 if (isSettable()) sl.append("set");
1787 if (isProtectedSettable()) sl.append("protected set");
1790 if (isPrivateGettable()) sl.append("private get");
1791 if (isPrivateSettable()) sl.append("private set");
1793 const char *s=sl.first();
1798 if (s) ol.docify(", ");
1804 if (isEvent() && (isAddable() || isRemovable() || isRaisable()))
1806 ol.writeLatexSpacing();
1807 ol.startTypewriter();
1810 if (isAddable()) sl.append("add");
1811 if (isRemovable()) sl.append("remove");
1812 if (isRaisable()) sl.append("raise");
1813 const char *s=sl.first();
1818 if (s) ol.docify(", ");
1826 ol.endDoxyAnchor(cfname,anchor());
1829 //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
1830 // name().data(),annoClassDef,annEnumType);
1832 if (endAnonScopeNeeded)
1834 ol.endAnonTypeScope(--s_indentLevel);
1837 // write brief description
1838 if (!briefDescription().isEmpty() &&
1839 Config_getBool(BRIEF_MEMBER_DESC)
1843 DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),
1844 getOuterScope()?getOuterScope():d,this,briefDescription(),
1845 TRUE,FALSE,0,TRUE,FALSE);
1847 if (rootNode && !rootNode->isEmpty())
1849 ol.startMemberDescription(anchor(),inheritId);
1850 ol.writeDoc(rootNode,getOuterScope()?getOuterScope():d,this);
1853 static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1854 ol.pushGeneratorState();
1855 ol.disableAllBut(OutputGenerator::Html);
1858 if (inheritedFrom ||
1859 separateMemberPages ||
1860 (m_impl->group!=0 && gd==0) ||
1861 (m_impl->nspace!=0 && nd==0)
1862 ) // forward link to the page or group or namespace
1864 ol.startTextLink(getOutputFileBase(),anchor());
1868 ol.startTextLink(0,anchor());
1870 ol.parseText(theTranslator->trMore());
1872 //ol.startEmphasis();
1873 ol.popGeneratorState();
1875 // for RTF we need to add an extra empty paragraph
1876 ol.pushGeneratorState();
1877 ol.disableAllBut(OutputGenerator::RTF);
1878 ol.startParagraph();
1880 ol.popGeneratorState();
1881 ol.endMemberDescription();
1886 ol.endMemberDeclaration(anchor(),inheritId);
1888 warnIfUndocumented();
1891 bool MemberDef::isDetailedSectionLinkable() const
1893 static bool extractAll = Config_getBool(EXTRACT_ALL);
1894 static bool alwaysDetailedSec = Config_getBool(ALWAYS_DETAILED_SEC);
1895 static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1896 static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
1897 static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
1898 static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1900 // the member has details documentation for any of the following reasons
1902 // treat everything as documented
1904 // has detailed docs
1905 !documentation().isEmpty() ||
1907 !inbodyDocumentation().isEmpty() ||
1908 // is an enum with values that are documented
1909 (m_impl->mtype==MemberType_Enumeration && m_impl->docEnumValues) ||
1910 // is documented enum value
1911 (m_impl->mtype==MemberType_EnumValue && !briefDescription().isEmpty()) ||
1912 // has brief description that is part of the detailed description
1913 (!briefDescription().isEmpty() && // has brief docs
1914 (alwaysDetailedSec && // they are visible in
1915 (repeatBrief || // detailed section or
1916 !briefMemberDesc // they are explicitly not
1917 ) // shown in brief section
1920 // has a multi-line initialization block
1921 //(initLines>0 && initLines<maxInitLines) ||
1922 (hasMultiLineInitializer() && !hideUndocMembers) ||
1923 // has one or more documented arguments
1924 (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()) ||
1925 // is an attribute or property - need to display that tag
1926 (m_impl->memSpec & (Entry::Attribute|Entry::Property)) ||
1927 // has user comments
1928 Doxygen::userComments
1931 // this is not a global static or global statics should be extracted
1932 bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic;
1934 // only include members that are non-private unless EXTRACT_PRIVATE is
1935 // set to YES or the member is part of a group
1936 bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend;
1938 // member is part of an anonymous scope that is the type of
1939 // another member in the list.
1941 //bool inAnonymousScope = !briefDescription().isEmpty() && annUsed;
1943 // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS
1945 bool friendCompoundFilter = !(Config_getBool(HIDE_FRIEND_COMPOUNDS) &&
1947 (m_impl->type=="friend class" ||
1948 m_impl->type=="friend struct" ||
1949 m_impl->type=="friend union"
1954 bool result = ((docFilter && staticFilter && privateFilter && friendCompoundFilter && !isHidden()));
1955 //printf("%s::isDetailedSectionLinkable: %d\n",name().data(),result);
1959 bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const
1961 static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1962 static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS);
1963 static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
1964 bool groupFilter = getGroupDef()==0 || inGroup || separateMemPages;
1965 bool fileFilter = getNamespaceDef()==0 || !getNamespaceDef()->isLinkable() || !inFile;
1966 bool simpleFilter = (hasBriefDescription() || !hideUndocMembers) && inlineSimpleStructs &&
1967 getClassDef()!=0 && getClassDef()->isSimple();
1969 bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter &&
1971 bool result = visible || simpleFilter;
1972 //printf("%s::isDetailedSectionVisble: %d groupFilter=%d fileFilter=%d\n",
1973 // name().data(),result,groupFilter,fileFilter);
1977 void MemberDef::getLabels(QStrList &sl,Definition *container) const
1979 static bool inlineInfo = Config_getBool(INLINE_INFO);
1981 Specifier lvirt=virtualness();
1982 if ((!isObjCMethod() || isOptional() || isRequired()) &&
1983 (protection()!=Public || lvirt!=Normal ||
1984 isFriend() || isRelated() ||
1985 (isInline() && inlineInfo) ||
1986 isSignal() || isSlot() ||
1988 (m_impl->classDef && m_impl->classDef!=container && container->definitionType()==TypeClass) ||
1989 (m_impl->memSpec & ~Entry::Inline)!=0
1993 // write the member specifier list
1994 //ol.writeLatexSpacing();
1995 //ol.startTypewriter();
1997 SrcLangExt lang = getLanguage();
1998 bool optVhdl = lang==SrcLangExt_VHDL;
1999 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
2002 sl.append(theTranslator->trVhdlType(getMemberSpecifiers(),TRUE));
2006 if (isFriend()) sl.append("friend");
2007 else if (isRelated()) sl.append("related");
2010 if (Config_getBool(INLINE_INFO) && isInline()) sl.append("inline");
2011 if (isExplicit()) sl.append("explicit");
2012 if (isMutable()) sl.append("mutable");
2013 if (isStatic()) sl.append("static");
2014 if (isGettable()) sl.append("get");
2015 if (isProtectedGettable()) sl.append("protected get");
2016 if (isSettable()) sl.append("set");
2017 if (isProtectedSettable()) sl.append("protected set");
2020 if (isPrivateGettable()) sl.append("private get");
2021 if (isPrivateSettable()) sl.append("private set");
2023 if (isAddable()) sl.append("add");
2024 if (!isUNOProperty() && isRemovable()) sl.append("remove");
2025 if (isRaisable()) sl.append("raise");
2026 if (isReadable()) sl.append("read");
2027 if (isWritable()) sl.append("write");
2028 if (isFinal()) sl.append("final");
2029 if (isAbstract()) sl.append("abstract");
2030 if (isOverride()) sl.append("override");
2031 if (isInitonly()) sl.append("initonly");
2032 if (isSealed()) sl.append("sealed");
2033 if (isNew()) sl.append("new");
2034 if (isOptional()) sl.append("optional");
2035 if (isRequired()) sl.append("required");
2037 if (isNonAtomic()) sl.append("nonatomic");
2038 else if (isObjCProperty()) sl.append("atomic");
2040 // mutual exclusive Objective 2.0 property attributes
2041 if (isAssign()) sl.append("assign");
2042 else if (isCopy()) sl.append("copy");
2043 else if (isRetain()) sl.append("retain");
2044 else if (isWeak()) sl.append("weak");
2045 else if (isStrong()) sl.append("strong");
2046 else if (isUnretained()) sl.append("unsafe_unretained");
2048 if (!isObjCMethod())
2050 if (protection()==Protected) sl.append("protected");
2051 else if (protection()==Private) sl.append("private");
2052 else if (protection()==Package) sl.append("package");
2054 if (lvirt==Virtual) sl.append("virtual");
2055 else if (lvirt==Pure) sl.append("pure virtual");
2056 if (isSignal()) sl.append("signal");
2057 if (isSlot()) sl.append("slot");
2058 if (isDefault()) sl.append("default");
2059 if (isDelete()) sl.append("delete");
2060 if (isNoExcept()) sl.append("noexcept");
2061 if (isAttribute()) sl.append("attribute");
2062 if (isUNOProperty()) sl.append("property");
2063 if (isReadonly()) sl.append("readonly");
2064 if (isBound()) sl.append("bound");
2065 if (isUNOProperty() && isRemovable()) sl.append("removable");
2066 if (isConstrained()) sl.append("constrained");
2067 if (isTransient()) sl.append("transient");
2068 if (isMaybeVoid()) sl.append("maybevoid");
2069 if (isMaybeDefault()) sl.append("maybedefault");
2070 if (isMaybeAmbiguous()) sl.append("maybeambiguous");
2071 if (isPublished()) sl.append("published"); // enum
2073 if (isObjCProperty() && isImplementation())
2075 sl.append("implementation");
2078 if (m_impl->classDef &&
2079 container->definitionType()==TypeClass &&
2080 m_impl->classDef!=container &&
2084 sl.append("inherited");
2088 else if (isObjCMethod() && isImplementation())
2090 sl.append("implementation");
2094 void MemberDef::_writeCallGraph(OutputList &ol)
2097 if (m_impl->hasCallGraph
2098 && (isFunction() || isSlot() || isSignal()) && Config_getBool(HAVE_DOT)
2101 DotCallGraph callGraph(this,FALSE);
2102 if (callGraph.isTooBig())
2104 warn_uncond("Call graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
2106 else if (!callGraph.isTrivial())
2108 msg("Generating call graph for function %s\n",qPrint(qualifiedName()));
2109 ol.disable(OutputGenerator::Man);
2110 ol.startCallGraph();
2111 ol.parseText(theTranslator->trCallGraph());
2112 ol.endCallGraph(callGraph);
2118 void MemberDef::_writeCallerGraph(OutputList &ol)
2120 if (m_impl->hasCallerGraph
2121 && (isFunction() || isSlot() || isSignal()) && Config_getBool(HAVE_DOT)
2124 DotCallGraph callerGraph(this, TRUE);
2125 if (callerGraph.isTooBig())
2127 warn_uncond("Caller graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
2129 else if (!callerGraph.isTrivial() && !callerGraph.isTooBig())
2131 msg("Generating caller graph for function %s\n",qPrint(qualifiedName()));
2132 ol.disable(OutputGenerator::Man);
2133 ol.startCallGraph();
2134 ol.parseText(theTranslator->trCallerGraph());
2135 ol.endCallGraph(callerGraph);
2141 void MemberDef::_writeReimplements(OutputList &ol)
2143 MemberDef *bmd=reimplements();
2145 if (bmd && (bcd=bmd->getClassDef()))
2147 // write class that contains a member that is reimplemented by this one
2148 if (bcd->isLinkable())
2150 ol.startParagraph();
2151 QCString reimplFromLine;
2152 if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
2154 reimplFromLine = theTranslator->trReimplementedFromList(1);
2158 reimplFromLine = theTranslator->trImplementedFromList(1);
2160 int markerPos = reimplFromLine.find("@0");
2161 if (markerPos!=-1) // should always pass this.
2163 ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
2164 if (bmd->isLinkable()) // replace marker with link
2166 //Definition *bd=bmd->group;
2167 //if (bd==0) bd=bcd;
2168 ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
2169 bmd->anchor(),bcd->displayName());
2171 //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2172 // bmd->anchor(),bcd->name());
2173 if ( bmd->isLinkableInProject() )
2175 writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
2180 ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2181 0,bcd->displayName());
2182 if (bcd->isLinkableInProject()/* && !Config_getBool(PDF_HYPERLINKS)*/ )
2184 writePageRef(ol,bcd->getOutputFileBase(),bcd->anchor());
2187 ol.parseText(reimplFromLine.right(
2188 reimplFromLine.length()-markerPos-2)); // text right from marker
2193 err("translation error: no marker in trReimplementsFromList()\n");
2200 void MemberDef::_writeReimplementedBy(OutputList &ol)
2202 MemberList *bml=reimplementedBy();
2205 MemberListIterator mli(*bml);
2209 for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
2211 // count the members that directly inherit from md and for
2212 // which the member and class are visible in the docs.
2213 if ( bmd->isLinkable() && bcd->isLinkable() )
2221 // write the list of classes that overwrite this member
2222 ol.startParagraph();
2224 QCString reimplInLine;
2225 if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface))
2227 reimplInLine = theTranslator->trImplementedInList(count);
2231 reimplInLine = theTranslator->trReimplementedInList(count);
2233 static QRegExp marker("@[0-9]+");
2234 int index=0,newIndex,matchLen;
2235 // now replace all markers in reimplInLine with links to the classes
2236 while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
2238 ol.parseText(reimplInLine.mid(index,newIndex-index));
2240 uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
2241 //bmd=bml->at(entryIndex);
2244 // find the entryIndex-th documented entry in the inheritance list.
2245 for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
2247 if ( bmd->isLinkable() && bcd->isLinkable())
2249 if (count==entryIndex) break;
2254 if (ok && bcd && bmd) // write link for marker
2256 //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2257 // bmd->anchor(),bcd->name());
2258 ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
2259 bmd->anchor(),bcd->displayName());
2261 if (bmd->isLinkableInProject() )
2263 writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
2267 index=newIndex+matchLen;
2269 ol.parseText(reimplInLine.right(reimplInLine.length()-index));
2275 void MemberDef::_writeCategoryRelation(OutputList &ol)
2277 if (m_impl->classDef) // this should be a member of a class/category
2279 //printf("%s: category %s relation %s class=%s categoryOf=%s\n",
2281 // m_impl->category ? m_impl->category->name().data() : "<none>",
2282 // m_impl->categoryRelation ? m_impl->categoryRelation->name().data() : "<none>",
2283 // m_impl->classDef->name().data(),
2284 // m_impl->classDef->categoryOf() ? m_impl->classDef->categoryOf()->name().data() : "<none>"
2292 if (m_impl->categoryRelation && m_impl->categoryRelation->isLinkable())
2294 if (m_impl->category)
2296 // this member is in a normal class and implements method categoryRelation from category
2297 // so link to method 'categoryRelation' with 'provided by category 'category' text.
2298 text = theTranslator->trProvidedByCategory();
2299 name = m_impl->category->displayName();
2301 else if (m_impl->classDef->categoryOf())
2303 // this member is part of a category so link to the corresponding class member of the class we extend
2304 // so link to method 'categoryRelation' with 'extends class 'classDef->categoryOf()'
2305 text = theTranslator->trExtendsClass();
2306 name = m_impl->classDef->categoryOf()->displayName();
2311 MemberDef *md = m_impl->categoryRelation;
2312 ref = md->getReference();
2313 file = md->getOutputFileBase();
2317 if (i!=-1 && !name.isEmpty())
2319 ol.startParagraph();
2320 ol.parseText(text.left(i));
2321 ol.writeObjectLink(ref,file,anc,name);
2322 ol.parseText(text.mid(i+2));
2328 void MemberDef::_writeExamples(OutputList &ol)
2330 // write the list of examples that use this member
2334 ol.startDescForItem();
2335 writeExample(ol,m_impl->exampleSDict);
2336 ol.endDescForItem();
2341 void MemberDef::_writeTypeConstraints(OutputList &ol)
2343 if (m_impl->typeConstraints)
2345 writeTypeConstraints(ol,this,m_impl->typeConstraints);
2349 void MemberDef::_writeEnumValues(OutputList &ol,Definition *container,
2350 const QCString &cfname,const QCString &ciname,
2351 const QCString &cname)
2353 // For enum, we also write the documented enum values
2357 MemberList *fmdl=enumFieldList();
2358 //printf("** %s: enum values=%d\n",name().data(),fmdl!=0 ? fmdl->count() : 0);
2361 MemberListIterator it(*fmdl);
2363 for (;(fmd=it.current());++it)
2365 //printf("Enum %p: isLinkable()=%d\n",fmd,fmd->isLinkable());
2366 if (fmd->isLinkable())
2370 ol.startDescTable(theTranslator->trEnumerationValues());
2373 ol.startDescTableRow();
2374 ol.addIndexItem(fmd->name(),ciname);
2375 ol.addIndexItem(ciname,fmd->name());
2377 Doxygen::indexList->addIndexItem(container,fmd);
2379 ol.startDescTableTitle();
2380 ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString());
2382 ol.docify(fmd->name());
2383 ol.disableAllBut(OutputGenerator::Man);
2384 ol.writeString(" ");
2386 ol.endDoxyAnchor(cfname,fmd->anchor());
2387 ol.endDescTableTitle();
2388 ol.startDescTableData();
2390 bool hasBrief = !fmd->briefDescription().isEmpty();
2391 bool hasDetails = !fmd->documentation().isEmpty();
2395 ol.generateDoc(fmd->briefFile(),fmd->briefLine(),
2396 getOuterScope()?getOuterScope():container,
2397 fmd,fmd->briefDescription(),TRUE,FALSE);
2400 //if (!fmd->briefDescription().isEmpty() &&
2401 // !fmd->documentation().isEmpty())
2403 // ol.newParagraph();
2407 ol.generateDoc(fmd->docFile(),fmd->docLine(),
2408 getOuterScope()?getOuterScope():container,
2409 fmd,fmd->documentation()+"\n",TRUE,FALSE);
2411 ol.endDescTableData();
2412 ol.endDescTableRow();
2423 QCString MemberDef::displayDefinition() const
2425 QCString ldef = definition();
2426 QCString title = name();
2429 if (title.at(0)=='@')
2431 ldef = title = "anonymous enum";
2432 if (!m_impl->enumBaseType.isEmpty())
2434 ldef+=" : "+m_impl->enumBaseType;
2439 ldef.prepend("enum ");
2442 ldef.prepend("local ");
2446 else if (isEnumValue())
2448 if (ldef.at(0)=='@')
2453 static QRegExp r("@[0-9]+");
2454 int l,i=r.match(ldef,0,&l);
2455 if (i!=-1) // replace anonymous parts with { ... }
2457 int si=ldef.find(' '),pi,ei=i+l;
2459 while ((pi=r.match(ldef,i+l,&l))!=-1)
2464 int ni=ldef.find("::",si);
2465 if (ni>=ei) ei=ni+2;
2466 ldef = ldef.left(si) + " { ... } " + ldef.right(ldef.length()-ei);
2468 ClassDef *cd=getClassDef();
2469 if (cd && cd->isObjectiveC())
2472 int ep = ldef.find("::");
2475 int sp=ldef.findRev(' ',ep);
2478 ldef=ldef.left(sp+1)+ldef.mid(ep+2);
2482 int dp = ldef.find(':');
2485 ldef=ldef.left(dp+1);
2488 //printf("start >%s<\n",ldef.data());
2490 while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
2491 while (i>=0 && isspace((uchar)ldef.at(i))) i--;
2494 // insert braches around the type
2495 QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
2498 //printf("end >%s< i=%d\n",ldef.data(),i);
2499 if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
2501 SrcLangExt lang = getLanguage();
2502 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
2503 return substitute(ldef,"::",sep);
2506 void MemberDef::_writeGroupInclude(OutputList &ol,bool inGroup)
2508 // only write out the include file if this is not part of a class or file
2510 static bool showGroupedMembInc = Config_getBool(SHOW_GROUPED_MEMB_INC);
2511 FileDef *fd = getFileDef();
2513 if (fd) nm = getFileDef()->docName();
2514 if (inGroup && fd && showGroupedMembInc && !nm.isEmpty())
2516 ol.startParagraph();
2517 ol.startTypewriter();
2518 SrcLangExt lang = getLanguage();
2519 bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
2522 ol.docify("import ");
2526 ol.docify("#include ");
2529 if (isIDLorJava) ol.docify("\""); else ol.docify("<");
2531 if (fd->isLinkable())
2533 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),fd->anchor(),nm);
2540 if (isIDLorJava) ol.docify("\""); else ol.docify(">");
2547 /*! Writes the "detailed documentation" section of this member to
2548 * all active output formats.
2550 void MemberDef::writeDocumentation(MemberList *ml,
2551 int memCount,int memTotal,
2554 Definition *container,
2556 bool showEnumValues,
2560 // if this member is in a group find the real scope name.
2561 bool hasParameterList = FALSE;
2562 bool inFile = container->definitionType()==Definition::TypeFile;
2563 bool hasDocs = isDetailedSectionVisible(inGroup,inFile);
2565 //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d sectionLinkable=%d\n",
2566 // name().data(),hasDocs,container->definitionType(),inGroup,isDetailedSectionLinkable());
2568 //if ( !hasDocs ) return;
2569 //if (isEnumValue() && !showEnumValues) return;
2571 SrcLangExt lang = getLanguage();
2572 //printf("member=%s lang=%d\n",name().data(),lang);
2573 bool optVhdl = lang==SrcLangExt_VHDL;
2574 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
2576 QCString scopeName = scName;
2577 QCString memAnchor = anchor();
2578 QCString ciname = container->displayName();
2579 Definition *scopedContainer = container; // see bug 753608
2580 if (container->definitionType()==TypeGroup)
2582 if (getClassDef()) { scopeName=getClassDef()->displayName(); scopedContainer=getClassDef(); }
2583 else if (getNamespaceDef()) { scopeName=getNamespaceDef()->displayName(); scopedContainer=getNamespaceDef(); }
2584 else if (getFileDef()) { scopeName=getFileDef()->displayName(); scopedContainer=getFileDef(); }
2585 ciname = ((GroupDef *)container)->groupTitle();
2587 else if (container->definitionType()==TypeFile && getNamespaceDef() && lang != SrcLangExt_Python)
2588 { // member is in a namespace, but is written as part of the file documentation
2589 // as well, so we need to make sure its label is unique.
2590 memAnchor.prepend("file_");
2593 QCString cname = container->name();
2594 QCString cfname = getOutputFileBase();
2597 QCString doxyName=name();
2598 // prepend scope if there is any. TODO: make this optional for C only docs
2599 if (!scopeName.isEmpty())
2601 doxyName.prepend(scopeName+sep);
2603 QCString doxyArgs=argsString();
2605 QCString ldef = definition();
2606 QCString title = name();
2607 //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
2610 if (title.at(0)=='@')
2612 ldef = title = "anonymous enum";
2613 if (!m_impl->enumBaseType.isEmpty())
2615 ldef+=" : "+m_impl->enumBaseType;
2620 ldef.prepend("enum ");
2623 ldef.prepend("local ");
2627 else if (isEnumValue())
2629 if (ldef.at(0)=='@')
2634 else if (isFunction())
2639 static QRegExp r("@[0-9]+");
2641 if (lang == SrcLangExt_Slice)
2643 // Remove the container scope from the member name.
2644 QCString prefix = scName + sep;
2645 int pos = ldef.findRev(prefix.data());
2648 ldef.remove(pos, prefix.length());
2652 //----------------------------------------
2654 ol.pushGeneratorState();
2656 bool htmlEndLabelTable=FALSE;
2658 getLabels(sl,scopedContainer);
2660 if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
2662 // find enum type and insert it in the definition
2663 MemberListIterator vmli(*ml);
2666 for ( ; (vmd=vmli.current()) && !found ; ++vmli)
2668 if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
2670 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2671 ol.startMemberDoc(ciname,name(),memAnchor,name(),memCount,memTotal,showInline);
2672 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.left(i));
2673 vmd->writeEnumDeclaration(ol,getClassDef(),getNamespaceDef(),getFileDef(),getGroupDef());
2674 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.right(ldef.length()-i-l));
2679 if (!found) // anonymous compound
2681 //printf("Anonymous compound `%s'\n",cname.data());
2682 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2683 ol.startMemberDoc(ciname,name(),memAnchor,name(),memCount,memTotal,showInline);
2684 // search for the last anonymous compound name in the definition
2685 int si=ldef.find(' '),pi,ei=i+l;
2687 while ((pi=r.match(ldef,i+l,&l))!=-1)
2692 // first si characters of ldef contain compound type name
2693 ol.startMemberDocName(isObjCMethod());
2694 ol.docify(ldef.left(si));
2695 ol.docify(" { ... } ");
2696 // last ei characters of ldef contain pointer/reference specifiers
2697 int ni=ldef.find("::",si);
2698 if (ni>=ei) ei=ni+2;
2699 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.right(ldef.length()-ei));
2702 else // not an enum value or anonymous compound
2704 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2705 ol.startMemberDoc(ciname,name(),memAnchor,title,memCount,memTotal,showInline);
2707 if (!m_impl->metaData.isEmpty() && getLanguage()==SrcLangExt_Slice)
2709 ol.startMemberDocPrefixItem();
2710 ol.docify(m_impl->metaData);
2711 ol.endMemberDocPrefixItem();
2714 ClassDef *cd=getClassDef();
2715 NamespaceDef *nd=getNamespaceDef();
2716 if (!Config_getBool(HIDE_SCOPE_NAMES))
2719 SrcLangExt lang = getLanguage();
2720 if (m_impl->defTmpArgLists && lang==SrcLangExt_Cpp)
2721 // definition has explicit template parameter declarations
2723 QListIterator<ArgumentList> ali(*m_impl->defTmpArgLists);
2725 for (ali.toFirst();(tal=ali.current());++ali)
2729 if (!first) ol.docify(" ");
2730 ol.startMemberDocPrefixItem();
2731 writeTemplatePrefix(ol,tal);
2732 ol.endMemberDocPrefixItem();
2736 else // definition gets it template parameters from its class
2737 // (since no definition was found)
2739 if (cd && lang==SrcLangExt_Cpp && !isTemplateSpecialization())
2741 QList<ArgumentList> tempParamLists;
2742 cd->getTemplateParameterLists(tempParamLists);
2743 //printf("#tempParamLists=%d\n",tempParamLists.count());
2744 QListIterator<ArgumentList> ali(tempParamLists);
2746 for (ali.toFirst();(tal=ali.current());++ali)
2750 if (!first) ol.docify(" ");
2751 ol.startMemberDocPrefixItem();
2752 writeTemplatePrefix(ol,tal);
2753 ol.endMemberDocPrefixItem();
2757 if (m_impl->tArgList && lang==SrcLangExt_Cpp) // function template prefix
2759 ol.startMemberDocPrefixItem();
2760 writeTemplatePrefix(ol,m_impl->tArgList);
2761 ol.endMemberDocPrefixItem();
2768 ol.pushGeneratorState();
2770 ol.enable(OutputGenerator::Html);
2771 ol.writeString("<table class=\"mlabels\">\n");
2772 ol.writeString(" <tr>\n");
2773 ol.writeString(" <td class=\"mlabels-left\">\n");
2774 ol.popGeneratorState();
2775 htmlEndLabelTable=TRUE;
2778 ol.startMemberDocName(isObjCMethod());
2779 if (cd && cd->isObjectiveC())
2782 int ep = ldef.find("::");
2785 int sp=ldef.findRev(' ',ep);
2788 ldef=ldef.left(sp+1)+ldef.mid(ep+2);
2790 ldef=ldef.mid(ep+2);
2794 int dp = ldef.find(':');
2797 ldef=ldef.left(dp+1);
2799 int l=ldef.length();
2800 //printf("start >%s<\n",ldef.data());
2802 while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
2803 while (i>=0 && isspace((uchar)ldef.at(i))) i--;
2806 // insert braches around the type
2807 QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
2810 //printf("end >%s< i=%d\n",ldef.data(),i);
2811 if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
2816 hasParameterList=VhdlDocGen::writeVHDLTypeDocumentation(this,scopedContainer,ol);
2818 else if (lang==SrcLangExt_Slice)
2820 // Eliminate the self-reference.
2821 int pos = ldef.findRev(' ');
2822 linkifyText(TextGeneratorOLImpl(ol),
2828 ol.docify(ldef.mid(pos));
2829 Definition *scope = cd;
2830 if (scope==0) scope = nd;
2831 hasParameterList=writeDefArgumentList(ol,scope,this);
2835 linkifyText(TextGeneratorOLImpl(ol),
2839 substitute(ldef,"::",sep)
2841 Definition *scope = cd;
2842 if (scope==0) scope = nd;
2843 hasParameterList=writeDefArgumentList(ol,scope,this);
2846 if (hasOneLineInitializer()) // add initializer
2852 QCString init = m_impl->initializer.simplifyWhiteSpace();
2853 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,init);
2857 ol.writeNonBreakableSpace(3);
2858 linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,m_impl->initializer);
2861 if (excpString()) // add exception list
2863 writeExceptionList(ol,cd,this);
2864 hasParameterList=true; // call endParameterList below
2868 ol.pushGeneratorState();
2869 ol.disable(OutputGenerator::Html);
2873 const char *s=sl.first();
2876 const char *ns = sl.next();
2877 ol.writeLabel(s,ns==0);
2882 ol.popGeneratorState();
2884 if (hasParameterList)
2886 ol.endParameterList();
2887 ol.endMemberDoc(TRUE);
2891 ol.endMemberDocName();
2892 ol.endMemberDoc(FALSE);
2895 // for HTML write the labels here
2896 ol.pushGeneratorState();
2898 ol.enable(OutputGenerator::Html);
2899 if (htmlEndLabelTable)
2901 ol.writeString(" </td>\n");
2902 ol.writeString(" <td class=\"mlabels-right\">\n");
2904 const char *s=sl.first();
2907 const char *ns = sl.next();
2908 ol.writeLabel(s,ns==0);
2912 ol.writeString(" </td>\n");
2913 ol.writeString(" </tr>\n");
2914 ol.writeString("</table>\n");
2916 ol.writeString("</div>");
2917 ol.popGeneratorState();
2920 ol.endDoxyAnchor(cfname,memAnchor);
2923 _writeGroupInclude(ol,inGroup);
2925 /* write multi-line initializer (if any) */
2926 if (hasMultiLineInitializer()
2927 //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
2928 // || initLines<userInitLines // explicitly enabled
2932 //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
2934 if (m_impl->mtype==MemberType_Define)
2935 ol.parseText(theTranslator->trDefineValue());
2937 ol.parseText(theTranslator->trInitialValue());
2939 ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
2940 pIntf->resetCodeParserState();
2941 ol.startCodeFragment();
2942 pIntf->parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,getFileDef(),
2943 -1,-1,TRUE,this,FALSE,this);
2944 ol.endCodeFragment();
2947 QCString brief = briefDescription();
2948 QCString detailed = documentation();
2949 ArgumentList *docArgList = m_impl->defArgList;
2950 if (m_impl->templateMaster)
2952 brief = m_impl->templateMaster->briefDescription();
2953 detailed = m_impl->templateMaster->documentation();
2954 docArgList = m_impl->templateMaster->argumentList();
2957 /* write brief description */
2958 if (!brief.isEmpty() &&
2959 (Config_getBool(REPEAT_BRIEF) ||
2960 !Config_getBool(BRIEF_MEMBER_DESC)
2964 ol.startParagraph();
2965 ol.generateDoc(briefFile(),briefLine(),
2966 scopedContainer,this,
2967 brief,FALSE,FALSE,0,TRUE,FALSE);
2971 /* write detailed description */
2972 if (!detailed.isEmpty() ||
2973 !inbodyDocumentation().isEmpty())
2975 // write vhdl inline code with or without option INLINE_SOURCE
2976 if (optVhdl && VhdlDocGen::isMisc(this))
2978 VhdlDocGen::writeSource(this,ol,cname);
2983 ol.generateDoc(docFile(),docLine(),scopedContainer,this,detailed+"\n",TRUE,FALSE);
2986 if (!inbodyDocumentation().isEmpty())
2988 ol.generateDoc(inbodyFile(),inbodyLine(),
2989 scopedContainer,this,
2990 inbodyDocumentation()+"\n",TRUE,FALSE);
2993 else if (!brief.isEmpty() && (Config_getBool(REPEAT_BRIEF) ||
2994 !Config_getBool(BRIEF_MEMBER_DESC)))
2996 if (!inbodyDocumentation().isEmpty())
2998 ol.generateDoc(inbodyFile(),inbodyLine(),scopedContainer,this,inbodyDocumentation()+"\n",TRUE,FALSE);
3003 //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
3005 // defArgList?defArgList->hasDocumentation():-1);
3006 if (docArgList!=0 && docArgList->hasDocumentation())
3009 ArgumentListIterator ali(*docArgList);
3011 // convert the parameter documentation into a list of @param commands
3012 for (ali.toFirst();(a=ali.current());++ali)
3014 if (a->hasDocumentation())
3016 QCString direction = extractDirection(a->docs);
3017 paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
3020 // feed the result to the documentation parser
3022 docFile(),docLine(),
3025 paramDocs, // docStr
3032 _writeEnumValues(ol,scopedContainer,cfname,ciname,cname);
3033 _writeReimplements(ol);
3034 _writeReimplementedBy(ol);
3035 _writeCategoryRelation(ol);
3037 _writeTypeConstraints(ol);
3038 writeSourceDef(ol,cname);
3039 writeInlineCode(ol,cname);
3040 if (hasReferencesRelation()) writeSourceRefs(ol,cname);
3041 if (hasReferencedByRelation()) writeSourceReffedBy(ol,cname);
3042 _writeCallGraph(ol);
3043 _writeCallerGraph(ol);
3045 if (Doxygen::userComments)
3047 ol.pushGeneratorState();
3048 ol.disableAllBut(OutputGenerator::Html);
3049 QCString cmd = "<? $root=$_SERVER['DOCUMENT_ROOT']; "
3050 "passthru(\"$root/doxynotes --lookup "+
3051 getOutputFileBase()+":"+anchor()+"\") ?>";
3052 ol.writeString(cmd);
3053 ol.popGeneratorState();
3058 // enable LaTeX again
3059 //if (Config_getBool(EXTRACT_ALL) && !hasDocs) ol.enable(OutputGenerator::Latex);
3060 ol.popGeneratorState();
3062 warnIfUndocumentedParams();
3065 // strip scope and field name from the type
3066 // example: "struct N::S.v.c" will become "struct v"
3067 static QCString simplifyTypeForTable(const QCString &s)
3069 QCString ts=removeAnonymousScopes(s);
3070 if (ts.right(2)=="::") ts = ts.left(ts.length()-2);
3071 static QRegExp re("[A-Z_a-z0-9]+::");
3073 while ((i=re.match(ts,0,&l))!=-1)
3075 ts=ts.left(i)+ts.mid(i+l);
3078 if (i!=-1) ts = ts.left(i);
3080 if (i!=-1) ts = ts.right(ts.length()-i-1);
3081 //printf("simplifyTypeForTable(%s)->%s\n",s.data(),ts.data());
3086 /** Returns the type definition corresponding to a member's return type.
3087 * @param[in] scope The scope in which to search for the class definition.
3088 * @param[in] type The string representing the member's return type.
3089 * @param[in] lang The programming language in which the class is defined.
3090 * @param[out] start The string position where the class definition name was found.
3091 * @param[out] length The length of the class definition's name.
3093 static Definition *getClassFromType(Definition *scope,const QCString &type,SrcLangExt lang,int &start,int &length)
3099 while ((i=extractClassNameFromType(type,pos,name,templSpec,lang))!=-1)
3103 int l = name.length()+templSpec.length();
3104 if (!templSpec.isEmpty())
3106 cd = getResolvedClass(scope,0,name+templSpec,&md);
3108 cd = getResolvedClass(scope,0,name);
3113 printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
3120 printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
3129 QCString MemberDef::fieldType() const
3131 QCString type = m_impl->accessorType;
3134 type = m_impl->type;
3137 if (isTypedef() && getLanguage() != SrcLangExt_Slice) type.prepend("typedef ");
3138 return simplifyTypeForTable(type);
3141 void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container)
3143 Definition *scope = getOuterScope();
3144 QCString doxyName = name();
3145 QCString doxyArgs = argsString();
3146 QCString memAnchor = anchor();
3147 QCString cfname = getOutputFileBase();
3149 if (scope) cname = scope->name();
3150 if (doxyName.at(0)=='@')
3152 doxyName="__unnamed__";
3155 ClassDef *cd = m_impl->accessorClass;
3156 //printf("===> %s::anonymous: %s\n",name().data(),cd?cd->name().data():"<none>");
3158 if (container && container->definitionType()==Definition::TypeClass &&
3159 !((ClassDef*)container)->isJavaEnum())
3161 ol.startInlineMemberType();
3162 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
3164 QCString ts = fieldType();
3166 if (cd) // cd points to an anonymous struct pointed to by this member
3167 // so we add a link to it from the type column.
3170 const char *prefixes[] = { "struct ","union ","class ", 0 };
3171 const char **p = prefixes;
3182 ol.writeObjectLink(cd->getReference(),
3183 cd->getOutputFileBase(),
3184 cd->anchor(),ts.mid(i));
3186 else // use standard auto linking
3188 linkifyText(TextGeneratorOLImpl(ol), // out
3190 getBodyDef(), // fileScope
3195 ol.endDoxyAnchor(cfname,memAnchor);
3196 ol.endInlineMemberType();
3199 ol.startInlineMemberName();
3200 ol.docify(doxyName);
3201 if (isVariable() && argsString() && !isObjCMethod())
3203 linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,argsString());
3205 if (!m_impl->bitfields.isEmpty()) // add bitfields
3207 linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,m_impl->bitfields);
3209 ol.endInlineMemberName();
3211 ol.startInlineMemberDoc();
3213 QCString brief = briefDescription();
3214 QCString detailed = documentation();
3216 /* write brief description */
3217 if (!brief.isEmpty())
3219 ol.generateDoc(briefFile(),briefLine(),
3220 getOuterScope()?getOuterScope():container,this,
3221 brief,FALSE,FALSE,0,TRUE,FALSE);
3224 /* write detailed description */
3225 if (!detailed.isEmpty())
3227 ol.generateDoc(docFile(),docLine(),
3228 getOuterScope()?getOuterScope():container,this,
3229 detailed+"\n",FALSE,FALSE,0,FALSE,FALSE);
3233 ol.endInlineMemberDoc();
3236 QCString MemberDef::memberTypeName() const
3238 switch (m_impl->mtype)
3240 case MemberType_Define: return "macro definition";
3241 case MemberType_Function: return "function";
3242 case MemberType_Variable: return "variable";
3243 case MemberType_Typedef: return "typedef";
3244 case MemberType_Enumeration: return "enumeration";
3245 case MemberType_EnumValue: return "enumvalue";
3246 case MemberType_Signal: return "signal";
3247 case MemberType_Slot: return "slot";
3248 case MemberType_Friend: return "friend";
3249 case MemberType_DCOP: return "dcop";
3250 case MemberType_Property: return "property";
3251 case MemberType_Event: return "event";
3252 case MemberType_Interface: return "interface";
3253 case MemberType_Service: return "service";
3254 case MemberType_Sequence: return "sequence";
3255 case MemberType_Dictionary: return "dictionary";
3256 default: return "unknown";
3260 void MemberDef::warnIfUndocumented()
3263 * Removed bug_303020:
3264 * if (m_impl->memberGroup) return;
3266 ClassDef *cd = getClassDef();
3267 NamespaceDef *nd = getNamespaceDef();
3268 FileDef *fd = getFileDef();
3269 GroupDef *gd = getGroupDef();
3277 if (d->getLanguage() == SrcLangExt_Fortran)
3286 static bool extractAll = Config_getBool(EXTRACT_ALL);
3288 //printf("%s:warnIfUndoc: hasUserDocs=%d isFriendClass=%d protection=%d isRef=%d isDel=%d\n",
3290 // hasUserDocumentation(),isFriendClass(),protectionLevelVisible(m_impl->prot),isReference(),isDeleted());
3291 if ((!hasUserDocumentation() && !extractAll) &&
3293 name().find('@')==-1 && d && d->name().find('@')==-1 &&
3294 protectionLevelVisible(m_impl->prot) &&
3295 !isReference() && !isDeleted()
3298 warn_undoc(getDefFileName(),getDefLine(),"Member %s%s (%s) of %s %s is not documented.",
3299 qPrint(name()),qPrint(argsString()),qPrint(memberTypeName()),t,qPrint(d->name()));
3301 else if (!isDetailedSectionLinkable())
3303 warnIfUndocumentedParams();
3308 void MemberDef::warnIfUndocumentedParams()
3310 if (!Config_getBool(EXTRACT_ALL) &&
3311 Config_getBool(WARN_IF_UNDOCUMENTED) &&
3312 Config_getBool(WARN_NO_PARAMDOC) &&
3314 !Doxygen::suppressDocWarnings)
3316 if (!hasDocumentedParams())
3318 warn_doc_error(getDefFileName(),getDefLine(),
3319 "parameters of member %s are not (all) documented",
3320 qPrint(qualifiedName()));
3322 if (!hasDocumentedReturnType() &&
3323 isFunction() && hasDocumentation())
3325 warn_doc_error(getDefFileName(),getDefLine(),
3326 "return type of member %s is not documented",
3327 qPrint(qualifiedName()));
3332 bool MemberDef::isFriendClass() const
3334 return (isFriend() &&
3335 (m_impl->type=="friend class" || m_impl->type=="friend struct" ||
3336 m_impl->type=="friend union"));
3339 bool MemberDef::isDocumentedFriendClass() const
3342 QCString baseName=name();
3343 int i=baseName.find('<');
3344 if (i!=-1) baseName=baseName.left(i);
3345 return (isFriendClass() &&
3346 (fcd=getClass(baseName)) && fcd->isLinkable());
3349 bool MemberDef::isDeleted() const
3351 return m_impl->defArgList && m_impl->defArgList->isDeleted;
3354 bool MemberDef::hasDocumentation() const
3356 return Definition::hasDocumentation() ||
3357 (m_impl->mtype==MemberType_Enumeration && m_impl->docEnumValues) || // has enum values
3358 (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments
3362 bool MemberDef::hasUserDocumentation() const
3364 bool hasDocs = Definition::hasUserDocumentation();
3370 void MemberDef::setMemberGroup(MemberGroup *grp)
3372 m_impl->memberGroup = grp;
3375 bool MemberDef::visibleMemberGroup(bool hideNoHeader)
3377 return m_impl->memberGroup!=0 &&
3378 (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]");
3381 QCString MemberDef::getScopeString() const
3384 if (getClassDef()) result=getClassDef()->displayName();
3385 else if (getNamespaceDef()) result=getNamespaceDef()->displayName();
3390 static QCString escapeAnchor(const QCString &anchor)
3393 int l = anchor.length(),i;
3396 char c = anchor.at(i);
3397 if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
3403 static char hexStr[]="0123456789ABCDEF";
3404 char escChar[]={ '_', 0, 0, 0 };
3405 escChar[1]=hexStr[c>>4];
3406 escChar[2]=hexStr[c&0xf];
3414 void MemberDef::setAnchor()
3416 QCString memAnchor = name();
3417 if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
3419 memAnchor.prepend(definition()); // actually the method name is now included
3420 // twice, which is silly, but we keep it this way for backward
3423 // include number of template arguments as well,
3424 // to distinguish between two template
3425 // specializations that only differ in the template parameters.
3426 if (m_impl->tArgList)
3429 qsnprintf(buf,20,"%d:",m_impl->tArgList->count());
3431 memAnchor.prepend(buf);
3434 // convert to md5 hash
3436 QCString sigStr(33);
3437 MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig);
3438 //printf("memAnchor=%s\n",memAnchor.data());
3439 MD5SigToString(md5_sig,sigStr.rawData(),33);
3440 m_impl->anc = "a"+sigStr;
3443 void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri,
3444 const QCString &fileName,int startLine,
3445 bool hasDocs,MemberDef *member)
3447 //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data());
3449 m_impl->grouppri=pri;
3450 m_impl->groupFileName=fileName;
3451 m_impl->groupStartLine=startLine;
3452 m_impl->groupHasDocs=hasDocs;
3453 m_impl->groupMember=member;
3454 m_isLinkableCached = 0;
3457 void MemberDef::setEnumScope(MemberDef *md,bool livesInsideEnum)
3459 m_impl->enumScope=md;
3460 m_impl->livesInsideEnum=livesInsideEnum;
3461 if (md->getGroupDef())
3463 m_impl->group=md->getGroupDef();
3464 m_impl->grouppri=md->getGroupPri();
3465 m_impl->groupFileName=md->getGroupFileName();
3466 m_impl->groupStartLine=md->getGroupStartLine();
3467 m_impl->groupHasDocs=md->getGroupHasDocs();
3468 m_isLinkableCached = 0;
3472 void MemberDef::setMemberClass(ClassDef *cd)
3474 m_impl->classDef=cd;
3475 m_isLinkableCached = 0;
3476 m_isConstructorCached = 0;
3480 void MemberDef::setNamespace(NamespaceDef *nd)
3486 MemberDef *MemberDef::createTemplateInstanceMember(
3487 ArgumentList *formalArgs,ArgumentList *actualArgs)
3489 //printf(" Member %s %s %s\n",typeString(),name().data(),argsString());
3490 ArgumentList *actualArgList = 0;
3491 if (m_impl->defArgList)
3493 actualArgList = m_impl->defArgList->deepCopy();
3495 // replace formal arguments with actuals
3496 ArgumentListIterator ali(*actualArgList);
3498 for (;(arg=ali.current());++ali)
3500 arg->type = substituteTemplateArgumentsInString(arg->type,formalArgs,actualArgs);
3502 actualArgList->trailingReturnType =
3503 substituteTemplateArgumentsInString(actualArgList->trailingReturnType,formalArgs,actualArgs);
3506 QCString methodName=name();
3507 if (methodName.left(9)=="operator ") // conversion operator
3509 methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs);
3512 MemberDef *imd = new MemberDef(
3513 getDefFileName(),getDefLine(),getDefColumn(),
3514 substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs),
3516 substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs),
3517 m_impl->exception, m_impl->prot,
3518 m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0, ""
3520 imd->setArgumentList(actualArgList);
3521 imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs));
3522 imd->setBodyDef(getBodyDef());
3523 imd->setBodySegment(getStartBodyLine(),getEndBodyLine());
3524 //imd->setBodyMember(this);
3526 // TODO: init other member variables (if needed).
3527 // TODO: reimplemented info
3531 bool MemberDef::hasOneLineInitializer() const
3533 //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
3534 // name().data(),m_impl->initializer.data(),m_impl->initLines,
3535 // m_impl->maxInitLines,m_impl->userInitLines);
3536 return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
3537 ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
3540 bool MemberDef::hasMultiLineInitializer() const
3542 //printf("initLines=%d userInitLines=%d maxInitLines=%d\n",
3543 // initLines,userInitLines,maxInitLines);
3544 return m_impl->initLines>0 &&
3545 ((m_impl->initLines<m_impl->maxInitLines && m_impl->userInitLines==-1) // implicitly enabled
3546 || m_impl->initLines<m_impl->userInitLines // explicitly enabled
3550 void MemberDef::setInitializer(const char *initializer)
3552 m_impl->initializer=initializer;
3553 int l=m_impl->initializer.length();
3555 while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
3556 m_impl->initializer=m_impl->initializer.left(p+1);
3557 m_impl->initLines=m_impl->initializer.contains('\n');
3558 //printf("%s::setInitializer(%s)\n",name().data(),m_impl->initializer.data());
3561 void MemberDef::addListReference(Definition *)
3563 static bool optimizeOutputForC = Config_getBool(OPTIMIZE_OUTPUT_FOR_C);
3564 //static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
3565 //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
3566 //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
3567 SrcLangExt lang = getLanguage();
3569 if (!isLinkableInProject()) return;
3571 if (optimizeOutputForC)
3573 memLabel=theTranslator->trGlobal(TRUE,TRUE);
3575 else if (lang==SrcLangExt_Fortran)
3577 memLabel=theTranslator->trSubprogram(TRUE,TRUE);
3581 memLabel=theTranslator->trMember(TRUE,TRUE);
3583 QCString memName = name();
3584 Definition *pd=getOuterScope();
3585 QCString pdName = pd->definitionType()==Definition::TypeClass ?
3586 ((ClassDef*)pd)->displayName() : pd->name();
3587 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
3590 /* && commented out as a result of bug 597016
3592 (!hideScopeNames && // there is a scope
3593 pd && pd!=Doxygen::globalScope) // and we can show it
3595 (pd=getClassDef()) // it's a class so we
3596 // show the scope anyway
3603 memName = "[" + pd->name() + " " + name() + "]";
3607 if (pd!=Doxygen::globalScope) memName.prepend(pdName+sep);
3608 memArgs = argsString();
3611 QList<ListItemInfo> *xrefItems = xrefListItems();
3614 addRefItem(xrefItems,
3615 qualifiedName()+argsString(), // argsString is needed for overloaded functions (see bug 609624)
3617 getOutputFileBase()+"#"+anchor(),memName,memArgs,pd);
3621 MemberList *MemberDef::getSectionList(Definition *d) const
3624 sprintf(key,"%p",d);
3625 return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0;
3628 void MemberDef::setSectionList(Definition *d, MemberList *sl)
3630 //printf("MemberDef::setSectionList(%p,%p) name=%s\n",d,sl,name().data());
3632 sprintf(key,"%p",d);
3633 if (m_impl->classSectionSDict==0)
3635 m_impl->classSectionSDict = new SDict<MemberList>(7);
3637 m_impl->classSectionSDict->append(key,sl);
3640 Specifier MemberDef::virtualness(int count) const
3644 warn(getDefFileName(),getDefLine(),
3645 "Internal inconsistency: recursion detected in overload relation for member %s!"
3650 Specifier v = m_impl->virt;
3651 MemberDef *rmd = reimplements();
3652 while (rmd && v==Normal)
3654 v = rmd->virtualness(count+1)==Normal ? Normal : Virtual;
3655 rmd = rmd->reimplements();
3660 void MemberDef::writeTagFile(FTextStream &tagFile)
3662 if (!isLinkableInProject()) return;
3663 tagFile << " <member kind=\"";
3664 switch (m_impl->mtype)
3666 case MemberType_Define: tagFile << "define"; break;
3667 case MemberType_EnumValue: tagFile << "enumvalue"; break;
3668 case MemberType_Property: tagFile << "property"; break;
3669 case MemberType_Event: tagFile << "event"; break;
3670 case MemberType_Variable: tagFile << "variable"; break;
3671 case MemberType_Typedef: tagFile << "typedef"; break;
3672 case MemberType_Enumeration: tagFile << "enumeration"; break;
3673 case MemberType_Function: tagFile << "function"; break;
3674 case MemberType_Signal: tagFile << "signal"; break;
3675 case MemberType_Friend: tagFile << "friend"; break;
3676 case MemberType_DCOP: tagFile << "dcop"; break;
3677 case MemberType_Slot: tagFile << "slot"; break;
3678 case MemberType_Interface: tagFile << "interface"; break;
3679 case MemberType_Service: tagFile << "service"; break;
3680 case MemberType_Sequence: tagFile << "sequence"; break;
3681 case MemberType_Dictionary: tagFile << "dictionary"; break;
3683 if (m_impl->prot!=Public)
3685 tagFile << "\" protection=\"";
3686 if (m_impl->prot==Protected) tagFile << "protected";
3687 else if (m_impl->prot==Package) tagFile << "package";
3688 else /* Private */ tagFile << "private";
3690 if (m_impl->virt!=Normal)
3692 tagFile << "\" virtualness=\"";
3693 if (m_impl->virt==Virtual) tagFile << "virtual";
3694 else /* Pure */ tagFile << "pure";
3698 tagFile << "\" static=\"yes";
3700 tagFile << "\">" << endl;
3701 if (typeString()!=QCString("@"))
3703 tagFile << " <type>" << convertToXML(typeString()) << "</type>" << endl;
3705 tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
3706 tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
3707 tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
3708 QCString idStr = id();
3709 if (!idStr.isEmpty())
3711 tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
3713 tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
3716 MemberList *fmdl=m_impl->enumFields;
3719 MemberListIterator mli(*fmdl);
3721 for (mli.toFirst();(fmd=mli.current());++mli)
3723 if (!fmd->isReference())
3725 tagFile << " <enumvalue file=\"" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension);
3726 tagFile << "\" anchor=\"" << convertToXML(fmd->anchor());
3727 QCString idStr = fmd->id();
3728 if (!idStr.isEmpty())
3730 tagFile << "\" clangid=\"" << convertToXML(idStr);
3732 tagFile << "\">" << convertToXML(fmd->name()) << "</enumvalue>" << endl;
3737 writeDocAnchorsToTagFile(tagFile);
3738 tagFile << " </member>" << endl;
3741 void MemberDef::_computeIsConstructor()
3743 m_isConstructorCached=1; // FALSE
3744 if (m_impl->classDef)
3746 if (m_impl->isDMember) // for D
3748 m_isConstructorCached = name()=="this" ? 2 : 1;
3751 else if (getLanguage()==SrcLangExt_PHP) // for PHP
3753 m_isConstructorCached = name()=="__construct" ? 2 : 1;
3756 else if (name()=="__init__" &&
3757 getLanguage()==SrcLangExt_Python) // for Python
3759 m_isConstructorCached = 2; // TRUE
3762 else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
3764 m_isConstructorCached = name()=="constructor" ? 2 : 1;
3767 else // for other languages
3769 QCString locName = m_impl->classDef->localName();
3770 int i=locName.find('<');
3771 if (i==-1) // not a template class
3773 m_isConstructorCached = name()==locName ? 2 : 1;
3777 m_isConstructorCached = name()==locName.left(i) ? 2 : 1;
3784 bool MemberDef::isConstructor() const
3786 if (m_isConstructorCached==0)
3788 MemberDef *that = (MemberDef*)this;
3789 that->_computeIsConstructor();
3791 ASSERT(m_isConstructorCached>0);
3792 return m_isConstructorCached==2;
3796 void MemberDef::_computeIsDestructor()
3799 if (m_impl->isDMember) // for D
3801 isDestructor = name()=="~this";
3803 else if (getLanguage()==SrcLangExt_PHP) // for PHP
3805 isDestructor = name()=="__destruct";
3807 else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
3809 isDestructor = name()=="destructor";
3811 else if (name()=="__del__" &&
3812 getLanguage()==SrcLangExt_Python) // for Python
3816 else // other languages
3819 (name().find('~')!=-1 || name().find('!')!=-1) // The ! is for C++/CLI
3820 && name().find("operator")==-1;
3822 m_isDestructorCached = isDestructor ? 2 : 1;
3825 bool MemberDef::isDestructor() const
3827 if (m_isDestructorCached==0)
3829 MemberDef *that=(MemberDef*)this;
3830 that->_computeIsDestructor();
3832 ASSERT(m_isDestructorCached>0);
3833 return m_isDestructorCached==2;
3836 void MemberDef::writeEnumDeclaration(OutputList &typeDecl,
3837 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd)
3841 MemberList *fmdl=m_impl->enumFields;
3842 uint numVisibleEnumValues=0;
3845 MemberListIterator mli(*fmdl);
3847 for (mli.toFirst();(fmd=mli.current());++mli)
3849 if (fmd->isBriefSectionVisible()) numVisibleEnumValues++;
3852 if (numVisibleEnumValues==0 && !isBriefSectionVisible())
3857 QCString n = name();
3858 int i=n.findRev("::");
3859 if (i!=-1) n=n.right(n.length()-i-2); // strip scope (TODO: is this needed?)
3860 if (n[0]!='@') // not an anonymous enum
3862 if (isLinkableInProject() || hasDocumentedEnumValues())
3864 //_writeTagData(compoundType);
3865 _addToSearchIndex();
3866 writeLink(typeDecl,cd,nd,fd,gd);
3870 typeDecl.startBold();
3874 typeDecl.writeChar(' ');
3876 if (!m_impl->enumBaseType.isEmpty())
3878 typeDecl.writeChar(':');
3879 typeDecl.writeChar(' ');
3880 typeDecl.docify(m_impl->enumBaseType);
3881 typeDecl.writeChar(' ');
3884 uint enumValuesPerLine = (uint)Config_getInt(ENUM_VALUES_PER_LINE);
3885 if (numVisibleEnumValues>0 && enumValuesPerLine>0)
3887 typeDecl.docify("{ ");
3890 MemberListIterator mli(*fmdl);
3891 MemberDef *fmd=mli.current();
3892 bool fmdVisible = fmd ? fmd->isBriefSectionVisible() : TRUE;
3897 /* in html we start a new line after a number of items */
3898 if (numVisibleEnumValues>enumValuesPerLine
3899 && (enumMemCount%enumValuesPerLine)==0
3902 typeDecl.pushGeneratorState();
3903 typeDecl.disableAllBut(OutputGenerator::Html);
3904 typeDecl.enable(OutputGenerator::Latex);
3905 typeDecl.enable(OutputGenerator::Docbook);
3906 typeDecl.lineBreak();
3907 typeDecl.disable(OutputGenerator::Latex);
3908 typeDecl.disable(OutputGenerator::Docbook);
3909 typeDecl.writeString("  ");
3910 typeDecl.popGeneratorState();
3913 if (fmd->hasDocumentation()) // enum value has docs
3915 //fmd->_writeTagData(compoundType);
3916 fmd->_addToSearchIndex();
3917 fmd->writeLink(typeDecl,cd,nd,fd,gd);
3919 else // no docs for this enum value
3921 typeDecl.startBold();
3922 typeDecl.docify(fmd->name());
3925 if (fmd->hasOneLineInitializer()) // enum value has initializer
3927 //typeDecl.writeString(" = ");
3928 typeDecl.writeString(" ");
3929 typeDecl.parseText(fmd->initializer());
3933 bool prevVisible = fmdVisible;
3936 if (fmd && (fmdVisible=fmd->isBriefSectionVisible()))
3938 typeDecl.writeString(", ");
3942 typeDecl.disable(OutputGenerator::Man);
3943 typeDecl.writeString("\n"); // to prevent too long lines in LaTeX
3944 typeDecl.enable(OutputGenerator::Man);
3948 if (numVisibleEnumValues>enumValuesPerLine)
3950 typeDecl.pushGeneratorState();
3951 typeDecl.disableAllBut(OutputGenerator::Html);
3952 typeDecl.lineBreak();
3953 typeDecl.popGeneratorState();
3956 typeDecl.docify(" }");
3960 void MemberDef::setArgumentList(ArgumentList *al)
3962 if (m_impl->defArgList) delete m_impl->defArgList;
3963 m_impl->defArgList = al;
3966 void MemberDef::setDeclArgumentList(ArgumentList *al)
3968 if (m_impl->declArgList) delete m_impl->declArgList;
3969 m_impl->declArgList = al;
3972 void MemberDef::setTypeConstraints(ArgumentList *al)
3975 if (m_impl->typeConstraints) delete m_impl->typeConstraints;
3976 m_impl->typeConstraints = new ArgumentList;
3977 m_impl->typeConstraints->setAutoDelete(TRUE);
3978 ArgumentListIterator ali(*al);
3980 for (;(a=ali.current());++ali)
3982 m_impl->typeConstraints->append(new Argument(*a));
3986 void MemberDef::setType(const char *t)
3991 void MemberDef::setAccessorType(ClassDef *cd,const char *t)
3993 m_impl->accessorClass = cd;
3994 m_impl->accessorType = t;
3997 ClassDef *MemberDef::accessorClass() const
3999 return m_impl->accessorClass;
4002 void MemberDef::findSectionsInDocumentation()
4004 docFindSections(documentation(),this,0,docFile());
4007 void MemberDef::enableCallGraph(bool e)
4009 m_impl->hasCallGraph=e;
4010 if (e) Doxygen::parseSourcesNeeded = TRUE;
4013 void MemberDef::enableCallerGraph(bool e)
4015 m_impl->hasCallerGraph=e;
4016 if (e) Doxygen::parseSourcesNeeded = TRUE;
4019 void MemberDef::enableReferencedByRelation(bool e)
4021 m_impl->hasReferencedByRelation=e;
4022 if (e) Doxygen::parseSourcesNeeded = TRUE;
4025 void MemberDef::enableReferencesRelation(bool e)
4027 m_impl->hasReferencesRelation=e;
4028 if (e) Doxygen::parseSourcesNeeded = TRUE;
4032 bool MemberDef::protectionVisible() const
4034 return m_impl->prot==Public ||
4035 (m_impl->prot==Private && Config_getBool(EXTRACT_PRIVATE)) ||
4036 (m_impl->prot==Protected && Config_getBool(EXTRACT_PROTECTED)) ||
4037 (m_impl->prot==Package && Config_getBool(EXTRACT_PACKAGE));
4042 void MemberDef::setInbodyDocumentation(const char *docs,
4043 const char *docFile,int docLine)
4045 m_impl->inbodyDocs = docs;
4046 m_impl->inbodyDocs = m_impl->inbodyDocs.stripWhiteSpace();
4047 m_impl->inbodyLine = docLine;
4048 m_impl->inbodyFile = docFile;
4052 bool MemberDef::isObjCMethod() const
4054 if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE;
4058 bool MemberDef::isObjCProperty() const
4060 if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isProperty()) return TRUE;
4064 QCString MemberDef::qualifiedName() const
4069 if (isStatic()) qm="+"; else qm="-";
4071 qm+=m_impl->classDef->name()+" ";
4076 else if (m_impl->enumScope && m_impl->enumScope->isStrong())
4078 return m_impl->enumScope->qualifiedName()+
4079 getLanguageSpecificSeparator(getLanguage())+
4084 return Definition::qualifiedName();
4088 void MemberDef::setTagInfo(TagInfo *ti)
4092 //printf("%s: Setting tag name=%s anchor=%s\n",name().data(),ti->tagName.data(),ti->anchor.data());
4093 m_impl->anc=ti->anchor;
4094 setReference(ti->tagName);
4095 m_impl->explicitOutputFileBase = stripExtension(ti->fileName);
4099 QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const
4104 if (isStatic()) qm="+ "; else qm="- ";
4107 if (!localLink) // link to method of same class
4110 qm+=m_impl->classDef->name();
4116 const char *MemberDef::declaration() const
4118 return m_impl->decl;
4121 const char *MemberDef::definition() const
4126 const char *MemberDef::extraTypeChars() const
4128 return m_impl->extraTypeChars;
4131 const char *MemberDef::typeString() const
4133 return m_impl->type;
4136 const char *MemberDef::argsString() const
4138 return m_impl->args;
4141 const char *MemberDef::excpString() const
4143 return m_impl->exception;
4146 const char *MemberDef::bitfieldString() const
4148 return m_impl->bitfields;
4151 const QCString &MemberDef::initializer() const
4153 return m_impl->initializer;
4156 int MemberDef::initializerLines() const
4158 return m_impl->initLines;
4161 uint64 MemberDef::getMemberSpecifiers() const
4163 return m_impl->memSpec;
4166 ClassDef *MemberDef::getClassDef() const
4168 return m_impl->classDef;
4171 FileDef *MemberDef::getFileDef() const
4173 return m_impl->fileDef;
4176 NamespaceDef* MemberDef::getNamespaceDef() const
4178 return m_impl->nspace;
4181 const char *MemberDef::getReadAccessor() const
4183 return m_impl->read;
4186 const char *MemberDef::getWriteAccessor() const
4188 return m_impl->write;
4191 GroupDef *MemberDef::getGroupDef() const
4193 return m_impl->group;
4196 Grouping::GroupPri_t MemberDef::getGroupPri() const
4198 return m_impl->grouppri;
4201 const char *MemberDef::getGroupFileName() const
4203 return m_impl->groupFileName;
4206 int MemberDef::getGroupStartLine() const
4208 return m_impl->groupStartLine;
4211 bool MemberDef::getGroupHasDocs() const
4213 return m_impl->groupHasDocs;
4216 Protection MemberDef::protection() const
4218 return m_impl->prot;
4221 MemberType MemberDef::memberType() const
4223 return m_impl->mtype;
4226 bool MemberDef::isSignal() const
4228 return m_impl->mtype==MemberType_Signal;
4231 bool MemberDef::isSlot() const
4233 return m_impl->mtype==MemberType_Slot;
4236 bool MemberDef::isVariable() const
4238 return m_impl->mtype==MemberType_Variable;
4241 bool MemberDef::isEnumerate() const
4243 return m_impl->mtype==MemberType_Enumeration;
4246 bool MemberDef::isEnumValue() const
4248 return m_impl->mtype==MemberType_EnumValue;
4251 bool MemberDef::isTypedef() const
4253 return m_impl->mtype==MemberType_Typedef;
4256 bool MemberDef::isSequence() const
4258 return m_impl->mtype==MemberType_Sequence;
4261 bool MemberDef::isDictionary() const
4263 return m_impl->mtype==MemberType_Dictionary;
4266 bool MemberDef::isFunction() const
4268 return m_impl->mtype==MemberType_Function;
4271 bool MemberDef::isFunctionPtr() const
4273 return m_impl->mtype==MemberType_Variable && QCString(argsString()).find(")(")!=-1;
4276 bool MemberDef::isDefine() const
4278 return m_impl->mtype==MemberType_Define;
4281 bool MemberDef::isFriend() const
4283 return m_impl->mtype==MemberType_Friend;
4286 bool MemberDef::isDCOP() const
4288 return m_impl->mtype==MemberType_DCOP;
4291 bool MemberDef::isProperty() const
4293 return m_impl->mtype==MemberType_Property;
4296 bool MemberDef::isEvent() const
4298 return m_impl->mtype==MemberType_Event;
4301 bool MemberDef::isRelated() const
4303 return m_impl->related == Related;
4306 bool MemberDef::isForeign() const
4308 return m_impl->related == Foreign;
4311 bool MemberDef::isStatic() const
4313 return m_impl->stat;
4316 bool MemberDef::isInline() const
4318 return (m_impl->memSpec&Entry::Inline)!=0;
4321 bool MemberDef::isExplicit() const
4323 return (m_impl->memSpec&Entry::Explicit)!=0;
4326 bool MemberDef::isMutable() const
4328 return (m_impl->memSpec&Entry::Mutable)!=0;
4331 bool MemberDef::isGettable() const
4333 return (m_impl->memSpec&Entry::Gettable)!=0;
4336 bool MemberDef::isPrivateGettable() const
4338 return (m_impl->memSpec&Entry::PrivateGettable)!=0;
4341 bool MemberDef::isProtectedGettable() const
4343 return (m_impl->memSpec&Entry::ProtectedGettable)!=0;
4346 bool MemberDef::isSettable() const
4348 return (m_impl->memSpec&Entry::Settable)!=0;
4351 bool MemberDef::isPrivateSettable() const
4353 return (m_impl->memSpec&Entry::PrivateSettable)!=0;
4356 bool MemberDef::isProtectedSettable() const
4358 return (m_impl->memSpec&Entry::ProtectedSettable)!=0;
4361 bool MemberDef::isAddable() const
4363 return (m_impl->memSpec&Entry::Addable)!=0;
4366 bool MemberDef::isRemovable() const
4368 return (m_impl->memSpec&Entry::Removable)!=0;
4371 bool MemberDef::isRaisable() const
4373 return (m_impl->memSpec&Entry::Raisable)!=0;
4376 bool MemberDef::isReadable() const
4378 return (m_impl->memSpec&Entry::Readable)!=0;
4381 bool MemberDef::isWritable() const
4383 return (m_impl->memSpec&Entry::Writable)!=0;
4386 bool MemberDef::isFinal() const
4388 return (m_impl->memSpec&Entry::Final)!=0;
4391 bool MemberDef::isNew() const
4393 return (m_impl->memSpec&Entry::New)!=0;
4396 bool MemberDef::isSealed() const
4398 return (m_impl->memSpec&Entry::Sealed)!=0;
4401 bool MemberDef::isOverride() const
4403 return (m_impl->memSpec&Entry::Override)!=0;
4406 bool MemberDef::isInitonly() const
4408 return (m_impl->memSpec&Entry::Initonly)!=0;
4411 bool MemberDef::isAbstract() const
4413 return (m_impl->memSpec&Entry::Abstract)!=0;
4416 bool MemberDef::isOptional() const
4418 return (m_impl->memSpec&Entry::Optional)!=0;
4421 bool MemberDef::isRequired() const
4423 return (m_impl->memSpec&Entry::Required)!=0;
4426 bool MemberDef::isNonAtomic() const
4428 return (m_impl->memSpec&Entry::NonAtomic)!=0;
4431 bool MemberDef::isCopy() const
4433 return (m_impl->memSpec&Entry::Copy)!=0;
4436 bool MemberDef::isAssign() const
4438 return (m_impl->memSpec&Entry::Assign)!=0;
4441 bool MemberDef::isRetain() const
4443 return (m_impl->memSpec&Entry::Retain)!=0;
4446 bool MemberDef::isWeak() const
4448 return (m_impl->memSpec&Entry::Weak)!=0;
4451 bool MemberDef::isStrong() const
4453 return (m_impl->memSpec&Entry::Strong)!=0;
4456 bool MemberDef::isStrongEnumValue() const
4458 return m_impl->mtype==MemberType_EnumValue &&
4459 m_impl->enumScope &&
4460 m_impl->enumScope->isStrong();
4463 bool MemberDef::isUnretained() const
4465 return (m_impl->memSpec&Entry::Unretained)!=0;
4468 bool MemberDef::isAlias() const
4470 return (m_impl->memSpec&Entry::Alias)!=0;
4473 bool MemberDef::isDefault() const
4475 return (m_impl->memSpec&Entry::Default)!=0;
4478 bool MemberDef::isDelete() const
4480 return (m_impl->memSpec&Entry::Delete)!=0;
4483 bool MemberDef::isNoExcept() const
4485 return (m_impl->memSpec&Entry::NoExcept)!=0;
4488 bool MemberDef::isAttribute() const
4490 return (m_impl->memSpec&Entry::Attribute)!=0;
4493 bool MemberDef::isUNOProperty() const
4495 return (m_impl->memSpec&Entry::Property)!=0;
4498 bool MemberDef::isReadonly() const
4500 return (m_impl->memSpec&Entry::Readonly)!=0;
4503 bool MemberDef::isBound() const
4505 return (m_impl->memSpec&Entry::Bound)!=0;
4508 bool MemberDef::isConstrained() const
4510 return (m_impl->memSpec&Entry::Constrained)!=0;
4513 bool MemberDef::isTransient() const
4515 return (m_impl->memSpec&Entry::Transient)!=0;
4518 bool MemberDef::isMaybeVoid() const
4520 return (m_impl->memSpec&Entry::MaybeVoid)!=0;
4523 bool MemberDef::isMaybeDefault() const
4525 return (m_impl->memSpec&Entry::MaybeDefault)!=0;
4528 bool MemberDef::isMaybeAmbiguous() const
4530 return (m_impl->memSpec&Entry::MaybeAmbiguous)!=0;
4533 bool MemberDef::isPublished() const
4535 return (m_impl->memSpec&Entry::Published)!=0;
4539 bool MemberDef::isImplementation() const
4541 return m_impl->implOnly;
4544 bool MemberDef::isExternal() const
4546 return m_impl->explExt;
4549 bool MemberDef::isTemplateSpecialization() const
4551 return m_impl->tspec;
4554 bool MemberDef::hasDocumentedParams() const
4556 return m_impl->hasDocumentedParams;
4559 bool MemberDef::hasDocumentedReturnType() const
4561 return m_impl->hasDocumentedReturnType;
4564 bool MemberDef::showInCallGraph() const
4566 return isFunction() ||
4573 ClassDef *MemberDef::relatedAlso() const
4575 return m_impl->relatedAlso;
4578 bool MemberDef::hasDocumentedEnumValues() const
4580 return m_impl->docEnumValues;
4583 MemberDef *MemberDef::getAnonymousEnumType() const
4585 return m_impl->annEnumType;
4588 bool MemberDef::isDocsForDefinition() const
4590 return m_impl->docsForDefinition;
4593 MemberDef *MemberDef::getEnumScope() const
4595 return m_impl->enumScope;
4598 bool MemberDef::livesInsideEnum() const
4600 return m_impl->livesInsideEnum;
4603 bool MemberDef::isSliceLocal() const
4605 return (m_impl->memSpec&Entry::Local)!=0;
4608 MemberList *MemberDef::enumFieldList() const
4610 return m_impl->enumFields;
4613 ExampleSDict *MemberDef::getExamples() const
4615 return m_impl->exampleSDict;
4618 bool MemberDef::isPrototype() const
4620 return m_impl->proto;
4623 ArgumentList *MemberDef::argumentList() const
4625 return m_impl->defArgList;
4628 ArgumentList *MemberDef::declArgumentList() const
4630 return m_impl->declArgList;
4633 ArgumentList *MemberDef::templateArguments() const
4635 return m_impl->tArgList;
4638 QList<ArgumentList> *MemberDef::definitionTemplateParameterLists() const
4640 return m_impl->defTmpArgLists;
4643 int MemberDef::getMemberGroupId() const
4645 return m_impl->grpId;
4648 MemberGroup *MemberDef::getMemberGroup() const
4650 return m_impl->memberGroup;
4653 bool MemberDef::fromAnonymousScope() const
4655 return m_impl->annScope;
4658 bool MemberDef::anonymousDeclShown() const
4660 return m_impl->annUsed;
4663 void MemberDef::setAnonymousUsed()
4665 m_impl->annUsed = TRUE;
4668 bool MemberDef::hasCallGraph() const
4670 return m_impl->hasCallGraph;
4673 bool MemberDef::hasCallerGraph() const
4675 return m_impl->hasCallerGraph;
4678 bool MemberDef::hasReferencedByRelation() const
4680 return m_impl->hasReferencedByRelation;
4683 bool MemberDef::hasReferencesRelation() const
4685 return m_impl->hasReferencesRelation;
4688 MemberDef *MemberDef::templateMaster() const
4690 return m_impl->templateMaster;
4693 bool MemberDef::isTypedefValCached() const
4695 return m_impl->isTypedefValCached;
4698 ClassDef *MemberDef::getCachedTypedefVal() const
4700 return m_impl->cachedTypedefValue;
4703 QCString MemberDef::getCachedTypedefTemplSpec() const
4705 return m_impl->cachedTypedefTemplSpec;
4708 QCString MemberDef::getCachedResolvedTypedef() const
4710 //printf("MemberDef::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
4711 return m_impl->cachedResolvedType;
4714 MemberDef *MemberDef::memberDefinition() const
4716 return m_impl->memDef;
4719 MemberDef *MemberDef::memberDeclaration() const
4721 return m_impl->memDec;
4724 MemberDef *MemberDef::inheritsDocsFrom() const
4726 return m_impl->docProvider;
4729 MemberDef *MemberDef::getGroupAlias() const
4731 return m_impl->groupAlias;
4734 void MemberDef::setMemberType(MemberType t)
4737 m_isLinkableCached = 0;
4740 void MemberDef::setDefinition(const char *d)
4745 void MemberDef::setFileDef(FileDef *fd)
4748 m_isLinkableCached = 0;
4749 m_isConstructorCached = 0;
4750 m_isDestructorCached = 0;
4753 void MemberDef::setProtection(Protection p)
4756 m_isLinkableCached = 0;
4759 void MemberDef::setMemberSpecifiers(uint64 s)
4764 void MemberDef::mergeMemberSpecifiers(uint64 s)
4769 void MemberDef::setBitfields(const char *s)
4771 m_impl->bitfields = QCString(s).simplifyWhiteSpace();
4774 void MemberDef::setMaxInitLines(int lines)
4778 m_impl->userInitLines=lines;
4782 void MemberDef::setExplicitExternal(bool b)
4787 void MemberDef::setReadAccessor(const char *r)
4792 void MemberDef::setWriteAccessor(const char *w)
4797 void MemberDef::setTemplateSpecialization(bool b)
4802 void MemberDef::makeRelated()
4804 m_impl->related = Related;
4805 m_isLinkableCached = 0;
4808 void MemberDef::makeForeign()
4810 m_impl->related = Foreign;
4811 m_isLinkableCached = 0;
4814 void MemberDef::setHasDocumentedParams(bool b)
4816 m_impl->hasDocumentedParams = b;
4819 void MemberDef::setHasDocumentedReturnType(bool b)
4821 m_impl->hasDocumentedReturnType = b;
4824 void MemberDef::setInheritsDocsFrom(MemberDef *md)
4826 m_impl->docProvider = md;
4829 void MemberDef::setArgsString(const char *as)
4834 void MemberDef::setRelatedAlso(ClassDef *cd)
4836 m_impl->relatedAlso=cd;
4839 void MemberDef::setEnumClassScope(ClassDef *cd)
4841 m_impl->classDef = cd;
4842 m_isLinkableCached = 0;
4843 m_isConstructorCached = 0;
4846 void MemberDef::setDocumentedEnumValues(bool value)
4848 m_impl->docEnumValues=value;
4851 void MemberDef::setAnonymousEnumType(MemberDef *md)
4853 m_impl->annEnumType = md;
4856 void MemberDef::setPrototype(bool p)
4861 void MemberDef::setMemberGroupId(int id)
4866 void MemberDef::makeImplementationDetail()
4868 m_impl->implOnly=TRUE;
4871 void MemberDef::setFromAnonymousScope(bool b)
4876 void MemberDef::setFromAnonymousMember(MemberDef *m)
4881 MemberDef *MemberDef::fromAnonymousMember() const
4883 return m_impl->annMemb;
4886 void MemberDef::setTemplateMaster(MemberDef *mt)
4888 m_impl->templateMaster=mt;
4889 m_isLinkableCached = 0;
4892 void MemberDef::setDocsForDefinition(bool b)
4894 m_impl->docsForDefinition = b;
4897 void MemberDef::setGroupAlias(MemberDef *md)
4899 m_impl->groupAlias = md;
4902 void MemberDef::invalidateTypedefValCache()
4904 m_impl->isTypedefValCached=FALSE;
4907 void MemberDef::setMemberDefinition(MemberDef *md)
4912 void MemberDef::setMemberDeclaration(MemberDef *md)
4917 ClassDef *MemberDef::category() const
4919 return m_impl->category;
4922 void MemberDef::setCategory(ClassDef *def)
4924 m_impl->category = def;
4927 MemberDef *MemberDef::categoryRelation() const
4929 return m_impl->categoryRelation;
4932 void MemberDef::setCategoryRelation(MemberDef *md)
4934 m_impl->categoryRelation = md;
4937 void MemberDef::setEnumBaseType(const QCString &type)
4939 m_impl->enumBaseType = type;
4942 QCString MemberDef::enumBaseType() const
4944 return m_impl->enumBaseType;
4948 void MemberDef::cacheTypedefVal(ClassDef*val, const QCString & templSpec, const QCString &resolvedType)
4950 m_impl->isTypedefValCached=TRUE;
4951 m_impl->cachedTypedefValue=val;
4952 m_impl->cachedTypedefTemplSpec=templSpec;
4953 m_impl->cachedResolvedType=resolvedType;
4954 //printf("MemberDef::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
4957 void MemberDef::copyArgumentNames(MemberDef *bmd)
4960 ArgumentList *arguments = bmd->argumentList();
4961 if (m_impl->defArgList && arguments)
4963 ArgumentListIterator aliDst(*m_impl->defArgList);
4964 ArgumentListIterator aliSrc(*arguments);
4965 Argument *argDst, *argSrc;
4966 for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
4968 argDst->name = argSrc->name;
4973 ArgumentList *arguments = bmd->declArgumentList();
4974 if (m_impl->declArgList && arguments)
4976 ArgumentListIterator aliDst(*m_impl->declArgList);
4977 ArgumentListIterator aliSrc(*arguments);
4978 Argument *argDst, *argSrc;
4979 for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
4981 argDst->name = argSrc->name;
4987 static void invalidateCachedTypesInArgumentList(ArgumentList *al)
4991 ArgumentListIterator ali(*al);
4993 for (ali.toFirst();(a=ali.current());++ali)
4995 a->canType.resize(0);
5000 void MemberDef::invalidateCachedArgumentTypes()
5002 invalidateCachedTypesInArgumentList(m_impl->defArgList);
5003 invalidateCachedTypesInArgumentList(m_impl->declArgList);
5006 void MemberDef::addFlowKeyWord()
5011 int MemberDef::numberOfFlowKeyWords()
5013 return number_of_flowkw;
5018 QCString MemberDef::displayName(bool) const
5020 return Definition::name();
5023 void MemberDef::_addToSearchIndex()
5025 // write search index info
5026 if (Doxygen::searchIndex && isLinkableInProject())
5028 Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
5029 QCString ln=localName(),qn=qualifiedName();
5030 Doxygen::searchIndex->addWord(ln,TRUE);
5033 Doxygen::searchIndex->addWord(qn,TRUE);
5036 Doxygen::searchIndex->addWord(getClassDef()->displayName(),TRUE);
5038 else if (getNamespaceDef())
5040 Doxygen::searchIndex->addWord(getNamespaceDef()->displayName(),TRUE);
5050 static void transferArgumentDocumentation(ArgumentList *decAl,ArgumentList *defAl)
5054 ArgumentListIterator decAli(*decAl);
5055 ArgumentListIterator defAli(*defAl);
5056 Argument *decA,*defA;
5057 for (decAli.toFirst(),defAli.toFirst();
5058 (decA=decAli.current()) && (defA=defAli.current());
5061 //printf("Argument decA->name=%s (doc=%s) defA->name=%s (doc=%s)\n",
5062 // decA->name.data(),decA->docs.data(),
5063 // defA->name.data(),defA->docs.data()
5065 if (decA->docs.isEmpty() && !defA->docs.isEmpty())
5067 decA->docs = defA->docs.copy();
5069 else if (defA->docs.isEmpty() && !decA->docs.isEmpty())
5071 defA->docs = decA->docs.copy();
5077 void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef)
5079 //printf("mdec=%s isPrototype()=%d\n",mdec->name().data(),mdec->isPrototype());
5081 (mdef->isFunction() && !mdef->isStatic() && !mdef->isPrototype()) ||
5082 (mdef->isVariable() && !mdef->isExternal() && !mdef->isStatic())
5085 //printf("mdef=(%p,%s) mdec=(%p,%s)\n",
5086 // mdef, mdef ? mdef->name().data() : "",
5087 // mdec, mdec ? mdec->name().data() : "");
5089 ArgumentList *mdefAl = mdef->argumentList();
5090 ArgumentList *mdecAl = mdec->argumentList();
5091 if (matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl,
5092 mdec->getOuterScope(),mdec->getFileDef(),mdecAl,
5097 //printf("Found member %s: definition in %s (doc=`%s') and declaration in %s (doc=`%s')\n",
5098 // mn->memberName(),
5099 // mdef->getFileDef()->name().data(),mdef->documentation().data(),
5100 // mdec->getFileDef()->name().data(),mdec->documentation().data()
5103 // first merge argument documentation
5104 transferArgumentDocumentation(mdecAl,mdefAl);
5106 /* copy documentation between function definition and declaration */
5107 if (!mdec->briefDescription().isEmpty())
5109 mdef->setBriefDescription(mdec->briefDescription(),mdec->briefFile(),mdec->briefLine());
5111 else if (!mdef->briefDescription().isEmpty())
5113 mdec->setBriefDescription(mdef->briefDescription(),mdef->briefFile(),mdef->briefLine());
5115 if (!mdef->documentation().isEmpty())
5117 //printf("transferring docs mdef->mdec (%s->%s)\n",mdef->argsString(),mdec->argsString());
5118 mdec->setDocumentation(mdef->documentation(),mdef->docFile(),mdef->docLine());
5119 mdec->setDocsForDefinition(mdef->isDocsForDefinition());
5122 ArgumentList *mdefAlComb = new ArgumentList;
5123 stringToArgumentList(mdef->argsString(),mdefAlComb);
5124 transferArgumentDocumentation(mdefAl,mdefAlComb);
5125 mdec->setArgumentList(mdefAlComb);
5128 else if (!mdec->documentation().isEmpty())
5130 //printf("transferring docs mdec->mdef (%s->%s)\n",mdec->argsString(),mdef->argsString());
5131 mdef->setDocumentation(mdec->documentation(),mdec->docFile(),mdec->docLine());
5132 mdef->setDocsForDefinition(mdec->isDocsForDefinition());
5135 ArgumentList *mdecAlComb = new ArgumentList;
5136 stringToArgumentList(mdec->argsString(),mdecAlComb);
5137 transferArgumentDocumentation(mdecAl,mdecAlComb);
5138 mdef->setDeclArgumentList(mdecAlComb);
5141 if (!mdef->inbodyDocumentation().isEmpty())
5143 mdec->setInbodyDocumentation(mdef->inbodyDocumentation(),mdef->inbodyFile(),mdef->inbodyLine());
5145 else if (!mdec->inbodyDocumentation().isEmpty())
5147 mdef->setInbodyDocumentation(mdec->inbodyDocumentation(),mdec->inbodyFile(),mdec->inbodyLine());
5149 if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
5151 //printf("body mdec->mdef %d-%d\n",mdec->getStartBodyLine(),mdef->getEndBodyLine());
5152 mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine());
5153 mdef->setBodyDef(mdec->getBodyDef());
5154 //mdef->setBodyMember(mdec);
5156 else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
5158 //printf("body mdef->mdec %d-%d\n",mdef->getStartBodyLine(),mdec->getEndBodyLine());
5159 mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine());
5160 mdec->setBodyDef(mdef->getBodyDef());
5161 //mdec->setBodyMember(mdef);
5163 mdec->mergeMemberSpecifiers(mdef->getMemberSpecifiers());
5164 mdef->mergeMemberSpecifiers(mdec->getMemberSpecifiers());
5168 if (mdec->getGroupDef()==0 && mdef->getGroupDef()!=0)
5170 mdec->setGroupDef(mdef->getGroupDef(),
5171 mdef->getGroupPri(),
5174 mdef->hasDocumentation(),
5178 else if (mdef->getGroupDef()==0 && mdec->getGroupDef()!=0)
5180 mdef->setGroupDef(mdec->getGroupDef(),
5181 mdec->getGroupPri(),
5184 mdec->hasDocumentation(),
5190 mdec->mergeRefItems(mdef);
5191 mdef->mergeRefItems(mdec);
5193 mdef->setMemberDeclaration(mdec);
5194 mdec->setMemberDefinition(mdef);
5196 mdef->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
5197 mdef->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
5198 mdec->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
5199 mdec->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
5201 mdef->enableReferencedByRelation(mdec->hasReferencedByRelation() || mdef->hasReferencedByRelation());
5202 mdef->enableCallerGraph(mdec->hasReferencesRelation() || mdef->hasReferencesRelation());
5203 mdec->enableReferencedByRelation(mdec->hasReferencedByRelation() || mdef->hasReferencedByRelation());
5204 mdec->enableCallerGraph(mdec->hasReferencesRelation() || mdef->hasReferencesRelation());
5209 QCString MemberDef::briefDescription(bool abbr) const
5211 if (m_impl->templateMaster)
5213 return m_impl->templateMaster->briefDescription(abbr);
5217 return Definition::briefDescription(abbr);
5221 QCString MemberDef::documentation() const
5223 if (m_impl->templateMaster)
5225 return m_impl->templateMaster->documentation();
5229 return Definition::documentation();
5233 const ArgumentList *MemberDef::typeConstraints() const
5235 return m_impl->typeConstraints;
5238 bool MemberDef::isFriendToHide() const
5240 static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
5241 bool isFriendToHide = hideFriendCompounds &&
5242 (m_impl->type=="friend class" ||
5243 m_impl->type=="friend struct" ||
5244 m_impl->type=="friend union");
5245 return isFriendToHide;
5248 bool MemberDef::isNotFriend() const
5250 return !(isFriend() && isFriendToHide());
5253 bool MemberDef::isFunctionOrSignalSlot() const
5255 return isFunction() || isSlot() || isSignal();
5258 bool MemberDef::isRelatedOrFriend() const
5260 return isRelated() || isForeign() || (isFriend() && !isFriendToHide());
5263 bool MemberDef::isReference() const
5265 return Definition::isReference() ||
5266 (m_impl->templateMaster && m_impl->templateMaster->isReference());