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/ADT/Twine.h"
23 #include "llvm/Support/raw_ostream.h"
28 using namespace clang
;
29 using llvm::StringRef
;
31 //===----------------------------------------------------------------------===//
32 // Code completion context implementation
33 //===----------------------------------------------------------------------===//
35 bool CodeCompletionContext::wantConstructorResults() const {
40 case CCC_ObjCMessageReceiver
:
41 case CCC_ParenthesizedExpression
:
45 case CCC_ObjCInterface
:
46 case CCC_ObjCImplementation
:
47 case CCC_ObjCIvarList
:
48 case CCC_ClassStructUnion
:
49 case CCC_MemberAccess
:
52 case CCC_ClassOrStructTag
:
53 case CCC_ObjCProtocolName
:
57 case CCC_PotentiallyQualifiedName
:
59 case CCC_MacroNameUse
:
60 case CCC_PreprocessorExpression
:
61 case CCC_PreprocessorDirective
:
62 case CCC_NaturalLanguage
:
63 case CCC_SelectorName
:
64 case CCC_TypeQualifiers
:
72 //===----------------------------------------------------------------------===//
73 // Code completion string implementation
74 //===----------------------------------------------------------------------===//
75 CodeCompletionString::Chunk::Chunk(ChunkKind Kind
, const char *Text
)
76 : Kind(Kind
), Text("")
84 case CK_CurrentParameter
:
89 llvm_unreachable("Optional strings cannot be created from text");
104 case CK_RightBracket
:
140 case CK_HorizontalSpace
:
144 case CK_VerticalSpace
:
150 CodeCompletionString::Chunk
151 CodeCompletionString::Chunk::CreateText(const char *Text
) {
152 return Chunk(CK_Text
, Text
);
155 CodeCompletionString::Chunk
156 CodeCompletionString::Chunk::CreateOptional(CodeCompletionString
*Optional
) {
158 Result
.Kind
= CK_Optional
;
159 Result
.Optional
= Optional
;
163 CodeCompletionString::Chunk
164 CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder
) {
165 return Chunk(CK_Placeholder
, Placeholder
);
168 CodeCompletionString::Chunk
169 CodeCompletionString::Chunk::CreateInformative(const char *Informative
) {
170 return Chunk(CK_Informative
, Informative
);
173 CodeCompletionString::Chunk
174 CodeCompletionString::Chunk::CreateResultType(const char *ResultType
) {
175 return Chunk(CK_ResultType
, ResultType
);
178 CodeCompletionString::Chunk
179 CodeCompletionString::Chunk::CreateCurrentParameter(
180 const char *CurrentParameter
) {
181 return Chunk(CK_CurrentParameter
, CurrentParameter
);
184 CodeCompletionString::CodeCompletionString(const Chunk
*Chunks
,
187 CXAvailabilityKind Availability
)
188 : NumChunks(NumChunks
), Priority(Priority
), Availability(Availability
)
190 Chunk
*StoredChunks
= reinterpret_cast<Chunk
*>(this + 1);
191 for (unsigned I
= 0; I
!= NumChunks
; ++I
)
192 StoredChunks
[I
] = Chunks
[I
];
195 std::string
CodeCompletionString::getAsString() const {
197 llvm::raw_string_ostream
OS(Result
);
199 for (iterator C
= begin(), CEnd
= end(); C
!= CEnd
; ++C
) {
201 case CK_Optional
: OS
<< "{#" << C
->Optional
->getAsString() << "#}"; break;
202 case CK_Placeholder
: OS
<< "<#" << C
->Text
<< "#>"; break;
206 OS
<< "[#" << C
->Text
<< "#]";
209 case CK_CurrentParameter
: OS
<< "<#" << C
->Text
<< "#>"; break;
210 default: OS
<< C
->Text
; break;
216 const char *CodeCompletionString::getTypedText() const {
217 for (iterator C
= begin(), CEnd
= end(); C
!= CEnd
; ++C
)
218 if (C
->Kind
== CK_TypedText
)
224 const char *CodeCompletionAllocator::CopyString(llvm::StringRef String
) {
225 char *Mem
= (char *)Allocate(String
.size() + 1, 1);
226 std::copy(String
.begin(), String
.end(), Mem
);
227 Mem
[String
.size()] = 0;
231 const char *CodeCompletionAllocator::CopyString(llvm::Twine String
) {
232 // FIXME: It would be more efficient to teach Twine to tell us its size and
233 // then add a routine there to fill in an allocated char* with the contents
235 llvm::SmallString
<128> Data
;
236 return CopyString(String
.toStringRef(Data
));
239 CodeCompletionString
*CodeCompletionBuilder::TakeString() {
240 void *Mem
= Allocator
.Allocate(
241 sizeof(CodeCompletionString
) + sizeof(Chunk
) * Chunks
.size(),
242 llvm::alignOf
<CodeCompletionString
>());
243 CodeCompletionString
*Result
244 = new (Mem
) CodeCompletionString(Chunks
.data(), Chunks
.size(),
245 Priority
, Availability
);
250 unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl
*ND
) {
254 // Context-based decisions.
255 DeclContext
*DC
= ND
->getDeclContext()->getRedeclContext();
256 if (DC
->isFunctionOrMethod() || isa
<BlockDecl
>(DC
)) {
257 // _cmd is relatively rare
258 if (ImplicitParamDecl
*ImplicitParam
= dyn_cast
<ImplicitParamDecl
>(ND
))
259 if (ImplicitParam
->getIdentifier() &&
260 ImplicitParam
->getIdentifier()->isStr("_cmd"))
263 return CCP_LocalDeclaration
;
265 if (DC
->isRecord() || isa
<ObjCContainerDecl
>(DC
))
266 return CCP_MemberDeclaration
;
268 // Content-based decisions.
269 if (isa
<EnumConstantDecl
>(ND
))
271 if (isa
<TypeDecl
>(ND
) || isa
<ObjCInterfaceDecl
>(ND
))
274 return CCP_Declaration
;
277 //===----------------------------------------------------------------------===//
278 // Code completion overload candidate implementation
279 //===----------------------------------------------------------------------===//
281 CodeCompleteConsumer::OverloadCandidate::getFunction() const {
282 if (getKind() == CK_Function
)
284 else if (getKind() == CK_FunctionTemplate
)
285 return FunctionTemplate
->getTemplatedDecl();
291 CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
294 return Function
->getType()->getAs
<FunctionType
>();
296 case CK_FunctionTemplate
:
297 return FunctionTemplate
->getTemplatedDecl()->getType()
298 ->getAs
<FunctionType
>();
300 case CK_FunctionType
:
307 //===----------------------------------------------------------------------===//
308 // Code completion consumer implementation
309 //===----------------------------------------------------------------------===//
311 CodeCompleteConsumer::~CodeCompleteConsumer() { }
314 PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema
&SemaRef
,
315 CodeCompletionContext Context
,
316 CodeCompletionResult
*Results
,
317 unsigned NumResults
) {
318 std::stable_sort(Results
, Results
+ NumResults
);
320 // Print the results.
321 for (unsigned I
= 0; I
!= NumResults
; ++I
) {
322 OS
<< "COMPLETION: ";
323 switch (Results
[I
].Kind
) {
324 case CodeCompletionResult::RK_Declaration
:
325 OS
<< Results
[I
].Declaration
;
326 if (Results
[I
].Hidden
)
328 if (CodeCompletionString
*CCS
329 = Results
[I
].CreateCodeCompletionString(SemaRef
, Allocator
)) {
330 OS
<< " : " << CCS
->getAsString();
336 case CodeCompletionResult::RK_Keyword
:
337 OS
<< Results
[I
].Keyword
<< '\n';
340 case CodeCompletionResult::RK_Macro
: {
341 OS
<< Results
[I
].Macro
->getName();
342 if (CodeCompletionString
*CCS
343 = Results
[I
].CreateCodeCompletionString(SemaRef
, Allocator
)) {
344 OS
<< " : " << CCS
->getAsString();
350 case CodeCompletionResult::RK_Pattern
: {
352 << Results
[I
].Pattern
->getAsString() << '\n';
360 PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema
&SemaRef
,
362 OverloadCandidate
*Candidates
,
363 unsigned NumCandidates
) {
364 for (unsigned I
= 0; I
!= NumCandidates
; ++I
) {
365 if (CodeCompletionString
*CCS
366 = Candidates
[I
].CreateSignatureString(CurrentArg
, SemaRef
,
368 OS
<< "OVERLOAD: " << CCS
->getAsString() << "\n";
373 void CodeCompletionResult::computeCursorKindAndAvailability() {
376 // Set the availability based on attributes.
377 Availability
= CXAvailability_Available
;
378 if (Declaration
->getAttr
<UnavailableAttr
>())
379 Availability
= CXAvailability_NotAvailable
;
380 else if (Declaration
->getAttr
<DeprecatedAttr
>())
381 Availability
= CXAvailability_Deprecated
;
383 if (FunctionDecl
*Function
= dyn_cast
<FunctionDecl
>(Declaration
))
384 if (Function
->isDeleted())
385 Availability
= CXAvailability_NotAvailable
;
387 CursorKind
= getCursorKindForDecl(Declaration
);
388 if (CursorKind
== CXCursor_UnexposedDecl
)
389 CursorKind
= CXCursor_NotImplemented
;
393 Availability
= CXAvailability_Available
;
394 CursorKind
= CXCursor_MacroDefinition
;
398 Availability
= CXAvailability_Available
;
399 CursorKind
= CXCursor_NotImplemented
;
403 // Do nothing: Patterns can come with cursor kinds!
408 /// \brief Retrieve the name that should be used to order a result.
410 /// If the name needs to be constructed as a string, that string will be
411 /// saved into Saved and the returned StringRef will refer to it.
412 static llvm::StringRef
getOrderedName(const CodeCompletionResult
&R
,
413 std::string
&Saved
) {
415 case CodeCompletionResult::RK_Keyword
:
418 case CodeCompletionResult::RK_Pattern
:
419 return R
.Pattern
->getTypedText();
421 case CodeCompletionResult::RK_Macro
:
422 return R
.Macro
->getName();
424 case CodeCompletionResult::RK_Declaration
:
425 // Handle declarations below.
429 DeclarationName Name
= R
.Declaration
->getDeclName();
431 // If the name is a simple identifier (by far the common case), or a
432 // zero-argument selector, just return a reference to that identifier.
433 if (IdentifierInfo
*Id
= Name
.getAsIdentifierInfo())
434 return Id
->getName();
435 if (Name
.isObjCZeroArgSelector())
436 if (IdentifierInfo
*Id
437 = Name
.getObjCSelector().getIdentifierInfoForSlot(0))
438 return Id
->getName();
440 Saved
= Name
.getAsString();
444 bool clang::operator<(const CodeCompletionResult
&X
,
445 const CodeCompletionResult
&Y
) {
446 std::string XSaved
, YSaved
;
447 llvm::StringRef XStr
= getOrderedName(X
, XSaved
);
448 llvm::StringRef YStr
= getOrderedName(Y
, YSaved
);
449 int cmp
= XStr
.compare_lower(YStr
);
453 // If case-insensitive comparison fails, try case-sensitive comparison.
454 cmp
= XStr
.compare(YStr
);