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

📄 semantic.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            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,    // becuase 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-emty 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, exept 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);    }}

⌨️ 快捷键说明

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