⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 semantic.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 2004-2006 Trolltech ASA. All rights reserved.** Copyright (C) 2001-2004 Roberto Raggi**** This file is part of the qt3to4 porting application of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.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 GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "smallobject.h"#include "tokenengine.h"#include "semantic.h"#include <QtDebug>#include <QString>#include <QRegExp>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 ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -