File indexing completed on 2024-05-12 04:39:12
0001 /* 0002 SPDX-FileCopyrightText: 2013 Milian Wolff <mail@milianw.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "debugvisitor.h" 0008 #include "util/clangtypes.h" 0009 #include "util/clangutils.h" 0010 0011 namespace { 0012 0013 struct ClientData 0014 { 0015 QTextStream* out; 0016 ParseSession* session; 0017 CXFile file; 0018 uint depth; 0019 }; 0020 0021 CXChildVisitResult visitCursor(CXCursor cursor, CXCursor /*parent*/, CXClientData d) 0022 { 0023 auto data = static_cast<ClientData*>(d); 0024 0025 const auto kind = clang_getCursorKind(cursor); 0026 0027 const auto location = clang_getCursorLocation(cursor); 0028 CXFile file; 0029 clang_getFileLocation(location, &file, nullptr, nullptr, nullptr); 0030 // don't skip MemberRefExpr with invalid location, see also: 0031 // http://lists.cs.uiuc.edu/pipermail/cfe-dev/2015-May/043114.html 0032 if (!ClangUtils::isFileEqual(file, data->file) && (file || kind != CXCursor_MemberRefExpr)) { 0033 return CXChildVisit_Continue; 0034 } 0035 0036 (*data->out) << QByteArray(data->depth * 2, ' '); 0037 0038 ClangString kindName(clang_getCursorKindSpelling(kind)); 0039 (*data->out) << kindName << " (" << kind << ") "; 0040 0041 auto type = clang_getCursorType(cursor); 0042 if (type.kind != CXType_Invalid) { 0043 ClangString typeName(clang_getTypeSpelling(type)); 0044 (*data->out) << "| type: \"" << typeName << '\"' << " (" << type.kind << ") "; 0045 } 0046 0047 auto canonicalType = clang_getCanonicalType(type); 0048 if (canonicalType.kind != CXType_Invalid 0049 && !clang_equalTypes(type, canonicalType)) { 0050 ClangString typeName(clang_getTypeSpelling(canonicalType)); 0051 (*data->out) << "| canonical type: \"" << typeName << '\"' << " (" << canonicalType.kind << ") "; 0052 } 0053 0054 auto typedefType = clang_getTypedefDeclUnderlyingType(cursor); 0055 if (typedefType.kind != CXType_Invalid 0056 && !clang_equalTypes(type, typedefType)) { 0057 ClangString typeName(clang_getTypeSpelling(typedefType)); 0058 (*data->out) << "| typedef type: \"" << typeName << '\"' << " (" << typedefType.kind << ") "; 0059 } 0060 0061 ClangString displayName(clang_getCursorDisplayName(cursor)); 0062 if (!displayName.isEmpty()) { 0063 (*data->out) << "| display: \"" << displayName << "\" "; 0064 } 0065 0066 auto cursorExtent = ClangRange(clang_getCursorExtent(cursor)).toRange(); 0067 ClangString fileName(clang_getFileName(file)); 0068 (*data->out) << "| loc: " << fileName << '@' << '[' 0069 << '(' << cursorExtent.start().line()+1 << ',' << cursorExtent.start().column()+1 << ")," 0070 << '(' << cursorExtent.end().line()+1 << ',' << cursorExtent.end().column()+1 << ")] "; 0071 0072 auto spellingNameRange = ClangRange(clang_Cursor_getSpellingNameRange(cursor, 0, 0)).toRange(); 0073 (*data->out) << "| sp-name-range: [" 0074 << '(' << spellingNameRange.start().line()+1 << ',' << spellingNameRange.start().column()+1 << ")," 0075 << '(' << spellingNameRange.end().line()+1 << ',' << spellingNameRange.end().column()+1 << ")] "; 0076 0077 if (clang_isDeclaration(kind)) { 0078 (*data->out) << "| isDecl"; 0079 } else { 0080 auto referenced = clang_getCursorReferenced(cursor); 0081 if (kind != CXCursor_UnexposedExpr && !clang_equalCursors(clang_getNullCursor(), referenced)) { 0082 (*data->out) << "| isUse"; 0083 } 0084 } 0085 0086 (*data->out) << Qt::endl; 0087 0088 ClientData childData{data->out, data->session, data->file, data->depth + 1}; 0089 clang_visitChildren(cursor, &visitCursor, &childData); 0090 0091 return CXChildVisit_Continue; 0092 } 0093 0094 } 0095 0096 DebugVisitor::DebugVisitor(ParseSession* session) 0097 : m_session(session) 0098 { 0099 0100 } 0101 0102 void DebugVisitor::visit(CXTranslationUnit unit, CXFile file) 0103 { 0104 auto cursor = clang_getTranslationUnitCursor(unit); 0105 QTextStream out(stdout); 0106 ClientData data {&out, m_session, file, 0}; 0107 clang_visitChildren(cursor, &visitCursor, &data); 0108 }