/****************************************************************************
**
** Copyright (C) 2001-2004 Roberto Raggi
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the qt3to4 porting application of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "smallobject.h"
#include "tokenengine.h"
#include "semantic.h"
#include <QtDebug>
#include <QString>
#include <QRegExp>

QT_BEGIN_NAMESPACE

using namespace TokenStreamAdapter;
using namespace TokenEngine;
using namespace CodeModel;

Semantic::Semantic(CodeModel::NamespaceScope *globalScope,
                   TokenStreamAdapter::TokenStream *tokenStream,
                   TypedPool<CodeModel::Item> *storage)
{
    m_storage = storage;
    m_tokenStream = tokenStream;

    m_currentAccess = CodeModel::Member::Public;
    m_inSlots = false;
    m_inSignals = false;
    m_inStorageSpec = false;
    m_inTypedef = false;

    globalScope->setName("::");
    currentScope.push(globalScope);

    //create global UnknownType and UnknownTypeMember
    UnknownType *type = Create<UnknownType>(m_storage);
    type->setName("__UnknownType");
    globalScope->addType(type);
    type->setParent(globalScope);

    m_sharedUnknownMember = Create<TypeMember>(m_storage);
    m_sharedUnknownMember->setNameToken(TokenRef());
    m_sharedUnknownMember->setName("Unknown");
    m_sharedUnknownMember->setType(type);
    globalScope->addMember(m_sharedUnknownMember);
    m_sharedUnknownMember->setParent(globalScope);

}

void Semantic::parseAST(TranslationUnitAST *node)
{
    TreeWalker::parseTranslationUnit(node);
}


void Semantic::parseLinkageSpecification(LinkageSpecificationAST *ast)
{
    if(!ast)
        return;
    int inStorageSpec = m_inStorageSpec;
    m_inStorageSpec = true;
    TreeWalker::parseLinkageSpecification(ast);
    m_inStorageSpec = inStorageSpec;
}

void Semantic::parseNamespace(NamespaceAST *ast)
{
    CodeModel::NamespaceScope *parent = currentScope.top()->toNamespaceScope();
    if(!parent->toNamespaceScope()) {
        emit error("Error in Semantic::parseNamespace: parent scope was not a namespace");
        return;
    }

    QByteArray nsName;
    if (!ast->namespaceName() || textOf(ast->namespaceName()).isEmpty()){
        nsName = "(__QT_ANON_NAMESPACE)";
    } else {
        nsName = textOf(ast->namespaceName());
    }

    CodeModel::NamespaceScope *namespaceScope = 0;

    // Look up namespace scope in case it is already defined.
    // (Unlike classes, C++ namespaces are "open" and can be added to.)
    CodeModel::Scope *scope = parent->scopes().value(nsName);
    if (scope)
        namespaceScope = scope->toNamespaceScope();

    // Create new namespace if not found.
    if (!namespaceScope) {
        namespaceScope = CodeModel::Create<CodeModel::NamespaceScope>(m_storage);
        namespaceScope->setName(nsName);
        parent->addScope(namespaceScope);

        NamespaceMember *namespaceMember = Create<NamespaceMember>(m_storage);
        namespaceMember->setNameToken(tokenRefFromAST(ast->namespaceName()));
        namespaceMember->setName(nsName);
        namespaceMember->setNamespaceScope(namespaceScope);
        currentScope.top()->addMember(namespaceMember);
        namespaceMember->setParent(currentScope.top());
    }

    currentScope.push(namespaceScope);
    TreeWalker::parseNamespace(ast);
    currentScope.pop();
}

void Semantic::parseClassSpecifier(ClassSpecifierAST *ast)
{
    if (!ast->name()){
        return;
    }

    QByteArray kind = textOf(ast->classKey());
    if (kind == "class")
        m_currentAccess = CodeModel::Member::Private;
    else // kind =="struct"
        m_currentAccess = CodeModel::Member::Public;

    QByteArray className = textOf(ast->name()->unqualifiedName());

    //create ClassScope
    CodeModel::ClassScope *klass = CodeModel::Create<CodeModel::ClassScope>(m_storage);
    klass->setName(className);
    currentScope.top()->addScope(klass);

    //create ClassType
    CodeModel::ClassType *type = CodeModel::Create<CodeModel::ClassType>(m_storage);
    type->setScope(klass);
    currentScope.top()->addType(type);
    type->setParent(currentScope.top());

    //create TypeMember
    CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
    typeMember->setNameToken(tokenRefFromAST(ast->name()->unqualifiedName()));
    typeMember->setName(className);
    typeMember->setType(type);
    currentScope.top()->addMember(typeMember);
    typeMember->setParent(currentScope.top());

    currentScope.push(klass);
    if (ast->baseClause())
        parseBaseClause(ast->baseClause(), klass);

    //TreeWalker::parseClassSpecifier(ast);
    parseNode(ast->winDeclSpec());
    parseNode(ast->classKey());
    parseNode(ast->baseClause());

    // Here's the trick for parsing c++ classes:
    // All inline function definitions must be interpreted as if they were
    // written after any other declarations in the class.
    QList<DeclarationAST *> functionDefinitions;
    if (ast->declarationList())
        foreach(DeclarationAST *decl, *ast->declarationList()) {
            if(decl->nodeType() == NodeType_FunctionDefinition)
                functionDefinitions.append(decl);
            else
            parseNode(decl);
        }
    foreach(DeclarationAST *decl, functionDefinitions)
        parseNode(decl);

    currentScope.pop();
}
/*
    Parse a class, struct or enum forward decalration.
*/
void Semantic::parseElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *node)
{
    if (!node)
        return;
    AST *kind = node->kind();
    if (!kind)
        return;

    const QByteArray kindText = textOf(kind);
    const QByteArray nameText = textOf(node->name());

    // Don't do anything if the class, struct or enum has already been declared or defined.
    if (lookupNameInScope(currentScope.top(), node->name()).count() > 0)
        return;

    if (kindText == "class" || kindText == "struct") {
        // Create ClassType.
        CodeModel::ClassType *type = CodeModel::Create<CodeModel::ClassType>(m_storage);
        type->setScope(0);
        currentScope.top()->addType(type);
        type->setParent(currentScope.top());

        // Create TypeMember.
        CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
        typeMember->setNameToken(tokenRefFromAST(node->name()->unqualifiedName()));
        typeMember->setName(nameText);
        typeMember->setType(type);
        currentScope.top()->addMember(typeMember);
        typeMember->setParent(currentScope.top());
    } else if (kindText == "enum") {
        //create a Type
        CodeModel::EnumType *enumType = CodeModel::Create<CodeModel::EnumType>(m_storage);
        enumType->setName(nameText);
        currentScope.top()->addType(enumType);
        enumType->setParent(currentScope.top());

        //create a TypeMember
        CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
        if(node->name())
            typeMember->setNameToken(tokenRefFromAST(node->name()->unqualifiedName()));
        typeMember->setName(nameText);
        typeMember->setType(enumType);
        currentScope.top()->addMember(typeMember);
        typeMember->setParent(currentScope.top());
    }
}

