CodeCompleteConsumer.cpp revision ac547d56ba6725811c9f09c241785bc230ce5345
1//===---- CodeCompleteConsumer.h - Code Completion Interface ----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the CodeCompleteConsumer class. 11// 12//===----------------------------------------------------------------------===// 13#include "clang/Sema/CodeCompleteConsumer.h" 14#include "clang/AST/DeclCXX.h" 15#include "clang/Parse/Scope.h" 16#include "clang/Lex/Preprocessor.h" 17#include "Sema.h" 18#include "llvm/ADT/STLExtras.h" 19#include "llvm/Support/Compiler.h" 20#include "llvm/Support/raw_ostream.h" 21#include <algorithm> 22#include <cstring> 23#include <functional> 24using namespace clang; 25 26//===----------------------------------------------------------------------===// 27// Code completion string implementation 28//===----------------------------------------------------------------------===// 29CodeCompletionString::Chunk 30CodeCompletionString::Chunk::CreateText(const char *Text) { 31 Chunk Result; 32 Result.Kind = CK_Text; 33 char *New = new char [std::strlen(Text) + 1]; 34 std::strcpy(New, Text); 35 Result.Text = New; 36 return Result; 37} 38 39CodeCompletionString::Chunk 40CodeCompletionString::Chunk::CreateOptional( 41 std::auto_ptr<CodeCompletionString> Optional) { 42 Chunk Result; 43 Result.Kind = CK_Optional; 44 Result.Optional = Optional.release(); 45 return Result; 46} 47 48CodeCompletionString::Chunk 49CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) { 50 Chunk Result; 51 Result.Kind = CK_Placeholder; 52 char *New = new char [std::strlen(Placeholder) + 1]; 53 std::strcpy(New, Placeholder); 54 Result.Placeholder = New; 55 return Result; 56} 57 58void 59CodeCompletionString::Chunk::Destroy() { 60 switch (Kind) { 61 case CK_Text: delete [] Text; break; 62 case CK_Optional: delete Optional; break; 63 case CK_Placeholder: delete [] Placeholder; break; 64 } 65} 66 67CodeCompletionString::~CodeCompletionString() { 68 std::for_each(Chunks.begin(), Chunks.end(), 69 std::mem_fun_ref(&Chunk::Destroy)); 70} 71 72std::string CodeCompletionString::getAsString() const { 73 std::string Result; 74 llvm::raw_string_ostream OS(Result); 75 76 for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) { 77 switch (C->Kind) { 78 case CK_Text: OS << C->Text; break; 79 case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break; 80 case CK_Placeholder: OS << "<#" << C->Placeholder << "#>"; break; 81 } 82 } 83 84 return Result; 85} 86 87//===----------------------------------------------------------------------===// 88// Code completion consumer implementation 89//===----------------------------------------------------------------------===// 90 91CodeCompleteConsumer::CodeCompleteConsumer(Sema &S) : SemaRef(S) { 92 SemaRef.setCodeCompleteConsumer(this); 93} 94 95CodeCompleteConsumer::~CodeCompleteConsumer() { 96 SemaRef.setCodeCompleteConsumer(0); 97} 98 99void 100CodeCompleteConsumer::CodeCompleteMemberReferenceExpr(Scope *S, 101 QualType BaseType, 102 bool IsArrow) { 103 if (IsArrow) { 104 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) 105 BaseType = Ptr->getPointeeType(); 106 else if (BaseType->isObjCObjectPointerType()) 107 /*Do nothing*/ ; 108 else 109 return; 110 } 111 112 ResultSet Results(*this); 113 unsigned NextRank = 0; 114 115 if (const RecordType *Record = BaseType->getAs<RecordType>()) { 116 NextRank = CollectMemberLookupResults(Record->getDecl(), NextRank, Results); 117 118 if (getSema().getLangOptions().CPlusPlus) { 119 if (!Results.empty()) 120 // The "template" keyword can follow "->" or "." in the grammar. 121 Results.MaybeAddResult(Result("template", NextRank++)); 122 123 // We could have the start of a nested-name-specifier. Add those 124 // results as well. 125 Results.setFilter(&CodeCompleteConsumer::IsNestedNameSpecifier); 126 CollectLookupResults(S, NextRank, Results); 127 } 128 129 // Hand off the results found for code completion. 130 ProcessCodeCompleteResults(Results.data(), Results.size()); 131 132 // We're done! 133 return; 134 } 135} 136 137void CodeCompleteConsumer::CodeCompleteTag(Scope *S, ElaboratedType::TagKind TK) { 138 ResultSet::LookupFilter Filter = 0; 139 switch (TK) { 140 case ElaboratedType::TK_enum: 141 Filter = &CodeCompleteConsumer::IsEnum; 142 break; 143 144 case ElaboratedType::TK_class: 145 case ElaboratedType::TK_struct: 146 Filter = &CodeCompleteConsumer::IsClassOrStruct; 147 break; 148 149 case ElaboratedType::TK_union: 150 Filter = &CodeCompleteConsumer::IsUnion; 151 break; 152 } 153 154 ResultSet Results(*this, Filter); 155 unsigned NextRank = CollectLookupResults(S, 0, Results); 156 157 if (getSema().getLangOptions().CPlusPlus) { 158 // We could have the start of a nested-name-specifier. Add those 159 // results as well. 160 Results.setFilter(&CodeCompleteConsumer::IsNestedNameSpecifier); 161 CollectLookupResults(S, NextRank, Results); 162 } 163 164 ProcessCodeCompleteResults(Results.data(), Results.size()); 165} 166 167void 168CodeCompleteConsumer::CodeCompleteQualifiedId(Scope *S, 169 NestedNameSpecifier *NNS, 170 bool EnteringContext) { 171 CXXScopeSpec SS; 172 SS.setScopeRep(NNS); 173 DeclContext *Ctx = getSema().computeDeclContext(SS, EnteringContext); 174 if (!Ctx) 175 return; 176 177 ResultSet Results(*this); 178 unsigned NextRank = CollectMemberLookupResults(Ctx, 0, Results); 179 180 // The "template" keyword can follow "::" in the grammar 181 if (!Results.empty()) 182 Results.MaybeAddResult(Result("template", NextRank)); 183 184 ProcessCodeCompleteResults(Results.data(), Results.size()); 185} 186 187void CodeCompleteConsumer::CodeCompleteUsing(Scope *S) { 188 ResultSet Results(*this, &CodeCompleteConsumer::IsNestedNameSpecifier); 189 190 // If we aren't in class scope, we could see the "namespace" keyword. 191 if (!S->isClassScope()) 192 Results.MaybeAddResult(Result("namespace", 0)); 193 194 // After "using", we can see anything that would start a 195 // nested-name-specifier. 196 CollectLookupResults(S, 0, Results); 197 198 ProcessCodeCompleteResults(Results.data(), Results.size()); 199} 200 201void CodeCompleteConsumer::CodeCompleteUsingDirective(Scope *S) { 202 // After "using namespace", we expect to see a namespace name or namespace 203 // alias. 204 ResultSet Results(*this, &CodeCompleteConsumer::IsNamespaceOrAlias); 205 CollectLookupResults(S, 0, Results); 206 ProcessCodeCompleteResults(Results.data(), Results.size()); 207} 208 209void CodeCompleteConsumer::CodeCompleteNamespaceDecl(Scope *S) { 210 ResultSet Results(*this, &CodeCompleteConsumer::IsNamespace); 211 DeclContext *Ctx = (DeclContext *)S->getEntity(); 212 if (!S->getParent()) 213 Ctx = getSema().Context.getTranslationUnitDecl(); 214 215 if (Ctx && Ctx->isFileContext()) { 216 // We only want to see those namespaces that have already been defined 217 // within this scope, because its likely that the user is creating an 218 // extended namespace declaration. Keep track of the most recent 219 // definition of each namespace. 220 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest; 221 for (DeclContext::specific_decl_iterator<NamespaceDecl> 222 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end()); 223 NS != NSEnd; ++NS) 224 OrigToLatest[NS->getOriginalNamespace()] = *NS; 225 226 // Add the most recent definition (or extended definition) of each 227 // namespace to the list of results. 228 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator 229 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end(); 230 NS != NSEnd; ++NS) 231 Results.MaybeAddResult(Result(NS->second, 0)); 232 } 233 234 ProcessCodeCompleteResults(Results.data(), Results.size()); 235} 236 237void CodeCompleteConsumer::CodeCompleteNamespaceAliasDecl(Scope *S) { 238 // After "namespace", we expect to see a namespace or alias. 239 ResultSet Results(*this, &CodeCompleteConsumer::IsNamespaceOrAlias); 240 CollectLookupResults(S, 0, Results); 241 ProcessCodeCompleteResults(Results.data(), Results.size()); 242} 243 244void CodeCompleteConsumer::CodeCompleteOperatorName(Scope *S) { 245 ResultSet Results(*this, &CodeCompleteConsumer::IsType); 246 247 // Add the names of overloadable operators. 248#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 249 if (std::strcmp(Spelling, "?")) \ 250 Results.MaybeAddResult(Result(Spelling, 0)); 251#include "clang/Basic/OperatorKinds.def" 252 253 // Add any type names visible from the current scope 254 unsigned NextRank = CollectLookupResults(S, 0, Results); 255 256 // Add any type specifiers 257 AddTypeSpecifierResults(0, Results); 258 259 // Add any nested-name-specifiers 260 Results.setFilter(&CodeCompleteConsumer::IsNestedNameSpecifier); 261 CollectLookupResults(S, NextRank + 1, Results); 262 263 ProcessCodeCompleteResults(Results.data(), Results.size()); 264} 265 266void CodeCompleteConsumer::ResultSet::MaybeAddResult(Result R) { 267 if (R.Kind != Result::RK_Declaration) { 268 // For non-declaration results, just add the result. 269 Results.push_back(R); 270 return; 271 } 272 273 // Look through using declarations. 274 if (UsingDecl *Using = dyn_cast<UsingDecl>(R.Declaration)) 275 return MaybeAddResult(Result(Using->getTargetDecl(), R.Rank)); 276 277 // Handle each declaration in an overload set separately. 278 if (OverloadedFunctionDecl *Ovl 279 = dyn_cast<OverloadedFunctionDecl>(R.Declaration)) { 280 for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(), 281 FEnd = Ovl->function_end(); 282 F != FEnd; ++F) 283 MaybeAddResult(Result(*F, R.Rank)); 284 285 return; 286 } 287 288 Decl *CanonDecl = R.Declaration->getCanonicalDecl(); 289 unsigned IDNS = CanonDecl->getIdentifierNamespace(); 290 291 // Friend declarations and declarations introduced due to friends are never 292 // added as results. 293 if (isa<FriendDecl>(CanonDecl) || 294 (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))) 295 return; 296 297 if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) { 298 // __va_list_tag is a freak of nature. Find it and skip it. 299 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list")) 300 return; 301 302 // FIXME: Should we filter out other names in the implementation's 303 // namespace, e.g., those containing a __ or that start with _[A-Z]? 304 } 305 306 // C++ constructors are never found by name lookup. 307 if (isa<CXXConstructorDecl>(CanonDecl)) 308 return; 309 310 // Filter out any unwanted results. 311 if (Filter && !(Completer.*Filter)(R.Declaration)) 312 return; 313 314 ShadowMap &SMap = ShadowMaps.back(); 315 ShadowMap::iterator I, IEnd; 316 for (llvm::tie(I, IEnd) = SMap.equal_range(R.Declaration->getDeclName()); 317 I != IEnd; ++I) { 318 NamedDecl *ND = I->second.first; 319 unsigned Index = I->second.second; 320 if (ND->getCanonicalDecl() == CanonDecl) { 321 // This is a redeclaration. Always pick the newer declaration. 322 I->second.first = R.Declaration; 323 Results[Index].Declaration = R.Declaration; 324 325 // Pick the best rank of the two. 326 Results[Index].Rank = std::min(Results[Index].Rank, R.Rank); 327 328 // We're done. 329 return; 330 } 331 } 332 333 // This is a new declaration in this scope. However, check whether this 334 // declaration name is hidden by a similarly-named declaration in an outer 335 // scope. 336 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end(); 337 --SMEnd; 338 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) { 339 for (llvm::tie(I, IEnd) = SM->equal_range(R.Declaration->getDeclName()); 340 I != IEnd; ++I) { 341 // A tag declaration does not hide a non-tag declaration. 342 if (I->second.first->getIdentifierNamespace() == Decl::IDNS_Tag && 343 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary | 344 Decl::IDNS_ObjCProtocol))) 345 continue; 346 347 // Protocols are in distinct namespaces from everything else. 348 if (((I->second.first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol) 349 || (IDNS & Decl::IDNS_ObjCProtocol)) && 350 I->second.first->getIdentifierNamespace() != IDNS) 351 continue; 352 353 // The newly-added result is hidden by an entry in the shadow map. 354 if (Completer.canHiddenResultBeFound(R.Declaration, I->second.first)) { 355 // Note that this result was hidden. 356 R.Hidden = true; 357 } else { 358 // This result was hidden and cannot be found; don't bother adding 359 // it. 360 return; 361 } 362 363 break; 364 } 365 } 366 367 // Make sure that any given declaration only shows up in the result set once. 368 if (!AllDeclsFound.insert(CanonDecl)) 369 return; 370 371 // Insert this result into the set of results and into the current shadow 372 // map. 373 SMap.insert(std::make_pair(R.Declaration->getDeclName(), 374 std::make_pair(R.Declaration, Results.size()))); 375 Results.push_back(R); 376} 377 378/// \brief Enter into a new scope. 379void CodeCompleteConsumer::ResultSet::EnterNewScope() { 380 ShadowMaps.push_back(ShadowMap()); 381} 382 383/// \brief Exit from the current scope. 384void CodeCompleteConsumer::ResultSet::ExitScope() { 385 ShadowMaps.pop_back(); 386} 387 388// Find the next outer declaration context corresponding to this scope. 389static DeclContext *findOuterContext(Scope *S) { 390 for (S = S->getParent(); S; S = S->getParent()) 391 if (S->getEntity()) 392 return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext(); 393 394 return 0; 395} 396 397/// \brief Collect the results of searching for declarations within the given 398/// scope and its parent scopes. 399/// 400/// \param S the scope in which we will start looking for declarations. 401/// 402/// \param InitialRank the initial rank given to results in this scope. 403/// Larger rank values will be used for results found in parent scopes. 404unsigned CodeCompleteConsumer::CollectLookupResults(Scope *S, 405 unsigned InitialRank, 406 ResultSet &Results) { 407 if (!S) 408 return InitialRank; 409 410 // FIXME: Using directives! 411 412 unsigned NextRank = InitialRank; 413 Results.EnterNewScope(); 414 if (S->getEntity() && 415 !((DeclContext *)S->getEntity())->isFunctionOrMethod()) { 416 // Look into this scope's declaration context, along with any of its 417 // parent lookup contexts (e.g., enclosing classes), up to the point 418 // where we hit the context stored in the next outer scope. 419 DeclContext *Ctx = (DeclContext *)S->getEntity(); 420 DeclContext *OuterCtx = findOuterContext(S); 421 422 for (; Ctx && Ctx->getPrimaryContext() != OuterCtx; 423 Ctx = Ctx->getLookupParent()) { 424 if (Ctx->isFunctionOrMethod()) 425 continue; 426 427 NextRank = CollectMemberLookupResults(Ctx, NextRank + 1, Results); 428 } 429 } else if (!S->getParent()) { 430 // Look into the translation unit scope. We walk through the translation 431 // unit's declaration context, because the Scope itself won't have all of 432 // the declarations if 433 NextRank = CollectMemberLookupResults( 434 getSema().Context.getTranslationUnitDecl(), 435 NextRank + 1, Results); 436 } else { 437 // Walk through the declarations in this Scope. 438 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); 439 D != DEnd; ++D) { 440 if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get()))) 441 Results.MaybeAddResult(Result(ND, NextRank)); 442 } 443 444 NextRank = NextRank + 1; 445 } 446 447 // Lookup names in the parent scope. 448 NextRank = CollectLookupResults(S->getParent(), NextRank, Results); 449 Results.ExitScope(); 450 451 return NextRank; 452} 453 454/// \brief Collect the results of searching for members within the given 455/// declaration context. 456/// 457/// \param Ctx the declaration context from which we will gather results. 458/// 459/// \param InitialRank the initial rank given to results in this declaration 460/// context. Larger rank values will be used for, e.g., members found in 461/// base classes. 462/// 463/// \param Results the result set that will be extended with any results 464/// found within this declaration context (and, for a C++ class, its bases). 465/// 466/// \returns the next higher rank value, after considering all of the 467/// names within this declaration context. 468unsigned CodeCompleteConsumer::CollectMemberLookupResults(DeclContext *Ctx, 469 unsigned InitialRank, 470 ResultSet &Results) { 471 llvm::SmallPtrSet<DeclContext *, 16> Visited; 472 return CollectMemberLookupResults(Ctx, InitialRank, Visited, Results); 473} 474 475/// \brief Collect the results of searching for members within the given 476/// declaration context. 477/// 478/// \param Ctx the declaration context from which we will gather results. 479/// 480/// \param InitialRank the initial rank given to results in this declaration 481/// context. Larger rank values will be used for, e.g., members found in 482/// base classes. 483/// 484/// \param Visited the set of declaration contexts that have already been 485/// visited. Declaration contexts will only be visited once. 486/// 487/// \param Results the result set that will be extended with any results 488/// found within this declaration context (and, for a C++ class, its bases). 489/// 490/// \returns the next higher rank value, after considering all of the 491/// names within this declaration context. 492unsigned CodeCompleteConsumer::CollectMemberLookupResults(DeclContext *Ctx, 493 unsigned InitialRank, 494 llvm::SmallPtrSet<DeclContext *, 16> &Visited, 495 ResultSet &Results) { 496 // Make sure we don't visit the same context twice. 497 if (!Visited.insert(Ctx->getPrimaryContext())) 498 return InitialRank; 499 500 // Enumerate all of the results in this context. 501 Results.EnterNewScope(); 502 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx; 503 CurCtx = CurCtx->getNextContext()) { 504 for (DeclContext::decl_iterator D = CurCtx->decls_begin(), 505 DEnd = CurCtx->decls_end(); 506 D != DEnd; ++D) { 507 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) 508 Results.MaybeAddResult(Result(ND, InitialRank)); 509 } 510 } 511 512 // Traverse the contexts of inherited classes. 513 unsigned NextRank = InitialRank; 514 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) { 515 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(), 516 BEnd = Record->bases_end(); 517 B != BEnd; ++B) { 518 QualType BaseType = B->getType(); 519 520 // Don't look into dependent bases, because name lookup can't look 521 // there anyway. 522 if (BaseType->isDependentType()) 523 continue; 524 525 const RecordType *Record = BaseType->getAs<RecordType>(); 526 if (!Record) 527 continue; 528 529 // FIXME: It would be nice to be able to determine whether referencing 530 // a particular member would be ambiguous. For example, given 531 // 532 // struct A { int member; }; 533 // struct B { int member; }; 534 // struct C : A, B { }; 535 // 536 // void f(C *c) { c->### } 537 // accessing 'member' would result in an ambiguity. However, code 538 // completion could be smart enough to qualify the member with the 539 // base class, e.g., 540 // 541 // c->B::member 542 // 543 // or 544 // 545 // c->A::member 546 547 // Collect results from this base class (and its bases). 548 NextRank = std::max(NextRank, 549 CollectMemberLookupResults(Record->getDecl(), 550 InitialRank + 1, 551 Visited, 552 Results)); 553 } 554 } 555 556 // FIXME: Look into base classes in Objective-C! 557 558 Results.ExitScope(); 559 return NextRank; 560} 561 562/// \brief Determines whether the given declaration is suitable as the 563/// start of a C++ nested-name-specifier, e.g., a class or namespace. 564bool CodeCompleteConsumer::IsNestedNameSpecifier(NamedDecl *ND) const { 565 // Allow us to find class templates, too. 566 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) 567 ND = ClassTemplate->getTemplatedDecl(); 568 569 return getSema().isAcceptableNestedNameSpecifier(ND); 570} 571 572/// \brief Determines whether the given declaration is an enumeration. 573bool CodeCompleteConsumer::IsEnum(NamedDecl *ND) const { 574 return isa<EnumDecl>(ND); 575} 576 577/// \brief Determines whether the given declaration is a class or struct. 578bool CodeCompleteConsumer::IsClassOrStruct(NamedDecl *ND) const { 579 // Allow us to find class templates, too. 580 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) 581 ND = ClassTemplate->getTemplatedDecl(); 582 583 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND)) 584 return RD->getTagKind() == TagDecl::TK_class || 585 RD->getTagKind() == TagDecl::TK_struct; 586 587 return false; 588} 589 590/// \brief Determines whether the given declaration is a union. 591bool CodeCompleteConsumer::IsUnion(NamedDecl *ND) const { 592 // Allow us to find class templates, too. 593 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) 594 ND = ClassTemplate->getTemplatedDecl(); 595 596 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND)) 597 return RD->getTagKind() == TagDecl::TK_union; 598 599 return false; 600} 601 602/// \brief Determines whether the given declaration is a namespace. 603bool CodeCompleteConsumer::IsNamespace(NamedDecl *ND) const { 604 return isa<NamespaceDecl>(ND); 605} 606 607/// \brief Determines whether the given declaration is a namespace or 608/// namespace alias. 609bool CodeCompleteConsumer::IsNamespaceOrAlias(NamedDecl *ND) const { 610 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND); 611} 612 613/// \brief Brief determines whether the given declaration is a namespace or 614/// namespace alias. 615bool CodeCompleteConsumer::IsType(NamedDecl *ND) const { 616 return isa<TypeDecl>(ND); 617} 618 619namespace { 620 struct VISIBILITY_HIDDEN SortCodeCompleteResult { 621 typedef CodeCompleteConsumer::Result Result; 622 623 bool operator()(const Result &X, const Result &Y) const { 624 // Sort first by rank. 625 if (X.Rank < Y.Rank) 626 return true; 627 else if (X.Rank > Y.Rank) 628 return false; 629 630 // Result kinds are ordered by decreasing importance. 631 if (X.Kind < Y.Kind) 632 return true; 633 else if (X.Kind > Y.Kind) 634 return false; 635 636 // Non-hidden names precede hidden names. 637 if (X.Hidden != Y.Hidden) 638 return !X.Hidden; 639 640 // Ordering depends on the kind of result. 641 switch (X.Kind) { 642 case Result::RK_Declaration: 643 // Order based on the declaration names. 644 return X.Declaration->getDeclName() < Y.Declaration->getDeclName(); 645 646 case Result::RK_Keyword: 647 return strcmp(X.Keyword, Y.Keyword) == -1; 648 } 649 650 // If only our C++ compiler did control-flow warnings properly. 651 return false; 652 } 653 }; 654} 655 656/// \brief Determines whether the given hidden result could be found with 657/// some extra work, e.g., by qualifying the name. 658/// 659/// \param Hidden the declaration that is hidden by the currenly \p Visible 660/// declaration. 661/// 662/// \param Visible the declaration with the same name that is already visible. 663/// 664/// \returns true if the hidden result can be found by some mechanism, 665/// false otherwise. 666bool CodeCompleteConsumer::canHiddenResultBeFound(NamedDecl *Hidden, 667 NamedDecl *Visible) { 668 // In C, there is no way to refer to a hidden name. 669 if (!getSema().getLangOptions().CPlusPlus) 670 return false; 671 672 DeclContext *HiddenCtx = Hidden->getDeclContext()->getLookupContext(); 673 674 // There is no way to qualify a name declared in a function or method. 675 if (HiddenCtx->isFunctionOrMethod()) 676 return false; 677 678 // If the hidden and visible declarations are in different name-lookup 679 // contexts, then we can qualify the name of the hidden declaration. 680 // FIXME: Optionally compute the string needed to refer to the hidden 681 // name. 682 return HiddenCtx != Visible->getDeclContext()->getLookupContext(); 683} 684 685/// \brief Add type specifiers for the current language as keyword results. 686void CodeCompleteConsumer::AddTypeSpecifierResults(unsigned Rank, 687 ResultSet &Results) { 688 Results.MaybeAddResult(Result("short", Rank)); 689 Results.MaybeAddResult(Result("long", Rank)); 690 Results.MaybeAddResult(Result("signed", Rank)); 691 Results.MaybeAddResult(Result("unsigned", Rank)); 692 Results.MaybeAddResult(Result("void", Rank)); 693 Results.MaybeAddResult(Result("char", Rank)); 694 Results.MaybeAddResult(Result("int", Rank)); 695 Results.MaybeAddResult(Result("float", Rank)); 696 Results.MaybeAddResult(Result("double", Rank)); 697 Results.MaybeAddResult(Result("enum", Rank)); 698 Results.MaybeAddResult(Result("struct", Rank)); 699 Results.MaybeAddResult(Result("union", Rank)); 700 701 if (getSema().getLangOptions().C99) { 702 // C99-specific 703 Results.MaybeAddResult(Result("_Complex", Rank)); 704 Results.MaybeAddResult(Result("_Imaginary", Rank)); 705 Results.MaybeAddResult(Result("_Bool", Rank)); 706 } 707 708 if (getSema().getLangOptions().CPlusPlus) { 709 // C++-specific 710 Results.MaybeAddResult(Result("bool", Rank)); 711 Results.MaybeAddResult(Result("class", Rank)); 712 Results.MaybeAddResult(Result("typename", Rank)); 713 Results.MaybeAddResult(Result("wchar_t", Rank)); 714 715 if (getSema().getLangOptions().CPlusPlus0x) { 716 Results.MaybeAddResult(Result("char16_t", Rank)); 717 Results.MaybeAddResult(Result("char32_t", Rank)); 718 Results.MaybeAddResult(Result("decltype", Rank)); 719 } 720 } 721 722 // GNU extensions 723 if (getSema().getLangOptions().GNUMode) { 724 // FIXME: Enable when we actually support decimal floating point. 725 // Results.MaybeAddResult(Result("_Decimal32", Rank)); 726 // Results.MaybeAddResult(Result("_Decimal64", Rank)); 727 // Results.MaybeAddResult(Result("_Decimal128", Rank)); 728 Results.MaybeAddResult(Result("typeof", Rank)); 729 } 730} 731 732/// \brief Add function parameter chunks to the given code completion string. 733static void AddFunctionParameterChunks(ASTContext &Context, 734 FunctionDecl *Function, 735 CodeCompletionString *Result) { 736 CodeCompletionString *CCStr = Result; 737 738 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) { 739 ParmVarDecl *Param = Function->getParamDecl(P); 740 741 if (Param->hasDefaultArg()) { 742 // When we see an optional default argument, put that argument and 743 // the remaining default arguments into a new, optional string. 744 CodeCompletionString *Opt = new CodeCompletionString; 745 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt)); 746 CCStr = Opt; 747 } 748 749 if (P != 0) 750 CCStr->AddTextChunk(", "); 751 752 // Format the placeholder string. 753 std::string PlaceholderStr; 754 if (Param->getIdentifier()) 755 PlaceholderStr = Param->getIdentifier()->getName(); 756 757 Param->getType().getAsStringInternal(PlaceholderStr, 758 Context.PrintingPolicy); 759 760 // Add the placeholder string. 761 CCStr->AddPlaceholderChunk(PlaceholderStr.c_str()); 762 } 763} 764 765/// \brief If possible, create a new code completion string for the given 766/// result. 767/// 768/// \returns Either a new, heap-allocated code completion string describing 769/// how to use this result, or NULL to indicate that the string or name of the 770/// result is all that is needed. 771CodeCompletionString * 772CodeCompleteConsumer::CreateCodeCompletionString(Result R) { 773 if (R.Kind != Result::RK_Declaration) 774 return 0; 775 776 NamedDecl *ND = R.Declaration; 777 778 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) { 779 CodeCompletionString *Result = new CodeCompletionString; 780 Result->AddTextChunk(Function->getNameAsString().c_str()); 781 Result->AddTextChunk("("); 782 AddFunctionParameterChunks(getSema().Context, Function, Result); 783 Result->AddTextChunk(")"); 784 return Result; 785 } 786 787 return 0; 788} 789 790void 791PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Result *Results, 792 unsigned NumResults) { 793 // Sort the results by rank/kind/etc. 794 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult()); 795 796 // Print the results. 797 for (unsigned I = 0; I != NumResults; ++I) { 798 switch (Results[I].Kind) { 799 case Result::RK_Declaration: 800 OS << Results[I].Declaration->getNameAsString() << " : " 801 << Results[I].Rank; 802 if (Results[I].Hidden) 803 OS << " (Hidden)"; 804 if (CodeCompletionString *CCS = CreateCodeCompletionString(Results[I])) { 805 OS << " : " << CCS->getAsString(); 806 delete CCS; 807 } 808 809 OS << '\n'; 810 break; 811 812 case Result::RK_Keyword: 813 OS << Results[I].Keyword << " : " << Results[I].Rank << '\n'; 814 break; 815 } 816 } 817 818 // Once we've printed the code-completion results, suppress remaining 819 // diagnostics. 820 // FIXME: Move this somewhere else! 821 getSema().PP.getDiagnostics().setSuppressAllDiagnostics(); 822} 823