My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Functions
memberdef.cpp File Reference
#include <stdio.h>
#include <qglobal.h>
#include <qregexp.h>
#include <assert.h>
#include "md5.h"
#include "memberdef.h"
#include "membername.h"
#include "doxygen.h"
#include "util.h"
#include "code.h"
#include "message.h"
#include "htmlhelp.h"
#include "language.h"
#include "outputlist.h"
#include "example.h"
#include "membergroup.h"
#include "groupdef.h"
#include "defargs.h"
#include "docparser.h"
#include "dot.h"
#include "searchindex.h"
#include "parserintf.h"
#include "marshal.h"
#include "objcache.h"
#include "vhdldocgen.h"
#include "arguments.h"
#include "memberlist.h"
#include "namespacedef.h"
#include "filedef.h"
#include "config.h"

Go to the source code of this file.

Classes

class  MemberDefImpl
 

Functions

static QCString addTemplateNames (const QCString &s, const QCString &n, const QCString &t)
 
static bool writeDefArgumentList (OutputList &ol, Definition *scope, MemberDef *md)
 
static void writeExceptionListImpl (OutputList &ol, ClassDef *cd, MemberDef *md, QCString const &exception)
 
static void writeExceptionList (OutputList &ol, ClassDef *cd, MemberDef *md)
 
static void writeTemplatePrefix (OutputList &ol, ArgumentList *al)
 
static QCString simplifyTypeForTable (const QCString &s)
 
static void invalidateCachedTypesInArgumentList (ArgumentList *al)
 
static void transferArgumentDocumentation (ArgumentList *decAl, ArgumentList *defAl)
 
void combineDeclarationAndDefinition (MemberDef *mdec, MemberDef *mdef)
 

Function Documentation

static QCString addTemplateNames ( const QCString &  s,
const QCString &  n,
const QCString &  t 
)
static

Definition at line 54 of file memberdef.cpp.

References isId().

Referenced by writeDefArgumentList().

{
QCString result;
QCString clRealName=n;
int p=0,i;
if ((i=clRealName.find('<'))!=-1)
{
clRealName=clRealName.left(i); // strip template specialization
}
if ((i=clRealName.findRev("::"))!=-1)
{
clRealName=clRealName.right(clRealName.length()-i-2);
}
while ((i=s.find(clRealName,p))!=-1)
{
result+=s.mid(p,i-p);
uint j=clRealName.length()+i;
if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
{ // add template names
//printf("Adding %s+%s\n",clRealName.data(),t.data());
result+=clRealName+t;
}
else
{ // template names already present
//printf("Adding %s\n",clRealName.data());
result+=clRealName;
}
p=i+clRealName.length();
}
result+=s.right(s.length()-p);
//printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
return result;
}
void combineDeclarationAndDefinition ( MemberDef mdec,
MemberDef mdef 
)

Definition at line 4960 of file memberdef.cpp.

References MemberDef::argsString(), MemberDef::argumentList(), MemberDef::briefDescription(), Definition::briefFile(), Definition::briefLine(), Definition::docFile(), Definition::docLine(), MemberDef::documentation(), MemberDef::enableCallerGraph(), MemberDef::enableCallGraph(), Definition::getBodyDef(), Definition::getEndBodyLine(), MemberDef::getFileDef(), MemberDef::getGroupDef(), MemberDef::getGroupPri(), MemberDef::getMemberSpecifiers(), Definition::getOuterScope(), Definition::getStartBodyLine(), MemberDef::hasCallerGraph(), MemberDef::hasCallGraph(), MemberDef::hasDocumentation(), Definition::inbodyDocumentation(), Definition::inbodyFile(), Definition::inbodyLine(), MemberDef::isDocsForDefinition(), MemberDef::isExternal(), MemberDef::isFunction(), MemberDef::isPrototype(), MemberDef::isStatic(), MemberDef::isVariable(), matchArguments2(), MemberDef::mergeMemberSpecifiers(), Definition::mergeRefItems(), MemberDef::setArgumentList(), Definition::setBodyDef(), Definition::setBodySegment(), MemberDef::setBriefDescription(), MemberDef::setDeclArgumentList(), MemberDef::setDocsForDefinition(), MemberDef::setDocumentation(), MemberDef::setGroupDef(), MemberDef::setInbodyDocumentation(), MemberDef::setMemberDeclaration(), MemberDef::setMemberDefinition(), stringToArgumentList(), and transferArgumentDocumentation().

