1 //===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Clang-C Source Indexing library hooks for
13 //===----------------------------------------------------------------------===//
16 #include "CXTranslationUnit.h"
20 #include "CIndexDiagnostic.h"
21 #include "clang/AST/Type.h"
22 #include "clang/AST/Decl.h"
23 #include "clang/AST/DeclObjC.h"
24 #include "clang/Basic/SourceManager.h"
25 #include "clang/Basic/FileManager.h"
26 #include "clang/Frontend/ASTUnit.h"
27 #include "clang/Frontend/CompilerInstance.h"
28 #include "clang/Frontend/FrontendDiagnostic.h"
29 #include "clang/Sema/CodeCompleteConsumer.h"
30 #include "llvm/ADT/SmallString.h"
31 #include "llvm/ADT/StringExtras.h"
32 #include "llvm/Support/Atomic.h"
33 #include "llvm/Support/CrashRecoveryContext.h"
34 #include "llvm/Support/MemoryBuffer.h"
35 #include "llvm/Support/Timer.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include "llvm/Support/Program.h"
42 #ifdef UDP_CODE_COMPLETION_LOGGER
43 #include "clang/Basic/Version.h"
44 #include <arpa/inet.h>
45 #include <sys/socket.h>
46 #include <sys/types.h>
50 using namespace clang;
51 using namespace clang::cxstring;
55 enum CXCompletionChunkKind
56 clang_getCompletionChunkKind(CXCompletionString completion_string,
57 unsigned chunk_number) {
58 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
59 if (!CCStr || chunk_number >= CCStr->size())
60 return CXCompletionChunk_Text;
62 switch ((*CCStr)[chunk_number].Kind) {
63 case CodeCompletionString::CK_TypedText:
64 return CXCompletionChunk_TypedText;
65 case CodeCompletionString::CK_Text:
66 return CXCompletionChunk_Text;
67 case CodeCompletionString::CK_Optional:
68 return CXCompletionChunk_Optional;
69 case CodeCompletionString::CK_Placeholder:
70 return CXCompletionChunk_Placeholder;
71 case CodeCompletionString::CK_Informative:
72 return CXCompletionChunk_Informative;
73 case CodeCompletionString::CK_ResultType:
74 return CXCompletionChunk_ResultType;
75 case CodeCompletionString::CK_CurrentParameter:
76 return CXCompletionChunk_CurrentParameter;
77 case CodeCompletionString::CK_LeftParen:
78 return CXCompletionChunk_LeftParen;
79 case CodeCompletionString::CK_RightParen:
80 return CXCompletionChunk_RightParen;
81 case CodeCompletionString::CK_LeftBracket:
82 return CXCompletionChunk_LeftBracket;
83 case CodeCompletionString::CK_RightBracket:
84 return CXCompletionChunk_RightBracket;
85 case CodeCompletionString::CK_LeftBrace:
86 return CXCompletionChunk_LeftBrace;
87 case CodeCompletionString::CK_RightBrace:
88 return CXCompletionChunk_RightBrace;
89 case CodeCompletionString::CK_LeftAngle:
90 return CXCompletionChunk_LeftAngle;
91 case CodeCompletionString::CK_RightAngle:
92 return CXCompletionChunk_RightAngle;
93 case CodeCompletionString::CK_Comma:
94 return CXCompletionChunk_Comma;
95 case CodeCompletionString::CK_Colon:
96 return CXCompletionChunk_Colon;
97 case CodeCompletionString::CK_SemiColon:
98 return CXCompletionChunk_SemiColon;
99 case CodeCompletionString::CK_Equal:
100 return CXCompletionChunk_Equal;
101 case CodeCompletionString::CK_HorizontalSpace:
102 return CXCompletionChunk_HorizontalSpace;
103 case CodeCompletionString::CK_VerticalSpace:
104 return CXCompletionChunk_VerticalSpace;
107 llvm_unreachable("Invalid CompletionKind!");
110 CXString clang_getCompletionChunkText(CXCompletionString completion_string,
111 unsigned chunk_number) {
112 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
113 if (!CCStr || chunk_number >= CCStr->size())
114 return createCXString((const char*)0);
116 switch ((*CCStr)[chunk_number].Kind) {
117 case CodeCompletionString::CK_TypedText:
118 case CodeCompletionString::CK_Text:
119 case CodeCompletionString::CK_Placeholder:
120 case CodeCompletionString::CK_CurrentParameter:
121 case CodeCompletionString::CK_Informative:
122 case CodeCompletionString::CK_LeftParen:
123 case CodeCompletionString::CK_RightParen:
124 case CodeCompletionString::CK_LeftBracket:
125 case CodeCompletionString::CK_RightBracket:
126 case CodeCompletionString::CK_LeftBrace:
127 case CodeCompletionString::CK_RightBrace:
128 case CodeCompletionString::CK_LeftAngle:
129 case CodeCompletionString::CK_RightAngle:
130 case CodeCompletionString::CK_Comma:
131 case CodeCompletionString::CK_ResultType:
132 case CodeCompletionString::CK_Colon:
133 case CodeCompletionString::CK_SemiColon:
134 case CodeCompletionString::CK_Equal:
135 case CodeCompletionString::CK_HorizontalSpace:
136 case CodeCompletionString::CK_VerticalSpace:
137 return createCXString((*CCStr)[chunk_number].Text, false);
139 case CodeCompletionString::CK_Optional:
140 // Note: treated as an empty text block.
141 return createCXString("");
144 llvm_unreachable("Invalid CodeCompletionString Kind!");
149 clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
150 unsigned chunk_number) {
151 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
152 if (!CCStr || chunk_number >= CCStr->size())
155 switch ((*CCStr)[chunk_number].Kind) {
156 case CodeCompletionString::CK_TypedText:
157 case CodeCompletionString::CK_Text:
158 case CodeCompletionString::CK_Placeholder:
159 case CodeCompletionString::CK_CurrentParameter:
160 case CodeCompletionString::CK_Informative:
161 case CodeCompletionString::CK_LeftParen:
162 case CodeCompletionString::CK_RightParen:
163 case CodeCompletionString::CK_LeftBracket:
164 case CodeCompletionString::CK_RightBracket:
165 case CodeCompletionString::CK_LeftBrace:
166 case CodeCompletionString::CK_RightBrace:
167 case CodeCompletionString::CK_LeftAngle:
168 case CodeCompletionString::CK_RightAngle:
169 case CodeCompletionString::CK_Comma:
170 case CodeCompletionString::CK_ResultType:
171 case CodeCompletionString::CK_Colon:
172 case CodeCompletionString::CK_SemiColon:
173 case CodeCompletionString::CK_Equal:
174 case CodeCompletionString::CK_HorizontalSpace:
175 case CodeCompletionString::CK_VerticalSpace:
178 case CodeCompletionString::CK_Optional:
179 // Note: treated as an empty text block.
180 return (*CCStr)[chunk_number].Optional;
183 llvm_unreachable("Invalid CompletionKind!");
186 unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
187 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
188 return CCStr? CCStr->size() : 0;
191 unsigned clang_getCompletionPriority(CXCompletionString completion_string) {
192 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
193 return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
196 enum CXAvailabilityKind
197 clang_getCompletionAvailability(CXCompletionString completion_string) {
198 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
199 return CCStr? static_cast<CXAvailabilityKind>(CCStr->getAvailability())
200 : CXAvailability_Available;
203 unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string)
205 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
206 return CCStr ? CCStr->getAnnotationCount() : 0;
209 CXString clang_getCompletionAnnotation(CXCompletionString completion_string,
210 unsigned annotation_number) {
211 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
212 return CCStr ? createCXString(CCStr->getAnnotation(annotation_number))
213 : createCXString((const char *) 0);
217 clang_getCompletionParent(CXCompletionString completion_string,
218 CXCursorKind *kind) {
220 *kind = CXCursor_NotImplemented;
222 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
224 return createCXString((const char *)0);
226 return createCXString(CCStr->getParentContextName(), /*DupString=*/false);
230 clang_getCompletionBriefComment(CXCompletionString completion_string) {
231 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
234 return createCXString((const char *) NULL);
236 return createCXString(CCStr->getBriefComment(), /*DupString=*/false);
240 /// \brief The CXCodeCompleteResults structure we allocate internally;
241 /// the client only sees the initial CXCodeCompleteResults structure.
242 struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
243 AllocatedCXCodeCompleteResults(const FileSystemOptions& FileSystemOpts);
244 ~AllocatedCXCodeCompleteResults();
246 /// \brief Diagnostics produced while performing code completion.
247 SmallVector<StoredDiagnostic, 8> Diagnostics;
249 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
251 /// \brief Diag object
252 IntrusiveRefCntPtr<DiagnosticsEngine> Diag;
254 /// \brief Language options used to adjust source locations.
255 LangOptions LangOpts;
257 FileSystemOptions FileSystemOpts;
259 /// \brief File manager, used for diagnostics.
260 IntrusiveRefCntPtr<FileManager> FileMgr;
262 /// \brief Source manager, used for diagnostics.
263 IntrusiveRefCntPtr<SourceManager> SourceMgr;
265 /// \brief Temporary files that should be removed once we have finished
266 /// with the code-completion results.
267 std::vector<llvm::sys::Path> TemporaryFiles;
269 /// \brief Temporary buffers that will be deleted once we have finished with
270 /// the code-completion results.
271 SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
273 /// \brief Allocator used to store globally cached code-completion results.
274 IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
275 CachedCompletionAllocator;
277 /// \brief Allocator used to store code completion results.
278 IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
279 CodeCompletionAllocator;
281 /// \brief Context under which completion occurred.
282 enum clang::CodeCompletionContext::Kind ContextKind;
284 /// \brief A bitfield representing the acceptable completions for the
286 unsigned long long Contexts;
288 /// \brief The kind of the container for the current context for completions.
289 enum CXCursorKind ContainerKind;
290 /// \brief The USR of the container for the current context for completions.
291 CXString ContainerUSR;
292 /// \brief a boolean value indicating whether there is complete information
293 /// about the container
294 unsigned ContainerIsIncomplete;
296 /// \brief A string containing the Objective-C selector entered thus far for a
298 std::string Selector;
301 /// \brief Tracks the number of code-completion result objects that are
302 /// currently active.
304 /// Used for debugging purposes only.
305 static llvm::sys::cas_flag CodeCompletionResultObjects;
307 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
308 const FileSystemOptions& FileSystemOpts)
309 : CXCodeCompleteResults(),
310 DiagOpts(new DiagnosticOptions),
311 Diag(new DiagnosticsEngine(
312 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
314 FileSystemOpts(FileSystemOpts),
315 FileMgr(new FileManager(FileSystemOpts)),
316 SourceMgr(new SourceManager(*Diag, *FileMgr)),
317 CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
318 Contexts(CXCompletionContext_Unknown),
319 ContainerKind(CXCursor_InvalidCode),
320 ContainerUSR(createCXString("")),
321 ContainerIsIncomplete(1)
323 if (getenv("LIBCLANG_OBJTRACKING")) {
324 llvm::sys::AtomicIncrement(&CodeCompletionResultObjects);
325 fprintf(stderr, "+++ %d completion results\n", CodeCompletionResultObjects);
329 AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
332 clang_disposeString(ContainerUSR);
334 for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
335 TemporaryFiles[I].eraseFromDisk();
336 for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
337 delete TemporaryBuffers[I];
339 if (getenv("LIBCLANG_OBJTRACKING")) {
340 llvm::sys::AtomicDecrement(&CodeCompletionResultObjects);
341 fprintf(stderr, "--- %d completion results\n", CodeCompletionResultObjects);
347 static unsigned long long getContextsForContextKind(
348 enum CodeCompletionContext::Kind kind,
350 unsigned long long contexts = 0;
352 case CodeCompletionContext::CCC_OtherWithMacros: {
353 //We can allow macros here, but we don't know what else is permissible
354 //So we'll say the only thing permissible are macros
355 contexts = CXCompletionContext_MacroName;
358 case CodeCompletionContext::CCC_TopLevel:
359 case CodeCompletionContext::CCC_ObjCIvarList:
360 case CodeCompletionContext::CCC_ClassStructUnion:
361 case CodeCompletionContext::CCC_Type: {
362 contexts = CXCompletionContext_AnyType |
363 CXCompletionContext_ObjCInterface;
364 if (S.getLangOpts().CPlusPlus) {
365 contexts |= CXCompletionContext_EnumTag |
366 CXCompletionContext_UnionTag |
367 CXCompletionContext_StructTag |
368 CXCompletionContext_ClassTag |
369 CXCompletionContext_NestedNameSpecifier;
373 case CodeCompletionContext::CCC_Statement: {
374 contexts = CXCompletionContext_AnyType |
375 CXCompletionContext_ObjCInterface |
376 CXCompletionContext_AnyValue;
377 if (S.getLangOpts().CPlusPlus) {
378 contexts |= CXCompletionContext_EnumTag |
379 CXCompletionContext_UnionTag |
380 CXCompletionContext_StructTag |
381 CXCompletionContext_ClassTag |
382 CXCompletionContext_NestedNameSpecifier;
386 case CodeCompletionContext::CCC_Expression: {
387 contexts = CXCompletionContext_AnyValue;
388 if (S.getLangOpts().CPlusPlus) {
389 contexts |= CXCompletionContext_AnyType |
390 CXCompletionContext_ObjCInterface |
391 CXCompletionContext_EnumTag |
392 CXCompletionContext_UnionTag |
393 CXCompletionContext_StructTag |
394 CXCompletionContext_ClassTag |
395 CXCompletionContext_NestedNameSpecifier;
399 case CodeCompletionContext::CCC_ObjCMessageReceiver: {
400 contexts = CXCompletionContext_ObjCObjectValue |
401 CXCompletionContext_ObjCSelectorValue |
402 CXCompletionContext_ObjCInterface;
403 if (S.getLangOpts().CPlusPlus) {
404 contexts |= CXCompletionContext_CXXClassTypeValue |
405 CXCompletionContext_AnyType |
406 CXCompletionContext_EnumTag |
407 CXCompletionContext_UnionTag |
408 CXCompletionContext_StructTag |
409 CXCompletionContext_ClassTag |
410 CXCompletionContext_NestedNameSpecifier;
414 case CodeCompletionContext::CCC_DotMemberAccess: {
415 contexts = CXCompletionContext_DotMemberAccess;
418 case CodeCompletionContext::CCC_ArrowMemberAccess: {
419 contexts = CXCompletionContext_ArrowMemberAccess;
422 case CodeCompletionContext::CCC_ObjCPropertyAccess: {
423 contexts = CXCompletionContext_ObjCPropertyAccess;
426 case CodeCompletionContext::CCC_EnumTag: {
427 contexts = CXCompletionContext_EnumTag |
428 CXCompletionContext_NestedNameSpecifier;
431 case CodeCompletionContext::CCC_UnionTag: {
432 contexts = CXCompletionContext_UnionTag |
433 CXCompletionContext_NestedNameSpecifier;
436 case CodeCompletionContext::CCC_ClassOrStructTag: {
437 contexts = CXCompletionContext_StructTag |
438 CXCompletionContext_ClassTag |
439 CXCompletionContext_NestedNameSpecifier;
442 case CodeCompletionContext::CCC_ObjCProtocolName: {
443 contexts = CXCompletionContext_ObjCProtocol;
446 case CodeCompletionContext::CCC_Namespace: {
447 contexts = CXCompletionContext_Namespace;
450 case CodeCompletionContext::CCC_PotentiallyQualifiedName: {
451 contexts = CXCompletionContext_NestedNameSpecifier;
454 case CodeCompletionContext::CCC_MacroNameUse: {
455 contexts = CXCompletionContext_MacroName;
458 case CodeCompletionContext::CCC_NaturalLanguage: {
459 contexts = CXCompletionContext_NaturalLanguage;
462 case CodeCompletionContext::CCC_SelectorName: {
463 contexts = CXCompletionContext_ObjCSelectorName;
466 case CodeCompletionContext::CCC_ParenthesizedExpression: {
467 contexts = CXCompletionContext_AnyType |
468 CXCompletionContext_ObjCInterface |
469 CXCompletionContext_AnyValue;
470 if (S.getLangOpts().CPlusPlus) {
471 contexts |= CXCompletionContext_EnumTag |
472 CXCompletionContext_UnionTag |
473 CXCompletionContext_StructTag |
474 CXCompletionContext_ClassTag |
475 CXCompletionContext_NestedNameSpecifier;
479 case CodeCompletionContext::CCC_ObjCInstanceMessage: {
480 contexts = CXCompletionContext_ObjCInstanceMessage;
483 case CodeCompletionContext::CCC_ObjCClassMessage: {
484 contexts = CXCompletionContext_ObjCClassMessage;
487 case CodeCompletionContext::CCC_ObjCInterfaceName: {
488 contexts = CXCompletionContext_ObjCInterface;
491 case CodeCompletionContext::CCC_ObjCCategoryName: {
492 contexts = CXCompletionContext_ObjCCategory;
495 case CodeCompletionContext::CCC_Other:
496 case CodeCompletionContext::CCC_ObjCInterface:
497 case CodeCompletionContext::CCC_ObjCImplementation:
498 case CodeCompletionContext::CCC_Name:
499 case CodeCompletionContext::CCC_MacroName:
500 case CodeCompletionContext::CCC_PreprocessorExpression:
501 case CodeCompletionContext::CCC_PreprocessorDirective:
502 case CodeCompletionContext::CCC_TypeQualifiers: {
503 //Only Clang results should be accepted, so we'll set all of the other
504 //context bits to 0 (i.e. the empty set)
505 contexts = CXCompletionContext_Unexposed;
508 case CodeCompletionContext::CCC_Recovery: {
509 //We don't know what the current context is, so we'll return unknown
510 //This is the equivalent of setting all of the other context bits
511 contexts = CXCompletionContext_Unknown;
519 class CaptureCompletionResults : public CodeCompleteConsumer {
520 AllocatedCXCodeCompleteResults &AllocatedResults;
521 CodeCompletionTUInfo CCTUInfo;
522 SmallVector<CXCompletionResult, 16> StoredResults;
523 CXTranslationUnit *TU;
525 CaptureCompletionResults(const CodeCompleteOptions &Opts,
526 AllocatedCXCodeCompleteResults &Results,
527 CXTranslationUnit *TranslationUnit)
528 : CodeCompleteConsumer(Opts, false),
529 AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
530 TU(TranslationUnit) { }
531 ~CaptureCompletionResults() { Finish(); }
533 virtual void ProcessCodeCompleteResults(Sema &S,
534 CodeCompletionContext Context,
535 CodeCompletionResult *Results,
536 unsigned NumResults) {
537 StoredResults.reserve(StoredResults.size() + NumResults);
538 for (unsigned I = 0; I != NumResults; ++I) {
539 CodeCompletionString *StoredCompletion
540 = Results[I].CreateCodeCompletionString(S, getAllocator(),
541 getCodeCompletionTUInfo(),
542 includeBriefComments());
544 CXCompletionResult R;
545 R.CursorKind = Results[I].CursorKind;
546 R.CompletionString = StoredCompletion;
547 StoredResults.push_back(R);
550 enum CodeCompletionContext::Kind contextKind = Context.getKind();
552 AllocatedResults.ContextKind = contextKind;
553 AllocatedResults.Contexts = getContextsForContextKind(contextKind, S);
555 AllocatedResults.Selector = "";
556 if (Context.getNumSelIdents() > 0) {
557 for (unsigned i = 0; i < Context.getNumSelIdents(); i++) {
558 IdentifierInfo *selIdent = Context.getSelIdents()[i];
559 if (selIdent != NULL) {
560 StringRef selectorString = Context.getSelIdents()[i]->getName();
561 AllocatedResults.Selector += selectorString;
563 AllocatedResults.Selector += ":";
567 QualType baseType = Context.getBaseType();
570 if (!baseType.isNull()) {
571 // Get the declaration for a class/struct/union/enum type
572 if (const TagType *Tag = baseType->getAs<TagType>())
574 // Get the @interface declaration for a (possibly-qualified) Objective-C
575 // object pointer type, e.g., NSString*
576 else if (const ObjCObjectPointerType *ObjPtr =
577 baseType->getAs<ObjCObjectPointerType>())
578 D = ObjPtr->getInterfaceDecl();
579 // Get the @interface declaration for an Objective-C object type
580 else if (const ObjCObjectType *Obj = baseType->getAs<ObjCObjectType>())
581 D = Obj->getInterface();
582 // Get the class for a C++ injected-class-name
583 else if (const InjectedClassNameType *Injected =
584 baseType->getAs<InjectedClassNameType>())
585 D = Injected->getDecl();
589 CXCursor cursor = cxcursor::MakeCXCursor(D, *TU);
591 CXCursorKind cursorKind = clang_getCursorKind(cursor);
592 CXString cursorUSR = clang_getCursorUSR(cursor);
594 // Normally, clients of CXString shouldn't care whether or not
595 // a CXString is managed by a pool or by explicitly malloc'ed memory.
596 // However, there are cases when AllocatedResults outlives the
597 // CXTranslationUnit. This is a workaround that failure mode.
598 if (cxstring::isManagedByPool(cursorUSR)) {
600 cxstring::createCXString(clang_getCString(cursorUSR), true);
601 clang_disposeString(cursorUSR);
605 AllocatedResults.ContainerKind = cursorKind;
606 AllocatedResults.ContainerUSR = cursorUSR;
608 const Type *type = baseType.getTypePtrOrNull();
610 AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
613 AllocatedResults.ContainerIsIncomplete = 1;
617 AllocatedResults.ContainerKind = CXCursor_InvalidCode;
618 AllocatedResults.ContainerUSR = createCXString("");
619 AllocatedResults.ContainerIsIncomplete = 1;
623 virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
624 OverloadCandidate *Candidates,
625 unsigned NumCandidates) {
626 StoredResults.reserve(StoredResults.size() + NumCandidates);
627 for (unsigned I = 0; I != NumCandidates; ++I) {
628 CodeCompletionString *StoredCompletion
629 = Candidates[I].CreateSignatureString(CurrentArg, S, getAllocator(),
630 getCodeCompletionTUInfo());
632 CXCompletionResult R;
633 R.CursorKind = CXCursor_NotImplemented;
634 R.CompletionString = StoredCompletion;
635 StoredResults.push_back(R);
639 virtual CodeCompletionAllocator &getAllocator() {
640 return *AllocatedResults.CodeCompletionAllocator;
643 virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; }
647 AllocatedResults.Results = new CXCompletionResult [StoredResults.size()];
648 AllocatedResults.NumResults = StoredResults.size();
649 std::memcpy(AllocatedResults.Results, StoredResults.data(),
650 StoredResults.size() * sizeof(CXCompletionResult));
651 StoredResults.clear();
657 struct CodeCompleteAtInfo {
658 CXTranslationUnit TU;
659 const char *complete_filename;
660 unsigned complete_line;
661 unsigned complete_column;
662 struct CXUnsavedFile *unsaved_files;
663 unsigned num_unsaved_files;
665 CXCodeCompleteResults *result;
667 void clang_codeCompleteAt_Impl(void *UserData) {
668 CodeCompleteAtInfo *CCAI = static_cast<CodeCompleteAtInfo*>(UserData);
669 CXTranslationUnit TU = CCAI->TU;
670 const char *complete_filename = CCAI->complete_filename;
671 unsigned complete_line = CCAI->complete_line;
672 unsigned complete_column = CCAI->complete_column;
673 struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files;
674 unsigned num_unsaved_files = CCAI->num_unsaved_files;
675 unsigned options = CCAI->options;
676 bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
679 #ifdef UDP_CODE_COMPLETION_LOGGER
680 #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
681 const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime();
685 bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
687 ASTUnit *AST = static_cast<ASTUnit *>(TU->TUData);
691 CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
692 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
693 setThreadBackgroundPriority();
695 ASTUnit::ConcurrencyCheck Check(*AST);
697 // Perform the remapping of source files.
698 SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
699 for (unsigned I = 0; I != num_unsaved_files; ++I) {
700 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
701 const llvm::MemoryBuffer *Buffer
702 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
703 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
708 // FIXME: Add logging.
711 // Parse the resulting source file to find code-completion results.
712 AllocatedCXCodeCompleteResults *Results =
713 new AllocatedCXCodeCompleteResults(AST->getFileSystemOpts());
714 Results->Results = 0;
715 Results->NumResults = 0;
717 // Create a code-completion consumer to capture the results.
718 CodeCompleteOptions Opts;
719 Opts.IncludeBriefComments = IncludeBriefComments;
720 CaptureCompletionResults Capture(Opts, *Results, &TU);
722 // Perform completion.
723 AST->CodeComplete(complete_filename, complete_line, complete_column,
724 RemappedFiles.data(), RemappedFiles.size(),
725 (options & CXCodeComplete_IncludeMacros),
726 (options & CXCodeComplete_IncludeCodePatterns),
727 IncludeBriefComments,
729 *Results->Diag, Results->LangOpts, *Results->SourceMgr,
730 *Results->FileMgr, Results->Diagnostics,
731 Results->TemporaryBuffers);
733 // Keep a reference to the allocator used for cached global completions, so
734 // that we can be sure that the memory used by our code completion strings
735 // doesn't get freed due to subsequent reparses (while the code completion
736 // results are still active).
737 Results->CachedCompletionAllocator = AST->getCachedCompletionAllocator();
741 #ifdef UDP_CODE_COMPLETION_LOGGER
742 #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
743 const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime();
744 SmallString<256> LogResult;
745 llvm::raw_svector_ostream os(LogResult);
747 // Figure out the language and whether or not it uses PCH.
748 const char *lang = 0;
749 bool usesPCH = false;
751 for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
755 if (strcmp(*I, "-x") == 0) {
761 else if (strcmp(*I, "-include") == 0) {
763 const char *arg = *(++I);
764 SmallString<512> pchName;
766 llvm::raw_svector_ostream os(pchName);
769 pchName.push_back('\0');
770 struct stat stat_results;
771 if (stat(pchName.str().c_str(), &stat_results) == 0)
779 os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
780 os << ", \"numRes\": " << Results->NumResults;
781 os << ", \"diags\": " << Results->Diagnostics.size();
782 os << ", \"pch\": " << (usesPCH ? "true" : "false");
783 os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
784 const char *name = getlogin();
785 os << ", \"user\": \"" << (name ? name : "unknown") << '"';
786 os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
789 StringRef res = os.str();
790 if (res.size() > 0) {
792 // Setup the UDP socket.
793 struct sockaddr_in servaddr;
794 bzero(&servaddr, sizeof(servaddr));
795 servaddr.sin_family = AF_INET;
796 servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
797 if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
798 &servaddr.sin_addr) <= 0)
801 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
805 sendto(sockfd, res.data(), res.size(), 0,
806 (struct sockaddr *)&servaddr, sizeof(servaddr));
813 CCAI->result = Results;
815 CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
816 const char *complete_filename,
817 unsigned complete_line,
818 unsigned complete_column,
819 struct CXUnsavedFile *unsaved_files,
820 unsigned num_unsaved_files,
822 CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line,
823 complete_column, unsaved_files, num_unsaved_files,
825 llvm::CrashRecoveryContext CRC;
827 if (!RunSafely(CRC, clang_codeCompleteAt_Impl, &CCAI)) {
828 fprintf(stderr, "libclang: crash detected in code completion\n");
829 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
831 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
832 PrintLibclangResourceUsage(TU);
837 unsigned clang_defaultCodeCompleteOptions(void) {
838 return CXCodeComplete_IncludeMacros;
841 void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
845 AllocatedCXCodeCompleteResults *Results
846 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
851 clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
852 AllocatedCXCodeCompleteResults *Results
853 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
857 return Results->Diagnostics.size();
861 clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
863 AllocatedCXCodeCompleteResults *Results
864 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
865 if (!Results || Index >= Results->Diagnostics.size())
868 return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
872 clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
873 AllocatedCXCodeCompleteResults *Results
874 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
878 return Results->Contexts;
881 enum CXCursorKind clang_codeCompleteGetContainerKind(
882 CXCodeCompleteResults *ResultsIn,
883 unsigned *IsIncomplete) {
884 AllocatedCXCodeCompleteResults *Results =
885 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
887 return CXCursor_InvalidCode;
889 if (IsIncomplete != NULL) {
890 *IsIncomplete = Results->ContainerIsIncomplete;
893 return Results->ContainerKind;
896 CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
897 AllocatedCXCodeCompleteResults *Results =
898 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
900 return createCXString("");
902 return createCXString(clang_getCString(Results->ContainerUSR));
906 CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
907 AllocatedCXCodeCompleteResults *Results =
908 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
910 return createCXString("");
912 return createCXString(Results->Selector);
917 /// \brief Simple utility function that appends a \p New string to the given
918 /// \p Old string, using the \p Buffer for storage.
920 /// \param Old The string to which we are appending. This parameter will be
921 /// updated to reflect the complete string.
924 /// \param New The string to append to \p Old.
926 /// \param Buffer A buffer that stores the actual, concatenated string. It will
927 /// be used if the old string is already-non-empty.
928 static void AppendToString(StringRef &Old, StringRef New,
929 SmallString<256> &Buffer) {
936 Buffer.append(Old.begin(), Old.end());
937 Buffer.append(New.begin(), New.end());
941 /// \brief Get the typed-text blocks from the given code-completion string
942 /// and return them as a single string.
944 /// \param String The code-completion string whose typed-text blocks will be
947 /// \param Buffer A buffer used for storage of the completed name.
948 static StringRef GetTypedName(CodeCompletionString *String,
949 SmallString<256> &Buffer) {
951 for (CodeCompletionString::iterator C = String->begin(), CEnd = String->end();
953 if (C->Kind == CodeCompletionString::CK_TypedText)
954 AppendToString(Result, C->Text, Buffer);
961 struct OrderCompletionResults {
962 bool operator()(const CXCompletionResult &XR,
963 const CXCompletionResult &YR) const {
964 CodeCompletionString *X
965 = (CodeCompletionString *)XR.CompletionString;
966 CodeCompletionString *Y
967 = (CodeCompletionString *)YR.CompletionString;
969 SmallString<256> XBuffer;
970 StringRef XText = GetTypedName(X, XBuffer);
971 SmallString<256> YBuffer;
972 StringRef YText = GetTypedName(Y, YBuffer);
974 if (XText.empty() || YText.empty())
975 return !XText.empty();
977 int result = XText.compare_lower(YText);
983 result = XText.compare(YText);
990 void clang_sortCodeCompletionResults(CXCompletionResult *Results,
991 unsigned NumResults) {
992 std::stable_sort(Results, Results + NumResults, OrderCompletionResults());