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