Referenced by ClassDef::mergeCategory(), and transferFunctionDocumentation().

{
//printf("mdec=%s isPrototype()=%d\n",mdec->name().data(),mdec->isPrototype());
if (
(mdef->isFunction() && !mdef->isStatic() && !mdef->isPrototype()) ||
(mdef->isVariable() && !mdef->isExternal() && !mdef->isStatic())
)
{
//printf("mdef=(%p,%s) mdec=(%p,%s)\n",
// mdef, mdef ? mdef->name().data() : "",
// mdec, mdec ? mdec->name().data() : "");
ArgumentList *mdefAl = mdef->argumentList();
ArgumentList *mdecAl = mdec->argumentList();
if (matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl,
mdec->getOuterScope(),mdec->getFileDef(),mdecAl,
TRUE
)
) /* match found */
{
//printf("Found member %s: definition in %s (doc=`%s') and declaration in %s (doc=`%s')\n",
// mn->memberName(),
// mdef->getFileDef()->name().data(),mdef->documentation().data(),
// mdec->getFileDef()->name().data(),mdec->documentation().data()
// );
// first merge argument documentation
/* copy documentation between function definition and declaration */
if (!mdec->briefDescription().isEmpty())
{
mdef->setBriefDescription(mdec->briefDescription(),mdec->briefFile(),mdec->briefLine());
}
else if (!mdef->briefDescription().isEmpty())
{
mdec->setBriefDescription(mdef->briefDescription(),mdef->briefFile(),mdef->briefLine());
}
if (!mdef->documentation().isEmpty())
{
//printf("transferring docs mdef->mdec (%s->%s)\n",mdef->argsString(),mdec->argsString());
mdec->setDocumentation(mdef->documentation(),mdef->docFile(),mdef->docLine());
if (mdefAl!=0)
{
ArgumentList *mdefAlComb = new ArgumentList;
stringToArgumentList(mdef->argsString(),mdefAlComb);
transferArgumentDocumentation(mdefAl,mdefAlComb);
mdec->setArgumentList(mdefAlComb);
}
}
else if (!mdec->documentation().isEmpty())
{
//printf("transferring docs mdec->mdef (%s->%s)\n",mdec->argsString(),mdef->argsString());
mdef->setDocumentation(mdec->documentation(),mdec->docFile(),mdec->docLine());
if (mdecAl!=0)
{
ArgumentList *mdecAlComb = new ArgumentList;
stringToArgumentList(mdec->argsString(),mdecAlComb);
transferArgumentDocumentation(mdecAl,mdecAlComb);
mdef->setDeclArgumentList(mdecAlComb);
}
}
if (!mdef->inbodyDocumentation().isEmpty())
{
}
else if (!mdec->inbodyDocumentation().isEmpty())
{
}
if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
{
//printf("body mdec->mdef %d-%d\n",mdec->getStartBodyLine(),mdef->getEndBodyLine());
mdef->setBodyDef(mdec->getBodyDef());
//mdef->setBodyMember(mdec);
}
else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
{
//printf("body mdef->mdec %d-%d\n",mdef->getStartBodyLine(),mdec->getEndBodyLine());
mdec->setBodyDef(mdef->getBodyDef());
//mdec->setBodyMember(mdef);
}
// copy group info.
if (mdec->getGroupDef()==0 && mdef->getGroupDef()!=0)
{
mdec->setGroupDef(mdef->getGroupDef(),
mdef->getGroupPri(),
mdef->docFile(),
mdef->docLine(),
mdef
);
}
else if (mdef->getGroupDef()==0 && mdec->getGroupDef()!=0)
{
mdef->setGroupDef(mdec->getGroupDef(),
mdec->getGroupPri(),
mdec->docFile(),
mdec->docLine(),
mdec
);
}
mdec->mergeRefItems(mdef);
mdef->mergeRefItems(mdec);
mdef->setMemberDeclaration(mdec);
mdec->setMemberDefinition(mdef);
mdef->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
mdef->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
mdec->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
mdec->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
}
}
}
static void invalidateCachedTypesInArgumentList ( ArgumentList al)
static

