xref: /minix3/external/bsd/llvm/dist/clang/tools/libclang/CIndexCodeCompletion.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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