File: debugvisitor.cpp

package info (click to toggle)
kdevelop 4%3A5.6.2-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 57,892 kB
  • sloc: cpp: 278,773; javascript: 3,558; python: 3,385; sh: 1,317; ansic: 689; xml: 273; php: 95; makefile: 40; lisp: 13; sed: 12
file content (127 lines) | stat: -rw-r--r-- 4,609 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
    This file is part of KDevelop

    Copyright 2013 Milian Wolff <mail@milianw.de>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "debugvisitor.h"
#include "util/clangtypes.h"
#include "util/clangutils.h"

namespace {

struct ClientData
{
    QTextStream* out;
    ParseSession* session;
    CXFile file;
    uint depth;
};

CXChildVisitResult visitCursor(CXCursor cursor, CXCursor /*parent*/, CXClientData d)
{
    auto data = static_cast<ClientData*>(d);

    const auto kind = clang_getCursorKind(cursor);

    const auto location = clang_getCursorLocation(cursor);
    CXFile file;
    clang_getFileLocation(location, &file, nullptr, nullptr, nullptr);
    // don't skip MemberRefExpr with invalid location, see also:
    // http://lists.cs.uiuc.edu/pipermail/cfe-dev/2015-May/043114.html
    if (!ClangUtils::isFileEqual(file, data->file) && (file || kind != CXCursor_MemberRefExpr)) {
        return CXChildVisit_Continue;
    }

    (*data->out) << QByteArray(data->depth * 2, ' ');

    ClangString kindName(clang_getCursorKindSpelling(kind));
    (*data->out) << kindName << " (" << kind << ") ";

    auto type = clang_getCursorType(cursor);
    if (type.kind != CXType_Invalid) {
        ClangString typeName(clang_getTypeSpelling(type));
        (*data->out) << "| type: \"" << typeName << '\"' << " (" << type.kind << ") ";
    }

    auto canonicalType = clang_getCanonicalType(type);
    if (canonicalType.kind != CXType_Invalid
        && !clang_equalTypes(type, canonicalType)) {
        ClangString typeName(clang_getTypeSpelling(canonicalType));
        (*data->out) << "| canonical type: \"" << typeName << '\"' << " (" << canonicalType.kind << ") ";
    }

    auto typedefType = clang_getTypedefDeclUnderlyingType(cursor);
    if (typedefType.kind != CXType_Invalid
        && !clang_equalTypes(type, typedefType)) {
        ClangString typeName(clang_getTypeSpelling(typedefType));
        (*data->out) << "| typedef type: \"" << typeName << '\"' << " (" << typedefType.kind << ") ";
    }

    ClangString displayName(clang_getCursorDisplayName(cursor));
    if (!displayName.isEmpty()) {
        (*data->out) << "| display: \"" << displayName << "\" ";
    }

    auto cursorExtent = ClangRange(clang_getCursorExtent(cursor)).toRange();
    ClangString fileName(clang_getFileName(file));
    (*data->out) << "| loc: " << fileName << '@' << '['
        << '(' << cursorExtent.start().line()+1 << ',' << cursorExtent.start().column()+1 << "),"
        << '(' << cursorExtent.end().line()+1 << ',' << cursorExtent.end().column()+1 << ")] ";

    auto spellingNameRange = ClangRange(clang_Cursor_getSpellingNameRange(cursor, 0, 0)).toRange();
    (*data->out) << "| sp-name-range: ["
        << '(' << spellingNameRange.start().line()+1 << ',' << spellingNameRange.start().column()+1 << "),"
        << '(' << spellingNameRange.end().line()+1 << ',' << spellingNameRange.end().column()+1 << ")] ";

    if (clang_isDeclaration(kind)) {
        (*data->out) << "| isDecl";
    } else {
        auto referenced = clang_getCursorReferenced(cursor);
        if (kind != CXCursor_UnexposedExpr && !clang_equalCursors(clang_getNullCursor(), referenced)) {
            (*data->out) << "| isUse";
        }
    }

#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
    (*data->out) << Qt::endl;
#else
    (*data->out) << endl;
#endif

    ClientData childData{data->out, data->session, data->file, data->depth + 1};
    clang_visitChildren(cursor, &visitCursor, &childData);

    return CXChildVisit_Continue;
}

}

DebugVisitor::DebugVisitor(ParseSession* session)
    : m_session(session)
{

}

void DebugVisitor::visit(CXTranslationUnit unit, CXFile file)
{
    auto cursor = clang_getTranslationUnitCursor(unit);
    QTextStream out(stdout);
    ClientData data {&out, m_session, file, 0};
    clang_visitChildren(cursor, &visitCursor, &data);
}