Definition at line 4880 of file memberdef.cpp.

References Argument::canType.

Referenced by MemberDef::invalidateCachedArgumentTypes().

{
if (al)
{
for (ali.toFirst();(a=ali.current());++ali)
{
a->canType.resize(0);
}
}
}
static QCString simplifyTypeForTable ( const QCString &  s)
static

Definition at line 3032 of file memberdef.cpp.

References removeAnonymousScopes().

Referenced by MemberDef::fieldType().

{
QCString ts=removeAnonymousScopes(s);
if (ts.right(2)=="::") ts = ts.left(ts.length()-2);
static QRegExp re("[A-Z_a-z0-9]+::");
int i,l;
while ((i=re.match(ts,0,&l))!=-1)
{
ts=ts.left(i)+ts.mid(i+l);
}
i=ts.findRev('.');
if (i!=-1) ts = ts.left(i);
i=ts.findRev('.');
if (i!=-1) ts = ts.right(ts.length()-i-1);
//printf("simplifyTypeForTable(%s)->%s\n",s.data(),ts.data());
return ts;
}
static void transferArgumentDocumentation ( ArgumentList decAl,
ArgumentList defAl 
)
static

Definition at line 4933 of file memberdef.cpp.

References Argument::docs.

Referenced by combineDeclarationAndDefinition().

{
if (decAl && defAl)
{
ArgumentListIterator decAli(*decAl);
ArgumentListIterator defAli(*defAl);
Argument *decA,*defA;
for (decAli.toFirst(),defAli.toFirst();
(decA=decAli.current()) && (defA=defAli.current());
++decAli,++defAli)
{
//printf("Argument decA->name=%s (doc=%s) defA->name=%s (doc=%s)\n",
// decA->name.data(),decA->docs.data(),
// defA->name.data(),defA->docs.data()
// );
if (decA->docs.isEmpty() && !defA->docs.isEmpty())
{
decA->docs = defA->docs.copy();
}
else if (defA->docs.isEmpty() && !decA->docs.isEmpty())
{
defA->docs = decA->docs.copy();
}
}
}
}
static bool writeDefArgumentList ( OutputList ol,
Definition scope,
MemberDef md 
)
static

Definition at line 121 of file memberdef.cpp.

References addTemplateNames(), MemberDef::argumentList(), Argument::array, Argument::attrib, ArgumentList::constSpecifier, MemberDef::declArgumentList(), DefinitionIntf::definitionType(), Argument::defval, OutputList::disable(), OutputList::docify(), OutputList::enable(), OutputList::enableAll(), OutputList::endEmphasis(), OutputList::endMemberDocName(), OutputList::endParameterName(), OutputList::endParameterType(), OutputList::endTypewriter(), MemberDef::extraTypeChars(), Definition::getBodyDef(), Definition::getLanguage(), OutputGenerator::Html, MemberDef::isDefine(), MemberDef::isDocsForDefinition(), OutputList::isEnabled(), MemberDef::isObjCMethod(), MemberDef::isProperty(), OutputGenerator::Latex, linkifyText(), OutputGenerator::Man, Argument::name, Definition::name(), OutputList::popGeneratorState(), OutputList::pushGeneratorState(), SrcLangExt_Tcl, OutputList::startEmphasis(), OutputList::startParameterList(), OutputList::startParameterName(), OutputList::startParameterType(), OutputList::startTypewriter(), tempArgListToString(), ArgumentList::trailingReturnType, Argument::type, DefinitionIntf::TypeClass, and ArgumentList::volatileSpecifier.

Referenced by MemberDef::writeDocumentation().