void Semantic::parseSimpleDeclaration(SimpleDeclarationAST *ast)
{
    TypeSpecifierAST *typeSpec = ast->typeSpec();
    InitDeclaratorListAST *declarators = ast->initDeclaratorList();

    if (typeSpec)
        parseTypeSpecifier(typeSpec);

    if (declarators){
        List<InitDeclaratorAST*> l = *declarators->initDeclaratorList();

        foreach (InitDeclaratorAST *current, l) {
            parseDeclaration(ast->functionSpecifier(), ast->storageSpecifier(), typeSpec, current);
        }
    }
}

void Semantic::parseDeclaration(AST *funSpec, AST *storageSpec, TypeSpecifierAST *typeSpec, InitDeclaratorAST *decl)
{
    if (m_inStorageSpec)
            return;

    if(!decl)
        return;

    DeclaratorAST *d = decl->declarator();
    if (!d)
        return;

    if (!d->subDeclarator() && d->parameterDeclarationClause()) {
        parseFunctionDeclaration(funSpec, storageSpec, typeSpec, decl);
		return;
	}
    if(!typeSpec || !typeSpec->name())
        return;

    DeclaratorAST *t = d;
    while (t && t->subDeclarator())
        t = t->subDeclarator();

    QByteArray id;
    if (t && t->declaratorId() && t->declaratorId()->unqualifiedName())
        id = textOf(t->declaratorId()->unqualifiedName());

    if (!t || !t->declaratorId() || !t->declaratorId()->unqualifiedName())
        return;
    AST *nameAST = t->declaratorId()->unqualifiedName();
    QByteArray name = textOf(nameAST);


    if (!scopeOfDeclarator(d, QList<QByteArray>()).isEmpty()){
        return;
    }

    //Check if this is possibly a function call by searching for '(' and ')'
    const QByteArray declText = textOf(decl);
    if (declText.contains("(") && declText.contains(")")) {
	if (decl->declarator() && decl->declarator()->subDeclarator()) {

        NameAST * name = decl->declarator()->subDeclarator()->declaratorId();
	if (name)
            parseNameUse(name);
	    return;	
        } 
    }

    //create VariableMember
    CodeModel::VariableMember *variableMember = CodeModel::Create<CodeModel::VariableMember>(m_storage);
    variableMember->setNameToken(tokenRefFromAST(nameAST));
    variableMember->setName(name);
    variableMember->setAccess(m_currentAccess);
    variableMember->setParent(currentScope.top());
    currentScope.top()->addMember(variableMember);

    //look up type of variableMember,

    TypeMember *typeMember = typeLookup(currentScope.top(), typeSpec->name());
    if(typeMember) {
        variableMember->setType(typeMember->type());
    } else {
        QByteArray text = typeOfDeclaration(typeSpec, d);
        CodeModel::UnknownType *type = CodeModel::Create<CodeModel::UnknownType>(m_storage);
        type->setName(text);
        variableMember->setType(type);
    }

    if (decl)
        parseNode(decl->initializer());

}

