diff options
Diffstat (limited to 'src/dot.cpp')
-rw-r--r-- | src/dot.cpp | 232 |
1 files changed, 46 insertions, 186 deletions
diff --git a/src/dot.cpp b/src/dot.cpp index 88e0571..bd13f75 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -40,7 +40,8 @@ static const char *edgeColorMap[] = "darkgreen", // Protected "firebrick4", // Private "darkorchid3", // "use" relation - "grey75" // Undocumented + "grey75", // Undocumented + "orange" // template relation }; static const char *edgeStyleMap[] = @@ -177,153 +178,6 @@ static bool isLeaf(ClassDef *cd) return TRUE; } -#if 0 -/*! Builds a mapping from formal arguments of class \a tcd to the - * actual arguments stored in templSpec. To properly initialize - * the mapping with the default template values - * ClassDef::initTemplateMapping() is called once for each class graph - * (the ClassDef::visited flag is used for this). - */ -static void setTemplateInstance(QCString templSpec,ClassDef *tcd) -{ - //printf("====== setTemplateInstance(templ=%s,class=%s)\n",templSpec.data(),tcd->name().data()); - if (!templSpec.isEmpty()) - { - //if (!tcd->visited) - //{ - // tcd->visited=TRUE; - //} - ArgumentList *tempArgList = new ArgumentList; - stringToArgumentList(templSpec,tempArgList); - ArgumentListIterator ali(*tempArgList); - Argument *arg; - uint count=0; - for (ali.toFirst();(arg=ali.current());++ali,++count) - { - ArgumentList *formalArgList = tcd->templateArguments(); - Argument *formalArg=0; - //printf("arg->type=%s count=%d formalArgList=%p\n", - // arg->type.data(),count,formalArgList); - if (formalArgList && formalArgList->count()>count && - (formalArg=formalArgList->at(count))) - { - if (formalArg->name!=arg->type) - { - tcd->setTemplateArgumentMapping(formalArg->name,arg->type); - //printf("%s->setTemplateInstantation(%s,%s)\n",tcd->name().data(), - // formalArg->name.data(),arg->type.data()); - } - } - } - delete tempArgList; - } -} - -/*! Substitutes the formal template argument list \a templSpec - * of class \a cd with the actual template arguments. - * The mapping from formal to actual template is assumed to be stored - * in \a cd using setTemplateInstance(). - */ -static QCString substituteTemplateSpec(ClassDef *cd,const QCString &templSpec) -{ - QCString result; - if (!templSpec.isEmpty()) - { - ArgumentList *tempArgList = new ArgumentList; - stringToArgumentList(templSpec,tempArgList); - ArgumentListIterator ali(*tempArgList); - Argument *arg; - bool first=TRUE; - for (ali.toFirst();(arg=ali.current());) - { - if (first) result="<",first=FALSE; - QCString actual = cd->getTemplateArgumentMapping(arg->type); - if (!actual.isEmpty()) - { - result+=actual; - } - else - { - result+=arg->type; - } - ++ali; - if (ali.current()) result+=","; else result+=">"; - } - delete tempArgList; - } - //printf("substituteTemplateSpec(%s,%s)=`%s'\n",cd->name().data(),templSpec.data(),result.data()); - return removeRedundantWhiteSpace(result); -} - -/*! Determines the actual template instance of template class \a tcd that - * relates to class \a cd. The result is stored in \a tcd. - * \param cd A class - * \param tcd A template base class - * \param templSpec Actual template parameter list to be used for tcd - * \param result resulting instance class - * \param actualArg actual template instance name of the resulting class - */ -static void computeTemplateInstance( - ClassDef *cd,ClassDef *tcd,const QCString templSpec, - ClassDef *&result,QCString &actualArg - - ) -{ - //printf("====== computeTemplateInstance(%s,base=%s,templ=%s)\n", - // cd->name().data(),tcd->name().data(),templSpec.data()); - // store the specific instance inside the class - setTemplateInstance(templSpec,tcd); - int tArgNum = tcd->isTemplateBaseClass(); - if (tArgNum!=-1) - { - //printf("tArgNum=%d\n",tArgNum); - ArgumentList *formalArgList = cd->templateArguments(); - if (formalArgList) - { - //printf("formalArgList=%p\n",formalArgList); - Argument *formalArg=formalArgList->at(tArgNum); - if (formalArg) - { - //printf("formalArg=%s\n",formalArg->name.data()); - actualArg = cd->getTemplateArgumentMapping(formalArg->name); - //printf("ActualArg=%s\n",actualArg.data()); - int pos=0; - QCString name; - QCString templSpec; - while (extractClassNameFromType(actualArg,pos,name,templSpec)) - { - Definition *scopeDef = cd->getOuterScope(); - QCString scopeName; - if (scopeDef) scopeName = scopeDef->qualifiedName(); - //printf("name=%s templSpec=%s\n",name.data(),templSpec.data()); - ClassDef *acd=0; - - // try with scope. - if (!scopeName.isEmpty()) - acd = getResolvedClass(scopeName+"::"+name); - // try without scope. - // TODO: try intermediate scopes as well! - if (acd==0) acd = getResolvedClass(name); - if (acd && !templSpec.isEmpty()) - { - // store specific template instance in the class - setTemplateInstance(templSpec,acd); - } - if (acd) - { - result = acd; - actualArg = acd->name()+templSpec; - return; - } - } - } - } - } - actualArg.resize(0); - result = 0; -} -#endif - //-------------------------------------------------------------------- class DotNodeList : public QList<DotNode> @@ -932,7 +786,7 @@ int DotClassGraph::m_curNodeNumber; void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot, const char *label,int distance,const char *usedName,const char *templSpec,bool base) { - int edgeStyle = label ? EdgeInfo::Dashed : EdgeInfo::Solid; + int edgeStyle = (label || prot==EdgeInfo::Orange) ? EdgeInfo::Dashed : EdgeInfo::Solid; QCString className; if (usedName) // name is a typedef { @@ -997,34 +851,22 @@ void DotClassGraph::addClass(ClassDef *cd,DotNode *n,int prot, void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base) { + // ---- Add inheritance relations + BaseClassListIterator bcli(base ? *cd->baseClasses() : *cd->subClasses()); BaseClassDef *bcd; for ( ; (bcd=bcli.current()) ; ++bcli ) { //printf("-------- inheritance relation %s->%s templ=`%s'\n", // cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data()); - //QCString templSpec; - //if (base) templSpec = substituteTemplateSpec( - // cd,bcd->templSpecifiers); - //ClassDef *acd=0; - //QCString actualArg; - //computeTemplateInstance(cd,bcd->classDef,templSpec,acd,actualArg); - //printf("acd=%p actualArg=%s\n",acd,actualArg.data()); - //if (acd) - //{ - // addClass(acd,n,bcd->prot,0,distance,actualArg, - // templSpec,base); - //} - //else - //{ - // addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName, - // templSpec,base); - //} addClass(bcd->classDef,n,bcd->prot,0,distance,bcd->usedName, bcd->templSpecifiers,base); } if (m_graphType != Inheritance) { + + // ---- Add usage relations + UsesClassDict *dict = m_graphType==Implementation ? cd->usedImplementationClasses() : cd->usedInterfaceClasses(); @@ -1050,30 +892,48 @@ void DotClassGraph::buildGraph(ClassDef *cd,DotNode *n,int distance,bool base) label+=QCString("\\n")+s; } } - //QCString actualArg; - //ClassDef *acd=0; - //printf("-------- usage relation %s->%s templ=`%s'\n", - // cd->name().data(),ucd->classDef->name().data(), - // ucd->templSpecifiers.data()); - //QCString templSpec = substituteTemplateSpec( - // cd,ucd->templSpecifiers); - //computeTemplateInstance(cd,ucd->classDef, templSpec, acd,actualArg); - //if (acd) - //{ - // addClass(acd,n,EdgeInfo::Black,label,distance,actualArg, - // templSpec,base); - //} - //else - //{ - // //printf("Found label=`%s'\n",label.data()); - // addClass(ucd->classDef,n,EdgeInfo::Black,label,distance,0, - // templSpec,base); - //} - addClass(ucd->classDef,n,EdgeInfo::Black,label,distance,0, + addClass(ucd->classDef,n,EdgeInfo::Purple,label,distance,0, ucd->templSpecifiers,base); } } } + + // ---- Add template instantiation relations + + if (Config_getBool("TEMPLATE_RELATIONS")) + { + if (base) // template relations for base classes + { + ClassDef *templMaster=cd->templateMaster(); + if (templMaster) + { + QDictIterator<ClassDef> cli(*templMaster->getTemplateInstances()); + ClassDef *templInstance; + for (;(templInstance=cli.current());++cli) + { + if (templInstance==cd) + { + addClass(templMaster,n,EdgeInfo::Orange,cli.currentKey(),distance,0, + 0,TRUE); + } + } + } + } + else // template relations for super classes + { + QDict<ClassDef> *templInstances = cd->getTemplateInstances(); + if (templInstances) + { + QDictIterator<ClassDef> cli(*templInstances); + ClassDef *templInstance; + for (;(templInstance=cli.current());++cli) + { + addClass(templInstance,n,EdgeInfo::Orange,cli.currentKey(),distance,0, + 0,FALSE); + } + } + } + } } DotClassGraph::DotClassGraph(ClassDef *cd,GraphType t,int maxRecursionDepth) |