1 //===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the Clang-C Source Indexing library hooks for
12 //===----------------------------------------------------------------------===//
15 #include "CIndexDiagnostic.h"
18 #include "CXSourceLocation.h"
20 #include "CXTranslationUnit.h"
21 #include "clang/AST/Decl.h"
22 #include "clang/AST/DeclObjC.h"
23 #include "clang/AST/Type.h"
24 #include "clang/Basic/FileManager.h"
25 #include "clang/Basic/SourceManager.h"
26 #include "clang/Frontend/ASTUnit.h"
27 #include "clang/Frontend/CompilerInstance.h"
28 #include "clang/Sema/CodeCompleteConsumer.h"
29 #include "clang/Sema/Sema.h"
30 #include "llvm/ADT/SmallString.h"
31 #include "llvm/ADT/StringExtras.h"
32 #include "llvm/Support/CrashRecoveryContext.h"
33 #include "llvm/Support/FileSystem.h"
34 #include "llvm/Support/FormatVariadic.h"
35 #include "llvm/Support/MemoryBuffer.h"
36 #include "llvm/Support/Program.h"
37 #include "llvm/Support/Timer.h"
38 #include "llvm/Support/raw_ostream.h"
45 #ifdef UDP_CODE_COMPLETION_LOGGER
46 #include "clang/Basic/Version.h"
47 #include <arpa/inet.h>
48 #include <sys/socket.h>
49 #include <sys/types.h>
53 using namespace clang
;
54 using namespace clang::cxindex
;
56 enum CXCompletionChunkKind
57 clang_getCompletionChunkKind(CXCompletionString completion_string
,
58 unsigned chunk_number
) {
59 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
60 if (!CCStr
|| chunk_number
>= CCStr
->size())
61 return CXCompletionChunk_Text
;
63 switch ((*CCStr
)[chunk_number
].Kind
) {
64 case CodeCompletionString::CK_TypedText
:
65 return CXCompletionChunk_TypedText
;
66 case CodeCompletionString::CK_Text
:
67 return CXCompletionChunk_Text
;
68 case CodeCompletionString::CK_Optional
:
69 return CXCompletionChunk_Optional
;
70 case CodeCompletionString::CK_Placeholder
:
71 return CXCompletionChunk_Placeholder
;
72 case CodeCompletionString::CK_Informative
:
73 return CXCompletionChunk_Informative
;
74 case CodeCompletionString::CK_ResultType
:
75 return CXCompletionChunk_ResultType
;
76 case CodeCompletionString::CK_CurrentParameter
:
77 return CXCompletionChunk_CurrentParameter
;
78 case CodeCompletionString::CK_LeftParen
:
79 return CXCompletionChunk_LeftParen
;
80 case CodeCompletionString::CK_RightParen
:
81 return CXCompletionChunk_RightParen
;
82 case CodeCompletionString::CK_LeftBracket
:
83 return CXCompletionChunk_LeftBracket
;
84 case CodeCompletionString::CK_RightBracket
:
85 return CXCompletionChunk_RightBracket
;
86 case CodeCompletionString::CK_LeftBrace
:
87 return CXCompletionChunk_LeftBrace
;
88 case CodeCompletionString::CK_RightBrace
:
89 return CXCompletionChunk_RightBrace
;
90 case CodeCompletionString::CK_LeftAngle
:
91 return CXCompletionChunk_LeftAngle
;
92 case CodeCompletionString::CK_RightAngle
:
93 return CXCompletionChunk_RightAngle
;
94 case CodeCompletionString::CK_Comma
:
95 return CXCompletionChunk_Comma
;
96 case CodeCompletionString::CK_Colon
:
97 return CXCompletionChunk_Colon
;
98 case CodeCompletionString::CK_SemiColon
:
99 return CXCompletionChunk_SemiColon
;
100 case CodeCompletionString::CK_Equal
:
101 return CXCompletionChunk_Equal
;
102 case CodeCompletionString::CK_HorizontalSpace
:
103 return CXCompletionChunk_HorizontalSpace
;
104 case CodeCompletionString::CK_VerticalSpace
:
105 return CXCompletionChunk_VerticalSpace
;
108 llvm_unreachable("Invalid CompletionKind!");
111 CXString
clang_getCompletionChunkText(CXCompletionString completion_string
,
112 unsigned chunk_number
) {
113 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
114 if (!CCStr
|| chunk_number
>= CCStr
->size())
115 return cxstring::createNull();
117 switch ((*CCStr
)[chunk_number
].Kind
) {
118 case CodeCompletionString::CK_TypedText
:
119 case CodeCompletionString::CK_Text
:
120 case CodeCompletionString::CK_Placeholder
:
121 case CodeCompletionString::CK_CurrentParameter
:
122 case CodeCompletionString::CK_Informative
:
123 case CodeCompletionString::CK_LeftParen
:
124 case CodeCompletionString::CK_RightParen
:
125 case CodeCompletionString::CK_LeftBracket
:
126 case CodeCompletionString::CK_RightBracket
:
127 case CodeCompletionString::CK_LeftBrace
:
128 case CodeCompletionString::CK_RightBrace
:
129 case CodeCompletionString::CK_LeftAngle
:
130 case CodeCompletionString::CK_RightAngle
:
131 case CodeCompletionString::CK_Comma
:
132 case CodeCompletionString::CK_ResultType
:
133 case CodeCompletionString::CK_Colon
:
134 case CodeCompletionString::CK_SemiColon
:
135 case CodeCompletionString::CK_Equal
:
136 case CodeCompletionString::CK_HorizontalSpace
:
137 case CodeCompletionString::CK_VerticalSpace
:
138 return cxstring::createRef((*CCStr
)[chunk_number
].Text
);
140 case CodeCompletionString::CK_Optional
:
141 // Note: treated as an empty text block.
142 return cxstring::createEmpty();
145 llvm_unreachable("Invalid CodeCompletionString Kind!");
150 clang_getCompletionChunkCompletionString(CXCompletionString completion_string
,
151 unsigned chunk_number
) {
152 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
153 if (!CCStr
|| chunk_number
>= CCStr
->size())
156 switch ((*CCStr
)[chunk_number
].Kind
) {
157 case CodeCompletionString::CK_TypedText
:
158 case CodeCompletionString::CK_Text
:
159 case CodeCompletionString::CK_Placeholder
:
160 case CodeCompletionString::CK_CurrentParameter
:
161 case CodeCompletionString::CK_Informative
:
162 case CodeCompletionString::CK_LeftParen
:
163 case CodeCompletionString::CK_RightParen
:
164 case CodeCompletionString::CK_LeftBracket
:
165 case CodeCompletionString::CK_RightBracket
:
166 case CodeCompletionString::CK_LeftBrace
:
167 case CodeCompletionString::CK_RightBrace
:
168 case CodeCompletionString::CK_LeftAngle
:
169 case CodeCompletionString::CK_RightAngle
:
170 case CodeCompletionString::CK_Comma
:
171 case CodeCompletionString::CK_ResultType
:
172 case CodeCompletionString::CK_Colon
:
173 case CodeCompletionString::CK_SemiColon
:
174 case CodeCompletionString::CK_Equal
:
175 case CodeCompletionString::CK_HorizontalSpace
:
176 case CodeCompletionString::CK_VerticalSpace
:
179 case CodeCompletionString::CK_Optional
:
180 // Note: treated as an empty text block.
181 return (*CCStr
)[chunk_number
].Optional
;
184 llvm_unreachable("Invalid CompletionKind!");
187 unsigned clang_getNumCompletionChunks(CXCompletionString completion_string
) {
188 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
189 return CCStr
? CCStr
->size() : 0;
192 unsigned clang_getCompletionPriority(CXCompletionString completion_string
) {
193 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
194 return CCStr
? CCStr
->getPriority() : unsigned(CCP_Unlikely
);
197 enum CXAvailabilityKind
198 clang_getCompletionAvailability(CXCompletionString completion_string
) {
199 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
200 return CCStr
? static_cast<CXAvailabilityKind
>(CCStr
->getAvailability())
201 : CXAvailability_Available
;
204 unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string
)
206 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
207 return CCStr
? CCStr
->getAnnotationCount() : 0;
210 CXString
clang_getCompletionAnnotation(CXCompletionString completion_string
,
211 unsigned annotation_number
) {
212 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
213 return CCStr
? cxstring::createRef(CCStr
->getAnnotation(annotation_number
))
214 : cxstring::createNull();
218 clang_getCompletionParent(CXCompletionString completion_string
,
219 CXCursorKind
*kind
) {
221 *kind
= CXCursor_NotImplemented
;
223 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
225 return cxstring::createNull();
227 return cxstring::createRef(CCStr
->getParentContextName());
231 clang_getCompletionBriefComment(CXCompletionString completion_string
) {
232 CodeCompletionString
*CCStr
= (CodeCompletionString
*)completion_string
;
235 return cxstring::createNull();
237 return cxstring::createRef(CCStr
->getBriefComment());
242 /// The CXCodeCompleteResults structure we allocate internally;
243 /// the client only sees the initial CXCodeCompleteResults structure.
245 /// Normally, clients of CXString shouldn't care whether or not a CXString is
246 /// managed by a pool or by explicitly malloc'ed memory. But
247 /// AllocatedCXCodeCompleteResults outlives the CXTranslationUnit, so we can
248 /// not rely on the StringPool in the TU.
249 struct AllocatedCXCodeCompleteResults
: public CXCodeCompleteResults
{
250 AllocatedCXCodeCompleteResults(IntrusiveRefCntPtr
<FileManager
> FileMgr
);
251 ~AllocatedCXCodeCompleteResults();
253 /// Diagnostics produced while performing code completion.
254 SmallVector
<StoredDiagnostic
, 8> Diagnostics
;
256 /// Allocated API-exposed wrappters for Diagnostics.
257 SmallVector
<std::unique_ptr
<CXStoredDiagnostic
>, 8> DiagnosticsWrappers
;
259 IntrusiveRefCntPtr
<DiagnosticOptions
> DiagOpts
;
262 IntrusiveRefCntPtr
<DiagnosticsEngine
> Diag
;
264 /// Language options used to adjust source locations.
265 LangOptions LangOpts
;
267 /// File manager, used for diagnostics.
268 IntrusiveRefCntPtr
<FileManager
> FileMgr
;
270 /// Source manager, used for diagnostics.
271 IntrusiveRefCntPtr
<SourceManager
> SourceMgr
;
273 /// Temporary buffers that will be deleted once we have finished with
274 /// the code-completion results.
275 SmallVector
<const llvm::MemoryBuffer
*, 1> TemporaryBuffers
;
277 /// Allocator used to store globally cached code-completion results.
278 std::shared_ptr
<clang::GlobalCodeCompletionAllocator
>
279 CachedCompletionAllocator
;
281 /// Allocator used to store code completion results.
282 std::shared_ptr
<clang::GlobalCodeCompletionAllocator
> CodeCompletionAllocator
;
284 /// Context under which completion occurred.
285 enum clang::CodeCompletionContext::Kind ContextKind
;
287 /// A bitfield representing the acceptable completions for the
289 unsigned long long Contexts
;
291 /// The kind of the container for the current context for completions.
292 enum CXCursorKind ContainerKind
;
294 /// The USR of the container for the current context for completions.
295 std::string ContainerUSR
;
297 /// a boolean value indicating whether there is complete information
298 /// about the container
299 unsigned ContainerIsIncomplete
;
301 /// A string containing the Objective-C selector entered thus far for a
303 std::string Selector
;
305 /// Vector of fix-its for each completion result that *must* be applied
306 /// before that result for the corresponding completion item.
307 std::vector
<std::vector
<FixItHint
>> FixItsVector
;
310 } // end anonymous namespace
312 unsigned clang_getCompletionNumFixIts(CXCodeCompleteResults
*results
,
313 unsigned completion_index
) {
314 AllocatedCXCodeCompleteResults
*allocated_results
= (AllocatedCXCodeCompleteResults
*)results
;
316 if (!allocated_results
|| allocated_results
->FixItsVector
.size() <= completion_index
)
319 return static_cast<unsigned>(allocated_results
->FixItsVector
[completion_index
].size());
322 CXString
clang_getCompletionFixIt(CXCodeCompleteResults
*results
,
323 unsigned completion_index
,
324 unsigned fixit_index
,
325 CXSourceRange
*replacement_range
) {
326 AllocatedCXCodeCompleteResults
*allocated_results
= (AllocatedCXCodeCompleteResults
*)results
;
328 if (!allocated_results
|| allocated_results
->FixItsVector
.size() <= completion_index
) {
329 if (replacement_range
)
330 *replacement_range
= clang_getNullRange();
331 return cxstring::createNull();
334 ArrayRef
<FixItHint
> FixIts
= allocated_results
->FixItsVector
[completion_index
];
335 if (FixIts
.size() <= fixit_index
) {
336 if (replacement_range
)
337 *replacement_range
= clang_getNullRange();
338 return cxstring::createNull();
341 const FixItHint
&FixIt
= FixIts
[fixit_index
];
342 if (replacement_range
) {
343 *replacement_range
= cxloc::translateSourceRange(
344 *allocated_results
->SourceMgr
, allocated_results
->LangOpts
,
348 return cxstring::createRef(FixIt
.CodeToInsert
.c_str());
351 /// Tracks the number of code-completion result objects that are
352 /// currently active.
354 /// Used for debugging purposes only.
355 static std::atomic
<unsigned> CodeCompletionResultObjects
;
357 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
358 IntrusiveRefCntPtr
<FileManager
> FileMgr
)
359 : CXCodeCompleteResults(), DiagOpts(new DiagnosticOptions
),
360 Diag(new DiagnosticsEngine(
361 IntrusiveRefCntPtr
<DiagnosticIDs
>(new DiagnosticIDs
), &*DiagOpts
)),
362 FileMgr(std::move(FileMgr
)),
363 SourceMgr(new SourceManager(*Diag
, *this->FileMgr
)),
364 CodeCompletionAllocator(
365 std::make_shared
<clang::GlobalCodeCompletionAllocator
>()),
366 Contexts(CXCompletionContext_Unknown
),
367 ContainerKind(CXCursor_InvalidCode
), ContainerIsIncomplete(1) {
368 if (getenv("LIBCLANG_OBJTRACKING"))
369 fprintf(stderr
, "+++ %u completion results\n",
370 ++CodeCompletionResultObjects
);
373 AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
376 for (unsigned I
= 0, N
= TemporaryBuffers
.size(); I
!= N
; ++I
)
377 delete TemporaryBuffers
[I
];
379 if (getenv("LIBCLANG_OBJTRACKING"))
380 fprintf(stderr
, "--- %u completion results\n",
381 --CodeCompletionResultObjects
);
384 static unsigned long long getContextsForContextKind(
385 enum CodeCompletionContext::Kind kind
,
387 unsigned long long contexts
= 0;
389 case CodeCompletionContext::CCC_OtherWithMacros
: {
390 //We can allow macros here, but we don't know what else is permissible
391 //So we'll say the only thing permissible are macros
392 contexts
= CXCompletionContext_MacroName
;
395 case CodeCompletionContext::CCC_TopLevel
:
396 case CodeCompletionContext::CCC_ObjCIvarList
:
397 case CodeCompletionContext::CCC_ClassStructUnion
:
398 case CodeCompletionContext::CCC_Type
: {
399 contexts
= CXCompletionContext_AnyType
|
400 CXCompletionContext_ObjCInterface
;
401 if (S
.getLangOpts().CPlusPlus
) {
402 contexts
|= CXCompletionContext_EnumTag
|
403 CXCompletionContext_UnionTag
|
404 CXCompletionContext_StructTag
|
405 CXCompletionContext_ClassTag
|
406 CXCompletionContext_NestedNameSpecifier
;
410 case CodeCompletionContext::CCC_Statement
: {
411 contexts
= CXCompletionContext_AnyType
|
412 CXCompletionContext_ObjCInterface
|
413 CXCompletionContext_AnyValue
;
414 if (S
.getLangOpts().CPlusPlus
) {
415 contexts
|= CXCompletionContext_EnumTag
|
416 CXCompletionContext_UnionTag
|
417 CXCompletionContext_StructTag
|
418 CXCompletionContext_ClassTag
|
419 CXCompletionContext_NestedNameSpecifier
;
423 case CodeCompletionContext::CCC_Expression
: {
424 contexts
= CXCompletionContext_AnyValue
;
425 if (S
.getLangOpts().CPlusPlus
) {
426 contexts
|= CXCompletionContext_AnyType
|
427 CXCompletionContext_ObjCInterface
|
428 CXCompletionContext_EnumTag
|
429 CXCompletionContext_UnionTag
|
430 CXCompletionContext_StructTag
|
431 CXCompletionContext_ClassTag
|
432 CXCompletionContext_NestedNameSpecifier
;
436 case CodeCompletionContext::CCC_ObjCMessageReceiver
: {
437 contexts
= CXCompletionContext_ObjCObjectValue
|
438 CXCompletionContext_ObjCSelectorValue
|
439 CXCompletionContext_ObjCInterface
;
440 if (S
.getLangOpts().CPlusPlus
) {
441 contexts
|= CXCompletionContext_CXXClassTypeValue
|
442 CXCompletionContext_AnyType
|
443 CXCompletionContext_EnumTag
|
444 CXCompletionContext_UnionTag
|
445 CXCompletionContext_StructTag
|
446 CXCompletionContext_ClassTag
|
447 CXCompletionContext_NestedNameSpecifier
;
451 case CodeCompletionContext::CCC_DotMemberAccess
: {
452 contexts
= CXCompletionContext_DotMemberAccess
;
455 case CodeCompletionContext::CCC_ArrowMemberAccess
: {
456 contexts
= CXCompletionContext_ArrowMemberAccess
;
459 case CodeCompletionContext::CCC_ObjCPropertyAccess
: {
460 contexts
= CXCompletionContext_ObjCPropertyAccess
;
463 case CodeCompletionContext::CCC_EnumTag
: {
464 contexts
= CXCompletionContext_EnumTag
|
465 CXCompletionContext_NestedNameSpecifier
;
468 case CodeCompletionContext::CCC_UnionTag
: {
469 contexts
= CXCompletionContext_UnionTag
|
470 CXCompletionContext_NestedNameSpecifier
;
473 case CodeCompletionContext::CCC_ClassOrStructTag
: {
474 contexts
= CXCompletionContext_StructTag
|
475 CXCompletionContext_ClassTag
|
476 CXCompletionContext_NestedNameSpecifier
;
479 case CodeCompletionContext::CCC_ObjCProtocolName
: {
480 contexts
= CXCompletionContext_ObjCProtocol
;
483 case CodeCompletionContext::CCC_Namespace
: {
484 contexts
= CXCompletionContext_Namespace
;
487 case CodeCompletionContext::CCC_SymbolOrNewName
:
488 case CodeCompletionContext::CCC_Symbol
: {
489 contexts
= CXCompletionContext_NestedNameSpecifier
;
492 case CodeCompletionContext::CCC_MacroNameUse
: {
493 contexts
= CXCompletionContext_MacroName
;
496 case CodeCompletionContext::CCC_NaturalLanguage
: {
497 contexts
= CXCompletionContext_NaturalLanguage
;
500 case CodeCompletionContext::CCC_IncludedFile
: {
501 contexts
= CXCompletionContext_IncludedFile
;
504 case CodeCompletionContext::CCC_SelectorName
: {
505 contexts
= CXCompletionContext_ObjCSelectorName
;
508 case CodeCompletionContext::CCC_ParenthesizedExpression
: {
509 contexts
= CXCompletionContext_AnyType
|
510 CXCompletionContext_ObjCInterface
|
511 CXCompletionContext_AnyValue
;
512 if (S
.getLangOpts().CPlusPlus
) {
513 contexts
|= CXCompletionContext_EnumTag
|
514 CXCompletionContext_UnionTag
|
515 CXCompletionContext_StructTag
|
516 CXCompletionContext_ClassTag
|
517 CXCompletionContext_NestedNameSpecifier
;
521 case CodeCompletionContext::CCC_ObjCInstanceMessage
: {
522 contexts
= CXCompletionContext_ObjCInstanceMessage
;
525 case CodeCompletionContext::CCC_ObjCClassMessage
: {
526 contexts
= CXCompletionContext_ObjCClassMessage
;
529 case CodeCompletionContext::CCC_ObjCInterfaceName
: {
530 contexts
= CXCompletionContext_ObjCInterface
;
533 case CodeCompletionContext::CCC_ObjCCategoryName
: {
534 contexts
= CXCompletionContext_ObjCCategory
;
537 case CodeCompletionContext::CCC_Other
:
538 case CodeCompletionContext::CCC_ObjCInterface
:
539 case CodeCompletionContext::CCC_ObjCImplementation
:
540 case CodeCompletionContext::CCC_NewName
:
541 case CodeCompletionContext::CCC_MacroName
:
542 case CodeCompletionContext::CCC_PreprocessorExpression
:
543 case CodeCompletionContext::CCC_PreprocessorDirective
:
544 case CodeCompletionContext::CCC_Attribute
:
545 case CodeCompletionContext::CCC_TypeQualifiers
: {
546 //Only Clang results should be accepted, so we'll set all of the other
547 //context bits to 0 (i.e. the empty set)
548 contexts
= CXCompletionContext_Unexposed
;
551 case CodeCompletionContext::CCC_Recovery
: {
552 //We don't know what the current context is, so we'll return unknown
553 //This is the equivalent of setting all of the other context bits
554 contexts
= CXCompletionContext_Unknown
;
562 class CaptureCompletionResults
: public CodeCompleteConsumer
{
563 AllocatedCXCodeCompleteResults
&AllocatedResults
;
564 CodeCompletionTUInfo CCTUInfo
;
565 SmallVector
<CXCompletionResult
, 16> StoredResults
;
566 CXTranslationUnit
*TU
;
568 CaptureCompletionResults(const CodeCompleteOptions
&Opts
,
569 AllocatedCXCodeCompleteResults
&Results
,
570 CXTranslationUnit
*TranslationUnit
)
571 : CodeCompleteConsumer(Opts
), AllocatedResults(Results
),
572 CCTUInfo(Results
.CodeCompletionAllocator
), TU(TranslationUnit
) {}
573 ~CaptureCompletionResults() override
{ Finish(); }
575 void ProcessCodeCompleteResults(Sema
&S
,
576 CodeCompletionContext Context
,
577 CodeCompletionResult
*Results
,
578 unsigned NumResults
) override
{
579 StoredResults
.reserve(StoredResults
.size() + NumResults
);
581 AllocatedResults
.FixItsVector
.reserve(NumResults
);
582 for (unsigned I
= 0; I
!= NumResults
; ++I
) {
583 CodeCompletionString
*StoredCompletion
584 = Results
[I
].CreateCodeCompletionString(S
, Context
, getAllocator(),
585 getCodeCompletionTUInfo(),
586 includeBriefComments());
588 CXCompletionResult R
;
589 R
.CursorKind
= Results
[I
].CursorKind
;
590 R
.CompletionString
= StoredCompletion
;
591 StoredResults
.push_back(R
);
593 AllocatedResults
.FixItsVector
.emplace_back(std::move(Results
[I
].FixIts
));
596 enum CodeCompletionContext::Kind contextKind
= Context
.getKind();
598 AllocatedResults
.ContextKind
= contextKind
;
599 AllocatedResults
.Contexts
= getContextsForContextKind(contextKind
, S
);
601 AllocatedResults
.Selector
= "";
602 ArrayRef
<IdentifierInfo
*> SelIdents
= Context
.getSelIdents();
603 for (ArrayRef
<IdentifierInfo
*>::iterator I
= SelIdents
.begin(),
606 if (IdentifierInfo
*selIdent
= *I
)
607 AllocatedResults
.Selector
+= selIdent
->getName();
608 AllocatedResults
.Selector
+= ":";
611 QualType baseType
= Context
.getBaseType();
612 NamedDecl
*D
= nullptr;
614 if (!baseType
.isNull()) {
615 // Get the declaration for a class/struct/union/enum type
616 if (const TagType
*Tag
= baseType
->getAs
<TagType
>())
618 // Get the @interface declaration for a (possibly-qualified) Objective-C
619 // object pointer type, e.g., NSString*
620 else if (const ObjCObjectPointerType
*ObjPtr
=
621 baseType
->getAs
<ObjCObjectPointerType
>())
622 D
= ObjPtr
->getInterfaceDecl();
623 // Get the @interface declaration for an Objective-C object type
624 else if (const ObjCObjectType
*Obj
= baseType
->getAs
<ObjCObjectType
>())
625 D
= Obj
->getInterface();
626 // Get the class for a C++ injected-class-name
627 else if (const InjectedClassNameType
*Injected
=
628 baseType
->getAs
<InjectedClassNameType
>())
629 D
= Injected
->getDecl();
633 CXCursor cursor
= cxcursor::MakeCXCursor(D
, *TU
);
635 AllocatedResults
.ContainerKind
= clang_getCursorKind(cursor
);
637 CXString CursorUSR
= clang_getCursorUSR(cursor
);
638 AllocatedResults
.ContainerUSR
= clang_getCString(CursorUSR
);
639 clang_disposeString(CursorUSR
);
641 const Type
*type
= baseType
.getTypePtrOrNull();
643 AllocatedResults
.ContainerIsIncomplete
= type
->isIncompleteType();
646 AllocatedResults
.ContainerIsIncomplete
= 1;
650 AllocatedResults
.ContainerKind
= CXCursor_InvalidCode
;
651 AllocatedResults
.ContainerUSR
.clear();
652 AllocatedResults
.ContainerIsIncomplete
= 1;
656 void ProcessOverloadCandidates(Sema
&S
, unsigned CurrentArg
,
657 OverloadCandidate
*Candidates
,
658 unsigned NumCandidates
,
659 SourceLocation OpenParLoc
,
660 bool Braced
) override
{
661 StoredResults
.reserve(StoredResults
.size() + NumCandidates
);
662 for (unsigned I
= 0; I
!= NumCandidates
; ++I
) {
663 CodeCompletionString
*StoredCompletion
=
664 Candidates
[I
].CreateSignatureString(CurrentArg
, S
, getAllocator(),
665 getCodeCompletionTUInfo(),
666 includeBriefComments(), Braced
);
668 CXCompletionResult R
;
669 R
.CursorKind
= CXCursor_OverloadCandidate
;
670 R
.CompletionString
= StoredCompletion
;
671 StoredResults
.push_back(R
);
675 CodeCompletionAllocator
&getAllocator() override
{
676 return *AllocatedResults
.CodeCompletionAllocator
;
679 CodeCompletionTUInfo
&getCodeCompletionTUInfo() override
{ return CCTUInfo
;}
683 AllocatedResults
.Results
= new CXCompletionResult
[StoredResults
.size()];
684 AllocatedResults
.NumResults
= StoredResults
.size();
685 std::memcpy(AllocatedResults
.Results
, StoredResults
.data(),
686 StoredResults
.size() * sizeof(CXCompletionResult
));
687 StoredResults
.clear();
692 static CXCodeCompleteResults
*
693 clang_codeCompleteAt_Impl(CXTranslationUnit TU
, const char *complete_filename
,
694 unsigned complete_line
, unsigned complete_column
,
695 ArrayRef
<CXUnsavedFile
> unsaved_files
,
697 bool IncludeBriefComments
= options
& CXCodeComplete_IncludeBriefComments
;
698 bool SkipPreamble
= options
& CXCodeComplete_SkipPreamble
;
699 bool IncludeFixIts
= options
& CXCodeComplete_IncludeCompletionsWithFixIts
;
701 #ifdef UDP_CODE_COMPLETION_LOGGER
702 #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
703 const llvm::TimeRecord
&StartTime
= llvm::TimeRecord::getCurrentTime();
706 bool EnableLogging
= getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr;
708 if (cxtu::isNotUsableTU(TU
)) {
713 ASTUnit
*AST
= cxtu::getASTUnit(TU
);
717 CIndexer
*CXXIdx
= TU
->CIdx
;
718 if (CXXIdx
->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing
))
719 setThreadBackgroundPriority();
721 ASTUnit::ConcurrencyCheck
Check(*AST
);
723 // Perform the remapping of source files.
724 SmallVector
<ASTUnit::RemappedFile
, 4> RemappedFiles
;
726 for (auto &UF
: unsaved_files
) {
727 std::unique_ptr
<llvm::MemoryBuffer
> MB
=
728 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF
), UF
.Filename
);
729 RemappedFiles
.push_back(std::make_pair(UF
.Filename
, MB
.release()));
733 // FIXME: Add logging.
736 // Parse the resulting source file to find code-completion results.
737 AllocatedCXCodeCompleteResults
*Results
= new AllocatedCXCodeCompleteResults(
738 &AST
->getFileManager());
739 Results
->Results
= nullptr;
740 Results
->NumResults
= 0;
742 // Create a code-completion consumer to capture the results.
743 CodeCompleteOptions Opts
;
744 Opts
.IncludeBriefComments
= IncludeBriefComments
;
745 Opts
.LoadExternal
= !SkipPreamble
;
746 Opts
.IncludeFixIts
= IncludeFixIts
;
747 CaptureCompletionResults
Capture(Opts
, *Results
, &TU
);
749 // Perform completion.
750 std::vector
<const char *> CArgs
;
751 for (const auto &Arg
: TU
->Arguments
)
752 CArgs
.push_back(Arg
.c_str());
753 std::string CompletionInvocation
=
754 llvm::formatv("-code-completion-at={0}:{1}:{2}", complete_filename
,
755 complete_line
, complete_column
)
757 LibclangInvocationReporter
InvocationReporter(
758 *CXXIdx
, LibclangInvocationReporter::OperationKind::CompletionOperation
,
759 TU
->ParsingOptions
, CArgs
, CompletionInvocation
, unsaved_files
);
760 AST
->CodeComplete(complete_filename
, complete_line
, complete_column
,
761 RemappedFiles
, (options
& CXCodeComplete_IncludeMacros
),
762 (options
& CXCodeComplete_IncludeCodePatterns
),
763 IncludeBriefComments
, Capture
,
764 CXXIdx
->getPCHContainerOperations(), *Results
->Diag
,
765 Results
->LangOpts
, *Results
->SourceMgr
, *Results
->FileMgr
,
766 Results
->Diagnostics
, Results
->TemporaryBuffers
);
768 Results
->DiagnosticsWrappers
.resize(Results
->Diagnostics
.size());
770 // Keep a reference to the allocator used for cached global completions, so
771 // that we can be sure that the memory used by our code completion strings
772 // doesn't get freed due to subsequent reparses (while the code completion
773 // results are still active).
774 Results
->CachedCompletionAllocator
= AST
->getCachedCompletionAllocator();
778 #ifdef UDP_CODE_COMPLETION_LOGGER
779 #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
780 const llvm::TimeRecord
&EndTime
= llvm::TimeRecord::getCurrentTime();
781 SmallString
<256> LogResult
;
782 llvm::raw_svector_ostream
os(LogResult
);
784 // Figure out the language and whether or not it uses PCH.
785 const char *lang
= 0;
786 bool usesPCH
= false;
788 for (std::vector
<const char*>::iterator I
= argv
.begin(), E
= argv
.end();
792 if (strcmp(*I
, "-x") == 0) {
798 else if (strcmp(*I
, "-include") == 0) {
800 const char *arg
= *(++I
);
801 SmallString
<512> pchName
;
803 llvm::raw_svector_ostream
os(pchName
);
806 pchName
.push_back('\0');
807 llvm::sys::fs::file_status stat_results
;
808 if (!llvm::sys::fs::status(pchName
, stat_results
))
816 os
<< "\"wall\": " << (EndTime
.getWallTime() - StartTime
.getWallTime());
817 os
<< ", \"numRes\": " << Results
->NumResults
;
818 os
<< ", \"diags\": " << Results
->Diagnostics
.size();
819 os
<< ", \"pch\": " << (usesPCH
? "true" : "false");
820 os
<< ", \"lang\": \"" << (lang
? lang
: "<unknown>") << '"';
821 const char *name
= getlogin();
822 os
<< ", \"user\": \"" << (name
? name
: "unknown") << '"';
823 os
<< ", \"clangVer\": \"" << getClangFullVersion() << '"';
826 StringRef res
= os
.str();
827 if (res
.size() > 0) {
829 // Setup the UDP socket.
830 struct sockaddr_in servaddr
;
831 bzero(&servaddr
, sizeof(servaddr
));
832 servaddr
.sin_family
= AF_INET
;
833 servaddr
.sin_port
= htons(UDP_CODE_COMPLETION_LOGGER_PORT
);
834 if (inet_pton(AF_INET
, UDP_CODE_COMPLETION_LOGGER
,
835 &servaddr
.sin_addr
) <= 0)
838 int sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
842 sendto(sockfd
, res
.data(), res
.size(), 0,
843 (struct sockaddr
*)&servaddr
, sizeof(servaddr
));
853 CXCodeCompleteResults
*clang_codeCompleteAt(CXTranslationUnit TU
,
854 const char *complete_filename
,
855 unsigned complete_line
,
856 unsigned complete_column
,
857 struct CXUnsavedFile
*unsaved_files
,
858 unsigned num_unsaved_files
,
862 << complete_filename
<< ':' << complete_line
<< ':' << complete_column
;
865 if (num_unsaved_files
&& !unsaved_files
)
868 CXCodeCompleteResults
*result
;
869 auto CodeCompleteAtImpl
= [=, &result
]() {
870 result
= clang_codeCompleteAt_Impl(
871 TU
, complete_filename
, complete_line
, complete_column
,
872 llvm::makeArrayRef(unsaved_files
, num_unsaved_files
), options
);
875 llvm::CrashRecoveryContext CRC
;
877 if (!RunSafely(CRC
, CodeCompleteAtImpl
)) {
878 fprintf(stderr
, "libclang: crash detected in code completion\n");
879 cxtu::getASTUnit(TU
)->setUnsafeToFree(true);
881 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
882 PrintLibclangResourceUsage(TU
);
887 unsigned clang_defaultCodeCompleteOptions(void) {
888 return CXCodeComplete_IncludeMacros
;
891 void clang_disposeCodeCompleteResults(CXCodeCompleteResults
*ResultsIn
) {
895 AllocatedCXCodeCompleteResults
*Results
896 = static_cast<AllocatedCXCodeCompleteResults
*>(ResultsIn
);
901 clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults
*ResultsIn
) {
902 AllocatedCXCodeCompleteResults
*Results
903 = static_cast<AllocatedCXCodeCompleteResults
*>(ResultsIn
);
907 return Results
->Diagnostics
.size();
911 clang_codeCompleteGetDiagnostic(CXCodeCompleteResults
*ResultsIn
,
913 AllocatedCXCodeCompleteResults
*Results
914 = static_cast<AllocatedCXCodeCompleteResults
*>(ResultsIn
);
915 if (!Results
|| Index
>= Results
->Diagnostics
.size())
918 CXStoredDiagnostic
*Diag
= Results
->DiagnosticsWrappers
[Index
].get();
920 Diag
= (Results
->DiagnosticsWrappers
[Index
] =
921 std::make_unique
<CXStoredDiagnostic
>(
922 Results
->Diagnostics
[Index
], Results
->LangOpts
))
928 clang_codeCompleteGetContexts(CXCodeCompleteResults
*ResultsIn
) {
929 AllocatedCXCodeCompleteResults
*Results
930 = static_cast<AllocatedCXCodeCompleteResults
*>(ResultsIn
);
934 return Results
->Contexts
;
937 enum CXCursorKind
clang_codeCompleteGetContainerKind(
938 CXCodeCompleteResults
*ResultsIn
,
939 unsigned *IsIncomplete
) {
940 AllocatedCXCodeCompleteResults
*Results
=
941 static_cast<AllocatedCXCodeCompleteResults
*>(ResultsIn
);
943 return CXCursor_InvalidCode
;
945 if (IsIncomplete
!= nullptr) {
946 *IsIncomplete
= Results
->ContainerIsIncomplete
;
949 return Results
->ContainerKind
;
952 CXString
clang_codeCompleteGetContainerUSR(CXCodeCompleteResults
*ResultsIn
) {
953 AllocatedCXCodeCompleteResults
*Results
=
954 static_cast<AllocatedCXCodeCompleteResults
*>(ResultsIn
);
956 return cxstring::createEmpty();
958 return cxstring::createRef(Results
->ContainerUSR
.c_str());
962 CXString
clang_codeCompleteGetObjCSelector(CXCodeCompleteResults
*ResultsIn
) {
963 AllocatedCXCodeCompleteResults
*Results
=
964 static_cast<AllocatedCXCodeCompleteResults
*>(ResultsIn
);
966 return cxstring::createEmpty();
968 return cxstring::createDup(Results
->Selector
);
971 /// Simple utility function that appends a \p New string to the given
972 /// \p Old string, using the \p Buffer for storage.
974 /// \param Old The string to which we are appending. This parameter will be
975 /// updated to reflect the complete string.
978 /// \param New The string to append to \p Old.
980 /// \param Buffer A buffer that stores the actual, concatenated string. It will
981 /// be used if the old string is already-non-empty.
982 static void AppendToString(StringRef
&Old
, StringRef New
,
983 SmallString
<256> &Buffer
) {
990 Buffer
.append(Old
.begin(), Old
.end());
991 Buffer
.append(New
.begin(), New
.end());
995 /// Get the typed-text blocks from the given code-completion string
996 /// and return them as a single string.
998 /// \param String The code-completion string whose typed-text blocks will be
1001 /// \param Buffer A buffer used for storage of the completed name.
1002 static StringRef
GetTypedName(CodeCompletionString
*String
,
1003 SmallString
<256> &Buffer
) {
1005 for (CodeCompletionString::iterator C
= String
->begin(), CEnd
= String
->end();
1007 if (C
->Kind
== CodeCompletionString::CK_TypedText
)
1008 AppendToString(Result
, C
->Text
, Buffer
);
1015 struct OrderCompletionResults
{
1016 bool operator()(const CXCompletionResult
&XR
,
1017 const CXCompletionResult
&YR
) const {
1018 CodeCompletionString
*X
1019 = (CodeCompletionString
*)XR
.CompletionString
;
1020 CodeCompletionString
*Y
1021 = (CodeCompletionString
*)YR
.CompletionString
;
1023 SmallString
<256> XBuffer
;
1024 StringRef XText
= GetTypedName(X
, XBuffer
);
1025 SmallString
<256> YBuffer
;
1026 StringRef YText
= GetTypedName(Y
, YBuffer
);
1028 if (XText
.empty() || YText
.empty())
1029 return !XText
.empty();
1031 int result
= XText
.compare_insensitive(YText
);
1037 result
= XText
.compare(YText
);
1043 void clang_sortCodeCompletionResults(CXCompletionResult
*Results
,
1044 unsigned NumResults
) {
1045 std::stable_sort(Results
, Results
+ NumResults
, OrderCompletionResults());