void Semantic::parseFunctionDeclaration(AST *funSpec, AST *storageSpec,
                                        TypeSpecifierAST * typeSpec, InitDeclaratorAST * initDeclarator)
{
    bool isFriend = false;
    bool isVirtual = false;
    bool isStatic = false;
    bool isInline = false;
    bool isPure = initDeclarator->initializer() != 0;

    if (funSpec){
        List<AST*> l = *funSpec->children();
        foreach (AST *current, l) {
            QByteArray text = textOf(current);
            if (text == "virtual") isVirtual = true;
            else if (text == "inline") isInline = true;
        }
    }

    if (storageSpec){
        List<AST*> l = *storageSpec->children();
        foreach (AST *current, l) {
            QByteArray text = textOf(current);
            if (text == "friend") isFriend = true;
            else if (text == "static") isStatic = true;
        }
    }
    DeclaratorAST *declarator = initDeclarator->declarator();
    if(!declarator || !declarator->declaratorId())
        return;
    AST *nameAST = declarator->declaratorId()->unqualifiedName();
    QByteArray name = textOf(nameAST);

    CodeModel::FunctionMember *method = CodeModel::Create<CodeModel::FunctionMember>(m_storage);
    method->setNameToken(tokenRefFromAST(nameAST));
    method->setName(name);
    method->setAccess(m_currentAccess);
    method->setStatic(isStatic);
    method->setVirtual(isVirtual);
    method->setAbstract(isPure);

    parseFunctionArguments(declarator, method);

    if (m_inSignals)
        method->setSignal(true);

    if (m_inSlots)
        method->setSlot(true);

    method->setConstant(declarator->constant() != 0);

    QByteArray text = typeOfDeclaration(typeSpec, declarator);
    if (!text.isEmpty()) {
        CodeModel::UnknownType *type = CodeModel::Create<CodeModel::UnknownType>(m_storage);
        type->setName(text);
        method->setReturnType(type);
    }

    method->setParent(currentScope.top());
    currentScope.top()->addMember(method);
}


void Semantic::parseBaseClause(BaseClauseAST * baseClause, CodeModel::ClassScope *klass)
{
    if(!baseClause)
        return;
    if(!klass)
        return;
    List<BaseSpecifierAST*> *l = baseClause->baseSpecifierList();
    if (!l)
        return;
    foreach (BaseSpecifierAST *baseSpecifier, *l) {
        QByteArray baseName;
        if (!baseSpecifier->name())
            continue;

        // Look up a class with the correct name.
        QList<Member *> candidates = nameLookup(klass, baseSpecifier->name());
        if (candidates.count() == 1 ) {
            Member *member = candidates.at(0);
            Q_ASSERT(member);
            TypeMember *typeMember = member->toTypeMember();
            if (typeMember) {
                Q_ASSERT(typeMember->type());
                ClassType *classType = typeMember->type()->toClassType();
                if (classType) {
                    klass->addBaseClass(classType);
                }
            }
        }
    }
}
void Semantic::parseFunctionArguments(const DeclaratorAST *declarator, CodeModel::FunctionMember *method)
{
    if(!declarator || !method)
        return;

    ParameterDeclarationClauseAST *clause = declarator->parameterDeclarationClause();

    if (clause && clause->parameterDeclarationList()){
        ParameterDeclarationListAST *params = clause->parameterDeclarationList();
        List<ParameterDeclarationAST*> *l = params->parameterList();
        if (!l)
            return;
        foreach (ParameterDeclarationAST *param, *l) {
            CodeModel::Argument *arg = CodeModel::Create<CodeModel::Argument>(m_storage);
            arg->setParent(method);

            if (param->declarator()){
                QByteArray text = declaratorToString(param->declarator(), QByteArray(), true);
                if(param->declarator()->declaratorId())
                    arg->setNameToken(tokenRefFromAST(param->declarator()->declaratorId()->unqualifiedName()));
                if (!text.isEmpty())
                    arg->setName(text);
            }

            QByteArray tp = typeOfDeclaration(param->typeSpec(), param->declarator());
            if (!tp.isEmpty()) {
                CodeModel::UnknownType *type = CodeModel::Create<CodeModel::UnknownType>(m_storage);
                type->setName(tp);
                arg->setType(type);
            }

            method->addArgument(arg);
        }
    }
}

