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