static QString fullyQualifiedName(Symbol *symbol, const Overview *overview)
{
    QStringList nestedNameSpecifier;

    for (Scope *scope = symbol->scope(); scope && scope->enclosingScope();
         scope = scope->enclosingScope())
    {
        Symbol *owner = scope->owner();

        if (! owner) {
            qWarning() << "invalid scope."; // ### better message.
            continue;
        }

        if (! owner->name())
            nestedNameSpecifier.prepend(QLatin1String("$anonymous"));

        else {
            const QString name = overview->prettyName(owner->name());

            nestedNameSpecifier.prepend(name);
        }
    }

    nestedNameSpecifier.append(overview->prettyName(symbol->name()));

    return nestedNameSpecifier.join(QLatin1String("::"));
}
/// Return all typedefs with given name from given scope up to function scope.
QList<LookupItem> TypeResolver::typedefsFromScopeUpToFunctionScope(const Name *name, Scope *scope)
{
    QList<LookupItem> results;
    if (!scope)
        return results;
    Scope *enclosingBlockScope = 0;
    for (Block *block = scope->asBlock(); block;
         block = enclosingBlockScope ? enclosingBlockScope->asBlock() : 0) {
        const unsigned memberCount = block->memberCount();
        for (unsigned i = 0; i < memberCount; ++i) {
            Symbol *symbol = block->memberAt(i);
            if (Declaration *declaration = symbol->asDeclaration()) {
                if (isTypedefWithName(declaration, name)) {
                    LookupItem item;
                    item.setDeclaration(declaration);
                    item.setScope(block);
                    item.setType(declaration->type());
                    results.append(item);
                }
            }
        }
        enclosingBlockScope = block->enclosingScope();
        if (enclosingBlockScope) {
            // For lambda, step beyond the function to its enclosing block
            if (Function *enclosingFunction = enclosingBlockScope->asFunction()) {
                if (!enclosingFunction->name())
                    enclosingBlockScope = enclosingBlockScope->enclosingScope();
            }
        }
    }
    return results;
}
Exemple #3
0
Block *Symbol::enclosingBlock() const
{
    for (Scope *s = _enclosingScope; s; s = s->enclosingScope()) {
        if (Block *block = s->asBlock())
            return block;
    }
    return 0;
}
Exemple #4
0
Function *Symbol::enclosingFunction() const
{
    for (Scope *s = _enclosingScope; s; s = s->enclosingScope()) {
        if (Function *fun = s->asFunction())
            return fun;
    }
    return 0;
}
Exemple #5
0
Enum *Symbol::enclosingEnum() const
{
    for (Scope *s = _enclosingScope; s; s = s->enclosingScope()) {
        if (Enum *e = s->asEnum())
            return e;
    }
    return 0;
}
Exemple #6
0
Class *Symbol::enclosingClass() const
{
    for (Scope *s = _enclosingScope; s; s = s->enclosingScope()) {
        if (Class *klass = s->asClass())
            return klass;
    }
    return 0;
}
Exemple #7
0
Template *Symbol::enclosingTemplate() const
{
    for (Scope *s = _enclosingScope; s; s = s->enclosingScope()) {
        if (Template *templ = s->asTemplate())
            return templ;
    }
    return 0;
}
Exemple #8
0
Namespace *Symbol::enclosingNamespace() const
{
    for (Scope *s = _enclosingScope; s; s = s->enclosingScope()) {
        if (Namespace *ns = s->asNamespace())
            return ns;
    }
    return 0;
}
Scope *Scope::enclosingNamespaceScope() const
{
    Scope *scope = enclosingScope();
    for (; scope; scope = scope->enclosingScope()) {
        if (scope->owner()->isNamespace())
            break;
    }
    return scope;
}
Scope *Scope::enclosingBlockScope() const
{
    Scope *scope = enclosingScope();
    for (; scope; scope = scope->enclosingScope()) {
        if (scope->owner()->isBlock())
            break;
    }
    return scope;
}
Scope *Scope::enclosingFunctionScope() const
{
    Scope *scope = enclosingScope();
    for (; scope; scope = scope->enclosingScope()) {
        if (scope->owner()->isFunction())
            break;
    }
    return scope;
}
Scope *Scope::enclosingClassScope() const
{
    Scope *scope = enclosingScope();
    for (; scope; scope = scope->enclosingScope()) {
        if (scope->owner()->isClass())
            break;
    }
    return scope;
}
// TODO: remove me, this is taken from cppeditor.cpp. Find some common place for this method
static Document::Ptr findDefinition(const Function *functionDeclaration, int *line)
{
    CppTools::CppModelManagerInterface *cppModelManager = cppModelManagerInstance();
    if (!cppModelManager)
        return Document::Ptr();

    QVector<const Name *> qualifiedName;
    Scope *scope = functionDeclaration->scope();
    for (; scope; scope = scope->enclosingScope()) {
        if (scope->isClassScope() || scope->isNamespaceScope()) {
            if (scope->owner() && scope->owner()->name()) {
                const Name *scopeOwnerName = scope->owner()->name();
                if (const QualifiedNameId *q = scopeOwnerName->asQualifiedNameId()) {
                    for (unsigned i = 0; i < q->nameCount(); ++i) {
                        qualifiedName.prepend(q->nameAt(i));

                    }
                } else {
                    qualifiedName.prepend(scopeOwnerName);
                }
            }
        }
    }

    qualifiedName.append(functionDeclaration->name());

    Control control;
    const QualifiedNameId *q = control.qualifiedNameId(&qualifiedName[0], qualifiedName.size());
    LookupContext context(&control);
    const Snapshot documents = cppModelManager->snapshot();
    foreach (Document::Ptr doc, documents) {
        QList<Scope *> visibleScopes;
        visibleScopes.append(doc->globalSymbols());
        visibleScopes = context.expand(visibleScopes);
        foreach (Scope *visibleScope, visibleScopes) {
            Symbol *symbol = 0;
            if (const NameId *nameId = q->unqualifiedNameId()->asNameId())
                symbol = visibleScope->lookat(nameId->identifier());
            else if (const DestructorNameId *dtorId = q->unqualifiedNameId()->asDestructorNameId())
                symbol = visibleScope->lookat(dtorId->identifier());
            else if (const TemplateNameId *templNameId = q->unqualifiedNameId()->asTemplateNameId())
                symbol = visibleScope->lookat(templNameId->identifier());
            else if (const OperatorNameId *opId = q->unqualifiedNameId()->asOperatorNameId())
                symbol = visibleScope->lookat(opId->kind());
            // ### cast operators
            for (; symbol; symbol = symbol->next()) {
                if (! symbol->isFunction())
                    continue;
                else if (! isCompatible(symbol->asFunction(), functionDeclaration, q))
                    continue;
                *line = symbol->line(); // TODO: shift the line so that we are inside a function. Maybe just find the nearest '{'?
                return doc;
            }
        }
Exemple #14
0
/*!
 * Extract the function name including scope at the given position.
 *
 * Note that a function (scope) starts at the name of that function, not at the return type. The
 * implication is that this function will return an empty string when the line/column is on the
 * return type.
 *
 * \param line the line number, starting with line 1
 * \param column the column number, starting with column 1
 * \param lineOpeningDeclaratorParenthesis optional output parameter, the line of the opening
          parenthesis of the declarator starting with 1
 * \param lineClosingBrace optional output parameter, the line of the closing brace starting with 1
 */
QString Document::functionAt(int line, int column, int *lineOpeningDeclaratorParenthesis,
                             int *lineClosingBrace) const
{
    if (line < 1 || column < 1)
        return QString();

    Symbol *symbol = lastVisibleSymbolAt(line, column);
    if (!symbol)
        return QString();

    // Find the enclosing function scope (which might be several levels up, or we might be standing
    // on it)
    Scope *scope = symbol->asScope();
    if (!scope)
        scope = symbol->enclosingScope();

    while (scope && !scope->isFunction() )
        scope = scope->enclosingScope();

    if (!scope)
        return QString();

    // We found the function scope
    if (lineOpeningDeclaratorParenthesis) {
        unsigned line;
        translationUnit()->getPosition(scope->startOffset(), &line);
        *lineOpeningDeclaratorParenthesis = static_cast<int>(line);
    }

    if (lineClosingBrace) {
        unsigned line;
        translationUnit()->getPosition(scope->endOffset(), &line);
        *lineClosingBrace = static_cast<int>(line);
    }

    const QList<const Name *> fullyQualifiedName = LookupContext::fullyQualifiedName(scope);
    return Overview().prettyName(fullyQualifiedName);
}