// using directive (using namespace A)
void Semantic::parseUsingDirective(UsingDirectiveAST *ast)
{
    QByteArray qualifiedname = textOf(ast->name());
    QByteArray name = textOf(ast->name()->unqualifiedName());

    //look up target namespace name
    QList<Member *> memberList = nameLookup(currentScope.top(), ast->name());

    NamespaceScope *targetNamespace = 0;

    // search for namespace in member list.
    QList<Member *>::ConstIterator it = memberList.constBegin();
    while(it != memberList.constEnd()) {
        if (NamespaceMember *namespaceMember = (*it)->toNamespaceMember()) {
            targetNamespace = namespaceMember->namespaceScope();
            break;
        }
        ++it;
    }

    if (targetNamespace == 0)
        return;

    // Find the insertion namespace, which is the first common
    // ancesotor namespace for the current scope and the target namespace

    // currentScope might be a block scope, find its first namespace parent
    CodeModel::Scope *currentParent = currentScope.top();
    while (currentParent->toNamespaceScope() == 0) {
        currentParent = currentParent->parent();
    }

    CodeModel::Scope *namespaceA = currentParent;
    while (namespaceA != 0) {
        CodeModel::Scope *namespaceB = targetNamespace;
        while (namespaceB != 0) {
            if (namespaceB == namespaceA)
                break;
            namespaceB = namespaceB->parent();
        }
        if (namespaceB == namespaceA)
            break;
        namespaceA = namespaceA->parent();
    }

    if (namespaceA == 0 || namespaceA->toNamespaceScope() == 0)
        return;

    NamespaceScope *insertionNamespace = namespaceA->toNamespaceScope();

    // Create using directive link
    UsingDirectiveLink *usingDirectiveLink = Create<UsingDirectiveLink>(m_storage);
    usingDirectiveLink->setParent(currentScope.top());
    usingDirectiveLink->setTargetNamespace(targetNamespace);
    usingDirectiveLink->setInsertionNamespace(insertionNamespace);

    // add it to current namespace
    if (NamespaceScope *namespaceScope = currentScope.top()->toNamespaceScope())
        namespaceScope->addUsingDirectiveLink(usingDirectiveLink);
    else if (BlockScope *blockScope = currentScope.top()->toBlockScope())
        blockScope->addUsingDirectiveLink(usingDirectiveLink);
}

void Semantic::parseFunctionDefinition(FunctionDefinitionAST *ast)
{
    AST *funSpec = ast->functionSpecifier();
    AST *storageSpec = ast->storageSpecifier();
    TypeSpecifierAST *typeSpec = ast->typeSpec();
    InitDeclaratorAST *initDeclarator = ast->initDeclarator();
    if (!ast->initDeclarator())
        return;

    DeclaratorAST *d = initDeclarator->declarator();

    if (!d->declaratorId())
        return;

    parseFunctionDeclaration(funSpec, storageSpec, typeSpec, initDeclarator);
    CodeModel::FunctionMember *method = functionLookup(currentScope.top(), d);

    if(!method) {
        emit error("Error in Semantic::parseFunctionDefinition: Could not find declaration for function definition");
        return;
    }

    CodeModel::Scope *parent = method->parent();

    if(!ast->functionBody()) {
        emit error("Error in Semantic::parseFunctionDefinition: no function body in function definition");
        return;
    }

    //create child function scope
    QByteArray id = textOf(d->declaratorId()->unqualifiedName());
    CodeModel::BlockScope *functionScope = CodeModel::Create<CodeModel::BlockScope>(m_storage);
    functionScope->setName(QByteArray("__QT_ANON_BLOCK_SCOPE(Function: ") + id + QByteArray(")"));
    functionScope->setParent(parent);
    method->setFunctionBodyScope(functionScope);

    //add arguments to child scope
     ArgumentCollection arguments = method->arguments();
     ArgumentCollection::ConstIterator it = arguments.constBegin();
     while(it != arguments.constEnd()) {
         CodeModel::Argument *argument = *it;
         CodeModel::VariableMember *variableMember = CodeModel::Create<CodeModel::VariableMember>(m_storage);
         variableMember->setNameToken(argument->nameToken());
         variableMember->setType(argument->type());
         variableMember->setName(argument->name());
         variableMember->setParent(functionScope);
         functionScope->addMember(variableMember);
         ++it;
     }

    //push function scope and parse function body
    currentScope.push(functionScope);
    parseStatementList(ast->functionBody());
    currentScope.pop();
}

void Semantic::parseStatementList(StatementListAST *statemenList)
{
    if(!statemenList)
        return;
    CodeModel::BlockScope *blockScope = CodeModel::Create<CodeModel::BlockScope>(m_storage);
    blockScope->setName("__QT_ANON_BLOCK_SCOPE");
    blockScope->setParent(currentScope.top());
    currentScope.top()->addScope(blockScope);

    currentScope.push(blockScope);
    TreeWalker::parseStatementList(statemenList);
    currentScope.pop();
}

void Semantic::parseExpression(AbstractExpressionAST* node)
{
    if(!node)
        return;
    if(node->nodeType() == NodeType_ClassMemberAccess)
        parseClassMemberAccess(static_cast<ClassMemberAccessAST *>(node));
    else
        TreeWalker::parseExpression(node);
}

