00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "store_walker.h"
00013 #include "ast_utils.h"
00014 #include "urlutil.h"
00015
00016 #include <kdebug.h>
00017 #include <qfileinfo.h>
00018 #include <qdir.h>
00019
00020 StoreWalker::StoreWalker( const QString& fileName, CodeModel* store )
00021 : m_store( store ), m_anon( 0 )
00022 {
00023 m_fileName = URLUtil::canonicalPath(fileName);
00024
00025
00026 }
00027
00028 StoreWalker::~StoreWalker()
00029 {
00030 }
00031
00032 void StoreWalker::parseTranslationUnit( TranslationUnitAST* ast )
00033 {
00034 m_file = m_store->create<FileModel>();
00035 m_file->setName( m_fileName );
00036
00037 m_currentScope.clear();
00038 m_currentNamespace.clear();
00039 m_currentClass.clear();
00040
00041 m_currentAccess = CodeModelItem::Public;
00042 m_inSlots = false;
00043 m_inSignals = false;
00044 m_inStorageSpec = false;
00045 m_inTypedef = false;
00046 m_currentDeclarator = 0;
00047 m_anon = 0;
00048 m_imports.clear();
00049
00050 m_imports << QStringList();
00051 TreeParser::parseTranslationUnit( ast );
00052 m_imports.pop_back();
00053 }
00054
00055 void StoreWalker::parseDeclaration( DeclarationAST* ast )
00056 {
00057 TreeParser::parseDeclaration( ast );
00058 }
00059
00060 void StoreWalker::parseLinkageSpecification( LinkageSpecificationAST* ast )
00061 {
00062 int inStorageSpec = m_inStorageSpec;
00063 m_inStorageSpec = true;
00064 TreeParser::parseLinkageSpecification( ast );
00065 m_inStorageSpec = inStorageSpec;
00066 }
00067
00068 void StoreWalker::parseNamespace( NamespaceAST* ast )
00069 {
00070 if( !m_currentClass.isEmpty() ){
00071 kdDebug(9007) << "!!!!!!!!!!!!!!!!!!!!!!!!!! **error** !!!!!!!!!!!!!!!!!!!!" << endl;
00072 return;
00073 }
00074
00075 QString nsName;
00076 if( !ast->namespaceName() || ast->namespaceName()->text().isEmpty() ){
00077 QFileInfo fileInfo( m_fileName );
00078 QString shortFileName = fileInfo.baseName();
00079
00080 nsName.sprintf( "(%s_%d)", shortFileName.local8Bit().data(), m_anon++ );
00081 } else {
00082 nsName = ast->namespaceName()->text();
00083 }
00084
00085 NamespaceDom ns = findOrInsertNamespace( ast, nsName );
00086
00087 m_currentScope.push_back( nsName );
00088 m_currentNamespace.push( ns );
00089
00090 TreeParser::parseNamespace( ast );
00091
00092 m_currentNamespace.pop();
00093 m_currentScope.pop_back();
00094 }
00095
00096 void StoreWalker::parseNamespaceAlias( NamespaceAliasAST* ast )
00097 {
00098 TreeParser::parseNamespaceAlias( ast );
00099 }
00100
00101 void StoreWalker::parseUsing( UsingAST* ast )
00102 {
00103 TreeParser::parseUsing( ast );
00104 }
00105
00106 void StoreWalker::parseUsingDirective( UsingDirectiveAST* ast )
00107 {
00108 QString name = ast->name()->unqualifiedName()->text();
00109 m_imports.back().push_back( name );
00110 }
00111
00112 void StoreWalker::parseTypedef( TypedefAST* ast )
00113 {
00114 #if 0
00115 DeclaratorAST* oldDeclarator = m_currentDeclarator;
00116
00117 if( ast && ast->initDeclaratorList() && ast->initDeclaratorList()->initDeclaratorList().count() > 0 ) {
00118 QPtrList<InitDeclaratorAST> lst( ast->initDeclaratorList()->initDeclaratorList() );
00119 m_currentDeclarator = lst.at( 0 )->declarator();
00120 }
00121
00122 m_inTypedef = true;
00123
00124 TreeParser::parseTypedef( ast );
00125
00126 m_inTypedef = false;
00127 m_currentDeclarator = oldDeclarator;
00128 #else
00129 TypeSpecifierAST* typeSpec = ast->typeSpec();
00130 InitDeclaratorListAST* declarators = ast->initDeclaratorList();
00131
00132 if( typeSpec && declarators ){
00133 QString typeId;
00134
00135 if( typeSpec->name() )
00136 typeId = typeSpec->name()->text();
00137
00138 QPtrList<InitDeclaratorAST> l( declarators->initDeclaratorList() );
00139 QPtrListIterator<InitDeclaratorAST> it( l );
00140
00141 InitDeclaratorAST* initDecl = 0;
00142 while( 0 != (initDecl = it.current()) ){
00143
00144 QString type, id;
00145 if( initDecl->declarator() ){
00146 type = typeOfDeclaration( typeSpec, initDecl->declarator() );
00147
00148 DeclaratorAST* d = initDecl->declarator();
00149 while( d->subDeclarator() ){
00150 d = d->subDeclarator();
00151 }
00152
00153 if( d->declaratorId() )
00154 id = d->declaratorId()->text();
00155 }
00156
00157 TypeAliasDom typeAlias = m_store->create<TypeAliasModel>();
00158 typeAlias->setFileName( m_fileName );
00159 typeAlias->setName( id );
00160 typeAlias->setType( type );
00161
00162 int line, col;
00163 initDecl->getStartPosition( &line, &col );
00164 typeAlias->setStartPosition( line, col );
00165
00166 initDecl->getEndPosition( &line, &col );
00167 typeAlias->setEndPosition( line, col );
00168
00169 if( m_currentClass.top() )
00170 m_currentClass.top()->addTypeAlias( typeAlias );
00171 else if( m_currentNamespace.top() )
00172 m_currentNamespace.top()->addTypeAlias( typeAlias );
00173 else
00174 m_file->addTypeAlias( typeAlias );
00175
00176 #if 0
00177 Tag tag;
00178 tag.setKind( Tag::Kind_Typedef );
00179 tag.setFileName( m_fileName );
00180 tag.setName( id );
00181 tag.setScope( m_currentScope );
00182 tag.setAttribute( "t", type );
00183 int line, col;
00184 initDecl->getStartPosition( &line, &col );
00185
00186 tag.setStartPosition( line, col );
00187
00188 initDecl->getEndPosition( &line, &col );
00189 tag.setEndPosition( line, col );
00190
00191 m_catalog->addItem( tag );
00192 #endif
00193
00194 ++it;
00195 }
00196
00197 }
00198 #endif
00199 }
00200
00201 void StoreWalker::parseTemplateDeclaration( TemplateDeclarationAST* ast )
00202 {
00203 if( ast->declaration() )
00204 parseDeclaration( ast->declaration() );
00205
00206 TreeParser::parseTemplateDeclaration( ast );
00207 }
00208
00209 void StoreWalker::parseSimpleDeclaration( SimpleDeclarationAST* ast )
00210 {
00211 TypeSpecifierAST* typeSpec = ast->typeSpec();
00212 InitDeclaratorListAST* declarators = ast->initDeclaratorList();
00213
00214 if( typeSpec )
00215 parseTypeSpecifier( typeSpec );
00216
00217 if( declarators ){
00218 QPtrList<InitDeclaratorAST> l = declarators->initDeclaratorList();
00219
00220 QPtrListIterator<InitDeclaratorAST> it( l );
00221 while( it.current() ){
00222 parseDeclaration( ast->functionSpecifier(), ast->storageSpecifier(), typeSpec, it.current() );
00223 ++it;
00224 }
00225 }
00226 }
00227
00228 void StoreWalker::parseFunctionDefinition( FunctionDefinitionAST* ast )
00229 {
00230 TypeSpecifierAST* typeSpec = ast->typeSpec();
00231 GroupAST* funSpec = ast->functionSpecifier();
00232 GroupAST* storageSpec = ast->storageSpecifier();
00233
00234 if( !ast->initDeclarator() )
00235 return;
00236
00237 DeclaratorAST* d = ast->initDeclarator()->declarator();
00238
00239 if( !d->declaratorId() )
00240 return;
00241
00242 bool isFriend = false;
00243 bool isVirtual = false;
00244 bool isStatic = false;
00245 bool isInline = false;
00246
00247 if( funSpec ){
00248 QPtrList<AST> l = funSpec->nodeList();
00249 QPtrListIterator<AST> it( l );
00250 while( it.current() ){
00251 QString text = it.current()->text();
00252 if( text == "virtual" ) isVirtual = true;
00253 else if( text == "inline" ) isInline = true;
00254 ++it;
00255 }
00256 }
00257
00258 if( storageSpec ){
00259 QPtrList<AST> l = storageSpec->nodeList();
00260 QPtrListIterator<AST> it( l );
00261 while( it.current() ){
00262 QString text = it.current()->text();
00263 if( text == "friend" ) isFriend = true;
00264 else if( text == "static" ) isStatic = true;
00265 ++it;
00266 }
00267 }
00268
00269 int startLine, startColumn;
00270 int endLine, endColumn;
00271 ast->getStartPosition( &startLine, &startColumn );
00272 ast->getEndPosition( &endLine, &endColumn );
00273
00274 QString id = d->declaratorId()->unqualifiedName()->text().stripWhiteSpace();
00275
00276 QStringList scope = scopeOfDeclarator( d, m_currentScope );
00277
00278 FunctionDefinitionDom method = m_store->create<FunctionDefinitionModel>();
00279 method->setScope( scope );
00280 method->setName( id );
00281
00282 parseFunctionArguments( d, model_cast<FunctionDom>(method) );
00283
00284 QString text = typeOfDeclaration( typeSpec, d );
00285 if( !text.isEmpty() )
00286 method->setResultType( text );
00287
00288 method->setFileName( m_fileName );
00289 method->setStartPosition( startLine, startColumn );
00290 method->setEndPosition( endLine, endColumn );
00291
00292 if( m_inSignals )
00293 method->setSignal( true );
00294
00295 if( m_inSlots )
00296 method->setSlot( true );
00297
00298 if( m_currentClass.top() || (method->name() == "main" && scope.isEmpty()) ){
00299 method->setConstant( d->constant() != 0 );
00300 method->setAccess( m_currentAccess );
00301 method->setStatic( isStatic );
00302 method->setVirtual( isVirtual );
00303
00304 if( m_currentClass.top() )
00305 m_currentClass.top()->addFunction( model_cast<FunctionDom>(method) );
00306 else
00307 m_file->addFunction( model_cast<FunctionDom>(method) );
00308 }
00309
00310 if( m_currentClass.top() )
00311 m_currentClass.top()->addFunctionDefinition( method );
00312 else if( m_currentNamespace.top() )
00313 m_currentNamespace.top()->addFunctionDefinition( method );
00314 else
00315 m_file->addFunctionDefinition( method );
00316 }
00317
00318 void StoreWalker::parseLinkageBody( LinkageBodyAST* ast )
00319 {
00320 TreeParser::parseLinkageBody( ast );
00321 }
00322
00323 void StoreWalker::parseTypeSpecifier( TypeSpecifierAST* ast )
00324 {
00325 TreeParser::parseTypeSpecifier( ast );
00326 }
00327
00328 void StoreWalker::parseClassSpecifier( ClassSpecifierAST* ast )
00329 {
00330 int startLine, startColumn;
00331 int endLine, endColumn;
00332 ast->getStartPosition( &startLine, &startColumn );
00333 ast->getEndPosition( &endLine, &endColumn );
00334
00335 int oldAccess = m_currentAccess;
00336 bool oldInSlots = m_inSlots;
00337 bool oldInSignals = m_inSignals;
00338
00339 QString kind = ast->classKey()->text();
00340 if( kind == "class" )
00341 m_currentAccess = CodeModelItem::Private;
00342 else
00343 m_currentAccess = CodeModelItem::Public;
00344 m_inSlots = false;
00345 m_inSignals = false;
00346
00347 QString className;
00348 if( !ast->name() && m_currentDeclarator && m_currentDeclarator->declaratorId() ) {
00349 className = m_currentDeclarator->declaratorId()->text().stripWhiteSpace();
00350 } else if( !ast->name() ){
00351 QFileInfo fileInfo( m_fileName );
00352 QString shortFileName = fileInfo.baseName();
00353 className.sprintf( "(%s_%d)", shortFileName.local8Bit().data(), m_anon++ );
00354 } else {
00355 className = ast->name()->unqualifiedName()->text().stripWhiteSpace();
00356 }
00357
00358 if( !scopeOfName( ast->name(), QStringList() ).isEmpty() ){
00359 kdDebug(9007) << "skip private class declarations" << endl;
00360 return;
00361 }
00362
00363 ClassDom klass = m_store->create<ClassModel>();
00364 klass->setStartPosition( startLine, startColumn );
00365 klass->setEndPosition( endLine, endColumn );
00366 klass->setFileName( m_fileName );
00367
00368 klass->setName( className );
00369
00370 klass->setScope( m_currentScope );
00371
00372 if( m_currentClass.top() )
00373 m_currentClass.top()->addClass( klass );
00374 else if( m_currentNamespace.top() )
00375 m_currentNamespace.top()->addClass( klass );
00376 else
00377 m_file->addClass( klass );
00378
00379 if ( ast->baseClause() )
00380 parseBaseClause( ast->baseClause(), klass );
00381
00382 m_currentScope.push_back( className );
00383 m_currentClass.push( klass );
00384
00385 m_imports.push_back( QStringList() );
00386
00387 TreeParser::parseClassSpecifier( ast );
00388
00389 m_imports.pop_back();
00390 m_currentClass.pop();
00391
00392 m_currentScope.pop_back();
00393
00394 m_currentAccess = oldAccess;
00395 m_inSlots = oldInSlots;
00396 m_inSignals = oldInSignals;
00397 }
00398
00399 void StoreWalker::parseEnumSpecifier( EnumSpecifierAST* ast )
00400 {
00401 QPtrList<EnumeratorAST> l = ast->enumeratorList();
00402 QPtrListIterator<EnumeratorAST> it( l );
00403 while( it.current() ){
00404 VariableDom attr = m_store->create<VariableModel>();
00405 attr->setName( it.current()->id()->text() );
00406 attr->setFileName( m_fileName );
00407 attr->setAccess( m_currentAccess );
00408 attr->setType( "int" );
00409 attr->setStatic( true );
00410
00411 int startLine, startColumn;
00412 int endLine, endColumn;
00413 it.current()->getStartPosition( &startLine, &startColumn );
00414 attr->setStartPosition( startLine, startColumn );
00415
00416 it.current()->getEndPosition( &endLine, &endColumn );
00417 attr->setEndPosition( endLine, endColumn );
00418
00419 if( m_currentClass.top() )
00420 m_currentClass.top()->addVariable( attr );
00421 else if( m_currentNamespace.top() )
00422 m_currentNamespace.top()->addVariable( attr );
00423 else
00424 m_file->addVariable( attr );
00425
00426 ++it;
00427 }
00428 }
00429
00430 void StoreWalker::parseElaboratedTypeSpecifier( ElaboratedTypeSpecifierAST* ast )
00431 {
00432 TreeParser::parseElaboratedTypeSpecifier( ast );
00433 }
00434
00435 void StoreWalker::parseTypeDeclaratation( TypeSpecifierAST* typeSpec )
00436 {
00437 parseTypeSpecifier( typeSpec );
00438 }
00439
00440 void StoreWalker::parseDeclaration( GroupAST* funSpec, GroupAST* storageSpec, TypeSpecifierAST* typeSpec, InitDeclaratorAST* decl )
00441 {
00442 if( m_inStorageSpec )
00443 return;
00444
00445 DeclaratorAST* d = decl->declarator();
00446
00447 if( !d )
00448 return;
00449
00450 if( !d->subDeclarator() && d->parameterDeclarationClause() )
00451 return parseFunctionDeclaration( funSpec, storageSpec, typeSpec, decl );
00452
00453 DeclaratorAST* t = d;
00454 while( t && t->subDeclarator() )
00455 t = t->subDeclarator();
00456
00457 QString id;
00458 if( t && t->declaratorId() && t->declaratorId()->unqualifiedName() )
00459 id = t->declaratorId()->unqualifiedName()->text();
00460
00461 if( !scopeOfDeclarator(d, QStringList()).isEmpty() ){
00462 kdDebug(9007) << "skip declaration" << endl;
00463 return;
00464 }
00465
00466 VariableDom attr = m_store->create<VariableModel>();
00467 attr->setName( id );
00468 attr->setFileName( m_fileName );
00469
00470 if( m_currentClass.top() )
00471 m_currentClass.top()->addVariable( attr );
00472 else if( m_currentNamespace.top() )
00473 m_currentNamespace.top()->addVariable( attr );
00474 else
00475 m_file->addVariable( attr );
00476
00477 attr->setAccess( m_currentAccess );
00478
00479 QString text = typeOfDeclaration( typeSpec, d );
00480 if( !text.isEmpty() )
00481 attr->setType( text );
00482
00483 bool isFriend = false;
00484
00485 bool isStatic = false;
00486
00487
00488
00489 if( storageSpec ){
00490 QPtrList<AST> l = storageSpec->nodeList();
00491 QPtrListIterator<AST> it( l );
00492 while( it.current() ){
00493 QString text = it.current()->text();
00494 if( text == "friend" ) isFriend = true;
00495 else if( text == "static" ) isStatic = true;
00496 ++it;
00497 }
00498 }
00499
00500 int startLine, startColumn;
00501 int endLine, endColumn;
00502 decl->getStartPosition( &startLine, &startColumn );
00503 decl->getEndPosition( &endLine, &endColumn );
00504
00505 attr->setStartPosition( startLine, startColumn );
00506 attr->setEndPosition( endLine, endColumn );
00507 attr->setStatic( isStatic );
00508 }
00509
00510 void StoreWalker::parseAccessDeclaration( AccessDeclarationAST * access )
00511 {
00512 QPtrList<AST> l = access->accessList();
00513
00514 QString accessStr = l.at( 0 )->text();
00515 if( accessStr == "public" )
00516 m_currentAccess = CodeModelItem::Public;
00517 else if( accessStr == "protected" )
00518 m_currentAccess = CodeModelItem::Protected;
00519 else if( accessStr == "private" )
00520 m_currentAccess = CodeModelItem::Private;
00521 else if( accessStr == "signals" )
00522 m_currentAccess = CodeModelItem::Protected;
00523 else
00524 m_currentAccess = CodeModelItem::Public;
00525
00526 m_inSlots = l.count() > 1 ? l.at( 1 )->text() == "slots" : false;
00527 m_inSignals = l.count() >= 1 ? l.at( 0 )->text() == "signals" : false;
00528 }
00529
00530 NamespaceDom StoreWalker::findOrInsertNamespace( NamespaceAST* ast, const QString & name )
00531 {
00532 if( m_currentNamespace.top() && m_currentNamespace.top()->hasNamespace(name) )
00533 return m_currentNamespace.top()->namespaceByName( name );
00534
00535 if( m_file->hasNamespace(name) )
00536 return m_file->namespaceByName( name );
00537
00538 int startLine, startColumn;
00539 int endLine, endColumn;
00540 ast->getStartPosition( &startLine, &startColumn );
00541 ast->getEndPosition( &endLine, &endColumn );
00542
00543 NamespaceDom ns = m_store->create<NamespaceModel>();
00544 ns->setFileName( m_fileName );
00545 ns->setName( name );
00546 ns->setStartPosition( startLine, startColumn );
00547 ns->setEndPosition( endLine, endColumn );
00548
00549 ns->setScope( m_currentScope );
00550
00551 if( m_currentNamespace.top() )
00552 m_currentNamespace.top()->addNamespace( ns );
00553 else
00554 m_file->addNamespace( ns );
00555
00556 return ns;
00557 }
00558
00559 void StoreWalker::parseFunctionDeclaration( GroupAST* funSpec, GroupAST* storageSpec,
00560 TypeSpecifierAST * typeSpec, InitDeclaratorAST * decl )
00561 {
00562 bool isFriend = false;
00563 bool isVirtual = false;
00564 bool isStatic = false;
00565 bool isInline = false;
00566 bool isPure = decl->initializer() != 0;
00567
00568 if( funSpec ){
00569 QPtrList<AST> l = funSpec->nodeList();
00570 QPtrListIterator<AST> it( l );
00571 while( it.current() ){
00572 QString text = it.current()->text();
00573 if( text == "virtual" ) isVirtual = true;
00574 else if( text == "inline" ) isInline = true;
00575 ++it;
00576 }
00577 }
00578
00579 if( storageSpec ){
00580 QPtrList<AST> l = storageSpec->nodeList();
00581 QPtrListIterator<AST> it( l );
00582 while( it.current() ){
00583 QString text = it.current()->text();
00584 if( text == "friend" ) isFriend = true;
00585 else if( text == "static" ) isStatic = true;
00586 ++it;
00587 }
00588 }
00589
00590 int startLine, startColumn;
00591 int endLine, endColumn;
00592 decl->getStartPosition( &startLine, &startColumn );
00593 decl->getEndPosition( &endLine, &endColumn );
00594
00595 DeclaratorAST* d = decl->declarator();
00596 QString id = d->declaratorId()->unqualifiedName()->text();
00597
00598 FunctionDom method = m_store->create<FunctionModel>();
00599 method->setName( id );
00600
00601 method->setFileName( m_fileName );
00602 method->setStartPosition( startLine, startColumn );
00603 method->setEndPosition( endLine, endColumn );
00604 method->setAccess( m_currentAccess );
00605 method->setStatic( isStatic );
00606 method->setVirtual( isVirtual );
00607 method->setAbstract( isPure );
00608 parseFunctionArguments( d, method );
00609
00610 if( m_inSignals )
00611 method->setSignal( true );
00612
00613 if( m_inSlots )
00614 method->setSlot( true );
00615
00616 QString text = typeOfDeclaration( typeSpec, d );
00617 if( !text.isEmpty() )
00618 method->setResultType( text );
00619
00620 method->setConstant( d->constant() != 0 );
00621 method->setScope( scopeOfDeclarator(d, m_currentScope) );
00622
00623 if( m_currentClass.top() )
00624 m_currentClass.top()->addFunction( method );
00625 else if( m_currentNamespace.top() )
00626 m_currentNamespace.top()->addFunction( method );
00627 else
00628 m_file->addFunction( method );
00629 }
00630
00631 void StoreWalker::parseFunctionArguments( DeclaratorAST* declarator, FunctionDom method )
00632 {
00633 ParameterDeclarationClauseAST* clause = declarator->parameterDeclarationClause();
00634
00635 if( clause && clause->parameterDeclarationList() ){
00636 ParameterDeclarationListAST* params = clause->parameterDeclarationList();
00637 QPtrList<ParameterDeclarationAST> l( params->parameterList() );
00638 QPtrListIterator<ParameterDeclarationAST> it( l );
00639 while( it.current() ){
00640 ParameterDeclarationAST* param = it.current();
00641 ++it;
00642
00643 ArgumentDom arg = m_store->create<ArgumentModel>();
00644
00645 if( param->declarator() ){
00646 QString text = declaratorToString(param->declarator(), QString::null, true );
00647 if( !text.isEmpty() )
00648 arg->setName( text );
00649 }
00650
00651 QString tp = typeOfDeclaration( param->typeSpec(), param->declarator() );
00652 if( !tp.isEmpty() )
00653 arg->setType( tp );
00654
00655 method->addArgument( arg );
00656 }
00657 }
00658 }
00659
00660 QString StoreWalker::typeOfDeclaration( TypeSpecifierAST* typeSpec, DeclaratorAST* declarator )
00661 {
00662 if( !typeSpec || !declarator )
00663 return QString::null;
00664
00665 QString text;
00666
00667 text += typeSpec->text();
00668
00669 QPtrList<AST> ptrOpList = declarator->ptrOpList();
00670 for( QPtrListIterator<AST> it(ptrOpList); it.current(); ++it ){
00671 text += it.current()->text();
00672 }
00673
00674 return text;
00675 }
00676
00677 void StoreWalker::parseBaseClause( BaseClauseAST * baseClause, ClassDom klass )
00678 {
00679 QPtrList<BaseSpecifierAST> l = baseClause->baseSpecifierList();
00680 QPtrListIterator<BaseSpecifierAST> it( l );
00681 while( it.current() ){
00682 BaseSpecifierAST* baseSpecifier = it.current();
00683
00684 QString baseName;
00685 if( baseSpecifier->name() )
00686 baseName = baseSpecifier->name()->text();
00687
00688 klass->addBaseClass( baseName );
00689
00690 ++it;
00691 }
00692 }
00693
00694 QStringList StoreWalker::scopeOfName( NameAST* id, const QStringList& startScope )
00695 {
00696 QStringList scope = startScope;
00697 if( id && id->classOrNamespaceNameList().count() ){
00698 if( id->isGlobal() )
00699 scope.clear();
00700 QPtrList<ClassOrNamespaceNameAST> l = id->classOrNamespaceNameList();
00701 QPtrListIterator<ClassOrNamespaceNameAST> it( l );
00702 while( it.current() ){
00703 if( it.current()->name() ){
00704 scope << it.current()->name()->text();
00705 }
00706 ++it;
00707 }
00708 }
00709
00710 return scope;
00711 }
00712
00713 QStringList StoreWalker::scopeOfDeclarator( DeclaratorAST* d, const QStringList& startScope )
00714 {
00715 return scopeOfName( d->declaratorId(), startScope );
00716 }