1 /******************************************************************************
5 * Copyright (C) 1997-2012 by Dimitri van Heesch.
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
23 #include "memberdef.h"
24 #include "membername.h"
31 #include "outputlist.h"
33 #include "membergroup.h"
36 #include "docparser.h"
38 #include "searchindex.h"
39 #include "parserintf.h"
42 #include "vhdlscanner.h"
43 #include "vhdldocgen.h"
44 #include "arguments.h"
46 #define START_MARKER 0x4D454D5B // MEM[
47 #define END_MARKER 0x4D454D5D // MEM]
49 #if defined(_OS_WIN32_)
50 #define snprintf _snprintf
53 // Put this macro at the start of any method of MemberDef that can directly
54 // or indirectly access other MemberDefs. It prevents that the content
55 // pointed to by m_impl gets flushed to disk in the middle of the method call!
56 #define KEEP_RESIDENT_DURING_CALL makeResident();LockingPtr<MemberDef> lock(this,this)
58 //-----------------------------------------------------------------------------
60 int MemberDef::s_indentLevel = 0;
62 //-----------------------------------------------------------------------------
64 static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
67 QCString clRealName=n;
69 if ((i=clRealName.find('<'))!=-1)
71 clRealName=clRealName.left(i); // strip template specialization
73 if ((i=clRealName.findRev("::"))!=-1)
75 clRealName=clRealName.right(clRealName.length()-i-2);
77 while ((i=s.find(clRealName,p))!=-1)
80 uint j=clRealName.length()+i;
81 if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
82 { // add template names
83 //printf("Adding %s+%s\n",clRealName.data(),t.data());
87 { // template names already present
88 //printf("Adding %s\n",clRealName.data());
91 p=i+clRealName.length();
93 result+=s.right(s.length()-p);
94 //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
98 static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
99 const QCString & /*scopeName*/,MemberDef *md)
101 LockingPtr<ArgumentList> defArgList=(md->isDocsForDefinition()) ?
102 md->argumentList() : md->declArgumentList();
103 //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
104 if (defArgList==0 || md->isProperty())
106 return FALSE; // member has no function like argument list
108 if (!md->isDefine()) ol.docify(" ");
110 // simple argument list for tcl
111 if (md->getLanguage()==SrcLangExt_Tcl)
113 Argument *a=defArgList->first();
114 ol.startParameterName(FALSE);
117 if (a->defval.isEmpty())
119 ol.docify(a->name+" ");
123 ol.docify("?"+a->name+"? ");
125 a=defArgList->next();
127 ol.endParameterName(FALSE,FALSE,FALSE);
128 ol.endMemberDocName();
132 //printf("writeDefArgList(%d)\n",defArgList->count());
133 ol.pushGeneratorState();
134 //ol.disableAllBut(OutputGenerator::Html);
135 bool htmlOn = ol.isEnabled(OutputGenerator::Html);
136 bool latexOn = ol.isEnabled(OutputGenerator::Latex);
139 if (htmlOn) ol.enable(OutputGenerator::Html);
140 if (latexOn) ol.enable(OutputGenerator::Latex);
142 ol.endMemberDocName();
143 ol.startParameterList(!md->isObjCMethod());
146 ol.disable(OutputGenerator::Html);
147 ol.disable(OutputGenerator::Latex);
150 if (!md->isObjCMethod()) ol.docify("("); // start argument list
151 ol.endMemberDocName();
153 ol.popGeneratorState();
154 //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
156 Argument *a=defArgList->first();
161 int il=cName.find('<');
162 int ir=cName.findRev('>');
163 if (il!=-1 && ir!=-1 && ir>il)
165 cName=cName.mid(il,ir-il+1);
166 //printf("1. cName=%s\n",cName.data());
168 else if (cd->templateArguments())
170 cName=tempArgListToString(cd->templateArguments());
171 //printf("2. cName=%s\n",cName.data());
173 else // no template specifier
178 //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
181 bool paramTypeStarted=FALSE;
182 bool isDefine = md->isDefine();
185 if (isDefine || first)
187 ol.startParameterType(first,0);
188 paramTypeStarted=TRUE;
191 ol.endParameterType();
192 ol.startParameterName(TRUE);
195 QRegExp re(")("),res("(.*\\*");
196 int vp=a->type.find(re);
197 int wp=a->type.find(res);
199 // use the following to put the function pointer type before the name
200 bool hasFuncPtrType=FALSE;
202 if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
204 ol.docify(a->attrib+" ");
206 if (hasFuncPtrType) // argument type is a function pointer
208 //printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data());
209 QCString n=a->type.left(vp);
210 if (hasFuncPtrType) n=a->type.left(wp);
211 if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
212 if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
213 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,n);
215 else // non-function pointer type
218 if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
221 if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
222 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,n);
227 if (paramTypeStarted)
229 ol.endParameterType();
230 paramTypeStarted=FALSE;
232 ol.startParameterName(defArgList->count()<2);
236 ol.docify(a->type.mid(wp,vp-wp));
238 if (!a->name.isEmpty() || (a->name.isEmpty() && a->type=="...")) // argument has a name
240 //if (!hasFuncPtrType)
244 ol.disable(OutputGenerator::Man);
245 ol.disable(OutputGenerator::Latex);
247 ol.enable(OutputGenerator::Man);
248 if (latexOn) ol.enable(OutputGenerator::Latex);
249 if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name);
250 ol.disable(OutputGenerator::Man);
251 ol.disable(OutputGenerator::Latex);
253 ol.enable(OutputGenerator::Man);
254 if (latexOn) ol.enable(OutputGenerator::Latex);
256 if (!a->array.isEmpty())
260 if (hasFuncPtrType) // write the part of the argument type
261 // that comes after the name
263 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),
264 md,a->type.right(a->type.length()-vp));
266 if (!a->defval.isEmpty()) // write the default value
268 QCString n=a->defval;
269 if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
272 ol.startTypewriter();
273 linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,n,FALSE,TRUE,TRUE);
277 a=defArgList->next();
280 if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
284 if (md->isObjCMethod() && a->attrib.length()>=2)
286 //printf("Found parameter keyword %s\n",a->attrib.data());
288 key=a->attrib.mid(1,a->attrib.length()-2);
289 if (key!=",") key+=":"; // for normal keywords add colon
291 ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
292 if (paramTypeStarted)
294 ol.endParameterType();
296 ol.startParameterType(FALSE,key);
297 paramTypeStarted=TRUE;
301 ol.endParameterName(FALSE,FALSE,TRUE);
306 ol.pushGeneratorState();
307 ol.disable(OutputGenerator::Html);
308 ol.disable(OutputGenerator::Latex);
309 if (!md->isObjCMethod()) ol.docify(")"); // end argument list
311 if (htmlOn) ol.enable(OutputGenerator::Html);
312 if (latexOn) ol.enable(OutputGenerator::Latex);
313 if (first) ol.startParameterName(defArgList->count()<2);
314 ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
315 ol.popGeneratorState();
316 if (md->extraTypeChars())
318 ol.docify(md->extraTypeChars());
320 if (defArgList->constSpecifier)
324 if (defArgList->volatileSpecifier)
326 ol.docify(" volatile");
328 if (!defArgList->trailingReturnType.isEmpty())
330 linkifyText(TextGeneratorOLImpl(ol), // out
332 md->getBodyDef(), // fileScope
334 defArgList->trailingReturnType, // text
342 static void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
344 ol.docify("template<");
345 Argument *a=al->first();
351 if (a->defval.length()!=0)
354 ol.docify(a->defval);
357 if (a) ol.docify(", ");
362 QCString extractDirection(QCString &docs)
364 QRegExp re("\\[[^\\]]+\\]"); // [...]
366 if (re.match(docs,0,&l)==0)
368 int inPos = docs.find("in", 1,FALSE);
369 int outPos = docs.find("out",1,FALSE);
370 bool input = inPos!=-1 && inPos<l;
371 bool output = outPos!=-1 && outPos<l;
372 if (input || output) // in,out attributes
374 docs = docs.mid(l); // strip attributes
375 if (input && output) return "[in,out]";
376 else if (input) return "[in]";
377 else if (output) return "[out]";
383 //-----------------------------------------------------------------------------
384 //-----------------------------------------------------------------------------
385 //-----------------------------------------------------------------------------
392 void init(Definition *def,const char *t,const char *a,const char *e,
393 Protection p,Specifier v,bool s,Relationship r,
394 MemberDef::MemberType mt,const ArgumentList *tal,
395 const ArgumentList *al
398 ClassDef *classDef; // member of or related to
399 FileDef *fileDef; // member of file definition
400 NamespaceDef *nspace; // the namespace this member is in.
402 MemberDef *enumScope; // the enclosing scope, if this is an enum field
403 MemberDef *annEnumType; // the anonymous enum that is the type of this member
404 MemberList *enumFields; // enumeration fields
406 MemberDef *redefines; // the members that this member redefines
407 MemberList *redefinedBy; // the list of members that redefine this one
409 MemberDef *memDef; // member definition for this declaration
410 MemberDef *memDec; // member declaration for this definition
411 ClassDef *relatedAlso; // points to class marked by relatedAlso
413 ExampleSDict *exampleSDict; // a dictionary of all examples for quick access
415 QCString type; // return actual type
416 QCString accessorType; // return type that tell how to get to this member
417 ClassDef *accessorClass; // class that this member accesses (for anonymous types)
418 QCString args; // function arguments/variable array specifiers
419 QCString def; // member definition in code (fully qualified name)
420 QCString anc; // HTML anchor name
421 Specifier virt; // normal/virtual/pure virtual
422 Protection prot; // protection type [Public/Protected/Private]
423 QCString decl; // member declaration in class
425 QCString bitfields; // struct member bitfields
426 QCString read; // property read accessor
427 QCString write; // property write accessor
428 QCString exception; // exceptions that can be thrown
429 QCString initializer; // initializer
430 QCString extraTypeChars; // extra type info found after the argument list
431 QCString enumBaseType; // base type of the enum (C++11)
432 int initLines; // number of lines in the initializer
434 int memSpec; // The specifiers present for this member
435 MemberDef::MemberType mtype; // returns the kind of member
436 int maxInitLines; // when the initializer will be displayed
437 int userInitLines; // result of explicit \hideinitializer or \showinitializer
440 ArgumentList *defArgList; // argument list of this member definition
441 ArgumentList *declArgList; // argument list of this member declaration
443 ArgumentList *tArgList; // template argument list of function template
444 ArgumentList *typeConstraints; // type constraints for template parameters
445 MemberDef *templateMaster;
446 QList<ArgumentList> *defTmpArgLists; // lists of template argument lists
447 // (for template functions in nested template classes)
449 ClassDef *cachedAnonymousType; // if the member has an anonymous compound
450 // as its type then this is computed by
451 // getClassDefOfAnonymousType() and
453 SDict<MemberList> *classSectionSDict; // not accessible
455 MemberDef *groupAlias; // Member containing the definition
456 int grpId; // group id
457 MemberGroup *memberGroup; // group's member definition
458 GroupDef *group; // group in which this member is in
459 Grouping::GroupPri_t grouppri; // priority of this definition
460 QCString groupFileName; // file where this grouping was defined
461 int groupStartLine; // line " " " " "
462 MemberDef *groupMember;
464 bool isTypedefValCached;
465 ClassDef *cachedTypedefValue;
466 QCString cachedTypedefTemplSpec;
467 QCString cachedResolvedType;
469 // inbody documentation
471 //QCString inbodyFile;
472 //QCString inbodyDocs;
474 // documentation inheritance
475 MemberDef *docProvider;
477 // to store the output file base from tag files
478 QCString explicitOutputFileBase;
481 bool implOnly; // function found in implementation but not
483 bool hasDocumentedParams;
484 bool hasDocumentedReturnType;
486 Relationship related; // relationship of this to the class
487 bool stat; // is it a static function?
488 bool proto; // is it a prototype;
489 bool docEnumValues; // is an enum with documented enum values.
490 bool annScope; // member is part of an annoymous scope
494 bool explExt; // member was explicitly declared external
495 bool tspec; // member is a template specialization
496 bool groupHasDocs; // true if the entry that caused the grouping was documented
497 bool docsForDefinition; // TRUE => documentation block is put before
499 // FALSE => block is put before declaration.
501 MemberDef *categoryRelation;
504 MemberDefImpl::MemberDefImpl() :
513 classSectionSDict(0),
519 MemberDefImpl::~MemberDefImpl()
526 delete typeConstraints;
527 delete defTmpArgLists;
528 delete classSectionSDict;
532 void MemberDefImpl::init(Definition *def,
533 const char *t,const char *a,const char *e,
534 Protection p,Specifier v,bool s,Relationship r,
535 MemberDef::MemberType mt,const ArgumentList *tal,
536 const ArgumentList *al
554 hasCallGraph = FALSE;
555 hasCallerGraph = FALSE;
558 if (mt==MemberDef::Typedef) type.stripPrefix("typedef ");
559 // type.stripPrefix("struct ");
560 // type.stripPrefix("class " );
561 // type.stripPrefix("union " );
562 type=removeRedundantWhiteSpace(type);
564 args=removeRedundantWhiteSpace(args);
565 if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args;
583 cachedAnonymousType=0;
584 maxInitLines=Config_getInt("MAX_INITIALIZER_LINES");
587 // copy function template arguments (if any)
590 tArgList = tal->deepCopy();
596 //printf("new member al=%p\n",al);
597 // copy function definition arguments (if any)
600 defArgList = al->deepCopy();
606 // convert function declaration arguments (if any)
609 declArgList = new ArgumentList;
610 stringToArgumentList(args,declArgList,&extraTypeChars);
611 //printf("setDeclArgList %s to %s const=%d\n",args.data(),
612 // argListToString(declArgList).data(),declArgList->constSpecifier);
619 classSectionSDict = 0;
620 docsForDefinition = TRUE;
621 isTypedefValCached = FALSE;
622 cachedTypedefValue = 0;
626 hasDocumentedParams = FALSE;
627 hasDocumentedReturnType = FALSE;
629 isDMember = def->getDefFileName().right(2).lower()==".d";
633 //-----------------------------------------------------------------------------
634 //-----------------------------------------------------------------------------
635 //-----------------------------------------------------------------------------
637 /*! Creates a new member definition.
639 * \param df File containing the definition of this member.
640 * \param dl Line at which the member definition was found.
641 * \param t A string representing the type of the member.
642 * \param na A string representing the name of the member.
643 * \param a A string representing the arguments of the member.
644 * \param e A string representing the throw clause of the members.
645 * \param p The protection context of the member, possible values are:
646 * \c Public, \c Protected, \c Private.
647 * \param v The degree of `virtualness' of the member, possible values are:
648 * \c Normal, \c Virtual, \c Pure.
649 * \param s A boolean that is true iff the member is static.
650 * \param r The relationship between the class and the member.
651 * \param mt The kind of member. See #MemberDef::MemberType for a list of
653 * \param tal The template arguments of this member.
654 * \param al The arguments of this member. This is a structured form of
655 * the string past as argument \a a.
658 MemberDef::MemberDef(const char *df,int dl,
659 const char *t,const char *na,const char *a,const char *e,
660 Protection p,Specifier v,bool s,Relationship r,MemberType mt,
661 const ArgumentList *tal,const ArgumentList *al
662 ) : Definition(df,dl,removeRedundantWhiteSpace(na))
664 //printf("MemberDef::MemberDef(%s)\n",na);
667 m_impl = new MemberDefImpl;
668 m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al);
669 m_flushPending = FALSE;
670 m_isLinkableCached = 0;
671 m_isConstructorCached = 0;
672 m_isDestructorCached = 0;
675 MemberDef::MemberDef(const MemberDef &md) : Definition(md)
679 m_impl = new MemberDefImpl;
680 m_flushPending = FALSE;
681 m_isLinkableCached = 0;
682 m_isConstructorCached = 0;
683 m_isDestructorCached = 0;
686 MemberDef *MemberDef::deepCopy() const
689 //MemberDef *result = new MemberDef(getDefFileName(),getDefLine(),name());
690 MemberDef *result = new MemberDef(*this);
691 // first copy everything by reference
692 *result->m_impl = *m_impl;
693 // clear pointers owned by object
694 result->m_impl->redefinedBy= 0;
695 result->m_impl->exampleSDict=0;
696 result->m_impl->enumFields=0;
697 result->m_impl->defArgList=0;
698 result->m_impl->tArgList=0;
699 result->m_impl->typeConstraints=0;
700 result->m_impl->defTmpArgLists=0;
701 result->m_impl->classSectionSDict=0;
702 result->m_impl->declArgList=0;
703 // replace pointers owned by the object by deep copies
704 if (m_impl->redefinedBy)
706 MemberListIterator mli(*m_impl->redefinedBy);
708 for (mli.toFirst();(md=mli.current());++mli)
710 result->insertReimplementedBy(md);
713 if (m_impl->exampleSDict)
715 ExampleSDict::Iterator it(*m_impl->exampleSDict);
717 for (it.toFirst();(e=it.current());++it)
719 result->addExample(e->anchor,e->name,e->file);
722 if (m_impl->enumFields)
724 MemberListIterator mli(*m_impl->redefinedBy);
726 for (mli.toFirst();(md=mli.current());++mli)
728 result->insertEnumField(md);
731 if (m_impl->defArgList)
733 result->m_impl->defArgList = m_impl->defArgList->deepCopy();
735 if (m_impl->tArgList)
737 result->m_impl->tArgList = m_impl->tArgList->deepCopy();
739 if (m_impl->typeConstraints)
741 result->m_impl->typeConstraints = m_impl->typeConstraints->deepCopy();
743 result->setDefinitionTemplateParameterLists(m_impl->defTmpArgLists);
744 if (m_impl->classSectionSDict)
746 result->m_impl->classSectionSDict = new SDict<MemberList>(7);
747 SDict<MemberList>::IteratorDict it(*m_impl->classSectionSDict);
749 for (it.toFirst();(ml=it.current());++it)
751 result->m_impl->classSectionSDict->append(it.currentKey(),ml);
754 if (m_impl->declArgList)
756 result->m_impl->declArgList = m_impl->declArgList->deepCopy();
761 void MemberDef::moveTo(Definition *scope)
763 setOuterScope(scope);
764 if (scope->definitionType()==Definition::TypeClass)
766 m_impl->classDef = (ClassDef*)scope;
768 else if (scope->definitionType()==Definition::TypeFile)
770 m_impl->fileDef = (FileDef*)scope;
772 else if (scope->definitionType()==Definition::TypeNamespace)
774 m_impl->nspace = (NamespaceDef*)scope;
776 m_isLinkableCached = 0;
777 m_isConstructorCached = 0;
781 /*! Destroys the member definition. */
782 MemberDef::~MemberDef()
785 //printf("%p: ~MemberDef()\n",this);
787 if (m_cacheHandle!=-1)
789 Doxygen::symbolCache->del(m_cacheHandle);
794 void MemberDef::setReimplements(MemberDef *md)
798 m_impl->redefines = md;
801 void MemberDef::insertReimplementedBy(MemberDef *md)
804 if (m_impl->templateMaster)
806 m_impl->templateMaster->insertReimplementedBy(md);
808 if (m_impl->redefinedBy==0) m_impl->redefinedBy = new MemberList(MemberList::redefinedBy);
809 if (m_impl->redefinedBy->findRef(md)==-1)
811 m_impl->redefinedBy->inSort(md);
815 MemberDef *MemberDef::reimplements() const
818 return m_impl->redefines;
821 LockingPtr<MemberList> MemberDef::reimplementedBy() const
824 return LockingPtr<MemberList>(this,m_impl->redefinedBy);
827 bool MemberDef::isReimplementedBy(ClassDef *cd) const
830 if (cd && m_impl->redefinedBy)
832 MemberListIterator mi(*m_impl->redefinedBy);
834 for (mi.toFirst();(md=mi.current());++mi)
836 ClassDef *mcd = md->getClassDef();
839 if (cd==mcd || cd->isBaseClass(mcd,TRUE))
849 void MemberDef::insertEnumField(MemberDef *md)
852 if (m_impl->enumFields==0) m_impl->enumFields=new MemberList(MemberList::enumFields);
853 m_impl->enumFields->append(md);
856 bool MemberDef::addExample(const char *anchor,const char *nameStr,
860 //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
861 if (m_impl->exampleSDict==0) m_impl->exampleSDict = new ExampleSDict;
862 if (m_impl->exampleSDict->find(nameStr)==0)
864 //printf("Add reference to example %s to member %s\n",nameStr,name.data());
865 Example *e=new Example;
869 m_impl->exampleSDict->inSort(nameStr,e);
875 bool MemberDef::hasExamples()
878 if (m_impl->exampleSDict==0)
881 return m_impl->exampleSDict->count()>0;
884 QCString MemberDef::getOutputFileBase() const
887 static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
889 //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
890 // name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
891 // m_impl->nspace,m_impl->fileDef);
892 if (!m_impl->explicitOutputFileBase.isEmpty())
894 return m_impl->explicitOutputFileBase;
896 else if (m_impl->templateMaster)
898 return m_impl->templateMaster->getOutputFileBase();
900 else if (m_impl->group)
902 baseName=m_impl->group->getOutputFileBase();
904 else if (m_impl->classDef)
906 baseName=m_impl->classDef->getOutputFileBase();
908 else if (m_impl->nspace)
910 baseName=m_impl->nspace->getOutputFileBase();
912 else if (m_impl->fileDef)
914 baseName=m_impl->fileDef->getOutputFileBase();
917 if (baseName.isEmpty())
919 warn(getDefFileName(),getDefLine(),
920 "warning: Internal inconsistency: member %s does not belong to any"
921 " container!",qPrint(name())
925 else if (separateMemberPages)
927 if (getEnumScope()) // enum value, which is part of enum's documentation
929 baseName+="_"+getEnumScope()->anchor();
933 baseName+="_"+anchor();
939 QCString MemberDef::getReference() const
942 QCString ref = Definition::getReference();
947 if (m_impl->templateMaster)
949 return m_impl->templateMaster->getReference();
951 else if (m_impl->group)
953 return m_impl->group->getReference();
955 else if (m_impl->classDef)
957 return m_impl->classDef->getReference();
959 else if (m_impl->nspace)
961 return m_impl->nspace->getReference();
963 else if (m_impl->fileDef)
965 return m_impl->fileDef->getReference();
970 QCString MemberDef::anchor() const
972 KEEP_RESIDENT_DURING_CALL;
973 QCString result=m_impl->anc;
974 if (m_impl->groupAlias) return m_impl->groupAlias->anchor();
975 if (m_impl->templateMaster) return m_impl->templateMaster->anchor();
976 if (m_impl->enumScope && m_impl->enumScope!=this) // avoid recursion for C#'s public enum E { E, F }
978 result.prepend(m_impl->enumScope->anchor());
982 if (m_impl->groupMember)
984 result=m_impl->groupMember->anchor();
986 else if (getReference().isEmpty())
994 void MemberDef::_computeLinkableInProject()
996 KEEP_RESIDENT_DURING_CALL;
997 static bool extractStatic = Config_getBool("EXTRACT_STATIC");
998 m_isLinkableCached = 2; // linkable
999 //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
1002 //printf("is hidden\n");
1003 m_isLinkableCached = 1;
1006 if (m_impl->templateMaster)
1008 //printf("has template master\n");
1009 m_isLinkableCached = m_impl->templateMaster->isLinkableInProject() ? 2 : 1;
1012 if (name().isEmpty() || name().at(0)=='@')
1014 //printf("name invalid\n");
1015 m_isLinkableCached = 1; // not a valid or a dummy name
1018 if (!hasDocumentation() && !isReference())
1020 //printf("no docs or reference\n");
1021 m_isLinkableCached = 1; // no documentation
1024 if (m_impl->group && !m_impl->group->isLinkableInProject())
1026 //printf("group but group not linkable!\n");
1027 m_isLinkableCached = 1; // group but group not linkable
1030 if (!m_impl->group && m_impl->classDef && !m_impl->classDef->isLinkableInProject())
1032 //printf("in a class but class not linkable!\n");
1033 m_isLinkableCached = 1; // in class but class not linkable
1036 if (!m_impl->group && m_impl->nspace && !m_impl->related && !m_impl->nspace->isLinkableInProject())
1038 //printf("in a namespace but namespace not linkable!\n");
1039 m_isLinkableCached = 1; // in namespace but namespace not linkable
1042 if (!m_impl->group && !m_impl->nspace &&
1043 !m_impl->related && !m_impl->classDef &&
1044 m_impl->fileDef && !m_impl->fileDef->isLinkableInProject())
1046 //printf("in a file but file not linkable!\n");
1047 m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable
1050 if (!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=Friend)
1052 //printf("private and invisible!\n");
1053 m_isLinkableCached = 1; // hidden due to protection
1056 if (m_impl->stat && m_impl->classDef==0 && !extractStatic)
1058 //printf("static and invisible!\n");
1059 m_isLinkableCached = 1; // hidden due to staticness
1062 //printf("linkable!\n");
1063 return; // linkable!
1066 void MemberDef::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
1069 Definition::setDocumentation(d,docFile,docLine,stripWhiteSpace);
1070 m_isLinkableCached = 0;
1073 void MemberDef::setBriefDescription(const char *b,const char *briefFile,int briefLine)
1076 Definition::setBriefDescription(b,briefFile,briefLine);
1077 m_isLinkableCached = 0;
1080 void MemberDef::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine)
1083 Definition::setInbodyDocumentation(d,inbodyFile,inbodyLine);
1084 m_isLinkableCached = 0;
1087 void MemberDef::setHidden(bool b)
1090 Definition::setHidden(b);
1091 m_isLinkableCached = 0;
1094 bool MemberDef::isLinkableInProject() const
1096 if (m_isLinkableCached==0)
1098 MemberDef *that = (MemberDef*)this;
1099 that->_computeLinkableInProject();
1101 ASSERT(m_isLinkableCached>0);
1102 return m_isLinkableCached==2;
1105 bool MemberDef::isLinkable() const
1108 if (m_impl->templateMaster)
1110 return m_impl->templateMaster->isLinkable();
1114 return isLinkableInProject() || isReference();
1119 void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists)
1124 if (m_impl->defTmpArgLists) delete m_impl->defTmpArgLists;
1125 m_impl->defTmpArgLists = copyArgumentLists(lists);
1129 void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *,
1130 FileDef *fd,GroupDef *gd,bool onlyText)
1132 KEEP_RESIDENT_DURING_CALL;
1133 SrcLangExt lang = getLanguage();
1134 static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
1135 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
1136 QCString n = name();
1137 if (!hideScopeNames)
1139 if (m_impl->classDef && gd && !isRelated())
1141 n.prepend(m_impl->classDef->displayName()+sep);
1143 else if (m_impl->nspace && (gd || fd))
1145 n.prepend(m_impl->nspace->displayName()+sep);
1151 if (isStatic()) ol.docify("+ "); else ol.docify("- ");
1153 if (!onlyText && isLinkable()) // write link
1155 if (m_impl->mtype==EnumValue && getGroupDef()==0 && // enum value is not grouped
1156 getEnumScope() && getEnumScope()->getGroupDef()) // but its container is
1158 GroupDef *enumValGroup = getEnumScope()->getGroupDef();
1159 ol.writeObjectLink(enumValGroup->getReference(),
1160 enumValGroup->getOutputFileBase(),
1165 ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),n);
1168 else // write only text
1176 /*! If this member has an anonymous class/struct/union as its type, then
1177 * this method will return the ClassDef that describes this return type.
1179 ClassDef *MemberDef::getClassDefOfAnonymousType()
1181 // split KEEP_RESIDENT_DURING_CALL for performance
1183 if (m_impl->cachedAnonymousType) return m_impl->cachedAnonymousType;
1184 LockingPtr<MemberDef> lock(this,this); // since this memberDef can access
1185 // other memberDefs prevent it from
1186 // being flushed to disk halfway
1189 if (getClassDef()!=0)
1191 cname=getClassDef()->name().copy();
1193 else if (getNamespaceDef()!=0)
1195 cname=getNamespaceDef()->name().copy();
1197 QCString ltype(m_impl->type);
1198 // strip `static' keyword from ltype
1199 //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
1200 // strip `friend' keyword from ltype
1201 ltype.stripPrefix("friend ");
1202 static QRegExp r("@[0-9]+");
1203 int l,i=r.match(ltype,0,&l);
1204 //printf("ltype=`%s' i=%d\n",ltype.data(),i);
1205 // search for the last anonymous scope in the member type
1206 ClassDef *annoClassDef=0;
1207 if (i!=-1) // found anonymous scope in type
1210 // extract anonymous scope
1211 while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
1212 if (il>0) il++; else if (il<0) il=0;
1213 while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;
1215 QCString annName = ltype.mid(il,ir-il);
1217 // if inside a class or namespace try to prepend the scope name
1218 if (!cname.isEmpty() && annName.left(cname.length()+2)!=cname+"::")
1220 QCString ts=stripAnonymousNamespaceScope(cname+"::"+annName);
1221 annoClassDef=getClass(ts);
1223 // if not found yet, try without scope name
1224 if (annoClassDef==0)
1226 QCString ts=stripAnonymousNamespaceScope(annName);
1227 annoClassDef=getClass(ts);
1230 m_impl->cachedAnonymousType = annoClassDef;
1231 return annoClassDef;
1234 /*! This methods returns TRUE iff the brief section (also known as
1235 * declaration section) is visible in the documentation.
1237 bool MemberDef::isBriefSectionVisible() const
1239 static bool extractStatic = Config_getBool("EXTRACT_STATIC");
1240 static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
1241 static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
1242 static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
1243 static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
1245 //printf("Member %s grpId=%d docs=%s file=%s args=%s\n",
1247 // 0,"", //grpId,grpId==-1?"<none>":Doxygen::memberDocDict[grpId]->data(),
1248 // "", //getFileDef()->name().data(),
1251 KEEP_RESIDENT_DURING_CALL;
1253 MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId];
1254 //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
1255 //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
1256 bool hasDocs = hasDocumentation() ||
1257 // part of a documented member group
1258 (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
1260 // only include static members with file/namespace scope if
1261 // explicitly enabled in the config file
1262 bool visibleIfStatic = !(getClassDef()==0 &&
1267 // only include members is the are documented or
1268 // HIDE_UNDOC_MEMBERS is NO in the config file
1269 bool visibleIfDocumented = (!hideUndocMembers ||
1271 isDocumentedFriendClass()
1274 // hide members with no detailed description and brief descriptions
1275 // explicitly disabled.
1276 bool visibleIfEnabled = !(hideUndocMembers &&
1277 documentation().isEmpty() &&
1282 // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true
1283 bool visibleIfFriendCompound = !(hideFriendCompounds &&
1285 (m_impl->type=="friend class" ||
1286 m_impl->type=="friend struct" ||
1287 m_impl->type=="friend union"
1291 // only include members that are non-private unless EXTRACT_PRIVATE is
1292 // set to YES or the member is part of a group
1293 bool visibleIfPrivate = (protectionLevelVisible(protection()) ||
1294 m_impl->mtype==Friend
1297 // hide member if it overrides a member in a superclass and has no
1298 // documentation of its own
1299 //bool visibleIfDocVirtual = !reimplements() ||
1300 // !Config_getBool("INHERIT_DOCS") ||
1303 // true if this member is a constructor or destructor
1304 bool cOrDTor = isConstructor() || isDestructor();
1306 // hide default constructors or destructors (no args) without
1308 bool visibleIfNotDefaultCDTor = !(cOrDTor &&
1309 m_impl->defArgList &&
1310 (m_impl->defArgList->isEmpty() ||
1311 m_impl->defArgList->first()->type == "void"
1317 //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d "
1318 // "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d "
1319 // "visibleIfFriendCompound=%d !annScope=%d\n",
1320 // visibleIfStatic,visibleIfDocumented,
1321 // visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
1322 // visibleIfFriendCompound,!m_impl->annScope);
1324 bool visible = visibleIfStatic && visibleIfDocumented &&
1325 visibleIfEnabled && visibleIfPrivate &&
1326 /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor &&
1327 visibleIfFriendCompound &&
1328 !m_impl->annScope && !isHidden();
1329 //printf("MemberDef::isBriefSectionVisible() %d\n",visible);
1334 void MemberDef::writeDeclaration(OutputList &ol,
1335 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
1336 bool inGroup,ClassDef *inheritedFrom,const char *inheritId
1339 //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",name().data(),inGroup);
1341 // hide enum value, since they appear already as part of the enum, unless they
1342 // are explicitly grouped.
1343 KEEP_RESIDENT_DURING_CALL;
1344 if (!inGroup && m_impl->mtype==EnumValue) return;
1346 // hide members whose brief section should not be visible
1347 //if (!isBriefSectionVisible()) return;
1350 ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
1351 if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
1353 // write tag file information of this member
1354 if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !isReference())
1356 Doxygen::tagFile << " <member kind=\"";
1357 switch (m_impl->mtype)
1359 case Define: Doxygen::tagFile << "define"; break;
1360 case EnumValue: Doxygen::tagFile << "enumvalue"; break;
1361 case Property: Doxygen::tagFile << "property"; break;
1362 case Event: Doxygen::tagFile << "event"; break;
1363 case Variable: Doxygen::tagFile << "variable"; break;
1364 case Typedef: Doxygen::tagFile << "typedef"; break;
1365 case Enumeration: Doxygen::tagFile << "enumeration"; break;
1366 case Function: Doxygen::tagFile << "function"; break;
1367 case Signal: Doxygen::tagFile << "signal"; break;
1368 //case Prototype: Doxygen::tagFile << "prototype"; break;
1369 case Friend: Doxygen::tagFile << "friend"; break;
1370 case DCOP: Doxygen::tagFile << "dcop"; break;
1371 case Slot: Doxygen::tagFile << "slot"; break;
1373 if (m_impl->prot!=Public)
1375 Doxygen::tagFile << "\" protection=\"";
1376 if (m_impl->prot==Protected) Doxygen::tagFile << "protected";
1377 else if (m_impl->prot==Package) Doxygen::tagFile << "package";
1378 else /* Private */ Doxygen::tagFile << "private";
1380 if (m_impl->virt!=Normal)
1382 Doxygen::tagFile << "\" virtualness=\"";
1383 if (m_impl->virt==Virtual) Doxygen::tagFile << "virtual";
1384 else /* Pure */ Doxygen::tagFile << "pure";
1388 Doxygen::tagFile << "\" static=\"yes";
1390 Doxygen::tagFile << "\">" << endl;
1391 Doxygen::tagFile << " <type>" << convertToXML(typeString()) << "</type>" << endl;
1392 Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
1393 Doxygen::tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
1394 Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
1395 Doxygen::tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
1396 writeDocAnchorsToTagFile();
1397 Doxygen::tagFile << " </member>" << endl;
1400 // write search index info
1401 if (Doxygen::searchIndex && isLinkableInProject())
1403 Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
1404 Doxygen::searchIndex->addWord(localName(),TRUE);
1405 Doxygen::searchIndex->addWord(qualifiedName(),FALSE);
1408 QCString cname = d->name();
1409 QCString cdname = d->displayName();
1410 QCString cfname = getOutputFileBase();
1411 //QCString osname = cname;
1412 // in case of class members that are put in a group the name of the outerscope
1413 // differs from the cname.
1414 //if (getOuterScope()) osname=getOuterScope()->name();
1416 //HtmlHelp *htmlHelp=0;
1417 //bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
1418 //if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
1420 // search for the last anonymous scope in the member type
1421 ClassDef *annoClassDef=getClassDefOfAnonymousType();
1423 ol.startMemberDeclaration();
1425 // start a new member declaration
1426 bool isAnonymous = annoClassDef || m_impl->annMemb || m_impl->annEnumType;
1427 ///printf("startMemberItem for %s\n",name().data());
1428 ol.startMemberItem(anchor(),
1429 isAnonymous ? 1 : m_impl->tArgList ? 3 : 0,
1433 // If there is no detailed description we need to write the anchor here.
1434 bool detailsVisible = isDetailedSectionLinkable();
1435 if (!detailsVisible && !m_impl->annMemb)
1437 QCString doxyName=name().copy();
1438 if (!cname.isEmpty())
1440 doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage()));
1442 QCString doxyArgs=argsString();
1443 ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs);
1445 ol.pushGeneratorState();
1446 ol.disable(OutputGenerator::Man);
1447 ol.disable(OutputGenerator::Latex);
1449 ol.popGeneratorState();
1452 if (annoClassDef || m_impl->annMemb)
1455 for (j=0;j<s_indentLevel;j++)
1457 ol.writeNonBreakableSpace(3);
1461 // *** write template lists
1462 if (m_impl->tArgList && getLanguage()==SrcLangExt_Cpp)
1464 if (!isAnonymous) ol.startMemberTemplateParams();
1465 writeTemplatePrefix(ol,m_impl->tArgList);
1466 if (!isAnonymous) ol.endMemberTemplateParams(anchor(),inheritId);
1470 QCString ltype(m_impl->type);
1471 if (m_impl->mtype==Typedef) ltype.prepend("typedef ");
1476 // strip `friend' keyword from ltype
1477 ltype.stripPrefix("friend ");
1478 static QRegExp r("@[0-9]+");
1480 bool endAnonScopeNeeded=FALSE;
1481 int l,i=r.match(ltype,0,&l);
1482 if (i!=-1) // member has an anonymous type
1484 //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n",
1485 // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());
1487 if (annoClassDef) // type is an anonymous compound
1490 //printf("<<<<<<<<<<<<<<\n");
1491 ol.startAnonTypeScope(s_indentLevel++);
1492 annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup,inheritedFrom,inheritId);
1493 //printf(">>>>>>>>>>>>>> startMemberItem(2)\n");
1494 ol.startMemberItem(anchor(),2,inheritId);
1496 for (j=0;j< s_indentLevel-1;j++)
1498 ol.writeNonBreakableSpace(3);
1500 QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
1501 //printf(">>>>>> indDepth=%d ltype=`%s' varName=`%s'\n",indDepth,ltype.data(),varName.data());
1503 if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@'))
1507 endAnonScopeNeeded=TRUE;
1511 if (getAnonymousEnumType()) // type is an anonymous enum
1513 linkifyText(TextGeneratorOLImpl(ol), // out
1515 getBodyDef(), // fileScope
1517 ltype.left(i), // text
1520 getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd);
1521 //ol+=*getAnonymousEnumType()->enumDecl();
1522 linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,this,ltype.right(ltype.length()-i-l),TRUE);
1526 ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
1527 linkifyText(TextGeneratorOLImpl(ol), // out
1529 getBodyDef(), // fileScope
1537 else if (ltype=="@") // rename type from enum values
1548 linkifyText(TextGeneratorOLImpl(ol), // out
1550 getBodyDef(), // fileScope
1556 bool htmlOn = ol.isEnabled(OutputGenerator::Html);
1557 if (htmlOn && /*Config_getBool("HTML_ALIGN_MEMBERS") &&*/ !ltype.isEmpty())
1559 ol.disable(OutputGenerator::Html);
1561 if (!ltype.isEmpty()) ol.docify(" ");
1564 ol.enable(OutputGenerator::Html);
1567 if (m_impl->annMemb)
1569 ol.pushGeneratorState();
1570 ol.disableAllBut(OutputGenerator::Html);
1571 ol.writeNonBreakableSpace(3);
1572 ol.popGeneratorState();
1576 ol.insertMemberAlign(m_impl->tArgList!=0);
1580 if (!name().isEmpty() && name().at(0)!='@') // hide anonymous stuff
1582 //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable());
1583 if (!(name().isEmpty() || name().at(0)=='@') && // name valid
1584 (hasDocumentation() || isReference()) && // has docs
1585 !(m_impl->prot==Private && !Config_getBool("EXTRACT_PRIVATE") && m_impl->mtype!=Friend) && // hidden due to protection
1586 !(isStatic() && m_impl->classDef==0 && !Config_getBool("EXTRACT_STATIC")) // hidden due to static-ness
1589 if (m_impl->annMemb)
1591 //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
1592 m_impl->annMemb->writeLink(ol,
1593 m_impl->annMemb->getClassDef(),
1594 m_impl->annMemb->getNamespaceDef(),
1595 m_impl->annMemb->getFileDef(),
1596 m_impl->annMemb->getGroupDef()
1598 m_impl->annMemb->setAnonymousUsed();
1603 //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
1605 if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
1606 writeLink(ol,rcd,nd,fd,gd);
1609 else if (isDocumentedFriendClass())
1610 // if the member is an undocumented friend declaration for some class,
1611 // then maybe we can link to the class
1613 writeLink(ol,getClass(name()),0,0,0);
1616 // there is a brief member description and brief member
1617 // descriptions are enabled or there is no detailed description.
1619 if (m_impl->annMemb)
1621 m_impl->annMemb->setAnonymousUsed();
1625 if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
1626 writeLink(ol,rcd,nd,fd,gd,TRUE);
1631 if (isEnumerate() && name().at(0)=='@')
1633 // don't add to index
1635 else // index member
1637 //static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
1638 //QCString cfname = getOutputFileBase();
1639 //QCString cfiname = d->getOutputFileBase();
1640 //Doxygen::indexList.addIndexItem(
1642 // name(), // level2
1643 // separateMemPages ? cfname : cfiname, // contRef
1644 // cfname, // memRef
1645 // anchor(), // anchor
1646 // this); // memberdef
1647 Doxygen::indexList.addIndexItem(d,this);
1650 // *** write arguments
1651 if (argsString() && !isObjCMethod())
1653 if (!isDefine()) ol.writeString(" ");
1654 linkifyText(TextGeneratorOLImpl(ol), // out
1656 getBodyDef(), // fileScope
1658 argsString(), // text
1659 m_impl->annMemb, // autoBreak
1661 FALSE, // keepSpaces
1665 // *** write exceptions
1668 ol.writeString(" ");
1669 ol.docify(excpString());
1672 // *** write bitfields
1673 if (!m_impl->bitfields.isEmpty()) // add bitfields
1675 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->bitfields.simplifyWhiteSpace());
1677 else if (hasOneLineInitializer()
1678 //!init.isEmpty() && initLines==0 && // one line initializer
1679 //((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
1680 ) // add initializer
1684 //ol.writeString(" = ");
1685 ol.writeString(" ");
1686 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer.simplifyWhiteSpace());
1690 ol.writeNonBreakableSpace(3);
1691 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer);
1694 else if (isAlias()) // using template alias
1696 ol.writeString(" = ");
1697 linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->type);
1701 if ((isObjCMethod() || isObjCProperty()) && isImplementation())
1703 ol.startTypewriter();
1704 ol.docify(" [implementation]");
1708 if (isProperty() && (isSettable() || isGettable()))
1710 ol.writeLatexSpacing();
1711 ol.startTypewriter();
1714 if (isGettable()) sl.append("get");
1715 if (isSettable()) sl.append("set");
1716 const char *s=sl.first();
1721 if (s) ol.docify(", ");
1727 if (isEvent() && (isAddable() || isRemovable() || isRaisable()))
1729 ol.writeLatexSpacing();
1730 ol.startTypewriter();
1733 if (isAddable()) sl.append("add");
1734 if (isRemovable()) sl.append("remove");
1735 if (isRaisable()) sl.append("raise");
1736 const char *s=sl.first();
1741 if (s) ol.docify(", ");
1747 if (!detailsVisible && !m_impl->annMemb)
1749 ol.endDoxyAnchor(cfname,anchor());
1752 //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
1753 // name().data(),annoClassDef,annEnumType);
1755 if (endAnonScopeNeeded)
1757 ol.endAnonTypeScope(--s_indentLevel);
1760 // write brief description
1761 if (!briefDescription().isEmpty() &&
1762 Config_getBool("BRIEF_MEMBER_DESC")
1766 ol.startMemberDescription(anchor(),inheritId);
1767 ol.parseDoc(briefFile(),briefLine(),
1768 getOuterScope()?getOuterScope():d,this,briefDescription(),
1769 TRUE,FALSE,0,TRUE,FALSE);
1772 ol.pushGeneratorState();
1773 ol.disableAllBut(OutputGenerator::Html);
1776 if (m_impl->group!=0 && gd==0) // forward link to the group
1778 ol.startTextLink(getOutputFileBase(),anchor());
1782 ol.startTextLink(0,anchor());
1785 //ol.startEmphasis();
1786 ol.popGeneratorState();
1788 // for RTF we need to add an extra empty paragraph
1789 ol.pushGeneratorState();
1790 ol.disableAllBut(OutputGenerator::RTF);
1791 ol.startParagraph();
1793 ol.popGeneratorState();
1794 ol.endMemberDescription();
1797 ol.endMemberDeclaration(anchor(),inheritId);
1799 warnIfUndocumented();
1802 bool MemberDef::isDetailedSectionLinkable() const
1804 static bool extractAll = Config_getBool("EXTRACT_ALL");
1805 static bool alwaysDetailedSec = Config_getBool("ALWAYS_DETAILED_SEC");
1806 static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
1807 static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
1808 static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
1809 static bool extractStatic = Config_getBool("EXTRACT_STATIC");
1811 KEEP_RESIDENT_DURING_CALL;
1813 // the member has details documentation for any of the following reasons
1815 // treat everything as documented
1817 // has detailed docs
1818 !documentation().isEmpty() ||
1820 !inbodyDocumentation().isEmpty() ||
1821 // is an enum with values that are documented
1822 (m_impl->mtype==Enumeration && m_impl->docEnumValues) ||
1823 // is documented enum value
1824 (m_impl->mtype==EnumValue && !briefDescription().isEmpty()) ||
1825 // has brief description that is part of the detailed description
1826 (!briefDescription().isEmpty() && // has brief docs
1827 (alwaysDetailedSec && // they are visible in
1828 (repeatBrief || // detailed section or
1829 !briefMemberDesc // they are explicitly not
1830 ) // shown in brief section
1833 // has a multi-line initialization block
1834 //(initLines>0 && initLines<maxInitLines) ||
1835 (hasMultiLineInitializer() && !hideUndocMembers) ||
1836 // has one or more documented arguments
1837 (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()) ||
1838 // has user comments
1839 Doxygen::userComments
1842 // this is not a global static or global statics should be extracted
1843 bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic;
1845 // only include members that are non-private unless EXTRACT_PRIVATE is
1846 // set to YES or the member is part of a group
1847 bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==Friend;
1849 // member is part of an anonymous scope that is the type of
1850 // another member in the list.
1852 //bool inAnonymousScope = !briefDescription().isEmpty() && annUsed;
1854 // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS
1856 bool friendCompoundFilter = !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
1858 (m_impl->type=="friend class" ||
1859 m_impl->type=="friend struct" ||
1860 m_impl->type=="friend union"
1865 bool result = ((docFilter && staticFilter && privateFilter && friendCompoundFilter && !isHidden()));
1866 //printf("%s::isDetailedSectionLinkable: %d\n",name().data(),result);
1870 bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const
1872 static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
1873 static bool inlineSimpleStructs = Config_getBool("INLINE_SIMPLE_STRUCTS");
1874 static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
1875 bool groupFilter = getGroupDef()==0 || inGroup || separateMemPages;
1876 bool fileFilter = getNamespaceDef()==0 || !inFile;
1877 bool simpleFilter = !hideUndocMembers && inlineSimpleStructs &&
1878 getClassDef()!=0 && getClassDef()->isSimple();
1880 bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter &&
1882 bool result = visible || simpleFilter;
1883 //printf("%s::isDetailedSectionVisble: %d groupFilter=%d fileFilter=%d\n",
1884 // name().data(),result,groupFilter,fileFilter);
1888 void MemberDef::_getLabels(QStrList &sl,Definition *container) const
1890 static bool inlineInfo = Config_getBool("INLINE_INFO");
1892 Specifier lvirt=virtualness();
1893 if ((!isObjCMethod() || isOptional() || isRequired()) &&
1894 (protection()!=Public || lvirt!=Normal ||
1895 isFriend() || isRelated() ||
1896 (isInline() && inlineInfo) ||
1897 isSignal() || isSlot() ||
1899 (m_impl->classDef && m_impl->classDef!=container && container->definitionType()==TypeClass) ||
1900 (m_impl->memSpec & ~Entry::Inline)!=0
1904 // write the member specifier list
1905 //ol.writeLatexSpacing();
1906 //ol.startTypewriter();
1908 SrcLangExt lang = getLanguage();
1909 bool optVhdl = lang==SrcLangExt_VHDL;
1912 sl.append(VhdlDocGen::trTypeString(getMemberSpecifiers()));
1916 if (isFriend()) sl.append("friend");
1917 else if (isRelated()) sl.append("related");
1920 if (Config_getBool("INLINE_INFO") && isInline()) sl.append("inline");
1921 if (isExplicit()) sl.append("explicit");
1922 if (isMutable()) sl.append("mutable");
1923 if (isStatic()) sl.append("static");
1924 if (isGettable()) sl.append("get");
1925 if (isSettable()) sl.append("set");
1926 if (isAddable()) sl.append("add");
1927 if (isRemovable()) sl.append("remove");
1928 if (isRaisable()) sl.append("raise");
1929 if (isReadable()) sl.append("read");
1930 if (isWritable()) sl.append("write");
1931 if (isFinal()) sl.append("final");
1932 if (isAbstract()) sl.append("abstract");
1933 if (isOverride()) sl.append("override");
1934 if (isInitonly()) sl.append("initonly");
1935 if (isSealed()) sl.append("sealed");
1936 if (isNew()) sl.append("new");
1937 if (isOptional()) sl.append("optional");
1938 if (isRequired()) sl.append("required");
1940 if (isNonAtomic()) sl.append("nonatomic");
1941 else if (isObjCProperty()) sl.append("atomic");
1943 // mutual exclusive Objective 2.0 property attributes
1944 if (isAssign()) sl.append("assign");
1945 else if (isCopy()) sl.append("copy");
1946 else if (isRetain()) sl.append("retain");
1947 else if (isWeak()) sl.append("weak");
1948 else if (isStrong()) sl.append("strong");
1949 else if (isUnretained()) sl.append("unsafe_unretained");
1951 if (!isObjCMethod())
1953 if (protection()==Protected) sl.append("protected");
1954 else if (protection()==Private) sl.append("private");
1955 else if (protection()==Package) sl.append("package");
1957 if (lvirt==Virtual) sl.append("virtual");
1958 else if (lvirt==Pure) sl.append("pure virtual");
1959 if (isSignal()) sl.append("signal");
1960 if (isSlot()) sl.append("slot");
1961 if (isDefault()) sl.append("default");
1962 if (isDelete()) sl.append("delete");
1963 if (isNoExcept()) sl.append("noexcept");
1965 if (isObjCProperty() && isImplementation())
1967 sl.append("implementation");
1970 if (m_impl->classDef &&
1971 container->definitionType()==TypeClass &&
1972 m_impl->classDef!=container &&
1976 sl.append("inherited");
1980 else if (isObjCMethod() && isImplementation())
1982 sl.append("implementation");
1986 void MemberDef::_writeCallGraph(OutputList &ol)
1989 if ((m_impl->hasCallGraph || Config_getBool("CALL_GRAPH"))
1990 && (isFunction() || isSlot() || isSignal()) && Config_getBool("HAVE_DOT")
1993 DotCallGraph callGraph(this,FALSE);
1994 if (callGraph.isTooBig())
1996 err("warning: Call graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
1998 else if (!callGraph.isTrivial())
2000 msg("Generating call graph for function %s\n",qPrint(qualifiedName()));
2001 ol.disable(OutputGenerator::Man);
2002 ol.startParagraph();
2003 ol.startCallGraph();
2004 ol.parseText(theTranslator->trCallGraph());
2005 ol.endCallGraph(callGraph);
2012 void MemberDef::_writeCallerGraph(OutputList &ol)
2014 if ((m_impl->hasCallerGraph || Config_getBool("CALLER_GRAPH"))
2015 && (isFunction() || isSlot() || isSignal()) && Config_getBool("HAVE_DOT")
2018 DotCallGraph callerGraph(this, TRUE);
2019 if (callerGraph.isTooBig())
2021 err("warning: Caller graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
2023 else if (!callerGraph.isTrivial() && !callerGraph.isTooBig())
2025 msg("Generating caller graph for function %s\n",qPrint(qualifiedName()));
2026 ol.disable(OutputGenerator::Man);
2027 ol.startParagraph();
2028 ol.startCallGraph();
2029 ol.parseText(theTranslator->trCallerGraph());
2030 ol.endCallGraph(callerGraph);
2037 void MemberDef::_writeReimplements(OutputList &ol)
2039 MemberDef *bmd=reimplements();
2041 if (bmd && (bcd=bmd->getClassDef()))
2043 // write class that contains a member that is reimplemented by this one
2044 if (bcd->isLinkable())
2046 ol.startParagraph();
2047 QCString reimplFromLine;
2048 if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
2050 reimplFromLine = theTranslator->trReimplementedFromList(1);
2054 reimplFromLine = theTranslator->trImplementedFromList(1);
2056 int markerPos = reimplFromLine.find("@0");
2057 if (markerPos!=-1) // should always pass this.
2059 ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
2060 if (bmd->isLinkable()) // replace marker with link
2062 //Definition *bd=bmd->group;
2063 //if (bd==0) bd=bcd;
2064 ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
2065 bmd->anchor(),bcd->displayName());
2067 //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2068 // bmd->anchor(),bcd->name());
2069 if ( bmd->isLinkableInProject() )
2071 writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
2076 ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2077 0,bcd->displayName());
2078 if (bcd->isLinkableInProject()/* && !Config_getBool("PDF_HYPERLINKS")*/ )
2080 writePageRef(ol,bcd->getOutputFileBase(),bcd->anchor());
2083 ol.parseText(reimplFromLine.right(
2084 reimplFromLine.length()-markerPos-2)); // text right from marker
2089 err("error: translation error: no marker in trReimplementsFromList()\n");
2096 void MemberDef::_writeReimplementedBy(OutputList &ol)
2098 LockingPtr<MemberList> bml=reimplementedBy();
2101 MemberListIterator mli(*bml);
2105 for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
2107 // count the members that directly inherit from md and for
2108 // which the member and class are visible in the docs.
2109 if ( bmd->isLinkable() && bcd->isLinkable() )
2117 // write the list of classes that overwrite this member
2118 ol.startParagraph();
2120 QCString reimplInLine;
2121 if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface))
2123 reimplInLine = theTranslator->trImplementedInList(count);
2127 reimplInLine = theTranslator->trReimplementedInList(count);
2129 static QRegExp marker("@[0-9]+");
2130 int index=0,newIndex,matchLen;
2131 // now replace all markers in reimplInLine with links to the classes
2132 while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
2134 ol.parseText(reimplInLine.mid(index,newIndex-index));
2136 uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
2137 //bmd=bml->at(entryIndex);
2140 // find the entryIndex-th documented entry in the inheritance list.
2141 for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
2143 if ( bmd->isLinkable() && bcd->isLinkable())
2145 if (count==entryIndex) break;
2150 if (ok && bcd && bmd) // write link for marker
2152 //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2153 // bmd->anchor(),bcd->name());
2154 ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
2155 bmd->anchor(),bcd->displayName());
2157 if (bmd->isLinkableInProject() )
2159 writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
2163 index=newIndex+matchLen;
2165 ol.parseText(reimplInLine.right(reimplInLine.length()-index));
2171 void MemberDef::_writeCategoryRelation(OutputList &ol)
2173 if (m_impl->classDef) // this should be a member of a class/category
2175 //printf("%s: category %s relation %s class=%s categoryOf=%s\n",
2177 // m_impl->category ? m_impl->category->name().data() : "<none>",
2178 // m_impl->categoryRelation ? m_impl->categoryRelation->name().data() : "<none>",
2179 // m_impl->classDef->name().data(),
2180 // m_impl->classDef->categoryOf() ? m_impl->classDef->categoryOf()->name().data() : "<none>"
2188 if (m_impl->categoryRelation && m_impl->categoryRelation->isLinkable())
2190 if (m_impl->category)
2192 // this member is in a normal class and implements method categoryRelation from category
2193 // so link to method 'categoryRelation' with 'provided by category 'category' text.
2194 text = theTranslator->trProvidedByCategory();
2195 name = m_impl->category->displayName();
2197 else if (m_impl->classDef->categoryOf())
2199 // this member is part of a category so link to the corresponding class member of the class we extend
2200 // so link to method 'categoryRelation' with 'extends class 'classDef->categoryOf()'
2201 text = theTranslator->trExtendsClass();
2202 name = m_impl->classDef->categoryOf()->displayName();
2207 MemberDef *md = m_impl->categoryRelation;
2208 ref = md->getReference();
2209 file = md->getOutputFileBase();
2213 if (i!=-1 && !name.isEmpty())
2215 ol.startParagraph();
2216 ol.parseText(text.left(i));
2217 ol.writeObjectLink(ref,file,anc,name);
2218 ol.parseText(text.mid(i+2));
2224 void MemberDef::_writeExamples(OutputList &ol)
2226 // write the list of examples that use this member
2229 ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
2230 ol.startDescForItem();
2231 writeExample(ol,m_impl->exampleSDict);
2232 ol.endDescForItem();
2237 void MemberDef::_writeTypeConstraints(OutputList &ol)
2239 if (m_impl->typeConstraints)
2241 writeTypeConstraints(ol,this,m_impl->typeConstraints);
2245 void MemberDef::_writeEnumValues(OutputList &ol,Definition *container,
2246 const QCString &cfname,const QCString &ciname,
2247 const QCString &cname)
2249 // For enum, we also write the documented enum values
2253 LockingPtr<MemberList> fmdl=enumFieldList();
2254 //printf("** %s: enum values=%d\n",name().data(),fmdl!=0 ? fmdl->count() : 0);
2257 MemberDef *fmd=fmdl->first();
2260 //printf("Enum %p: isLinkable()=%d\n",fmd,fmd->isLinkable());
2261 if (fmd->isLinkable())
2265 ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": ");
2266 ol.startDescForItem();
2267 ol.startDescTable();
2270 ol.addIndexItem(fmd->name(),ciname);
2271 ol.addIndexItem(ciname,fmd->name());
2273 //Doxygen::indexList.addIndexItem(
2274 // ciname, // level1
2275 // fmd->name(), // level2
2276 // separateMemPages ? cfname : cfiname, // contRef
2277 // cfname, // memRef
2278 // fmd->anchor(), // anchor
2279 // fmd); // memberdef
2280 Doxygen::indexList.addIndexItem(container,fmd);
2282 //ol.writeListItem();
2283 ol.startDescTableTitle(); // this enables emphasis!
2284 ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString());
2286 //ol.startEmphasis();
2287 ol.docify(fmd->name());
2289 ol.disableAllBut(OutputGenerator::Man);
2290 ol.writeString(" ");
2292 ol.endDoxyAnchor(cfname,fmd->anchor());
2293 ol.endDescTableTitle();
2294 //ol.newParagraph();
2295 ol.startDescTableData();
2297 if (!fmd->briefDescription().isEmpty())
2299 ol.parseDoc(fmd->briefFile(),fmd->briefLine(),getOuterScope()?getOuterScope():container,fmd,fmd->briefDescription(),TRUE,FALSE);
2302 //if (!fmd->briefDescription().isEmpty() &&
2303 // !fmd->documentation().isEmpty())
2305 // ol.newParagraph();
2307 if (!fmd->documentation().isEmpty())
2309 ol.parseDoc(fmd->docFile(),fmd->docLine(),getOuterScope()?getOuterScope():container,fmd,fmd->documentation()+"\n",TRUE,FALSE);
2311 ol.endDescTableData();
2320 ol.endDescForItem();
2328 /*! Writes the "detailed documentation" section of this member to
2329 * all active output formats.
2331 void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
2333 Definition *container,
2335 bool showEnumValues,
2339 // if this member is in a group find the real scope name.
2340 bool hasParameterList = FALSE;
2341 bool inFile = container->definitionType()==Definition::TypeFile;
2342 bool hasDocs = isDetailedSectionVisible(inGroup,inFile);
2344 //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d\n",
2345 // name().data(),hasDocs,container->definitionType(),inGroup);
2347 if ( !hasDocs ) return;
2348 if (isEnumValue() && !showEnumValues) return;
2350 KEEP_RESIDENT_DURING_CALL;
2352 SrcLangExt lang = getLanguage();
2353 //printf("member=%s lang=%d\n",name().data(),lang);
2354 bool optVhdl = lang==SrcLangExt_VHDL;
2355 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
2357 QCString scopeName = scName;
2358 QCString memAnchor = anchor();
2359 QCString ciname = container->name();
2360 if (container->definitionType()==TypeGroup)
2362 if (getClassDef()) scopeName=getClassDef()->displayName();
2363 else if (getNamespaceDef()) scopeName=getNamespaceDef()->displayName();
2364 else if (getFileDef()) scopeName=getFileDef()->displayName();
2365 ciname = ((GroupDef *)container)->groupTitle();
2367 else if (container->definitionType()==TypeFile && getNamespaceDef())
2368 { // member is in a namespace, but is written as part of the file documentation
2369 // as well, so we need to make sure its label is unique.
2370 memAnchor.prepend("file_");
2373 QCString cname = container->name();
2374 QCString cfname = getOutputFileBase();
2375 QCString cfiname = container->getOutputFileBase();
2378 QCString doxyName=name();
2379 // prepend scope if there is any. TODO: make this optional for C only docs
2380 if (!scopeName.isEmpty())
2382 doxyName.prepend(scopeName+sep);
2384 QCString doxyArgs=argsString();
2386 QCString ldef = definition();
2387 QCString title = name();
2388 //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
2391 if (title.at(0)=='@')
2393 ldef = title = "anonymous enum";
2397 ldef.prepend("enum ");
2400 else if (isEnumValue())
2402 if (ldef.at(0)=='@')
2408 static QRegExp r("@[0-9]+");
2410 //----------------------------------------
2412 ol.pushGeneratorState();
2414 bool htmlEndLabelTable=FALSE;
2416 _getLabels(sl,container);
2418 if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
2420 // find enum type and insert it in the definition
2421 QListIterator<MemberDef> vmli(*ml);
2424 for ( ; (vmd=vmli.current()) && !found ; ++vmli)
2426 if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
2428 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2429 ol.startMemberDoc(ciname,name(),memAnchor,name(),showInline);
2430 linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,ldef.left(i));
2431 vmd->writeEnumDeclaration(ol,getClassDef(),getNamespaceDef(),getFileDef(),getGroupDef());
2432 linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,ldef.right(ldef.length()-i-l));
2437 if (!found) // anonymous compound
2439 //printf("Anonymous compound `%s'\n",cname.data());
2440 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2441 ol.startMemberDoc(ciname,name(),memAnchor,name(),showInline);
2442 // search for the last anonymous compound name in the definition
2443 int si=ldef.find(' '),pi,ei=i+l;
2445 while ((pi=r.match(ldef,i+l,&l))!=-1)
2450 // first si characters of ldef contain compound type name
2451 ol.startMemberDocName(isObjCMethod());
2452 ol.docify(ldef.left(si));
2453 ol.docify(" { ... } ");
2454 // last ei characters of ldef contain pointer/reference specifiers
2455 int ni=ldef.find("::",si);
2456 if (ni>=ei) ei=ni+2;
2457 linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,ldef.right(ldef.length()-ei));
2460 else // not an enum value or anonymous compound
2462 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2463 ol.startMemberDoc(ciname,name(),memAnchor,title,showInline);
2465 ClassDef *cd=getClassDef();
2466 if (!Config_getBool("HIDE_SCOPE_NAMES"))
2469 SrcLangExt lang = getLanguage();
2470 if (m_impl->defTmpArgLists && lang==SrcLangExt_Cpp)
2471 // definition has explicit template parameter declarations
2473 QListIterator<ArgumentList> ali(*m_impl->defTmpArgLists);
2475 for (ali.toFirst();(tal=ali.current());++ali)
2479 if (!first) ol.docify(" ");
2480 ol.startMemberDocPrefixItem();
2481 writeTemplatePrefix(ol,tal);
2482 ol.endMemberDocPrefixItem();
2486 else // definition gets it template parameters from its class
2487 // (since no definition was found)
2489 if (cd && lang==SrcLangExt_Cpp && !isTemplateSpecialization())
2491 QList<ArgumentList> tempParamLists;
2492 cd->getTemplateParameterLists(tempParamLists);
2493 //printf("#tempParamLists=%d\n",tempParamLists.count());
2494 QListIterator<ArgumentList> ali(tempParamLists);
2496 for (ali.toFirst();(tal=ali.current());++ali)
2500 if (!first) ol.docify(" ");
2501 ol.startMemberDocPrefixItem();
2502 writeTemplatePrefix(ol,tal);
2503 ol.endMemberDocPrefixItem();
2507 if (m_impl->tArgList && lang==SrcLangExt_Cpp) // function template prefix
2509 ol.startMemberDocPrefixItem();
2510 writeTemplatePrefix(ol,m_impl->tArgList);
2511 ol.endMemberDocPrefixItem();
2518 ol.pushGeneratorState();
2520 ol.enable(OutputGenerator::Html);
2521 ol.writeString("<table class=\"mlabels\">\n");
2522 ol.writeString(" <tr>\n");
2523 ol.writeString(" <td class=\"mlabels-left\">\n");
2524 ol.popGeneratorState();
2525 htmlEndLabelTable=TRUE;
2528 ol.startMemberDocName(isObjCMethod());
2529 if (cd && cd->isObjectiveC())
2532 int ep = ldef.find("::");
2535 int sp=ldef.findRev(' ',ep);
2538 ldef=ldef.left(sp+1)+ldef.mid(ep+2);
2542 int dp = ldef.find(':');
2545 ldef=ldef.left(dp+1);
2547 int l=ldef.length();
2548 //printf("start >%s<\n",ldef.data());
2550 while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
2551 while (i>=0 && isspace((uchar)ldef.at(i))) i--;
2554 // insert braches around the type
2555 QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
2558 //printf("end >%s< i=%d\n",ldef.data(),i);
2559 if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
2564 VhdlDocGen::writeVHDLTypeDocumentation(this,container,ol);
2568 linkifyText(TextGeneratorOLImpl(ol),
2572 substitute(ldef,"::",sep)
2574 hasParameterList=writeDefArgumentList(ol,cd,scopeName,this);
2577 if (hasOneLineInitializer()) // add initializer
2583 QCString init = m_impl->initializer.simplifyWhiteSpace();
2584 linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,init);
2588 ol.writeNonBreakableSpace(3);
2589 linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,m_impl->initializer);
2592 if (excpString()) // add exception list
2595 linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),this,excpString());
2599 ol.pushGeneratorState();
2600 ol.disable(OutputGenerator::Html);
2604 const char *s=sl.first();
2607 const char *ns = sl.next();
2608 ol.writeLabel(s,ns==0);
2613 ol.popGeneratorState();
2615 if (hasParameterList)
2617 ol.endParameterList();
2618 ol.endMemberDoc(TRUE);
2622 ol.endMemberDocName();
2623 ol.endMemberDoc(FALSE);
2626 // for HTML write the labels here
2627 ol.pushGeneratorState();
2629 ol.enable(OutputGenerator::Html);
2630 if (htmlEndLabelTable)
2632 ol.writeString(" </td>\n");
2633 ol.writeString(" <td class=\"mlabels-right\">\n");
2635 const char *s=sl.first();
2638 const char *ns = sl.next();
2639 ol.writeLabel(s,ns==0);
2643 ol.writeString(" </td>\n");
2644 ol.writeString(" </tr>\n");
2645 ol.writeString("</table>\n");
2647 ol.writeString("</div>");
2648 ol.popGeneratorState();
2651 ol.endDoxyAnchor(cfname,memAnchor);
2654 /* write multi-line initializer (if any) */
2655 if (hasMultiLineInitializer()
2656 //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
2657 // || initLines<userInitLines // explicitly enabled
2661 //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
2663 if (m_impl->mtype==Define)
2664 ol.parseText(theTranslator->trDefineValue());
2666 ol.parseText(theTranslator->trInitialValue());
2668 ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
2669 pIntf->resetCodeParserState();
2670 ol.startCodeFragment();
2671 pIntf->parseCode(ol,scopeName,m_impl->initializer,FALSE,0,getFileDef(),
2672 -1,-1,TRUE,this,FALSE,this);
2673 ol.endCodeFragment();
2676 QCString brief = briefDescription();
2677 QCString detailed = documentation();
2678 LockingPtr<ArgumentList> docArgList = LockingPtr<ArgumentList>(this,m_impl->defArgList);
2679 if (m_impl->templateMaster)
2681 brief = m_impl->templateMaster->briefDescription();
2682 detailed = m_impl->templateMaster->documentation();
2683 docArgList = m_impl->templateMaster->argumentList();
2686 /* write brief description */
2687 if (!brief.isEmpty() &&
2688 (Config_getBool("REPEAT_BRIEF") ||
2689 !Config_getBool("BRIEF_MEMBER_DESC")
2693 ol.startParagraph();
2694 ol.parseDoc(briefFile(),briefLine(),
2695 getOuterScope()?getOuterScope():container,this,
2696 brief,FALSE,FALSE,0,TRUE,FALSE);
2700 /* write detailed description */
2701 if (!detailed.isEmpty() ||
2702 !inbodyDocumentation().isEmpty())
2704 // write vhdl inline code with or without option INLINE_SOURCE
2705 if (optVhdl && VhdlDocGen::isMisc(this))
2707 VhdlDocGen::writeSource(this,ol,cname);
2712 ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,detailed+"\n",TRUE,FALSE);
2715 if (!inbodyDocumentation().isEmpty())
2717 ol.parseDoc(inbodyFile(),inbodyLine(),
2718 getOuterScope()?getOuterScope():container,this,
2719 inbodyDocumentation()+"\n",TRUE,FALSE);
2722 else if (!brief.isEmpty() && (Config_getBool("REPEAT_BRIEF") ||
2723 !Config_getBool("BRIEF_MEMBER_DESC")))
2725 if (!inbodyDocumentation().isEmpty())
2727 ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,inbodyDocumentation()+"\n",TRUE,FALSE);
2732 //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
2734 // defArgList?defArgList->hasDocumentation():-1);
2735 if (docArgList!=0 && docArgList->hasDocumentation())
2738 ArgumentListIterator ali(*docArgList);
2740 // convert the parameter documentation into a list of @param commands
2741 for (ali.toFirst();(a=ali.current());++ali)
2743 if (a->hasDocumentation())
2745 QCString direction = extractDirection(a->docs);
2746 paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
2749 // feed the result to the documentation parser
2751 docFile(),docLine(),
2752 getOuterScope()?getOuterScope():container,
2754 paramDocs, // docStr
2761 _writeEnumValues(ol,container,cfname,ciname,cname);
2762 _writeReimplements(ol);
2763 _writeReimplementedBy(ol);
2764 _writeCategoryRelation(ol);
2766 _writeTypeConstraints(ol);
2767 writeSourceDef(ol,cname);
2768 writeSourceRefs(ol,cname);
2769 writeSourceReffedBy(ol,cname);
2770 writeInlineCode(ol,cname);
2771 _writeCallGraph(ol);
2772 _writeCallerGraph(ol);
2774 if (Doxygen::userComments)
2776 ol.pushGeneratorState();
2777 ol.disableAllBut(OutputGenerator::Html);
2778 QCString cmd = "<? $root=$_SERVER['DOCUMENT_ROOT']; "
2779 "passthru(\"$root/doxynotes --lookup "+
2780 getOutputFileBase()+":"+anchor()+"\") ?>";
2781 ol.writeString(cmd);
2782 ol.popGeneratorState();
2787 // enable LaTeX again
2788 //if (Config_getBool("EXTRACT_ALL") && !hasDocs) ol.enable(OutputGenerator::Latex);
2789 ol.popGeneratorState();
2791 //------------------------------------------------
2793 if (!Config_getBool("EXTRACT_ALL") &&
2794 Config_getBool("WARN_IF_UNDOCUMENTED") &&
2795 Config_getBool("WARN_NO_PARAMDOC") &&
2796 !Doxygen::suppressDocWarnings)
2798 if (!hasDocumentedParams())
2800 warn_doc_error(docFile(),docLine(),
2801 "warning: parameters of member %s are not (all) documented",
2802 qPrint(qualifiedName()));
2804 if (!hasDocumentedReturnType() && isFunction() && hasDocumentation())
2806 warn_doc_error(docFile(),docLine(),
2807 "warning: return type of member %s is not documented",
2808 qPrint(qualifiedName()));
2813 // strip scope and field name from the type
2814 // example: "struct N::S.v.c" will become "struct v"
2815 static QCString simplifyTypeForTable(const QCString &s)
2817 QCString ts=removeAnonymousScopes(s);
2818 if (ts.right(2)=="::") ts = ts.left(ts.length()-2);
2819 static QRegExp re("[A-Z_a-z0-9]+::");
2821 while ((i=re.match(ts,0,&l))!=-1)
2823 ts=ts.left(i)+ts.mid(i+l);
2826 if (i!=-1) ts = ts.left(i);
2828 if (i!=-1) ts = ts.right(ts.length()-i-1);
2829 //printf("simplifyTypeForTable(%s)->%s\n",s.data(),ts.data());
2834 /** Returns the type definition corresponding to a member's return type.
2835 * @param[in] scope The scope in which to search for the class definition.
2836 * @param[in] type The string representing the member's return type.
2837 * @param[in] lang The programming language in which the class is defined.
2838 * @param[out] start The string position where the class definition name was found.
2839 * @param[out] length The length of the class definition's name.
2841 static Definition *getClassFromType(Definition *scope,const QCString &type,SrcLangExt lang,int &start,int &length)
2847 while ((i=extractClassNameFromType(type,pos,name,templSpec,lang))!=-1)
2851 int l = name.length()+templSpec.length();
2852 if (!templSpec.isEmpty())
2854 cd = getResolvedClass(scope,0,name+templSpec,&md);
2856 cd = getResolvedClass(scope,0,name);
2861 printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
2868 printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
2877 void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container)
2879 KEEP_RESIDENT_DURING_CALL;
2881 Definition *scope = getOuterScope();
2882 QCString doxyName = name();
2883 QCString doxyArgs = argsString();
2884 QCString memAnchor = anchor();
2885 QCString cfname = getOutputFileBase();
2887 if (scope) cname = scope->name();
2888 if (doxyName.at(0)=='@')
2890 doxyName="__unnamed__";
2893 ClassDef *cd = m_impl->accessorClass;
2894 //printf("===> %s::anonymous: %s\n",name().data(),cd?cd->name().data():"<none>");
2896 ol.startInlineMemberType();
2897 ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2899 QCString type = m_impl->accessorType;
2902 type = m_impl->type;
2904 QCString ts = simplifyTypeForTable(type);
2906 if (cd) // cd points to an anonymous struct pointed to by this member
2907 // so we add a link to it from the type column.
2910 const char *prefixes[] = { "struct ","union ","class ", 0 };
2911 const char **p = prefixes;
2922 ol.writeObjectLink(cd->getReference(),
2923 cd->getOutputFileBase(),
2924 cd->anchor(),ts.mid(i));
2926 else // use standard auto linking
2928 linkifyText(TextGeneratorOLImpl(ol), // out
2930 getBodyDef(), // fileScope
2936 ol.endDoxyAnchor(cfname,memAnchor);
2937 ol.endInlineMemberType();
2939 ol.startInlineMemberName();
2940 ol.docify(doxyName);
2941 if (!m_impl->bitfields.isEmpty()) // add bitfields
2943 linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,m_impl->bitfields.simplifyWhiteSpace());
2945 ol.endInlineMemberName();
2947 ol.startInlineMemberDoc();
2949 QCString brief = briefDescription();
2950 QCString detailed = documentation();
2952 /* write brief description */
2953 if (!brief.isEmpty() &&
2954 (Config_getBool("REPEAT_BRIEF") ||
2955 !Config_getBool("BRIEF_MEMBER_DESC")
2959 ol.parseDoc(briefFile(),briefLine(),
2960 getOuterScope()?getOuterScope():container,this,
2961 brief,FALSE,FALSE,0,TRUE,FALSE);
2964 /* write detailed description */
2965 if (!detailed.isEmpty())
2967 ol.parseDoc(docFile(),docLine(),
2968 getOuterScope()?getOuterScope():container,this,
2969 detailed+"\n",FALSE,FALSE,0,TRUE,FALSE);
2973 ol.endInlineMemberDoc();
2976 QCString MemberDef::memberTypeName() const
2979 switch (m_impl->mtype)
2981 case Define: return "macro definition";
2982 case Function: return "function";
2983 case Variable: return "variable";
2984 case Typedef: return "typedef";
2985 case Enumeration: return "enumeration";
2986 case EnumValue: return "enumvalue";
2987 case Signal: return "signal";
2988 case Slot: return "slot";
2989 case Friend: return "friend";
2990 case DCOP: return "dcop";
2991 case Property: return "property";
2992 case Event: return "event";
2993 default: return "unknown";
2997 void MemberDef::warnIfUndocumented()
3000 if (m_impl->memberGroup) return;
3001 ClassDef *cd = getClassDef();
3002 NamespaceDef *nd = getNamespaceDef();
3003 FileDef *fd = getFileDef();
3004 GroupDef *gd = getGroupDef();
3010 t="namespace", d=nd;
3015 static bool extractAll = Config_getBool("EXTRACT_ALL");
3017 //printf("warnIfUndoc: d->isLinkable()=%d isLinkable()=%d "
3018 // "isDocumentedFriendClass()=%d name()=%s prot=%d\n",
3019 // d->isLinkable(),isLinkable(),isDocumentedFriendClass(),
3020 // name().data(),prot);
3021 if ((!hasUserDocumentation() && !extractAll) &&
3023 name().find('@')==-1 && d && d->name().find('@')==-1 &&
3024 protectionLevelVisible(m_impl->prot) &&
3028 warn_undoc(getDefFileName(),getDefLine(),"warning: Member %s%s (%s) of %s %s is not documented.",
3029 qPrint(name()),qPrint(argsString()),qPrint(memberTypeName()),t,qPrint(d->name()));
3035 bool MemberDef::isFriendClass() const
3038 return (isFriend() &&
3039 (m_impl->type=="friend class" || m_impl->type=="friend struct" ||
3040 m_impl->type=="friend union"));
3043 bool MemberDef::isDocumentedFriendClass() const
3047 QCString baseName=name();
3048 int i=baseName.find('<');
3049 if (i!=-1) baseName=baseName.left(i);
3050 return (isFriendClass() &&
3051 (fcd=getClass(baseName)) && fcd->isLinkable());
3054 bool MemberDef::hasDocumentation() const
3057 return Definition::hasDocumentation() ||
3058 (m_impl->mtype==Enumeration && m_impl->docEnumValues) || // has enum values
3059 (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments
3063 bool MemberDef::hasUserDocumentation() const
3065 bool hasDocs = Definition::hasUserDocumentation();
3071 void MemberDef::setMemberGroup(MemberGroup *grp)
3074 m_impl->memberGroup = grp;
3077 bool MemberDef::visibleMemberGroup(bool hideNoHeader)
3080 return m_impl->memberGroup!=0 &&
3081 (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]");
3084 QCString MemberDef::getScopeString() const
3088 if (getClassDef()) result=getClassDef()->displayName();
3089 else if (getNamespaceDef()) result=getNamespaceDef()->displayName();
3094 static QCString escapeAnchor(const QCString &anchor)
3097 int l = anchor.length(),i;
3100 char c = anchor.at(i);
3101 if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
3107 static char hexStr[]="0123456789ABCDEF";
3108 char escChar[]={ '_', 0, 0, 0 };
3109 escChar[1]=hexStr[c>>4];
3110 escChar[2]=hexStr[c&0xf];
3118 void MemberDef::setAnchor(const char *a)
3123 QCString memAnchor = name();
3124 if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
3126 memAnchor.prepend(definition()); // actually the method name is now included
3127 // twice, which is silly, but we keep it this way for backward
3130 // include number of template arguments as well,
3131 // to distinguish between two template
3132 // specializations that only differ in the template parameters.
3133 if (m_impl->tArgList)
3136 snprintf(buf,20,"%d:",m_impl->tArgList->count());
3138 memAnchor.prepend(buf);
3141 // convert to md5 hash
3143 QCString sigStr(33);
3144 MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig);
3145 //printf("memAnchor=%s\n",memAnchor.data());
3146 MD5SigToString(md5_sig,sigStr.data(),33);
3147 m_impl->anc = "a"+sigStr;
3150 void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri,
3151 const QCString &fileName,int startLine,
3152 bool hasDocs,MemberDef *member)
3154 //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data());
3157 m_impl->grouppri=pri;
3158 m_impl->groupFileName=fileName;
3159 m_impl->groupStartLine=startLine;
3160 m_impl->groupHasDocs=hasDocs;
3161 m_impl->groupMember=member;
3162 m_isLinkableCached = 0;
3165 void MemberDef::setEnumScope(MemberDef *md)
3168 m_impl->enumScope=md;
3169 if (md->getGroupDef())
3171 m_impl->group=md->getGroupDef();
3172 m_impl->grouppri=md->getGroupPri();
3173 m_impl->groupFileName=md->getGroupFileName();
3174 m_impl->groupStartLine=md->getGroupStartLine();
3175 m_impl->groupHasDocs=md->getGroupHasDocs();
3176 m_isLinkableCached = 0;
3180 void MemberDef::setMemberClass(ClassDef *cd)
3183 m_impl->classDef=cd;
3184 m_isLinkableCached = 0;
3185 m_isConstructorCached = 0;
3189 void MemberDef::setNamespace(NamespaceDef *nd)
3196 MemberDef *MemberDef::createTemplateInstanceMember(
3197 ArgumentList *formalArgs,ArgumentList *actualArgs)
3199 KEEP_RESIDENT_DURING_CALL;
3200 //printf(" Member %s %s %s\n",typeString(),name().data(),argsString());
3201 ArgumentList *actualArgList = 0;
3202 if (m_impl->defArgList)
3204 actualArgList = m_impl->defArgList->deepCopy();
3206 // replace formal arguments with actuals
3207 ArgumentListIterator ali(*actualArgList);
3209 for (;(arg=ali.current());++ali)
3211 arg->type = substituteTemplateArgumentsInString(arg->type,formalArgs,actualArgs);
3213 actualArgList->trailingReturnType =
3214 substituteTemplateArgumentsInString(actualArgList->trailingReturnType,formalArgs,actualArgs);
3217 QCString methodName=name();
3218 if (methodName.left(9)=="operator ") // conversion operator
3220 methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs);
3223 MemberDef *imd = new MemberDef(
3224 getDefFileName(),getDefLine(),
3225 substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs),
3227 substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs),
3228 m_impl->exception, m_impl->prot,
3229 m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0
3231 imd->setArgumentList(actualArgList);
3232 imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs));
3233 imd->setBodyDef(getBodyDef());
3234 imd->setBodySegment(getStartBodyLine(),getEndBodyLine());
3235 //imd->setBodyMember(this);
3237 // TODO: init other member variables (if needed).
3238 // TODO: reimplemented info
3242 bool MemberDef::hasOneLineInitializer() const
3245 //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
3246 // name().data(),m_impl->initializer.data(),m_impl->initLines,
3247 // m_impl->maxInitLines,m_impl->userInitLines);
3248 return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
3249 ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
3252 bool MemberDef::hasMultiLineInitializer() const
3255 //printf("initLines=%d userInitLines=%d maxInitLines=%d\n",
3256 // initLines,userInitLines,maxInitLines);
3257 return m_impl->initLines>0 &&
3258 ((m_impl->initLines<m_impl->maxInitLines && m_impl->userInitLines==-1) // implicitly enabled
3259 || m_impl->initLines<m_impl->userInitLines // explicitly enabled
3263 void MemberDef::setInitializer(const char *initializer)
3266 m_impl->initializer=initializer;
3267 int l=m_impl->initializer.length();
3269 while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
3270 m_impl->initializer=m_impl->initializer.left(p+1);
3271 m_impl->initLines=m_impl->initializer.contains('\n');
3272 //printf("%s::setInitializer(%s)\n",name().data(),m_impl->initializer.data());
3275 void MemberDef::addListReference(Definition *)
3277 KEEP_RESIDENT_DURING_CALL;
3278 static bool optimizeOutputForC = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
3279 //static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
3280 //static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
3281 //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
3282 SrcLangExt lang = getLanguage();
3284 if (!isLinkableInProject()) return;
3286 if (optimizeOutputForC)
3288 memLabel=theTranslator->trGlobal(TRUE,TRUE);
3290 else if (lang==SrcLangExt_Fortran)
3292 memLabel=theTranslator->trSubprogram(TRUE,TRUE);
3296 memLabel=theTranslator->trMember(TRUE,TRUE);
3298 QCString memName = name();
3299 Definition *pd=getOuterScope();
3300 QCString pdName = pd->definitionType()==Definition::TypeClass ?
3301 ((ClassDef*)pd)->displayName() : pd->name();
3302 QCString sep = getLanguageSpecificSeparator(lang,TRUE);
3305 /* && commented out as a result of bug 597016
3307 (!hideScopeNames && // there is a scope
3308 pd && pd!=Doxygen::globalScope) // and we can show it
3310 (pd=getClassDef()) // it's a class so we
3311 // show the scope anyway
3318 memName = "[" + pd->name() + " " + name() + "]";
3322 if (pd!=Doxygen::globalScope) memName.prepend(pdName+sep);
3323 memArgs = argsString();
3326 LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
3329 addRefItem(xrefItems.pointer(),
3330 qualifiedName()+argsString(), // argsString is needed for overloaded functions (see bug 609624)
3332 getOutputFileBase()+"#"+anchor(),memName,memArgs);
3336 MemberList *MemberDef::getSectionList(Definition *d) const
3340 sprintf(key,"%p",d);
3341 return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0;
3344 void MemberDef::setSectionList(Definition *d, MemberList *sl)
3347 //printf("MemberDef::setSectionList(%p,%p) name=%s\n",d,sl,name().data());
3349 sprintf(key,"%p",d);
3350 if (m_impl->classSectionSDict==0)
3352 m_impl->classSectionSDict = new SDict<MemberList>(7);
3354 m_impl->classSectionSDict->append(key,sl);
3357 Specifier MemberDef::virtualness(int count) const
3359 KEEP_RESIDENT_DURING_CALL;
3362 warn(getDefFileName(),getDefLine(),
3363 "warning: Internal inconsistency: recursion detected in overload relation for member %s!"
3369 Specifier v = m_impl->virt;
3370 MemberDef *rmd = reimplements();
3371 while (rmd && v==Normal)
3373 v = rmd->virtualness(count+1)==Normal ? Normal : Virtual;
3374 rmd = rmd->reimplements();
3379 void MemberDef::_computeIsConstructor()
3381 KEEP_RESIDENT_DURING_CALL;
3382 m_isConstructorCached=1; // FALSE
3383 if (m_impl->classDef)
3385 if (m_impl->isDMember) // for D
3387 m_isConstructorCached = name()=="this" ? 2 : 1;
3390 else if (getLanguage()==SrcLangExt_PHP) // for PHP
3392 m_isConstructorCached = name()=="__construct" ? 2 : 1;
3395 else if (name()=="__init__" &&
3396 getLanguage()==SrcLangExt_Python) // for Python
3398 m_isConstructorCached = 2; // TRUE
3401 else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
3403 m_isConstructorCached = name()=="constructor" ? 2 : 1;
3406 else // for other languages
3408 QCString locName = m_impl->classDef->localName();
3409 int i=locName.find('<');
3410 if (i==-1) // not a template class
3412 m_isConstructorCached = name()==locName ? 2 : 1;
3416 m_isConstructorCached = name()==locName.left(i) ? 2 : 1;
3423 bool MemberDef::isConstructor() const
3425 if (m_isConstructorCached==0)
3427 MemberDef *that = (MemberDef*)this;
3428 that->_computeIsConstructor();
3430 ASSERT(m_isConstructorCached>0);
3431 return m_isConstructorCached==2;
3435 void MemberDef::_computeIsDestructor()
3437 KEEP_RESIDENT_DURING_CALL;
3439 if (m_impl->isDMember) // for D
3441 isDestructor = name()=="~this";
3443 else if (getLanguage()==SrcLangExt_PHP) // for PHP
3445 isDestructor = name()=="__destruct";
3447 else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
3449 isDestructor = name()=="destructor";
3451 else if (name()=="__del__" &&
3452 getLanguage()==SrcLangExt_Python) // for Python
3456 else // other languages
3459 (name().find('~')!=-1 || name().find('!')!=-1) // The ! is for C++/CLI
3460 && name().find("operator")==-1;
3462 m_isDestructorCached = isDestructor ? 2 : 1;
3465 bool MemberDef::isDestructor() const
3467 if (m_isDestructorCached==0)
3469 MemberDef *that=(MemberDef*)this;
3470 that->_computeIsDestructor();
3472 ASSERT(m_isDestructorCached>0);
3473 return m_isDestructorCached==2;
3476 void MemberDef::writeEnumDeclaration(OutputList &typeDecl,
3477 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd)
3479 KEEP_RESIDENT_DURING_CALL;
3483 MemberList *fmdl=m_impl->enumFields;
3484 uint numVisibleEnumValues=0;
3487 MemberDef *fmd=fmdl->first();
3490 if (fmd->isBriefSectionVisible()) numVisibleEnumValues++;
3494 if (numVisibleEnumValues==0 && !isBriefSectionVisible())
3499 QCString n = name();
3500 int i=n.findRev("::");
3501 if (i!=-1) n=n.right(n.length()-i-2); // strip scope (TODO: is this needed?)
3502 if (n[0]!='@') // not an anonymous enum
3504 if (isLinkableInProject() || hasDocumentedEnumValues())
3506 if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !isReference())
3508 Doxygen::tagFile << " <member kind=\"enumeration\">" << endl;
3509 Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
3510 Doxygen::tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
3511 Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
3512 Doxygen::tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
3513 Doxygen::tagFile << " </member>" << endl;
3515 writeLink(typeDecl,cd,nd,fd,gd);
3519 typeDecl.startBold();
3523 typeDecl.writeChar(' ');
3524 if (!m_impl->enumBaseType.isEmpty())
3526 typeDecl.writeChar(':');
3527 typeDecl.writeChar(' ');
3528 typeDecl.docify(m_impl->enumBaseType);
3529 typeDecl.writeChar(' ');
3533 uint enumValuesPerLine = (uint)Config_getInt("ENUM_VALUES_PER_LINE");
3534 if (numVisibleEnumValues>0 && enumValuesPerLine>0)
3536 typeDecl.docify("{ ");
3539 MemberDef *fmd=fmdl->first();
3540 bool fmdVisible = fmd->isBriefSectionVisible();
3545 /* in html we start a new line after a number of items */
3546 if (numVisibleEnumValues>enumValuesPerLine
3547 && (enumMemCount%enumValuesPerLine)==0
3550 typeDecl.pushGeneratorState();
3551 typeDecl.disableAllBut(OutputGenerator::Html);
3552 typeDecl.enable(OutputGenerator::Latex);
3553 typeDecl.lineBreak();
3554 typeDecl.disable(OutputGenerator::Latex);
3555 typeDecl.writeString("  ");
3556 typeDecl.popGeneratorState();
3559 if (fmd->hasDocumentation()) // enum value has docs
3561 if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !fmd->isReference())
3563 Doxygen::tagFile << " <member kind=\"enumvalue\">" << endl;
3564 Doxygen::tagFile << " <name>" << convertToXML(fmd->name()) << "</name>" << endl;
3565 Doxygen::tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
3566 Doxygen::tagFile << " <anchor>" << convertToXML(fmd->anchor()) << "</anchor>" << endl;
3567 Doxygen::tagFile << " <arglist>" << convertToXML(fmd->argsString()) << "</arglist>" << endl;
3568 Doxygen::tagFile << " </member>" << endl;
3570 fmd->writeLink(typeDecl,cd,nd,fd,gd);
3572 else // no docs for this enum value
3574 typeDecl.startBold();
3575 typeDecl.docify(fmd->name());
3578 if (fmd->hasOneLineInitializer()) // enum value has initializer
3580 //typeDecl.writeString(" = ");
3581 typeDecl.writeString(" ");
3582 typeDecl.parseText(fmd->initializer());
3586 bool prevVisible = fmdVisible;
3588 if (fmd && (fmdVisible=fmd->isBriefSectionVisible()))
3590 typeDecl.writeString(", ");
3594 typeDecl.disable(OutputGenerator::Man);
3595 typeDecl.writeString("\n"); // to prevent too long lines in LaTeX
3596 typeDecl.enable(OutputGenerator::Man);
3600 if (numVisibleEnumValues>enumValuesPerLine)
3602 typeDecl.pushGeneratorState();
3603 typeDecl.disableAllBut(OutputGenerator::Html);
3604 typeDecl.lineBreak();
3605 typeDecl.popGeneratorState();
3608 typeDecl.docify(" }");
3612 void MemberDef::setArgumentList(ArgumentList *al)
3615 if (m_impl->defArgList) delete m_impl->defArgList;
3616 m_impl->defArgList = al;
3619 void MemberDef::setDeclArgumentList(ArgumentList *al)
3622 if (m_impl->declArgList) delete m_impl->declArgList;
3623 m_impl->declArgList = al;
3626 void MemberDef::setTypeConstraints(ArgumentList *al)
3630 if (m_impl->typeConstraints) delete m_impl->typeConstraints;
3631 m_impl->typeConstraints = new ArgumentList;
3632 m_impl->typeConstraints->setAutoDelete(TRUE);
3633 ArgumentListIterator ali(*al);
3635 for (;(a=ali.current());++ali)
3637 m_impl->typeConstraints->append(new Argument(*a));
3641 void MemberDef::setType(const char *t)
3647 void MemberDef::setAccessorType(ClassDef *cd,const char *t)
3650 m_impl->accessorClass = cd;
3651 m_impl->accessorType = t;
3654 void MemberDef::findSectionsInDocumentation()
3657 docFindSections(documentation(),this,0,docFile());
3660 void MemberDef::enableCallGraph(bool e)
3663 m_impl->hasCallGraph=e;
3664 if (e) Doxygen::parseSourcesNeeded = TRUE;
3667 void MemberDef::enableCallerGraph(bool e)
3670 m_impl->hasCallerGraph=e;
3671 if (e) Doxygen::parseSourcesNeeded = TRUE;
3675 bool MemberDef::protectionVisible() const
3678 return m_impl->prot==Public ||
3679 (m_impl->prot==Private && Config_getBool("EXTRACT_PRIVATE")) ||
3680 (m_impl->prot==Protected && Config_getBool("EXTRACT_PROTECTED")) ||
3681 (m_impl->prot==Package && Config_getBool("EXTRACT_PACKAGE"));
3686 void MemberDef::setInbodyDocumentation(const char *docs,
3687 const char *docFile,int docLine)
3690 m_impl->inbodyDocs = docs;
3691 m_impl->inbodyDocs = m_impl->inbodyDocs.stripWhiteSpace();
3692 m_impl->inbodyLine = docLine;
3693 m_impl->inbodyFile = docFile;
3697 bool MemberDef::isObjCMethod() const
3700 if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE;
3704 bool MemberDef::isObjCProperty() const
3707 if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isProperty()) return TRUE;
3711 QCString MemberDef::qualifiedName() const
3717 if (isStatic()) qm="+"; else qm="-";
3719 qm+=m_impl->classDef->name()+" ";
3726 return Definition::qualifiedName();
3730 void MemberDef::setTagInfo(TagInfo *ti)
3735 //printf("%s: Setting tag name=%s anchor=%s\n",name().data(),ti->tagName.data(),ti->anchor.data());
3736 m_impl->anc=ti->anchor;
3737 setReference(ti->tagName);
3738 m_impl->explicitOutputFileBase = stripExtension(ti->fileName);
3742 QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const
3748 if (isStatic()) qm="+ "; else qm="- ";
3751 if (!localLink) // link to method of same class
3754 qm+=m_impl->classDef->name();
3760 const char *MemberDef::declaration() const
3763 return m_impl->decl;
3766 const char *MemberDef::definition() const
3772 const char *MemberDef::extraTypeChars() const
3775 return m_impl->extraTypeChars;
3778 const char *MemberDef::typeString() const
3781 return m_impl->type;
3784 const char *MemberDef::argsString() const
3787 return m_impl->args;
3790 const char *MemberDef::excpString() const
3793 return m_impl->exception;
3796 const char *MemberDef::bitfieldString() const
3799 return m_impl->bitfields;
3802 const QCString &MemberDef::initializer() const
3805 return m_impl->initializer;
3808 int MemberDef::initializerLines() const
3811 return m_impl->initLines;
3814 int MemberDef::getMemberSpecifiers() const
3817 return m_impl->memSpec;
3820 ClassDef *MemberDef::getClassDef() const
3823 return m_impl->classDef;
3826 FileDef *MemberDef::getFileDef() const
3829 return m_impl->fileDef;
3832 NamespaceDef* MemberDef::getNamespaceDef() const
3835 return m_impl->nspace;
3838 const char *MemberDef::getReadAccessor() const
3841 return m_impl->read;
3844 const char *MemberDef::getWriteAccessor() const
3847 return m_impl->write;
3850 GroupDef *MemberDef::getGroupDef() const
3853 return m_impl->group;
3856 Grouping::GroupPri_t MemberDef::getGroupPri() const
3859 return m_impl->grouppri;
3862 const char *MemberDef::getGroupFileName() const
3865 return m_impl->groupFileName;
3868 int MemberDef::getGroupStartLine() const
3871 return m_impl->groupStartLine;
3874 bool MemberDef::getGroupHasDocs() const
3877 return m_impl->groupHasDocs;
3880 Protection MemberDef::protection() const
3883 return m_impl->prot;
3886 MemberDef::MemberType MemberDef::memberType() const
3889 return m_impl->mtype;
3892 bool MemberDef::isSignal() const
3895 return m_impl->mtype==Signal;
3898 bool MemberDef::isSlot() const
3901 return m_impl->mtype==Slot;
3904 bool MemberDef::isVariable() const
3907 return m_impl->mtype==Variable;
3910 bool MemberDef::isEnumerate() const
3913 return m_impl->mtype==Enumeration;
3916 bool MemberDef::isEnumValue() const
3919 return m_impl->mtype==EnumValue;
3922 bool MemberDef::isTypedef() const
3925 return m_impl->mtype==Typedef;
3928 bool MemberDef::isFunction() const
3931 return m_impl->mtype==Function;
3934 bool MemberDef::isFunctionPtr() const
3937 return m_impl->mtype==Variable && QCString(argsString()).find(")(")!=-1;
3940 bool MemberDef::isDefine() const
3943 return m_impl->mtype==Define;
3946 bool MemberDef::isFriend() const
3949 return m_impl->mtype==Friend;
3952 bool MemberDef::isDCOP() const
3955 return m_impl->mtype==DCOP;
3958 bool MemberDef::isProperty() const
3961 return m_impl->mtype==Property;
3964 bool MemberDef::isEvent() const
3967 return m_impl->mtype==Event;
3970 bool MemberDef::isRelated() const
3973 return m_impl->related == Related;
3976 bool MemberDef::isForeign() const
3979 return m_impl->related == Foreign;
3982 bool MemberDef::isStatic() const
3985 return m_impl->stat;
3988 bool MemberDef::isInline() const
3991 return (m_impl->memSpec&Entry::Inline)!=0;
3994 bool MemberDef::isExplicit() const
3997 return (m_impl->memSpec&Entry::Explicit)!=0;
4000 bool MemberDef::isMutable() const
4003 return (m_impl->memSpec&Entry::Mutable)!=0;
4006 bool MemberDef::isGettable() const
4009 return (m_impl->memSpec&Entry::Gettable)!=0;
4012 bool MemberDef::isSettable() const
4015 return (m_impl->memSpec&Entry::Settable)!=0;
4018 bool MemberDef::isAddable() const
4021 return (m_impl->memSpec&Entry::Addable)!=0;
4024 bool MemberDef::isRemovable() const
4027 return (m_impl->memSpec&Entry::Removable)!=0;
4030 bool MemberDef::isRaisable() const
4033 return (m_impl->memSpec&Entry::Raisable)!=0;
4036 bool MemberDef::isReadable() const
4039 return (m_impl->memSpec&Entry::Readable)!=0;
4042 bool MemberDef::isWritable() const
4045 return (m_impl->memSpec&Entry::Writable)!=0;
4048 bool MemberDef::isFinal() const
4051 return (m_impl->memSpec&Entry::Final)!=0;
4054 bool MemberDef::isNew() const
4057 return (m_impl->memSpec&Entry::New)!=0;
4060 bool MemberDef::isSealed() const
4063 return (m_impl->memSpec&Entry::Sealed)!=0;
4066 bool MemberDef::isOverride() const
4069 return (m_impl->memSpec&Entry::Override)!=0;
4072 bool MemberDef::isInitonly() const
4075 return (m_impl->memSpec&Entry::Initonly)!=0;
4078 bool MemberDef::isAbstract() const
4081 return (m_impl->memSpec&Entry::Abstract)!=0;
4084 bool MemberDef::isOptional() const
4087 return (m_impl->memSpec&Entry::Optional)!=0;
4090 bool MemberDef::isRequired() const
4093 return (m_impl->memSpec&Entry::Required)!=0;
4096 bool MemberDef::isNonAtomic() const
4099 return (m_impl->memSpec&Entry::NonAtomic)!=0;
4102 bool MemberDef::isCopy() const
4105 return (m_impl->memSpec&Entry::Copy)!=0;
4108 bool MemberDef::isAssign() const
4111 return (m_impl->memSpec&Entry::Assign)!=0;
4114 bool MemberDef::isRetain() const
4117 return (m_impl->memSpec&Entry::Retain)!=0;
4120 bool MemberDef::isWeak() const
4123 return (m_impl->memSpec&Entry::Weak)!=0;
4126 bool MemberDef::isStrong() const
4129 return (m_impl->memSpec&Entry::Strong)!=0;
4132 bool MemberDef::isUnretained() const
4135 return (m_impl->memSpec&Entry::Unretained)!=0;
4138 bool MemberDef::isAlias() const
4141 return (m_impl->memSpec&Entry::Alias)!=0;
4144 bool MemberDef::isDefault() const
4147 return (m_impl->memSpec&Entry::Default)!=0;
4150 bool MemberDef::isDelete() const
4153 return (m_impl->memSpec&Entry::Delete)!=0;
4156 bool MemberDef::isNoExcept() const
4159 return (m_impl->memSpec&Entry::NoExcept)!=0;
4164 bool MemberDef::isImplementation() const
4167 return m_impl->implOnly;
4170 bool MemberDef::isExternal() const
4173 return m_impl->explExt;
4176 bool MemberDef::isTemplateSpecialization() const
4179 return m_impl->tspec;
4182 bool MemberDef::hasDocumentedParams() const
4185 return m_impl->hasDocumentedParams;
4188 bool MemberDef::hasDocumentedReturnType() const
4191 return m_impl->hasDocumentedReturnType;
4194 ClassDef *MemberDef::relatedAlso() const
4197 return m_impl->relatedAlso;
4200 bool MemberDef::hasDocumentedEnumValues() const
4203 return m_impl->docEnumValues;
4206 MemberDef *MemberDef::getAnonymousEnumType() const
4209 return m_impl->annEnumType;
4212 bool MemberDef::isDocsForDefinition() const
4215 return m_impl->docsForDefinition;
4218 MemberDef *MemberDef::getEnumScope() const
4221 return m_impl->enumScope;
4224 LockingPtr<MemberList> MemberDef::enumFieldList() const
4227 return LockingPtr<MemberList>(this,m_impl->enumFields);
4230 LockingPtr<ExampleSDict> MemberDef::getExamples() const
4233 return LockingPtr<ExampleSDict>(this,m_impl->exampleSDict);
4236 bool MemberDef::isPrototype() const
4239 return m_impl->proto;
4242 LockingPtr<ArgumentList> MemberDef::argumentList() const
4245 return LockingPtr<ArgumentList>(this,m_impl->defArgList);
4248 LockingPtr<ArgumentList> MemberDef::declArgumentList() const
4251 return LockingPtr<ArgumentList>(this,m_impl->declArgList);
4254 LockingPtr<ArgumentList> MemberDef::templateArguments() const
4257 return LockingPtr<ArgumentList>(this,m_impl->tArgList);
4260 LockingPtr< QList<ArgumentList> > MemberDef::definitionTemplateParameterLists() const
4263 return LockingPtr< QList<ArgumentList> >(this,m_impl->defTmpArgLists);
4266 int MemberDef::getMemberGroupId() const
4269 return m_impl->grpId;
4272 MemberGroup *MemberDef::getMemberGroup() const
4275 return m_impl->memberGroup;
4278 bool MemberDef::fromAnonymousScope() const
4281 return m_impl->annScope;
4284 bool MemberDef::anonymousDeclShown() const
4287 return m_impl->annUsed;
4290 void MemberDef::setAnonymousUsed()
4293 m_impl->annUsed = TRUE;
4296 bool MemberDef::hasCallGraph() const
4299 return m_impl->hasCallGraph;
4302 bool MemberDef::hasCallerGraph() const
4305 return m_impl->hasCallerGraph;
4308 MemberDef *MemberDef::templateMaster() const
4311 return m_impl->templateMaster;
4314 bool MemberDef::isTypedefValCached() const
4317 return m_impl->isTypedefValCached;
4320 ClassDef *MemberDef::getCachedTypedefVal() const
4323 return m_impl->cachedTypedefValue;
4326 QCString MemberDef::getCachedTypedefTemplSpec() const
4329 return m_impl->cachedTypedefTemplSpec;
4332 QCString MemberDef::getCachedResolvedTypedef() const
4335 //printf("MemberDef::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
4336 return m_impl->cachedResolvedType;
4339 MemberDef *MemberDef::memberDefinition() const
4342 return m_impl->memDef;
4345 MemberDef *MemberDef::memberDeclaration() const
4348 return m_impl->memDec;
4351 MemberDef *MemberDef::inheritsDocsFrom() const
4354 return m_impl->docProvider;
4357 MemberDef *MemberDef::getGroupAlias() const
4360 return m_impl->groupAlias;
4363 void MemberDef::setMemberType(MemberType t)
4367 m_isLinkableCached = 0;
4370 void MemberDef::setDefinition(const char *d)
4376 void MemberDef::setFileDef(FileDef *fd)
4380 m_isLinkableCached = 0;
4381 m_isConstructorCached = 0;
4382 m_isDestructorCached = 0;
4385 void MemberDef::setProtection(Protection p)
4389 m_isLinkableCached = 0;
4392 void MemberDef::setMemberSpecifiers(int s)
4398 void MemberDef::mergeMemberSpecifiers(int s)
4404 void MemberDef::setBitfields(const char *s)
4407 m_impl->bitfields = s;
4410 void MemberDef::setMaxInitLines(int lines)
4415 m_impl->userInitLines=lines;
4419 void MemberDef::setExplicitExternal(bool b)
4425 void MemberDef::setReadAccessor(const char *r)
4431 void MemberDef::setWriteAccessor(const char *w)
4437 void MemberDef::setTemplateSpecialization(bool b)
4443 void MemberDef::makeRelated()
4446 m_impl->related = Related;
4447 m_isLinkableCached = 0;
4450 void MemberDef::makeForeign()
4453 m_impl->related = Foreign;
4454 m_isLinkableCached = 0;
4457 void MemberDef::setHasDocumentedParams(bool b)
4460 m_impl->hasDocumentedParams = b;
4463 void MemberDef::setHasDocumentedReturnType(bool b)
4466 m_impl->hasDocumentedReturnType = b;
4469 void MemberDef::setInheritsDocsFrom(MemberDef *md)
4472 m_impl->docProvider = md;
4475 void MemberDef::setArgsString(const char *as)
4481 void MemberDef::setRelatedAlso(ClassDef *cd)
4484 m_impl->relatedAlso=cd;
4487 void MemberDef::setEnumClassScope(ClassDef *cd)
4490 m_impl->classDef = cd;
4491 m_isLinkableCached = 0;
4492 m_isConstructorCached = 0;
4495 void MemberDef::setDocumentedEnumValues(bool value)
4498 m_impl->docEnumValues=value;
4501 void MemberDef::setAnonymousEnumType(MemberDef *md)
4504 m_impl->annEnumType = md;
4507 void MemberDef::setPrototype(bool p)
4513 void MemberDef::setMemberGroupId(int id)
4519 void MemberDef::makeImplementationDetail()
4522 m_impl->implOnly=TRUE;
4525 void MemberDef::setFromAnonymousScope(bool b)
4531 void MemberDef::setFromAnonymousMember(MemberDef *m)
4537 void MemberDef::setTemplateMaster(MemberDef *mt)
4540 m_impl->templateMaster=mt;
4541 m_isLinkableCached = 0;
4544 void MemberDef::setDocsForDefinition(bool b)
4547 m_impl->docsForDefinition = b;
4550 void MemberDef::setGroupAlias(MemberDef *md)
4553 m_impl->groupAlias = md;
4556 void MemberDef::invalidateTypedefValCache()
4559 m_impl->isTypedefValCached=FALSE;
4562 void MemberDef::setMemberDefinition(MemberDef *md)
4568 void MemberDef::setMemberDeclaration(MemberDef *md)
4574 ClassDef *MemberDef::category() const
4577 return m_impl->category;
4580 void MemberDef::setCategory(ClassDef *def)
4583 m_impl->category = def;
4586 MemberDef *MemberDef::categoryRelation() const
4589 return m_impl->categoryRelation;
4592 void MemberDef::setCategoryRelation(MemberDef *md)
4595 m_impl->categoryRelation = md;
4598 void MemberDef::setEnumBaseType(const QCString &type)
4601 m_impl->enumBaseType = type;
4604 QCString MemberDef::enumBaseType() const
4607 return m_impl->enumBaseType;
4611 void MemberDef::cacheTypedefVal(ClassDef*val, const QCString & templSpec, const QCString &resolvedType)
4614 m_impl->isTypedefValCached=TRUE;
4615 m_impl->cachedTypedefValue=val;
4616 m_impl->cachedTypedefTemplSpec=templSpec;
4617 m_impl->cachedResolvedType=resolvedType;
4618 //printf("MemberDef::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
4621 void MemberDef::copyArgumentNames(MemberDef *bmd)
4625 LockingPtr<ArgumentList> arguments = bmd->argumentList();
4626 if (m_impl->defArgList && arguments!=0)
4628 ArgumentListIterator aliDst(*m_impl->defArgList);
4629 ArgumentListIterator aliSrc(*arguments);
4630 Argument *argDst, *argSrc;
4631 for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
4633 argDst->name = argSrc->name;
4638 LockingPtr<ArgumentList> arguments = bmd->declArgumentList();
4639 if (m_impl->declArgList && arguments!=0)
4641 ArgumentListIterator aliDst(*m_impl->declArgList);
4642 ArgumentListIterator aliSrc(*arguments);
4643 Argument *argDst, *argSrc;
4644 for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
4646 argDst->name = argSrc->name;
4652 static void invalidateCachedTypesInArgumentList(ArgumentList *al)
4656 ArgumentListIterator ali(*al);
4658 for (ali.toFirst();(a=ali.current());++ali)
4660 a->canType.resize(0);
4665 void MemberDef::invalidateCachedArgumentTypes()
4668 invalidateCachedTypesInArgumentList(m_impl->defArgList);
4669 invalidateCachedTypesInArgumentList(m_impl->declArgList);
4673 //-----------------------------------------------------------------
4675 void MemberDef::flushToDisk() const
4677 if (isLocked()) return;
4678 MemberDef *that = (MemberDef*)this;
4679 that->m_storagePos = Doxygen::symbolStorage->alloc();
4680 //printf("%p: MemberDef::flushToDisk() m_impl=%p\n",this,m_impl);
4681 // write the definition base class member variables to disk
4682 Definition::flushToDisk();
4684 //printf("%p: flushing specific part\n",this);
4686 // write the memberdef member variables to disk
4687 marshalUInt(Doxygen::symbolStorage,START_MARKER);
4688 marshalObjPointer (Doxygen::symbolStorage,m_impl->classDef);
4689 marshalObjPointer (Doxygen::symbolStorage,m_impl->fileDef);
4690 marshalObjPointer (Doxygen::symbolStorage,m_impl->nspace);
4691 marshalObjPointer (Doxygen::symbolStorage,m_impl->enumScope);
4692 marshalObjPointer (Doxygen::symbolStorage,m_impl->annEnumType);
4693 marshalMemberList (Doxygen::symbolStorage,m_impl->enumFields);
4694 marshalObjPointer (Doxygen::symbolStorage,m_impl->redefines);
4695 marshalMemberList (Doxygen::symbolStorage,m_impl->redefinedBy);
4696 marshalObjPointer (Doxygen::symbolStorage,m_impl->memDef);
4697 marshalObjPointer (Doxygen::symbolStorage,m_impl->memDec);
4698 marshalObjPointer (Doxygen::symbolStorage,m_impl->relatedAlso);
4699 marshalExampleSDict (Doxygen::symbolStorage,m_impl->exampleSDict);
4700 marshalQCString (Doxygen::symbolStorage,m_impl->type);
4701 marshalQCString (Doxygen::symbolStorage,m_impl->enumBaseType);
4702 marshalQCString (Doxygen::symbolStorage,m_impl->accessorType);
4703 marshalObjPointer (Doxygen::symbolStorage,m_impl->accessorClass);
4704 marshalQCString (Doxygen::symbolStorage,m_impl->args);
4705 marshalQCString (Doxygen::symbolStorage,m_impl->def);
4706 marshalQCString (Doxygen::symbolStorage,m_impl->anc);
4707 marshalInt (Doxygen::symbolStorage,(int)m_impl->virt);
4708 marshalInt (Doxygen::symbolStorage,(int)m_impl->prot);
4709 marshalQCString (Doxygen::symbolStorage,m_impl->decl);
4710 marshalQCString (Doxygen::symbolStorage,m_impl->bitfields);
4711 marshalQCString (Doxygen::symbolStorage,m_impl->read);
4712 marshalQCString (Doxygen::symbolStorage,m_impl->write);
4713 marshalQCString (Doxygen::symbolStorage,m_impl->exception);
4714 marshalQCString (Doxygen::symbolStorage,m_impl->initializer);
4715 marshalQCString (Doxygen::symbolStorage,m_impl->extraTypeChars);
4716 marshalInt (Doxygen::symbolStorage,m_impl->initLines);
4717 marshalInt (Doxygen::symbolStorage,m_impl->memSpec);
4718 marshalInt (Doxygen::symbolStorage,(int)m_impl->mtype);
4719 marshalInt (Doxygen::symbolStorage,m_impl->maxInitLines);
4720 marshalInt (Doxygen::symbolStorage,m_impl->userInitLines);
4721 marshalObjPointer (Doxygen::symbolStorage,m_impl->annMemb);
4722 marshalArgumentList (Doxygen::symbolStorage,m_impl->defArgList);
4723 marshalArgumentList (Doxygen::symbolStorage,m_impl->declArgList);
4724 marshalArgumentList (Doxygen::symbolStorage,m_impl->tArgList);
4725 marshalArgumentList (Doxygen::symbolStorage,m_impl->typeConstraints);
4726 marshalObjPointer (Doxygen::symbolStorage,m_impl->templateMaster);
4727 marshalArgumentLists(Doxygen::symbolStorage,m_impl->defTmpArgLists);
4728 marshalObjPointer (Doxygen::symbolStorage,m_impl->cachedAnonymousType);
4729 marshalMemberLists (Doxygen::symbolStorage,m_impl->classSectionSDict);
4730 marshalObjPointer (Doxygen::symbolStorage,m_impl->groupAlias);
4731 marshalInt (Doxygen::symbolStorage,m_impl->grpId);
4732 marshalObjPointer (Doxygen::symbolStorage,m_impl->memberGroup);
4733 marshalObjPointer (Doxygen::symbolStorage,m_impl->group);
4734 marshalInt (Doxygen::symbolStorage,(int)m_impl->grouppri);
4735 marshalQCString (Doxygen::symbolStorage,m_impl->groupFileName);
4736 marshalInt (Doxygen::symbolStorage,m_impl->groupStartLine);
4737 marshalObjPointer (Doxygen::symbolStorage,m_impl->groupMember);
4738 marshalBool (Doxygen::symbolStorage,m_impl->isTypedefValCached);
4739 marshalObjPointer (Doxygen::symbolStorage,m_impl->cachedTypedefValue);
4740 marshalQCString (Doxygen::symbolStorage,m_impl->cachedTypedefTemplSpec);
4741 marshalQCString (Doxygen::symbolStorage,m_impl->cachedResolvedType);
4742 marshalObjPointer (Doxygen::symbolStorage,m_impl->docProvider);
4743 marshalQCString (Doxygen::symbolStorage,m_impl->explicitOutputFileBase);
4744 marshalBool (Doxygen::symbolStorage,m_impl->implOnly);
4745 marshalBool (Doxygen::symbolStorage,m_impl->hasDocumentedParams);
4746 marshalBool (Doxygen::symbolStorage,m_impl->hasDocumentedReturnType);
4747 marshalBool (Doxygen::symbolStorage,m_impl->isDMember);
4748 marshalInt (Doxygen::symbolStorage,(int)m_impl->related);
4749 marshalBool (Doxygen::symbolStorage,m_impl->stat);
4750 marshalBool (Doxygen::symbolStorage,m_impl->proto);
4751 marshalBool (Doxygen::symbolStorage,m_impl->docEnumValues);
4752 marshalBool (Doxygen::symbolStorage,m_impl->annScope);
4753 marshalBool (Doxygen::symbolStorage,m_impl->annUsed);
4754 marshalBool (Doxygen::symbolStorage,m_impl->hasCallGraph);
4755 marshalBool (Doxygen::symbolStorage,m_impl->hasCallerGraph);
4756 marshalBool (Doxygen::symbolStorage,m_impl->explExt);
4757 marshalBool (Doxygen::symbolStorage,m_impl->tspec);
4758 marshalBool (Doxygen::symbolStorage,m_impl->groupHasDocs);
4759 marshalBool (Doxygen::symbolStorage,m_impl->docsForDefinition);
4760 marshalObjPointer (Doxygen::symbolStorage,m_impl->category);
4761 marshalObjPointer (Doxygen::symbolStorage,m_impl->categoryRelation);
4762 marshalUInt(Doxygen::symbolStorage,END_MARKER);
4764 // function doesn't modify the object conceptually but compiler doesn't know this.
4765 delete that->m_impl;
4767 that->m_flushPending=FALSE;
4770 void MemberDef::loadFromDisk() const
4772 MemberDef *that = (MemberDef *)this;
4775 //printf("%p: loadFromDisk() locked: so still in memory\n",this);
4781 Doxygen::symbolStorage->seek(m_storagePos);
4782 Definition::loadFromDisk();
4784 //printf("%p: loading specific part\n",this);
4786 that->m_impl = new MemberDefImpl;
4787 //printf("%p: MemberDef::loadFromDisk(): m_impl=%p\n",this,m_impl);
4789 uint marker = unmarshalUInt(Doxygen::symbolStorage);
4790 assert(marker==START_MARKER);
4791 m_impl->classDef = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4792 m_impl->fileDef = (FileDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4793 m_impl->nspace = (NamespaceDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4794 m_impl->enumScope = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4795 m_impl->annEnumType = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4796 m_impl->enumFields = unmarshalMemberList (Doxygen::symbolStorage);
4797 m_impl->redefines = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4798 m_impl->redefinedBy = unmarshalMemberList (Doxygen::symbolStorage);
4799 m_impl->memDef = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4800 m_impl->memDec = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4801 m_impl->relatedAlso = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4802 m_impl->exampleSDict = unmarshalExampleSDict (Doxygen::symbolStorage);
4803 m_impl->type = unmarshalQCString (Doxygen::symbolStorage);
4804 m_impl->enumBaseType = unmarshalQCString (Doxygen::symbolStorage);
4805 m_impl->accessorType = unmarshalQCString (Doxygen::symbolStorage);
4806 m_impl->accessorClass = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4807 m_impl->args = unmarshalQCString (Doxygen::symbolStorage);
4808 m_impl->def = unmarshalQCString (Doxygen::symbolStorage);
4809 m_impl->anc = unmarshalQCString (Doxygen::symbolStorage);
4810 m_impl->virt = (Specifier)unmarshalInt (Doxygen::symbolStorage);
4811 m_impl->prot = (Protection)unmarshalInt(Doxygen::symbolStorage);
4812 m_impl->decl = unmarshalQCString (Doxygen::symbolStorage);
4813 m_impl->bitfields = unmarshalQCString (Doxygen::symbolStorage);
4814 m_impl->read = unmarshalQCString (Doxygen::symbolStorage);
4815 m_impl->write = unmarshalQCString (Doxygen::symbolStorage);
4816 m_impl->exception = unmarshalQCString (Doxygen::symbolStorage);
4817 m_impl->initializer = unmarshalQCString (Doxygen::symbolStorage);
4818 m_impl->extraTypeChars = unmarshalQCString (Doxygen::symbolStorage);
4819 m_impl->initLines = unmarshalInt (Doxygen::symbolStorage);
4820 m_impl->memSpec = unmarshalInt (Doxygen::symbolStorage);
4821 m_impl->mtype = (MemberDef::MemberType)unmarshalInt (Doxygen::symbolStorage);
4822 m_impl->maxInitLines = unmarshalInt (Doxygen::symbolStorage);
4823 m_impl->userInitLines = unmarshalInt (Doxygen::symbolStorage);
4824 m_impl->annMemb = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4825 m_impl->defArgList = unmarshalArgumentList (Doxygen::symbolStorage);
4826 m_impl->declArgList = unmarshalArgumentList (Doxygen::symbolStorage);
4827 m_impl->tArgList = unmarshalArgumentList (Doxygen::symbolStorage);
4828 m_impl->typeConstraints = unmarshalArgumentList (Doxygen::symbolStorage);
4829 m_impl->templateMaster = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4830 m_impl->defTmpArgLists = unmarshalArgumentLists(Doxygen::symbolStorage);
4831 m_impl->cachedAnonymousType = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4832 m_impl->classSectionSDict = unmarshalMemberLists (Doxygen::symbolStorage);
4833 m_impl->groupAlias = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4834 m_impl->grpId = unmarshalInt (Doxygen::symbolStorage);
4835 m_impl->memberGroup = (MemberGroup*)unmarshalObjPointer (Doxygen::symbolStorage);
4836 m_impl->group = (GroupDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4837 m_impl->grouppri = (Grouping::GroupPri_t)unmarshalInt (Doxygen::symbolStorage);
4838 m_impl->groupFileName = unmarshalQCString (Doxygen::symbolStorage);
4839 m_impl->groupStartLine = unmarshalInt (Doxygen::symbolStorage);
4840 m_impl->groupMember = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4841 m_impl->isTypedefValCached = unmarshalBool (Doxygen::symbolStorage);
4842 m_impl->cachedTypedefValue = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4843 m_impl->cachedTypedefTemplSpec = unmarshalQCString (Doxygen::symbolStorage);
4844 m_impl->cachedResolvedType = unmarshalQCString (Doxygen::symbolStorage);
4845 m_impl->docProvider = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4846 m_impl->explicitOutputFileBase = unmarshalQCString (Doxygen::symbolStorage);
4847 m_impl->implOnly = unmarshalBool (Doxygen::symbolStorage);
4848 m_impl->hasDocumentedParams = unmarshalBool (Doxygen::symbolStorage);
4849 m_impl->hasDocumentedReturnType = unmarshalBool (Doxygen::symbolStorage);
4850 m_impl->isDMember = unmarshalBool (Doxygen::symbolStorage);
4851 m_impl->related = (Relationship)unmarshalInt(Doxygen::symbolStorage);
4852 m_impl->stat = unmarshalBool (Doxygen::symbolStorage);
4853 m_impl->proto = unmarshalBool (Doxygen::symbolStorage);
4854 m_impl->docEnumValues = unmarshalBool (Doxygen::symbolStorage);
4855 m_impl->annScope = unmarshalBool (Doxygen::symbolStorage);
4856 m_impl->annUsed = unmarshalBool (Doxygen::symbolStorage);
4857 m_impl->hasCallGraph = unmarshalBool (Doxygen::symbolStorage);
4858 m_impl->hasCallerGraph = unmarshalBool (Doxygen::symbolStorage);
4859 m_impl->explExt = unmarshalBool (Doxygen::symbolStorage);
4860 m_impl->tspec = unmarshalBool (Doxygen::symbolStorage);
4861 m_impl->groupHasDocs = unmarshalBool (Doxygen::symbolStorage);
4862 m_impl->docsForDefinition = unmarshalBool (Doxygen::symbolStorage);
4863 m_impl->category = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4864 m_impl->categoryRelation = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
4865 marker = unmarshalUInt(Doxygen::symbolStorage);
4866 assert(marker==END_MARKER);
4868 //printf("%p: MemberDef::loadFromDisk(): sorting\n",this);
4871 void MemberDef::makeResident() const
4873 if (Doxygen::symbolCache==0) return;
4874 if (m_cacheHandle==-1) // not yet in cache
4876 MemberDef *victim = 0;
4877 MemberDef *that = (MemberDef*)this; // fake method constness
4878 that->m_cacheHandle = Doxygen::symbolCache->add(that,(void **)&victim);
4879 //printf("adding %s to cache, handle=%d\n",m_impl->name.data(),that->m_cacheHandle);
4880 if (victim) // cache was full, victim was the least recently used item and has to go
4882 //printf("%p: makeResident(): cache full %p::saveToDisk(): m_impl=%p\n",this,victim,victim->m_impl);
4883 victim->m_cacheHandle=-1; // invalidate cache handle
4884 victim->saveToDisk(); // store the item on disk
4886 else // cache not yet full
4888 //printf("Adding %s to cache, handle=%d\n",m_impl->name.data(),m_cacheHandle);
4890 if (m_storagePos!=-1) // already been written to disk
4892 if (isLocked()) // locked in memory
4895 that->m_flushPending=FALSE; // no need to flush anymore
4897 else // not locked in memory
4904 else // already cached, make this object the most recently used.
4907 //printf("Touching symbol %s\n",m_impl->name.data());
4908 Doxygen::symbolCache->use(m_cacheHandle);
4912 void MemberDef::saveToDisk() const
4915 MemberDef *that = (MemberDef *)this;
4916 //printf("%p: saveToDisk(): m_impl=%p\n",this,m_impl);
4917 if (isLocked()) // cannot flush the item as it is locked
4919 that->m_flushPending=TRUE; // flush when unlocked
4921 else // ready to flush the item to disk
4923 //printf("Adding %s to cache, handle=%d by replacing %s\n",
4924 // m_impl->name.data(),m_cacheHandle,victim->m_impl->name.data());
4925 if (m_storagePos!=-1)
4926 // if victim was stored on disk already and is not locked
4928 // free the storage space occupied by the old store item
4929 Doxygen::symbolStorage->release(m_storagePos); // free up space for others
4931 // write a the new (possibly modified) instance to disk
4933 // end to write sequence (unless nothing was written due to the lock)
4934 Doxygen::symbolStorage->end();
4938 void MemberDef::lock() const
4942 void MemberDef::unlock() const
4944 if (m_flushPending && !isLocked())
4946 //printf("%p: flush after unlock\n",this);
4947 // write a the new (possibly modified) instance to disk
4949 // end to write sequence (unless nothing was written due to the lock)
4950 Doxygen::symbolStorage->end();
4954 QCString MemberDef::displayName(bool) const
4956 return Definition::name();
4961 static void transferArgumentDocumentation(ArgumentList *decAl,ArgumentList *defAl)
4965 ArgumentListIterator decAli(*decAl);
4966 ArgumentListIterator defAli(*defAl);
4967 Argument *decA,*defA;
4968 for (decAli.toFirst(),defAli.toFirst();
4969 (decA=decAli.current()) && (defA=defAli.current());
4972 //printf("Argument decA->name=%s (doc=%s) defA->name=%s (doc=%s)\n",
4973 // decA->name.data(),decA->docs.data(),
4974 // defA->name.data(),defA->docs.data()
4976 if (decA->docs.isEmpty() && !defA->docs.isEmpty())
4978 decA->docs = defA->docs.copy();
4980 else if (defA->docs.isEmpty() && !decA->docs.isEmpty())
4982 defA->docs = decA->docs.copy();
4988 void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef)
4990 //printf("mdec=%s isPrototype()=%d\n",mdec->name().data(),mdec->isPrototype());
4992 (mdef->isFunction() && !mdef->isStatic() && !mdef->isPrototype()) ||
4993 (mdef->isVariable() && !mdef->isExternal() && !mdef->isStatic())
4996 //printf("mdef=(%p,%s) mdec=(%p,%s)\n",
4997 // mdef, mdef ? mdef->name().data() : "",
4998 // mdec, mdec ? mdec->name().data() : "");
5000 LockingPtr<ArgumentList> mdefAl = mdef->argumentList();
5001 LockingPtr<ArgumentList> mdecAl = mdec->argumentList();
5002 if (matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl.pointer(),
5003 mdec->getOuterScope(),mdec->getFileDef(),mdecAl.pointer(),
5008 //printf("Found member %s: definition in %s (doc=`%s') and declaration in %s (doc=`%s')\n",
5009 // mn->memberName(),
5010 // mdef->getFileDef()->name().data(),mdef->documentation().data(),
5011 // mdec->getFileDef()->name().data(),mdec->documentation().data()
5014 // first merge argument documentation
5015 transferArgumentDocumentation(mdecAl.pointer(),mdefAl.pointer());
5017 /* copy documentation between function definition and declaration */
5018 if (!mdec->briefDescription().isEmpty())
5020 mdef->setBriefDescription(mdec->briefDescription(),mdec->briefFile(),mdec->briefLine());
5022 else if (!mdef->briefDescription().isEmpty())
5024 mdec->setBriefDescription(mdef->briefDescription(),mdef->briefFile(),mdef->briefLine());
5026 if (!mdef->documentation().isEmpty())
5028 //printf("transfering docs mdef->mdec (%s->%s)\n",mdef->argsString(),mdec->argsString());
5029 mdec->setDocumentation(mdef->documentation(),mdef->docFile(),mdef->docLine());
5030 mdec->setDocsForDefinition(mdef->isDocsForDefinition());
5033 ArgumentList *mdefAlComb = new ArgumentList;
5034 stringToArgumentList(mdef->argsString(),mdefAlComb);
5035 transferArgumentDocumentation(mdefAl.pointer(),mdefAlComb);
5036 mdec->setArgumentList(mdefAlComb);
5039 else if (!mdec->documentation().isEmpty())
5041 //printf("transfering docs mdec->mdef (%s->%s)\n",mdec->argsString(),mdef->argsString());
5042 mdef->setDocumentation(mdec->documentation(),mdec->docFile(),mdec->docLine());
5043 mdef->setDocsForDefinition(mdec->isDocsForDefinition());
5046 ArgumentList *mdecAlComb = new ArgumentList;
5047 stringToArgumentList(mdec->argsString(),mdecAlComb);
5048 transferArgumentDocumentation(mdecAl.pointer(),mdecAlComb);
5049 mdef->setDeclArgumentList(mdecAlComb);
5052 if (!mdef->inbodyDocumentation().isEmpty())
5054 mdec->setInbodyDocumentation(mdef->inbodyDocumentation(),mdef->inbodyFile(),mdef->inbodyLine());
5056 else if (!mdec->inbodyDocumentation().isEmpty())
5058 mdef->setInbodyDocumentation(mdec->inbodyDocumentation(),mdec->inbodyFile(),mdec->inbodyLine());
5060 if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
5062 //printf("body mdec->mdef %d-%d\n",mdec->getStartBodyLine(),mdef->getEndBodyLine());
5063 mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine());
5064 mdef->setBodyDef(mdec->getBodyDef());
5065 //mdef->setBodyMember(mdec);
5067 else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
5069 //printf("body mdef->mdec %d-%d\n",mdef->getStartBodyLine(),mdec->getEndBodyLine());
5070 mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine());
5071 mdec->setBodyDef(mdef->getBodyDef());
5072 //mdec->setBodyMember(mdef);
5074 mdec->mergeMemberSpecifiers(mdef->getMemberSpecifiers());
5075 mdef->mergeMemberSpecifiers(mdec->getMemberSpecifiers());
5079 if (mdec->getGroupDef()==0 && mdef->getGroupDef()!=0)
5081 mdec->setGroupDef(mdef->getGroupDef(),
5082 mdef->getGroupPri(),
5085 mdef->hasDocumentation(),
5089 else if (mdef->getGroupDef()==0 && mdec->getGroupDef()!=0)
5091 mdef->setGroupDef(mdec->getGroupDef(),
5092 mdec->getGroupPri(),
5095 mdec->hasDocumentation(),
5101 mdec->mergeRefItems(mdef);
5102 mdef->mergeRefItems(mdec);
5104 mdef->setMemberDeclaration(mdec);
5105 mdec->setMemberDefinition(mdef);
5107 mdef->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
5108 mdef->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
5109 mdec->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
5110 mdec->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());