/*
    Pretty hardwired code for handling class member access of the types:
    object.member and objectPtr->member.

    This function creates a name use for object to its declaration, and a
    name use from member to its declaration in the class.
*/
void Semantic::parseClassMemberAccess(ClassMemberAccessAST *node)
{
    if(!node)
        return;
    parseExpression(node->expression());
    // Get a name use for the 'object' name.
    NameUse *nameUse = findNameUse(node->expression());
    // Since the NameUse refers to an object, its decalaration must be
    // a ClassType. Get the scope of this class type.
    if(    nameUse
        && nameUse->declaration()
        && nameUse->declaration()->toVariableMember()
        && nameUse->declaration()->toVariableMember()->type()
        && nameUse->declaration()->toVariableMember()->type()->toClassType()
        && nameUse->declaration()->toVariableMember()->type()->toClassType()->scope())   {

        CodeModel::Scope *scope = nameUse->declaration()->toVariableMember()->type()->toClassType()->scope();
        QList<CodeModel::Member *> members = lookupNameInScope(scope, node->name());
            if(members.count() != 0) {
                createNameUse(members.at(0), node->name());
                return;
            }
    }
    // Create a NameUse that refers to the global shared unknown type.
    createNameUse(m_sharedUnknownMember, node->name());
}

void Semantic::parseExpressionStatement(ExpressionStatementAST *node)
{
    TreeWalker::parseExpressionStatement(node);
}

// using declaration (using A::b)
void Semantic::parseUsing(UsingAST *ast)
{
    //CodeModel::Scope *s = lookUpScope(currentScope.top(), ast->name());
    QList<CodeModel::Member *> members = nameLookup(currentScope.top(), ast->name());
    if(members.isEmpty()) {
        emit error("Error in Semantic::parseUsing: could not look up using target");
        return;
    }
    //TODO: handle multiple members (when nameLookup returns a set of overloded functions)
    CodeModel::Member *member = members[0];
    CodeModel::Scope *targetScope = member->parent();
    if(!targetScope) {
        emit error("Error in Semantic::parseUsing: target has no parent scope");
        return;
    }

    if(!ast->name())
        return;
    AST *nameAST = ast->name()->unqualifiedName();
    if(!nameAST)
        return;
    QByteArray name = textOf(nameAST);
}

void Semantic::parseEnumSpecifier(EnumSpecifierAST *ast)
{
    if (!ast->name())
         return;

    QByteArray name = textOf(ast->name());

    //create a Type
    CodeModel::EnumType *enumType = CodeModel::Create<CodeModel::EnumType>(m_storage);
    enumType->setName(name);
    currentScope.top()->addType(enumType);
    enumType->setParent(currentScope.top());

    //create a TypeMember
    CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
    if(ast->name())
        typeMember->setNameToken(tokenRefFromAST(ast->name()->unqualifiedName()));
    typeMember->setName(name);
    typeMember->setType(enumType);
    currentScope.top()->addMember(typeMember);
    typeMember->setParent(currentScope.top());

    //parse the eneumerators
    List<EnumeratorAST*> *list = ast->enumeratorList();
    if (!list)
        return;
    foreach (EnumeratorAST *current, *list) {
        CodeModel::VariableMember *enumerator = CodeModel::Create<CodeModel::VariableMember>(m_storage);
        enumerator->setNameToken(tokenRefFromAST(current->id()));
        enumerator->setName(textOf(current->id()));
        enumerator->setAccess(m_currentAccess);
        enumerator->setStatic(true);
        enumerator->setType(enumType);
        currentScope.top()->addMember(enumerator);
        enumerator->setParent(currentScope.top());
    }

}

void Semantic::parseTypedef(TypedefAST *ast)
{
    TypeSpecifierAST *typeSpec = ast->typeSpec();
    InitDeclaratorListAST *declarators = ast->initDeclaratorList();

    if (typeSpec && declarators){
        QByteArray typeId;

        if (typeSpec->name())
            typeId = textOf(typeSpec->name());

        List<InitDeclaratorAST*> *l = declarators->initDeclaratorList();
        if (!l)
            return;
        foreach (InitDeclaratorAST *initDecl, *l) {
            QByteArray type, id;
            if (initDecl->declarator()){
               type = typeOfDeclaration(typeSpec, initDecl->declarator());

               DeclaratorAST *d = initDecl->declarator();
               while (d->subDeclarator()){
                   d = d->subDeclarator();
               }

               if (d->declaratorId())
                  id = textOf(d->declaratorId());
            }

            //create a type
            CodeModel::Scope *scope = currentScope.top();
            CodeModel::AliasType *typeAlias = CodeModel::Create<CodeModel::AliasType>(m_storage);
            //typeAlias->setName(id);
            //typeAlias->setParent(scope);
            scope->addType(typeAlias);

            //create a TypeMember
            CodeModel::TypeMember *typeMember = CodeModel::Create<CodeModel::TypeMember>(m_storage);
            if(typeSpec->name())
                typeMember->setNameToken(tokenRefFromAST(typeSpec->name()->unqualifiedName()));
            typeMember->setName(id);
            typeMember->setType(typeAlias);
            currentScope.top()->addMember(typeMember);
            typeMember->setParent(currentScope.top());

        }

    }
}

