Ejemplo n.º 1
0
static ClassDocumentPtrPair
        findClassRecursively(const LookupContext &context, const QString &className,
                             unsigned maxIncludeDepth, QString *namespaceName)
{
    const Document::Ptr doc = context.thisDocument();
    const Snapshot docTable = context.snapshot();
    if (Designer::Constants::Internal::debug)
        qDebug() << Q_FUNC_INFO << doc->fileName() << className << maxIncludeDepth;
    // Check document
    if (const Class *cl = findClass(doc->globalNamespace(), context, className, namespaceName))
        return ClassDocumentPtrPair(cl, doc);
    if (maxIncludeDepth) {
        // Check the includes
        const unsigned recursionMaxIncludeDepth = maxIncludeDepth - 1u;
        const auto includedFiles = doc->includedFiles();
        for (const QString &include : includedFiles) {
            const Snapshot::const_iterator it = docTable.find(include);
            if (it != docTable.end()) {
                const Document::Ptr includeDoc = it.value();
                LookupContext context(includeDoc, docTable);
                const ClassDocumentPtrPair irc = findClassRecursively(context, className,
                    recursionMaxIncludeDepth, namespaceName);
                if (irc.first)
                    return irc;
            }
        }
    }
    return ClassDocumentPtrPair(0, Document::Ptr());
}
Ejemplo n.º 2
0
/////////////////////////////////////////////////////////////////////
// ResolveExpression
/////////////////////////////////////////////////////////////////////
ResolveExpression::ResolveExpression(const LookupContext &context)
    : ASTVisitor(context.expressionDocument()->translationUnit()),
      _scope(0),
      _context(context),
      bind(context.expressionDocument()->translationUnit()),
      _reference(false)
{ }
Ejemplo n.º 3
0
void CppClass::lookupBases(Symbol *declaration, const LookupContext &context)
{
    using Data = QPair<ClassOrNamespace*, CppClass*>;

    if (ClassOrNamespace *clazz = context.lookupType(declaration)) {
        QSet<ClassOrNamespace *> visited;

        QQueue<Data> q;
        q.enqueue(qMakePair(clazz, this));
        while (!q.isEmpty()) {
            Data current = q.dequeue();
            clazz = current.first;
            visited.insert(clazz);
            const QList<ClassOrNamespace *> &bases = clazz->usings();
            foreach (ClassOrNamespace *baseClass, bases) {
                const QList<Symbol *> &symbols = baseClass->symbols();
                foreach (Symbol *symbol, symbols) {
                    if (symbol->isClass() && (
                        clazz = context.lookupType(symbol)) &&
                        !visited.contains(clazz)) {
                        CppClass baseCppClass(symbol);
                        CppClass *cppClass = current.second;
                        cppClass->bases.append(baseCppClass);
                        q.enqueue(qMakePair(clazz, &cppClass->bases.last()));
                    }
                }
            }
        }
    }
Ejemplo n.º 4
0
/////////////////////////////////////////////////////////////////////
// ResolveExpression
/////////////////////////////////////////////////////////////////////
ResolveExpression::ResolveExpression(const LookupContext &context,
                                     const QSet<const Declaration *> &autoDeclarationsBeingResolved)
    : ASTVisitor(context.expressionDocument()->translationUnit()),
      _scope(0),
      _context(context),
      bind(context.expressionDocument()->translationUnit()),
      _autoDeclarationsBeingResolved(autoDeclarationsBeingResolved),
      _reference(false)
{ }
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));
        }
    }
}
Ejemplo n.º 6
0
QString fullyQualifiedName(const LookupContext &context, const Name *name, Scope *scope)
{
    if (!name || !scope)
        return QString();

    const QList<LookupItem> items = context.lookup(name, scope);
    if (items.isEmpty()) // "ui_xxx.h" might not be generated and nothing is forward declared.
        return Overview().prettyName(name);
    Symbol *symbol = items.first().declaration();
    return Overview().prettyName(LookupContext::fullyQualifiedName(symbol));
}
Ejemplo n.º 7
0
static bool isVirtualFunction_helper(const Function *function,
                                     const LookupContext &context,
                                     VirtualType virtualType,
                                     const Function **firstVirtual)
{
    enum { Unknown, False, True } res = Unknown;

    if (firstVirtual)
        *firstVirtual = 0;

    if (!function)
        return false;

    if (virtualType == PureVirtual)
        res = function->isPureVirtual() ? True : False;

    if (function->isVirtual()) {
        if (firstVirtual)
            *firstVirtual = function;
        if (res == Unknown)
            res = True;
    }

    if (!firstVirtual && res != Unknown)
        return res == True;

    QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope());
    if (!results.isEmpty()) {
        const bool isDestructor = function->name()->isDestructorNameId();
        foreach (const LookupItem &item, results) {
            if (Symbol *symbol = item.declaration()) {
                if (Function *functionType = symbol->type()->asFunctionType()) {
                    if (functionType->name()->isDestructorNameId() != isDestructor)
                        continue;
                    if (functionType == function) // already tested
                        continue;
                    if (!function->isSignatureEqualTo(functionType))
                        continue;
                    if (functionType->isFinal())
                        return res == True;
                    if (functionType->isVirtual()) {
                        if (!firstVirtual)
                            return true;
                        if (res == Unknown)
                            res = True;
                        *firstVirtual = functionType;
                    }
                }
            }
        }
    }

    return res == True;
}
Ejemplo n.º 8
0
bool isOwnershipRAIIType(Symbol *symbol, const LookupContext &context)
{
    if (!symbol)
        return false;

    // This is not a "real" comparison of types. What we do is to resolve the symbol
    // in question and then try to match its name with already known ones.
    if (symbol->isDeclaration()) {
        Declaration *declaration = symbol->asDeclaration();
        const NamedType *namedType = declaration->type()->asNamedType();
        if (namedType) {
            LookupScope *clazz = context.lookupType(namedType->name(),
                                                         declaration->enclosingScope());
            if (clazz && !clazz->symbols().isEmpty()) {
                Overview overview;
                Symbol *symbol = clazz->symbols().at(0);
                return isOwnershipRAIIName(overview.prettyName(symbol->name()));
            }
        }
    }

    return false;
}