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

📄 semantic.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//look up an unqualified nameQList<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 nameQList<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 scopeQList<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 funciton 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(textOf(typeSpec)).replace(QRegExp(" :: "), 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 += " ";    }    text += scope;    if (declarator->subDeclarator())        text += "(" + declaratorToString(declarator->subDeclarator()) + ")";    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 += "[]";        }    }    if (declarator->parameterDeclarationClause()){        text += "(";        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 += " ";                text += declaratorToString(current->declarator());                // ### FIXME if (it.current())                    text += ", ";            }        }        text += ")";        if (declarator->constant() != 0)            text += " const";    }    return QString(text).replace(QRegExp(" :: "), "::").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 += " ";            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);}

⌨️ 快捷键说明

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