void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot,
                                                const LookupItem &lookupItem,
                                                const LookupContext &context,
                                                const Scope *scope)
{
    Symbol *declaration = lookupItem.declaration();
    if (!declaration) {
        const QString &type = Overview().prettyType(lookupItem.type(), QString());
        //  special case for bug QTCREATORBUG-4780
        if (scope && scope->isFunction()
                && lookupItem.type().match(scope->asFunction()->returnType())) {
            return;
        }
        m_element = QSharedPointer<CppElement>(new Unknown(type));
    } else {
        const FullySpecifiedType &type = declaration->type();
        if (declaration->isNamespace()) {
            m_element = QSharedPointer<CppElement>(new CppNamespace(declaration));
        } else if (declaration->isClass()
                   || declaration->isForwardClassDeclaration()
                   || (declaration->isTemplate() && declaration->asTemplate()->declaration()
                       && (declaration->asTemplate()->declaration()->isClass()
                           || declaration->asTemplate()->declaration()->isForwardClassDeclaration()))) {
            LookupContext contextToUse = context;
            if (declaration->isForwardClassDeclaration())
                if (Symbol *classDeclaration =
                        m_symbolFinder.findMatchingClassDeclaration(declaration, snapshot)) {
                    declaration = classDeclaration;
                    const QString fileName = QString::fromUtf8(declaration->fileName(),
                                                               declaration->fileNameLength());
                    const Document::Ptr declarationDocument = snapshot.document(fileName);
                    if (declarationDocument != context.thisDocument())
                        contextToUse = LookupContext(declarationDocument, snapshot);
                }

            CppClass *cppClass = new CppClass(declaration);
            if (m_lookupBaseClasses)
                cppClass->lookupBases(declaration, contextToUse);
            if (m_lookupDerivedClasses)
                cppClass->lookupDerived(declaration, snapshot);
            m_element = QSharedPointer<CppElement>(cppClass);
        } else if (Enum *enumDecl = declaration->asEnum()) {
            m_element = QSharedPointer<CppElement>(new CppEnum(enumDecl));
        } else if (EnumeratorDeclaration *enumerator = dynamic_cast<EnumeratorDeclaration *>(declaration)) {
            m_element = QSharedPointer<CppElement>(new CppEnumerator(enumerator));
        } else if (declaration->isTypedef()) {
            m_element = QSharedPointer<CppElement>(new CppTypedef(declaration));
        } else if (declaration->isFunction()
                   || (type.isValid() && type->isFunctionType())
                   || declaration->isTemplate()) {
            m_element = QSharedPointer<CppElement>(new CppFunction(declaration));
        } else if (declaration->isDeclaration() && type.isValid()) {
            m_element = QSharedPointer<CppElement>(
                new CppVariable(declaration, context, lookupItem.scope()));
        } else {
            m_element = QSharedPointer<CppElement>(new CppDeclarableElement(declaration));
        }
    }
}
Beispiel #2
0
QString CPlusPlus::toString(const LookupItem &it, const QString &id)
{
    QString result = QString::fromLatin1("%1:").arg(id);
    if (it.declaration())
        result.append(QString::fromLatin1("\n%1").arg(indent(toString(it.declaration(), QLatin1String("Decl")))));
    if (it.type().isValid())
        result.append(QString::fromLatin1("\n%1").arg(indent(toString(it.type()))));
    if (it.scope())
        result.append(QString::fromLatin1("\n%1").arg(indent(toString(it.scope(), QLatin1String("Scope")))));
    if (it.binding())
        result.append(QString::fromLatin1("\n%1").arg(indent(toString(it.binding(), QLatin1String("Binding")))));
    return result;
}
void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot,
                                                const LookupItem &lookupItem,
                                                const LookupContext &context)
{
    Symbol *declaration = lookupItem.declaration();
    if (!declaration) {
        const QString &type = Overview().prettyType(lookupItem.type(), QString());
        m_element = QSharedPointer<CppElement>(new Unknown(type));
    } else {
        const FullySpecifiedType &type = declaration->type();
        if (declaration->isNamespace()) {
            m_element = QSharedPointer<CppElement>(new CppNamespace(declaration));
        } else if (declaration->isClass()
                   || declaration->isForwardClassDeclaration()
                   || (declaration->isTemplate() && declaration->asTemplate()->declaration()
                       && (declaration->asTemplate()->declaration()->isClass()
                           || declaration->asTemplate()->declaration()->isForwardClassDeclaration()))) {
            if (declaration->isForwardClassDeclaration())
                if (Symbol *classDeclaration =
                        m_symbolFinder.findMatchingClassDeclaration(declaration, snapshot)) {
                    declaration = classDeclaration;
                }
            CppClass *cppClass = new CppClass(declaration);
            if (m_lookupBaseClasses)
                cppClass->lookupBases(declaration, context);
            if (m_lookupDerivedClasses)
                cppClass->lookupDerived(declaration, snapshot);
            m_element = QSharedPointer<CppElement>(cppClass);
        } else if (Enum *enumDecl = declaration->asEnum()) {
            m_element = QSharedPointer<CppElement>(new CppEnum(enumDecl));
        } else if (EnumeratorDeclaration *enumerator = dynamic_cast<EnumeratorDeclaration *>(declaration)) {
            m_element = QSharedPointer<CppElement>(new CppEnumerator(enumerator));
        } else if (declaration->isTypedef()) {
            m_element = QSharedPointer<CppElement>(new CppTypedef(declaration));
        } else if (declaration->isFunction()
                   || (type.isValid() && type->isFunctionType())
                   || declaration->isTemplate()) {
            m_element = QSharedPointer<CppElement>(new CppFunction(declaration));
        } else if (declaration->isDeclaration() && type.isValid()) {
            m_element = QSharedPointer<CppElement>(
                new CppVariable(declaration, context, lookupItem.scope()));
        } else {
            m_element = QSharedPointer<CppElement>(new CppDeclarableElement(declaration));
        }
    }
}
bool TypeResolver::findTypedef(const QList<LookupItem> &namedTypeItems, FullySpecifiedType *type,
                               Scope **scope, QSet<Symbol *> &visited)
{
    foreach (const LookupItem &it, namedTypeItems) {
        Symbol *declaration = it.declaration();
        if (!declaration)
            continue;
        if (Template *specialization = declaration->asTemplate())
            declaration = specialization->declaration();
        if (!declaration || (!declaration->isTypedef() && !declaration->type().isDecltype()))
            continue;
        if (visited.contains(declaration))
            break;
        visited.insert(declaration);

        // continue working with the typedefed type and scope
        if (type->type()->isPointerType()) {
            *type = FullySpecifiedType(
                        _factory.control()->pointerType(declaration->type()));
        } else if (type->type()->isReferenceType()) {
            *type = FullySpecifiedType(
                        _factory.control()->referenceType(
                            declaration->type(),
                            declaration->type()->asReferenceType()->isRvalueReference()));
        } else if (declaration->type().isDecltype()) {
            Declaration *decl = declaration->asDeclaration();
            const QList<LookupItem> resolved =
                    resolveDeclInitializer(_factory, decl, QSet<const Declaration* >() << decl);
            if (!resolved.isEmpty()) {
                LookupItem item = resolved.first();
                *type = item.type();
                *scope = item.scope();
                _binding = item.binding();
                return true;
            }
        } else {
            *type = it.type();
        }

        *scope = it.scope();
        _binding = it.binding();
        return true;
    }