Ejemplo n.º 1
0
SourceRangeContainer FollowSymbol::followSymbol(CXTranslationUnit tu,
                                                const Cursor &fullCursor,
                                                uint line,
                                                uint column)
{
    std::unique_ptr<Tokens> tokens(new Tokens(fullCursor));

    if (!tokens->tokenCount)
        tokens.reset(new Tokens(tu));

    if (!tokens->tokenCount)
        return SourceRangeContainer();

    QVector<CXCursor> cursors(static_cast<int>(tokens->tokenCount));
    clang_annotateTokens(tu, tokens->data, tokens->tokenCount, cursors.data());
    int tokenIndex = getTokenIndex(tu, *tokens, line, column);
    QTC_ASSERT(tokenIndex >= 0, return SourceRangeContainer());

    const Utf8String tokenSpelling = ClangString(
                clang_getTokenSpelling(tu, tokens->data[tokenIndex]));
    if (tokenSpelling.isEmpty())
        return SourceRangeContainer();

    Cursor cursor{cursors[tokenIndex]};

    if (cursor.kind() == CXCursor_InclusionDirective) {
        CXFile file = clang_getIncludedFile(cursors[tokenIndex]);
        const ClangString filename(clang_getFileName(file));
        const SourceLocation loc(tu, filename, 1, 1);
        return SourceRange(loc, loc);
    }

    // For definitions we can always find a declaration in current TU
    if (cursor.isDefinition())
        return extractMatchingTokenRange(cursor.canonical(), tokenSpelling);

    if (!cursor.isDeclaration()) {
        // This is the symbol usage
        // We want to return definition
        cursor = cursor.referenced();
        if (cursor.isNull() || !cursor.isDefinition()) {
            // We can't find definition in this TU
            return SourceRangeContainer();
        }
        return extractMatchingTokenRange(cursor, tokenSpelling);
    }

    cursor = cursor.definition();
    // If we are able to find a definition in current TU
    if (!cursor.isNull())
        return extractMatchingTokenRange(cursor, tokenSpelling);

    return SourceRangeContainer();
}
Ejemplo n.º 2
0
SourceRangeContainer SourceRange::toSourceRangeContainer() const
{
    return SourceRangeContainer(start().toSourceLocationContainer(),
                                end().toSourceLocationContainer());
}