void Semantic::parseTypeSpecifier(TypeSpecifierAST *ast)
{
    // If this is a classSpecifier or a EnumSpecifier we skip the name lookup,
    // because looking up the name "E" in a class definition like
    // "class E { ..." makes no sense. (There might be a variable named E
    // already declared, but that variable is now shadowed by the class type.)
    if(   ast->nodeType() != NodeType_EnumSpecifier
       && ast->nodeType() != NodeType_ClassSpecifier
       && ast->nodeType() != NodeType_ElaboratedTypeSpecifier )
        parseNameUse(ast->name());
    TreeWalker::parseTypeSpecifier(ast);
}

/*
    Parses a name: looks up name, creates name use.
*/
void Semantic::parseNameUse(NameAST* name)
{
    if(!name)
        return;

    // Look up name
    QList<CodeModel::Member *> members = nameLookup(currentScope.top(), name);
    if(members.isEmpty()) {
        //cout << "no declaration found for " << textOf(name).constData() << endl;
        // Create NameUse that refer to a shared UnknownMember
        createNameUse(m_sharedUnknownMember, name);
        return;
    }

    //TODO: handle multiple members (when nameLookup returns a set of overloaded functions)
    CodeModel::Member *member = members[0];
    if(!member->parent()) {
        emit error("Error in Semantic::parseUsing: target has no parent scope");
        return;
    }

    createNameUse(member, name);
}

/*
    Looks up name used in basescope. If name->isGlobal() is true or if classOrNamespaceList()
    returns a non-empty list, the C++ qualified name lookup rules are used. Otherwise the
    unquialified name lookup rules are used.  Returns the a list of members that was found,
    In most cases this list will contain zero or one element, except in the case of overloaded functions.
    TODO: Argument-dependent name lookup
*/
QList<CodeModel::Member *> Semantic::nameLookup(CodeModel::Scope *baseScope, const NameAST* name)
{
    if (name->isGlobal() || (name->classOrNamespaceNameList()
                              && name->classOrNamespaceNameList()->size()>0 )) {
        return qualifiedNameLookup(baseScope, name);
    } else {
        return unqualifiedNameLookup(baseScope, name);
    }
}

//look up an unqualified name
QList<CodeModel::Member *> Semantic::unqualifiedNameLookup(CodeModel::Scope *baseScope, const NameAST* name)
{
    QList<UsingDirectiveLink *> usingDirectiveLinks;
    CodeModel::Scope *currentScope = baseScope;
    QList<CodeModel::Member *>  entities;

    while (currentScope != 0) {
        // Add any "using namespace" directive links for the current scope to
        // usingDirectiveLinks
        if (NamespaceScope *namespaceScope = currentScope->toNamespaceScope())
            usingDirectiveLinks += namespaceScope->usingDirectiveLinks();
        if (BlockScope *blockScope = currentScope->toBlockScope())
            usingDirectiveLinks += blockScope->usingDirectiveLinks();

        // Search usingDirectiveLinks for a link where currentScope is the
        // insertion namespace. If found look up name in the target namespace
        // for that link.
        if (NamespaceScope *namespaceScope = currentScope->toNamespaceScope()) {
            QList<UsingDirectiveLink *>::ConstIterator it = usingDirectiveLinks.constBegin();
            while (it != usingDirectiveLinks.constEnd()) {
                if ((*it)->insertionNamespace() == namespaceScope)
                    entities = lookupNameInScope((*it)->targetNamespace(), name);
                ++it;
            }
        }

        // Look up names in this scope.
        entities += lookupNameInScope(currentScope, name);
        if (!entities.isEmpty())
            break;
        currentScope = currentScope->parent();
    }
    return entities;
}

//look up a qualified name
QList<CodeModel::Member *> Semantic::qualifiedNameLookup(CodeModel::Scope *baseScope, const NameAST* name)
{
    QList<CodeModel::Member *> entities;
    CodeModel::Scope *currentScope = baseScope;

    // Check if the global ("::") scope has been specified.
    if(name->isGlobal()) {
        while (currentScope->parent())
            currentScope = currentScope->parent();
    }

    while (entities.isEmpty() && currentScope != 0) {
        CodeModel::Scope *targetScope = scopeLookup(currentScope, name);
        entities = lookupNameInScope(targetScope, name);
        currentScope = currentScope->parent();
    }

    return entities;
}

//looks up a name in a scope, includes base classes if scope is a class scope
QList<CodeModel::Member *> Semantic::lookupNameInScope(CodeModel::Scope *scope, const NameAST* name)
{
    QList<CodeModel::Member *> entities;

    if(!scope || !name)
        return entities;

    QByteArray nameText = textOf(name->unqualifiedName()->name());
    //look up name in members of current scope
    const CodeModel::MemberCollection members = scope->members();
    if (members.contains(nameText))
        entities.append(members.value(nameText));

    // if not found, look up name in  base classes (if any)
    CodeModel::ClassScope *classScope = scope->toClassScope();
    if (entities.isEmpty() && classScope) {
        const TypeCollection baseClasses = classScope->baseClasses();
        TypeCollection::ConstIterator it = baseClasses.constBegin();
        while (it != baseClasses.constEnd()) {
            CodeModel::Scope *baseClass = it.value()->toClassType()->scope();
            if (scope != baseClass)
                entities += lookupNameInScope(baseClass, name);
            ++it;
        }

        if (entities.count() > 1)
            emit error("Error in Semantic::lookupNameInScope: name "
            + nameText + " is ambigous");
    }
    return entities;
}

