| 216 | } |
| 217 | |
| 218 | CXChildVisitResult declVisitor(CXCursor cursor, CXCursor parent, CXClientData d) |
| 219 | { |
| 220 | CXCursorKind kind = clang_getCursorKind(cursor); |
| 221 | auto* data = static_cast<struct ImplementsInfo*>(d); |
| 222 | |
| 223 | auto location = clang_getCursorLocation(cursor); |
| 224 | if (clang_Location_isInSystemHeader(location)) { |
| 225 | // never offer implementation items for system headers |
| 226 | // TODO: also filter out non-system files unrelated to the current file |
| 227 | // e.g. based on the path or similar |
| 228 | return CXChildVisit_Continue; |
| 229 | } |
| 230 | CXFile file = nullptr; |
| 231 | clang_getFileLocation(location, &file, nullptr, nullptr, nullptr); |
| 232 | if (!data->fileFilter.contains(file)) { |
| 233 | return CXChildVisit_Continue; |
| 234 | } |
| 235 | |
| 236 | //Recurse into cursors which could contain a function declaration |
| 237 | if (ClangUtils::isScopeKind(kind)) { |
| 238 | |
| 239 | //Don't enter a scope that branches from the origin's scope |
| 240 | if (data->depth < data->originScope.count() && |
| 241 | !clang_equalCursors(cursor, data->originScope.at(data->depth))) { |
| 242 | return CXChildVisit_Continue; |
| 243 | } |
| 244 | |
| 245 | // we must not declare a function outside of its anonymous namespace, so |
| 246 | // don't recurse into anonymous namespaces if we are not in one already |
| 247 | if (kind == CXCursor_Namespace && !clang_equalCursors(data->origin, cursor) && ClangString(clang_getCursorDisplayName(cursor)).isEmpty()) { |
| 248 | return CXChildVisit_Continue; |
| 249 | } |
| 250 | |
| 251 | QString templatePrefix; |
| 252 | if (data->depth >= data->originScope.count()) { |
| 253 | if (kind == CXCursor_ClassTemplate || kind == CXCursor_ClassTemplatePartialSpecialization) { |
| 254 | //If we're at a template, we need to construct the template<typename T1, typename T2> |
| 255 | //which goes at the front of the prototype |
| 256 | const QStringList templateTypes = templateParams(kind == CXCursor_ClassTemplate ? cursor : clang_getSpecializedCursorTemplate(cursor)); |
| 257 | |
| 258 | templatePrefix = QLatin1String("template<") + templateTypes.join(QLatin1String(", ")) + QLatin1String("> "); |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | ImplementsInfo info{data->origin, data->top, data->prototypes, data->originScope, |
| 263 | data->fileFilter, |
| 264 | data->depth + 1, |
| 265 | data->templatePrefix + templatePrefix}; |
| 266 | clang_visitChildren(cursor, declVisitor, &info); |
| 267 | |
| 268 | return CXChildVisit_Continue; |
| 269 | } |
| 270 | |
| 271 | if (data->depth < data->originScope.count()) { |
| 272 | return CXChildVisit_Continue; |
| 273 | } |
| 274 | |
| 275 | //If the current cursor is not a function or if it is already defined, there's nothing to do here |
nothing calls this directly
no test coverage detected