umbrello API Documentation

cpptree2uml.cpp

00001 /***************************************************************************
00002  *   Based on kdevelop-3.0 languages/cpp/store_walker.cpp by Roberto Raggi *
00003  *                                                                         *
00004  *   This program is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU General Public License as published by  *
00006  *   the Free Software Foundation; either version 2 of the License, or     *
00007  *   (at your option) any later version.                                   *
00008  *                                                                         *
00009  *   copyright (C) 2004-2007                                               *
00010  *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
00011  ***************************************************************************/
00012 
00013 // own header
00014 #include "cpptree2uml.h"
00015 // qt/kde includes
00016 #include <qfileinfo.h>
00017 #include <qdir.h>
00018 #include <qregexp.h>
00019 #include <kdebug.h>
00020 // app includes
00021 #include "ast_utils.h"
00022 #include "urlutil.h"
00023 #include "../import_utils.h"
00024 // FIXME: The sole reason for the next 2 includes is parseTypedef().
00025 // Make capsule methods in ClassImport, and remove these includes.
00026 #include "../../classifier.h"
00027 // FIXME The next include is motivated by template params
00028 #include "../../template.h"
00029 
00030 CppTree2Uml::CppTree2Uml( const QString& fileName)
00031     : m_anon( 0 ), m_nsCnt( 0 ), m_clsCnt( 0 )
00032 {
00033     m_fileName = URLUtil::canonicalPath(fileName);
00034 }
00035 
00036 CppTree2Uml::~CppTree2Uml()
00037 {
00038 }
00039 
00040 void CppTree2Uml::parseTranslationUnit( TranslationUnitAST* ast )
00041 {
00042     m_currentScope.clear();
00043     m_currentNamespace[0] = NULL;  // index 0 is reserved (always NULL)
00044     m_currentClass[0] = NULL;  // index 0 is reserved (always NULL)
00045     m_nsCnt = 0;
00046     m_clsCnt = 0;
00047 
00048     m_currentAccess = Uml::Visibility::Public;
00049     m_inSlots = false;
00050     m_inSignals = false;
00051     m_inStorageSpec = false;
00052     m_inTypedef = false;
00053     m_currentDeclarator = 0;
00054     m_anon = 0;
00055 
00056     TreeParser::parseTranslationUnit( ast );
00057 }
00058 
00059 void CppTree2Uml::parseNamespace( NamespaceAST* ast )
00060 {
00061     if (m_clsCnt > 0) {
00062         kdDebug() << "CppTree2Uml::parseNamespace: error - cannot nest namespace inside class"
00063                   << endl;
00064         return;
00065     }
00066 
00067     QString nsName;
00068     if( !ast->namespaceName() || ast->namespaceName()->text().isEmpty() ){
00069         QFileInfo fileInfo( m_fileName );
00070         QString shortFileName = fileInfo.baseName();
00071 
00072         nsName.sprintf( "(%s_%d)", shortFileName.local8Bit().data(), m_anon++ );
00073     } else {
00074         nsName = ast->namespaceName()->text();
00075     }
00076 
00077 #ifdef DEBUG_CPPTREE2UML
00078     kdDebug() << "CppTree2Uml::parseNamespace: " << nsName << endl;
00079 #endif
00080     UMLObject * o = Import_Utils::createUMLObject( Uml::ot_Package, nsName,
00081                                                  m_currentNamespace[m_nsCnt],
00082                                                  ast->comment());
00083     UMLPackage *ns = (UMLPackage *)o;
00084     m_currentScope.push_back( nsName );
00085     if (++m_nsCnt > STACKSIZE) {
00086         kdError() << "CppTree2Uml::parseNamespace: excessive namespace nesting" << endl;
00087         m_nsCnt = STACKSIZE;
00088     }
00089     m_currentNamespace[m_nsCnt] = ns;
00090 
00091     TreeParser::parseNamespace( ast );
00092 
00093     --m_nsCnt;
00094     m_currentScope.pop_back();
00095 }
00096 
00097 void CppTree2Uml::parseTypedef( TypedefAST* ast )
00098 {
00099 #if 0
00100     DeclaratorAST* oldDeclarator = m_currentDeclarator;
00101 
00102     if( ast && ast->initDeclaratorList() && ast->initDeclaratorList()->initDeclaratorList().count() > 0 ) {
00103             QPtrList<InitDeclaratorAST> lst( ast->initDeclaratorList()->initDeclaratorList() );
00104             m_currentDeclarator = lst.at( 0 )->declarator();
00105     }
00106 
00107     m_inTypedef = true;
00108 
00109     TreeParser::parseTypedef( ast );
00110 
00111     m_inTypedef = false;
00112     m_currentDeclarator = oldDeclarator;
00113 #else
00114     TypeSpecifierAST* typeSpec = ast->typeSpec();
00115     InitDeclaratorListAST* declarators = ast->initDeclaratorList();
00116 
00117     if( typeSpec && declarators ){
00118         QString typeId;
00119 
00120         if( typeSpec->name() )
00121             typeId = typeSpec->name()->text();
00122 
00123         QPtrList<InitDeclaratorAST> l( declarators->initDeclaratorList() );
00124         QPtrListIterator<InitDeclaratorAST> it( l );
00125 
00126         InitDeclaratorAST* initDecl = 0;
00127         while( 0 != (initDecl = it.current()) ){
00128 
00129             QString type, id;
00130             if( initDecl->declarator() ){
00131                type = typeOfDeclaration( typeSpec, initDecl->declarator() );
00132 
00133                DeclaratorAST* d = initDecl->declarator();
00134                while( d->subDeclarator() ){
00135                    d = d->subDeclarator();
00136                }
00137 
00138                if( d->declaratorId() )
00139                   id = d->declaratorId()->text();
00140             }
00141 //#ifdef DEBUG_CPPTREE2UML
00142             kdDebug() << "CppTree2Uml::parseTypedef: name=" << id << ", type=" << type << endl;
00143 //#endif
00144             /* @todo Trace typedefs back to their root type for deciding
00145                      whether to build a Datatype (for pointers.)  */
00146             /* check out if the ID type is a Datatype
00147                ex: typedef unsigned int uint;
00148                where unsigned int is a known datatype
00149                I'm not sure if setIsReference() should be run
00150              */
00151             bool isDatatype = Import_Utils::isDatatype(typeId, m_currentNamespace[m_nsCnt]);
00152 
00153             if (type.contains('*') || isDatatype) {
00154                 UMLObject *inner =
00155                 Import_Utils::createUMLObject( Uml::ot_Class, typeId,
00156                                              m_currentNamespace[m_nsCnt] );
00157                 UMLObject *typedefObj =
00158                 Import_Utils::createUMLObject( Uml::ot_Datatype, id,
00159                                              m_currentNamespace[m_nsCnt] );
00160                 UMLClassifier *dt = static_cast<UMLClassifier*>(typedefObj);
00161                 dt->setIsReference();
00162                 dt->setOriginType(static_cast<UMLClassifier*>(inner));
00163             } else {
00164                 Import_Utils::createUMLObject( Uml::ot_Class, id,
00165                                              m_currentNamespace[m_nsCnt],
00166                                              "" /* doc */,
00167                                              "typedef" /* stereotype */);
00168             }
00169             ++it;
00170         }
00171 
00172     }
00173 #endif
00174 }
00175 
00176 void CppTree2Uml::parseTemplateDeclaration( TemplateDeclarationAST* ast )
00177 {
00178     TemplateParameterListAST* parmListAST = ast->templateParameterList();
00179     if (parmListAST == NULL)
00180         return;
00181     QPtrList<TemplateParameterAST> parmList = parmListAST->templateParameterList();
00182     for (QPtrListIterator<TemplateParameterAST> it(parmList); it.current(); ++it) {
00183         // The template is either a typeParameter or a typeValueParameter.
00184 
00185         TemplateParameterAST* tmplParmNode = it.current();
00186         TypeParameterAST* typeParmNode = tmplParmNode->typeParameter();
00187         if (typeParmNode) {
00188             NameAST* nameNode = typeParmNode->name();
00189             if (nameNode) {
00190                 QString typeName = nameNode->unqualifiedName()->text();
00191                 Model_Utils::NameAndType nt(typeName, NULL);
00192                 m_templateParams.append(nt);
00193             } else {
00194                 kdError() << "CppTree2Uml::parseTemplateDeclaration(type):"
00195                           << " nameNode is NULL" << endl;
00196             }
00197         }
00198 
00199         ParameterDeclarationAST* valueNode = tmplParmNode->typeValueParameter();
00200         if (valueNode) {
00201             TypeSpecifierAST* typeSpec = valueNode->typeSpec();
00202             if (typeSpec == NULL) {
00203                 kdError() << "CppTree2Uml::parseTemplateDeclaration(value):"
00204                           << " typeSpec is NULL" << endl;
00205                 continue;
00206             }
00207             QString typeName = typeSpec->name()->text();
00208             UMLObject *t = Import_Utils::createUMLObject( Uml::ot_UMLObject, typeName,
00209                                                         m_currentNamespace[m_nsCnt] );
00210             DeclaratorAST* declNode = valueNode->declarator();
00211             NameAST* nameNode = declNode->declaratorId();
00212             if (nameNode == NULL) {
00213                 kdError() << "CppTree2Uml::parseTemplateDeclaration(value):"
00214                           << " nameNode is NULL" << endl;
00215                 continue;
00216             }
00217             QString paramName = nameNode->unqualifiedName()->text();
00218             Model_Utils::NameAndType nt(paramName, t);
00219             m_templateParams.append(nt);
00220         }
00221     }
00222 
00223     if( ast->declaration() )
00224         TreeParser::parseDeclaration( ast->declaration() );
00225 }
00226 
00227 void CppTree2Uml::parseSimpleDeclaration( SimpleDeclarationAST* ast )
00228 {
00229     TypeSpecifierAST* typeSpec = ast->typeSpec();
00230     InitDeclaratorListAST* declarators = ast->initDeclaratorList();
00231 
00232     m_comment = ast->comment();
00233 
00234     if( typeSpec )
00235         parseTypeSpecifier( typeSpec );
00236 
00237     if( declarators ){
00238         QPtrList<InitDeclaratorAST> l = declarators->initDeclaratorList();
00239 
00240         QPtrListIterator<InitDeclaratorAST> it( l );
00241         while( it.current() ){
00242             parseDeclaration(  ast->functionSpecifier(), ast->storageSpecifier(), typeSpec, it.current() );
00243             ++it;
00244         }
00245     }
00246 }
00247 
00248 void CppTree2Uml::parseFunctionDefinition( FunctionDefinitionAST* ast )
00249 {
00250     TypeSpecifierAST* typeSpec = ast->typeSpec();
00251     GroupAST* funSpec = ast->functionSpecifier();
00252     GroupAST* storageSpec = ast->storageSpecifier();
00253 
00254     if( !ast->initDeclarator() )
00255         return;
00256 
00257     DeclaratorAST* d = ast->initDeclarator()->declarator();
00258 
00259     if( !d->declaratorId() )
00260         return;
00261 
00262     bool isFriend = false;
00263     bool isVirtual = false;
00264     bool isStatic = false;
00265     bool isInline = false;
00266     bool isConstructor = false;
00267 
00268     if( funSpec ){
00269         QPtrList<AST> l = funSpec->nodeList();
00270         QPtrListIterator<AST> it( l );
00271         while( it.current() ){
00272             QString text = it.current()->text();
00273             if( text == "virtual" ) isVirtual = true;
00274             else if( text == "inline" ) isInline = true;
00275             ++it;
00276         }
00277     }
00278 
00279     if( storageSpec ){
00280         QPtrList<AST> l = storageSpec->nodeList();
00281         QPtrListIterator<AST> it( l );
00282         while( it.current() ){
00283             QString text = it.current()->text();
00284             if( text == "friend" ) isFriend = true;
00285             else if( text == "static" ) isStatic = true;
00286             ++it;
00287         }
00288     }
00289 
00290     QString id = d->declaratorId()->unqualifiedName()->text().stripWhiteSpace();
00291 
00292     UMLClassifier *c = m_currentClass[m_clsCnt];
00293     if (c == NULL) {
00294         kdDebug() << "CppTree2Uml::parseFunctionDefinition (" << id
00295                   << "): need a surrounding class." << endl;
00296         return;
00297     }
00298 
00299     QString returnType = typeOfDeclaration( typeSpec, d );
00300     UMLOperation *m = Import_Utils::makeOperation(c, id);
00301     // if a class has no return type, it could be a constructor or
00302     // a destructor
00303     if (d && returnType.isEmpty() && id.find("~") == -1)
00304         isConstructor = true;
00305 
00306     parseFunctionArguments( d, m );
00307     Import_Utils::insertMethod( c, m, m_currentAccess, returnType,
00308                               isStatic, false /*isAbstract*/, isFriend, isConstructor, m_comment);
00309     m_comment = "";
00310 
00311 /* For reference, Kdevelop does some more:
00312     method->setFileName( m_fileName );
00313     if( m_inSignals )
00314         method->setSignal( true );
00315     if( m_inSlots )
00316         method->setSlot( true );
00317  */
00318 }
00319 
00320 void CppTree2Uml::parseClassSpecifier( ClassSpecifierAST* ast )
00321 {
00322     Uml::Visibility oldAccess = m_currentAccess;
00323     bool oldInSlots = m_inSlots;
00324     bool oldInSignals = m_inSignals;
00325 
00326     QString kind = ast->classKey()->text();
00327     m_currentAccess=Uml::Visibility::fromString(kind);
00328     m_inSlots = false;
00329     m_inSignals = false;
00330 
00331     QString className;
00332     if( !ast->name() && m_currentDeclarator && m_currentDeclarator->declaratorId() ) {
00333         className = m_currentDeclarator->declaratorId()->text().stripWhiteSpace();
00334     } else if( !ast->name() ){
00335         QFileInfo fileInfo( m_fileName );
00336         QString shortFileName = fileInfo.baseName();
00337         className.sprintf( "(%s_%d)", shortFileName.local8Bit().data(), m_anon++ );
00338     } else {
00339         className = ast->name()->unqualifiedName()->text().stripWhiteSpace();
00340     }
00341 //#ifdef DEBUG_CPPTREE2UML
00342     kdDebug() << "CppTree2Uml::parseClassSpecifier: name=" << className << endl;
00343 //#endif
00344     if( !scopeOfName( ast->name(), QStringList() ).isEmpty() ){
00345         kdDebug() << "skip private class declarations" << endl;
00346         return;
00347     }
00348 
00349     if (className.isEmpty()) {
00350         className = "anon_" + QString::number(m_anon);
00351         m_anon++;
00352     }
00353     UMLObject * o = Import_Utils::createUMLObject( Uml::ot_Class, className,
00354                                                  m_currentNamespace[m_nsCnt],
00355                                                  ast->comment() );
00356     UMLClassifier *klass = static_cast<UMLClassifier*>(o);
00357     flushTemplateParams(klass);
00358     if ( ast->baseClause() )
00359         parseBaseClause( ast->baseClause(), klass );
00360 
00361     m_currentScope.push_back( className );
00362     if (++m_clsCnt > STACKSIZE) {
00363         kdError() << "CppTree2Uml::parseNamespace: excessive class nesting" << endl;
00364         m_clsCnt = STACKSIZE;
00365     }
00366     m_currentClass[m_clsCnt] = klass;
00367     if (++m_nsCnt > STACKSIZE) {
00368         kdError() << "CppTree2Uml::parseNamespace: excessive namespace nesting" << endl;
00369         m_nsCnt = STACKSIZE;
00370     }
00371     m_currentNamespace[m_nsCnt] = (UMLPackage*)klass;
00372 
00373     TreeParser::parseClassSpecifier( ast );
00374 
00375     --m_nsCnt;
00376     --m_clsCnt;
00377 
00378     m_currentScope.pop_back();
00379 
00380     m_currentAccess = oldAccess;
00381     m_inSlots = oldInSlots;
00382     m_inSignals = oldInSignals;
00383 }
00384 
00385 void CppTree2Uml::parseEnumSpecifier( EnumSpecifierAST* ast )
00386 {
00387     NameAST *nameNode = ast->name();
00388     if (nameNode == NULL)
00389         return;  // skip constants
00390     QString typeName = nameNode->unqualifiedName()->text().stripWhiteSpace();
00391     if (typeName.isEmpty())
00392         return;  // skip constants
00393     UMLObject *o = Import_Utils::createUMLObject( Uml::ot_Enum, typeName,
00394                                                 m_currentNamespace[m_nsCnt],
00395                                                 ast->comment() );
00396 
00397     QPtrList<EnumeratorAST> l = ast->enumeratorList();
00398     QPtrListIterator<EnumeratorAST> it( l );
00399     while ( it.current() ) {
00400         QString enumLiteral = it.current()->id()->text();
00401         Import_Utils::addEnumLiteral( (UMLEnum*)o, enumLiteral );
00402         ++it;
00403     }
00404 }
00405 
00406 void CppTree2Uml::parseElaboratedTypeSpecifier( ElaboratedTypeSpecifierAST* typeSpec )
00407 {
00408     // This is invoked for forward declarations.
00412     QString text = typeSpec->text();
00413     kdDebug() << "CppTree2Uml::parseElaboratedTypeSpecifier: text is " << text << endl;
00414     text.remove(QRegExp("^class\\s+"));
00415     UMLObject *o = Import_Utils::createUMLObject(Uml::ot_Class, text, m_currentNamespace[m_nsCnt]);
00416     flushTemplateParams( static_cast<UMLClassifier*>(o) );
00417 }
00418 
00419 void CppTree2Uml::parseDeclaration( GroupAST* funSpec, GroupAST* storageSpec,
00420                                     TypeSpecifierAST* typeSpec, InitDeclaratorAST* decl )
00421 {
00422     if( m_inStorageSpec )
00423             return;
00424 
00425     DeclaratorAST* d = decl->declarator();
00426 
00427     if( !d )
00428         return;
00429 
00430     if( !d->subDeclarator() && d->parameterDeclarationClause() )
00431         return parseFunctionDeclaration( funSpec, storageSpec, typeSpec, decl );
00432 
00433     DeclaratorAST* t = d;
00434     while( t && t->subDeclarator() )
00435         t = t->subDeclarator();
00436 
00437     QString id;
00438     if( t && t->declaratorId() && t->declaratorId()->unqualifiedName() )
00439         id = t->declaratorId()->unqualifiedName()->text();
00440 
00441     if( !scopeOfDeclarator(d, QStringList()).isEmpty() ){
00442         kdDebug() << "CppTree2Uml::parseDeclaration (" << id << "): skipping."
00443                   << endl;
00444         return;
00445     }
00446 
00447     UMLClassifier *c = m_currentClass[m_clsCnt];
00448     if (c == NULL) {
00449         kdDebug() << "CppTree2Uml::parseDeclaration (" << id
00450                   << "): need a surrounding class." << endl;
00451         return;
00452     }
00453 
00454     QString typeName = typeOfDeclaration( typeSpec, d );
00455     bool isFriend = false;
00456     bool isStatic = false;
00457     //bool isInitialized = decl->initializer() != 0;
00458 
00459     if( storageSpec ){
00460         QPtrList<AST> l = storageSpec->nodeList();
00461         QPtrListIterator<AST> it( l );
00462         while( it.current() ){
00463             QString text = it.current()->text();
00464             if( text == "friend" ) isFriend = true;
00465             else if( text == "static" ) isStatic = true;
00466             ++it;
00467         }
00468     }
00469 
00470     Import_Utils::insertAttribute( c, m_currentAccess, id, typeName,
00471                                  m_comment, isStatic);
00472     m_comment = "";
00473 }
00474 
00475 void CppTree2Uml::parseAccessDeclaration( AccessDeclarationAST * access )
00476 {
00477     QPtrList<AST> l = access->accessList();
00478 
00479     QString accessStr = l.at( 0 )->text();
00480 
00481     m_currentAccess=Uml::Visibility::fromString(accessStr);
00482 
00483     m_inSlots = l.count() > 1 ? l.at( 1 )->text() == "slots" : false;
00484     m_inSignals = l.count() >= 1 ? l.at( 0 )->text() == "signals" : false;
00485 }
00486 
00487 void CppTree2Uml::parseFunctionDeclaration(  GroupAST* funSpec, GroupAST* storageSpec,
00488                                              TypeSpecifierAST * typeSpec, InitDeclaratorAST * decl )
00489 {
00490     bool isFriend = false;
00491     bool isVirtual = false;
00492     bool isStatic = false;
00493     bool isInline = false;
00494     bool isPure = decl->initializer() != 0;
00495     bool isConstructor = false;
00496 
00497     if( funSpec ){
00498         QPtrList<AST> l = funSpec->nodeList();
00499         QPtrListIterator<AST> it( l );
00500         while( it.current() ){
00501             QString text = it.current()->text();
00502             if( text == "virtual" ) isVirtual = true;
00503             else if( text == "inline" ) isInline = true;
00504             ++it;
00505         }
00506     }
00507 
00508     if( storageSpec ){
00509         QPtrList<AST> l = storageSpec->nodeList();
00510         QPtrListIterator<AST> it( l );
00511         while( it.current() ){
00512             QString text = it.current()->text();
00513             if( text == "friend" ) isFriend = true;
00514             else if( text == "static" ) isStatic = true;
00515             ++it;
00516         }
00517     }
00518 
00519     DeclaratorAST* d = decl->declarator();
00520     QString id = d->declaratorId()->unqualifiedName()->text();
00521 
00522     UMLClassifier *c = m_currentClass[m_clsCnt];
00523     if (c == NULL) {
00524         kdDebug() << "CppTree2Uml::parseFunctionDeclaration (" << id
00525                   << "): need a surrounding class." << endl;
00526         return;
00527     }
00528 
00529     QString returnType = typeOfDeclaration( typeSpec, d );
00530     UMLOperation *m = Import_Utils::makeOperation(c, id);
00531     // if a class has no return type, it could be a constructor or
00532     // a destructor
00533     if (d && returnType.isEmpty() && id.find("~") == -1)
00534         isConstructor = true;
00535 
00536     parseFunctionArguments( d, m );
00537     Import_Utils::insertMethod( c, m, m_currentAccess, returnType,
00538                               isStatic, isPure, isFriend, isConstructor, m_comment);
00539     m_comment = "";
00540 }
00541 
00542 void CppTree2Uml::parseFunctionArguments(DeclaratorAST* declarator,
00543                                          UMLOperation* method)
00544 {
00545     ParameterDeclarationClauseAST* clause = declarator->parameterDeclarationClause();
00546 
00547     if( clause && clause->parameterDeclarationList() ){
00548         ParameterDeclarationListAST* params = clause->parameterDeclarationList();
00549         QPtrList<ParameterDeclarationAST> l( params->parameterList() );
00550         QPtrListIterator<ParameterDeclarationAST> it( l );
00551         while( it.current() ){
00552             ParameterDeclarationAST* param = it.current();
00553             ++it;
00554 
00555             QString name;
00556             if (param->declarator())
00557                 name = declaratorToString(param->declarator(), QString::null, true );
00558 
00559             QString tp = typeOfDeclaration( param->typeSpec(), param->declarator() );
00560 
00561             if (tp != "void")
00562                 Import_Utils::addMethodParameter( method, tp, name );
00563         }
00564     }
00565 }
00566 
00567 QString CppTree2Uml::typeOfDeclaration( TypeSpecifierAST* typeSpec, DeclaratorAST* declarator )
00568 {
00569     if( !typeSpec || !declarator )
00570         return QString::null;
00571 
00572     QString text;
00573 
00574     text += typeSpec->text();
00575 
00576     QPtrList<AST> ptrOpList = declarator->ptrOpList();
00577     for( QPtrListIterator<AST> it(ptrOpList); it.current(); ++it ){
00578         text += it.current()->text();
00579     }
00580 
00581     return text;
00582 }
00583 
00584 void CppTree2Uml::parseBaseClause( BaseClauseAST * baseClause, UMLClassifier* klass )
00585 {
00586     QPtrList<BaseSpecifierAST> l = baseClause->baseSpecifierList();
00587     QPtrListIterator<BaseSpecifierAST> it( l );
00588     while( it.current() ){
00589         BaseSpecifierAST* baseSpecifier = it.current();
00590         ++it;
00591 
00592         if (baseSpecifier->name() == NULL) {
00593                 kdDebug() << "CppTree2Uml::parseBaseClause: baseSpecifier->name() is NULL"
00594                           << endl;
00595                 continue;
00596         }
00597 
00598         QString baseName = baseSpecifier->name()->text();
00599         Import_Utils::createGeneralization( klass, baseName );
00600     }
00601 }
00602 
00603 QStringList CppTree2Uml::scopeOfName( NameAST* id, const QStringList& startScope )
00604 {
00605     QStringList scope = startScope;
00606     if( id && id->classOrNamespaceNameList().count() ){
00607         if( id->isGlobal() )
00608             scope.clear();
00609         QPtrList<ClassOrNamespaceNameAST> l = id->classOrNamespaceNameList();
00610         QPtrListIterator<ClassOrNamespaceNameAST> it( l );
00611         while( it.current() ){
00612             if( it.current()->name() ){
00613                scope << it.current()->name()->text();
00614             }
00615             ++it;
00616         }
00617     }
00618 
00619     return scope;
00620 }
00621 
00622 QStringList CppTree2Uml::scopeOfDeclarator( DeclaratorAST* d, const QStringList& startScope )
00623 {
00624     return scopeOfName( d->declaratorId(), startScope );
00625 }
00626 
00627 void CppTree2Uml::flushTemplateParams(UMLClassifier *klass) {
00628     if (m_templateParams.count()) {
00629         Model_Utils::NameAndType_ListIt it;
00630         for (it = m_templateParams.begin(); it != m_templateParams.end(); ++it) {
00631             const Model_Utils::NameAndType &nt = *it;
00632             kdDebug() << "CppTree2Uml::parseClassSpecifier: adding template param: "
00633                       << nt.m_name << endl;
00634             UMLTemplate *tmpl = klass->addTemplate(nt.m_name);
00635             tmpl->setType(nt.m_type);
00636         }
00637         m_templateParams.clear();
00638     }
00639 }
00640 
KDE Logo
This file is part of the documentation for umbrello Version 3.1.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 26 08:07:56 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003