/*
    Resolves the classOrNamespaceNameList part of a NameAST against a base scope.
*/
CodeModel::Scope *Semantic::scopeLookup(CodeModel::Scope *baseScope, const NameAST* name)
{
    CodeModel::Scope *currentScope = baseScope;
    const List<ClassOrNamespaceNameAST *> *scopeList = name->classOrNamespaceNameList();
    // if there is no scope list, then the scope we are looking for is baseScope
    if (!scopeList)
        return baseScope;

    // Check if the global ("::") scope has been specified.
    if(name->isGlobal()) {
        while (currentScope->parent())
            currentScope = currentScope->parent();
    }

    while(currentScope != 0) {
        int nestingCounter = 0;
        CodeModel::Scope *nestedScope = currentScope;
        while (nestingCounter < scopeList->count()) {
            const QByteArray nameText = textOf((*scopeList)[nestingCounter]->name());
            nestedScope = nestedScope->scopes().value(nameText);
            if (!nestedScope)
                break;
            ++nestingCounter;
        }
        if(nestedScope) // found target scope?
            return nestedScope;

        currentScope = currentScope->parent(); //look in parent scope
    }

    return 0;
}

TypeMember *Semantic::typeLookup(CodeModel::Scope *baseScope, const NameAST* name)
{
    QList<CodeModel::Member *> memberList = nameLookup(baseScope, name);

    foreach(Member *member, memberList) {
        if(TypeMember *typeMember = member->toTypeMember())
            return typeMember;
    }
    return 0;
}

FunctionMember *Semantic::functionLookup(CodeModel::Scope *baseScope,
                                          const DeclaratorAST *functionDeclarator)
{

    QList<CodeModel::Member*> candidateList =
                nameLookup(baseScope, functionDeclarator->declaratorId());
    return selectFunction(candidateList, functionDeclarator);
}

/*
    This is a simplified function lookup routine, for matching member function
    definitions with member function declarations. It does not implement
    the general C++ function overload resolution rules.
*/
FunctionMember *Semantic::selectFunction(QList<CodeModel::Member*> candidatateList, const DeclaratorAST *functionDeclarator)
{
    // get arguments for function we are looking for
    FunctionMember testFunction;
    parseFunctionArguments(functionDeclarator, &testFunction);
    const ArgumentCollection testArgumentCollection = testFunction.arguments();

    //test againts functions in overload list.
    foreach(Member* member, candidatateList) {
        FunctionMember *function = member->toFunctionMember();
        if (!function)
            continue;
        const ArgumentCollection argumentCollection = function->arguments();

        //test argument types and number of arguments
        ArgumentCollection::ConstIterator arg1 = argumentCollection.constBegin();
        ArgumentCollection::ConstIterator arg2 = testArgumentCollection.constBegin();
        bool match = true;
        while(arg1 != argumentCollection.constEnd() && arg2 != testArgumentCollection.constEnd()) {
            if( arg1.value()->type()->name() != arg2.value()->type()->name() ) {
                match = false;
                break;
            }
            ++arg1;
            ++arg2;
        }
        if(match)
            return function;
    }
    return 0;
}

QByteArray Semantic::typeOfDeclaration(TypeSpecifierAST *typeSpec, DeclaratorAST *declarator)
{
    if (!typeSpec)
        return QByteArray();

    QByteArray text;

    if (typeSpec->cvQualify()) {
        List<AST*> cv = *typeSpec->cvQualify()->children();
        foreach (AST *current, cv) {
            text += " " + textOf(current);
        }
        text += " ";
    }


    text += textOf(typeSpec);

    if (typeSpec->cv2Qualify()) {
        List<AST*> cv = *typeSpec->cv2Qualify()->children();
        foreach (AST *current, cv) {
            text += textOf(current) + " ";
        }
    }

    if (declarator && declarator->ptrOpList()) {
        List<AST*> ptrOpList = *declarator->ptrOpList();
        foreach (AST *current, ptrOpList) {
            text += " " + textOf(current);
        }
        text += " ";
    }

    return text.trimmed().simplified();
}



QList<QByteArray> Semantic::scopeOfName(NameAST *id, const QList<QByteArray>& startScope)
{
    QList<QByteArray> scope = startScope;
    if (id && id->classOrNamespaceNameList()){
        if (id->isGlobal())
            scope.clear();

        List<ClassOrNamespaceNameAST*> l = *id->classOrNamespaceNameList();
        foreach (ClassOrNamespaceNameAST *current, l) {
            if (current->name())
               scope << textOf(current->name());
        }
    }

    return scope;
}

