tools/porting/src/semantic.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2001-2004 Roberto Raggi
       
     4 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     5 ** All rights reserved.
       
     6 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     7 **
       
     8 ** This file is part of the qt3to4 porting application of the Qt Toolkit.
       
     9 **
       
    10 ** $QT_BEGIN_LICENSE:LGPL$
       
    11 ** No Commercial Usage
       
    12 ** This file contains pre-release code and may not be distributed.
       
    13 ** You may use this file in accordance with the terms and conditions
       
    14 ** contained in the Technology Preview License Agreement accompanying
       
    15 ** this package.
       
    16 **
       
    17 ** GNU Lesser General Public License Usage
       
    18 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    19 ** General Public License version 2.1 as published by the Free Software
       
    20 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    21 ** packaging of this file.  Please review the following information to
       
    22 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    24 **
       
    25 ** In addition, as a special exception, Nokia gives you certain additional
       
    26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    28 **
       
    29 ** If you have questions regarding the use of this file, please contact
       
    30 ** Nokia at qt-info@nokia.com.
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 **
       
    39 ** $QT_END_LICENSE$
       
    40 **
       
    41 ****************************************************************************/
       
    42 
       
    43 #include "smallobject.h"
       
    44 #include "tokenengine.h"
       
    45 #include "semantic.h"
       
    46 #include <QtDebug>
       
    47 #include <QString>
       
    48 #include <QRegExp>
       
    49 
       
    50 QT_BEGIN_NAMESPACE
       
    51 
       
    52 using namespace TokenStreamAdapter;
       
    53 using namespace TokenEngine;
       
    54 using namespace CodeModel;
       
    55 
       
    56 Semantic::Semantic(CodeModel::NamespaceScope *globalScope,
       
    57                    TokenStreamAdapter::TokenStream *tokenStream,
       
    58                    TypedPool<CodeModel::Item> *storage)
       
    59 {
       
    60     m_storage = storage;
       
    61     m_tokenStream = tokenStream;
       
    62 
       
    63     m_currentAccess = CodeModel::Member::Public;
       
    64     m_inSlots = false;
       
    65     m_inSignals = false;
       
    66     m_inStorageSpec = false;
       
    67     m_inTypedef = false;
       
    68 
       
    69     globalScope->setName("::");
       
    70     currentScope.push(globalScope);
       
    71 
       
    72     //create global UnknownType and UnknownTypeMember
       
    73     UnknownType *type = Create<UnknownType>(m_storage);
       
    74     type->setName("__UnknownType");
       
    75     globalScope->addType(type);
       
    76     type->setParent(globalScope);
       
    77 
       
    78     m_sharedUnknownMember = Create<TypeMember>(m_storage);
       
    79     m_sharedUnknownMember->setNameToken(TokenRef());
       
    80     m_sharedUnknownMember->setName("Unknown");
       
    81     m_sharedUnknownMember->setType(type);
       
    82     globalScope->addMember(m_sharedUnknownMember);
       
    83     m_sharedUnknownMember->setParent(globalScope);
       
    84 
       
    85 }
       
    86 
       
    87 void Semantic::parseAST(TranslationUnitAST *node)
       
    88 {
       
    89     TreeWalker::parseTranslationUnit(node);
       
    90 }
       
    91 
       
    92 
       
    93 void Semantic::parseLinkageSpecification(LinkageSpecificationAST *ast)
       
    94 {
       
    95     if(!ast)
       
    96         return;
       
    97     int inStorageSpec = m_inStorageSpec;
       
    98     m_inStorageSpec = true;
       
    99     TreeWalker::parseLinkageSpecification(ast);
       
   100     m_inStorageSpec = inStorageSpec;
       
   101 }
       
   102 
       
   103 void Semantic::parseNamespace(NamespaceAST *ast)
       
   104 {
       
   105     CodeModel::NamespaceScope *parent = currentScope.top()->toNamespaceScope();
       
   106     if(!parent->toNamespaceScope()) {
       
   107         emit error("Error in Semantic::parseNamespace: parent scope was not a namespace");
       
   108         return;
       
   109     }
       
   110 
       
   111     QByteArray nsName;
       
   112     if (!ast->namespaceName() || textOf(ast->namespaceName()).isEmpty()){
       
   113         nsName = "(__QT_ANON_NAMESPACE)";
       
   114     } else {
       
   115         nsName = textOf(ast->namespaceName());
       
   116     }
       
   117 
       
   118     CodeModel::NamespaceScope *namespaceScope = 0;
       
   119 
       
   120     // Look up namespace scope in case it is already defined.
       
   121     // (Unlike classes, C++ namespaces are "open" and can be added to.)
       
   122     CodeModel::Scope *scope = parent->scopes().value(nsName);
       
   123     if (scope)
       
   124         namespaceScope = scope->toNamespaceScope();
       
   125 
       
   126     // Create new namespace if not found.
       
   127     if (!namespaceScope) {
       
   128         namespaceScope = CodeModel::Create<CodeModel::NamespaceScope>(m_storage);
       
   129         namespaceScope->setName(nsName);
       
   130         parent->addScope(namespaceScope);
       
   131 
       
   132         NamespaceMember *namespaceMember = Create<NamespaceMember>(m_storage);
       
   133         namespaceMember->setNameToken(tokenRefFromAST(ast->namespaceName()));
       
   134         namespaceMember->setName(nsName);
       
   135         namespaceMember->setNamespaceScope(namespaceScope);
       
   136         currentScope.top()->addMember(namespaceMember);
       
   137         namespaceMember->setParent(currentScope.top());
       
   138     }
       
   139 
       
   140     currentScope.push(namespaceScope);
       
   141     TreeWalker::parseNamespace(ast);
       
   142     currentScope.pop();
       
   143 }
       
   144 
       
   145 void Semantic::parseClassSpecifier(ClassSpecifierAST *ast)
       
   146 {
       
   147     if (!ast->name()){
       
   148         return;
       
   149     }
       
   150 
       
   151     QByteArray kind = textOf(ast->classKey());
       
   152     if (kind == "class")
       
   153         m_currentAccess = CodeModel::Member::Private;
       
   154     else // kind =="struct"
       
   155         m_currentAccess = CodeModel::Member::Public;
       
   156 
       
   157     QByteArray className = textOf(ast->name()->unqualifiedName());
       
   158 
       
   159     //create ClassScope
       
   160     CodeModel::ClassScope *klass = CodeModel::Create<CodeModel::ClassScope>(m_storage);
       
   161     klass->setName(className);
       
   162     currentScope.top()->addScope(klass);
       
   163 
       
   164     //create ClassType
       
   165     CodeModel::ClassType *type = CodeModel::Create<CodeModel::ClassType>(m_storage);
       
   166     type->setScope(klass);
       
   167     currentScope.top()->addType(type);
       
   168     type->setParent(currentScope.top());
       
   169 
       
   170     //create TypeMember
       
   171     CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
       
   172     typeMember->setNameToken(tokenRefFromAST(ast->name()->unqualifiedName()));
       
   173     typeMember->setName(className);
       
   174     typeMember->setType(type);
       
   175     currentScope.top()->addMember(typeMember);
       
   176     typeMember->setParent(currentScope.top());
       
   177 
       
   178     currentScope.push(klass);
       
   179     if (ast->baseClause())
       
   180         parseBaseClause(ast->baseClause(), klass);
       
   181 
       
   182     //TreeWalker::parseClassSpecifier(ast);
       
   183     parseNode(ast->winDeclSpec());
       
   184     parseNode(ast->classKey());
       
   185     parseNode(ast->baseClause());
       
   186 
       
   187     // Here's the trick for parsing c++ classes:
       
   188     // All inline function definitions must be interpreted as if they were
       
   189     // written after any other declarations in the class.
       
   190     QList<DeclarationAST *> functionDefinitions;
       
   191     if (ast->declarationList())
       
   192         foreach(DeclarationAST *decl, *ast->declarationList()) {
       
   193             if(decl->nodeType() == NodeType_FunctionDefinition)
       
   194                 functionDefinitions.append(decl);
       
   195             else
       
   196             parseNode(decl);
       
   197         }
       
   198     foreach(DeclarationAST *decl, functionDefinitions)
       
   199         parseNode(decl);
       
   200 
       
   201     currentScope.pop();
       
   202 }
       
   203 /*
       
   204     Parse a class, struct or enum forward decalration.
       
   205 */
       
   206 void Semantic::parseElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *node)
       
   207 {
       
   208     if (!node)
       
   209         return;
       
   210     AST *kind = node->kind();
       
   211     if (!kind)
       
   212         return;
       
   213 
       
   214     const QByteArray kindText = textOf(kind);
       
   215     const QByteArray nameText = textOf(node->name());
       
   216 
       
   217     // Don't do anything if the class, struct or enum has already been declared or defined.
       
   218     if (lookupNameInScope(currentScope.top(), node->name()).count() > 0)
       
   219         return;
       
   220 
       
   221     if (kindText == "class" || kindText == "struct") {
       
   222         // Create ClassType.
       
   223         CodeModel::ClassType *type = CodeModel::Create<CodeModel::ClassType>(m_storage);
       
   224         type->setScope(0);
       
   225         currentScope.top()->addType(type);
       
   226         type->setParent(currentScope.top());
       
   227 
       
   228         // Create TypeMember.
       
   229         CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
       
   230         typeMember->setNameToken(tokenRefFromAST(node->name()->unqualifiedName()));
       
   231         typeMember->setName(nameText);
       
   232         typeMember->setType(type);
       
   233         currentScope.top()->addMember(typeMember);
       
   234         typeMember->setParent(currentScope.top());
       
   235     } else if (kindText == "enum") {
       
   236         //create a Type
       
   237         CodeModel::EnumType *enumType = CodeModel::Create<CodeModel::EnumType>(m_storage);
       
   238         enumType->setName(nameText);
       
   239         currentScope.top()->addType(enumType);
       
   240         enumType->setParent(currentScope.top());
       
   241 
       
   242         //create a TypeMember
       
   243         CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
       
   244         if(node->name())
       
   245             typeMember->setNameToken(tokenRefFromAST(node->name()->unqualifiedName()));
       
   246         typeMember->setName(nameText);
       
   247         typeMember->setType(enumType);
       
   248         currentScope.top()->addMember(typeMember);
       
   249         typeMember->setParent(currentScope.top());
       
   250     }
       
   251 }
       
   252 
       
   253 void Semantic::parseSimpleDeclaration(SimpleDeclarationAST *ast)
       
   254 {
       
   255     TypeSpecifierAST *typeSpec = ast->typeSpec();
       
   256     InitDeclaratorListAST *declarators = ast->initDeclaratorList();
       
   257 
       
   258     if (typeSpec)
       
   259         parseTypeSpecifier(typeSpec);
       
   260 
       
   261     if (declarators){
       
   262         List<InitDeclaratorAST*> l = *declarators->initDeclaratorList();
       
   263 
       
   264         foreach (InitDeclaratorAST *current, l) {
       
   265             parseDeclaration(ast->functionSpecifier(), ast->storageSpecifier(), typeSpec, current);
       
   266         }
       
   267     }
       
   268 }
       
   269 
       
   270 void Semantic::parseDeclaration(AST *funSpec, AST *storageSpec, TypeSpecifierAST *typeSpec, InitDeclaratorAST *decl)
       
   271 {
       
   272     if (m_inStorageSpec)
       
   273             return;
       
   274 
       
   275     if(!decl)
       
   276         return;
       
   277 
       
   278     DeclaratorAST *d = decl->declarator();
       
   279     if (!d)
       
   280         return;
       
   281 
       
   282     if (!d->subDeclarator() && d->parameterDeclarationClause()) {
       
   283         parseFunctionDeclaration(funSpec, storageSpec, typeSpec, decl);
       
   284 		return;
       
   285 	}
       
   286     if(!typeSpec || !typeSpec->name())
       
   287         return;
       
   288 
       
   289     DeclaratorAST *t = d;
       
   290     while (t && t->subDeclarator())
       
   291         t = t->subDeclarator();
       
   292 
       
   293     QByteArray id;
       
   294     if (t && t->declaratorId() && t->declaratorId()->unqualifiedName())
       
   295         id = textOf(t->declaratorId()->unqualifiedName());
       
   296 
       
   297     if (!t || !t->declaratorId() || !t->declaratorId()->unqualifiedName())
       
   298         return;
       
   299     AST *nameAST = t->declaratorId()->unqualifiedName();
       
   300     QByteArray name = textOf(nameAST);
       
   301 
       
   302 
       
   303     if (!scopeOfDeclarator(d, QList<QByteArray>()).isEmpty()){
       
   304         return;
       
   305     }
       
   306 
       
   307     //Check if this is possibly a function call by searching for '(' and ')'
       
   308     const QByteArray declText = textOf(decl);
       
   309     if (declText.contains("(") && declText.contains(")")) {
       
   310 	if (decl->declarator() && decl->declarator()->subDeclarator()) {
       
   311 
       
   312         NameAST * name = decl->declarator()->subDeclarator()->declaratorId();
       
   313 	if (name)
       
   314             parseNameUse(name);
       
   315 	    return;	
       
   316         } 
       
   317     }
       
   318 
       
   319     //create VariableMember
       
   320     CodeModel::VariableMember *variableMember = CodeModel::Create<CodeModel::VariableMember>(m_storage);
       
   321     variableMember->setNameToken(tokenRefFromAST(nameAST));
       
   322     variableMember->setName(name);
       
   323     variableMember->setAccess(m_currentAccess);
       
   324     variableMember->setParent(currentScope.top());
       
   325     currentScope.top()->addMember(variableMember);
       
   326 
       
   327     //look up type of variableMember,
       
   328 
       
   329     TypeMember *typeMember = typeLookup(currentScope.top(), typeSpec->name());
       
   330     if(typeMember) {
       
   331         variableMember->setType(typeMember->type());
       
   332     } else {
       
   333         QByteArray text = typeOfDeclaration(typeSpec, d);
       
   334         CodeModel::UnknownType *type = CodeModel::Create<CodeModel::UnknownType>(m_storage);
       
   335         type->setName(text);
       
   336         variableMember->setType(type);
       
   337     }
       
   338 
       
   339     if (decl)
       
   340         parseNode(decl->initializer());
       
   341 
       
   342 }
       
   343 
       
   344 void Semantic::parseFunctionDeclaration(AST *funSpec, AST *storageSpec,
       
   345                                         TypeSpecifierAST * typeSpec, InitDeclaratorAST * initDeclarator)
       
   346 {
       
   347     bool isFriend = false;
       
   348     bool isVirtual = false;
       
   349     bool isStatic = false;
       
   350     bool isInline = false;
       
   351     bool isPure = initDeclarator->initializer() != 0;
       
   352 
       
   353     if (funSpec){
       
   354         List<AST*> l = *funSpec->children();
       
   355         foreach (AST *current, l) {
       
   356             QByteArray text = textOf(current);
       
   357             if (text == "virtual") isVirtual = true;
       
   358             else if (text == "inline") isInline = true;
       
   359         }
       
   360     }
       
   361 
       
   362     if (storageSpec){
       
   363         List<AST*> l = *storageSpec->children();
       
   364         foreach (AST *current, l) {
       
   365             QByteArray text = textOf(current);
       
   366             if (text == "friend") isFriend = true;
       
   367             else if (text == "static") isStatic = true;
       
   368         }
       
   369     }
       
   370     DeclaratorAST *declarator = initDeclarator->declarator();
       
   371     if(!declarator || !declarator->declaratorId())
       
   372         return;
       
   373     AST *nameAST = declarator->declaratorId()->unqualifiedName();
       
   374     QByteArray name = textOf(nameAST);
       
   375 
       
   376     CodeModel::FunctionMember *method = CodeModel::Create<CodeModel::FunctionMember>(m_storage);
       
   377     method->setNameToken(tokenRefFromAST(nameAST));
       
   378     method->setName(name);
       
   379     method->setAccess(m_currentAccess);
       
   380     method->setStatic(isStatic);
       
   381     method->setVirtual(isVirtual);
       
   382     method->setAbstract(isPure);
       
   383 
       
   384     parseFunctionArguments(declarator, method);
       
   385 
       
   386     if (m_inSignals)
       
   387         method->setSignal(true);
       
   388 
       
   389     if (m_inSlots)
       
   390         method->setSlot(true);
       
   391 
       
   392     method->setConstant(declarator->constant() != 0);
       
   393 
       
   394     QByteArray text = typeOfDeclaration(typeSpec, declarator);
       
   395     if (!text.isEmpty()) {
       
   396         CodeModel::UnknownType *type = CodeModel::Create<CodeModel::UnknownType>(m_storage);
       
   397         type->setName(text);
       
   398         method->setReturnType(type);
       
   399     }
       
   400 
       
   401     method->setParent(currentScope.top());
       
   402     currentScope.top()->addMember(method);
       
   403 }
       
   404 
       
   405 
       
   406 void Semantic::parseBaseClause(BaseClauseAST * baseClause, CodeModel::ClassScope *klass)
       
   407 {
       
   408     if(!baseClause)
       
   409         return;
       
   410     if(!klass)
       
   411         return;
       
   412     List<BaseSpecifierAST*> *l = baseClause->baseSpecifierList();
       
   413     if (!l)
       
   414         return;
       
   415     foreach (BaseSpecifierAST *baseSpecifier, *l) {
       
   416         QByteArray baseName;
       
   417         if (!baseSpecifier->name())
       
   418             continue;
       
   419 
       
   420         // Look up a class with the correct name.
       
   421         QList<Member *> candidates = nameLookup(klass, baseSpecifier->name());
       
   422         if (candidates.count() == 1 ) {
       
   423             Member *member = candidates.at(0);
       
   424             Q_ASSERT(member);
       
   425             TypeMember *typeMember = member->toTypeMember();
       
   426             if (typeMember) {
       
   427                 Q_ASSERT(typeMember->type());
       
   428                 ClassType *classType = typeMember->type()->toClassType();
       
   429                 if (classType) {
       
   430                     klass->addBaseClass(classType);
       
   431                 }
       
   432             }
       
   433         }
       
   434     }
       
   435 }
       
   436 void Semantic::parseFunctionArguments(const DeclaratorAST *declarator, CodeModel::FunctionMember *method)
       
   437 {
       
   438     if(!declarator || !method)
       
   439         return;
       
   440 
       
   441     ParameterDeclarationClauseAST *clause = declarator->parameterDeclarationClause();
       
   442 
       
   443     if (clause && clause->parameterDeclarationList()){
       
   444         ParameterDeclarationListAST *params = clause->parameterDeclarationList();
       
   445         List<ParameterDeclarationAST*> *l = params->parameterList();
       
   446         if (!l)
       
   447             return;
       
   448         foreach (ParameterDeclarationAST *param, *l) {
       
   449             CodeModel::Argument *arg = CodeModel::Create<CodeModel::Argument>(m_storage);
       
   450             arg->setParent(method);
       
   451 
       
   452             if (param->declarator()){
       
   453                 QByteArray text = declaratorToString(param->declarator(), QByteArray(), true);
       
   454                 if(param->declarator()->declaratorId())
       
   455                     arg->setNameToken(tokenRefFromAST(param->declarator()->declaratorId()->unqualifiedName()));
       
   456                 if (!text.isEmpty())
       
   457                     arg->setName(text);
       
   458             }
       
   459 
       
   460             QByteArray tp = typeOfDeclaration(param->typeSpec(), param->declarator());
       
   461             if (!tp.isEmpty()) {
       
   462                 CodeModel::UnknownType *type = CodeModel::Create<CodeModel::UnknownType>(m_storage);
       
   463                 type->setName(tp);
       
   464                 arg->setType(type);
       
   465             }
       
   466 
       
   467             method->addArgument(arg);
       
   468         }
       
   469     }
       
   470 }
       
   471 
       
   472 // using directive (using namespace A)
       
   473 void Semantic::parseUsingDirective(UsingDirectiveAST *ast)
       
   474 {
       
   475     QByteArray qualifiedname = textOf(ast->name());
       
   476     QByteArray name = textOf(ast->name()->unqualifiedName());
       
   477 
       
   478     //look up target namespace name
       
   479     QList<Member *> memberList = nameLookup(currentScope.top(), ast->name());
       
   480 
       
   481     NamespaceScope *targetNamespace = 0;
       
   482 
       
   483     // search for namespace in member list.
       
   484     QList<Member *>::ConstIterator it = memberList.constBegin();
       
   485     while(it != memberList.constEnd()) {
       
   486         if (NamespaceMember *namespaceMember = (*it)->toNamespaceMember()) {
       
   487             targetNamespace = namespaceMember->namespaceScope();
       
   488             break;
       
   489         }
       
   490         ++it;
       
   491     }
       
   492 
       
   493     if (targetNamespace == 0)
       
   494         return;
       
   495 
       
   496     // Find the insertion namespace, which is the first common
       
   497     // ancesotor namespace for the current scope and the target namespace
       
   498 
       
   499     // currentScope might be a block scope, find its first namespace parent
       
   500     CodeModel::Scope *currentParent = currentScope.top();
       
   501     while (currentParent->toNamespaceScope() == 0) {
       
   502         currentParent = currentParent->parent();
       
   503     }
       
   504 
       
   505     CodeModel::Scope *namespaceA = currentParent;
       
   506     while (namespaceA != 0) {
       
   507         CodeModel::Scope *namespaceB = targetNamespace;
       
   508         while (namespaceB != 0) {
       
   509             if (namespaceB == namespaceA)
       
   510                 break;
       
   511             namespaceB = namespaceB->parent();
       
   512         }
       
   513         if (namespaceB == namespaceA)
       
   514             break;
       
   515         namespaceA = namespaceA->parent();
       
   516     }
       
   517 
       
   518     if (namespaceA == 0 || namespaceA->toNamespaceScope() == 0)
       
   519         return;
       
   520 
       
   521     NamespaceScope *insertionNamespace = namespaceA->toNamespaceScope();
       
   522 
       
   523     // Create using directive link
       
   524     UsingDirectiveLink *usingDirectiveLink = Create<UsingDirectiveLink>(m_storage);
       
   525     usingDirectiveLink->setParent(currentScope.top());
       
   526     usingDirectiveLink->setTargetNamespace(targetNamespace);
       
   527     usingDirectiveLink->setInsertionNamespace(insertionNamespace);
       
   528 
       
   529     // add it to current namespace
       
   530     if (NamespaceScope *namespaceScope = currentScope.top()->toNamespaceScope())
       
   531         namespaceScope->addUsingDirectiveLink(usingDirectiveLink);
       
   532     else if (BlockScope *blockScope = currentScope.top()->toBlockScope())
       
   533         blockScope->addUsingDirectiveLink(usingDirectiveLink);
       
   534 }
       
   535 
       
   536 void Semantic::parseFunctionDefinition(FunctionDefinitionAST *ast)
       
   537 {
       
   538     AST *funSpec = ast->functionSpecifier();
       
   539     AST *storageSpec = ast->storageSpecifier();
       
   540     TypeSpecifierAST *typeSpec = ast->typeSpec();
       
   541     InitDeclaratorAST *initDeclarator = ast->initDeclarator();
       
   542     if (!ast->initDeclarator())
       
   543         return;
       
   544 
       
   545     DeclaratorAST *d = initDeclarator->declarator();
       
   546 
       
   547     if (!d->declaratorId())
       
   548         return;
       
   549 
       
   550     parseFunctionDeclaration(funSpec, storageSpec, typeSpec, initDeclarator);
       
   551     CodeModel::FunctionMember *method = functionLookup(currentScope.top(), d);
       
   552 
       
   553     if(!method) {
       
   554         emit error("Error in Semantic::parseFunctionDefinition: Could not find declaration for function definition");
       
   555         return;
       
   556     }
       
   557 
       
   558     CodeModel::Scope *parent = method->parent();
       
   559 
       
   560     if(!ast->functionBody()) {
       
   561         emit error("Error in Semantic::parseFunctionDefinition: no function body in function definition");
       
   562         return;
       
   563     }
       
   564 
       
   565     //create child function scope
       
   566     QByteArray id = textOf(d->declaratorId()->unqualifiedName());
       
   567     CodeModel::BlockScope *functionScope = CodeModel::Create<CodeModel::BlockScope>(m_storage);
       
   568     functionScope->setName(QByteArray("__QT_ANON_BLOCK_SCOPE(Function: ") + id + QByteArray(")"));
       
   569     functionScope->setParent(parent);
       
   570     method->setFunctionBodyScope(functionScope);
       
   571 
       
   572     //add arguments to child scope
       
   573      ArgumentCollection arguments = method->arguments();
       
   574      ArgumentCollection::ConstIterator it = arguments.constBegin();
       
   575      while(it != arguments.constEnd()) {
       
   576          CodeModel::Argument *argument = *it;
       
   577          CodeModel::VariableMember *variableMember = CodeModel::Create<CodeModel::VariableMember>(m_storage);
       
   578          variableMember->setNameToken(argument->nameToken());
       
   579          variableMember->setType(argument->type());
       
   580          variableMember->setName(argument->name());
       
   581          variableMember->setParent(functionScope);
       
   582          functionScope->addMember(variableMember);
       
   583          ++it;
       
   584      }
       
   585 
       
   586     //push function scope and parse function body
       
   587     currentScope.push(functionScope);
       
   588     parseStatementList(ast->functionBody());
       
   589     currentScope.pop();
       
   590 }
       
   591 
       
   592 void Semantic::parseStatementList(StatementListAST *statemenList)
       
   593 {
       
   594     if(!statemenList)
       
   595         return;
       
   596     CodeModel::BlockScope *blockScope = CodeModel::Create<CodeModel::BlockScope>(m_storage);
       
   597     blockScope->setName("__QT_ANON_BLOCK_SCOPE");
       
   598     blockScope->setParent(currentScope.top());
       
   599     currentScope.top()->addScope(blockScope);
       
   600 
       
   601     currentScope.push(blockScope);
       
   602     TreeWalker::parseStatementList(statemenList);
       
   603     currentScope.pop();
       
   604 }
       
   605 
       
   606 void Semantic::parseExpression(AbstractExpressionAST* node)
       
   607 {
       
   608     if(!node)
       
   609         return;
       
   610     if(node->nodeType() == NodeType_ClassMemberAccess)
       
   611         parseClassMemberAccess(static_cast<ClassMemberAccessAST *>(node));
       
   612     else
       
   613         TreeWalker::parseExpression(node);
       
   614 }
       
   615 
       
   616 /*
       
   617     Pretty hardwired code for handling class member access of the types:
       
   618     object.member and objectPtr->member.
       
   619 
       
   620     This function creates a name use for object to its declaration, and a
       
   621     name use from member to its declaration in the class.
       
   622 */
       
   623 void Semantic::parseClassMemberAccess(ClassMemberAccessAST *node)
       
   624 {
       
   625     if(!node)
       
   626         return;
       
   627     parseExpression(node->expression());
       
   628     // Get a name use for the 'object' name.
       
   629     NameUse *nameUse = findNameUse(node->expression());
       
   630     // Since the NameUse refers to an object, its decalaration must be
       
   631     // a ClassType. Get the scope of this class type.
       
   632     if(    nameUse
       
   633         && nameUse->declaration()
       
   634         && nameUse->declaration()->toVariableMember()
       
   635         && nameUse->declaration()->toVariableMember()->type()
       
   636         && nameUse->declaration()->toVariableMember()->type()->toClassType()
       
   637         && nameUse->declaration()->toVariableMember()->type()->toClassType()->scope())   {
       
   638 
       
   639         CodeModel::Scope *scope = nameUse->declaration()->toVariableMember()->type()->toClassType()->scope();
       
   640         QList<CodeModel::Member *> members = lookupNameInScope(scope, node->name());
       
   641             if(members.count() != 0) {
       
   642                 createNameUse(members.at(0), node->name());
       
   643                 return;
       
   644             }
       
   645     }
       
   646     // Create a NameUse that refers to the global shared unknown type.
       
   647     createNameUse(m_sharedUnknownMember, node->name());
       
   648 }
       
   649 
       
   650 void Semantic::parseExpressionStatement(ExpressionStatementAST *node)
       
   651 {
       
   652     TreeWalker::parseExpressionStatement(node);
       
   653 }
       
   654 
       
   655 // using declaration (using A::b)
       
   656 void Semantic::parseUsing(UsingAST *ast)
       
   657 {
       
   658     //CodeModel::Scope *s = lookUpScope(currentScope.top(), ast->name());
       
   659     QList<CodeModel::Member *> members = nameLookup(currentScope.top(), ast->name());
       
   660     if(members.isEmpty()) {
       
   661         emit error("Error in Semantic::parseUsing: could not look up using target");
       
   662         return;
       
   663     }
       
   664     //TODO: handle multiple members (when nameLookup returns a set of overloded functions)
       
   665     CodeModel::Member *member = members[0];
       
   666     CodeModel::Scope *targetScope = member->parent();
       
   667     if(!targetScope) {
       
   668         emit error("Error in Semantic::parseUsing: target has no parent scope");
       
   669         return;
       
   670     }
       
   671 
       
   672     if(!ast->name())
       
   673         return;
       
   674     AST *nameAST = ast->name()->unqualifiedName();
       
   675     if(!nameAST)
       
   676         return;
       
   677     QByteArray name = textOf(nameAST);
       
   678 }
       
   679 
       
   680 void Semantic::parseEnumSpecifier(EnumSpecifierAST *ast)
       
   681 {
       
   682     if (!ast->name())
       
   683          return;
       
   684 
       
   685     QByteArray name = textOf(ast->name());
       
   686 
       
   687     //create a Type
       
   688     CodeModel::EnumType *enumType = CodeModel::Create<CodeModel::EnumType>(m_storage);
       
   689     enumType->setName(name);
       
   690     currentScope.top()->addType(enumType);
       
   691     enumType->setParent(currentScope.top());
       
   692 
       
   693     //create a TypeMember
       
   694     CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
       
   695     if(ast->name())
       
   696         typeMember->setNameToken(tokenRefFromAST(ast->name()->unqualifiedName()));
       
   697     typeMember->setName(name);
       
   698     typeMember->setType(enumType);
       
   699     currentScope.top()->addMember(typeMember);
       
   700     typeMember->setParent(currentScope.top());
       
   701 
       
   702     //parse the eneumerators
       
   703     List<EnumeratorAST*> *list = ast->enumeratorList();
       
   704     if (!list)
       
   705         return;
       
   706     foreach (EnumeratorAST *current, *list) {
       
   707         CodeModel::VariableMember *enumerator = CodeModel::Create<CodeModel::VariableMember>(m_storage);
       
   708         enumerator->setNameToken(tokenRefFromAST(current->id()));
       
   709         enumerator->setName(textOf(current->id()));
       
   710         enumerator->setAccess(m_currentAccess);
       
   711         enumerator->setStatic(true);
       
   712         enumerator->setType(enumType);
       
   713         currentScope.top()->addMember(enumerator);
       
   714         enumerator->setParent(currentScope.top());
       
   715     }
       
   716 
       
   717 }
       
   718 
       
   719 void Semantic::parseTypedef(TypedefAST *ast)
       
   720 {
       
   721     TypeSpecifierAST *typeSpec = ast->typeSpec();
       
   722     InitDeclaratorListAST *declarators = ast->initDeclaratorList();
       
   723 
       
   724     if (typeSpec && declarators){
       
   725         QByteArray typeId;
       
   726 
       
   727         if (typeSpec->name())
       
   728             typeId = textOf(typeSpec->name());
       
   729 
       
   730         List<InitDeclaratorAST*> *l = declarators->initDeclaratorList();
       
   731         if (!l)
       
   732             return;
       
   733         foreach (InitDeclaratorAST *initDecl, *l) {
       
   734             QByteArray type, id;
       
   735             if (initDecl->declarator()){
       
   736                type = typeOfDeclaration(typeSpec, initDecl->declarator());
       
   737 
       
   738                DeclaratorAST *d = initDecl->declarator();
       
   739                while (d->subDeclarator()){
       
   740                    d = d->subDeclarator();
       
   741                }
       
   742 
       
   743                if (d->declaratorId())
       
   744                   id = textOf(d->declaratorId());
       
   745             }
       
   746 
       
   747             //create a type
       
   748             CodeModel::Scope *scope = currentScope.top();
       
   749             CodeModel::AliasType *typeAlias = CodeModel::Create<CodeModel::AliasType>(m_storage);
       
   750             //typeAlias->setName(id);
       
   751             //typeAlias->setParent(scope);
       
   752             scope->addType(typeAlias);
       
   753 
       
   754             //create a TypeMember
       
   755             CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
       
   756             if(typeSpec->name())
       
   757                 typeMember->setNameToken(tokenRefFromAST(typeSpec->name()->unqualifiedName()));
       
   758             typeMember->setName(id);
       
   759             typeMember->setType(typeAlias);
       
   760             currentScope.top()->addMember(typeMember);
       
   761             typeMember->setParent(currentScope.top());
       
   762 
       
   763         }
       
   764 
       
   765     }
       
   766 }
       
   767 
       
   768 void Semantic::parseTypeSpecifier(TypeSpecifierAST *ast)
       
   769 {
       
   770     // If this is a classSpecifier or a EnumSpecifier we skip the name lookup,
       
   771     // becuase looking up the name "E" in a class definition like
       
   772     // "class E { ..." makes no sense. (There might be a variable named E
       
   773     // already declared, but that variable is now shadowed by the class type.)
       
   774     if(   ast->nodeType() != NodeType_EnumSpecifier
       
   775        && ast->nodeType() != NodeType_ClassSpecifier
       
   776        && ast->nodeType() != NodeType_ElaboratedTypeSpecifier )
       
   777         parseNameUse(ast->name());
       
   778     TreeWalker::parseTypeSpecifier(ast);
       
   779 }
       
   780 
       
   781 /*
       
   782     Parses a name: looks up name, creates name use.
       
   783 */
       
   784 void Semantic::parseNameUse(NameAST* name)
       
   785 {
       
   786     if(!name)
       
   787         return;
       
   788 
       
   789     // Look up name
       
   790     QList<CodeModel::Member *> members = nameLookup(currentScope.top(), name);
       
   791     if(members.isEmpty()) {
       
   792         //cout << "no declaration found for " << textOf(name).constData() << endl;
       
   793         // Create NameUse that refer to a shared UnknownMember
       
   794         createNameUse(m_sharedUnknownMember, name);
       
   795         return;
       
   796     }
       
   797 
       
   798     //TODO: handle multiple members (when nameLookup returns a set of overloaded functions)
       
   799     CodeModel::Member *member = members[0];
       
   800     if(!member->parent()) {
       
   801         emit error("Error in Semantic::parseUsing: target has no parent scope");
       
   802         return;
       
   803     }
       
   804 
       
   805     createNameUse(member, name);
       
   806 }
       
   807 
       
   808 /*
       
   809     looks up name used in basescope. If name->isGlobal() is true or if classOrNamespaceList()
       
   810     returns a non-emty list, the C++ qualified name lookup rules are used. Otherwise the
       
   811     unquialified name lookup rules are used.  Returns the a list of members that was found,
       
   812     In most cases this list will contain zero or one element, exept in the case of overloaded functions.
       
   813     TODO: Argument-dependent name lookup
       
   814 */
       
   815 QList<CodeModel::Member *> Semantic::nameLookup(CodeModel::Scope *baseScope, const NameAST* name)
       
   816 {
       
   817     if (name->isGlobal() || (name->classOrNamespaceNameList()
       
   818                               && name->classOrNamespaceNameList()->size()>0 )) {
       
   819         return qualifiedNameLookup(baseScope, name);
       
   820     } else {
       
   821         return unqualifiedNameLookup(baseScope, name);
       
   822     }
       
   823 }
       
   824 
       
   825 //look up an unqualified name
       
   826 QList<CodeModel::Member *> Semantic::unqualifiedNameLookup(CodeModel::Scope *baseScope, const NameAST* name)
       
   827 {
       
   828     QList<UsingDirectiveLink *> usingDirectiveLinks;
       
   829     CodeModel::Scope *currentScope = baseScope;
       
   830     QList<CodeModel::Member *>  entities;
       
   831 
       
   832     while (currentScope != 0) {
       
   833         // Add any "using namespace" directive links for the current scope to
       
   834         // usingDirectiveLinks
       
   835         if (NamespaceScope *namespaceScope = currentScope->toNamespaceScope())
       
   836             usingDirectiveLinks += namespaceScope->usingDirectiveLinks();
       
   837         if (BlockScope *blockScope = currentScope->toBlockScope())
       
   838             usingDirectiveLinks += blockScope->usingDirectiveLinks();
       
   839 
       
   840         // Search usingDirectiveLinks for a link where currentScope is the
       
   841         // insertion namespace. If found look up name in the target namespace
       
   842         // for that link.
       
   843         if (NamespaceScope *namespaceScope = currentScope->toNamespaceScope()) {
       
   844             QList<UsingDirectiveLink *>::ConstIterator it = usingDirectiveLinks.constBegin();
       
   845             while (it != usingDirectiveLinks.constEnd()) {
       
   846                 if ((*it)->insertionNamespace() == namespaceScope)
       
   847                     entities = lookupNameInScope((*it)->targetNamespace(), name);
       
   848                 ++it;
       
   849             }
       
   850         }
       
   851 
       
   852         // Look up names in this scope.
       
   853         entities += lookupNameInScope(currentScope, name);
       
   854         if (!entities.isEmpty())
       
   855             break;
       
   856         currentScope = currentScope->parent();
       
   857     }
       
   858     return entities;
       
   859 }
       
   860 
       
   861 //look up a qualified name
       
   862 QList<CodeModel::Member *> Semantic::qualifiedNameLookup(CodeModel::Scope *baseScope, const NameAST* name)
       
   863 {
       
   864     QList<CodeModel::Member *> entities;
       
   865     CodeModel::Scope *currentScope = baseScope;
       
   866 
       
   867     // Check if the global ("::") scope has been specified.
       
   868     if(name->isGlobal()) {
       
   869         while (currentScope->parent())
       
   870             currentScope = currentScope->parent();
       
   871     }
       
   872 
       
   873     while (entities.isEmpty() && currentScope != 0) {
       
   874         CodeModel::Scope *targetScope = scopeLookup(currentScope, name);
       
   875         entities = lookupNameInScope(targetScope, name);
       
   876         currentScope = currentScope->parent();
       
   877     }
       
   878 
       
   879     return entities;
       
   880 }
       
   881 
       
   882 //looks up a name in a scope, includes base classes if scope is a class scope
       
   883 QList<CodeModel::Member *> Semantic::lookupNameInScope(CodeModel::Scope *scope, const NameAST* name)
       
   884 {
       
   885     QList<CodeModel::Member *> entities;
       
   886 
       
   887     if(!scope || !name)
       
   888         return entities;
       
   889 
       
   890     QByteArray nameText = textOf(name->unqualifiedName()->name());
       
   891     //look up name in members of current scope
       
   892     const CodeModel::MemberCollection members = scope->members();
       
   893     if (members.contains(nameText))
       
   894         entities.append(members.value(nameText));
       
   895 
       
   896     // if not found, look up name in  base classes (if any)
       
   897     CodeModel::ClassScope *classScope = scope->toClassScope();
       
   898     if (entities.isEmpty() && classScope) {
       
   899         const TypeCollection baseClasses = classScope->baseClasses();
       
   900         TypeCollection::ConstIterator it = baseClasses.constBegin();
       
   901         while (it != baseClasses.constEnd()) {
       
   902             CodeModel::Scope *baseClass = it.value()->toClassType()->scope();
       
   903             if (scope != baseClass)
       
   904                 entities += lookupNameInScope(baseClass, name);
       
   905             ++it;
       
   906         }
       
   907 
       
   908         if (entities.count() > 1)
       
   909             emit error("Error in Semantic::lookupNameInScope: name "
       
   910             + nameText + " is ambigous");
       
   911     }
       
   912     return entities;
       
   913 }
       
   914 
       
   915 /*
       
   916     Resolves the classOrNamespaceNameList part of a NameAST against a base scope.
       
   917 */
       
   918 CodeModel::Scope *Semantic::scopeLookup(CodeModel::Scope *baseScope, const NameAST* name)
       
   919 {
       
   920     CodeModel::Scope *currentScope = baseScope;
       
   921     const List<ClassOrNamespaceNameAST *> *scopeList = name->classOrNamespaceNameList();
       
   922     // if there is no scope list, then the scope we are looking for is baseScope
       
   923     if (!scopeList)
       
   924         return baseScope;
       
   925 
       
   926     // Check if the global ("::") scope has been specified.
       
   927     if(name->isGlobal()) {
       
   928         while (currentScope->parent())
       
   929             currentScope = currentScope->parent();
       
   930     }
       
   931 
       
   932     while(currentScope != 0) {
       
   933         int nestingCounter = 0;
       
   934         CodeModel::Scope *nestedScope = currentScope;
       
   935         while (nestingCounter < scopeList->count()) {
       
   936             const QByteArray nameText = textOf((*scopeList)[nestingCounter]->name());
       
   937             nestedScope = nestedScope->scopes().value(nameText);
       
   938             if (!nestedScope)
       
   939                 break;
       
   940             ++nestingCounter;
       
   941         }
       
   942         if(nestedScope) // found target scope?
       
   943             return nestedScope;
       
   944 
       
   945         currentScope = currentScope->parent(); //look in parent scope
       
   946     }
       
   947 
       
   948     return 0;
       
   949 }
       
   950 
       
   951 TypeMember *Semantic::typeLookup(CodeModel::Scope *baseScope, const NameAST* name)
       
   952 {
       
   953     QList<CodeModel::Member *> memberList = nameLookup(baseScope, name);
       
   954 
       
   955     foreach(Member *member, memberList) {
       
   956         if(TypeMember *typeMember = member->toTypeMember())
       
   957             return typeMember;
       
   958     }
       
   959     return 0;
       
   960 }
       
   961 
       
   962 FunctionMember *Semantic::functionLookup(CodeModel::Scope *baseScope,
       
   963                                           const DeclaratorAST *functionDeclarator)
       
   964 {
       
   965 
       
   966     QList<CodeModel::Member*> candidateList =
       
   967                 nameLookup(baseScope, functionDeclarator->declaratorId());
       
   968     return selectFunction(candidateList, functionDeclarator);
       
   969 }
       
   970 
       
   971 /*
       
   972     This is a simplified function lookup routine, for matching member function
       
   973     definitions with member function declarations. It does not implement
       
   974     the general C++ function overload resolution rules.
       
   975 */
       
   976 FunctionMember *Semantic::selectFunction(QList<CodeModel::Member*> candidatateList, const DeclaratorAST *functionDeclarator)
       
   977 {
       
   978     // get arguments for funciton we are looking for
       
   979     FunctionMember testFunction;
       
   980     parseFunctionArguments(functionDeclarator, &testFunction);
       
   981     const ArgumentCollection testArgumentCollection = testFunction.arguments();
       
   982 
       
   983     //test againts functions in overload list.
       
   984     foreach(Member* member, candidatateList) {
       
   985         FunctionMember *function = member->toFunctionMember();
       
   986         if (!function)
       
   987             continue;
       
   988         const ArgumentCollection argumentCollection = function->arguments();
       
   989 
       
   990         //test argument types and number of arguments
       
   991         ArgumentCollection::ConstIterator arg1 = argumentCollection.constBegin();
       
   992         ArgumentCollection::ConstIterator arg2 = testArgumentCollection.constBegin();
       
   993         bool match = true;
       
   994         while(arg1 != argumentCollection.constEnd() && arg2 != testArgumentCollection.constEnd()) {
       
   995             if( arg1.value()->type()->name() != arg2.value()->type()->name() ) {
       
   996                 match = false;
       
   997                 break;
       
   998             }
       
   999             ++arg1;
       
  1000             ++arg2;
       
  1001         }
       
  1002         if(match)
       
  1003             return function;
       
  1004     }
       
  1005     return 0;
       
  1006 }
       
  1007 
       
  1008 QByteArray Semantic::typeOfDeclaration(TypeSpecifierAST *typeSpec, DeclaratorAST *declarator)
       
  1009 {
       
  1010     if (!typeSpec)
       
  1011         return QByteArray();
       
  1012 
       
  1013     QByteArray text;
       
  1014 
       
  1015     if (typeSpec->cvQualify()) {
       
  1016         List<AST*> cv = *typeSpec->cvQualify()->children();
       
  1017         foreach (AST *current, cv) {
       
  1018             text += " " + textOf(current);
       
  1019         }
       
  1020         text += " ";
       
  1021     }
       
  1022 
       
  1023 
       
  1024     text += textOf(typeSpec);
       
  1025 
       
  1026     if (typeSpec->cv2Qualify()) {
       
  1027         List<AST*> cv = *typeSpec->cv2Qualify()->children();
       
  1028         foreach (AST *current, cv) {
       
  1029             text += textOf(current) + " ";
       
  1030         }
       
  1031     }
       
  1032 
       
  1033     if (declarator && declarator->ptrOpList()) {
       
  1034         List<AST*> ptrOpList = *declarator->ptrOpList();
       
  1035         foreach (AST *current, ptrOpList) {
       
  1036             text += " " + textOf(current);
       
  1037         }
       
  1038         text += " ";
       
  1039     }
       
  1040 
       
  1041     return text.trimmed().simplified();
       
  1042 }
       
  1043 
       
  1044 
       
  1045 
       
  1046 QList<QByteArray> Semantic::scopeOfName(NameAST *id, const QList<QByteArray>& startScope)
       
  1047 {
       
  1048     QList<QByteArray> scope = startScope;
       
  1049     if (id && id->classOrNamespaceNameList()){
       
  1050         if (id->isGlobal())
       
  1051             scope.clear();
       
  1052 
       
  1053         List<ClassOrNamespaceNameAST*> l = *id->classOrNamespaceNameList();
       
  1054         foreach (ClassOrNamespaceNameAST *current, l) {
       
  1055             if (current->name())
       
  1056                scope << textOf(current->name());
       
  1057         }
       
  1058     }
       
  1059 
       
  1060     return scope;
       
  1061 }
       
  1062 
       
  1063 QList<QByteArray> Semantic::scopeOfDeclarator(DeclaratorAST *d, const QList<QByteArray>& startScope)
       
  1064 {
       
  1065     if(!d)
       
  1066         return QList<QByteArray>();
       
  1067     return scopeOfName(d->declaratorId(), startScope);
       
  1068 }
       
  1069 
       
  1070 QByteArray Semantic::typeSpecToString(TypeSpecifierAST* typeSpec)
       
  1071 {
       
  1072     if (!typeSpec)
       
  1073         return QByteArray();
       
  1074 
       
  1075     QByteArray tp;
       
  1076     if (typeSpec->cvQualify()) {
       
  1077         tp += "const ";
       
  1078     }
       
  1079 
       
  1080     tp += (QString::fromLatin1(textOf(typeSpec)).replace(QRegExp(QLatin1String(" :: ")), QString::fromUtf8("::"))).toLatin1();
       
  1081     return tp;
       
  1082 }
       
  1083 
       
  1084 QByteArray Semantic::declaratorToString(DeclaratorAST* declarator, const QByteArray& scope, bool skipPtrOp)
       
  1085 {
       
  1086     if (!declarator)
       
  1087         return QByteArray();
       
  1088 
       
  1089     QByteArray text;
       
  1090 
       
  1091     if (!skipPtrOp && declarator->ptrOpList()){
       
  1092         List<AST*> ptrOpList = *declarator->ptrOpList();
       
  1093         foreach (AST *current, ptrOpList) {
       
  1094             text += textOf(current);
       
  1095         }
       
  1096         text += QByteArray(" ");
       
  1097     }
       
  1098 
       
  1099     text += scope;
       
  1100 
       
  1101     if (declarator->subDeclarator())
       
  1102         text += QByteArray("(") + declaratorToString(declarator->subDeclarator()) + QByteArray(")");
       
  1103 
       
  1104     if (declarator->declaratorId())
       
  1105         text += textOf(declarator->declaratorId());
       
  1106 
       
  1107     if (declarator->arrayDimensionList()) {
       
  1108         List<AST*> arrays = *declarator->arrayDimensionList();
       
  1109         foreach (AST *current, arrays) {
       
  1110             current=current;    //silence unused symbol warning
       
  1111             text += QByteArray("[]");
       
  1112         }
       
  1113     }
       
  1114 
       
  1115     if (declarator->parameterDeclarationClause()){
       
  1116         text += QByteArray("(");
       
  1117 
       
  1118         ParameterDeclarationListAST* l = declarator->parameterDeclarationClause()->parameterDeclarationList();
       
  1119         if (l != 0){
       
  1120             List<ParameterDeclarationAST*> params = *l->parameterList();
       
  1121             foreach (ParameterDeclarationAST *current, params) {
       
  1122                 QByteArray type = typeSpecToString(current->typeSpec());
       
  1123                 text += type;
       
  1124                 if (!type.isEmpty())
       
  1125                     text += QByteArray(" ");
       
  1126                 text += declaratorToString(current->declarator());
       
  1127 
       
  1128                 // ### FIXME if (it.current())
       
  1129                     text += QByteArray(", ");
       
  1130             }
       
  1131         }
       
  1132 
       
  1133         text += QByteArray(")");
       
  1134 
       
  1135         if (declarator->constant() != 0)
       
  1136             text += QByteArray(" const");
       
  1137     }
       
  1138 
       
  1139     return QString::fromLatin1(text).replace(QRegExp(QLatin1String(" :: ")), QLatin1String("::")).simplified().toLatin1();
       
  1140 }
       
  1141 
       
  1142 QByteArray Semantic::textOf(const AST *node) const
       
  1143 {
       
  1144     if (!node)
       
  1145         return QByteArray();
       
  1146     QByteArray text;
       
  1147     for (int i = node->startToken(); i < node->endToken(); ++i) {
       
  1148         if (!m_tokenStream->isHidden(i)) {
       
  1149             if (i != node->startToken())
       
  1150                 text += QByteArray(" ");
       
  1151             text += m_tokenStream->tokenText(i);
       
  1152         }
       
  1153     }
       
  1154     return text;
       
  1155 }
       
  1156 
       
  1157 void Semantic::createNameUse(Member *member, NameAST *name)
       
  1158 {
       
  1159     if (!name)
       
  1160        return;
       
  1161 
       
  1162     AST *unqualifedName = name->unqualifiedName()->name();
       
  1163 
       
  1164     if(!unqualifedName || !member)
       
  1165         return;
       
  1166 
       
  1167     CodeModel::NameUse *nameUse = CodeModel::Create<CodeModel::NameUse>(m_storage);
       
  1168     nameUse->setParent(currentScope.top());
       
  1169     nameUse->setNameToken(tokenRefFromAST(unqualifedName));
       
  1170     nameUse->setName(textOf(unqualifedName));
       
  1171     nameUse->setDeclaration(member);
       
  1172 
       
  1173     currentScope.top()->addNameUse(nameUse);
       
  1174     addNameUse(unqualifedName, nameUse);
       
  1175 }
       
  1176 
       
  1177 void Semantic::addNameUse(AST *node, NameUse *nameUse)
       
  1178 {
       
  1179     const int tokenIndex = node->startToken();
       
  1180     m_nameUses.insert(tokenIndex, nameUse);
       
  1181 }
       
  1182 
       
  1183 /*
       
  1184     Searches a AST node and all its children for a nameUse. The name use is
       
  1185     found by looking up each node's tokens in the m_nameUses map. A depth-first
       
  1186     search is used.
       
  1187 */
       
  1188 NameUse *Semantic::findNameUse(AST *node)
       
  1189 {
       
  1190     if(!node)
       
  1191         return 0;
       
  1192 
       
  1193     List<AST*> *children = node->children();
       
  1194     if(children) {
       
  1195         NameUse *nameUse = 0;
       
  1196         foreach(AST* child , *children) {
       
  1197             nameUse = findNameUse(child);
       
  1198             if(nameUse)
       
  1199                 break;
       
  1200         }
       
  1201         if (nameUse)
       
  1202             return nameUse;
       
  1203     }
       
  1204 
       
  1205     for (int t = node->startToken(); t < node->endToken(); ++t) {
       
  1206  //       cout << t <<" |" <<m_tokenStream->tokenText(t).constData() << "|" << endl;
       
  1207         if (m_nameUses.contains(t))
       
  1208             return m_nameUses.value(t);
       
  1209     }
       
  1210     return 0;
       
  1211 }
       
  1212 
       
  1213 /*
       
  1214     Gets a TokenRef from an AST node.
       
  1215     Assumes that the node only covers one token, which means that
       
  1216     node->statToken() == node->endToken(). If this is not the case
       
  1217     then the TokenRef will reference the token at startToken.
       
  1218 */
       
  1219 TokenEngine::TokenRef Semantic::tokenRefFromAST(AST *node)
       
  1220 {
       
  1221     const int startTokenIndex = node->startToken();
       
  1222     const TokenEngine::TokenContainer tokenContainer = m_tokenStream->tokenContainer(startTokenIndex);
       
  1223     const int containerIndex = m_tokenStream->containerIndex(startTokenIndex);
       
  1224     return TokenEngine::TokenRef(tokenContainer, containerIndex);
       
  1225 }
       
  1226 
       
  1227 QT_END_NAMESPACE