{
ArgumentList *defArgList=(md->isDocsForDefinition()) ?
//printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
if (defArgList==0 || md->isProperty())
{
return FALSE; // member has no function like argument list
}
// simple argument list for tcl
{
if (defArgList->count()==0) return FALSE;
ArgumentListIterator ali(*defArgList);
ol.startParameterList(FALSE);
ol.startParameterType(TRUE,0);
ol.startParameterName(FALSE);
for (;(a=ali.current());++ali)
{
if (a->defval.isEmpty())
{
ol.docify(a->name+" ");
}
else
{
ol.docify("?"+a->name+"? ");
}
}
ol.endParameterName(TRUE,FALSE,FALSE);
return TRUE;
}
if (!md->isDefine()) ol.docify(" ");
//printf("writeDefArgList(%d)\n",defArgList->count());
//ol.disableAllBut(OutputGenerator::Html);
bool htmlOn = ol.isEnabled(OutputGenerator::Html);
bool latexOn = ol.isEnabled(OutputGenerator::Latex);
{
// html and latex
if (htmlOn) ol.enable(OutputGenerator::Html);
if (latexOn) ol.enable(OutputGenerator::Latex);
}
ol.enableAll();
{
// other formats
if (!md->isObjCMethod()) ol.docify("("); // start argument list
}
//printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
QCString cName;
if (scope)
{
cName=scope->name();
int il=cName.find('<');
int ir=cName.findRev('>');
if (il!=-1 && ir!=-1 && ir>il)
{
cName=cName.mid(il,ir-il+1);
//printf("1. cName=%s\n",cName.data());
}
else if (scope->definitionType()==Definition::TypeClass && ((ClassDef*)scope)->templateArguments())
{
cName=tempArgListToString(((ClassDef*)scope)->templateArguments(),scope->getLanguage());
//printf("2. cName=%s\n",cName.data());
}
else // no template specifier
{
cName.resize(0);
}
}
//printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
bool first=TRUE;
bool paramTypeStarted=FALSE;
bool isDefine = md->isDefine();
ArgumentListIterator ali(*defArgList);
Argument *a=ali.current();
while (a)
{
if (isDefine || first)
{
ol.startParameterType(first,0);
paramTypeStarted=TRUE;
if (isDefine)
{
}
}
QRegExp re(")("),res("(.*\\*");
int vp=a->type.find(re);
int wp=a->type.find(res);
// use the following to put the function pointer type before the name
bool hasFuncPtrType=FALSE;
if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
{
ol.docify(a->attrib+" ");
}
if (hasFuncPtrType) // argument type is a function pointer
{
//printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data());
QCString n=a->type.left(vp);
if (hasFuncPtrType) n=a->type.left(wp);
if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
}
else // non-function pointer type
{
QCString n=a->type;
if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
if (a->type!="...")
{
if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
}
}
if (!isDefine)
{
if (paramTypeStarted)
{
paramTypeStarted=FALSE;
}
ol.startParameterName(defArgList->count()<2);
}
if (hasFuncPtrType)
{
ol.docify(a->type.mid(wp,vp-wp));
}
if (!a->name.isEmpty() || a->type=="...") // argument has a name
{
//if (!hasFuncPtrType)
//{
// ol.docify(" ");
//}
ol.docify(" "); /* man page */
if (htmlOn) ol.enable(OutputGenerator::Html);
if (latexOn) ol.enable(OutputGenerator::Latex);
if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name);
if (latexOn) ol.enable(OutputGenerator::Latex);
}
if (!a->array.isEmpty())
{
ol.docify(a->array);
}
if (hasFuncPtrType) // write the part of the argument type
// that comes after the name
{
md,a->type.right(a->type.length()-vp));
}
if (!a->defval.isEmpty()) // write the default value
{
QCString n=a->defval;
if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
ol.docify(" = ");
linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n,FALSE,TRUE,TRUE);
}
++ali;
a=ali.current();
if (a)
{
if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
if (!isDefine)
{
QCString key;
if (md->isObjCMethod() && a->attrib.length()>=2)
{
//printf("Found parameter keyword %s\n",a->attrib.data());
// strip [ and ]
key=a->attrib.mid(1,a->attrib.length()-2);
if (key!=",") key+=":"; // for normal keywords add colon
}
ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
if (paramTypeStarted)
{
}
ol.startParameterType(FALSE,key);
paramTypeStarted=TRUE;
}
else // isDefine
{
ol.endParameterName(FALSE,FALSE,TRUE);
}
}
first=FALSE;
}
if (!md->isObjCMethod()) ol.docify(")"); // end argument list
ol.enableAll();
if (htmlOn) ol.enable(OutputGenerator::Html);
if (latexOn) ol.enable(OutputGenerator::Latex);
if (first) ol.startParameterName(defArgList->count()<2);
ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
if (md->extraTypeChars())
{
}
if (defArgList->constSpecifier)
{
ol.docify(" const");
}
if (defArgList->volatileSpecifier)
{
ol.docify(" volatile");
}
if (!defArgList->trailingReturnType.isEmpty())
{
scope, // scope
md->getBodyDef(), // fileScope
md, // self
defArgList->trailingReturnType, // text
FALSE // autoBreak
);
}
return TRUE;
}
static void writeExceptionList ( OutputList ol,
ClassDef cd,
MemberDef md 
)
static