QList<QByteArray> Semantic::scopeOfDeclarator(DeclaratorAST *d, const QList<QByteArray>& startScope)
{
    if(!d)
        return QList<QByteArray>();
    return scopeOfName(d->declaratorId(), startScope);
}

QByteArray Semantic::typeSpecToString(TypeSpecifierAST* typeSpec)
{
    if (!typeSpec)
        return QByteArray();

    QByteArray tp;
    if (typeSpec->cvQualify()) {
        tp += "const ";
    }

    tp += (QString::fromLatin1(textOf(typeSpec)).replace(QRegExp(QLatin1String(" :: ")), QString::fromUtf8("::"))).toLatin1();
    return tp;
}

QByteArray Semantic::declaratorToString(DeclaratorAST* declarator, const QByteArray& scope, bool skipPtrOp)
{
    if (!declarator)
        return QByteArray();

    QByteArray text;

    if (!skipPtrOp && declarator->ptrOpList()){
        List<AST*> ptrOpList = *declarator->ptrOpList();
        foreach (AST *current, ptrOpList) {
            text += textOf(current);
        }
        text += QByteArray(" ");
    }

    text += scope;

    if (declarator->subDeclarator())
        text += QByteArray("(") + declaratorToString(declarator->subDeclarator()) + QByteArray(")");

    if (declarator->declaratorId())
        text += textOf(declarator->declaratorId());

    if (declarator->arrayDimensionList()) {
        List<AST*> arrays = *declarator->arrayDimensionList();
        foreach (AST *current, arrays) {
            current=current;    //silence unused symbol warning
            text += QByteArray("[]");
        }
    }

    if (declarator->parameterDeclarationClause()){
        text += QByteArray("(");

        ParameterDeclarationListAST* l = declarator->parameterDeclarationClause()->parameterDeclarationList();
        if (l != 0){
            List<ParameterDeclarationAST*> params = *l->parameterList();
            foreach (ParameterDeclarationAST *current, params) {
                QByteArray type = typeSpecToString(current->typeSpec());
                text += type;
                if (!type.isEmpty())
                    text += QByteArray(" ");
                text += declaratorToString(current->declarator());

                // ### FIXME if (it.current())
                    text += QByteArray(", ");
            }
        }

        text += QByteArray(")");

        if (declarator->constant() != 0)
            text += QByteArray(" const");
    }

    return QString::fromLatin1(text).replace(QRegExp(QLatin1String(" :: ")), QLatin1String("::")).simplified().toLatin1();
}

QByteArray Semantic::textOf(const AST *node) const
{
    if (!node)
        return QByteArray();
    QByteArray text;
    for (int i = node->startToken(); i < node->endToken(); ++i) {
        if (!m_tokenStream->isHidden(i)) {
            if (i != node->startToken())
                text += QByteArray(" ");
            text += m_tokenStream->tokenText(i);
        }
    }
    return text;
}

void Semantic::createNameUse(Member *member, NameAST *name)
{
    if (!name)
       return;

    AST *unqualifedName = name->unqualifiedName()->name();

    if(!unqualifedName || !member)
        return;

    CodeModel::NameUse *nameUse = CodeModel::Create<CodeModel::NameUse>(m_storage);
    nameUse->setParent(currentScope.top());
    nameUse->setNameToken(tokenRefFromAST(unqualifedName));
    nameUse->setName(textOf(unqualifedName));
    nameUse->setDeclaration(member);

    currentScope.top()->addNameUse(nameUse);
    addNameUse(unqualifedName, nameUse);
}

void Semantic::addNameUse(AST *node, NameUse *nameUse)
{
    const int tokenIndex = node->startToken();
    m_nameUses.insert(tokenIndex, nameUse);
}

/*
    Searches a AST node and all its children for a nameUse. The name use is
    found by looking up each node's tokens in the m_nameUses map. A depth-first
    search is used.
*/
NameUse *Semantic::findNameUse(AST *node)
{
    if(!node)
        return 0;

    List<AST*> *children = node->children();
    if(children) {
        NameUse *nameUse = 0;
        foreach(AST* child , *children) {
            nameUse = findNameUse(child);
            if(nameUse)
                break;
        }
        if (nameUse)
            return nameUse;
    }

    for (int t = node->startToken(); t < node->endToken(); ++t) {
 //       cout << t <<" |" <<m_tokenStream->tokenText(t).constData() << "|" << endl;
        if (m_nameUses.contains(t))
            return m_nameUses.value(t);
    }
    return 0;
}

/*
    Gets a TokenRef from an AST node.
    Assumes that the node only covers one token, which means that
    node->statToken() == node->endToken(). If this is not the case
    then the TokenRef will reference the token at startToken.
*/
TokenEngine::TokenRef Semantic::tokenRefFromAST(AST *node)
{
    const int startTokenIndex = node->startToken();
    const TokenEngine::TokenContainer tokenContainer = m_tokenStream->tokenContainer(startTokenIndex);
    const int containerIndex = m_tokenStream->containerIndex(startTokenIndex);
    return TokenEngine::TokenRef(tokenContainer, containerIndex);
}

QT_END_NAMESPACE
