| 1084 | } |
| 1085 | |
| 1086 | QList<CompletionTreeItemPointer> ClangCodeCompletionContext::completionItems(bool& abort, bool /*fullCompletion*/) |
| 1087 | { |
| 1088 | if (!m_valid || !m_duContext || !m_results) { |
| 1089 | return {}; |
| 1090 | } |
| 1091 | |
| 1092 | const auto ctx = DUContextPointer(m_duContext->findContextAt(m_position)); |
| 1093 | |
| 1094 | /// Normal completion items, such as 'void Foo::foo()' |
| 1095 | QList<CompletionTreeItemPointer> items; |
| 1096 | /// Stuff like 'Foo& Foo::operator=(const Foo&)', etc. Not regularly used by our users. |
| 1097 | QList<CompletionTreeItemPointer> specialItems; |
| 1098 | /// Macros from the current context |
| 1099 | QList<CompletionTreeItemPointer> macros; |
| 1100 | /// Builtins reported by Clang |
| 1101 | QList<CompletionTreeItemPointer> builtin; |
| 1102 | |
| 1103 | // two sets of handled declarations to prevent duplicates and make sure we show |
| 1104 | // all available overloads |
| 1105 | QSet<Declaration*> handled; |
| 1106 | // this is only used for the CXCursor_OverloadCandidate completion items |
| 1107 | QSet<Declaration*> overloadsHandled; |
| 1108 | |
| 1109 | LookAheadItemMatcher lookAheadMatcher(TopDUContextPointer(ctx->topContext())); |
| 1110 | |
| 1111 | // If ctx is/inside the Class context, this represents that context. |
| 1112 | const auto currentClassContext = classDeclarationForContext(ctx, m_position); |
| 1113 | |
| 1114 | // HACK: try to build a fallback parent ID from the USR |
| 1115 | // otherwise we won't identify typedefed anon structs correctly :( |
| 1116 | auto parentFromUSR = [this]() -> QString { |
| 1117 | const auto containerUSR = ClangString(clang_codeCompleteGetContainerUSR(m_results.get())).toString(); |
| 1118 | const auto lastAt = containerUSR.lastIndexOf(QLatin1Char('@')); |
| 1119 | if (lastAt <= 0 || containerUSR[lastAt - 1] != QLatin1Char('A')) // we use this hack only for _A_non stuff |
| 1120 | return {}; |
| 1121 | |
| 1122 | return containerUSR.mid(lastAt + 1); |
| 1123 | }; |
| 1124 | const auto fallbackParentFromUSR = parentFromUSR(); |
| 1125 | |
| 1126 | clangDebug() << "Clang found" << m_results->NumResults << "completion results"; |
| 1127 | |
| 1128 | for (uint i = 0; i < m_results->NumResults; ++i) { |
| 1129 | if (abort) { |
| 1130 | return {}; |
| 1131 | } |
| 1132 | |
| 1133 | auto result = m_results->Results[i]; |
| 1134 | #if CINDEX_VERSION_MINOR >= 30 |
| 1135 | const bool isOverloadCandidate = result.CursorKind == CXCursor_OverloadCandidate; |
| 1136 | #else |
| 1137 | const bool isOverloadCandidate = false; |
| 1138 | #endif |
| 1139 | |
| 1140 | const auto availability = clang_getCompletionAvailability(result.CompletionString); |
| 1141 | if (availability == CXAvailability_NotAvailable) { |
| 1142 | continue; |
| 1143 | } |