Definition at line 413 of file memberdef.cpp.

References Entry::exception, MemberDef::excpString(), and writeExceptionListImpl().

Referenced by MemberDef::writeDocumentation().

{
QCString exception(QCString(md->excpString()).stripWhiteSpace());
if ('{'==exception.at(0))
{
// this is an UNO IDL attribute - need special handling
int index = exception.find(';');
int oldIndex = 1;
while (-1 != index) // there should be no more than 2 (set / get)
{
// omit '{' and ';' -> "set raises (...)"
writeExceptionListImpl(ol,cd,md,exception.mid(oldIndex,index-oldIndex));
oldIndex=index+1;
index = exception.find(';',oldIndex);
}
// the rest is now just '}' - omit that
}
else
{
writeExceptionListImpl(ol,cd,md,exception);
}
}
static void writeExceptionListImpl ( OutputList ol,
ClassDef cd,
MemberDef md,
QCString const &  exception 
)
static

Definition at line 374 of file memberdef.cpp.

References OutputList::docify(), Entry::exception, OutputList::exceptionEntry(), Definition::getBodyDef(), Definition::getDefFileName(), Definition::getDefLine(), linkifyText(), Definition::name(), removeRedundantWhiteSpace(), Entry::type, and warn().

Referenced by writeExceptionList().

{
// this is ordinary exception spec - there must be a '('
//printf("exception='%s'\n",exception.data());
int index = exception.find('(');
if (index!=-1)
{
ol.exceptionEntry(exception.left(index),false);
++index; // paren in second column so skip it here
for (int comma = exception.find(',', index); comma!=-1; )
{
++comma; // include comma
exception.mid(index,comma-index));
ol.exceptionEntry(0,false);
index=comma;
comma = exception.find(',', index);
}
int close = exception.find(')', index);
if (close!=-1)
{
QCString type=removeRedundantWhiteSpace(exception.mid(index,close-index));
ol.exceptionEntry(0,true);
}
else
{
"missing ) in exception list on member %s",qPrint(md->name()));
}
}
else // Java Exception
{
ol.docify(" ");
linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,exception);
}
}
static void writeTemplatePrefix ( OutputList ol,
ArgumentList al 
)
static

Definition at line 436 of file memberdef.cpp.

References Argument::defval, OutputList::docify(), Argument::name, and Argument::type.

Referenced by MemberDef::writeDeclaration(), and MemberDef::writeDocumentation().

{
ol.docify("template<");
Argument *a = ali.current();
while (a)
{
ol.docify(a->type);
ol.docify(" ");
ol.docify(a->name);
if (a->defval.length()!=0)
{
ol.docify(" = ");
ol.docify(a->defval);
}
++ali;
a=ali.current();
if (a) ol.docify(", ");
}
ol.docify("> ");
}