1f4a2713aSLionel Sambuc //===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the Clang-C Source Indexing library hooks for
11f4a2713aSLionel Sambuc // code completion.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc
15f4a2713aSLionel Sambuc #include "CIndexer.h"
16f4a2713aSLionel Sambuc #include "CIndexDiagnostic.h"
17f4a2713aSLionel Sambuc #include "CLog.h"
18f4a2713aSLionel Sambuc #include "CXCursor.h"
19f4a2713aSLionel Sambuc #include "CXString.h"
20f4a2713aSLionel Sambuc #include "CXTranslationUnit.h"
21f4a2713aSLionel Sambuc #include "clang/AST/Decl.h"
22f4a2713aSLionel Sambuc #include "clang/AST/DeclObjC.h"
23f4a2713aSLionel Sambuc #include "clang/AST/Type.h"
24f4a2713aSLionel Sambuc #include "clang/Basic/FileManager.h"
25f4a2713aSLionel Sambuc #include "clang/Basic/SourceManager.h"
26f4a2713aSLionel Sambuc #include "clang/Frontend/ASTUnit.h"
27f4a2713aSLionel Sambuc #include "clang/Frontend/CompilerInstance.h"
28f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendDiagnostic.h"
29f4a2713aSLionel Sambuc #include "clang/Sema/CodeCompleteConsumer.h"
30f4a2713aSLionel Sambuc #include "clang/Sema/Sema.h"
31f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
32f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
33f4a2713aSLionel Sambuc #include "llvm/Support/CrashRecoveryContext.h"
34f4a2713aSLionel Sambuc #include "llvm/Support/FileSystem.h"
35f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
36f4a2713aSLionel Sambuc #include "llvm/Support/Program.h"
37f4a2713aSLionel Sambuc #include "llvm/Support/Timer.h"
38f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
39*0a6a1f1dSLionel Sambuc #if !defined(_LIBCPP_HAS_NO_THREADS) && defined(__minix)
40*0a6a1f1dSLionel Sambuc #include <atomic>
41*0a6a1f1dSLionel Sambuc #endif // !defined(_LIBCPP_HAS_NO_THREADS) && defined(__minix)
42f4a2713aSLionel Sambuc #include <cstdio>
43f4a2713aSLionel Sambuc #include <cstdlib>
44f4a2713aSLionel Sambuc #include <string>
45f4a2713aSLionel Sambuc
46f4a2713aSLionel Sambuc
47f4a2713aSLionel Sambuc #ifdef UDP_CODE_COMPLETION_LOGGER
48f4a2713aSLionel Sambuc #include "clang/Basic/Version.h"
49f4a2713aSLionel Sambuc #include <arpa/inet.h>
50f4a2713aSLionel Sambuc #include <sys/socket.h>
51f4a2713aSLionel Sambuc #include <sys/types.h>
52f4a2713aSLionel Sambuc #include <unistd.h>
53f4a2713aSLionel Sambuc #endif
54f4a2713aSLionel Sambuc
55f4a2713aSLionel Sambuc using namespace clang;
56f4a2713aSLionel Sambuc using namespace clang::cxindex;
57f4a2713aSLionel Sambuc
58f4a2713aSLionel Sambuc extern "C" {
59f4a2713aSLionel Sambuc
60f4a2713aSLionel Sambuc enum CXCompletionChunkKind
clang_getCompletionChunkKind(CXCompletionString completion_string,unsigned chunk_number)61f4a2713aSLionel Sambuc clang_getCompletionChunkKind(CXCompletionString completion_string,
62f4a2713aSLionel Sambuc unsigned chunk_number) {
63f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
64f4a2713aSLionel Sambuc if (!CCStr || chunk_number >= CCStr->size())
65f4a2713aSLionel Sambuc return CXCompletionChunk_Text;
66f4a2713aSLionel Sambuc
67f4a2713aSLionel Sambuc switch ((*CCStr)[chunk_number].Kind) {
68f4a2713aSLionel Sambuc case CodeCompletionString::CK_TypedText:
69f4a2713aSLionel Sambuc return CXCompletionChunk_TypedText;
70f4a2713aSLionel Sambuc case CodeCompletionString::CK_Text:
71f4a2713aSLionel Sambuc return CXCompletionChunk_Text;
72f4a2713aSLionel Sambuc case CodeCompletionString::CK_Optional:
73f4a2713aSLionel Sambuc return CXCompletionChunk_Optional;
74f4a2713aSLionel Sambuc case CodeCompletionString::CK_Placeholder:
75f4a2713aSLionel Sambuc return CXCompletionChunk_Placeholder;
76f4a2713aSLionel Sambuc case CodeCompletionString::CK_Informative:
77f4a2713aSLionel Sambuc return CXCompletionChunk_Informative;
78f4a2713aSLionel Sambuc case CodeCompletionString::CK_ResultType:
79f4a2713aSLionel Sambuc return CXCompletionChunk_ResultType;
80f4a2713aSLionel Sambuc case CodeCompletionString::CK_CurrentParameter:
81f4a2713aSLionel Sambuc return CXCompletionChunk_CurrentParameter;
82f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftParen:
83f4a2713aSLionel Sambuc return CXCompletionChunk_LeftParen;
84f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightParen:
85f4a2713aSLionel Sambuc return CXCompletionChunk_RightParen;
86f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftBracket:
87f4a2713aSLionel Sambuc return CXCompletionChunk_LeftBracket;
88f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightBracket:
89f4a2713aSLionel Sambuc return CXCompletionChunk_RightBracket;
90f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftBrace:
91f4a2713aSLionel Sambuc return CXCompletionChunk_LeftBrace;
92f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightBrace:
93f4a2713aSLionel Sambuc return CXCompletionChunk_RightBrace;
94f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftAngle:
95f4a2713aSLionel Sambuc return CXCompletionChunk_LeftAngle;
96f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightAngle:
97f4a2713aSLionel Sambuc return CXCompletionChunk_RightAngle;
98f4a2713aSLionel Sambuc case CodeCompletionString::CK_Comma:
99f4a2713aSLionel Sambuc return CXCompletionChunk_Comma;
100f4a2713aSLionel Sambuc case CodeCompletionString::CK_Colon:
101f4a2713aSLionel Sambuc return CXCompletionChunk_Colon;
102f4a2713aSLionel Sambuc case CodeCompletionString::CK_SemiColon:
103f4a2713aSLionel Sambuc return CXCompletionChunk_SemiColon;
104f4a2713aSLionel Sambuc case CodeCompletionString::CK_Equal:
105f4a2713aSLionel Sambuc return CXCompletionChunk_Equal;
106f4a2713aSLionel Sambuc case CodeCompletionString::CK_HorizontalSpace:
107f4a2713aSLionel Sambuc return CXCompletionChunk_HorizontalSpace;
108f4a2713aSLionel Sambuc case CodeCompletionString::CK_VerticalSpace:
109f4a2713aSLionel Sambuc return CXCompletionChunk_VerticalSpace;
110f4a2713aSLionel Sambuc }
111f4a2713aSLionel Sambuc
112f4a2713aSLionel Sambuc llvm_unreachable("Invalid CompletionKind!");
113f4a2713aSLionel Sambuc }
114f4a2713aSLionel Sambuc
clang_getCompletionChunkText(CXCompletionString completion_string,unsigned chunk_number)115f4a2713aSLionel Sambuc CXString clang_getCompletionChunkText(CXCompletionString completion_string,
116f4a2713aSLionel Sambuc unsigned chunk_number) {
117f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
118f4a2713aSLionel Sambuc if (!CCStr || chunk_number >= CCStr->size())
119f4a2713aSLionel Sambuc return cxstring::createNull();
120f4a2713aSLionel Sambuc
121f4a2713aSLionel Sambuc switch ((*CCStr)[chunk_number].Kind) {
122f4a2713aSLionel Sambuc case CodeCompletionString::CK_TypedText:
123f4a2713aSLionel Sambuc case CodeCompletionString::CK_Text:
124f4a2713aSLionel Sambuc case CodeCompletionString::CK_Placeholder:
125f4a2713aSLionel Sambuc case CodeCompletionString::CK_CurrentParameter:
126f4a2713aSLionel Sambuc case CodeCompletionString::CK_Informative:
127f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftParen:
128f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightParen:
129f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftBracket:
130f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightBracket:
131f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftBrace:
132f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightBrace:
133f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftAngle:
134f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightAngle:
135f4a2713aSLionel Sambuc case CodeCompletionString::CK_Comma:
136f4a2713aSLionel Sambuc case CodeCompletionString::CK_ResultType:
137f4a2713aSLionel Sambuc case CodeCompletionString::CK_Colon:
138f4a2713aSLionel Sambuc case CodeCompletionString::CK_SemiColon:
139f4a2713aSLionel Sambuc case CodeCompletionString::CK_Equal:
140f4a2713aSLionel Sambuc case CodeCompletionString::CK_HorizontalSpace:
141f4a2713aSLionel Sambuc case CodeCompletionString::CK_VerticalSpace:
142f4a2713aSLionel Sambuc return cxstring::createRef((*CCStr)[chunk_number].Text);
143f4a2713aSLionel Sambuc
144f4a2713aSLionel Sambuc case CodeCompletionString::CK_Optional:
145f4a2713aSLionel Sambuc // Note: treated as an empty text block.
146f4a2713aSLionel Sambuc return cxstring::createEmpty();
147f4a2713aSLionel Sambuc }
148f4a2713aSLionel Sambuc
149f4a2713aSLionel Sambuc llvm_unreachable("Invalid CodeCompletionString Kind!");
150f4a2713aSLionel Sambuc }
151f4a2713aSLionel Sambuc
152f4a2713aSLionel Sambuc
153f4a2713aSLionel Sambuc CXCompletionString
clang_getCompletionChunkCompletionString(CXCompletionString completion_string,unsigned chunk_number)154f4a2713aSLionel Sambuc clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
155f4a2713aSLionel Sambuc unsigned chunk_number) {
156f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
157f4a2713aSLionel Sambuc if (!CCStr || chunk_number >= CCStr->size())
158*0a6a1f1dSLionel Sambuc return nullptr;
159f4a2713aSLionel Sambuc
160f4a2713aSLionel Sambuc switch ((*CCStr)[chunk_number].Kind) {
161f4a2713aSLionel Sambuc case CodeCompletionString::CK_TypedText:
162f4a2713aSLionel Sambuc case CodeCompletionString::CK_Text:
163f4a2713aSLionel Sambuc case CodeCompletionString::CK_Placeholder:
164f4a2713aSLionel Sambuc case CodeCompletionString::CK_CurrentParameter:
165f4a2713aSLionel Sambuc case CodeCompletionString::CK_Informative:
166f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftParen:
167f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightParen:
168f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftBracket:
169f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightBracket:
170f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftBrace:
171f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightBrace:
172f4a2713aSLionel Sambuc case CodeCompletionString::CK_LeftAngle:
173f4a2713aSLionel Sambuc case CodeCompletionString::CK_RightAngle:
174f4a2713aSLionel Sambuc case CodeCompletionString::CK_Comma:
175f4a2713aSLionel Sambuc case CodeCompletionString::CK_ResultType:
176f4a2713aSLionel Sambuc case CodeCompletionString::CK_Colon:
177f4a2713aSLionel Sambuc case CodeCompletionString::CK_SemiColon:
178f4a2713aSLionel Sambuc case CodeCompletionString::CK_Equal:
179f4a2713aSLionel Sambuc case CodeCompletionString::CK_HorizontalSpace:
180f4a2713aSLionel Sambuc case CodeCompletionString::CK_VerticalSpace:
181*0a6a1f1dSLionel Sambuc return nullptr;
182f4a2713aSLionel Sambuc
183f4a2713aSLionel Sambuc case CodeCompletionString::CK_Optional:
184f4a2713aSLionel Sambuc // Note: treated as an empty text block.
185f4a2713aSLionel Sambuc return (*CCStr)[chunk_number].Optional;
186f4a2713aSLionel Sambuc }
187f4a2713aSLionel Sambuc
188f4a2713aSLionel Sambuc llvm_unreachable("Invalid CompletionKind!");
189f4a2713aSLionel Sambuc }
190f4a2713aSLionel Sambuc
clang_getNumCompletionChunks(CXCompletionString completion_string)191f4a2713aSLionel Sambuc unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
192f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
193f4a2713aSLionel Sambuc return CCStr? CCStr->size() : 0;
194f4a2713aSLionel Sambuc }
195f4a2713aSLionel Sambuc
clang_getCompletionPriority(CXCompletionString completion_string)196f4a2713aSLionel Sambuc unsigned clang_getCompletionPriority(CXCompletionString completion_string) {
197f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
198f4a2713aSLionel Sambuc return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
199f4a2713aSLionel Sambuc }
200f4a2713aSLionel Sambuc
201f4a2713aSLionel Sambuc enum CXAvailabilityKind
clang_getCompletionAvailability(CXCompletionString completion_string)202f4a2713aSLionel Sambuc clang_getCompletionAvailability(CXCompletionString completion_string) {
203f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
204f4a2713aSLionel Sambuc return CCStr? static_cast<CXAvailabilityKind>(CCStr->getAvailability())
205f4a2713aSLionel Sambuc : CXAvailability_Available;
206f4a2713aSLionel Sambuc }
207f4a2713aSLionel Sambuc
clang_getCompletionNumAnnotations(CXCompletionString completion_string)208f4a2713aSLionel Sambuc unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string)
209f4a2713aSLionel Sambuc {
210f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
211f4a2713aSLionel Sambuc return CCStr ? CCStr->getAnnotationCount() : 0;
212f4a2713aSLionel Sambuc }
213f4a2713aSLionel Sambuc
clang_getCompletionAnnotation(CXCompletionString completion_string,unsigned annotation_number)214f4a2713aSLionel Sambuc CXString clang_getCompletionAnnotation(CXCompletionString completion_string,
215f4a2713aSLionel Sambuc unsigned annotation_number) {
216f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
217f4a2713aSLionel Sambuc return CCStr ? cxstring::createRef(CCStr->getAnnotation(annotation_number))
218f4a2713aSLionel Sambuc : cxstring::createNull();
219f4a2713aSLionel Sambuc }
220f4a2713aSLionel Sambuc
221f4a2713aSLionel Sambuc CXString
clang_getCompletionParent(CXCompletionString completion_string,CXCursorKind * kind)222f4a2713aSLionel Sambuc clang_getCompletionParent(CXCompletionString completion_string,
223f4a2713aSLionel Sambuc CXCursorKind *kind) {
224f4a2713aSLionel Sambuc if (kind)
225f4a2713aSLionel Sambuc *kind = CXCursor_NotImplemented;
226f4a2713aSLionel Sambuc
227f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
228f4a2713aSLionel Sambuc if (!CCStr)
229f4a2713aSLionel Sambuc return cxstring::createNull();
230f4a2713aSLionel Sambuc
231f4a2713aSLionel Sambuc return cxstring::createRef(CCStr->getParentContextName());
232f4a2713aSLionel Sambuc }
233f4a2713aSLionel Sambuc
234f4a2713aSLionel Sambuc CXString
clang_getCompletionBriefComment(CXCompletionString completion_string)235f4a2713aSLionel Sambuc clang_getCompletionBriefComment(CXCompletionString completion_string) {
236f4a2713aSLionel Sambuc CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
237f4a2713aSLionel Sambuc
238f4a2713aSLionel Sambuc if (!CCStr)
239f4a2713aSLionel Sambuc return cxstring::createNull();
240f4a2713aSLionel Sambuc
241f4a2713aSLionel Sambuc return cxstring::createRef(CCStr->getBriefComment());
242f4a2713aSLionel Sambuc }
243f4a2713aSLionel Sambuc
244f4a2713aSLionel Sambuc namespace {
245f4a2713aSLionel Sambuc
246f4a2713aSLionel Sambuc /// \brief The CXCodeCompleteResults structure we allocate internally;
247f4a2713aSLionel Sambuc /// the client only sees the initial CXCodeCompleteResults structure.
248f4a2713aSLionel Sambuc ///
249f4a2713aSLionel Sambuc /// Normally, clients of CXString shouldn't care whether or not a CXString is
250f4a2713aSLionel Sambuc /// managed by a pool or by explicitly malloc'ed memory. But
251f4a2713aSLionel Sambuc /// AllocatedCXCodeCompleteResults outlives the CXTranslationUnit, so we can
252f4a2713aSLionel Sambuc /// not rely on the StringPool in the TU.
253f4a2713aSLionel Sambuc struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
254*0a6a1f1dSLionel Sambuc AllocatedCXCodeCompleteResults(IntrusiveRefCntPtr<FileManager> FileMgr);
255f4a2713aSLionel Sambuc ~AllocatedCXCodeCompleteResults();
256f4a2713aSLionel Sambuc
257f4a2713aSLionel Sambuc /// \brief Diagnostics produced while performing code completion.
258f4a2713aSLionel Sambuc SmallVector<StoredDiagnostic, 8> Diagnostics;
259f4a2713aSLionel Sambuc
260*0a6a1f1dSLionel Sambuc /// \brief Allocated API-exposed wrappters for Diagnostics.
261*0a6a1f1dSLionel Sambuc SmallVector<CXStoredDiagnostic *, 8> DiagnosticsWrappers;
262*0a6a1f1dSLionel Sambuc
263f4a2713aSLionel Sambuc IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
264f4a2713aSLionel Sambuc
265f4a2713aSLionel Sambuc /// \brief Diag object
266f4a2713aSLionel Sambuc IntrusiveRefCntPtr<DiagnosticsEngine> Diag;
267f4a2713aSLionel Sambuc
268f4a2713aSLionel Sambuc /// \brief Language options used to adjust source locations.
269f4a2713aSLionel Sambuc LangOptions LangOpts;
270f4a2713aSLionel Sambuc
271f4a2713aSLionel Sambuc /// \brief File manager, used for diagnostics.
272f4a2713aSLionel Sambuc IntrusiveRefCntPtr<FileManager> FileMgr;
273f4a2713aSLionel Sambuc
274f4a2713aSLionel Sambuc /// \brief Source manager, used for diagnostics.
275f4a2713aSLionel Sambuc IntrusiveRefCntPtr<SourceManager> SourceMgr;
276f4a2713aSLionel Sambuc
277f4a2713aSLionel Sambuc /// \brief Temporary files that should be removed once we have finished
278f4a2713aSLionel Sambuc /// with the code-completion results.
279f4a2713aSLionel Sambuc std::vector<std::string> TemporaryFiles;
280f4a2713aSLionel Sambuc
281f4a2713aSLionel Sambuc /// \brief Temporary buffers that will be deleted once we have finished with
282f4a2713aSLionel Sambuc /// the code-completion results.
283f4a2713aSLionel Sambuc SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
284f4a2713aSLionel Sambuc
285f4a2713aSLionel Sambuc /// \brief Allocator used to store globally cached code-completion results.
286f4a2713aSLionel Sambuc IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
287f4a2713aSLionel Sambuc CachedCompletionAllocator;
288f4a2713aSLionel Sambuc
289f4a2713aSLionel Sambuc /// \brief Allocator used to store code completion results.
290f4a2713aSLionel Sambuc IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
291f4a2713aSLionel Sambuc CodeCompletionAllocator;
292f4a2713aSLionel Sambuc
293f4a2713aSLionel Sambuc /// \brief Context under which completion occurred.
294f4a2713aSLionel Sambuc enum clang::CodeCompletionContext::Kind ContextKind;
295f4a2713aSLionel Sambuc
296f4a2713aSLionel Sambuc /// \brief A bitfield representing the acceptable completions for the
297f4a2713aSLionel Sambuc /// current context.
298f4a2713aSLionel Sambuc unsigned long long Contexts;
299f4a2713aSLionel Sambuc
300f4a2713aSLionel Sambuc /// \brief The kind of the container for the current context for completions.
301f4a2713aSLionel Sambuc enum CXCursorKind ContainerKind;
302f4a2713aSLionel Sambuc
303f4a2713aSLionel Sambuc /// \brief The USR of the container for the current context for completions.
304f4a2713aSLionel Sambuc std::string ContainerUSR;
305f4a2713aSLionel Sambuc
306f4a2713aSLionel Sambuc /// \brief a boolean value indicating whether there is complete information
307f4a2713aSLionel Sambuc /// about the container
308f4a2713aSLionel Sambuc unsigned ContainerIsIncomplete;
309f4a2713aSLionel Sambuc
310f4a2713aSLionel Sambuc /// \brief A string containing the Objective-C selector entered thus far for a
311f4a2713aSLionel Sambuc /// message send.
312f4a2713aSLionel Sambuc std::string Selector;
313f4a2713aSLionel Sambuc };
314f4a2713aSLionel Sambuc
315f4a2713aSLionel Sambuc } // end anonymous namespace
316f4a2713aSLionel Sambuc
317f4a2713aSLionel Sambuc /// \brief Tracks the number of code-completion result objects that are
318f4a2713aSLionel Sambuc /// currently active.
319f4a2713aSLionel Sambuc ///
320f4a2713aSLionel Sambuc /// Used for debugging purposes only.
321*0a6a1f1dSLionel Sambuc #if !defined(_LIBCPP_HAS_NO_THREADS) && defined(__minix)
322*0a6a1f1dSLionel Sambuc static std::atomic<unsigned> CodeCompletionResultObjects;
323*0a6a1f1dSLionel Sambuc #else
324*0a6a1f1dSLionel Sambuc static unsigned CodeCompletionResultObjects;
325*0a6a1f1dSLionel Sambuc #endif // !defined(_LIBCPP_HAS_NO_THREADS) && defined(__minix)
326f4a2713aSLionel Sambuc
AllocatedCXCodeCompleteResults(IntrusiveRefCntPtr<FileManager> FileMgr)327f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
328*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<FileManager> FileMgr)
329f4a2713aSLionel Sambuc : CXCodeCompleteResults(),
330f4a2713aSLionel Sambuc DiagOpts(new DiagnosticOptions),
331f4a2713aSLionel Sambuc Diag(new DiagnosticsEngine(
332*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts)),
333*0a6a1f1dSLionel Sambuc FileMgr(FileMgr), SourceMgr(new SourceManager(*Diag, *FileMgr)),
334f4a2713aSLionel Sambuc CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
335f4a2713aSLionel Sambuc Contexts(CXCompletionContext_Unknown),
336*0a6a1f1dSLionel Sambuc ContainerKind(CXCursor_InvalidCode), ContainerIsIncomplete(1) {
337*0a6a1f1dSLionel Sambuc if (getenv("LIBCLANG_OBJTRACKING"))
338*0a6a1f1dSLionel Sambuc fprintf(stderr, "+++ %u completion results\n",
339*0a6a1f1dSLionel Sambuc ++CodeCompletionResultObjects);
340f4a2713aSLionel Sambuc }
341f4a2713aSLionel Sambuc
~AllocatedCXCodeCompleteResults()342f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
343*0a6a1f1dSLionel Sambuc llvm::DeleteContainerPointers(DiagnosticsWrappers);
344f4a2713aSLionel Sambuc delete [] Results;
345f4a2713aSLionel Sambuc
346f4a2713aSLionel Sambuc for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
347f4a2713aSLionel Sambuc llvm::sys::fs::remove(TemporaryFiles[I]);
348f4a2713aSLionel Sambuc for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
349f4a2713aSLionel Sambuc delete TemporaryBuffers[I];
350f4a2713aSLionel Sambuc
351*0a6a1f1dSLionel Sambuc if (getenv("LIBCLANG_OBJTRACKING"))
352*0a6a1f1dSLionel Sambuc fprintf(stderr, "--- %u completion results\n",
353*0a6a1f1dSLionel Sambuc --CodeCompletionResultObjects);
354f4a2713aSLionel Sambuc }
355f4a2713aSLionel Sambuc
356f4a2713aSLionel Sambuc } // end extern "C"
357f4a2713aSLionel Sambuc
getContextsForContextKind(enum CodeCompletionContext::Kind kind,Sema & S)358f4a2713aSLionel Sambuc static unsigned long long getContextsForContextKind(
359f4a2713aSLionel Sambuc enum CodeCompletionContext::Kind kind,
360f4a2713aSLionel Sambuc Sema &S) {
361f4a2713aSLionel Sambuc unsigned long long contexts = 0;
362f4a2713aSLionel Sambuc switch (kind) {
363f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_OtherWithMacros: {
364f4a2713aSLionel Sambuc //We can allow macros here, but we don't know what else is permissible
365f4a2713aSLionel Sambuc //So we'll say the only thing permissible are macros
366f4a2713aSLionel Sambuc contexts = CXCompletionContext_MacroName;
367f4a2713aSLionel Sambuc break;
368f4a2713aSLionel Sambuc }
369f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_TopLevel:
370f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCIvarList:
371f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ClassStructUnion:
372f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_Type: {
373f4a2713aSLionel Sambuc contexts = CXCompletionContext_AnyType |
374f4a2713aSLionel Sambuc CXCompletionContext_ObjCInterface;
375f4a2713aSLionel Sambuc if (S.getLangOpts().CPlusPlus) {
376f4a2713aSLionel Sambuc contexts |= CXCompletionContext_EnumTag |
377f4a2713aSLionel Sambuc CXCompletionContext_UnionTag |
378f4a2713aSLionel Sambuc CXCompletionContext_StructTag |
379f4a2713aSLionel Sambuc CXCompletionContext_ClassTag |
380f4a2713aSLionel Sambuc CXCompletionContext_NestedNameSpecifier;
381f4a2713aSLionel Sambuc }
382f4a2713aSLionel Sambuc break;
383f4a2713aSLionel Sambuc }
384f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_Statement: {
385f4a2713aSLionel Sambuc contexts = CXCompletionContext_AnyType |
386f4a2713aSLionel Sambuc CXCompletionContext_ObjCInterface |
387f4a2713aSLionel Sambuc CXCompletionContext_AnyValue;
388f4a2713aSLionel Sambuc if (S.getLangOpts().CPlusPlus) {
389f4a2713aSLionel Sambuc contexts |= CXCompletionContext_EnumTag |
390f4a2713aSLionel Sambuc CXCompletionContext_UnionTag |
391f4a2713aSLionel Sambuc CXCompletionContext_StructTag |
392f4a2713aSLionel Sambuc CXCompletionContext_ClassTag |
393f4a2713aSLionel Sambuc CXCompletionContext_NestedNameSpecifier;
394f4a2713aSLionel Sambuc }
395f4a2713aSLionel Sambuc break;
396f4a2713aSLionel Sambuc }
397f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_Expression: {
398f4a2713aSLionel Sambuc contexts = CXCompletionContext_AnyValue;
399f4a2713aSLionel Sambuc if (S.getLangOpts().CPlusPlus) {
400f4a2713aSLionel Sambuc contexts |= CXCompletionContext_AnyType |
401f4a2713aSLionel Sambuc CXCompletionContext_ObjCInterface |
402f4a2713aSLionel Sambuc CXCompletionContext_EnumTag |
403f4a2713aSLionel Sambuc CXCompletionContext_UnionTag |
404f4a2713aSLionel Sambuc CXCompletionContext_StructTag |
405f4a2713aSLionel Sambuc CXCompletionContext_ClassTag |
406f4a2713aSLionel Sambuc CXCompletionContext_NestedNameSpecifier;
407f4a2713aSLionel Sambuc }
408f4a2713aSLionel Sambuc break;
409f4a2713aSLionel Sambuc }
410f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCMessageReceiver: {
411f4a2713aSLionel Sambuc contexts = CXCompletionContext_ObjCObjectValue |
412f4a2713aSLionel Sambuc CXCompletionContext_ObjCSelectorValue |
413f4a2713aSLionel Sambuc CXCompletionContext_ObjCInterface;
414f4a2713aSLionel Sambuc if (S.getLangOpts().CPlusPlus) {
415f4a2713aSLionel Sambuc contexts |= CXCompletionContext_CXXClassTypeValue |
416f4a2713aSLionel Sambuc CXCompletionContext_AnyType |
417f4a2713aSLionel Sambuc CXCompletionContext_EnumTag |
418f4a2713aSLionel Sambuc CXCompletionContext_UnionTag |
419f4a2713aSLionel Sambuc CXCompletionContext_StructTag |
420f4a2713aSLionel Sambuc CXCompletionContext_ClassTag |
421f4a2713aSLionel Sambuc CXCompletionContext_NestedNameSpecifier;
422f4a2713aSLionel Sambuc }
423f4a2713aSLionel Sambuc break;
424f4a2713aSLionel Sambuc }
425f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_DotMemberAccess: {
426f4a2713aSLionel Sambuc contexts = CXCompletionContext_DotMemberAccess;
427f4a2713aSLionel Sambuc break;
428f4a2713aSLionel Sambuc }
429f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ArrowMemberAccess: {
430f4a2713aSLionel Sambuc contexts = CXCompletionContext_ArrowMemberAccess;
431f4a2713aSLionel Sambuc break;
432f4a2713aSLionel Sambuc }
433f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCPropertyAccess: {
434f4a2713aSLionel Sambuc contexts = CXCompletionContext_ObjCPropertyAccess;
435f4a2713aSLionel Sambuc break;
436f4a2713aSLionel Sambuc }
437f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_EnumTag: {
438f4a2713aSLionel Sambuc contexts = CXCompletionContext_EnumTag |
439f4a2713aSLionel Sambuc CXCompletionContext_NestedNameSpecifier;
440f4a2713aSLionel Sambuc break;
441f4a2713aSLionel Sambuc }
442f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_UnionTag: {
443f4a2713aSLionel Sambuc contexts = CXCompletionContext_UnionTag |
444f4a2713aSLionel Sambuc CXCompletionContext_NestedNameSpecifier;
445f4a2713aSLionel Sambuc break;
446f4a2713aSLionel Sambuc }
447f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ClassOrStructTag: {
448f4a2713aSLionel Sambuc contexts = CXCompletionContext_StructTag |
449f4a2713aSLionel Sambuc CXCompletionContext_ClassTag |
450f4a2713aSLionel Sambuc CXCompletionContext_NestedNameSpecifier;
451f4a2713aSLionel Sambuc break;
452f4a2713aSLionel Sambuc }
453f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCProtocolName: {
454f4a2713aSLionel Sambuc contexts = CXCompletionContext_ObjCProtocol;
455f4a2713aSLionel Sambuc break;
456f4a2713aSLionel Sambuc }
457f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_Namespace: {
458f4a2713aSLionel Sambuc contexts = CXCompletionContext_Namespace;
459f4a2713aSLionel Sambuc break;
460f4a2713aSLionel Sambuc }
461f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_PotentiallyQualifiedName: {
462f4a2713aSLionel Sambuc contexts = CXCompletionContext_NestedNameSpecifier;
463f4a2713aSLionel Sambuc break;
464f4a2713aSLionel Sambuc }
465f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_MacroNameUse: {
466f4a2713aSLionel Sambuc contexts = CXCompletionContext_MacroName;
467f4a2713aSLionel Sambuc break;
468f4a2713aSLionel Sambuc }
469f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_NaturalLanguage: {
470f4a2713aSLionel Sambuc contexts = CXCompletionContext_NaturalLanguage;
471f4a2713aSLionel Sambuc break;
472f4a2713aSLionel Sambuc }
473f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_SelectorName: {
474f4a2713aSLionel Sambuc contexts = CXCompletionContext_ObjCSelectorName;
475f4a2713aSLionel Sambuc break;
476f4a2713aSLionel Sambuc }
477f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ParenthesizedExpression: {
478f4a2713aSLionel Sambuc contexts = CXCompletionContext_AnyType |
479f4a2713aSLionel Sambuc CXCompletionContext_ObjCInterface |
480f4a2713aSLionel Sambuc CXCompletionContext_AnyValue;
481f4a2713aSLionel Sambuc if (S.getLangOpts().CPlusPlus) {
482f4a2713aSLionel Sambuc contexts |= CXCompletionContext_EnumTag |
483f4a2713aSLionel Sambuc CXCompletionContext_UnionTag |
484f4a2713aSLionel Sambuc CXCompletionContext_StructTag |
485f4a2713aSLionel Sambuc CXCompletionContext_ClassTag |
486f4a2713aSLionel Sambuc CXCompletionContext_NestedNameSpecifier;
487f4a2713aSLionel Sambuc }
488f4a2713aSLionel Sambuc break;
489f4a2713aSLionel Sambuc }
490f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCInstanceMessage: {
491f4a2713aSLionel Sambuc contexts = CXCompletionContext_ObjCInstanceMessage;
492f4a2713aSLionel Sambuc break;
493f4a2713aSLionel Sambuc }
494f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCClassMessage: {
495f4a2713aSLionel Sambuc contexts = CXCompletionContext_ObjCClassMessage;
496f4a2713aSLionel Sambuc break;
497f4a2713aSLionel Sambuc }
498f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCInterfaceName: {
499f4a2713aSLionel Sambuc contexts = CXCompletionContext_ObjCInterface;
500f4a2713aSLionel Sambuc break;
501f4a2713aSLionel Sambuc }
502f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCCategoryName: {
503f4a2713aSLionel Sambuc contexts = CXCompletionContext_ObjCCategory;
504f4a2713aSLionel Sambuc break;
505f4a2713aSLionel Sambuc }
506f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_Other:
507f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCInterface:
508f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_ObjCImplementation:
509f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_Name:
510f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_MacroName:
511f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_PreprocessorExpression:
512f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_PreprocessorDirective:
513f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_TypeQualifiers: {
514f4a2713aSLionel Sambuc //Only Clang results should be accepted, so we'll set all of the other
515f4a2713aSLionel Sambuc //context bits to 0 (i.e. the empty set)
516f4a2713aSLionel Sambuc contexts = CXCompletionContext_Unexposed;
517f4a2713aSLionel Sambuc break;
518f4a2713aSLionel Sambuc }
519f4a2713aSLionel Sambuc case CodeCompletionContext::CCC_Recovery: {
520f4a2713aSLionel Sambuc //We don't know what the current context is, so we'll return unknown
521f4a2713aSLionel Sambuc //This is the equivalent of setting all of the other context bits
522f4a2713aSLionel Sambuc contexts = CXCompletionContext_Unknown;
523f4a2713aSLionel Sambuc break;
524f4a2713aSLionel Sambuc }
525f4a2713aSLionel Sambuc }
526f4a2713aSLionel Sambuc return contexts;
527f4a2713aSLionel Sambuc }
528f4a2713aSLionel Sambuc
529f4a2713aSLionel Sambuc namespace {
530f4a2713aSLionel Sambuc class CaptureCompletionResults : public CodeCompleteConsumer {
531f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults &AllocatedResults;
532f4a2713aSLionel Sambuc CodeCompletionTUInfo CCTUInfo;
533f4a2713aSLionel Sambuc SmallVector<CXCompletionResult, 16> StoredResults;
534f4a2713aSLionel Sambuc CXTranslationUnit *TU;
535f4a2713aSLionel Sambuc public:
CaptureCompletionResults(const CodeCompleteOptions & Opts,AllocatedCXCodeCompleteResults & Results,CXTranslationUnit * TranslationUnit)536f4a2713aSLionel Sambuc CaptureCompletionResults(const CodeCompleteOptions &Opts,
537f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults &Results,
538f4a2713aSLionel Sambuc CXTranslationUnit *TranslationUnit)
539f4a2713aSLionel Sambuc : CodeCompleteConsumer(Opts, false),
540f4a2713aSLionel Sambuc AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
541f4a2713aSLionel Sambuc TU(TranslationUnit) { }
~CaptureCompletionResults()542f4a2713aSLionel Sambuc ~CaptureCompletionResults() { Finish(); }
543f4a2713aSLionel Sambuc
ProcessCodeCompleteResults(Sema & S,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)544*0a6a1f1dSLionel Sambuc void ProcessCodeCompleteResults(Sema &S,
545f4a2713aSLionel Sambuc CodeCompletionContext Context,
546f4a2713aSLionel Sambuc CodeCompletionResult *Results,
547*0a6a1f1dSLionel Sambuc unsigned NumResults) override {
548f4a2713aSLionel Sambuc StoredResults.reserve(StoredResults.size() + NumResults);
549f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumResults; ++I) {
550f4a2713aSLionel Sambuc CodeCompletionString *StoredCompletion
551f4a2713aSLionel Sambuc = Results[I].CreateCodeCompletionString(S, getAllocator(),
552f4a2713aSLionel Sambuc getCodeCompletionTUInfo(),
553f4a2713aSLionel Sambuc includeBriefComments());
554f4a2713aSLionel Sambuc
555f4a2713aSLionel Sambuc CXCompletionResult R;
556f4a2713aSLionel Sambuc R.CursorKind = Results[I].CursorKind;
557f4a2713aSLionel Sambuc R.CompletionString = StoredCompletion;
558f4a2713aSLionel Sambuc StoredResults.push_back(R);
559f4a2713aSLionel Sambuc }
560f4a2713aSLionel Sambuc
561f4a2713aSLionel Sambuc enum CodeCompletionContext::Kind contextKind = Context.getKind();
562f4a2713aSLionel Sambuc
563f4a2713aSLionel Sambuc AllocatedResults.ContextKind = contextKind;
564f4a2713aSLionel Sambuc AllocatedResults.Contexts = getContextsForContextKind(contextKind, S);
565f4a2713aSLionel Sambuc
566f4a2713aSLionel Sambuc AllocatedResults.Selector = "";
567f4a2713aSLionel Sambuc ArrayRef<IdentifierInfo *> SelIdents = Context.getSelIdents();
568f4a2713aSLionel Sambuc for (ArrayRef<IdentifierInfo *>::iterator I = SelIdents.begin(),
569f4a2713aSLionel Sambuc E = SelIdents.end();
570f4a2713aSLionel Sambuc I != E; ++I) {
571f4a2713aSLionel Sambuc if (IdentifierInfo *selIdent = *I)
572f4a2713aSLionel Sambuc AllocatedResults.Selector += selIdent->getName();
573f4a2713aSLionel Sambuc AllocatedResults.Selector += ":";
574f4a2713aSLionel Sambuc }
575f4a2713aSLionel Sambuc
576f4a2713aSLionel Sambuc QualType baseType = Context.getBaseType();
577*0a6a1f1dSLionel Sambuc NamedDecl *D = nullptr;
578f4a2713aSLionel Sambuc
579f4a2713aSLionel Sambuc if (!baseType.isNull()) {
580f4a2713aSLionel Sambuc // Get the declaration for a class/struct/union/enum type
581f4a2713aSLionel Sambuc if (const TagType *Tag = baseType->getAs<TagType>())
582f4a2713aSLionel Sambuc D = Tag->getDecl();
583f4a2713aSLionel Sambuc // Get the @interface declaration for a (possibly-qualified) Objective-C
584f4a2713aSLionel Sambuc // object pointer type, e.g., NSString*
585f4a2713aSLionel Sambuc else if (const ObjCObjectPointerType *ObjPtr =
586f4a2713aSLionel Sambuc baseType->getAs<ObjCObjectPointerType>())
587f4a2713aSLionel Sambuc D = ObjPtr->getInterfaceDecl();
588f4a2713aSLionel Sambuc // Get the @interface declaration for an Objective-C object type
589f4a2713aSLionel Sambuc else if (const ObjCObjectType *Obj = baseType->getAs<ObjCObjectType>())
590f4a2713aSLionel Sambuc D = Obj->getInterface();
591f4a2713aSLionel Sambuc // Get the class for a C++ injected-class-name
592f4a2713aSLionel Sambuc else if (const InjectedClassNameType *Injected =
593f4a2713aSLionel Sambuc baseType->getAs<InjectedClassNameType>())
594f4a2713aSLionel Sambuc D = Injected->getDecl();
595f4a2713aSLionel Sambuc }
596f4a2713aSLionel Sambuc
597*0a6a1f1dSLionel Sambuc if (D != nullptr) {
598f4a2713aSLionel Sambuc CXCursor cursor = cxcursor::MakeCXCursor(D, *TU);
599f4a2713aSLionel Sambuc
600f4a2713aSLionel Sambuc AllocatedResults.ContainerKind = clang_getCursorKind(cursor);
601f4a2713aSLionel Sambuc
602f4a2713aSLionel Sambuc CXString CursorUSR = clang_getCursorUSR(cursor);
603f4a2713aSLionel Sambuc AllocatedResults.ContainerUSR = clang_getCString(CursorUSR);
604f4a2713aSLionel Sambuc clang_disposeString(CursorUSR);
605f4a2713aSLionel Sambuc
606f4a2713aSLionel Sambuc const Type *type = baseType.getTypePtrOrNull();
607*0a6a1f1dSLionel Sambuc if (type) {
608f4a2713aSLionel Sambuc AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
609f4a2713aSLionel Sambuc }
610f4a2713aSLionel Sambuc else {
611f4a2713aSLionel Sambuc AllocatedResults.ContainerIsIncomplete = 1;
612f4a2713aSLionel Sambuc }
613f4a2713aSLionel Sambuc }
614f4a2713aSLionel Sambuc else {
615f4a2713aSLionel Sambuc AllocatedResults.ContainerKind = CXCursor_InvalidCode;
616f4a2713aSLionel Sambuc AllocatedResults.ContainerUSR.clear();
617f4a2713aSLionel Sambuc AllocatedResults.ContainerIsIncomplete = 1;
618f4a2713aSLionel Sambuc }
619f4a2713aSLionel Sambuc }
620f4a2713aSLionel Sambuc
ProcessOverloadCandidates(Sema & S,unsigned CurrentArg,OverloadCandidate * Candidates,unsigned NumCandidates)621*0a6a1f1dSLionel Sambuc void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
622f4a2713aSLionel Sambuc OverloadCandidate *Candidates,
623*0a6a1f1dSLionel Sambuc unsigned NumCandidates) override {
624f4a2713aSLionel Sambuc StoredResults.reserve(StoredResults.size() + NumCandidates);
625f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumCandidates; ++I) {
626f4a2713aSLionel Sambuc CodeCompletionString *StoredCompletion
627f4a2713aSLionel Sambuc = Candidates[I].CreateSignatureString(CurrentArg, S, getAllocator(),
628f4a2713aSLionel Sambuc getCodeCompletionTUInfo());
629f4a2713aSLionel Sambuc
630f4a2713aSLionel Sambuc CXCompletionResult R;
631f4a2713aSLionel Sambuc R.CursorKind = CXCursor_NotImplemented;
632f4a2713aSLionel Sambuc R.CompletionString = StoredCompletion;
633f4a2713aSLionel Sambuc StoredResults.push_back(R);
634f4a2713aSLionel Sambuc }
635f4a2713aSLionel Sambuc }
636f4a2713aSLionel Sambuc
getAllocator()637*0a6a1f1dSLionel Sambuc CodeCompletionAllocator &getAllocator() override {
638f4a2713aSLionel Sambuc return *AllocatedResults.CodeCompletionAllocator;
639f4a2713aSLionel Sambuc }
640f4a2713aSLionel Sambuc
getCodeCompletionTUInfo()641*0a6a1f1dSLionel Sambuc CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;}
642f4a2713aSLionel Sambuc
643f4a2713aSLionel Sambuc private:
Finish()644f4a2713aSLionel Sambuc void Finish() {
645f4a2713aSLionel Sambuc AllocatedResults.Results = new CXCompletionResult [StoredResults.size()];
646f4a2713aSLionel Sambuc AllocatedResults.NumResults = StoredResults.size();
647f4a2713aSLionel Sambuc std::memcpy(AllocatedResults.Results, StoredResults.data(),
648f4a2713aSLionel Sambuc StoredResults.size() * sizeof(CXCompletionResult));
649f4a2713aSLionel Sambuc StoredResults.clear();
650f4a2713aSLionel Sambuc }
651f4a2713aSLionel Sambuc };
652f4a2713aSLionel Sambuc }
653f4a2713aSLionel Sambuc
654f4a2713aSLionel Sambuc extern "C" {
655f4a2713aSLionel Sambuc struct CodeCompleteAtInfo {
656f4a2713aSLionel Sambuc CXTranslationUnit TU;
657f4a2713aSLionel Sambuc const char *complete_filename;
658f4a2713aSLionel Sambuc unsigned complete_line;
659f4a2713aSLionel Sambuc unsigned complete_column;
660*0a6a1f1dSLionel Sambuc ArrayRef<CXUnsavedFile> unsaved_files;
661f4a2713aSLionel Sambuc unsigned options;
662f4a2713aSLionel Sambuc CXCodeCompleteResults *result;
663f4a2713aSLionel Sambuc };
clang_codeCompleteAt_Impl(void * UserData)664f4a2713aSLionel Sambuc void clang_codeCompleteAt_Impl(void *UserData) {
665f4a2713aSLionel Sambuc CodeCompleteAtInfo *CCAI = static_cast<CodeCompleteAtInfo*>(UserData);
666f4a2713aSLionel Sambuc CXTranslationUnit TU = CCAI->TU;
667f4a2713aSLionel Sambuc const char *complete_filename = CCAI->complete_filename;
668f4a2713aSLionel Sambuc unsigned complete_line = CCAI->complete_line;
669f4a2713aSLionel Sambuc unsigned complete_column = CCAI->complete_column;
670f4a2713aSLionel Sambuc unsigned options = CCAI->options;
671f4a2713aSLionel Sambuc bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
672*0a6a1f1dSLionel Sambuc CCAI->result = nullptr;
673f4a2713aSLionel Sambuc
674f4a2713aSLionel Sambuc #ifdef UDP_CODE_COMPLETION_LOGGER
675f4a2713aSLionel Sambuc #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
676f4a2713aSLionel Sambuc const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime();
677f4a2713aSLionel Sambuc #endif
678f4a2713aSLionel Sambuc #endif
679f4a2713aSLionel Sambuc
680*0a6a1f1dSLionel Sambuc bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr;
681*0a6a1f1dSLionel Sambuc
682*0a6a1f1dSLionel Sambuc if (cxtu::isNotUsableTU(TU)) {
683*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
684*0a6a1f1dSLionel Sambuc return;
685*0a6a1f1dSLionel Sambuc }
686f4a2713aSLionel Sambuc
687f4a2713aSLionel Sambuc ASTUnit *AST = cxtu::getASTUnit(TU);
688f4a2713aSLionel Sambuc if (!AST)
689f4a2713aSLionel Sambuc return;
690f4a2713aSLionel Sambuc
691f4a2713aSLionel Sambuc CIndexer *CXXIdx = TU->CIdx;
692f4a2713aSLionel Sambuc if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
693f4a2713aSLionel Sambuc setThreadBackgroundPriority();
694f4a2713aSLionel Sambuc
695f4a2713aSLionel Sambuc ASTUnit::ConcurrencyCheck Check(*AST);
696f4a2713aSLionel Sambuc
697f4a2713aSLionel Sambuc // Perform the remapping of source files.
698f4a2713aSLionel Sambuc SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
699*0a6a1f1dSLionel Sambuc
700*0a6a1f1dSLionel Sambuc for (auto &UF : CCAI->unsaved_files) {
701*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::MemoryBuffer> MB =
702*0a6a1f1dSLionel Sambuc llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
703*0a6a1f1dSLionel Sambuc RemappedFiles.push_back(std::make_pair(UF.Filename, MB.release()));
704f4a2713aSLionel Sambuc }
705f4a2713aSLionel Sambuc
706f4a2713aSLionel Sambuc if (EnableLogging) {
707f4a2713aSLionel Sambuc // FIXME: Add logging.
708f4a2713aSLionel Sambuc }
709f4a2713aSLionel Sambuc
710f4a2713aSLionel Sambuc // Parse the resulting source file to find code-completion results.
711*0a6a1f1dSLionel Sambuc AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults(
712*0a6a1f1dSLionel Sambuc &AST->getFileManager());
713*0a6a1f1dSLionel Sambuc Results->Results = nullptr;
714f4a2713aSLionel Sambuc Results->NumResults = 0;
715f4a2713aSLionel Sambuc
716f4a2713aSLionel Sambuc // Create a code-completion consumer to capture the results.
717f4a2713aSLionel Sambuc CodeCompleteOptions Opts;
718f4a2713aSLionel Sambuc Opts.IncludeBriefComments = IncludeBriefComments;
719f4a2713aSLionel Sambuc CaptureCompletionResults Capture(Opts, *Results, &TU);
720f4a2713aSLionel Sambuc
721f4a2713aSLionel Sambuc // Perform completion.
722f4a2713aSLionel Sambuc AST->CodeComplete(complete_filename, complete_line, complete_column,
723*0a6a1f1dSLionel Sambuc RemappedFiles,
724f4a2713aSLionel Sambuc (options & CXCodeComplete_IncludeMacros),
725f4a2713aSLionel Sambuc (options & CXCodeComplete_IncludeCodePatterns),
726f4a2713aSLionel Sambuc IncludeBriefComments,
727f4a2713aSLionel Sambuc Capture,
728f4a2713aSLionel Sambuc *Results->Diag, Results->LangOpts, *Results->SourceMgr,
729f4a2713aSLionel Sambuc *Results->FileMgr, Results->Diagnostics,
730f4a2713aSLionel Sambuc Results->TemporaryBuffers);
731f4a2713aSLionel Sambuc
732*0a6a1f1dSLionel Sambuc Results->DiagnosticsWrappers.resize(Results->Diagnostics.size());
733*0a6a1f1dSLionel Sambuc
734f4a2713aSLionel Sambuc // Keep a reference to the allocator used for cached global completions, so
735f4a2713aSLionel Sambuc // that we can be sure that the memory used by our code completion strings
736f4a2713aSLionel Sambuc // doesn't get freed due to subsequent reparses (while the code completion
737f4a2713aSLionel Sambuc // results are still active).
738f4a2713aSLionel Sambuc Results->CachedCompletionAllocator = AST->getCachedCompletionAllocator();
739f4a2713aSLionel Sambuc
740f4a2713aSLionel Sambuc
741f4a2713aSLionel Sambuc
742f4a2713aSLionel Sambuc #ifdef UDP_CODE_COMPLETION_LOGGER
743f4a2713aSLionel Sambuc #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
744f4a2713aSLionel Sambuc const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime();
745f4a2713aSLionel Sambuc SmallString<256> LogResult;
746f4a2713aSLionel Sambuc llvm::raw_svector_ostream os(LogResult);
747f4a2713aSLionel Sambuc
748f4a2713aSLionel Sambuc // Figure out the language and whether or not it uses PCH.
749f4a2713aSLionel Sambuc const char *lang = 0;
750f4a2713aSLionel Sambuc bool usesPCH = false;
751f4a2713aSLionel Sambuc
752f4a2713aSLionel Sambuc for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
753f4a2713aSLionel Sambuc I != E; ++I) {
754f4a2713aSLionel Sambuc if (*I == 0)
755f4a2713aSLionel Sambuc continue;
756f4a2713aSLionel Sambuc if (strcmp(*I, "-x") == 0) {
757f4a2713aSLionel Sambuc if (I + 1 != E) {
758f4a2713aSLionel Sambuc lang = *(++I);
759f4a2713aSLionel Sambuc continue;
760f4a2713aSLionel Sambuc }
761f4a2713aSLionel Sambuc }
762f4a2713aSLionel Sambuc else if (strcmp(*I, "-include") == 0) {
763f4a2713aSLionel Sambuc if (I+1 != E) {
764f4a2713aSLionel Sambuc const char *arg = *(++I);
765f4a2713aSLionel Sambuc SmallString<512> pchName;
766f4a2713aSLionel Sambuc {
767f4a2713aSLionel Sambuc llvm::raw_svector_ostream os(pchName);
768f4a2713aSLionel Sambuc os << arg << ".pth";
769f4a2713aSLionel Sambuc }
770f4a2713aSLionel Sambuc pchName.push_back('\0');
771f4a2713aSLionel Sambuc struct stat stat_results;
772f4a2713aSLionel Sambuc if (stat(pchName.str().c_str(), &stat_results) == 0)
773f4a2713aSLionel Sambuc usesPCH = true;
774f4a2713aSLionel Sambuc continue;
775f4a2713aSLionel Sambuc }
776f4a2713aSLionel Sambuc }
777f4a2713aSLionel Sambuc }
778f4a2713aSLionel Sambuc
779f4a2713aSLionel Sambuc os << "{ ";
780f4a2713aSLionel Sambuc os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
781f4a2713aSLionel Sambuc os << ", \"numRes\": " << Results->NumResults;
782f4a2713aSLionel Sambuc os << ", \"diags\": " << Results->Diagnostics.size();
783f4a2713aSLionel Sambuc os << ", \"pch\": " << (usesPCH ? "true" : "false");
784f4a2713aSLionel Sambuc os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
785f4a2713aSLionel Sambuc const char *name = getlogin();
786f4a2713aSLionel Sambuc os << ", \"user\": \"" << (name ? name : "unknown") << '"';
787f4a2713aSLionel Sambuc os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
788f4a2713aSLionel Sambuc os << " }";
789f4a2713aSLionel Sambuc
790f4a2713aSLionel Sambuc StringRef res = os.str();
791f4a2713aSLionel Sambuc if (res.size() > 0) {
792f4a2713aSLionel Sambuc do {
793f4a2713aSLionel Sambuc // Setup the UDP socket.
794f4a2713aSLionel Sambuc struct sockaddr_in servaddr;
795f4a2713aSLionel Sambuc bzero(&servaddr, sizeof(servaddr));
796f4a2713aSLionel Sambuc servaddr.sin_family = AF_INET;
797f4a2713aSLionel Sambuc servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
798f4a2713aSLionel Sambuc if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
799f4a2713aSLionel Sambuc &servaddr.sin_addr) <= 0)
800f4a2713aSLionel Sambuc break;
801f4a2713aSLionel Sambuc
802f4a2713aSLionel Sambuc int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
803f4a2713aSLionel Sambuc if (sockfd < 0)
804f4a2713aSLionel Sambuc break;
805f4a2713aSLionel Sambuc
806f4a2713aSLionel Sambuc sendto(sockfd, res.data(), res.size(), 0,
807f4a2713aSLionel Sambuc (struct sockaddr *)&servaddr, sizeof(servaddr));
808f4a2713aSLionel Sambuc close(sockfd);
809f4a2713aSLionel Sambuc }
810f4a2713aSLionel Sambuc while (false);
811f4a2713aSLionel Sambuc }
812f4a2713aSLionel Sambuc #endif
813f4a2713aSLionel Sambuc #endif
814f4a2713aSLionel Sambuc CCAI->result = Results;
815f4a2713aSLionel Sambuc }
clang_codeCompleteAt(CXTranslationUnit TU,const char * complete_filename,unsigned complete_line,unsigned complete_column,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options)816f4a2713aSLionel Sambuc CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
817f4a2713aSLionel Sambuc const char *complete_filename,
818f4a2713aSLionel Sambuc unsigned complete_line,
819f4a2713aSLionel Sambuc unsigned complete_column,
820f4a2713aSLionel Sambuc struct CXUnsavedFile *unsaved_files,
821f4a2713aSLionel Sambuc unsigned num_unsaved_files,
822f4a2713aSLionel Sambuc unsigned options) {
823f4a2713aSLionel Sambuc LOG_FUNC_SECTION {
824f4a2713aSLionel Sambuc *Log << TU << ' '
825f4a2713aSLionel Sambuc << complete_filename << ':' << complete_line << ':' << complete_column;
826f4a2713aSLionel Sambuc }
827f4a2713aSLionel Sambuc
828*0a6a1f1dSLionel Sambuc if (num_unsaved_files && !unsaved_files)
829*0a6a1f1dSLionel Sambuc return nullptr;
830*0a6a1f1dSLionel Sambuc
831f4a2713aSLionel Sambuc CodeCompleteAtInfo CCAI = {TU, complete_filename, complete_line,
832*0a6a1f1dSLionel Sambuc complete_column, llvm::makeArrayRef(unsaved_files, num_unsaved_files),
833*0a6a1f1dSLionel Sambuc options, nullptr};
834f4a2713aSLionel Sambuc
835f4a2713aSLionel Sambuc if (getenv("LIBCLANG_NOTHREADS")) {
836f4a2713aSLionel Sambuc clang_codeCompleteAt_Impl(&CCAI);
837f4a2713aSLionel Sambuc return CCAI.result;
838f4a2713aSLionel Sambuc }
839f4a2713aSLionel Sambuc
840f4a2713aSLionel Sambuc llvm::CrashRecoveryContext CRC;
841f4a2713aSLionel Sambuc
842f4a2713aSLionel Sambuc if (!RunSafely(CRC, clang_codeCompleteAt_Impl, &CCAI)) {
843f4a2713aSLionel Sambuc fprintf(stderr, "libclang: crash detected in code completion\n");
844f4a2713aSLionel Sambuc cxtu::getASTUnit(TU)->setUnsafeToFree(true);
845*0a6a1f1dSLionel Sambuc return nullptr;
846f4a2713aSLionel Sambuc } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
847f4a2713aSLionel Sambuc PrintLibclangResourceUsage(TU);
848f4a2713aSLionel Sambuc
849f4a2713aSLionel Sambuc return CCAI.result;
850f4a2713aSLionel Sambuc }
851f4a2713aSLionel Sambuc
clang_defaultCodeCompleteOptions(void)852f4a2713aSLionel Sambuc unsigned clang_defaultCodeCompleteOptions(void) {
853f4a2713aSLionel Sambuc return CXCodeComplete_IncludeMacros;
854f4a2713aSLionel Sambuc }
855f4a2713aSLionel Sambuc
clang_disposeCodeCompleteResults(CXCodeCompleteResults * ResultsIn)856f4a2713aSLionel Sambuc void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
857f4a2713aSLionel Sambuc if (!ResultsIn)
858f4a2713aSLionel Sambuc return;
859f4a2713aSLionel Sambuc
860f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults *Results
861f4a2713aSLionel Sambuc = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
862f4a2713aSLionel Sambuc delete Results;
863f4a2713aSLionel Sambuc }
864f4a2713aSLionel Sambuc
865f4a2713aSLionel Sambuc unsigned
clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults * ResultsIn)866f4a2713aSLionel Sambuc clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
867f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults *Results
868f4a2713aSLionel Sambuc = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
869f4a2713aSLionel Sambuc if (!Results)
870f4a2713aSLionel Sambuc return 0;
871f4a2713aSLionel Sambuc
872f4a2713aSLionel Sambuc return Results->Diagnostics.size();
873f4a2713aSLionel Sambuc }
874f4a2713aSLionel Sambuc
875f4a2713aSLionel Sambuc CXDiagnostic
clang_codeCompleteGetDiagnostic(CXCodeCompleteResults * ResultsIn,unsigned Index)876f4a2713aSLionel Sambuc clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
877f4a2713aSLionel Sambuc unsigned Index) {
878f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults *Results
879f4a2713aSLionel Sambuc = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
880f4a2713aSLionel Sambuc if (!Results || Index >= Results->Diagnostics.size())
881*0a6a1f1dSLionel Sambuc return nullptr;
882f4a2713aSLionel Sambuc
883*0a6a1f1dSLionel Sambuc CXStoredDiagnostic *Diag = Results->DiagnosticsWrappers[Index];
884*0a6a1f1dSLionel Sambuc if (!Diag)
885*0a6a1f1dSLionel Sambuc Results->DiagnosticsWrappers[Index] = Diag =
886*0a6a1f1dSLionel Sambuc new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
887*0a6a1f1dSLionel Sambuc return Diag;
888f4a2713aSLionel Sambuc }
889f4a2713aSLionel Sambuc
890f4a2713aSLionel Sambuc unsigned long long
clang_codeCompleteGetContexts(CXCodeCompleteResults * ResultsIn)891f4a2713aSLionel Sambuc clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
892f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults *Results
893f4a2713aSLionel Sambuc = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
894f4a2713aSLionel Sambuc if (!Results)
895f4a2713aSLionel Sambuc return 0;
896f4a2713aSLionel Sambuc
897f4a2713aSLionel Sambuc return Results->Contexts;
898f4a2713aSLionel Sambuc }
899f4a2713aSLionel Sambuc
clang_codeCompleteGetContainerKind(CXCodeCompleteResults * ResultsIn,unsigned * IsIncomplete)900f4a2713aSLionel Sambuc enum CXCursorKind clang_codeCompleteGetContainerKind(
901f4a2713aSLionel Sambuc CXCodeCompleteResults *ResultsIn,
902f4a2713aSLionel Sambuc unsigned *IsIncomplete) {
903f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults *Results =
904f4a2713aSLionel Sambuc static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
905f4a2713aSLionel Sambuc if (!Results)
906f4a2713aSLionel Sambuc return CXCursor_InvalidCode;
907f4a2713aSLionel Sambuc
908*0a6a1f1dSLionel Sambuc if (IsIncomplete != nullptr) {
909f4a2713aSLionel Sambuc *IsIncomplete = Results->ContainerIsIncomplete;
910f4a2713aSLionel Sambuc }
911f4a2713aSLionel Sambuc
912f4a2713aSLionel Sambuc return Results->ContainerKind;
913f4a2713aSLionel Sambuc }
914f4a2713aSLionel Sambuc
clang_codeCompleteGetContainerUSR(CXCodeCompleteResults * ResultsIn)915f4a2713aSLionel Sambuc CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
916f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults *Results =
917f4a2713aSLionel Sambuc static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
918f4a2713aSLionel Sambuc if (!Results)
919f4a2713aSLionel Sambuc return cxstring::createEmpty();
920f4a2713aSLionel Sambuc
921f4a2713aSLionel Sambuc return cxstring::createRef(Results->ContainerUSR.c_str());
922f4a2713aSLionel Sambuc }
923f4a2713aSLionel Sambuc
924f4a2713aSLionel Sambuc
clang_codeCompleteGetObjCSelector(CXCodeCompleteResults * ResultsIn)925f4a2713aSLionel Sambuc CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
926f4a2713aSLionel Sambuc AllocatedCXCodeCompleteResults *Results =
927f4a2713aSLionel Sambuc static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
928f4a2713aSLionel Sambuc if (!Results)
929f4a2713aSLionel Sambuc return cxstring::createEmpty();
930f4a2713aSLionel Sambuc
931f4a2713aSLionel Sambuc return cxstring::createDup(Results->Selector);
932f4a2713aSLionel Sambuc }
933f4a2713aSLionel Sambuc
934f4a2713aSLionel Sambuc } // end extern "C"
935f4a2713aSLionel Sambuc
936f4a2713aSLionel Sambuc /// \brief Simple utility function that appends a \p New string to the given
937f4a2713aSLionel Sambuc /// \p Old string, using the \p Buffer for storage.
938f4a2713aSLionel Sambuc ///
939f4a2713aSLionel Sambuc /// \param Old The string to which we are appending. This parameter will be
940f4a2713aSLionel Sambuc /// updated to reflect the complete string.
941f4a2713aSLionel Sambuc ///
942f4a2713aSLionel Sambuc ///
943f4a2713aSLionel Sambuc /// \param New The string to append to \p Old.
944f4a2713aSLionel Sambuc ///
945f4a2713aSLionel Sambuc /// \param Buffer A buffer that stores the actual, concatenated string. It will
946f4a2713aSLionel Sambuc /// be used if the old string is already-non-empty.
AppendToString(StringRef & Old,StringRef New,SmallString<256> & Buffer)947f4a2713aSLionel Sambuc static void AppendToString(StringRef &Old, StringRef New,
948f4a2713aSLionel Sambuc SmallString<256> &Buffer) {
949f4a2713aSLionel Sambuc if (Old.empty()) {
950f4a2713aSLionel Sambuc Old = New;
951f4a2713aSLionel Sambuc return;
952f4a2713aSLionel Sambuc }
953f4a2713aSLionel Sambuc
954f4a2713aSLionel Sambuc if (Buffer.empty())
955f4a2713aSLionel Sambuc Buffer.append(Old.begin(), Old.end());
956f4a2713aSLionel Sambuc Buffer.append(New.begin(), New.end());
957f4a2713aSLionel Sambuc Old = Buffer.str();
958f4a2713aSLionel Sambuc }
959f4a2713aSLionel Sambuc
960f4a2713aSLionel Sambuc /// \brief Get the typed-text blocks from the given code-completion string
961f4a2713aSLionel Sambuc /// and return them as a single string.
962f4a2713aSLionel Sambuc ///
963f4a2713aSLionel Sambuc /// \param String The code-completion string whose typed-text blocks will be
964f4a2713aSLionel Sambuc /// concatenated.
965f4a2713aSLionel Sambuc ///
966f4a2713aSLionel Sambuc /// \param Buffer A buffer used for storage of the completed name.
GetTypedName(CodeCompletionString * String,SmallString<256> & Buffer)967f4a2713aSLionel Sambuc static StringRef GetTypedName(CodeCompletionString *String,
968f4a2713aSLionel Sambuc SmallString<256> &Buffer) {
969f4a2713aSLionel Sambuc StringRef Result;
970f4a2713aSLionel Sambuc for (CodeCompletionString::iterator C = String->begin(), CEnd = String->end();
971f4a2713aSLionel Sambuc C != CEnd; ++C) {
972f4a2713aSLionel Sambuc if (C->Kind == CodeCompletionString::CK_TypedText)
973f4a2713aSLionel Sambuc AppendToString(Result, C->Text, Buffer);
974f4a2713aSLionel Sambuc }
975f4a2713aSLionel Sambuc
976f4a2713aSLionel Sambuc return Result;
977f4a2713aSLionel Sambuc }
978f4a2713aSLionel Sambuc
979f4a2713aSLionel Sambuc namespace {
980f4a2713aSLionel Sambuc struct OrderCompletionResults {
operator ()__anonb8e724a20311::OrderCompletionResults981f4a2713aSLionel Sambuc bool operator()(const CXCompletionResult &XR,
982f4a2713aSLionel Sambuc const CXCompletionResult &YR) const {
983f4a2713aSLionel Sambuc CodeCompletionString *X
984f4a2713aSLionel Sambuc = (CodeCompletionString *)XR.CompletionString;
985f4a2713aSLionel Sambuc CodeCompletionString *Y
986f4a2713aSLionel Sambuc = (CodeCompletionString *)YR.CompletionString;
987f4a2713aSLionel Sambuc
988f4a2713aSLionel Sambuc SmallString<256> XBuffer;
989f4a2713aSLionel Sambuc StringRef XText = GetTypedName(X, XBuffer);
990f4a2713aSLionel Sambuc SmallString<256> YBuffer;
991f4a2713aSLionel Sambuc StringRef YText = GetTypedName(Y, YBuffer);
992f4a2713aSLionel Sambuc
993f4a2713aSLionel Sambuc if (XText.empty() || YText.empty())
994f4a2713aSLionel Sambuc return !XText.empty();
995f4a2713aSLionel Sambuc
996f4a2713aSLionel Sambuc int result = XText.compare_lower(YText);
997f4a2713aSLionel Sambuc if (result < 0)
998f4a2713aSLionel Sambuc return true;
999f4a2713aSLionel Sambuc if (result > 0)
1000f4a2713aSLionel Sambuc return false;
1001f4a2713aSLionel Sambuc
1002f4a2713aSLionel Sambuc result = XText.compare(YText);
1003f4a2713aSLionel Sambuc return result < 0;
1004f4a2713aSLionel Sambuc }
1005f4a2713aSLionel Sambuc };
1006f4a2713aSLionel Sambuc }
1007f4a2713aSLionel Sambuc
1008f4a2713aSLionel Sambuc extern "C" {
clang_sortCodeCompletionResults(CXCompletionResult * Results,unsigned NumResults)1009f4a2713aSLionel Sambuc void clang_sortCodeCompletionResults(CXCompletionResult *Results,
1010f4a2713aSLionel Sambuc unsigned NumResults) {
1011f4a2713aSLionel Sambuc std::stable_sort(Results, Results + NumResults, OrderCompletionResults());
1012f4a2713aSLionel Sambuc }
1013f4a2713aSLionel Sambuc }
1014