1 //===--- CodeCompleteConsumer.cpp - Code Completion Interface ---*- C++ -*-===//
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 CodeCompleteConsumer class.
12 //===----------------------------------------------------------------------===//
13 #include "clang/Sema/CodeCompleteConsumer.h"
14 #include "clang/Sema/Scope.h"
15 #include "clang/Sema/Sema.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/Lex/Preprocessor.h"
20 #include "clang-c/Index.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/Support/raw_ostream.h"
27 using namespace clang
;
28 using llvm::StringRef
;
30 //===----------------------------------------------------------------------===//
31 // Code completion context implementation
32 //===----------------------------------------------------------------------===//
34 bool CodeCompletionContext::wantConstructorResults() const {
39 case CCC_ObjCMessageReceiver
:
40 case CCC_ParenthesizedExpression
:
44 case CCC_ObjCInterface
:
45 case CCC_ObjCImplementation
:
46 case CCC_ObjCIvarList
:
47 case CCC_ClassStructUnion
:
48 case CCC_MemberAccess
:
51 case CCC_ClassOrStructTag
:
52 case CCC_ObjCProtocolName
:
56 case CCC_PotentiallyQualifiedName
:
58 case CCC_MacroNameUse
:
59 case CCC_PreprocessorExpression
:
60 case CCC_PreprocessorDirective
:
61 case CCC_NaturalLanguage
:
62 case CCC_SelectorName
:
63 case CCC_TypeQualifiers
:
71 //===----------------------------------------------------------------------===//
72 // Code completion string implementation
73 //===----------------------------------------------------------------------===//
74 CodeCompletionString::Chunk::Chunk(ChunkKind Kind
, llvm::StringRef Text
)
75 : Kind(Kind
), Text("")
83 case CK_CurrentParameter
: {
84 char *New
= new char [Text
.size() + 1];
85 std::memcpy(New
, Text
.data(), Text
.size());
86 New
[Text
.size()] = '\0';
92 llvm_unreachable("Optional strings cannot be created from text");
107 case CK_RightBracket
:
143 case CK_HorizontalSpace
:
147 case CK_VerticalSpace
:
153 CodeCompletionString::Chunk
154 CodeCompletionString::Chunk::CreateText(StringRef Text
) {
155 return Chunk(CK_Text
, Text
);
158 CodeCompletionString::Chunk
159 CodeCompletionString::Chunk::CreateOptional(
160 std::auto_ptr
<CodeCompletionString
> Optional
) {
162 Result
.Kind
= CK_Optional
;
163 Result
.Optional
= Optional
.release();
167 CodeCompletionString::Chunk
168 CodeCompletionString::Chunk::CreatePlaceholder(StringRef Placeholder
) {
169 return Chunk(CK_Placeholder
, Placeholder
);
172 CodeCompletionString::Chunk
173 CodeCompletionString::Chunk::CreateInformative(StringRef Informative
) {
174 return Chunk(CK_Informative
, Informative
);
177 CodeCompletionString::Chunk
178 CodeCompletionString::Chunk::CreateResultType(StringRef ResultType
) {
179 return Chunk(CK_ResultType
, ResultType
);
182 CodeCompletionString::Chunk
183 CodeCompletionString::Chunk::CreateCurrentParameter(
184 StringRef CurrentParameter
) {
185 return Chunk(CK_CurrentParameter
, CurrentParameter
);
188 CodeCompletionString::Chunk
CodeCompletionString::Chunk::Clone() const {
195 case CK_CurrentParameter
:
199 case CK_RightBracket
:
208 case CK_HorizontalSpace
:
209 case CK_VerticalSpace
:
210 return Chunk(Kind
, Text
);
213 std::auto_ptr
<CodeCompletionString
> Opt(Optional
->Clone());
214 return CreateOptional(Opt
);
218 // Silence GCC warning.
223 CodeCompletionString::Chunk::Destroy() {
234 case CK_CurrentParameter
:
241 case CK_RightBracket
:
250 case CK_HorizontalSpace
:
251 case CK_VerticalSpace
:
256 void CodeCompletionString::clear() {
257 std::for_each(Chunks
.begin(), Chunks
.end(),
258 std::mem_fun_ref(&Chunk::Destroy
));
262 std::string
CodeCompletionString::getAsString() const {
264 llvm::raw_string_ostream
OS(Result
);
266 for (iterator C
= begin(), CEnd
= end(); C
!= CEnd
; ++C
) {
268 case CK_Optional
: OS
<< "{#" << C
->Optional
->getAsString() << "#}"; break;
269 case CK_Placeholder
: OS
<< "<#" << C
->Text
<< "#>"; break;
273 OS
<< "[#" << C
->Text
<< "#]";
276 case CK_CurrentParameter
: OS
<< "<#" << C
->Text
<< "#>"; break;
277 default: OS
<< C
->Text
; break;
283 const char *CodeCompletionString::getTypedText() const {
284 for (iterator C
= begin(), CEnd
= end(); C
!= CEnd
; ++C
)
285 if (C
->Kind
== CK_TypedText
)
291 CodeCompletionString
*
292 CodeCompletionString::Clone(CodeCompletionString
*Result
) const {
294 Result
= new CodeCompletionString
;
295 for (iterator C
= begin(), CEnd
= end(); C
!= CEnd
; ++C
)
296 Result
->AddChunk(C
->Clone());
300 void CodeCompletionResult::Destroy() {
301 if (Kind
== RK_Pattern
) {
307 unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl
*ND
) {
311 // Context-based decisions.
312 DeclContext
*DC
= ND
->getDeclContext()->getRedeclContext();
313 if (DC
->isFunctionOrMethod() || isa
<BlockDecl
>(DC
)) {
314 // _cmd is relatively rare
315 if (ImplicitParamDecl
*ImplicitParam
= dyn_cast
<ImplicitParamDecl
>(ND
))
316 if (ImplicitParam
->getIdentifier() &&
317 ImplicitParam
->getIdentifier()->isStr("_cmd"))
320 return CCP_LocalDeclaration
;
322 if (DC
->isRecord() || isa
<ObjCContainerDecl
>(DC
))
323 return CCP_MemberDeclaration
;
325 // Content-based decisions.
326 if (isa
<EnumConstantDecl
>(ND
))
328 if (isa
<TypeDecl
>(ND
) || isa
<ObjCInterfaceDecl
>(ND
))
331 return CCP_Declaration
;
334 //===----------------------------------------------------------------------===//
335 // Code completion overload candidate implementation
336 //===----------------------------------------------------------------------===//
338 CodeCompleteConsumer::OverloadCandidate::getFunction() const {
339 if (getKind() == CK_Function
)
341 else if (getKind() == CK_FunctionTemplate
)
342 return FunctionTemplate
->getTemplatedDecl();
348 CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
351 return Function
->getType()->getAs
<FunctionType
>();
353 case CK_FunctionTemplate
:
354 return FunctionTemplate
->getTemplatedDecl()->getType()
355 ->getAs
<FunctionType
>();
357 case CK_FunctionType
:
364 //===----------------------------------------------------------------------===//
365 // Code completion consumer implementation
366 //===----------------------------------------------------------------------===//
368 CodeCompleteConsumer::~CodeCompleteConsumer() { }
371 PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema
&SemaRef
,
372 CodeCompletionContext Context
,
373 CodeCompletionResult
*Results
,
374 unsigned NumResults
) {
375 std::stable_sort(Results
, Results
+ NumResults
);
377 // Print the results.
378 for (unsigned I
= 0; I
!= NumResults
; ++I
) {
379 OS
<< "COMPLETION: ";
380 switch (Results
[I
].Kind
) {
381 case CodeCompletionResult::RK_Declaration
:
382 OS
<< Results
[I
].Declaration
;
383 if (Results
[I
].Hidden
)
385 if (CodeCompletionString
*CCS
386 = Results
[I
].CreateCodeCompletionString(SemaRef
)) {
387 OS
<< " : " << CCS
->getAsString();
394 case CodeCompletionResult::RK_Keyword
:
395 OS
<< Results
[I
].Keyword
<< '\n';
398 case CodeCompletionResult::RK_Macro
: {
399 OS
<< Results
[I
].Macro
->getName();
400 if (CodeCompletionString
*CCS
401 = Results
[I
].CreateCodeCompletionString(SemaRef
)) {
402 OS
<< " : " << CCS
->getAsString();
409 case CodeCompletionResult::RK_Pattern
: {
411 << Results
[I
].Pattern
->getAsString() << '\n';
419 PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema
&SemaRef
,
421 OverloadCandidate
*Candidates
,
422 unsigned NumCandidates
) {
423 for (unsigned I
= 0; I
!= NumCandidates
; ++I
) {
424 if (CodeCompletionString
*CCS
425 = Candidates
[I
].CreateSignatureString(CurrentArg
, SemaRef
)) {
426 OS
<< "OVERLOAD: " << CCS
->getAsString() << "\n";
432 void CodeCompletionResult::computeCursorKindAndAvailability() {
435 // Set the availability based on attributes.
436 Availability
= CXAvailability_Available
;
437 if (Declaration
->getAttr
<UnavailableAttr
>())
438 Availability
= CXAvailability_NotAvailable
;
439 else if (Declaration
->getAttr
<DeprecatedAttr
>())
440 Availability
= CXAvailability_Deprecated
;
442 if (FunctionDecl
*Function
= dyn_cast
<FunctionDecl
>(Declaration
))
443 if (Function
->isDeleted())
444 Availability
= CXAvailability_NotAvailable
;
446 CursorKind
= getCursorKindForDecl(Declaration
);
447 if (CursorKind
== CXCursor_UnexposedDecl
)
448 CursorKind
= CXCursor_NotImplemented
;
452 Availability
= CXAvailability_Available
;
453 CursorKind
= CXCursor_MacroDefinition
;
457 Availability
= CXAvailability_Available
;
458 CursorKind
= CXCursor_NotImplemented
;
462 // Do nothing: Patterns can come with cursor kinds!
467 /// \brief Retrieve the name that should be used to order a result.
469 /// If the name needs to be constructed as a string, that string will be
470 /// saved into Saved and the returned StringRef will refer to it.
471 static llvm::StringRef
getOrderedName(const CodeCompletionResult
&R
,
472 std::string
&Saved
) {
474 case CodeCompletionResult::RK_Keyword
:
477 case CodeCompletionResult::RK_Pattern
:
478 return R
.Pattern
->getTypedText();
480 case CodeCompletionResult::RK_Macro
:
481 return R
.Macro
->getName();
483 case CodeCompletionResult::RK_Declaration
:
484 // Handle declarations below.
488 DeclarationName Name
= R
.Declaration
->getDeclName();
490 // If the name is a simple identifier (by far the common case), or a
491 // zero-argument selector, just return a reference to that identifier.
492 if (IdentifierInfo
*Id
= Name
.getAsIdentifierInfo())
493 return Id
->getName();
494 if (Name
.isObjCZeroArgSelector())
495 if (IdentifierInfo
*Id
496 = Name
.getObjCSelector().getIdentifierInfoForSlot(0))
497 return Id
->getName();
499 Saved
= Name
.getAsString();
503 bool clang::operator<(const CodeCompletionResult
&X
,
504 const CodeCompletionResult
&Y
) {
505 std::string XSaved
, YSaved
;
506 llvm::StringRef XStr
= getOrderedName(X
, XSaved
);
507 llvm::StringRef YStr
= getOrderedName(Y
, YSaved
);
508 int cmp
= XStr
.compare_lower(YStr
);
512 // If case-insensitive comparison fails, try case-sensitive comparison.
513 cmp
= XStr
.compare(YStr
);