1 //===---------------- SemaCodeComplete.cpp - Code Completion ----*- 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 defines the code-completion semantic actions. 11 // 12 //===----------------------------------------------------------------------===// 13 #include "clang/Sema/SemaInternal.h" 14 #include "clang/Sema/Lookup.h" 15 #include "clang/Sema/Overload.h" 16 #include "clang/Sema/CodeCompleteConsumer.h" 17 #include "clang/Sema/ExternalSemaSource.h" 18 #include "clang/Sema/Scope.h" 19 #include "clang/Sema/ScopeInfo.h" 20 #include "clang/AST/DeclObjC.h" 21 #include "clang/AST/ExprCXX.h" 22 #include "clang/AST/ExprObjC.h" 23 #include "clang/Lex/MacroInfo.h" 24 #include "clang/Lex/Preprocessor.h" 25 #include "llvm/ADT/DenseSet.h" 26 #include "llvm/ADT/SmallPtrSet.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/ADT/StringSwitch.h" 29 #include "llvm/ADT/Twine.h" 30 #include <list> 31 #include <map> 32 #include <vector> 33 34 using namespace clang; 35 using namespace sema; 36 37 namespace { 38 /// \brief A container of code-completion results. 39 class ResultBuilder { 40 public: 41 /// \brief The type of a name-lookup filter, which can be provided to the 42 /// name-lookup routines to specify which declarations should be included in 43 /// the result set (when it returns true) and which declarations should be 44 /// filtered out (returns false). 45 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const; 46 47 typedef CodeCompletionResult Result; 48 49 private: 50 /// \brief The actual results we have found. 51 std::vector<Result> Results; 52 53 /// \brief A record of all of the declarations we have found and placed 54 /// into the result set, used to ensure that no declaration ever gets into 55 /// the result set twice. 56 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound; 57 58 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair; 59 60 /// \brief An entry in the shadow map, which is optimized to store 61 /// a single (declaration, index) mapping (the common case) but 62 /// can also store a list of (declaration, index) mappings. 63 class ShadowMapEntry { 64 typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector; 65 66 /// \brief Contains either the solitary NamedDecl * or a vector 67 /// of (declaration, index) pairs. 68 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector; 69 70 /// \brief When the entry contains a single declaration, this is 71 /// the index associated with that entry. 72 unsigned SingleDeclIndex; 73 74 public: 75 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { } 76 77 void Add(NamedDecl *ND, unsigned Index) { 78 if (DeclOrVector.isNull()) { 79 // 0 - > 1 elements: just set the single element information. 80 DeclOrVector = ND; 81 SingleDeclIndex = Index; 82 return; 83 } 84 85 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) { 86 // 1 -> 2 elements: create the vector of results and push in the 87 // existing declaration. 88 DeclIndexPairVector *Vec = new DeclIndexPairVector; 89 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex)); 90 DeclOrVector = Vec; 91 } 92 93 // Add the new element to the end of the vector. 94 DeclOrVector.get<DeclIndexPairVector*>()->push_back( 95 DeclIndexPair(ND, Index)); 96 } 97 98 void Destroy() { 99 if (DeclIndexPairVector *Vec 100 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) { 101 delete Vec; 102 DeclOrVector = ((NamedDecl *)0); 103 } 104 } 105 106 // Iteration. 107 class iterator; 108 iterator begin() const; 109 iterator end() const; 110 }; 111 112 /// \brief A mapping from declaration names to the declarations that have 113 /// this name within a particular scope and their index within the list of 114 /// results. 115 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap; 116 117 /// \brief The semantic analysis object for which results are being 118 /// produced. 119 Sema &SemaRef; 120 121 /// \brief The allocator used to allocate new code-completion strings. 122 CodeCompletionAllocator &Allocator; 123 124 /// \brief If non-NULL, a filter function used to remove any code-completion 125 /// results that are not desirable. 126 LookupFilter Filter; 127 128 /// \brief Whether we should allow declarations as 129 /// nested-name-specifiers that would otherwise be filtered out. 130 bool AllowNestedNameSpecifiers; 131 132 /// \brief If set, the type that we would prefer our resulting value 133 /// declarations to have. 134 /// 135 /// Closely matching the preferred type gives a boost to a result's 136 /// priority. 137 CanQualType PreferredType; 138 139 /// \brief A list of shadow maps, which is used to model name hiding at 140 /// different levels of, e.g., the inheritance hierarchy. 141 std::list<ShadowMap> ShadowMaps; 142 143 /// \brief If we're potentially referring to a C++ member function, the set 144 /// of qualifiers applied to the object type. 145 Qualifiers ObjectTypeQualifiers; 146 147 /// \brief Whether the \p ObjectTypeQualifiers field is active. 148 bool HasObjectTypeQualifiers; 149 150 /// \brief The selector that we prefer. 151 Selector PreferredSelector; 152 153 /// \brief The completion context in which we are gathering results. 154 CodeCompletionContext CompletionContext; 155 156 /// \brief If we are in an instance method definition, the @implementation 157 /// object. 158 ObjCImplementationDecl *ObjCImplementation; 159 160 void AdjustResultPriorityForDecl(Result &R); 161 162 void MaybeAddConstructorResults(Result R); 163 164 public: 165 explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator, 166 const CodeCompletionContext &CompletionContext, 167 LookupFilter Filter = 0) 168 : SemaRef(SemaRef), Allocator(Allocator), Filter(Filter), 169 AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false), 170 CompletionContext(CompletionContext), 171 ObjCImplementation(0) 172 { 173 // If this is an Objective-C instance method definition, dig out the 174 // corresponding implementation. 175 switch (CompletionContext.getKind()) { 176 case CodeCompletionContext::CCC_Expression: 177 case CodeCompletionContext::CCC_ObjCMessageReceiver: 178 case CodeCompletionContext::CCC_ParenthesizedExpression: 179 case CodeCompletionContext::CCC_Statement: 180 case CodeCompletionContext::CCC_Recovery: 181 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) 182 if (Method->isInstanceMethod()) 183 if (ObjCInterfaceDecl *Interface = Method->getClassInterface()) 184 ObjCImplementation = Interface->getImplementation(); 185 break; 186 187 default: 188 break; 189 } 190 } 191 192 /// \brief Whether we should include code patterns in the completion 193 /// results. 194 bool includeCodePatterns() const { 195 return SemaRef.CodeCompleter && 196 SemaRef.CodeCompleter->includeCodePatterns(); 197 } 198 199 /// \brief Set the filter used for code-completion results. 200 void setFilter(LookupFilter Filter) { 201 this->Filter = Filter; 202 } 203 204 Result *data() { return Results.empty()? 0 : &Results.front(); } 205 unsigned size() const { return Results.size(); } 206 bool empty() const { return Results.empty(); } 207 208 /// \brief Specify the preferred type. 209 void setPreferredType(QualType T) { 210 PreferredType = SemaRef.Context.getCanonicalType(T); 211 } 212 213 /// \brief Set the cv-qualifiers on the object type, for us in filtering 214 /// calls to member functions. 215 /// 216 /// When there are qualifiers in this set, they will be used to filter 217 /// out member functions that aren't available (because there will be a 218 /// cv-qualifier mismatch) or prefer functions with an exact qualifier 219 /// match. 220 void setObjectTypeQualifiers(Qualifiers Quals) { 221 ObjectTypeQualifiers = Quals; 222 HasObjectTypeQualifiers = true; 223 } 224 225 /// \brief Set the preferred selector. 226 /// 227 /// When an Objective-C method declaration result is added, and that 228 /// method's selector matches this preferred selector, we give that method 229 /// a slight priority boost. 230 void setPreferredSelector(Selector Sel) { 231 PreferredSelector = Sel; 232 } 233 234 /// \brief Retrieve the code-completion context for which results are 235 /// being collected. 236 const CodeCompletionContext &getCompletionContext() const { 237 return CompletionContext; 238 } 239 240 /// \brief Specify whether nested-name-specifiers are allowed. 241 void allowNestedNameSpecifiers(bool Allow = true) { 242 AllowNestedNameSpecifiers = Allow; 243 } 244 245 /// \brief Return the semantic analysis object for which we are collecting 246 /// code completion results. 247 Sema &getSema() const { return SemaRef; } 248 249 /// \brief Retrieve the allocator used to allocate code completion strings. 250 CodeCompletionAllocator &getAllocator() const { return Allocator; } 251 252 /// \brief Determine whether the given declaration is at all interesting 253 /// as a code-completion result. 254 /// 255 /// \param ND the declaration that we are inspecting. 256 /// 257 /// \param AsNestedNameSpecifier will be set true if this declaration is 258 /// only interesting when it is a nested-name-specifier. 259 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const; 260 261 /// \brief Check whether the result is hidden by the Hiding declaration. 262 /// 263 /// \returns true if the result is hidden and cannot be found, false if 264 /// the hidden result could still be found. When false, \p R may be 265 /// modified to describe how the result can be found (e.g., via extra 266 /// qualification). 267 bool CheckHiddenResult(Result &R, DeclContext *CurContext, 268 NamedDecl *Hiding); 269 270 /// \brief Add a new result to this result set (if it isn't already in one 271 /// of the shadow maps), or replace an existing result (for, e.g., a 272 /// redeclaration). 273 /// 274 /// \param CurContext the result to add (if it is unique). 275 /// 276 /// \param R the context in which this result will be named. 277 void MaybeAddResult(Result R, DeclContext *CurContext = 0); 278 279 /// \brief Add a new result to this result set, where we already know 280 /// the hiding declation (if any). 281 /// 282 /// \param R the result to add (if it is unique). 283 /// 284 /// \param CurContext the context in which this result will be named. 285 /// 286 /// \param Hiding the declaration that hides the result. 287 /// 288 /// \param InBaseClass whether the result was found in a base 289 /// class of the searched context. 290 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding, 291 bool InBaseClass); 292 293 /// \brief Add a new non-declaration result to this result set. 294 void AddResult(Result R); 295 296 /// \brief Enter into a new scope. 297 void EnterNewScope(); 298 299 /// \brief Exit from the current scope. 300 void ExitScope(); 301 302 /// \brief Ignore this declaration, if it is seen again. 303 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); } 304 305 /// \name Name lookup predicates 306 /// 307 /// These predicates can be passed to the name lookup functions to filter the 308 /// results of name lookup. All of the predicates have the same type, so that 309 /// 310 //@{ 311 bool IsOrdinaryName(NamedDecl *ND) const; 312 bool IsOrdinaryNonTypeName(NamedDecl *ND) const; 313 bool IsIntegralConstantValue(NamedDecl *ND) const; 314 bool IsOrdinaryNonValueName(NamedDecl *ND) const; 315 bool IsNestedNameSpecifier(NamedDecl *ND) const; 316 bool IsEnum(NamedDecl *ND) const; 317 bool IsClassOrStruct(NamedDecl *ND) const; 318 bool IsUnion(NamedDecl *ND) const; 319 bool IsNamespace(NamedDecl *ND) const; 320 bool IsNamespaceOrAlias(NamedDecl *ND) const; 321 bool IsType(NamedDecl *ND) const; 322 bool IsMember(NamedDecl *ND) const; 323 bool IsObjCIvar(NamedDecl *ND) const; 324 bool IsObjCMessageReceiver(NamedDecl *ND) const; 325 bool IsObjCCollection(NamedDecl *ND) const; 326 bool IsImpossibleToSatisfy(NamedDecl *ND) const; 327 //@} 328 }; 329 } 330 331 class ResultBuilder::ShadowMapEntry::iterator { 332 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator; 333 unsigned SingleDeclIndex; 334 335 public: 336 typedef DeclIndexPair value_type; 337 typedef value_type reference; 338 typedef std::ptrdiff_t difference_type; 339 typedef std::input_iterator_tag iterator_category; 340 341 class pointer { 342 DeclIndexPair Value; 343 344 public: 345 pointer(const DeclIndexPair &Value) : Value(Value) { } 346 347 const DeclIndexPair *operator->() const { 348 return &Value; 349 } 350 }; 351 352 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { } 353 354 iterator(NamedDecl *SingleDecl, unsigned Index) 355 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { } 356 357 iterator(const DeclIndexPair *Iterator) 358 : DeclOrIterator(Iterator), SingleDeclIndex(0) { } 359 360 iterator &operator++() { 361 if (DeclOrIterator.is<NamedDecl *>()) { 362 DeclOrIterator = (NamedDecl *)0; 363 SingleDeclIndex = 0; 364 return *this; 365 } 366 367 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>(); 368 ++I; 369 DeclOrIterator = I; 370 return *this; 371 } 372 373 /*iterator operator++(int) { 374 iterator tmp(*this); 375 ++(*this); 376 return tmp; 377 }*/ 378 379 reference operator*() const { 380 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>()) 381 return reference(ND, SingleDeclIndex); 382 383 return *DeclOrIterator.get<const DeclIndexPair*>(); 384 } 385 386 pointer operator->() const { 387 return pointer(**this); 388 } 389 390 friend bool operator==(const iterator &X, const iterator &Y) { 391 return X.DeclOrIterator.getOpaqueValue() 392 == Y.DeclOrIterator.getOpaqueValue() && 393 X.SingleDeclIndex == Y.SingleDeclIndex; 394 } 395 396 friend bool operator!=(const iterator &X, const iterator &Y) { 397 return !(X == Y); 398 } 399 }; 400 401 ResultBuilder::ShadowMapEntry::iterator 402 ResultBuilder::ShadowMapEntry::begin() const { 403 if (DeclOrVector.isNull()) 404 return iterator(); 405 406 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>()) 407 return iterator(ND, SingleDeclIndex); 408 409 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin()); 410 } 411 412 ResultBuilder::ShadowMapEntry::iterator 413 ResultBuilder::ShadowMapEntry::end() const { 414 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull()) 415 return iterator(); 416 417 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end()); 418 } 419 420 /// \brief Compute the qualification required to get from the current context 421 /// (\p CurContext) to the target context (\p TargetContext). 422 /// 423 /// \param Context the AST context in which the qualification will be used. 424 /// 425 /// \param CurContext the context where an entity is being named, which is 426 /// typically based on the current scope. 427 /// 428 /// \param TargetContext the context in which the named entity actually 429 /// resides. 430 /// 431 /// \returns a nested name specifier that refers into the target context, or 432 /// NULL if no qualification is needed. 433 static NestedNameSpecifier * 434 getRequiredQualification(ASTContext &Context, 435 DeclContext *CurContext, 436 DeclContext *TargetContext) { 437 SmallVector<DeclContext *, 4> TargetParents; 438 439 for (DeclContext *CommonAncestor = TargetContext; 440 CommonAncestor && !CommonAncestor->Encloses(CurContext); 441 CommonAncestor = CommonAncestor->getLookupParent()) { 442 if (CommonAncestor->isTransparentContext() || 443 CommonAncestor->isFunctionOrMethod()) 444 continue; 445 446 TargetParents.push_back(CommonAncestor); 447 } 448 449 NestedNameSpecifier *Result = 0; 450 while (!TargetParents.empty()) { 451 DeclContext *Parent = TargetParents.back(); 452 TargetParents.pop_back(); 453 454 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) { 455 if (!Namespace->getIdentifier()) 456 continue; 457 458 Result = NestedNameSpecifier::Create(Context, Result, Namespace); 459 } 460 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent)) 461 Result = NestedNameSpecifier::Create(Context, Result, 462 false, 463 Context.getTypeDeclType(TD).getTypePtr()); 464 } 465 return Result; 466 } 467 468 bool ResultBuilder::isInterestingDecl(NamedDecl *ND, 469 bool &AsNestedNameSpecifier) const { 470 AsNestedNameSpecifier = false; 471 472 ND = ND->getUnderlyingDecl(); 473 unsigned IDNS = ND->getIdentifierNamespace(); 474 475 // Skip unnamed entities. 476 if (!ND->getDeclName()) 477 return false; 478 479 // Friend declarations and declarations introduced due to friends are never 480 // added as results. 481 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)) 482 return false; 483 484 // Class template (partial) specializations are never added as results. 485 if (isa<ClassTemplateSpecializationDecl>(ND) || 486 isa<ClassTemplatePartialSpecializationDecl>(ND)) 487 return false; 488 489 // Using declarations themselves are never added as results. 490 if (isa<UsingDecl>(ND)) 491 return false; 492 493 // Some declarations have reserved names that we don't want to ever show. 494 if (const IdentifierInfo *Id = ND->getIdentifier()) { 495 // __va_list_tag is a freak of nature. Find it and skip it. 496 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list")) 497 return false; 498 499 // Filter out names reserved for the implementation (C99 7.1.3, 500 // C++ [lib.global.names]) if they come from a system header. 501 // 502 // FIXME: Add predicate for this. 503 if (Id->getLength() >= 2) { 504 const char *Name = Id->getNameStart(); 505 if (Name[0] == '_' && 506 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) && 507 (ND->getLocation().isInvalid() || 508 SemaRef.SourceMgr.isInSystemHeader( 509 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation())))) 510 return false; 511 } 512 } 513 514 // Skip out-of-line declarations and definitions. 515 // NOTE: Unless it's an Objective-C property, method, or ivar, where 516 // the contexts can be messy. 517 if (!ND->getDeclContext()->Equals(ND->getLexicalDeclContext()) && 518 !(isa<ObjCPropertyDecl>(ND) || isa<ObjCIvarDecl>(ND) || 519 isa<ObjCMethodDecl>(ND))) 520 return false; 521 522 if (Filter == &ResultBuilder::IsNestedNameSpecifier || 523 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) && 524 Filter != &ResultBuilder::IsNamespace && 525 Filter != &ResultBuilder::IsNamespaceOrAlias && 526 Filter != 0)) 527 AsNestedNameSpecifier = true; 528 529 // Filter out any unwanted results. 530 if (Filter && !(this->*Filter)(ND)) { 531 // Check whether it is interesting as a nested-name-specifier. 532 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus && 533 IsNestedNameSpecifier(ND) && 534 (Filter != &ResultBuilder::IsMember || 535 (isa<CXXRecordDecl>(ND) && 536 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) { 537 AsNestedNameSpecifier = true; 538 return true; 539 } 540 541 return false; 542 } 543 // ... then it must be interesting! 544 return true; 545 } 546 547 bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext, 548 NamedDecl *Hiding) { 549 // In C, there is no way to refer to a hidden name. 550 // FIXME: This isn't true; we can find a tag name hidden by an ordinary 551 // name if we introduce the tag type. 552 if (!SemaRef.getLangOptions().CPlusPlus) 553 return true; 554 555 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext(); 556 557 // There is no way to qualify a name declared in a function or method. 558 if (HiddenCtx->isFunctionOrMethod()) 559 return true; 560 561 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext()) 562 return true; 563 564 // We can refer to the result with the appropriate qualification. Do it. 565 R.Hidden = true; 566 R.QualifierIsInformative = false; 567 568 if (!R.Qualifier) 569 R.Qualifier = getRequiredQualification(SemaRef.Context, 570 CurContext, 571 R.Declaration->getDeclContext()); 572 return false; 573 } 574 575 /// \brief A simplified classification of types used to determine whether two 576 /// types are "similar enough" when adjusting priorities. 577 SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) { 578 switch (T->getTypeClass()) { 579 case Type::Builtin: 580 switch (cast<BuiltinType>(T)->getKind()) { 581 case BuiltinType::Void: 582 return STC_Void; 583 584 case BuiltinType::NullPtr: 585 return STC_Pointer; 586 587 case BuiltinType::Overload: 588 case BuiltinType::Dependent: 589 return STC_Other; 590 591 case BuiltinType::ObjCId: 592 case BuiltinType::ObjCClass: 593 case BuiltinType::ObjCSel: 594 return STC_ObjectiveC; 595 596 default: 597 return STC_Arithmetic; 598 } 599 return STC_Other; 600 601 case Type::Complex: 602 return STC_Arithmetic; 603 604 case Type::Pointer: 605 return STC_Pointer; 606 607 case Type::BlockPointer: 608 return STC_Block; 609 610 case Type::LValueReference: 611 case Type::RValueReference: 612 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType()); 613 614 case Type::ConstantArray: 615 case Type::IncompleteArray: 616 case Type::VariableArray: 617 case Type::DependentSizedArray: 618 return STC_Array; 619 620 case Type::DependentSizedExtVector: 621 case Type::Vector: 622 case Type::ExtVector: 623 return STC_Arithmetic; 624 625 case Type::FunctionProto: 626 case Type::FunctionNoProto: 627 return STC_Function; 628 629 case Type::Record: 630 return STC_Record; 631 632 case Type::Enum: 633 return STC_Arithmetic; 634 635 case Type::ObjCObject: 636 case Type::ObjCInterface: 637 case Type::ObjCObjectPointer: 638 return STC_ObjectiveC; 639 640 default: 641 return STC_Other; 642 } 643 } 644 645 /// \brief Get the type that a given expression will have if this declaration 646 /// is used as an expression in its "typical" code-completion form. 647 QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) { 648 ND = cast<NamedDecl>(ND->getUnderlyingDecl()); 649 650 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND)) 651 return C.getTypeDeclType(Type); 652 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND)) 653 return C.getObjCInterfaceType(Iface); 654 655 QualType T; 656 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) 657 T = Function->getCallResultType(); 658 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) 659 T = Method->getSendResultType(); 660 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) 661 T = FunTmpl->getTemplatedDecl()->getCallResultType(); 662 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) 663 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext())); 664 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) 665 T = Property->getType(); 666 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND)) 667 T = Value->getType(); 668 else 669 return QualType(); 670 671 // Dig through references, function pointers, and block pointers to 672 // get down to the likely type of an expression when the entity is 673 // used. 674 do { 675 if (const ReferenceType *Ref = T->getAs<ReferenceType>()) { 676 T = Ref->getPointeeType(); 677 continue; 678 } 679 680 if (const PointerType *Pointer = T->getAs<PointerType>()) { 681 if (Pointer->getPointeeType()->isFunctionType()) { 682 T = Pointer->getPointeeType(); 683 continue; 684 } 685 686 break; 687 } 688 689 if (const BlockPointerType *Block = T->getAs<BlockPointerType>()) { 690 T = Block->getPointeeType(); 691 continue; 692 } 693 694 if (const FunctionType *Function = T->getAs<FunctionType>()) { 695 T = Function->getResultType(); 696 continue; 697 } 698 699 break; 700 } while (true); 701 702 return T; 703 } 704 705 void ResultBuilder::AdjustResultPriorityForDecl(Result &R) { 706 // If this is an Objective-C method declaration whose selector matches our 707 // preferred selector, give it a priority boost. 708 if (!PreferredSelector.isNull()) 709 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration)) 710 if (PreferredSelector == Method->getSelector()) 711 R.Priority += CCD_SelectorMatch; 712 713 // If we have a preferred type, adjust the priority for results with exactly- 714 // matching or nearly-matching types. 715 if (!PreferredType.isNull()) { 716 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration); 717 if (!T.isNull()) { 718 CanQualType TC = SemaRef.Context.getCanonicalType(T); 719 // Check for exactly-matching types (modulo qualifiers). 720 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) 721 R.Priority /= CCF_ExactTypeMatch; 722 // Check for nearly-matching types, based on classification of each. 723 else if ((getSimplifiedTypeClass(PreferredType) 724 == getSimplifiedTypeClass(TC)) && 725 !(PreferredType->isEnumeralType() && TC->isEnumeralType())) 726 R.Priority /= CCF_SimilarTypeMatch; 727 } 728 } 729 } 730 731 void ResultBuilder::MaybeAddConstructorResults(Result R) { 732 if (!SemaRef.getLangOptions().CPlusPlus || !R.Declaration || 733 !CompletionContext.wantConstructorResults()) 734 return; 735 736 ASTContext &Context = SemaRef.Context; 737 NamedDecl *D = R.Declaration; 738 CXXRecordDecl *Record = 0; 739 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) 740 Record = ClassTemplate->getTemplatedDecl(); 741 else if ((Record = dyn_cast<CXXRecordDecl>(D))) { 742 // Skip specializations and partial specializations. 743 if (isa<ClassTemplateSpecializationDecl>(Record)) 744 return; 745 } else { 746 // There are no constructors here. 747 return; 748 } 749 750 Record = Record->getDefinition(); 751 if (!Record) 752 return; 753 754 755 QualType RecordTy = Context.getTypeDeclType(Record); 756 DeclarationName ConstructorName 757 = Context.DeclarationNames.getCXXConstructorName( 758 Context.getCanonicalType(RecordTy)); 759 for (DeclContext::lookup_result Ctors = Record->lookup(ConstructorName); 760 Ctors.first != Ctors.second; ++Ctors.first) { 761 R.Declaration = *Ctors.first; 762 R.CursorKind = getCursorKindForDecl(R.Declaration); 763 Results.push_back(R); 764 } 765 } 766 767 void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) { 768 assert(!ShadowMaps.empty() && "Must enter into a results scope"); 769 770 if (R.Kind != Result::RK_Declaration) { 771 // For non-declaration results, just add the result. 772 Results.push_back(R); 773 return; 774 } 775 776 // Look through using declarations. 777 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) { 778 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext); 779 return; 780 } 781 782 Decl *CanonDecl = R.Declaration->getCanonicalDecl(); 783 unsigned IDNS = CanonDecl->getIdentifierNamespace(); 784 785 bool AsNestedNameSpecifier = false; 786 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier)) 787 return; 788 789 // C++ constructors are never found by name lookup. 790 if (isa<CXXConstructorDecl>(R.Declaration)) 791 return; 792 793 ShadowMap &SMap = ShadowMaps.back(); 794 ShadowMapEntry::iterator I, IEnd; 795 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName()); 796 if (NamePos != SMap.end()) { 797 I = NamePos->second.begin(); 798 IEnd = NamePos->second.end(); 799 } 800 801 for (; I != IEnd; ++I) { 802 NamedDecl *ND = I->first; 803 unsigned Index = I->second; 804 if (ND->getCanonicalDecl() == CanonDecl) { 805 // This is a redeclaration. Always pick the newer declaration. 806 Results[Index].Declaration = R.Declaration; 807 808 // We're done. 809 return; 810 } 811 } 812 813 // This is a new declaration in this scope. However, check whether this 814 // declaration name is hidden by a similarly-named declaration in an outer 815 // scope. 816 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end(); 817 --SMEnd; 818 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) { 819 ShadowMapEntry::iterator I, IEnd; 820 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName()); 821 if (NamePos != SM->end()) { 822 I = NamePos->second.begin(); 823 IEnd = NamePos->second.end(); 824 } 825 for (; I != IEnd; ++I) { 826 // A tag declaration does not hide a non-tag declaration. 827 if (I->first->hasTagIdentifierNamespace() && 828 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary | 829 Decl::IDNS_ObjCProtocol))) 830 continue; 831 832 // Protocols are in distinct namespaces from everything else. 833 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol) 834 || (IDNS & Decl::IDNS_ObjCProtocol)) && 835 I->first->getIdentifierNamespace() != IDNS) 836 continue; 837 838 // The newly-added result is hidden by an entry in the shadow map. 839 if (CheckHiddenResult(R, CurContext, I->first)) 840 return; 841 842 break; 843 } 844 } 845 846 // Make sure that any given declaration only shows up in the result set once. 847 if (!AllDeclsFound.insert(CanonDecl)) 848 return; 849 850 // If the filter is for nested-name-specifiers, then this result starts a 851 // nested-name-specifier. 852 if (AsNestedNameSpecifier) { 853 R.StartsNestedNameSpecifier = true; 854 R.Priority = CCP_NestedNameSpecifier; 855 } else 856 AdjustResultPriorityForDecl(R); 857 858 // If this result is supposed to have an informative qualifier, add one. 859 if (R.QualifierIsInformative && !R.Qualifier && 860 !R.StartsNestedNameSpecifier) { 861 DeclContext *Ctx = R.Declaration->getDeclContext(); 862 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx)) 863 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace); 864 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx)) 865 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false, 866 SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); 867 else 868 R.QualifierIsInformative = false; 869 } 870 871 // Insert this result into the set of results and into the current shadow 872 // map. 873 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size()); 874 Results.push_back(R); 875 876 if (!AsNestedNameSpecifier) 877 MaybeAddConstructorResults(R); 878 } 879 880 void ResultBuilder::AddResult(Result R, DeclContext *CurContext, 881 NamedDecl *Hiding, bool InBaseClass = false) { 882 if (R.Kind != Result::RK_Declaration) { 883 // For non-declaration results, just add the result. 884 Results.push_back(R); 885 return; 886 } 887 888 // Look through using declarations. 889 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) { 890 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding); 891 return; 892 } 893 894 bool AsNestedNameSpecifier = false; 895 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier)) 896 return; 897 898 // C++ constructors are never found by name lookup. 899 if (isa<CXXConstructorDecl>(R.Declaration)) 900 return; 901 902 if (Hiding && CheckHiddenResult(R, CurContext, Hiding)) 903 return; 904 905 // Make sure that any given declaration only shows up in the result set once. 906 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl())) 907 return; 908 909 // If the filter is for nested-name-specifiers, then this result starts a 910 // nested-name-specifier. 911 if (AsNestedNameSpecifier) { 912 R.StartsNestedNameSpecifier = true; 913 R.Priority = CCP_NestedNameSpecifier; 914 } 915 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass && 916 isa<CXXRecordDecl>(R.Declaration->getDeclContext() 917 ->getRedeclContext())) 918 R.QualifierIsInformative = true; 919 920 // If this result is supposed to have an informative qualifier, add one. 921 if (R.QualifierIsInformative && !R.Qualifier && 922 !R.StartsNestedNameSpecifier) { 923 DeclContext *Ctx = R.Declaration->getDeclContext(); 924 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx)) 925 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace); 926 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx)) 927 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false, 928 SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); 929 else 930 R.QualifierIsInformative = false; 931 } 932 933 // Adjust the priority if this result comes from a base class. 934 if (InBaseClass) 935 R.Priority += CCD_InBaseClass; 936 937 AdjustResultPriorityForDecl(R); 938 939 if (HasObjectTypeQualifiers) 940 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration)) 941 if (Method->isInstance()) { 942 Qualifiers MethodQuals 943 = Qualifiers::fromCVRMask(Method->getTypeQualifiers()); 944 if (ObjectTypeQualifiers == MethodQuals) 945 R.Priority += CCD_ObjectQualifierMatch; 946 else if (ObjectTypeQualifiers - MethodQuals) { 947 // The method cannot be invoked, because doing so would drop 948 // qualifiers. 949 return; 950 } 951 } 952 953 // Insert this result into the set of results. 954 Results.push_back(R); 955 956 if (!AsNestedNameSpecifier) 957 MaybeAddConstructorResults(R); 958 } 959 960 void ResultBuilder::AddResult(Result R) { 961 assert(R.Kind != Result::RK_Declaration && 962 "Declaration results need more context"); 963 Results.push_back(R); 964 } 965 966 /// \brief Enter into a new scope. 967 void ResultBuilder::EnterNewScope() { 968 ShadowMaps.push_back(ShadowMap()); 969 } 970 971 /// \brief Exit from the current scope. 972 void ResultBuilder::ExitScope() { 973 for (ShadowMap::iterator E = ShadowMaps.back().begin(), 974 EEnd = ShadowMaps.back().end(); 975 E != EEnd; 976 ++E) 977 E->second.Destroy(); 978 979 ShadowMaps.pop_back(); 980 } 981 982 /// \brief Determines whether this given declaration will be found by 983 /// ordinary name lookup. 984 bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const { 985 ND = cast<NamedDecl>(ND->getUnderlyingDecl()); 986 987 unsigned IDNS = Decl::IDNS_Ordinary; 988 if (SemaRef.getLangOptions().CPlusPlus) 989 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; 990 else if (SemaRef.getLangOptions().ObjC1) { 991 if (isa<ObjCIvarDecl>(ND)) 992 return true; 993 } 994 995 return ND->getIdentifierNamespace() & IDNS; 996 } 997 998 /// \brief Determines whether this given declaration will be found by 999 /// ordinary name lookup but is not a type name. 1000 bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const { 1001 ND = cast<NamedDecl>(ND->getUnderlyingDecl()); 1002 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) 1003 return false; 1004 1005 unsigned IDNS = Decl::IDNS_Ordinary; 1006 if (SemaRef.getLangOptions().CPlusPlus) 1007 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; 1008 else if (SemaRef.getLangOptions().ObjC1) { 1009 if (isa<ObjCIvarDecl>(ND)) 1010 return true; 1011 } 1012 1013 return ND->getIdentifierNamespace() & IDNS; 1014 } 1015 1016 bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const { 1017 if (!IsOrdinaryNonTypeName(ND)) 1018 return 0; 1019 1020 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl())) 1021 if (VD->getType()->isIntegralOrEnumerationType()) 1022 return true; 1023 1024 return false; 1025 } 1026 1027 /// \brief Determines whether this given declaration will be found by 1028 /// ordinary name lookup. 1029 bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const { 1030 ND = cast<NamedDecl>(ND->getUnderlyingDecl()); 1031 1032 unsigned IDNS = Decl::IDNS_Ordinary; 1033 if (SemaRef.getLangOptions().CPlusPlus) 1034 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace; 1035 1036 return (ND->getIdentifierNamespace() & IDNS) && 1037 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) && 1038 !isa<ObjCPropertyDecl>(ND); 1039 } 1040 1041 /// \brief Determines whether the given declaration is suitable as the 1042 /// start of a C++ nested-name-specifier, e.g., a class or namespace. 1043 bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const { 1044 // Allow us to find class templates, too. 1045 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) 1046 ND = ClassTemplate->getTemplatedDecl(); 1047 1048 return SemaRef.isAcceptableNestedNameSpecifier(ND); 1049 } 1050 1051 /// \brief Determines whether the given declaration is an enumeration. 1052 bool ResultBuilder::IsEnum(NamedDecl *ND) const { 1053 return isa<EnumDecl>(ND); 1054 } 1055 1056 /// \brief Determines whether the given declaration is a class or struct. 1057 bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const { 1058 // Allow us to find class templates, too. 1059 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) 1060 ND = ClassTemplate->getTemplatedDecl(); 1061 1062 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND)) 1063 return RD->getTagKind() == TTK_Class || 1064 RD->getTagKind() == TTK_Struct; 1065 1066 return false; 1067 } 1068 1069 /// \brief Determines whether the given declaration is a union. 1070 bool ResultBuilder::IsUnion(NamedDecl *ND) const { 1071 // Allow us to find class templates, too. 1072 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) 1073 ND = ClassTemplate->getTemplatedDecl(); 1074 1075 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND)) 1076 return RD->getTagKind() == TTK_Union; 1077 1078 return false; 1079 } 1080 1081 /// \brief Determines whether the given declaration is a namespace. 1082 bool ResultBuilder::IsNamespace(NamedDecl *ND) const { 1083 return isa<NamespaceDecl>(ND); 1084 } 1085 1086 /// \brief Determines whether the given declaration is a namespace or 1087 /// namespace alias. 1088 bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const { 1089 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND); 1090 } 1091 1092 /// \brief Determines whether the given declaration is a type. 1093 bool ResultBuilder::IsType(NamedDecl *ND) const { 1094 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND)) 1095 ND = Using->getTargetDecl(); 1096 1097 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND); 1098 } 1099 1100 /// \brief Determines which members of a class should be visible via 1101 /// "." or "->". Only value declarations, nested name specifiers, and 1102 /// using declarations thereof should show up. 1103 bool ResultBuilder::IsMember(NamedDecl *ND) const { 1104 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND)) 1105 ND = Using->getTargetDecl(); 1106 1107 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) || 1108 isa<ObjCPropertyDecl>(ND); 1109 } 1110 1111 static bool isObjCReceiverType(ASTContext &C, QualType T) { 1112 T = C.getCanonicalType(T); 1113 switch (T->getTypeClass()) { 1114 case Type::ObjCObject: 1115 case Type::ObjCInterface: 1116 case Type::ObjCObjectPointer: 1117 return true; 1118 1119 case Type::Builtin: 1120 switch (cast<BuiltinType>(T)->getKind()) { 1121 case BuiltinType::ObjCId: 1122 case BuiltinType::ObjCClass: 1123 case BuiltinType::ObjCSel: 1124 return true; 1125 1126 default: 1127 break; 1128 } 1129 return false; 1130 1131 default: 1132 break; 1133 } 1134 1135 if (!C.getLangOptions().CPlusPlus) 1136 return false; 1137 1138 // FIXME: We could perform more analysis here to determine whether a 1139 // particular class type has any conversions to Objective-C types. For now, 1140 // just accept all class types. 1141 return T->isDependentType() || T->isRecordType(); 1142 } 1143 1144 bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const { 1145 QualType T = getDeclUsageType(SemaRef.Context, ND); 1146 if (T.isNull()) 1147 return false; 1148 1149 T = SemaRef.Context.getBaseElementType(T); 1150 return isObjCReceiverType(SemaRef.Context, T); 1151 } 1152 1153 bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const { 1154 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) || 1155 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND))) 1156 return false; 1157 1158 QualType T = getDeclUsageType(SemaRef.Context, ND); 1159 if (T.isNull()) 1160 return false; 1161 1162 T = SemaRef.Context.getBaseElementType(T); 1163 return T->isObjCObjectType() || T->isObjCObjectPointerType() || 1164 T->isObjCIdType() || 1165 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType()); 1166 } 1167 1168 bool ResultBuilder::IsImpossibleToSatisfy(NamedDecl *ND) const { 1169 return false; 1170 } 1171 1172 /// \rief Determines whether the given declaration is an Objective-C 1173 /// instance variable. 1174 bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const { 1175 return isa<ObjCIvarDecl>(ND); 1176 } 1177 1178 namespace { 1179 /// \brief Visible declaration consumer that adds a code-completion result 1180 /// for each visible declaration. 1181 class CodeCompletionDeclConsumer : public VisibleDeclConsumer { 1182 ResultBuilder &Results; 1183 DeclContext *CurContext; 1184 1185 public: 1186 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext) 1187 : Results(Results), CurContext(CurContext) { } 1188 1189 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) { 1190 Results.AddResult(ND, CurContext, Hiding, InBaseClass); 1191 } 1192 }; 1193 } 1194 1195 /// \brief Add type specifiers for the current language as keyword results. 1196 static void AddTypeSpecifierResults(const LangOptions &LangOpts, 1197 ResultBuilder &Results) { 1198 typedef CodeCompletionResult Result; 1199 Results.AddResult(Result("short", CCP_Type)); 1200 Results.AddResult(Result("long", CCP_Type)); 1201 Results.AddResult(Result("signed", CCP_Type)); 1202 Results.AddResult(Result("unsigned", CCP_Type)); 1203 Results.AddResult(Result("void", CCP_Type)); 1204 Results.AddResult(Result("char", CCP_Type)); 1205 Results.AddResult(Result("int", CCP_Type)); 1206 Results.AddResult(Result("float", CCP_Type)); 1207 Results.AddResult(Result("double", CCP_Type)); 1208 Results.AddResult(Result("enum", CCP_Type)); 1209 Results.AddResult(Result("struct", CCP_Type)); 1210 Results.AddResult(Result("union", CCP_Type)); 1211 Results.AddResult(Result("const", CCP_Type)); 1212 Results.AddResult(Result("volatile", CCP_Type)); 1213 1214 if (LangOpts.C99) { 1215 // C99-specific 1216 Results.AddResult(Result("_Complex", CCP_Type)); 1217 Results.AddResult(Result("_Imaginary", CCP_Type)); 1218 Results.AddResult(Result("_Bool", CCP_Type)); 1219 Results.AddResult(Result("restrict", CCP_Type)); 1220 } 1221 1222 CodeCompletionBuilder Builder(Results.getAllocator()); 1223 if (LangOpts.CPlusPlus) { 1224 // C++-specific 1225 Results.AddResult(Result("bool", CCP_Type + 1226 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0))); 1227 Results.AddResult(Result("class", CCP_Type)); 1228 Results.AddResult(Result("wchar_t", CCP_Type)); 1229 1230 // typename qualified-id 1231 Builder.AddTypedTextChunk("typename"); 1232 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1233 Builder.AddPlaceholderChunk("qualifier"); 1234 Builder.AddTextChunk("::"); 1235 Builder.AddPlaceholderChunk("name"); 1236 Results.AddResult(Result(Builder.TakeString())); 1237 1238 if (LangOpts.CPlusPlus0x) { 1239 Results.AddResult(Result("auto", CCP_Type)); 1240 Results.AddResult(Result("char16_t", CCP_Type)); 1241 Results.AddResult(Result("char32_t", CCP_Type)); 1242 1243 Builder.AddTypedTextChunk("decltype"); 1244 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1245 Builder.AddPlaceholderChunk("expression"); 1246 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1247 Results.AddResult(Result(Builder.TakeString())); 1248 } 1249 } 1250 1251 // GNU extensions 1252 if (LangOpts.GNUMode) { 1253 // FIXME: Enable when we actually support decimal floating point. 1254 // Results.AddResult(Result("_Decimal32")); 1255 // Results.AddResult(Result("_Decimal64")); 1256 // Results.AddResult(Result("_Decimal128")); 1257 1258 Builder.AddTypedTextChunk("typeof"); 1259 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1260 Builder.AddPlaceholderChunk("expression"); 1261 Results.AddResult(Result(Builder.TakeString())); 1262 1263 Builder.AddTypedTextChunk("typeof"); 1264 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1265 Builder.AddPlaceholderChunk("type"); 1266 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1267 Results.AddResult(Result(Builder.TakeString())); 1268 } 1269 } 1270 1271 static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC, 1272 const LangOptions &LangOpts, 1273 ResultBuilder &Results) { 1274 typedef CodeCompletionResult Result; 1275 // Note: we don't suggest either "auto" or "register", because both 1276 // are pointless as storage specifiers. Elsewhere, we suggest "auto" 1277 // in C++0x as a type specifier. 1278 Results.AddResult(Result("extern")); 1279 Results.AddResult(Result("static")); 1280 } 1281 1282 static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC, 1283 const LangOptions &LangOpts, 1284 ResultBuilder &Results) { 1285 typedef CodeCompletionResult Result; 1286 switch (CCC) { 1287 case Sema::PCC_Class: 1288 case Sema::PCC_MemberTemplate: 1289 if (LangOpts.CPlusPlus) { 1290 Results.AddResult(Result("explicit")); 1291 Results.AddResult(Result("friend")); 1292 Results.AddResult(Result("mutable")); 1293 Results.AddResult(Result("virtual")); 1294 } 1295 // Fall through 1296 1297 case Sema::PCC_ObjCInterface: 1298 case Sema::PCC_ObjCImplementation: 1299 case Sema::PCC_Namespace: 1300 case Sema::PCC_Template: 1301 if (LangOpts.CPlusPlus || LangOpts.C99) 1302 Results.AddResult(Result("inline")); 1303 break; 1304 1305 case Sema::PCC_ObjCInstanceVariableList: 1306 case Sema::PCC_Expression: 1307 case Sema::PCC_Statement: 1308 case Sema::PCC_ForInit: 1309 case Sema::PCC_Condition: 1310 case Sema::PCC_RecoveryInFunction: 1311 case Sema::PCC_Type: 1312 case Sema::PCC_ParenthesizedExpression: 1313 case Sema::PCC_LocalDeclarationSpecifiers: 1314 break; 1315 } 1316 } 1317 1318 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt); 1319 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt); 1320 static void AddObjCVisibilityResults(const LangOptions &LangOpts, 1321 ResultBuilder &Results, 1322 bool NeedAt); 1323 static void AddObjCImplementationResults(const LangOptions &LangOpts, 1324 ResultBuilder &Results, 1325 bool NeedAt); 1326 static void AddObjCInterfaceResults(const LangOptions &LangOpts, 1327 ResultBuilder &Results, 1328 bool NeedAt); 1329 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt); 1330 1331 static void AddTypedefResult(ResultBuilder &Results) { 1332 CodeCompletionBuilder Builder(Results.getAllocator()); 1333 Builder.AddTypedTextChunk("typedef"); 1334 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1335 Builder.AddPlaceholderChunk("type"); 1336 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1337 Builder.AddPlaceholderChunk("name"); 1338 Results.AddResult(CodeCompletionResult(Builder.TakeString())); 1339 } 1340 1341 static bool WantTypesInContext(Sema::ParserCompletionContext CCC, 1342 const LangOptions &LangOpts) { 1343 switch (CCC) { 1344 case Sema::PCC_Namespace: 1345 case Sema::PCC_Class: 1346 case Sema::PCC_ObjCInstanceVariableList: 1347 case Sema::PCC_Template: 1348 case Sema::PCC_MemberTemplate: 1349 case Sema::PCC_Statement: 1350 case Sema::PCC_RecoveryInFunction: 1351 case Sema::PCC_Type: 1352 case Sema::PCC_ParenthesizedExpression: 1353 case Sema::PCC_LocalDeclarationSpecifiers: 1354 return true; 1355 1356 case Sema::PCC_Expression: 1357 case Sema::PCC_Condition: 1358 return LangOpts.CPlusPlus; 1359 1360 case Sema::PCC_ObjCInterface: 1361 case Sema::PCC_ObjCImplementation: 1362 return false; 1363 1364 case Sema::PCC_ForInit: 1365 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99; 1366 } 1367 1368 return false; 1369 } 1370 1371 /// \brief Add language constructs that show up for "ordinary" names. 1372 static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, 1373 Scope *S, 1374 Sema &SemaRef, 1375 ResultBuilder &Results) { 1376 CodeCompletionBuilder Builder(Results.getAllocator()); 1377 1378 typedef CodeCompletionResult Result; 1379 switch (CCC) { 1380 case Sema::PCC_Namespace: 1381 if (SemaRef.getLangOptions().CPlusPlus) { 1382 if (Results.includeCodePatterns()) { 1383 // namespace <identifier> { declarations } 1384 Builder.AddTypedTextChunk("namespace"); 1385 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1386 Builder.AddPlaceholderChunk("identifier"); 1387 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 1388 Builder.AddPlaceholderChunk("declarations"); 1389 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 1390 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 1391 Results.AddResult(Result(Builder.TakeString())); 1392 } 1393 1394 // namespace identifier = identifier ; 1395 Builder.AddTypedTextChunk("namespace"); 1396 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1397 Builder.AddPlaceholderChunk("name"); 1398 Builder.AddChunk(CodeCompletionString::CK_Equal); 1399 Builder.AddPlaceholderChunk("namespace"); 1400 Results.AddResult(Result(Builder.TakeString())); 1401 1402 // Using directives 1403 Builder.AddTypedTextChunk("using"); 1404 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1405 Builder.AddTextChunk("namespace"); 1406 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1407 Builder.AddPlaceholderChunk("identifier"); 1408 Results.AddResult(Result(Builder.TakeString())); 1409 1410 // asm(string-literal) 1411 Builder.AddTypedTextChunk("asm"); 1412 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1413 Builder.AddPlaceholderChunk("string-literal"); 1414 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1415 Results.AddResult(Result(Builder.TakeString())); 1416 1417 if (Results.includeCodePatterns()) { 1418 // Explicit template instantiation 1419 Builder.AddTypedTextChunk("template"); 1420 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1421 Builder.AddPlaceholderChunk("declaration"); 1422 Results.AddResult(Result(Builder.TakeString())); 1423 } 1424 } 1425 1426 if (SemaRef.getLangOptions().ObjC1) 1427 AddObjCTopLevelResults(Results, true); 1428 1429 AddTypedefResult(Results); 1430 // Fall through 1431 1432 case Sema::PCC_Class: 1433 if (SemaRef.getLangOptions().CPlusPlus) { 1434 // Using declaration 1435 Builder.AddTypedTextChunk("using"); 1436 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1437 Builder.AddPlaceholderChunk("qualifier"); 1438 Builder.AddTextChunk("::"); 1439 Builder.AddPlaceholderChunk("name"); 1440 Results.AddResult(Result(Builder.TakeString())); 1441 1442 // using typename qualifier::name (only in a dependent context) 1443 if (SemaRef.CurContext->isDependentContext()) { 1444 Builder.AddTypedTextChunk("using"); 1445 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1446 Builder.AddTextChunk("typename"); 1447 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1448 Builder.AddPlaceholderChunk("qualifier"); 1449 Builder.AddTextChunk("::"); 1450 Builder.AddPlaceholderChunk("name"); 1451 Results.AddResult(Result(Builder.TakeString())); 1452 } 1453 1454 if (CCC == Sema::PCC_Class) { 1455 AddTypedefResult(Results); 1456 1457 // public: 1458 Builder.AddTypedTextChunk("public"); 1459 Builder.AddChunk(CodeCompletionString::CK_Colon); 1460 Results.AddResult(Result(Builder.TakeString())); 1461 1462 // protected: 1463 Builder.AddTypedTextChunk("protected"); 1464 Builder.AddChunk(CodeCompletionString::CK_Colon); 1465 Results.AddResult(Result(Builder.TakeString())); 1466 1467 // private: 1468 Builder.AddTypedTextChunk("private"); 1469 Builder.AddChunk(CodeCompletionString::CK_Colon); 1470 Results.AddResult(Result(Builder.TakeString())); 1471 } 1472 } 1473 // Fall through 1474 1475 case Sema::PCC_Template: 1476 case Sema::PCC_MemberTemplate: 1477 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) { 1478 // template < parameters > 1479 Builder.AddTypedTextChunk("template"); 1480 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 1481 Builder.AddPlaceholderChunk("parameters"); 1482 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 1483 Results.AddResult(Result(Builder.TakeString())); 1484 } 1485 1486 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results); 1487 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results); 1488 break; 1489 1490 case Sema::PCC_ObjCInterface: 1491 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true); 1492 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results); 1493 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results); 1494 break; 1495 1496 case Sema::PCC_ObjCImplementation: 1497 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true); 1498 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results); 1499 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results); 1500 break; 1501 1502 case Sema::PCC_ObjCInstanceVariableList: 1503 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true); 1504 break; 1505 1506 case Sema::PCC_RecoveryInFunction: 1507 case Sema::PCC_Statement: { 1508 AddTypedefResult(Results); 1509 1510 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns() && 1511 SemaRef.getLangOptions().CXXExceptions) { 1512 Builder.AddTypedTextChunk("try"); 1513 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 1514 Builder.AddPlaceholderChunk("statements"); 1515 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 1516 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 1517 Builder.AddTextChunk("catch"); 1518 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1519 Builder.AddPlaceholderChunk("declaration"); 1520 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1521 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 1522 Builder.AddPlaceholderChunk("statements"); 1523 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 1524 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 1525 Results.AddResult(Result(Builder.TakeString())); 1526 } 1527 if (SemaRef.getLangOptions().ObjC1) 1528 AddObjCStatementResults(Results, true); 1529 1530 if (Results.includeCodePatterns()) { 1531 // if (condition) { statements } 1532 Builder.AddTypedTextChunk("if"); 1533 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1534 if (SemaRef.getLangOptions().CPlusPlus) 1535 Builder.AddPlaceholderChunk("condition"); 1536 else 1537 Builder.AddPlaceholderChunk("expression"); 1538 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1539 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 1540 Builder.AddPlaceholderChunk("statements"); 1541 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 1542 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 1543 Results.AddResult(Result(Builder.TakeString())); 1544 1545 // switch (condition) { } 1546 Builder.AddTypedTextChunk("switch"); 1547 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1548 if (SemaRef.getLangOptions().CPlusPlus) 1549 Builder.AddPlaceholderChunk("condition"); 1550 else 1551 Builder.AddPlaceholderChunk("expression"); 1552 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1553 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 1554 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 1555 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 1556 Results.AddResult(Result(Builder.TakeString())); 1557 } 1558 1559 // Switch-specific statements. 1560 if (!SemaRef.getCurFunction()->SwitchStack.empty()) { 1561 // case expression: 1562 Builder.AddTypedTextChunk("case"); 1563 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1564 Builder.AddPlaceholderChunk("expression"); 1565 Builder.AddChunk(CodeCompletionString::CK_Colon); 1566 Results.AddResult(Result(Builder.TakeString())); 1567 1568 // default: 1569 Builder.AddTypedTextChunk("default"); 1570 Builder.AddChunk(CodeCompletionString::CK_Colon); 1571 Results.AddResult(Result(Builder.TakeString())); 1572 } 1573 1574 if (Results.includeCodePatterns()) { 1575 /// while (condition) { statements } 1576 Builder.AddTypedTextChunk("while"); 1577 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1578 if (SemaRef.getLangOptions().CPlusPlus) 1579 Builder.AddPlaceholderChunk("condition"); 1580 else 1581 Builder.AddPlaceholderChunk("expression"); 1582 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1583 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 1584 Builder.AddPlaceholderChunk("statements"); 1585 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 1586 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 1587 Results.AddResult(Result(Builder.TakeString())); 1588 1589 // do { statements } while ( expression ); 1590 Builder.AddTypedTextChunk("do"); 1591 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 1592 Builder.AddPlaceholderChunk("statements"); 1593 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 1594 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 1595 Builder.AddTextChunk("while"); 1596 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1597 Builder.AddPlaceholderChunk("expression"); 1598 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1599 Results.AddResult(Result(Builder.TakeString())); 1600 1601 // for ( for-init-statement ; condition ; expression ) { statements } 1602 Builder.AddTypedTextChunk("for"); 1603 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1604 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99) 1605 Builder.AddPlaceholderChunk("init-statement"); 1606 else 1607 Builder.AddPlaceholderChunk("init-expression"); 1608 Builder.AddChunk(CodeCompletionString::CK_SemiColon); 1609 Builder.AddPlaceholderChunk("condition"); 1610 Builder.AddChunk(CodeCompletionString::CK_SemiColon); 1611 Builder.AddPlaceholderChunk("inc-expression"); 1612 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1613 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 1614 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 1615 Builder.AddPlaceholderChunk("statements"); 1616 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 1617 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 1618 Results.AddResult(Result(Builder.TakeString())); 1619 } 1620 1621 if (S->getContinueParent()) { 1622 // continue ; 1623 Builder.AddTypedTextChunk("continue"); 1624 Results.AddResult(Result(Builder.TakeString())); 1625 } 1626 1627 if (S->getBreakParent()) { 1628 // break ; 1629 Builder.AddTypedTextChunk("break"); 1630 Results.AddResult(Result(Builder.TakeString())); 1631 } 1632 1633 // "return expression ;" or "return ;", depending on whether we 1634 // know the function is void or not. 1635 bool isVoid = false; 1636 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext)) 1637 isVoid = Function->getResultType()->isVoidType(); 1638 else if (ObjCMethodDecl *Method 1639 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext)) 1640 isVoid = Method->getResultType()->isVoidType(); 1641 else if (SemaRef.getCurBlock() && 1642 !SemaRef.getCurBlock()->ReturnType.isNull()) 1643 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType(); 1644 Builder.AddTypedTextChunk("return"); 1645 if (!isVoid) { 1646 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1647 Builder.AddPlaceholderChunk("expression"); 1648 } 1649 Results.AddResult(Result(Builder.TakeString())); 1650 1651 // goto identifier ; 1652 Builder.AddTypedTextChunk("goto"); 1653 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1654 Builder.AddPlaceholderChunk("label"); 1655 Results.AddResult(Result(Builder.TakeString())); 1656 1657 // Using directives 1658 Builder.AddTypedTextChunk("using"); 1659 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1660 Builder.AddTextChunk("namespace"); 1661 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1662 Builder.AddPlaceholderChunk("identifier"); 1663 Results.AddResult(Result(Builder.TakeString())); 1664 } 1665 1666 // Fall through (for statement expressions). 1667 case Sema::PCC_ForInit: 1668 case Sema::PCC_Condition: 1669 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results); 1670 // Fall through: conditions and statements can have expressions. 1671 1672 case Sema::PCC_ParenthesizedExpression: 1673 if (SemaRef.getLangOptions().ObjCAutoRefCount && 1674 CCC == Sema::PCC_ParenthesizedExpression) { 1675 // (__bridge <type>)<expression> 1676 Builder.AddTypedTextChunk("__bridge"); 1677 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1678 Builder.AddPlaceholderChunk("type"); 1679 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1680 Builder.AddPlaceholderChunk("expression"); 1681 Results.AddResult(Result(Builder.TakeString())); 1682 1683 // (__bridge_transfer <Objective-C type>)<expression> 1684 Builder.AddTypedTextChunk("__bridge_transfer"); 1685 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1686 Builder.AddPlaceholderChunk("Objective-C type"); 1687 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1688 Builder.AddPlaceholderChunk("expression"); 1689 Results.AddResult(Result(Builder.TakeString())); 1690 1691 // (__bridge_retained <CF type>)<expression> 1692 Builder.AddTypedTextChunk("__bridge_retained"); 1693 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1694 Builder.AddPlaceholderChunk("CF type"); 1695 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1696 Builder.AddPlaceholderChunk("expression"); 1697 Results.AddResult(Result(Builder.TakeString())); 1698 } 1699 // Fall through 1700 1701 case Sema::PCC_Expression: { 1702 if (SemaRef.getLangOptions().CPlusPlus) { 1703 // 'this', if we're in a non-static member function. 1704 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext)) 1705 if (!Method->isStatic()) 1706 Results.AddResult(Result("this")); 1707 1708 // true, false 1709 Results.AddResult(Result("true")); 1710 Results.AddResult(Result("false")); 1711 1712 if (SemaRef.getLangOptions().RTTI) { 1713 // dynamic_cast < type-id > ( expression ) 1714 Builder.AddTypedTextChunk("dynamic_cast"); 1715 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 1716 Builder.AddPlaceholderChunk("type"); 1717 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 1718 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1719 Builder.AddPlaceholderChunk("expression"); 1720 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1721 Results.AddResult(Result(Builder.TakeString())); 1722 } 1723 1724 // static_cast < type-id > ( expression ) 1725 Builder.AddTypedTextChunk("static_cast"); 1726 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 1727 Builder.AddPlaceholderChunk("type"); 1728 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 1729 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1730 Builder.AddPlaceholderChunk("expression"); 1731 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1732 Results.AddResult(Result(Builder.TakeString())); 1733 1734 // reinterpret_cast < type-id > ( expression ) 1735 Builder.AddTypedTextChunk("reinterpret_cast"); 1736 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 1737 Builder.AddPlaceholderChunk("type"); 1738 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 1739 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1740 Builder.AddPlaceholderChunk("expression"); 1741 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1742 Results.AddResult(Result(Builder.TakeString())); 1743 1744 // const_cast < type-id > ( expression ) 1745 Builder.AddTypedTextChunk("const_cast"); 1746 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 1747 Builder.AddPlaceholderChunk("type"); 1748 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 1749 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1750 Builder.AddPlaceholderChunk("expression"); 1751 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1752 Results.AddResult(Result(Builder.TakeString())); 1753 1754 if (SemaRef.getLangOptions().RTTI) { 1755 // typeid ( expression-or-type ) 1756 Builder.AddTypedTextChunk("typeid"); 1757 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1758 Builder.AddPlaceholderChunk("expression-or-type"); 1759 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1760 Results.AddResult(Result(Builder.TakeString())); 1761 } 1762 1763 // new T ( ... ) 1764 Builder.AddTypedTextChunk("new"); 1765 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1766 Builder.AddPlaceholderChunk("type"); 1767 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1768 Builder.AddPlaceholderChunk("expressions"); 1769 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1770 Results.AddResult(Result(Builder.TakeString())); 1771 1772 // new T [ ] ( ... ) 1773 Builder.AddTypedTextChunk("new"); 1774 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1775 Builder.AddPlaceholderChunk("type"); 1776 Builder.AddChunk(CodeCompletionString::CK_LeftBracket); 1777 Builder.AddPlaceholderChunk("size"); 1778 Builder.AddChunk(CodeCompletionString::CK_RightBracket); 1779 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1780 Builder.AddPlaceholderChunk("expressions"); 1781 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1782 Results.AddResult(Result(Builder.TakeString())); 1783 1784 // delete expression 1785 Builder.AddTypedTextChunk("delete"); 1786 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1787 Builder.AddPlaceholderChunk("expression"); 1788 Results.AddResult(Result(Builder.TakeString())); 1789 1790 // delete [] expression 1791 Builder.AddTypedTextChunk("delete"); 1792 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1793 Builder.AddChunk(CodeCompletionString::CK_LeftBracket); 1794 Builder.AddChunk(CodeCompletionString::CK_RightBracket); 1795 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1796 Builder.AddPlaceholderChunk("expression"); 1797 Results.AddResult(Result(Builder.TakeString())); 1798 1799 if (SemaRef.getLangOptions().CXXExceptions) { 1800 // throw expression 1801 Builder.AddTypedTextChunk("throw"); 1802 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 1803 Builder.AddPlaceholderChunk("expression"); 1804 Results.AddResult(Result(Builder.TakeString())); 1805 } 1806 1807 // FIXME: Rethrow? 1808 } 1809 1810 if (SemaRef.getLangOptions().ObjC1) { 1811 // Add "super", if we're in an Objective-C class with a superclass. 1812 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) { 1813 // The interface can be NULL. 1814 if (ObjCInterfaceDecl *ID = Method->getClassInterface()) 1815 if (ID->getSuperClass()) 1816 Results.AddResult(Result("super")); 1817 } 1818 1819 AddObjCExpressionResults(Results, true); 1820 } 1821 1822 // sizeof expression 1823 Builder.AddTypedTextChunk("sizeof"); 1824 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 1825 Builder.AddPlaceholderChunk("expression-or-type"); 1826 Builder.AddChunk(CodeCompletionString::CK_RightParen); 1827 Results.AddResult(Result(Builder.TakeString())); 1828 break; 1829 } 1830 1831 case Sema::PCC_Type: 1832 case Sema::PCC_LocalDeclarationSpecifiers: 1833 break; 1834 } 1835 1836 if (WantTypesInContext(CCC, SemaRef.getLangOptions())) 1837 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results); 1838 1839 if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type) 1840 Results.AddResult(Result("operator")); 1841 } 1842 1843 /// \brief Retrieve a printing policy suitable for code completion. 1844 static PrintingPolicy getCompletionPrintingPolicy(Sema &S) { 1845 PrintingPolicy Policy = S.getPrintingPolicy(); 1846 Policy.AnonymousTagLocations = false; 1847 Policy.SuppressStrongLifetime = true; 1848 return Policy; 1849 } 1850 1851 /// \brief Retrieve the string representation of the given type as a string 1852 /// that has the appropriate lifetime for code completion. 1853 /// 1854 /// This routine provides a fast path where we provide constant strings for 1855 /// common type names. 1856 static const char *GetCompletionTypeString(QualType T, 1857 ASTContext &Context, 1858 const PrintingPolicy &Policy, 1859 CodeCompletionAllocator &Allocator) { 1860 if (!T.getLocalQualifiers()) { 1861 // Built-in type names are constant strings. 1862 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T)) 1863 return BT->getName(Policy); 1864 1865 // Anonymous tag types are constant strings. 1866 if (const TagType *TagT = dyn_cast<TagType>(T)) 1867 if (TagDecl *Tag = TagT->getDecl()) 1868 if (!Tag->getIdentifier() && !Tag->getTypedefNameForAnonDecl()) { 1869 switch (Tag->getTagKind()) { 1870 case TTK_Struct: return "struct <anonymous>"; 1871 case TTK_Class: return "class <anonymous>"; 1872 case TTK_Union: return "union <anonymous>"; 1873 case TTK_Enum: return "enum <anonymous>"; 1874 } 1875 } 1876 } 1877 1878 // Slow path: format the type as a string. 1879 std::string Result; 1880 T.getAsStringInternal(Result, Policy); 1881 return Allocator.CopyString(Result); 1882 } 1883 1884 /// \brief If the given declaration has an associated type, add it as a result 1885 /// type chunk. 1886 static void AddResultTypeChunk(ASTContext &Context, 1887 const PrintingPolicy &Policy, 1888 NamedDecl *ND, 1889 CodeCompletionBuilder &Result) { 1890 if (!ND) 1891 return; 1892 1893 // Skip constructors and conversion functions, which have their return types 1894 // built into their names. 1895 if (isa<CXXConstructorDecl>(ND) || isa<CXXConversionDecl>(ND)) 1896 return; 1897 1898 // Determine the type of the declaration (if it has a type). 1899 QualType T; 1900 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) 1901 T = Function->getResultType(); 1902 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) 1903 T = Method->getResultType(); 1904 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) 1905 T = FunTmpl->getTemplatedDecl()->getResultType(); 1906 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) 1907 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext())); 1908 else if (isa<UnresolvedUsingValueDecl>(ND)) { 1909 /* Do nothing: ignore unresolved using declarations*/ 1910 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND)) { 1911 T = Value->getType(); 1912 } else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) 1913 T = Property->getType(); 1914 1915 if (T.isNull() || Context.hasSameType(T, Context.DependentTy)) 1916 return; 1917 1918 Result.AddResultTypeChunk(GetCompletionTypeString(T, Context, Policy, 1919 Result.getAllocator())); 1920 } 1921 1922 static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod, 1923 CodeCompletionBuilder &Result) { 1924 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>()) 1925 if (Sentinel->getSentinel() == 0) { 1926 if (Context.getLangOptions().ObjC1 && 1927 Context.Idents.get("nil").hasMacroDefinition()) 1928 Result.AddTextChunk(", nil"); 1929 else if (Context.Idents.get("NULL").hasMacroDefinition()) 1930 Result.AddTextChunk(", NULL"); 1931 else 1932 Result.AddTextChunk(", (void*)0"); 1933 } 1934 } 1935 1936 static void appendWithSpace(std::string &Result, StringRef Text) { 1937 if (!Result.empty()) 1938 Result += ' '; 1939 Result += Text.str(); 1940 } 1941 static std::string formatObjCParamQualifiers(unsigned ObjCQuals) { 1942 std::string Result; 1943 if (ObjCQuals & Decl::OBJC_TQ_In) 1944 appendWithSpace(Result, "in"); 1945 else if (ObjCQuals & Decl::OBJC_TQ_Inout) 1946 appendWithSpace(Result, "inout"); 1947 else if (ObjCQuals & Decl::OBJC_TQ_Out) 1948 appendWithSpace(Result, "out"); 1949 if (ObjCQuals & Decl::OBJC_TQ_Bycopy) 1950 appendWithSpace(Result, "bycopy"); 1951 else if (ObjCQuals & Decl::OBJC_TQ_Byref) 1952 appendWithSpace(Result, "byref"); 1953 if (ObjCQuals & Decl::OBJC_TQ_Oneway) 1954 appendWithSpace(Result, "oneway"); 1955 return Result; 1956 } 1957 1958 static std::string FormatFunctionParameter(ASTContext &Context, 1959 const PrintingPolicy &Policy, 1960 ParmVarDecl *Param, 1961 bool SuppressName = false) { 1962 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext()); 1963 if (Param->getType()->isDependentType() || 1964 !Param->getType()->isBlockPointerType()) { 1965 // The argument for a dependent or non-block parameter is a placeholder 1966 // containing that parameter's type. 1967 std::string Result; 1968 1969 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName) 1970 Result = Param->getIdentifier()->getName(); 1971 1972 Param->getType().getAsStringInternal(Result, Policy); 1973 1974 if (ObjCMethodParam) { 1975 Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier()) 1976 + Result + ")"; 1977 if (Param->getIdentifier() && !SuppressName) 1978 Result += Param->getIdentifier()->getName(); 1979 } 1980 return Result; 1981 } 1982 1983 // The argument for a block pointer parameter is a block literal with 1984 // the appropriate type. 1985 FunctionTypeLoc *Block = 0; 1986 FunctionProtoTypeLoc *BlockProto = 0; 1987 TypeLoc TL; 1988 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) { 1989 TL = TSInfo->getTypeLoc().getUnqualifiedLoc(); 1990 while (true) { 1991 // Look through typedefs. 1992 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) { 1993 if (TypeSourceInfo *InnerTSInfo 1994 = TypedefTL->getTypedefNameDecl()->getTypeSourceInfo()) { 1995 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc(); 1996 continue; 1997 } 1998 } 1999 2000 // Look through qualified types 2001 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) { 2002 TL = QualifiedTL->getUnqualifiedLoc(); 2003 continue; 2004 } 2005 2006 // Try to get the function prototype behind the block pointer type, 2007 // then we're done. 2008 if (BlockPointerTypeLoc *BlockPtr 2009 = dyn_cast<BlockPointerTypeLoc>(&TL)) { 2010 TL = BlockPtr->getPointeeLoc().IgnoreParens(); 2011 Block = dyn_cast<FunctionTypeLoc>(&TL); 2012 BlockProto = dyn_cast<FunctionProtoTypeLoc>(&TL); 2013 } 2014 break; 2015 } 2016 } 2017 2018 if (!Block) { 2019 // We were unable to find a FunctionProtoTypeLoc with parameter names 2020 // for the block; just use the parameter type as a placeholder. 2021 std::string Result; 2022 Param->getType().getUnqualifiedType().getAsStringInternal(Result, Policy); 2023 2024 if (ObjCMethodParam) { 2025 Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier()) 2026 + Result + ")"; 2027 if (Param->getIdentifier()) 2028 Result += Param->getIdentifier()->getName(); 2029 } 2030 2031 return Result; 2032 } 2033 2034 // We have the function prototype behind the block pointer type, as it was 2035 // written in the source. 2036 std::string Result; 2037 QualType ResultType = Block->getTypePtr()->getResultType(); 2038 if (!ResultType->isVoidType()) 2039 ResultType.getAsStringInternal(Result, Policy); 2040 2041 Result = '^' + Result; 2042 if (!BlockProto || Block->getNumArgs() == 0) { 2043 if (BlockProto && BlockProto->getTypePtr()->isVariadic()) 2044 Result += "(...)"; 2045 else 2046 Result += "(void)"; 2047 } else { 2048 Result += "("; 2049 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) { 2050 if (I) 2051 Result += ", "; 2052 Result += FormatFunctionParameter(Context, Policy, Block->getArg(I)); 2053 2054 if (I == N - 1 && BlockProto->getTypePtr()->isVariadic()) 2055 Result += ", ..."; 2056 } 2057 Result += ")"; 2058 } 2059 2060 if (Param->getIdentifier()) 2061 Result += Param->getIdentifier()->getName(); 2062 2063 return Result; 2064 } 2065 2066 /// \brief Add function parameter chunks to the given code completion string. 2067 static void AddFunctionParameterChunks(ASTContext &Context, 2068 const PrintingPolicy &Policy, 2069 FunctionDecl *Function, 2070 CodeCompletionBuilder &Result, 2071 unsigned Start = 0, 2072 bool InOptional = false) { 2073 typedef CodeCompletionString::Chunk Chunk; 2074 bool FirstParameter = true; 2075 2076 for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) { 2077 ParmVarDecl *Param = Function->getParamDecl(P); 2078 2079 if (Param->hasDefaultArg() && !InOptional) { 2080 // When we see an optional default argument, put that argument and 2081 // the remaining default arguments into a new, optional string. 2082 CodeCompletionBuilder Opt(Result.getAllocator()); 2083 if (!FirstParameter) 2084 Opt.AddChunk(Chunk(CodeCompletionString::CK_Comma)); 2085 AddFunctionParameterChunks(Context, Policy, Function, Opt, P, true); 2086 Result.AddOptionalChunk(Opt.TakeString()); 2087 break; 2088 } 2089 2090 if (FirstParameter) 2091 FirstParameter = false; 2092 else 2093 Result.AddChunk(Chunk(CodeCompletionString::CK_Comma)); 2094 2095 InOptional = false; 2096 2097 // Format the placeholder string. 2098 std::string PlaceholderStr = FormatFunctionParameter(Context, Policy, 2099 Param); 2100 2101 if (Function->isVariadic() && P == N - 1) 2102 PlaceholderStr += ", ..."; 2103 2104 // Add the placeholder string. 2105 Result.AddPlaceholderChunk( 2106 Result.getAllocator().CopyString(PlaceholderStr)); 2107 } 2108 2109 if (const FunctionProtoType *Proto 2110 = Function->getType()->getAs<FunctionProtoType>()) 2111 if (Proto->isVariadic()) { 2112 if (Proto->getNumArgs() == 0) 2113 Result.AddPlaceholderChunk("..."); 2114 2115 MaybeAddSentinel(Context, Function, Result); 2116 } 2117 } 2118 2119 /// \brief Add template parameter chunks to the given code completion string. 2120 static void AddTemplateParameterChunks(ASTContext &Context, 2121 const PrintingPolicy &Policy, 2122 TemplateDecl *Template, 2123 CodeCompletionBuilder &Result, 2124 unsigned MaxParameters = 0, 2125 unsigned Start = 0, 2126 bool InDefaultArg = false) { 2127 typedef CodeCompletionString::Chunk Chunk; 2128 bool FirstParameter = true; 2129 2130 TemplateParameterList *Params = Template->getTemplateParameters(); 2131 TemplateParameterList::iterator PEnd = Params->end(); 2132 if (MaxParameters) 2133 PEnd = Params->begin() + MaxParameters; 2134 for (TemplateParameterList::iterator P = Params->begin() + Start; 2135 P != PEnd; ++P) { 2136 bool HasDefaultArg = false; 2137 std::string PlaceholderStr; 2138 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { 2139 if (TTP->wasDeclaredWithTypename()) 2140 PlaceholderStr = "typename"; 2141 else 2142 PlaceholderStr = "class"; 2143 2144 if (TTP->getIdentifier()) { 2145 PlaceholderStr += ' '; 2146 PlaceholderStr += TTP->getIdentifier()->getName(); 2147 } 2148 2149 HasDefaultArg = TTP->hasDefaultArgument(); 2150 } else if (NonTypeTemplateParmDecl *NTTP 2151 = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 2152 if (NTTP->getIdentifier()) 2153 PlaceholderStr = NTTP->getIdentifier()->getName(); 2154 NTTP->getType().getAsStringInternal(PlaceholderStr, Policy); 2155 HasDefaultArg = NTTP->hasDefaultArgument(); 2156 } else { 2157 assert(isa<TemplateTemplateParmDecl>(*P)); 2158 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P); 2159 2160 // Since putting the template argument list into the placeholder would 2161 // be very, very long, we just use an abbreviation. 2162 PlaceholderStr = "template<...> class"; 2163 if (TTP->getIdentifier()) { 2164 PlaceholderStr += ' '; 2165 PlaceholderStr += TTP->getIdentifier()->getName(); 2166 } 2167 2168 HasDefaultArg = TTP->hasDefaultArgument(); 2169 } 2170 2171 if (HasDefaultArg && !InDefaultArg) { 2172 // When we see an optional default argument, put that argument and 2173 // the remaining default arguments into a new, optional string. 2174 CodeCompletionBuilder Opt(Result.getAllocator()); 2175 if (!FirstParameter) 2176 Opt.AddChunk(Chunk(CodeCompletionString::CK_Comma)); 2177 AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters, 2178 P - Params->begin(), true); 2179 Result.AddOptionalChunk(Opt.TakeString()); 2180 break; 2181 } 2182 2183 InDefaultArg = false; 2184 2185 if (FirstParameter) 2186 FirstParameter = false; 2187 else 2188 Result.AddChunk(Chunk(CodeCompletionString::CK_Comma)); 2189 2190 // Add the placeholder string. 2191 Result.AddPlaceholderChunk( 2192 Result.getAllocator().CopyString(PlaceholderStr)); 2193 } 2194 } 2195 2196 /// \brief Add a qualifier to the given code-completion string, if the 2197 /// provided nested-name-specifier is non-NULL. 2198 static void 2199 AddQualifierToCompletionString(CodeCompletionBuilder &Result, 2200 NestedNameSpecifier *Qualifier, 2201 bool QualifierIsInformative, 2202 ASTContext &Context, 2203 const PrintingPolicy &Policy) { 2204 if (!Qualifier) 2205 return; 2206 2207 std::string PrintedNNS; 2208 { 2209 llvm::raw_string_ostream OS(PrintedNNS); 2210 Qualifier->print(OS, Policy); 2211 } 2212 if (QualifierIsInformative) 2213 Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS)); 2214 else 2215 Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS)); 2216 } 2217 2218 static void 2219 AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result, 2220 FunctionDecl *Function) { 2221 const FunctionProtoType *Proto 2222 = Function->getType()->getAs<FunctionProtoType>(); 2223 if (!Proto || !Proto->getTypeQuals()) 2224 return; 2225 2226 // FIXME: Add ref-qualifier! 2227 2228 // Handle single qualifiers without copying 2229 if (Proto->getTypeQuals() == Qualifiers::Const) { 2230 Result.AddInformativeChunk(" const"); 2231 return; 2232 } 2233 2234 if (Proto->getTypeQuals() == Qualifiers::Volatile) { 2235 Result.AddInformativeChunk(" volatile"); 2236 return; 2237 } 2238 2239 if (Proto->getTypeQuals() == Qualifiers::Restrict) { 2240 Result.AddInformativeChunk(" restrict"); 2241 return; 2242 } 2243 2244 // Handle multiple qualifiers. 2245 std::string QualsStr; 2246 if (Proto->getTypeQuals() & Qualifiers::Const) 2247 QualsStr += " const"; 2248 if (Proto->getTypeQuals() & Qualifiers::Volatile) 2249 QualsStr += " volatile"; 2250 if (Proto->getTypeQuals() & Qualifiers::Restrict) 2251 QualsStr += " restrict"; 2252 Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr)); 2253 } 2254 2255 /// \brief Add the name of the given declaration 2256 static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, 2257 NamedDecl *ND, CodeCompletionBuilder &Result) { 2258 typedef CodeCompletionString::Chunk Chunk; 2259 2260 DeclarationName Name = ND->getDeclName(); 2261 if (!Name) 2262 return; 2263 2264 switch (Name.getNameKind()) { 2265 case DeclarationName::CXXOperatorName: { 2266 const char *OperatorName = 0; 2267 switch (Name.getCXXOverloadedOperator()) { 2268 case OO_None: 2269 case OO_Conditional: 2270 case NUM_OVERLOADED_OPERATORS: 2271 OperatorName = "operator"; 2272 break; 2273 2274 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 2275 case OO_##Name: OperatorName = "operator" Spelling; break; 2276 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 2277 #include "clang/Basic/OperatorKinds.def" 2278 2279 case OO_New: OperatorName = "operator new"; break; 2280 case OO_Delete: OperatorName = "operator delete"; break; 2281 case OO_Array_New: OperatorName = "operator new[]"; break; 2282 case OO_Array_Delete: OperatorName = "operator delete[]"; break; 2283 case OO_Call: OperatorName = "operator()"; break; 2284 case OO_Subscript: OperatorName = "operator[]"; break; 2285 } 2286 Result.AddTypedTextChunk(OperatorName); 2287 break; 2288 } 2289 2290 case DeclarationName::Identifier: 2291 case DeclarationName::CXXConversionFunctionName: 2292 case DeclarationName::CXXDestructorName: 2293 case DeclarationName::CXXLiteralOperatorName: 2294 Result.AddTypedTextChunk( 2295 Result.getAllocator().CopyString(ND->getNameAsString())); 2296 break; 2297 2298 case DeclarationName::CXXUsingDirective: 2299 case DeclarationName::ObjCZeroArgSelector: 2300 case DeclarationName::ObjCOneArgSelector: 2301 case DeclarationName::ObjCMultiArgSelector: 2302 break; 2303 2304 case DeclarationName::CXXConstructorName: { 2305 CXXRecordDecl *Record = 0; 2306 QualType Ty = Name.getCXXNameType(); 2307 if (const RecordType *RecordTy = Ty->getAs<RecordType>()) 2308 Record = cast<CXXRecordDecl>(RecordTy->getDecl()); 2309 else if (const InjectedClassNameType *InjectedTy 2310 = Ty->getAs<InjectedClassNameType>()) 2311 Record = InjectedTy->getDecl(); 2312 else { 2313 Result.AddTypedTextChunk( 2314 Result.getAllocator().CopyString(ND->getNameAsString())); 2315 break; 2316 } 2317 2318 Result.AddTypedTextChunk( 2319 Result.getAllocator().CopyString(Record->getNameAsString())); 2320 if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) { 2321 Result.AddChunk(Chunk(CodeCompletionString::CK_LeftAngle)); 2322 AddTemplateParameterChunks(Context, Policy, Template, Result); 2323 Result.AddChunk(Chunk(CodeCompletionString::CK_RightAngle)); 2324 } 2325 break; 2326 } 2327 } 2328 } 2329 2330 /// \brief If possible, create a new code completion string for the given 2331 /// result. 2332 /// 2333 /// \returns Either a new, heap-allocated code completion string describing 2334 /// how to use this result, or NULL to indicate that the string or name of the 2335 /// result is all that is needed. 2336 CodeCompletionString * 2337 CodeCompletionResult::CreateCodeCompletionString(Sema &S, 2338 CodeCompletionAllocator &Allocator) { 2339 typedef CodeCompletionString::Chunk Chunk; 2340 CodeCompletionBuilder Result(Allocator, Priority, Availability); 2341 2342 PrintingPolicy Policy = getCompletionPrintingPolicy(S); 2343 if (Kind == RK_Pattern) { 2344 Pattern->Priority = Priority; 2345 Pattern->Availability = Availability; 2346 return Pattern; 2347 } 2348 2349 if (Kind == RK_Keyword) { 2350 Result.AddTypedTextChunk(Keyword); 2351 return Result.TakeString(); 2352 } 2353 2354 if (Kind == RK_Macro) { 2355 MacroInfo *MI = S.PP.getMacroInfo(Macro); 2356 assert(MI && "Not a macro?"); 2357 2358 Result.AddTypedTextChunk( 2359 Result.getAllocator().CopyString(Macro->getName())); 2360 2361 if (!MI->isFunctionLike()) 2362 return Result.TakeString(); 2363 2364 // Format a function-like macro with placeholders for the arguments. 2365 Result.AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); 2366 bool CombineVariadicArgument = false; 2367 MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end(); 2368 if (MI->isVariadic() && AEnd - A > 1) { 2369 AEnd -= 2; 2370 CombineVariadicArgument = true; 2371 } 2372 for (MacroInfo::arg_iterator A = MI->arg_begin(); A != AEnd; ++A) { 2373 if (A != MI->arg_begin()) 2374 Result.AddChunk(Chunk(CodeCompletionString::CK_Comma)); 2375 2376 if (!MI->isVariadic() || A + 1 != AEnd) { 2377 // Non-variadic argument. 2378 Result.AddPlaceholderChunk( 2379 Result.getAllocator().CopyString((*A)->getName())); 2380 continue; 2381 } 2382 2383 // Variadic argument; cope with the difference between GNU and C99 2384 // variadic macros, providing a single placeholder for the rest of the 2385 // arguments. 2386 if ((*A)->isStr("__VA_ARGS__")) 2387 Result.AddPlaceholderChunk("..."); 2388 else { 2389 std::string Arg = (*A)->getName(); 2390 Arg += "..."; 2391 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg)); 2392 } 2393 } 2394 2395 if (CombineVariadicArgument) { 2396 // Handle the next-to-last argument, combining it with the variadic 2397 // argument. 2398 std::string LastArg = (*A)->getName(); 2399 ++A; 2400 if ((*A)->isStr("__VA_ARGS__")) 2401 LastArg += ", ..."; 2402 else 2403 LastArg += ", " + (*A)->getName().str() + "..."; 2404 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(LastArg)); 2405 } 2406 Result.AddChunk(Chunk(CodeCompletionString::CK_RightParen)); 2407 return Result.TakeString(); 2408 } 2409 2410 assert(Kind == RK_Declaration && "Missed a result kind?"); 2411 NamedDecl *ND = Declaration; 2412 2413 if (StartsNestedNameSpecifier) { 2414 Result.AddTypedTextChunk( 2415 Result.getAllocator().CopyString(ND->getNameAsString())); 2416 Result.AddTextChunk("::"); 2417 return Result.TakeString(); 2418 } 2419 2420 AddResultTypeChunk(S.Context, Policy, ND, Result); 2421 2422 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) { 2423 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 2424 S.Context, Policy); 2425 AddTypedNameChunk(S.Context, Policy, ND, Result); 2426 Result.AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); 2427 AddFunctionParameterChunks(S.Context, Policy, Function, Result); 2428 Result.AddChunk(Chunk(CodeCompletionString::CK_RightParen)); 2429 AddFunctionTypeQualsToCompletionString(Result, Function); 2430 return Result.TakeString(); 2431 } 2432 2433 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) { 2434 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 2435 S.Context, Policy); 2436 FunctionDecl *Function = FunTmpl->getTemplatedDecl(); 2437 AddTypedNameChunk(S.Context, Policy, Function, Result); 2438 2439 // Figure out which template parameters are deduced (or have default 2440 // arguments). 2441 SmallVector<bool, 16> Deduced; 2442 S.MarkDeducedTemplateParameters(FunTmpl, Deduced); 2443 unsigned LastDeducibleArgument; 2444 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0; 2445 --LastDeducibleArgument) { 2446 if (!Deduced[LastDeducibleArgument - 1]) { 2447 // C++0x: Figure out if the template argument has a default. If so, 2448 // the user doesn't need to type this argument. 2449 // FIXME: We need to abstract template parameters better! 2450 bool HasDefaultArg = false; 2451 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam( 2452 LastDeducibleArgument - 1); 2453 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) 2454 HasDefaultArg = TTP->hasDefaultArgument(); 2455 else if (NonTypeTemplateParmDecl *NTTP 2456 = dyn_cast<NonTypeTemplateParmDecl>(Param)) 2457 HasDefaultArg = NTTP->hasDefaultArgument(); 2458 else { 2459 assert(isa<TemplateTemplateParmDecl>(Param)); 2460 HasDefaultArg 2461 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument(); 2462 } 2463 2464 if (!HasDefaultArg) 2465 break; 2466 } 2467 } 2468 2469 if (LastDeducibleArgument) { 2470 // Some of the function template arguments cannot be deduced from a 2471 // function call, so we introduce an explicit template argument list 2472 // containing all of the arguments up to the first deducible argument. 2473 Result.AddChunk(Chunk(CodeCompletionString::CK_LeftAngle)); 2474 AddTemplateParameterChunks(S.Context, Policy, FunTmpl, Result, 2475 LastDeducibleArgument); 2476 Result.AddChunk(Chunk(CodeCompletionString::CK_RightAngle)); 2477 } 2478 2479 // Add the function parameters 2480 Result.AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); 2481 AddFunctionParameterChunks(S.Context, Policy, Function, Result); 2482 Result.AddChunk(Chunk(CodeCompletionString::CK_RightParen)); 2483 AddFunctionTypeQualsToCompletionString(Result, Function); 2484 return Result.TakeString(); 2485 } 2486 2487 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) { 2488 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 2489 S.Context, Policy); 2490 Result.AddTypedTextChunk( 2491 Result.getAllocator().CopyString(Template->getNameAsString())); 2492 Result.AddChunk(Chunk(CodeCompletionString::CK_LeftAngle)); 2493 AddTemplateParameterChunks(S.Context, Policy, Template, Result); 2494 Result.AddChunk(Chunk(CodeCompletionString::CK_RightAngle)); 2495 return Result.TakeString(); 2496 } 2497 2498 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) { 2499 Selector Sel = Method->getSelector(); 2500 if (Sel.isUnarySelector()) { 2501 Result.AddTypedTextChunk(Result.getAllocator().CopyString( 2502 Sel.getNameForSlot(0))); 2503 return Result.TakeString(); 2504 } 2505 2506 std::string SelName = Sel.getNameForSlot(0).str(); 2507 SelName += ':'; 2508 if (StartParameter == 0) 2509 Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName)); 2510 else { 2511 Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName)); 2512 2513 // If there is only one parameter, and we're past it, add an empty 2514 // typed-text chunk since there is nothing to type. 2515 if (Method->param_size() == 1) 2516 Result.AddTypedTextChunk(""); 2517 } 2518 unsigned Idx = 0; 2519 for (ObjCMethodDecl::param_iterator P = Method->param_begin(), 2520 PEnd = Method->param_end(); 2521 P != PEnd; (void)++P, ++Idx) { 2522 if (Idx > 0) { 2523 std::string Keyword; 2524 if (Idx > StartParameter) 2525 Result.AddChunk(CodeCompletionString::CK_HorizontalSpace); 2526 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx)) 2527 Keyword += II->getName(); 2528 Keyword += ":"; 2529 if (Idx < StartParameter || AllParametersAreInformative) 2530 Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword)); 2531 else 2532 Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword)); 2533 } 2534 2535 // If we're before the starting parameter, skip the placeholder. 2536 if (Idx < StartParameter) 2537 continue; 2538 2539 std::string Arg; 2540 2541 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity) 2542 Arg = FormatFunctionParameter(S.Context, Policy, *P, true); 2543 else { 2544 (*P)->getType().getAsStringInternal(Arg, Policy); 2545 Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier()) 2546 + Arg + ")"; 2547 if (IdentifierInfo *II = (*P)->getIdentifier()) 2548 if (DeclaringEntity || AllParametersAreInformative) 2549 Arg += II->getName(); 2550 } 2551 2552 if (Method->isVariadic() && (P + 1) == PEnd) 2553 Arg += ", ..."; 2554 2555 if (DeclaringEntity) 2556 Result.AddTextChunk(Result.getAllocator().CopyString(Arg)); 2557 else if (AllParametersAreInformative) 2558 Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg)); 2559 else 2560 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg)); 2561 } 2562 2563 if (Method->isVariadic()) { 2564 if (Method->param_size() == 0) { 2565 if (DeclaringEntity) 2566 Result.AddTextChunk(", ..."); 2567 else if (AllParametersAreInformative) 2568 Result.AddInformativeChunk(", ..."); 2569 else 2570 Result.AddPlaceholderChunk(", ..."); 2571 } 2572 2573 MaybeAddSentinel(S.Context, Method, Result); 2574 } 2575 2576 return Result.TakeString(); 2577 } 2578 2579 if (Qualifier) 2580 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 2581 S.Context, Policy); 2582 2583 Result.AddTypedTextChunk( 2584 Result.getAllocator().CopyString(ND->getNameAsString())); 2585 return Result.TakeString(); 2586 } 2587 2588 CodeCompletionString * 2589 CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( 2590 unsigned CurrentArg, 2591 Sema &S, 2592 CodeCompletionAllocator &Allocator) const { 2593 typedef CodeCompletionString::Chunk Chunk; 2594 PrintingPolicy Policy = getCompletionPrintingPolicy(S); 2595 2596 // FIXME: Set priority, availability appropriately. 2597 CodeCompletionBuilder Result(Allocator, 1, CXAvailability_Available); 2598 FunctionDecl *FDecl = getFunction(); 2599 AddResultTypeChunk(S.Context, Policy, FDecl, Result); 2600 const FunctionProtoType *Proto 2601 = dyn_cast<FunctionProtoType>(getFunctionType()); 2602 if (!FDecl && !Proto) { 2603 // Function without a prototype. Just give the return type and a 2604 // highlighted ellipsis. 2605 const FunctionType *FT = getFunctionType(); 2606 Result.AddTextChunk(GetCompletionTypeString(FT->getResultType(), 2607 S.Context, Policy, 2608 Result.getAllocator())); 2609 Result.AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); 2610 Result.AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "...")); 2611 Result.AddChunk(Chunk(CodeCompletionString::CK_RightParen)); 2612 return Result.TakeString(); 2613 } 2614 2615 if (FDecl) 2616 Result.AddTextChunk( 2617 Result.getAllocator().CopyString(FDecl->getNameAsString())); 2618 else 2619 Result.AddTextChunk( 2620 Result.getAllocator().CopyString( 2621 Proto->getResultType().getAsString(Policy))); 2622 2623 Result.AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); 2624 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs(); 2625 for (unsigned I = 0; I != NumParams; ++I) { 2626 if (I) 2627 Result.AddChunk(Chunk(CodeCompletionString::CK_Comma)); 2628 2629 std::string ArgString; 2630 QualType ArgType; 2631 2632 if (FDecl) { 2633 ArgString = FDecl->getParamDecl(I)->getNameAsString(); 2634 ArgType = FDecl->getParamDecl(I)->getOriginalType(); 2635 } else { 2636 ArgType = Proto->getArgType(I); 2637 } 2638 2639 ArgType.getAsStringInternal(ArgString, Policy); 2640 2641 if (I == CurrentArg) 2642 Result.AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, 2643 Result.getAllocator().CopyString(ArgString))); 2644 else 2645 Result.AddTextChunk(Result.getAllocator().CopyString(ArgString)); 2646 } 2647 2648 if (Proto && Proto->isVariadic()) { 2649 Result.AddChunk(Chunk(CodeCompletionString::CK_Comma)); 2650 if (CurrentArg < NumParams) 2651 Result.AddTextChunk("..."); 2652 else 2653 Result.AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "...")); 2654 } 2655 Result.AddChunk(Chunk(CodeCompletionString::CK_RightParen)); 2656 2657 return Result.TakeString(); 2658 } 2659 2660 unsigned clang::getMacroUsagePriority(StringRef MacroName, 2661 const LangOptions &LangOpts, 2662 bool PreferredTypeIsPointer) { 2663 unsigned Priority = CCP_Macro; 2664 2665 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants. 2666 if (MacroName.equals("nil") || MacroName.equals("NULL") || 2667 MacroName.equals("Nil")) { 2668 Priority = CCP_Constant; 2669 if (PreferredTypeIsPointer) 2670 Priority = Priority / CCF_SimilarTypeMatch; 2671 } 2672 // Treat "YES", "NO", "true", and "false" as constants. 2673 else if (MacroName.equals("YES") || MacroName.equals("NO") || 2674 MacroName.equals("true") || MacroName.equals("false")) 2675 Priority = CCP_Constant; 2676 // Treat "bool" as a type. 2677 else if (MacroName.equals("bool")) 2678 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0); 2679 2680 2681 return Priority; 2682 } 2683 2684 CXCursorKind clang::getCursorKindForDecl(Decl *D) { 2685 if (!D) 2686 return CXCursor_UnexposedDecl; 2687 2688 switch (D->getKind()) { 2689 case Decl::Enum: return CXCursor_EnumDecl; 2690 case Decl::EnumConstant: return CXCursor_EnumConstantDecl; 2691 case Decl::Field: return CXCursor_FieldDecl; 2692 case Decl::Function: 2693 return CXCursor_FunctionDecl; 2694 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl; 2695 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl; 2696 case Decl::ObjCClass: 2697 // FIXME 2698 return CXCursor_UnexposedDecl; 2699 case Decl::ObjCForwardProtocol: 2700 // FIXME 2701 return CXCursor_UnexposedDecl; 2702 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl; 2703 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl; 2704 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl; 2705 case Decl::ObjCMethod: 2706 return cast<ObjCMethodDecl>(D)->isInstanceMethod() 2707 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl; 2708 case Decl::CXXMethod: return CXCursor_CXXMethod; 2709 case Decl::CXXConstructor: return CXCursor_Constructor; 2710 case Decl::CXXDestructor: return CXCursor_Destructor; 2711 case Decl::CXXConversion: return CXCursor_ConversionFunction; 2712 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl; 2713 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl; 2714 case Decl::ParmVar: return CXCursor_ParmDecl; 2715 case Decl::Typedef: return CXCursor_TypedefDecl; 2716 case Decl::TypeAlias: return CXCursor_TypeAliasDecl; 2717 case Decl::Var: return CXCursor_VarDecl; 2718 case Decl::Namespace: return CXCursor_Namespace; 2719 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias; 2720 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter; 2721 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter; 2722 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter; 2723 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate; 2724 case Decl::ClassTemplate: return CXCursor_ClassTemplate; 2725 case Decl::AccessSpec: return CXCursor_CXXAccessSpecifier; 2726 case Decl::ClassTemplatePartialSpecialization: 2727 return CXCursor_ClassTemplatePartialSpecialization; 2728 case Decl::UsingDirective: return CXCursor_UsingDirective; 2729 2730 case Decl::Using: 2731 case Decl::UnresolvedUsingValue: 2732 case Decl::UnresolvedUsingTypename: 2733 return CXCursor_UsingDeclaration; 2734 2735 case Decl::ObjCPropertyImpl: 2736 switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) { 2737 case ObjCPropertyImplDecl::Dynamic: 2738 return CXCursor_ObjCDynamicDecl; 2739 2740 case ObjCPropertyImplDecl::Synthesize: 2741 return CXCursor_ObjCSynthesizeDecl; 2742 } 2743 break; 2744 2745 default: 2746 if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 2747 switch (TD->getTagKind()) { 2748 case TTK_Struct: return CXCursor_StructDecl; 2749 case TTK_Class: return CXCursor_ClassDecl; 2750 case TTK_Union: return CXCursor_UnionDecl; 2751 case TTK_Enum: return CXCursor_EnumDecl; 2752 } 2753 } 2754 } 2755 2756 return CXCursor_UnexposedDecl; 2757 } 2758 2759 static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results, 2760 bool TargetTypeIsPointer = false) { 2761 typedef CodeCompletionResult Result; 2762 2763 Results.EnterNewScope(); 2764 2765 for (Preprocessor::macro_iterator M = PP.macro_begin(), 2766 MEnd = PP.macro_end(); 2767 M != MEnd; ++M) { 2768 Results.AddResult(Result(M->first, 2769 getMacroUsagePriority(M->first->getName(), 2770 PP.getLangOptions(), 2771 TargetTypeIsPointer))); 2772 } 2773 2774 Results.ExitScope(); 2775 2776 } 2777 2778 static void AddPrettyFunctionResults(const LangOptions &LangOpts, 2779 ResultBuilder &Results) { 2780 typedef CodeCompletionResult Result; 2781 2782 Results.EnterNewScope(); 2783 2784 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant)); 2785 Results.AddResult(Result("__FUNCTION__", CCP_Constant)); 2786 if (LangOpts.C99 || LangOpts.CPlusPlus0x) 2787 Results.AddResult(Result("__func__", CCP_Constant)); 2788 Results.ExitScope(); 2789 } 2790 2791 static void HandleCodeCompleteResults(Sema *S, 2792 CodeCompleteConsumer *CodeCompleter, 2793 CodeCompletionContext Context, 2794 CodeCompletionResult *Results, 2795 unsigned NumResults) { 2796 if (CodeCompleter) 2797 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults); 2798 } 2799 2800 static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S, 2801 Sema::ParserCompletionContext PCC) { 2802 switch (PCC) { 2803 case Sema::PCC_Namespace: 2804 return CodeCompletionContext::CCC_TopLevel; 2805 2806 case Sema::PCC_Class: 2807 return CodeCompletionContext::CCC_ClassStructUnion; 2808 2809 case Sema::PCC_ObjCInterface: 2810 return CodeCompletionContext::CCC_ObjCInterface; 2811 2812 case Sema::PCC_ObjCImplementation: 2813 return CodeCompletionContext::CCC_ObjCImplementation; 2814 2815 case Sema::PCC_ObjCInstanceVariableList: 2816 return CodeCompletionContext::CCC_ObjCIvarList; 2817 2818 case Sema::PCC_Template: 2819 case Sema::PCC_MemberTemplate: 2820 if (S.CurContext->isFileContext()) 2821 return CodeCompletionContext::CCC_TopLevel; 2822 else if (S.CurContext->isRecord()) 2823 return CodeCompletionContext::CCC_ClassStructUnion; 2824 else 2825 return CodeCompletionContext::CCC_Other; 2826 2827 case Sema::PCC_RecoveryInFunction: 2828 return CodeCompletionContext::CCC_Recovery; 2829 2830 case Sema::PCC_ForInit: 2831 if (S.getLangOptions().CPlusPlus || S.getLangOptions().C99 || 2832 S.getLangOptions().ObjC1) 2833 return CodeCompletionContext::CCC_ParenthesizedExpression; 2834 else 2835 return CodeCompletionContext::CCC_Expression; 2836 2837 case Sema::PCC_Expression: 2838 case Sema::PCC_Condition: 2839 return CodeCompletionContext::CCC_Expression; 2840 2841 case Sema::PCC_Statement: 2842 return CodeCompletionContext::CCC_Statement; 2843 2844 case Sema::PCC_Type: 2845 return CodeCompletionContext::CCC_Type; 2846 2847 case Sema::PCC_ParenthesizedExpression: 2848 return CodeCompletionContext::CCC_ParenthesizedExpression; 2849 2850 case Sema::PCC_LocalDeclarationSpecifiers: 2851 return CodeCompletionContext::CCC_Type; 2852 } 2853 2854 return CodeCompletionContext::CCC_Other; 2855 } 2856 2857 /// \brief If we're in a C++ virtual member function, add completion results 2858 /// that invoke the functions we override, since it's common to invoke the 2859 /// overridden function as well as adding new functionality. 2860 /// 2861 /// \param S The semantic analysis object for which we are generating results. 2862 /// 2863 /// \param InContext This context in which the nested-name-specifier preceding 2864 /// the code-completion point 2865 static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext, 2866 ResultBuilder &Results) { 2867 // Look through blocks. 2868 DeclContext *CurContext = S.CurContext; 2869 while (isa<BlockDecl>(CurContext)) 2870 CurContext = CurContext->getParent(); 2871 2872 2873 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext); 2874 if (!Method || !Method->isVirtual()) 2875 return; 2876 2877 // We need to have names for all of the parameters, if we're going to 2878 // generate a forwarding call. 2879 for (CXXMethodDecl::param_iterator P = Method->param_begin(), 2880 PEnd = Method->param_end(); 2881 P != PEnd; 2882 ++P) { 2883 if (!(*P)->getDeclName()) 2884 return; 2885 } 2886 2887 PrintingPolicy Policy = getCompletionPrintingPolicy(S); 2888 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(), 2889 MEnd = Method->end_overridden_methods(); 2890 M != MEnd; ++M) { 2891 CodeCompletionBuilder Builder(Results.getAllocator()); 2892 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M); 2893 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl()) 2894 continue; 2895 2896 // If we need a nested-name-specifier, add one now. 2897 if (!InContext) { 2898 NestedNameSpecifier *NNS 2899 = getRequiredQualification(S.Context, CurContext, 2900 Overridden->getDeclContext()); 2901 if (NNS) { 2902 std::string Str; 2903 llvm::raw_string_ostream OS(Str); 2904 NNS->print(OS, Policy); 2905 Builder.AddTextChunk(Results.getAllocator().CopyString(OS.str())); 2906 } 2907 } else if (!InContext->Equals(Overridden->getDeclContext())) 2908 continue; 2909 2910 Builder.AddTypedTextChunk(Results.getAllocator().CopyString( 2911 Overridden->getNameAsString())); 2912 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 2913 bool FirstParam = true; 2914 for (CXXMethodDecl::param_iterator P = Method->param_begin(), 2915 PEnd = Method->param_end(); 2916 P != PEnd; ++P) { 2917 if (FirstParam) 2918 FirstParam = false; 2919 else 2920 Builder.AddChunk(CodeCompletionString::CK_Comma); 2921 2922 Builder.AddPlaceholderChunk(Results.getAllocator().CopyString( 2923 (*P)->getIdentifier()->getName())); 2924 } 2925 Builder.AddChunk(CodeCompletionString::CK_RightParen); 2926 Results.AddResult(CodeCompletionResult(Builder.TakeString(), 2927 CCP_SuperCompletion, 2928 CXCursor_CXXMethod)); 2929 Results.Ignore(Overridden); 2930 } 2931 } 2932 2933 void Sema::CodeCompleteOrdinaryName(Scope *S, 2934 ParserCompletionContext CompletionContext) { 2935 typedef CodeCompletionResult Result; 2936 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 2937 mapCodeCompletionContext(*this, CompletionContext)); 2938 Results.EnterNewScope(); 2939 2940 // Determine how to filter results, e.g., so that the names of 2941 // values (functions, enumerators, function templates, etc.) are 2942 // only allowed where we can have an expression. 2943 switch (CompletionContext) { 2944 case PCC_Namespace: 2945 case PCC_Class: 2946 case PCC_ObjCInterface: 2947 case PCC_ObjCImplementation: 2948 case PCC_ObjCInstanceVariableList: 2949 case PCC_Template: 2950 case PCC_MemberTemplate: 2951 case PCC_Type: 2952 case PCC_LocalDeclarationSpecifiers: 2953 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName); 2954 break; 2955 2956 case PCC_Statement: 2957 case PCC_ParenthesizedExpression: 2958 case PCC_Expression: 2959 case PCC_ForInit: 2960 case PCC_Condition: 2961 if (WantTypesInContext(CompletionContext, getLangOptions())) 2962 Results.setFilter(&ResultBuilder::IsOrdinaryName); 2963 else 2964 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); 2965 2966 if (getLangOptions().CPlusPlus) 2967 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results); 2968 break; 2969 2970 case PCC_RecoveryInFunction: 2971 // Unfiltered 2972 break; 2973 } 2974 2975 // If we are in a C++ non-static member function, check the qualifiers on 2976 // the member function to filter/prioritize the results list. 2977 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext)) 2978 if (CurMethod->isInstance()) 2979 Results.setObjectTypeQualifiers( 2980 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers())); 2981 2982 CodeCompletionDeclConsumer Consumer(Results, CurContext); 2983 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 2984 CodeCompleter->includeGlobals()); 2985 2986 AddOrdinaryNameResults(CompletionContext, S, *this, Results); 2987 Results.ExitScope(); 2988 2989 switch (CompletionContext) { 2990 case PCC_ParenthesizedExpression: 2991 case PCC_Expression: 2992 case PCC_Statement: 2993 case PCC_RecoveryInFunction: 2994 if (S->getFnParent()) 2995 AddPrettyFunctionResults(PP.getLangOptions(), Results); 2996 break; 2997 2998 case PCC_Namespace: 2999 case PCC_Class: 3000 case PCC_ObjCInterface: 3001 case PCC_ObjCImplementation: 3002 case PCC_ObjCInstanceVariableList: 3003 case PCC_Template: 3004 case PCC_MemberTemplate: 3005 case PCC_ForInit: 3006 case PCC_Condition: 3007 case PCC_Type: 3008 case PCC_LocalDeclarationSpecifiers: 3009 break; 3010 } 3011 3012 if (CodeCompleter->includeMacros()) 3013 AddMacroResults(PP, Results); 3014 3015 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 3016 Results.data(),Results.size()); 3017 } 3018 3019 static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, 3020 ParsedType Receiver, 3021 IdentifierInfo **SelIdents, 3022 unsigned NumSelIdents, 3023 bool AtArgumentExpression, 3024 bool IsSuper, 3025 ResultBuilder &Results); 3026 3027 void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, 3028 bool AllowNonIdentifiers, 3029 bool AllowNestedNameSpecifiers) { 3030 typedef CodeCompletionResult Result; 3031 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3032 AllowNestedNameSpecifiers 3033 ? CodeCompletionContext::CCC_PotentiallyQualifiedName 3034 : CodeCompletionContext::CCC_Name); 3035 Results.EnterNewScope(); 3036 3037 // Type qualifiers can come after names. 3038 Results.AddResult(Result("const")); 3039 Results.AddResult(Result("volatile")); 3040 if (getLangOptions().C99) 3041 Results.AddResult(Result("restrict")); 3042 3043 if (getLangOptions().CPlusPlus) { 3044 if (AllowNonIdentifiers) { 3045 Results.AddResult(Result("operator")); 3046 } 3047 3048 // Add nested-name-specifiers. 3049 if (AllowNestedNameSpecifiers) { 3050 Results.allowNestedNameSpecifiers(); 3051 Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy); 3052 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3053 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer, 3054 CodeCompleter->includeGlobals()); 3055 Results.setFilter(0); 3056 } 3057 } 3058 Results.ExitScope(); 3059 3060 // If we're in a context where we might have an expression (rather than a 3061 // declaration), and what we've seen so far is an Objective-C type that could 3062 // be a receiver of a class message, this may be a class message send with 3063 // the initial opening bracket '[' missing. Add appropriate completions. 3064 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers && 3065 DS.getTypeSpecType() == DeclSpec::TST_typename && 3066 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified && 3067 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() && 3068 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified && 3069 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified && 3070 DS.getTypeQualifiers() == 0 && 3071 S && 3072 (S->getFlags() & Scope::DeclScope) != 0 && 3073 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope | 3074 Scope::FunctionPrototypeScope | 3075 Scope::AtCatchScope)) == 0) { 3076 ParsedType T = DS.getRepAsType(); 3077 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType()) 3078 AddClassMessageCompletions(*this, S, T, 0, 0, false, false, Results); 3079 } 3080 3081 // Note that we intentionally suppress macro results here, since we do not 3082 // encourage using macros to produce the names of entities. 3083 3084 HandleCodeCompleteResults(this, CodeCompleter, 3085 Results.getCompletionContext(), 3086 Results.data(), Results.size()); 3087 } 3088 3089 struct Sema::CodeCompleteExpressionData { 3090 CodeCompleteExpressionData(QualType PreferredType = QualType()) 3091 : PreferredType(PreferredType), IntegralConstantExpression(false), 3092 ObjCCollection(false) { } 3093 3094 QualType PreferredType; 3095 bool IntegralConstantExpression; 3096 bool ObjCCollection; 3097 SmallVector<Decl *, 4> IgnoreDecls; 3098 }; 3099 3100 /// \brief Perform code-completion in an expression context when we know what 3101 /// type we're looking for. 3102 /// 3103 /// \param IntegralConstantExpression Only permit integral constant 3104 /// expressions. 3105 void Sema::CodeCompleteExpression(Scope *S, 3106 const CodeCompleteExpressionData &Data) { 3107 typedef CodeCompletionResult Result; 3108 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3109 CodeCompletionContext::CCC_Expression); 3110 if (Data.ObjCCollection) 3111 Results.setFilter(&ResultBuilder::IsObjCCollection); 3112 else if (Data.IntegralConstantExpression) 3113 Results.setFilter(&ResultBuilder::IsIntegralConstantValue); 3114 else if (WantTypesInContext(PCC_Expression, getLangOptions())) 3115 Results.setFilter(&ResultBuilder::IsOrdinaryName); 3116 else 3117 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); 3118 3119 if (!Data.PreferredType.isNull()) 3120 Results.setPreferredType(Data.PreferredType.getNonReferenceType()); 3121 3122 // Ignore any declarations that we were told that we don't care about. 3123 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I) 3124 Results.Ignore(Data.IgnoreDecls[I]); 3125 3126 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3127 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 3128 CodeCompleter->includeGlobals()); 3129 3130 Results.EnterNewScope(); 3131 AddOrdinaryNameResults(PCC_Expression, S, *this, Results); 3132 Results.ExitScope(); 3133 3134 bool PreferredTypeIsPointer = false; 3135 if (!Data.PreferredType.isNull()) 3136 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType() 3137 || Data.PreferredType->isMemberPointerType() 3138 || Data.PreferredType->isBlockPointerType(); 3139 3140 if (S->getFnParent() && 3141 !Data.ObjCCollection && 3142 !Data.IntegralConstantExpression) 3143 AddPrettyFunctionResults(PP.getLangOptions(), Results); 3144 3145 if (CodeCompleter->includeMacros()) 3146 AddMacroResults(PP, Results, PreferredTypeIsPointer); 3147 HandleCodeCompleteResults(this, CodeCompleter, 3148 CodeCompletionContext(CodeCompletionContext::CCC_Expression, 3149 Data.PreferredType), 3150 Results.data(),Results.size()); 3151 } 3152 3153 void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) { 3154 if (E.isInvalid()) 3155 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction); 3156 else if (getLangOptions().ObjC1) 3157 CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false); 3158 } 3159 3160 /// \brief The set of properties that have already been added, referenced by 3161 /// property name. 3162 typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet; 3163 3164 static void AddObjCProperties(ObjCContainerDecl *Container, 3165 bool AllowCategories, 3166 bool AllowNullaryMethods, 3167 DeclContext *CurContext, 3168 AddedPropertiesSet &AddedProperties, 3169 ResultBuilder &Results) { 3170 typedef CodeCompletionResult Result; 3171 3172 // Add properties in this container. 3173 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(), 3174 PEnd = Container->prop_end(); 3175 P != PEnd; 3176 ++P) { 3177 if (AddedProperties.insert(P->getIdentifier())) 3178 Results.MaybeAddResult(Result(*P, 0), CurContext); 3179 } 3180 3181 // Add nullary methods 3182 if (AllowNullaryMethods) { 3183 ASTContext &Context = Container->getASTContext(); 3184 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema()); 3185 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(), 3186 MEnd = Container->meth_end(); 3187 M != MEnd; ++M) { 3188 if (M->getSelector().isUnarySelector()) 3189 if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0)) 3190 if (AddedProperties.insert(Name)) { 3191 CodeCompletionBuilder Builder(Results.getAllocator()); 3192 AddResultTypeChunk(Context, Policy, *M, Builder); 3193 Builder.AddTypedTextChunk( 3194 Results.getAllocator().CopyString(Name->getName())); 3195 3196 CXAvailabilityKind Availability = CXAvailability_Available; 3197 switch (M->getAvailability()) { 3198 case AR_Available: 3199 case AR_NotYetIntroduced: 3200 Availability = CXAvailability_Available; 3201 break; 3202 3203 case AR_Deprecated: 3204 Availability = CXAvailability_Deprecated; 3205 break; 3206 3207 case AR_Unavailable: 3208 Availability = CXAvailability_NotAvailable; 3209 break; 3210 } 3211 3212 Results.MaybeAddResult(Result(Builder.TakeString(), 3213 CCP_MemberDeclaration + CCD_MethodAsProperty, 3214 M->isInstanceMethod() 3215 ? CXCursor_ObjCInstanceMethodDecl 3216 : CXCursor_ObjCClassMethodDecl, 3217 Availability), 3218 CurContext); 3219 } 3220 } 3221 } 3222 3223 3224 // Add properties in referenced protocols. 3225 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 3226 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(), 3227 PEnd = Protocol->protocol_end(); 3228 P != PEnd; ++P) 3229 AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext, 3230 AddedProperties, Results); 3231 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){ 3232 if (AllowCategories) { 3233 // Look through categories. 3234 for (ObjCCategoryDecl *Category = IFace->getCategoryList(); 3235 Category; Category = Category->getNextClassCategory()) 3236 AddObjCProperties(Category, AllowCategories, AllowNullaryMethods, 3237 CurContext, AddedProperties, Results); 3238 } 3239 3240 // Look through protocols. 3241 for (ObjCInterfaceDecl::all_protocol_iterator 3242 I = IFace->all_referenced_protocol_begin(), 3243 E = IFace->all_referenced_protocol_end(); I != E; ++I) 3244 AddObjCProperties(*I, AllowCategories, AllowNullaryMethods, CurContext, 3245 AddedProperties, Results); 3246 3247 // Look in the superclass. 3248 if (IFace->getSuperClass()) 3249 AddObjCProperties(IFace->getSuperClass(), AllowCategories, 3250 AllowNullaryMethods, CurContext, 3251 AddedProperties, Results); 3252 } else if (const ObjCCategoryDecl *Category 3253 = dyn_cast<ObjCCategoryDecl>(Container)) { 3254 // Look through protocols. 3255 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(), 3256 PEnd = Category->protocol_end(); 3257 P != PEnd; ++P) 3258 AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext, 3259 AddedProperties, Results); 3260 } 3261 } 3262 3263 void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *BaseE, 3264 SourceLocation OpLoc, 3265 bool IsArrow) { 3266 if (!BaseE || !CodeCompleter) 3267 return; 3268 3269 typedef CodeCompletionResult Result; 3270 3271 Expr *Base = static_cast<Expr *>(BaseE); 3272 QualType BaseType = Base->getType(); 3273 3274 if (IsArrow) { 3275 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) 3276 BaseType = Ptr->getPointeeType(); 3277 else if (BaseType->isObjCObjectPointerType()) 3278 /*Do nothing*/ ; 3279 else 3280 return; 3281 } 3282 3283 enum CodeCompletionContext::Kind contextKind; 3284 3285 if (IsArrow) { 3286 contextKind = CodeCompletionContext::CCC_ArrowMemberAccess; 3287 } 3288 else { 3289 if (BaseType->isObjCObjectPointerType() || 3290 BaseType->isObjCObjectOrInterfaceType()) { 3291 contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess; 3292 } 3293 else { 3294 contextKind = CodeCompletionContext::CCC_DotMemberAccess; 3295 } 3296 } 3297 3298 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3299 CodeCompletionContext(contextKind, 3300 BaseType), 3301 &ResultBuilder::IsMember); 3302 Results.EnterNewScope(); 3303 if (const RecordType *Record = BaseType->getAs<RecordType>()) { 3304 // Indicate that we are performing a member access, and the cv-qualifiers 3305 // for the base object type. 3306 Results.setObjectTypeQualifiers(BaseType.getQualifiers()); 3307 3308 // Access to a C/C++ class, struct, or union. 3309 Results.allowNestedNameSpecifiers(); 3310 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3311 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer, 3312 CodeCompleter->includeGlobals()); 3313 3314 if (getLangOptions().CPlusPlus) { 3315 if (!Results.empty()) { 3316 // The "template" keyword can follow "->" or "." in the grammar. 3317 // However, we only want to suggest the template keyword if something 3318 // is dependent. 3319 bool IsDependent = BaseType->isDependentType(); 3320 if (!IsDependent) { 3321 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent()) 3322 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) { 3323 IsDependent = Ctx->isDependentContext(); 3324 break; 3325 } 3326 } 3327 3328 if (IsDependent) 3329 Results.AddResult(Result("template")); 3330 } 3331 } 3332 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) { 3333 // Objective-C property reference. 3334 AddedPropertiesSet AddedProperties; 3335 3336 // Add property results based on our interface. 3337 const ObjCObjectPointerType *ObjCPtr 3338 = BaseType->getAsObjCInterfacePointerType(); 3339 assert(ObjCPtr && "Non-NULL pointer guaranteed above!"); 3340 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, 3341 /*AllowNullaryMethods=*/true, CurContext, 3342 AddedProperties, Results); 3343 3344 // Add properties from the protocols in a qualified interface. 3345 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(), 3346 E = ObjCPtr->qual_end(); 3347 I != E; ++I) 3348 AddObjCProperties(*I, true, /*AllowNullaryMethods=*/true, CurContext, 3349 AddedProperties, Results); 3350 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) || 3351 (!IsArrow && BaseType->isObjCObjectType())) { 3352 // Objective-C instance variable access. 3353 ObjCInterfaceDecl *Class = 0; 3354 if (const ObjCObjectPointerType *ObjCPtr 3355 = BaseType->getAs<ObjCObjectPointerType>()) 3356 Class = ObjCPtr->getInterfaceDecl(); 3357 else 3358 Class = BaseType->getAs<ObjCObjectType>()->getInterface(); 3359 3360 // Add all ivars from this class and its superclasses. 3361 if (Class) { 3362 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3363 Results.setFilter(&ResultBuilder::IsObjCIvar); 3364 LookupVisibleDecls(Class, LookupMemberName, Consumer, 3365 CodeCompleter->includeGlobals()); 3366 } 3367 } 3368 3369 // FIXME: How do we cope with isa? 3370 3371 Results.ExitScope(); 3372 3373 // Hand off the results found for code completion. 3374 HandleCodeCompleteResults(this, CodeCompleter, 3375 Results.getCompletionContext(), 3376 Results.data(),Results.size()); 3377 } 3378 3379 void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { 3380 if (!CodeCompleter) 3381 return; 3382 3383 typedef CodeCompletionResult Result; 3384 ResultBuilder::LookupFilter Filter = 0; 3385 enum CodeCompletionContext::Kind ContextKind 3386 = CodeCompletionContext::CCC_Other; 3387 switch ((DeclSpec::TST)TagSpec) { 3388 case DeclSpec::TST_enum: 3389 Filter = &ResultBuilder::IsEnum; 3390 ContextKind = CodeCompletionContext::CCC_EnumTag; 3391 break; 3392 3393 case DeclSpec::TST_union: 3394 Filter = &ResultBuilder::IsUnion; 3395 ContextKind = CodeCompletionContext::CCC_UnionTag; 3396 break; 3397 3398 case DeclSpec::TST_struct: 3399 case DeclSpec::TST_class: 3400 Filter = &ResultBuilder::IsClassOrStruct; 3401 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag; 3402 break; 3403 3404 default: 3405 llvm_unreachable("Unknown type specifier kind in CodeCompleteTag"); 3406 } 3407 3408 ResultBuilder Results(*this, CodeCompleter->getAllocator(), ContextKind); 3409 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3410 3411 // First pass: look for tags. 3412 Results.setFilter(Filter); 3413 LookupVisibleDecls(S, LookupTagName, Consumer, 3414 CodeCompleter->includeGlobals()); 3415 3416 if (CodeCompleter->includeGlobals()) { 3417 // Second pass: look for nested name specifiers. 3418 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier); 3419 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer); 3420 } 3421 3422 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 3423 Results.data(),Results.size()); 3424 } 3425 3426 void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) { 3427 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3428 CodeCompletionContext::CCC_TypeQualifiers); 3429 Results.EnterNewScope(); 3430 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const)) 3431 Results.AddResult("const"); 3432 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile)) 3433 Results.AddResult("volatile"); 3434 if (getLangOptions().C99 && 3435 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict)) 3436 Results.AddResult("restrict"); 3437 Results.ExitScope(); 3438 HandleCodeCompleteResults(this, CodeCompleter, 3439 Results.getCompletionContext(), 3440 Results.data(), Results.size()); 3441 } 3442 3443 void Sema::CodeCompleteCase(Scope *S) { 3444 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter) 3445 return; 3446 3447 SwitchStmt *Switch = getCurFunction()->SwitchStack.back(); 3448 QualType type = Switch->getCond()->IgnoreImplicit()->getType(); 3449 if (!type->isEnumeralType()) { 3450 CodeCompleteExpressionData Data(type); 3451 Data.IntegralConstantExpression = true; 3452 CodeCompleteExpression(S, Data); 3453 return; 3454 } 3455 3456 // Code-complete the cases of a switch statement over an enumeration type 3457 // by providing the list of 3458 EnumDecl *Enum = type->castAs<EnumType>()->getDecl(); 3459 3460 // Determine which enumerators we have already seen in the switch statement. 3461 // FIXME: Ideally, we would also be able to look *past* the code-completion 3462 // token, in case we are code-completing in the middle of the switch and not 3463 // at the end. However, we aren't able to do so at the moment. 3464 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen; 3465 NestedNameSpecifier *Qualifier = 0; 3466 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC; 3467 SC = SC->getNextSwitchCase()) { 3468 CaseStmt *Case = dyn_cast<CaseStmt>(SC); 3469 if (!Case) 3470 continue; 3471 3472 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts(); 3473 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal)) 3474 if (EnumConstantDecl *Enumerator 3475 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { 3476 // We look into the AST of the case statement to determine which 3477 // enumerator was named. Alternatively, we could compute the value of 3478 // the integral constant expression, then compare it against the 3479 // values of each enumerator. However, value-based approach would not 3480 // work as well with C++ templates where enumerators declared within a 3481 // template are type- and value-dependent. 3482 EnumeratorsSeen.insert(Enumerator); 3483 3484 // If this is a qualified-id, keep track of the nested-name-specifier 3485 // so that we can reproduce it as part of code completion, e.g., 3486 // 3487 // switch (TagD.getKind()) { 3488 // case TagDecl::TK_enum: 3489 // break; 3490 // case XXX 3491 // 3492 // At the XXX, our completions are TagDecl::TK_union, 3493 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union, 3494 // TK_struct, and TK_class. 3495 Qualifier = DRE->getQualifier(); 3496 } 3497 } 3498 3499 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) { 3500 // If there are no prior enumerators in C++, check whether we have to 3501 // qualify the names of the enumerators that we suggest, because they 3502 // may not be visible in this scope. 3503 Qualifier = getRequiredQualification(Context, CurContext, 3504 Enum->getDeclContext()); 3505 3506 // FIXME: Scoped enums need to start with "EnumDecl" as the context! 3507 } 3508 3509 // Add any enumerators that have not yet been mentioned. 3510 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3511 CodeCompletionContext::CCC_Expression); 3512 Results.EnterNewScope(); 3513 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(), 3514 EEnd = Enum->enumerator_end(); 3515 E != EEnd; ++E) { 3516 if (EnumeratorsSeen.count(*E)) 3517 continue; 3518 3519 CodeCompletionResult R(*E, Qualifier); 3520 R.Priority = CCP_EnumInCase; 3521 Results.AddResult(R, CurContext, 0, false); 3522 } 3523 Results.ExitScope(); 3524 3525 //We need to make sure we're setting the right context, 3526 //so only say we include macros if the code completer says we do 3527 enum CodeCompletionContext::Kind kind = CodeCompletionContext::CCC_Other; 3528 if (CodeCompleter->includeMacros()) { 3529 AddMacroResults(PP, Results); 3530 kind = CodeCompletionContext::CCC_OtherWithMacros; 3531 } 3532 3533 3534 HandleCodeCompleteResults(this, CodeCompleter, 3535 kind, 3536 Results.data(),Results.size()); 3537 } 3538 3539 namespace { 3540 struct IsBetterOverloadCandidate { 3541 Sema &S; 3542 SourceLocation Loc; 3543 3544 public: 3545 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc) 3546 : S(S), Loc(Loc) { } 3547 3548 bool 3549 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const { 3550 return isBetterOverloadCandidate(S, X, Y, Loc); 3551 } 3552 }; 3553 } 3554 3555 static bool anyNullArguments(Expr **Args, unsigned NumArgs) { 3556 if (NumArgs && !Args) 3557 return true; 3558 3559 for (unsigned I = 0; I != NumArgs; ++I) 3560 if (!Args[I]) 3561 return true; 3562 3563 return false; 3564 } 3565 3566 void Sema::CodeCompleteCall(Scope *S, Expr *FnIn, 3567 Expr **ArgsIn, unsigned NumArgs) { 3568 if (!CodeCompleter) 3569 return; 3570 3571 // When we're code-completing for a call, we fall back to ordinary 3572 // name code-completion whenever we can't produce specific 3573 // results. We may want to revisit this strategy in the future, 3574 // e.g., by merging the two kinds of results. 3575 3576 Expr *Fn = (Expr *)FnIn; 3577 Expr **Args = (Expr **)ArgsIn; 3578 3579 // Ignore type-dependent call expressions entirely. 3580 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) || 3581 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) { 3582 CodeCompleteOrdinaryName(S, PCC_Expression); 3583 return; 3584 } 3585 3586 // Build an overload candidate set based on the functions we find. 3587 SourceLocation Loc = Fn->getExprLoc(); 3588 OverloadCandidateSet CandidateSet(Loc); 3589 3590 // FIXME: What if we're calling something that isn't a function declaration? 3591 // FIXME: What if we're calling a pseudo-destructor? 3592 // FIXME: What if we're calling a member function? 3593 3594 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate; 3595 SmallVector<ResultCandidate, 8> Results; 3596 3597 Expr *NakedFn = Fn->IgnoreParenCasts(); 3598 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn)) 3599 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet, 3600 /*PartialOverloading=*/ true); 3601 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) { 3602 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl()); 3603 if (FDecl) { 3604 if (!getLangOptions().CPlusPlus || 3605 !FDecl->getType()->getAs<FunctionProtoType>()) 3606 Results.push_back(ResultCandidate(FDecl)); 3607 else 3608 // FIXME: access? 3609 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none), 3610 Args, NumArgs, CandidateSet, 3611 false, /*PartialOverloading*/true); 3612 } 3613 } 3614 3615 QualType ParamType; 3616 3617 if (!CandidateSet.empty()) { 3618 // Sort the overload candidate set by placing the best overloads first. 3619 std::stable_sort(CandidateSet.begin(), CandidateSet.end(), 3620 IsBetterOverloadCandidate(*this, Loc)); 3621 3622 // Add the remaining viable overload candidates as code-completion reslults. 3623 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), 3624 CandEnd = CandidateSet.end(); 3625 Cand != CandEnd; ++Cand) { 3626 if (Cand->Viable) 3627 Results.push_back(ResultCandidate(Cand->Function)); 3628 } 3629 3630 // From the viable candidates, try to determine the type of this parameter. 3631 for (unsigned I = 0, N = Results.size(); I != N; ++I) { 3632 if (const FunctionType *FType = Results[I].getFunctionType()) 3633 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType)) 3634 if (NumArgs < Proto->getNumArgs()) { 3635 if (ParamType.isNull()) 3636 ParamType = Proto->getArgType(NumArgs); 3637 else if (!Context.hasSameUnqualifiedType( 3638 ParamType.getNonReferenceType(), 3639 Proto->getArgType(NumArgs).getNonReferenceType())) { 3640 ParamType = QualType(); 3641 break; 3642 } 3643 } 3644 } 3645 } else { 3646 // Try to determine the parameter type from the type of the expression 3647 // being called. 3648 QualType FunctionType = Fn->getType(); 3649 if (const PointerType *Ptr = FunctionType->getAs<PointerType>()) 3650 FunctionType = Ptr->getPointeeType(); 3651 else if (const BlockPointerType *BlockPtr 3652 = FunctionType->getAs<BlockPointerType>()) 3653 FunctionType = BlockPtr->getPointeeType(); 3654 else if (const MemberPointerType *MemPtr 3655 = FunctionType->getAs<MemberPointerType>()) 3656 FunctionType = MemPtr->getPointeeType(); 3657 3658 if (const FunctionProtoType *Proto 3659 = FunctionType->getAs<FunctionProtoType>()) { 3660 if (NumArgs < Proto->getNumArgs()) 3661 ParamType = Proto->getArgType(NumArgs); 3662 } 3663 } 3664 3665 if (ParamType.isNull()) 3666 CodeCompleteOrdinaryName(S, PCC_Expression); 3667 else 3668 CodeCompleteExpression(S, ParamType); 3669 3670 if (!Results.empty()) 3671 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(), 3672 Results.size()); 3673 } 3674 3675 void Sema::CodeCompleteInitializer(Scope *S, Decl *D) { 3676 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D); 3677 if (!VD) { 3678 CodeCompleteOrdinaryName(S, PCC_Expression); 3679 return; 3680 } 3681 3682 CodeCompleteExpression(S, VD->getType()); 3683 } 3684 3685 void Sema::CodeCompleteReturn(Scope *S) { 3686 QualType ResultType; 3687 if (isa<BlockDecl>(CurContext)) { 3688 if (BlockScopeInfo *BSI = getCurBlock()) 3689 ResultType = BSI->ReturnType; 3690 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext)) 3691 ResultType = Function->getResultType(); 3692 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext)) 3693 ResultType = Method->getResultType(); 3694 3695 if (ResultType.isNull()) 3696 CodeCompleteOrdinaryName(S, PCC_Expression); 3697 else 3698 CodeCompleteExpression(S, ResultType); 3699 } 3700 3701 void Sema::CodeCompleteAfterIf(Scope *S) { 3702 typedef CodeCompletionResult Result; 3703 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3704 mapCodeCompletionContext(*this, PCC_Statement)); 3705 Results.setFilter(&ResultBuilder::IsOrdinaryName); 3706 Results.EnterNewScope(); 3707 3708 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3709 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 3710 CodeCompleter->includeGlobals()); 3711 3712 AddOrdinaryNameResults(PCC_Statement, S, *this, Results); 3713 3714 // "else" block 3715 CodeCompletionBuilder Builder(Results.getAllocator()); 3716 Builder.AddTypedTextChunk("else"); 3717 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 3718 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 3719 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 3720 Builder.AddPlaceholderChunk("statements"); 3721 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 3722 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 3723 Results.AddResult(Builder.TakeString()); 3724 3725 // "else if" block 3726 Builder.AddTypedTextChunk("else"); 3727 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 3728 Builder.AddTextChunk("if"); 3729 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 3730 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 3731 if (getLangOptions().CPlusPlus) 3732 Builder.AddPlaceholderChunk("condition"); 3733 else 3734 Builder.AddPlaceholderChunk("expression"); 3735 Builder.AddChunk(CodeCompletionString::CK_RightParen); 3736 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 3737 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 3738 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 3739 Builder.AddPlaceholderChunk("statements"); 3740 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 3741 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 3742 Results.AddResult(Builder.TakeString()); 3743 3744 Results.ExitScope(); 3745 3746 if (S->getFnParent()) 3747 AddPrettyFunctionResults(PP.getLangOptions(), Results); 3748 3749 if (CodeCompleter->includeMacros()) 3750 AddMacroResults(PP, Results); 3751 3752 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 3753 Results.data(),Results.size()); 3754 } 3755 3756 void Sema::CodeCompleteAssignmentRHS(Scope *S, Expr *LHS) { 3757 if (LHS) 3758 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType()); 3759 else 3760 CodeCompleteOrdinaryName(S, PCC_Expression); 3761 } 3762 3763 void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, 3764 bool EnteringContext) { 3765 if (!SS.getScopeRep() || !CodeCompleter) 3766 return; 3767 3768 DeclContext *Ctx = computeDeclContext(SS, EnteringContext); 3769 if (!Ctx) 3770 return; 3771 3772 // Try to instantiate any non-dependent declaration contexts before 3773 // we look in them. 3774 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx)) 3775 return; 3776 3777 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3778 CodeCompletionContext::CCC_Name); 3779 Results.EnterNewScope(); 3780 3781 // The "template" keyword can follow "::" in the grammar, but only 3782 // put it into the grammar if the nested-name-specifier is dependent. 3783 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep(); 3784 if (!Results.empty() && NNS->isDependent()) 3785 Results.AddResult("template"); 3786 3787 // Add calls to overridden virtual functions, if there are any. 3788 // 3789 // FIXME: This isn't wonderful, because we don't know whether we're actually 3790 // in a context that permits expressions. This is a general issue with 3791 // qualified-id completions. 3792 if (!EnteringContext) 3793 MaybeAddOverrideCalls(*this, Ctx, Results); 3794 Results.ExitScope(); 3795 3796 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3797 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer); 3798 3799 HandleCodeCompleteResults(this, CodeCompleter, 3800 Results.getCompletionContext(), 3801 Results.data(),Results.size()); 3802 } 3803 3804 void Sema::CodeCompleteUsing(Scope *S) { 3805 if (!CodeCompleter) 3806 return; 3807 3808 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3809 CodeCompletionContext::CCC_PotentiallyQualifiedName, 3810 &ResultBuilder::IsNestedNameSpecifier); 3811 Results.EnterNewScope(); 3812 3813 // If we aren't in class scope, we could see the "namespace" keyword. 3814 if (!S->isClassScope()) 3815 Results.AddResult(CodeCompletionResult("namespace")); 3816 3817 // After "using", we can see anything that would start a 3818 // nested-name-specifier. 3819 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3820 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 3821 CodeCompleter->includeGlobals()); 3822 Results.ExitScope(); 3823 3824 HandleCodeCompleteResults(this, CodeCompleter, 3825 CodeCompletionContext::CCC_PotentiallyQualifiedName, 3826 Results.data(),Results.size()); 3827 } 3828 3829 void Sema::CodeCompleteUsingDirective(Scope *S) { 3830 if (!CodeCompleter) 3831 return; 3832 3833 // After "using namespace", we expect to see a namespace name or namespace 3834 // alias. 3835 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3836 CodeCompletionContext::CCC_Namespace, 3837 &ResultBuilder::IsNamespaceOrAlias); 3838 Results.EnterNewScope(); 3839 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3840 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 3841 CodeCompleter->includeGlobals()); 3842 Results.ExitScope(); 3843 HandleCodeCompleteResults(this, CodeCompleter, 3844 CodeCompletionContext::CCC_Namespace, 3845 Results.data(),Results.size()); 3846 } 3847 3848 void Sema::CodeCompleteNamespaceDecl(Scope *S) { 3849 if (!CodeCompleter) 3850 return; 3851 3852 DeclContext *Ctx = (DeclContext *)S->getEntity(); 3853 if (!S->getParent()) 3854 Ctx = Context.getTranslationUnitDecl(); 3855 3856 bool SuppressedGlobalResults 3857 = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx); 3858 3859 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3860 SuppressedGlobalResults 3861 ? CodeCompletionContext::CCC_Namespace 3862 : CodeCompletionContext::CCC_Other, 3863 &ResultBuilder::IsNamespace); 3864 3865 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) { 3866 // We only want to see those namespaces that have already been defined 3867 // within this scope, because its likely that the user is creating an 3868 // extended namespace declaration. Keep track of the most recent 3869 // definition of each namespace. 3870 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest; 3871 for (DeclContext::specific_decl_iterator<NamespaceDecl> 3872 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end()); 3873 NS != NSEnd; ++NS) 3874 OrigToLatest[NS->getOriginalNamespace()] = *NS; 3875 3876 // Add the most recent definition (or extended definition) of each 3877 // namespace to the list of results. 3878 Results.EnterNewScope(); 3879 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator 3880 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end(); 3881 NS != NSEnd; ++NS) 3882 Results.AddResult(CodeCompletionResult(NS->second, 0), 3883 CurContext, 0, false); 3884 Results.ExitScope(); 3885 } 3886 3887 HandleCodeCompleteResults(this, CodeCompleter, 3888 Results.getCompletionContext(), 3889 Results.data(),Results.size()); 3890 } 3891 3892 void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { 3893 if (!CodeCompleter) 3894 return; 3895 3896 // After "namespace", we expect to see a namespace or alias. 3897 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3898 CodeCompletionContext::CCC_Namespace, 3899 &ResultBuilder::IsNamespaceOrAlias); 3900 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3901 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 3902 CodeCompleter->includeGlobals()); 3903 HandleCodeCompleteResults(this, CodeCompleter, 3904 Results.getCompletionContext(), 3905 Results.data(),Results.size()); 3906 } 3907 3908 void Sema::CodeCompleteOperatorName(Scope *S) { 3909 if (!CodeCompleter) 3910 return; 3911 3912 typedef CodeCompletionResult Result; 3913 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3914 CodeCompletionContext::CCC_Type, 3915 &ResultBuilder::IsType); 3916 Results.EnterNewScope(); 3917 3918 // Add the names of overloadable operators. 3919 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 3920 if (std::strcmp(Spelling, "?")) \ 3921 Results.AddResult(Result(Spelling)); 3922 #include "clang/Basic/OperatorKinds.def" 3923 3924 // Add any type names visible from the current scope 3925 Results.allowNestedNameSpecifiers(); 3926 CodeCompletionDeclConsumer Consumer(Results, CurContext); 3927 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 3928 CodeCompleter->includeGlobals()); 3929 3930 // Add any type specifiers 3931 AddTypeSpecifierResults(getLangOptions(), Results); 3932 Results.ExitScope(); 3933 3934 HandleCodeCompleteResults(this, CodeCompleter, 3935 CodeCompletionContext::CCC_Type, 3936 Results.data(),Results.size()); 3937 } 3938 3939 void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD, 3940 CXXCtorInitializer** Initializers, 3941 unsigned NumInitializers) { 3942 PrintingPolicy Policy = getCompletionPrintingPolicy(*this); 3943 CXXConstructorDecl *Constructor 3944 = static_cast<CXXConstructorDecl *>(ConstructorD); 3945 if (!Constructor) 3946 return; 3947 3948 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 3949 CodeCompletionContext::CCC_PotentiallyQualifiedName); 3950 Results.EnterNewScope(); 3951 3952 // Fill in any already-initialized fields or base classes. 3953 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields; 3954 llvm::SmallPtrSet<CanQualType, 4> InitializedBases; 3955 for (unsigned I = 0; I != NumInitializers; ++I) { 3956 if (Initializers[I]->isBaseInitializer()) 3957 InitializedBases.insert( 3958 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0))); 3959 else 3960 InitializedFields.insert(cast<FieldDecl>( 3961 Initializers[I]->getAnyMember())); 3962 } 3963 3964 // Add completions for base classes. 3965 CodeCompletionBuilder Builder(Results.getAllocator()); 3966 bool SawLastInitializer = (NumInitializers == 0); 3967 CXXRecordDecl *ClassDecl = Constructor->getParent(); 3968 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), 3969 BaseEnd = ClassDecl->bases_end(); 3970 Base != BaseEnd; ++Base) { 3971 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) { 3972 SawLastInitializer 3973 = NumInitializers > 0 && 3974 Initializers[NumInitializers - 1]->isBaseInitializer() && 3975 Context.hasSameUnqualifiedType(Base->getType(), 3976 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0)); 3977 continue; 3978 } 3979 3980 Builder.AddTypedTextChunk( 3981 Results.getAllocator().CopyString( 3982 Base->getType().getAsString(Policy))); 3983 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 3984 Builder.AddPlaceholderChunk("args"); 3985 Builder.AddChunk(CodeCompletionString::CK_RightParen); 3986 Results.AddResult(CodeCompletionResult(Builder.TakeString(), 3987 SawLastInitializer? CCP_NextInitializer 3988 : CCP_MemberDeclaration)); 3989 SawLastInitializer = false; 3990 } 3991 3992 // Add completions for virtual base classes. 3993 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), 3994 BaseEnd = ClassDecl->vbases_end(); 3995 Base != BaseEnd; ++Base) { 3996 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) { 3997 SawLastInitializer 3998 = NumInitializers > 0 && 3999 Initializers[NumInitializers - 1]->isBaseInitializer() && 4000 Context.hasSameUnqualifiedType(Base->getType(), 4001 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0)); 4002 continue; 4003 } 4004 4005 Builder.AddTypedTextChunk( 4006 Builder.getAllocator().CopyString( 4007 Base->getType().getAsString(Policy))); 4008 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 4009 Builder.AddPlaceholderChunk("args"); 4010 Builder.AddChunk(CodeCompletionString::CK_RightParen); 4011 Results.AddResult(CodeCompletionResult(Builder.TakeString(), 4012 SawLastInitializer? CCP_NextInitializer 4013 : CCP_MemberDeclaration)); 4014 SawLastInitializer = false; 4015 } 4016 4017 // Add completions for members. 4018 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), 4019 FieldEnd = ClassDecl->field_end(); 4020 Field != FieldEnd; ++Field) { 4021 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) { 4022 SawLastInitializer 4023 = NumInitializers > 0 && 4024 Initializers[NumInitializers - 1]->isAnyMemberInitializer() && 4025 Initializers[NumInitializers - 1]->getAnyMember() == *Field; 4026 continue; 4027 } 4028 4029 if (!Field->getDeclName()) 4030 continue; 4031 4032 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 4033 Field->getIdentifier()->getName())); 4034 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 4035 Builder.AddPlaceholderChunk("args"); 4036 Builder.AddChunk(CodeCompletionString::CK_RightParen); 4037 Results.AddResult(CodeCompletionResult(Builder.TakeString(), 4038 SawLastInitializer? CCP_NextInitializer 4039 : CCP_MemberDeclaration, 4040 CXCursor_MemberRef)); 4041 SawLastInitializer = false; 4042 } 4043 Results.ExitScope(); 4044 4045 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 4046 Results.data(), Results.size()); 4047 } 4048 4049 // Macro that expands to @Keyword or Keyword, depending on whether NeedAt is 4050 // true or false. 4051 #define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword 4052 static void AddObjCImplementationResults(const LangOptions &LangOpts, 4053 ResultBuilder &Results, 4054 bool NeedAt) { 4055 typedef CodeCompletionResult Result; 4056 // Since we have an implementation, we can end it. 4057 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end))); 4058 4059 CodeCompletionBuilder Builder(Results.getAllocator()); 4060 if (LangOpts.ObjC2) { 4061 // @dynamic 4062 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic)); 4063 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4064 Builder.AddPlaceholderChunk("property"); 4065 Results.AddResult(Result(Builder.TakeString())); 4066 4067 // @synthesize 4068 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize)); 4069 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4070 Builder.AddPlaceholderChunk("property"); 4071 Results.AddResult(Result(Builder.TakeString())); 4072 } 4073 } 4074 4075 static void AddObjCInterfaceResults(const LangOptions &LangOpts, 4076 ResultBuilder &Results, 4077 bool NeedAt) { 4078 typedef CodeCompletionResult Result; 4079 4080 // Since we have an interface or protocol, we can end it. 4081 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end))); 4082 4083 if (LangOpts.ObjC2) { 4084 // @property 4085 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property))); 4086 4087 // @required 4088 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required))); 4089 4090 // @optional 4091 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional))); 4092 } 4093 } 4094 4095 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) { 4096 typedef CodeCompletionResult Result; 4097 CodeCompletionBuilder Builder(Results.getAllocator()); 4098 4099 // @class name ; 4100 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class)); 4101 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4102 Builder.AddPlaceholderChunk("name"); 4103 Results.AddResult(Result(Builder.TakeString())); 4104 4105 if (Results.includeCodePatterns()) { 4106 // @interface name 4107 // FIXME: Could introduce the whole pattern, including superclasses and 4108 // such. 4109 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface)); 4110 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4111 Builder.AddPlaceholderChunk("class"); 4112 Results.AddResult(Result(Builder.TakeString())); 4113 4114 // @protocol name 4115 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol)); 4116 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4117 Builder.AddPlaceholderChunk("protocol"); 4118 Results.AddResult(Result(Builder.TakeString())); 4119 4120 // @implementation name 4121 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation)); 4122 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4123 Builder.AddPlaceholderChunk("class"); 4124 Results.AddResult(Result(Builder.TakeString())); 4125 } 4126 4127 // @compatibility_alias name 4128 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias)); 4129 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4130 Builder.AddPlaceholderChunk("alias"); 4131 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4132 Builder.AddPlaceholderChunk("class"); 4133 Results.AddResult(Result(Builder.TakeString())); 4134 } 4135 4136 void Sema::CodeCompleteObjCAtDirective(Scope *S) { 4137 typedef CodeCompletionResult Result; 4138 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 4139 CodeCompletionContext::CCC_Other); 4140 Results.EnterNewScope(); 4141 if (isa<ObjCImplDecl>(CurContext)) 4142 AddObjCImplementationResults(getLangOptions(), Results, false); 4143 else if (CurContext->isObjCContainer()) 4144 AddObjCInterfaceResults(getLangOptions(), Results, false); 4145 else 4146 AddObjCTopLevelResults(Results, false); 4147 Results.ExitScope(); 4148 HandleCodeCompleteResults(this, CodeCompleter, 4149 CodeCompletionContext::CCC_Other, 4150 Results.data(),Results.size()); 4151 } 4152 4153 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) { 4154 typedef CodeCompletionResult Result; 4155 CodeCompletionBuilder Builder(Results.getAllocator()); 4156 4157 // @encode ( type-name ) 4158 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode)); 4159 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 4160 Builder.AddPlaceholderChunk("type-name"); 4161 Builder.AddChunk(CodeCompletionString::CK_RightParen); 4162 Results.AddResult(Result(Builder.TakeString())); 4163 4164 // @protocol ( protocol-name ) 4165 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol)); 4166 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 4167 Builder.AddPlaceholderChunk("protocol-name"); 4168 Builder.AddChunk(CodeCompletionString::CK_RightParen); 4169 Results.AddResult(Result(Builder.TakeString())); 4170 4171 // @selector ( selector ) 4172 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector)); 4173 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 4174 Builder.AddPlaceholderChunk("selector"); 4175 Builder.AddChunk(CodeCompletionString::CK_RightParen); 4176 Results.AddResult(Result(Builder.TakeString())); 4177 } 4178 4179 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) { 4180 typedef CodeCompletionResult Result; 4181 CodeCompletionBuilder Builder(Results.getAllocator()); 4182 4183 if (Results.includeCodePatterns()) { 4184 // @try { statements } @catch ( declaration ) { statements } @finally 4185 // { statements } 4186 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try)); 4187 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 4188 Builder.AddPlaceholderChunk("statements"); 4189 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 4190 Builder.AddTextChunk("@catch"); 4191 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 4192 Builder.AddPlaceholderChunk("parameter"); 4193 Builder.AddChunk(CodeCompletionString::CK_RightParen); 4194 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 4195 Builder.AddPlaceholderChunk("statements"); 4196 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 4197 Builder.AddTextChunk("@finally"); 4198 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 4199 Builder.AddPlaceholderChunk("statements"); 4200 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 4201 Results.AddResult(Result(Builder.TakeString())); 4202 } 4203 4204 // @throw 4205 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw)); 4206 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4207 Builder.AddPlaceholderChunk("expression"); 4208 Results.AddResult(Result(Builder.TakeString())); 4209 4210 if (Results.includeCodePatterns()) { 4211 // @synchronized ( expression ) { statements } 4212 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized)); 4213 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4214 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 4215 Builder.AddPlaceholderChunk("expression"); 4216 Builder.AddChunk(CodeCompletionString::CK_RightParen); 4217 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 4218 Builder.AddPlaceholderChunk("statements"); 4219 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 4220 Results.AddResult(Result(Builder.TakeString())); 4221 } 4222 } 4223 4224 static void AddObjCVisibilityResults(const LangOptions &LangOpts, 4225 ResultBuilder &Results, 4226 bool NeedAt) { 4227 typedef CodeCompletionResult Result; 4228 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private))); 4229 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected))); 4230 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public))); 4231 if (LangOpts.ObjC2) 4232 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package))); 4233 } 4234 4235 void Sema::CodeCompleteObjCAtVisibility(Scope *S) { 4236 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 4237 CodeCompletionContext::CCC_Other); 4238 Results.EnterNewScope(); 4239 AddObjCVisibilityResults(getLangOptions(), Results, false); 4240 Results.ExitScope(); 4241 HandleCodeCompleteResults(this, CodeCompleter, 4242 CodeCompletionContext::CCC_Other, 4243 Results.data(),Results.size()); 4244 } 4245 4246 void Sema::CodeCompleteObjCAtStatement(Scope *S) { 4247 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 4248 CodeCompletionContext::CCC_Other); 4249 Results.EnterNewScope(); 4250 AddObjCStatementResults(Results, false); 4251 AddObjCExpressionResults(Results, false); 4252 Results.ExitScope(); 4253 HandleCodeCompleteResults(this, CodeCompleter, 4254 CodeCompletionContext::CCC_Other, 4255 Results.data(),Results.size()); 4256 } 4257 4258 void Sema::CodeCompleteObjCAtExpression(Scope *S) { 4259 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 4260 CodeCompletionContext::CCC_Other); 4261 Results.EnterNewScope(); 4262 AddObjCExpressionResults(Results, false); 4263 Results.ExitScope(); 4264 HandleCodeCompleteResults(this, CodeCompleter, 4265 CodeCompletionContext::CCC_Other, 4266 Results.data(),Results.size()); 4267 } 4268 4269 /// \brief Determine whether the addition of the given flag to an Objective-C 4270 /// property's attributes will cause a conflict. 4271 static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) { 4272 // Check if we've already added this flag. 4273 if (Attributes & NewFlag) 4274 return true; 4275 4276 Attributes |= NewFlag; 4277 4278 // Check for collisions with "readonly". 4279 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 4280 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 4281 ObjCDeclSpec::DQ_PR_assign | 4282 ObjCDeclSpec::DQ_PR_unsafe_unretained | 4283 ObjCDeclSpec::DQ_PR_copy | 4284 ObjCDeclSpec::DQ_PR_retain | 4285 ObjCDeclSpec::DQ_PR_strong))) 4286 return true; 4287 4288 // Check for more than one of { assign, copy, retain, strong }. 4289 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign | 4290 ObjCDeclSpec::DQ_PR_unsafe_unretained | 4291 ObjCDeclSpec::DQ_PR_copy | 4292 ObjCDeclSpec::DQ_PR_retain| 4293 ObjCDeclSpec::DQ_PR_strong); 4294 if (AssignCopyRetMask && 4295 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign && 4296 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained && 4297 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy && 4298 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain && 4299 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong) 4300 return true; 4301 4302 return false; 4303 } 4304 4305 void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { 4306 if (!CodeCompleter) 4307 return; 4308 4309 unsigned Attributes = ODS.getPropertyAttributes(); 4310 4311 typedef CodeCompletionResult Result; 4312 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 4313 CodeCompletionContext::CCC_Other); 4314 Results.EnterNewScope(); 4315 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly)) 4316 Results.AddResult(CodeCompletionResult("readonly")); 4317 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign)) 4318 Results.AddResult(CodeCompletionResult("assign")); 4319 if (!ObjCPropertyFlagConflicts(Attributes, 4320 ObjCDeclSpec::DQ_PR_unsafe_unretained)) 4321 Results.AddResult(CodeCompletionResult("unsafe_unretained")); 4322 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite)) 4323 Results.AddResult(CodeCompletionResult("readwrite")); 4324 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain)) 4325 Results.AddResult(CodeCompletionResult("retain")); 4326 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_strong)) 4327 Results.AddResult(CodeCompletionResult("strong")); 4328 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy)) 4329 Results.AddResult(CodeCompletionResult("copy")); 4330 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic)) 4331 Results.AddResult(CodeCompletionResult("nonatomic")); 4332 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic)) 4333 Results.AddResult(CodeCompletionResult("atomic")); 4334 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) { 4335 CodeCompletionBuilder Setter(Results.getAllocator()); 4336 Setter.AddTypedTextChunk("setter"); 4337 Setter.AddTextChunk(" = "); 4338 Setter.AddPlaceholderChunk("method"); 4339 Results.AddResult(CodeCompletionResult(Setter.TakeString())); 4340 } 4341 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) { 4342 CodeCompletionBuilder Getter(Results.getAllocator()); 4343 Getter.AddTypedTextChunk("getter"); 4344 Getter.AddTextChunk(" = "); 4345 Getter.AddPlaceholderChunk("method"); 4346 Results.AddResult(CodeCompletionResult(Getter.TakeString())); 4347 } 4348 Results.ExitScope(); 4349 HandleCodeCompleteResults(this, CodeCompleter, 4350 CodeCompletionContext::CCC_Other, 4351 Results.data(),Results.size()); 4352 } 4353 4354 /// \brief Descripts the kind of Objective-C method that we want to find 4355 /// via code completion. 4356 enum ObjCMethodKind { 4357 MK_Any, //< Any kind of method, provided it means other specified criteria. 4358 MK_ZeroArgSelector, //< Zero-argument (unary) selector. 4359 MK_OneArgSelector //< One-argument selector. 4360 }; 4361 4362 static bool isAcceptableObjCSelector(Selector Sel, 4363 ObjCMethodKind WantKind, 4364 IdentifierInfo **SelIdents, 4365 unsigned NumSelIdents, 4366 bool AllowSameLength = true) { 4367 if (NumSelIdents > Sel.getNumArgs()) 4368 return false; 4369 4370 switch (WantKind) { 4371 case MK_Any: break; 4372 case MK_ZeroArgSelector: return Sel.isUnarySelector(); 4373 case MK_OneArgSelector: return Sel.getNumArgs() == 1; 4374 } 4375 4376 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs()) 4377 return false; 4378 4379 for (unsigned I = 0; I != NumSelIdents; ++I) 4380 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I)) 4381 return false; 4382 4383 return true; 4384 } 4385 4386 static bool isAcceptableObjCMethod(ObjCMethodDecl *Method, 4387 ObjCMethodKind WantKind, 4388 IdentifierInfo **SelIdents, 4389 unsigned NumSelIdents, 4390 bool AllowSameLength = true) { 4391 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents, 4392 NumSelIdents, AllowSameLength); 4393 } 4394 4395 namespace { 4396 /// \brief A set of selectors, which is used to avoid introducing multiple 4397 /// completions with the same selector into the result set. 4398 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet; 4399 } 4400 4401 /// \brief Add all of the Objective-C methods in the given Objective-C 4402 /// container to the set of results. 4403 /// 4404 /// The container will be a class, protocol, category, or implementation of 4405 /// any of the above. This mether will recurse to include methods from 4406 /// the superclasses of classes along with their categories, protocols, and 4407 /// implementations. 4408 /// 4409 /// \param Container the container in which we'll look to find methods. 4410 /// 4411 /// \param WantInstance whether to add instance methods (only); if false, this 4412 /// routine will add factory methods (only). 4413 /// 4414 /// \param CurContext the context in which we're performing the lookup that 4415 /// finds methods. 4416 /// 4417 /// \param AllowSameLength Whether we allow a method to be added to the list 4418 /// when it has the same number of parameters as we have selector identifiers. 4419 /// 4420 /// \param Results the structure into which we'll add results. 4421 static void AddObjCMethods(ObjCContainerDecl *Container, 4422 bool WantInstanceMethods, 4423 ObjCMethodKind WantKind, 4424 IdentifierInfo **SelIdents, 4425 unsigned NumSelIdents, 4426 DeclContext *CurContext, 4427 VisitedSelectorSet &Selectors, 4428 bool AllowSameLength, 4429 ResultBuilder &Results, 4430 bool InOriginalClass = true) { 4431 typedef CodeCompletionResult Result; 4432 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(), 4433 MEnd = Container->meth_end(); 4434 M != MEnd; ++M) { 4435 if ((*M)->isInstanceMethod() == WantInstanceMethods) { 4436 // Check whether the selector identifiers we've been given are a 4437 // subset of the identifiers for this particular method. 4438 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents, 4439 AllowSameLength)) 4440 continue; 4441 4442 if (!Selectors.insert((*M)->getSelector())) 4443 continue; 4444 4445 Result R = Result(*M, 0); 4446 R.StartParameter = NumSelIdents; 4447 R.AllParametersAreInformative = (WantKind != MK_Any); 4448 if (!InOriginalClass) 4449 R.Priority += CCD_InBaseClass; 4450 Results.MaybeAddResult(R, CurContext); 4451 } 4452 } 4453 4454 // Visit the protocols of protocols. 4455 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 4456 const ObjCList<ObjCProtocolDecl> &Protocols 4457 = Protocol->getReferencedProtocols(); 4458 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 4459 E = Protocols.end(); 4460 I != E; ++I) 4461 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents, 4462 CurContext, Selectors, AllowSameLength, Results, false); 4463 } 4464 4465 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container); 4466 if (!IFace) 4467 return; 4468 4469 // Add methods in protocols. 4470 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols(); 4471 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 4472 E = Protocols.end(); 4473 I != E; ++I) 4474 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents, 4475 CurContext, Selectors, AllowSameLength, Results, false); 4476 4477 // Add methods in categories. 4478 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl; 4479 CatDecl = CatDecl->getNextClassCategory()) { 4480 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents, 4481 NumSelIdents, CurContext, Selectors, AllowSameLength, 4482 Results, InOriginalClass); 4483 4484 // Add a categories protocol methods. 4485 const ObjCList<ObjCProtocolDecl> &Protocols 4486 = CatDecl->getReferencedProtocols(); 4487 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 4488 E = Protocols.end(); 4489 I != E; ++I) 4490 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 4491 NumSelIdents, CurContext, Selectors, AllowSameLength, 4492 Results, false); 4493 4494 // Add methods in category implementations. 4495 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation()) 4496 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 4497 NumSelIdents, CurContext, Selectors, AllowSameLength, 4498 Results, InOriginalClass); 4499 } 4500 4501 // Add methods in superclass. 4502 if (IFace->getSuperClass()) 4503 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, 4504 SelIdents, NumSelIdents, CurContext, Selectors, 4505 AllowSameLength, Results, false); 4506 4507 // Add methods in our implementation, if any. 4508 if (ObjCImplementationDecl *Impl = IFace->getImplementation()) 4509 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 4510 NumSelIdents, CurContext, Selectors, AllowSameLength, 4511 Results, InOriginalClass); 4512 } 4513 4514 4515 void Sema::CodeCompleteObjCPropertyGetter(Scope *S) { 4516 typedef CodeCompletionResult Result; 4517 4518 // Try to find the interface where getters might live. 4519 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext); 4520 if (!Class) { 4521 if (ObjCCategoryDecl *Category 4522 = dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) 4523 Class = Category->getClassInterface(); 4524 4525 if (!Class) 4526 return; 4527 } 4528 4529 // Find all of the potential getters. 4530 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 4531 CodeCompletionContext::CCC_Other); 4532 Results.EnterNewScope(); 4533 4534 VisitedSelectorSet Selectors; 4535 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors, 4536 /*AllowSameLength=*/true, Results); 4537 Results.ExitScope(); 4538 HandleCodeCompleteResults(this, CodeCompleter, 4539 CodeCompletionContext::CCC_Other, 4540 Results.data(),Results.size()); 4541 } 4542 4543 void Sema::CodeCompleteObjCPropertySetter(Scope *S) { 4544 typedef CodeCompletionResult Result; 4545 4546 // Try to find the interface where setters might live. 4547 ObjCInterfaceDecl *Class 4548 = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext); 4549 if (!Class) { 4550 if (ObjCCategoryDecl *Category 4551 = dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) 4552 Class = Category->getClassInterface(); 4553 4554 if (!Class) 4555 return; 4556 } 4557 4558 // Find all of the potential getters. 4559 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 4560 CodeCompletionContext::CCC_Other); 4561 Results.EnterNewScope(); 4562 4563 VisitedSelectorSet Selectors; 4564 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, 4565 Selectors, /*AllowSameLength=*/true, Results); 4566 4567 Results.ExitScope(); 4568 HandleCodeCompleteResults(this, CodeCompleter, 4569 CodeCompletionContext::CCC_Other, 4570 Results.data(),Results.size()); 4571 } 4572 4573 void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, 4574 bool IsParameter) { 4575 typedef CodeCompletionResult Result; 4576 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 4577 CodeCompletionContext::CCC_Type); 4578 Results.EnterNewScope(); 4579 4580 // Add context-sensitive, Objective-C parameter-passing keywords. 4581 bool AddedInOut = false; 4582 if ((DS.getObjCDeclQualifier() & 4583 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) { 4584 Results.AddResult("in"); 4585 Results.AddResult("inout"); 4586 AddedInOut = true; 4587 } 4588 if ((DS.getObjCDeclQualifier() & 4589 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) { 4590 Results.AddResult("out"); 4591 if (!AddedInOut) 4592 Results.AddResult("inout"); 4593 } 4594 if ((DS.getObjCDeclQualifier() & 4595 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref | 4596 ObjCDeclSpec::DQ_Oneway)) == 0) { 4597 Results.AddResult("bycopy"); 4598 Results.AddResult("byref"); 4599 Results.AddResult("oneway"); 4600 } 4601 4602 // If we're completing the return type of an Objective-C method and the 4603 // identifier IBAction refers to a macro, provide a completion item for 4604 // an action, e.g., 4605 // IBAction)<#selector#>:(id)sender 4606 if (DS.getObjCDeclQualifier() == 0 && !IsParameter && 4607 Context.Idents.get("IBAction").hasMacroDefinition()) { 4608 typedef CodeCompletionString::Chunk Chunk; 4609 CodeCompletionBuilder Builder(Results.getAllocator(), CCP_CodePattern, 4610 CXAvailability_Available); 4611 Builder.AddTypedTextChunk("IBAction"); 4612 Builder.AddChunk(Chunk(CodeCompletionString::CK_RightParen)); 4613 Builder.AddPlaceholderChunk("selector"); 4614 Builder.AddChunk(Chunk(CodeCompletionString::CK_Colon)); 4615 Builder.AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); 4616 Builder.AddTextChunk("id"); 4617 Builder.AddChunk(Chunk(CodeCompletionString::CK_RightParen)); 4618 Builder.AddTextChunk("sender"); 4619 Results.AddResult(CodeCompletionResult(Builder.TakeString())); 4620 } 4621 4622 // Add various builtin type names and specifiers. 4623 AddOrdinaryNameResults(PCC_Type, S, *this, Results); 4624 Results.ExitScope(); 4625 4626 // Add the various type names 4627 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName); 4628 CodeCompletionDeclConsumer Consumer(Results, CurContext); 4629 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 4630 CodeCompleter->includeGlobals()); 4631 4632 if (CodeCompleter->includeMacros()) 4633 AddMacroResults(PP, Results); 4634 4635 HandleCodeCompleteResults(this, CodeCompleter, 4636 CodeCompletionContext::CCC_Type, 4637 Results.data(), Results.size()); 4638 } 4639 4640 /// \brief When we have an expression with type "id", we may assume 4641 /// that it has some more-specific class type based on knowledge of 4642 /// common uses of Objective-C. This routine returns that class type, 4643 /// or NULL if no better result could be determined. 4644 static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) { 4645 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E); 4646 if (!Msg) 4647 return 0; 4648 4649 Selector Sel = Msg->getSelector(); 4650 if (Sel.isNull()) 4651 return 0; 4652 4653 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0); 4654 if (!Id) 4655 return 0; 4656 4657 ObjCMethodDecl *Method = Msg->getMethodDecl(); 4658 if (!Method) 4659 return 0; 4660 4661 // Determine the class that we're sending the message to. 4662 ObjCInterfaceDecl *IFace = 0; 4663 switch (Msg->getReceiverKind()) { 4664 case ObjCMessageExpr::Class: 4665 if (const ObjCObjectType *ObjType 4666 = Msg->getClassReceiver()->getAs<ObjCObjectType>()) 4667 IFace = ObjType->getInterface(); 4668 break; 4669 4670 case ObjCMessageExpr::Instance: { 4671 QualType T = Msg->getInstanceReceiver()->getType(); 4672 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>()) 4673 IFace = Ptr->getInterfaceDecl(); 4674 break; 4675 } 4676 4677 case ObjCMessageExpr::SuperInstance: 4678 case ObjCMessageExpr::SuperClass: 4679 break; 4680 } 4681 4682 if (!IFace) 4683 return 0; 4684 4685 ObjCInterfaceDecl *Super = IFace->getSuperClass(); 4686 if (Method->isInstanceMethod()) 4687 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName()) 4688 .Case("retain", IFace) 4689 .Case("strong", IFace) 4690 .Case("autorelease", IFace) 4691 .Case("copy", IFace) 4692 .Case("copyWithZone", IFace) 4693 .Case("mutableCopy", IFace) 4694 .Case("mutableCopyWithZone", IFace) 4695 .Case("awakeFromCoder", IFace) 4696 .Case("replacementObjectFromCoder", IFace) 4697 .Case("class", IFace) 4698 .Case("classForCoder", IFace) 4699 .Case("superclass", Super) 4700 .Default(0); 4701 4702 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName()) 4703 .Case("new", IFace) 4704 .Case("alloc", IFace) 4705 .Case("allocWithZone", IFace) 4706 .Case("class", IFace) 4707 .Case("superclass", Super) 4708 .Default(0); 4709 } 4710 4711 // Add a special completion for a message send to "super", which fills in the 4712 // most likely case of forwarding all of our arguments to the superclass 4713 // function. 4714 /// 4715 /// \param S The semantic analysis object. 4716 /// 4717 /// \param S NeedSuperKeyword Whether we need to prefix this completion with 4718 /// the "super" keyword. Otherwise, we just need to provide the arguments. 4719 /// 4720 /// \param SelIdents The identifiers in the selector that have already been 4721 /// provided as arguments for a send to "super". 4722 /// 4723 /// \param NumSelIdents The number of identifiers in \p SelIdents. 4724 /// 4725 /// \param Results The set of results to augment. 4726 /// 4727 /// \returns the Objective-C method declaration that would be invoked by 4728 /// this "super" completion. If NULL, no completion was added. 4729 static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword, 4730 IdentifierInfo **SelIdents, 4731 unsigned NumSelIdents, 4732 ResultBuilder &Results) { 4733 ObjCMethodDecl *CurMethod = S.getCurMethodDecl(); 4734 if (!CurMethod) 4735 return 0; 4736 4737 ObjCInterfaceDecl *Class = CurMethod->getClassInterface(); 4738 if (!Class) 4739 return 0; 4740 4741 // Try to find a superclass method with the same selector. 4742 ObjCMethodDecl *SuperMethod = 0; 4743 while ((Class = Class->getSuperClass()) && !SuperMethod) { 4744 // Check in the class 4745 SuperMethod = Class->getMethod(CurMethod->getSelector(), 4746 CurMethod->isInstanceMethod()); 4747 4748 // Check in categories or class extensions. 4749 if (!SuperMethod) { 4750 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category; 4751 Category = Category->getNextClassCategory()) 4752 if ((SuperMethod = Category->getMethod(CurMethod->getSelector(), 4753 CurMethod->isInstanceMethod()))) 4754 break; 4755 } 4756 } 4757 4758 if (!SuperMethod) 4759 return 0; 4760 4761 // Check whether the superclass method has the same signature. 4762 if (CurMethod->param_size() != SuperMethod->param_size() || 4763 CurMethod->isVariadic() != SuperMethod->isVariadic()) 4764 return 0; 4765 4766 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(), 4767 CurPEnd = CurMethod->param_end(), 4768 SuperP = SuperMethod->param_begin(); 4769 CurP != CurPEnd; ++CurP, ++SuperP) { 4770 // Make sure the parameter types are compatible. 4771 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(), 4772 (*SuperP)->getType())) 4773 return 0; 4774 4775 // Make sure we have a parameter name to forward! 4776 if (!(*CurP)->getIdentifier()) 4777 return 0; 4778 } 4779 4780 // We have a superclass method. Now, form the send-to-super completion. 4781 CodeCompletionBuilder Builder(Results.getAllocator()); 4782 4783 // Give this completion a return type. 4784 AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod, 4785 Builder); 4786 4787 // If we need the "super" keyword, add it (plus some spacing). 4788 if (NeedSuperKeyword) { 4789 Builder.AddTypedTextChunk("super"); 4790 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4791 } 4792 4793 Selector Sel = CurMethod->getSelector(); 4794 if (Sel.isUnarySelector()) { 4795 if (NeedSuperKeyword) 4796 Builder.AddTextChunk(Builder.getAllocator().CopyString( 4797 Sel.getNameForSlot(0))); 4798 else 4799 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 4800 Sel.getNameForSlot(0))); 4801 } else { 4802 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(); 4803 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) { 4804 if (I > NumSelIdents) 4805 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 4806 4807 if (I < NumSelIdents) 4808 Builder.AddInformativeChunk( 4809 Builder.getAllocator().CopyString( 4810 Sel.getNameForSlot(I) + ":")); 4811 else if (NeedSuperKeyword || I > NumSelIdents) { 4812 Builder.AddTextChunk( 4813 Builder.getAllocator().CopyString( 4814 Sel.getNameForSlot(I) + ":")); 4815 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString( 4816 (*CurP)->getIdentifier()->getName())); 4817 } else { 4818 Builder.AddTypedTextChunk( 4819 Builder.getAllocator().CopyString( 4820 Sel.getNameForSlot(I) + ":")); 4821 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString( 4822 (*CurP)->getIdentifier()->getName())); 4823 } 4824 } 4825 } 4826 4827 Results.AddResult(CodeCompletionResult(Builder.TakeString(), CCP_SuperCompletion, 4828 SuperMethod->isInstanceMethod() 4829 ? CXCursor_ObjCInstanceMethodDecl 4830 : CXCursor_ObjCClassMethodDecl)); 4831 return SuperMethod; 4832 } 4833 4834 void Sema::CodeCompleteObjCMessageReceiver(Scope *S) { 4835 typedef CodeCompletionResult Result; 4836 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 4837 CodeCompletionContext::CCC_ObjCMessageReceiver, 4838 &ResultBuilder::IsObjCMessageReceiver); 4839 4840 CodeCompletionDeclConsumer Consumer(Results, CurContext); 4841 Results.EnterNewScope(); 4842 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 4843 CodeCompleter->includeGlobals()); 4844 4845 // If we are in an Objective-C method inside a class that has a superclass, 4846 // add "super" as an option. 4847 if (ObjCMethodDecl *Method = getCurMethodDecl()) 4848 if (ObjCInterfaceDecl *Iface = Method->getClassInterface()) 4849 if (Iface->getSuperClass()) { 4850 Results.AddResult(Result("super")); 4851 4852 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results); 4853 } 4854 4855 Results.ExitScope(); 4856 4857 if (CodeCompleter->includeMacros()) 4858 AddMacroResults(PP, Results); 4859 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 4860 Results.data(), Results.size()); 4861 4862 } 4863 4864 void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, 4865 IdentifierInfo **SelIdents, 4866 unsigned NumSelIdents, 4867 bool AtArgumentExpression) { 4868 ObjCInterfaceDecl *CDecl = 0; 4869 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) { 4870 // Figure out which interface we're in. 4871 CDecl = CurMethod->getClassInterface(); 4872 if (!CDecl) 4873 return; 4874 4875 // Find the superclass of this class. 4876 CDecl = CDecl->getSuperClass(); 4877 if (!CDecl) 4878 return; 4879 4880 if (CurMethod->isInstanceMethod()) { 4881 // We are inside an instance method, which means that the message 4882 // send [super ...] is actually calling an instance method on the 4883 // current object. 4884 return CodeCompleteObjCInstanceMessage(S, 0, 4885 SelIdents, NumSelIdents, 4886 AtArgumentExpression, 4887 CDecl); 4888 } 4889 4890 // Fall through to send to the superclass in CDecl. 4891 } else { 4892 // "super" may be the name of a type or variable. Figure out which 4893 // it is. 4894 IdentifierInfo *Super = &Context.Idents.get("super"); 4895 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc, 4896 LookupOrdinaryName); 4897 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) { 4898 // "super" names an interface. Use it. 4899 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) { 4900 if (const ObjCObjectType *Iface 4901 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>()) 4902 CDecl = Iface->getInterface(); 4903 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) { 4904 // "super" names an unresolved type; we can't be more specific. 4905 } else { 4906 // Assume that "super" names some kind of value and parse that way. 4907 CXXScopeSpec SS; 4908 UnqualifiedId id; 4909 id.setIdentifier(Super, SuperLoc); 4910 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false); 4911 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(), 4912 SelIdents, NumSelIdents, 4913 AtArgumentExpression); 4914 } 4915 4916 // Fall through 4917 } 4918 4919 ParsedType Receiver; 4920 if (CDecl) 4921 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl)); 4922 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents, 4923 NumSelIdents, AtArgumentExpression, 4924 /*IsSuper=*/true); 4925 } 4926 4927 /// \brief Given a set of code-completion results for the argument of a message 4928 /// send, determine the preferred type (if any) for that argument expression. 4929 static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results, 4930 unsigned NumSelIdents) { 4931 typedef CodeCompletionResult Result; 4932 ASTContext &Context = Results.getSema().Context; 4933 4934 QualType PreferredType; 4935 unsigned BestPriority = CCP_Unlikely * 2; 4936 Result *ResultsData = Results.data(); 4937 for (unsigned I = 0, N = Results.size(); I != N; ++I) { 4938 Result &R = ResultsData[I]; 4939 if (R.Kind == Result::RK_Declaration && 4940 isa<ObjCMethodDecl>(R.Declaration)) { 4941 if (R.Priority <= BestPriority) { 4942 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration); 4943 if (NumSelIdents <= Method->param_size()) { 4944 QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1] 4945 ->getType(); 4946 if (R.Priority < BestPriority || PreferredType.isNull()) { 4947 BestPriority = R.Priority; 4948 PreferredType = MyPreferredType; 4949 } else if (!Context.hasSameUnqualifiedType(PreferredType, 4950 MyPreferredType)) { 4951 PreferredType = QualType(); 4952 } 4953 } 4954 } 4955 } 4956 } 4957 4958 return PreferredType; 4959 } 4960 4961 static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, 4962 ParsedType Receiver, 4963 IdentifierInfo **SelIdents, 4964 unsigned NumSelIdents, 4965 bool AtArgumentExpression, 4966 bool IsSuper, 4967 ResultBuilder &Results) { 4968 typedef CodeCompletionResult Result; 4969 ObjCInterfaceDecl *CDecl = 0; 4970 4971 // If the given name refers to an interface type, retrieve the 4972 // corresponding declaration. 4973 if (Receiver) { 4974 QualType T = SemaRef.GetTypeFromParser(Receiver, 0); 4975 if (!T.isNull()) 4976 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>()) 4977 CDecl = Interface->getInterface(); 4978 } 4979 4980 // Add all of the factory methods in this Objective-C class, its protocols, 4981 // superclasses, categories, implementation, etc. 4982 Results.EnterNewScope(); 4983 4984 // If this is a send-to-super, try to add the special "super" send 4985 // completion. 4986 if (IsSuper) { 4987 if (ObjCMethodDecl *SuperMethod 4988 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents, 4989 Results)) 4990 Results.Ignore(SuperMethod); 4991 } 4992 4993 // If we're inside an Objective-C method definition, prefer its selector to 4994 // others. 4995 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl()) 4996 Results.setPreferredSelector(CurMethod->getSelector()); 4997 4998 VisitedSelectorSet Selectors; 4999 if (CDecl) 5000 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, 5001 SemaRef.CurContext, Selectors, AtArgumentExpression, 5002 Results); 5003 else { 5004 // We're messaging "id" as a type; provide all class/factory methods. 5005 5006 // If we have an external source, load the entire class method 5007 // pool from the AST file. 5008 if (SemaRef.ExternalSource) { 5009 for (uint32_t I = 0, 5010 N = SemaRef.ExternalSource->GetNumExternalSelectors(); 5011 I != N; ++I) { 5012 Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I); 5013 if (Sel.isNull() || SemaRef.MethodPool.count(Sel)) 5014 continue; 5015 5016 SemaRef.ReadMethodPool(Sel); 5017 } 5018 } 5019 5020 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(), 5021 MEnd = SemaRef.MethodPool.end(); 5022 M != MEnd; ++M) { 5023 for (ObjCMethodList *MethList = &M->second.second; 5024 MethList && MethList->Method; 5025 MethList = MethList->Next) { 5026 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 5027 NumSelIdents)) 5028 continue; 5029 5030 Result R(MethList->Method, 0); 5031 R.StartParameter = NumSelIdents; 5032 R.AllParametersAreInformative = false; 5033 Results.MaybeAddResult(R, SemaRef.CurContext); 5034 } 5035 } 5036 } 5037 5038 Results.ExitScope(); 5039 } 5040 5041 void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, 5042 IdentifierInfo **SelIdents, 5043 unsigned NumSelIdents, 5044 bool AtArgumentExpression, 5045 bool IsSuper) { 5046 5047 QualType T = this->GetTypeFromParser(Receiver); 5048 5049 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5050 CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage, 5051 T, SelIdents, NumSelIdents)); 5052 5053 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents, 5054 AtArgumentExpression, IsSuper, Results); 5055 5056 // If we're actually at the argument expression (rather than prior to the 5057 // selector), we're actually performing code completion for an expression. 5058 // Determine whether we have a single, best method. If so, we can 5059 // code-complete the expression using the corresponding parameter type as 5060 // our preferred type, improving completion results. 5061 if (AtArgumentExpression) { 5062 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results, 5063 NumSelIdents); 5064 if (PreferredType.isNull()) 5065 CodeCompleteOrdinaryName(S, PCC_Expression); 5066 else 5067 CodeCompleteExpression(S, PreferredType); 5068 return; 5069 } 5070 5071 HandleCodeCompleteResults(this, CodeCompleter, 5072 Results.getCompletionContext(), 5073 Results.data(), Results.size()); 5074 } 5075 5076 void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, 5077 IdentifierInfo **SelIdents, 5078 unsigned NumSelIdents, 5079 bool AtArgumentExpression, 5080 ObjCInterfaceDecl *Super) { 5081 typedef CodeCompletionResult Result; 5082 5083 Expr *RecExpr = static_cast<Expr *>(Receiver); 5084 5085 // If necessary, apply function/array conversion to the receiver. 5086 // C99 6.7.5.3p[7,8]. 5087 if (RecExpr) { 5088 ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr); 5089 if (Conv.isInvalid()) // conversion failed. bail. 5090 return; 5091 RecExpr = Conv.take(); 5092 } 5093 QualType ReceiverType = RecExpr? RecExpr->getType() 5094 : Super? Context.getObjCObjectPointerType( 5095 Context.getObjCInterfaceType(Super)) 5096 : Context.getObjCIdType(); 5097 5098 // If we're messaging an expression with type "id" or "Class", check 5099 // whether we know something special about the receiver that allows 5100 // us to assume a more-specific receiver type. 5101 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) 5102 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) { 5103 if (ReceiverType->isObjCClassType()) 5104 return CodeCompleteObjCClassMessage(S, 5105 ParsedType::make(Context.getObjCInterfaceType(IFace)), 5106 SelIdents, NumSelIdents, 5107 AtArgumentExpression, Super); 5108 5109 ReceiverType = Context.getObjCObjectPointerType( 5110 Context.getObjCInterfaceType(IFace)); 5111 } 5112 5113 // Build the set of methods we can see. 5114 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5115 CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage, 5116 ReceiverType, SelIdents, NumSelIdents)); 5117 5118 Results.EnterNewScope(); 5119 5120 // If this is a send-to-super, try to add the special "super" send 5121 // completion. 5122 if (Super) { 5123 if (ObjCMethodDecl *SuperMethod 5124 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents, 5125 Results)) 5126 Results.Ignore(SuperMethod); 5127 } 5128 5129 // If we're inside an Objective-C method definition, prefer its selector to 5130 // others. 5131 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) 5132 Results.setPreferredSelector(CurMethod->getSelector()); 5133 5134 // Keep track of the selectors we've already added. 5135 VisitedSelectorSet Selectors; 5136 5137 // Handle messages to Class. This really isn't a message to an instance 5138 // method, so we treat it the same way we would treat a message send to a 5139 // class method. 5140 if (ReceiverType->isObjCClassType() || 5141 ReceiverType->isObjCQualifiedClassType()) { 5142 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) { 5143 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface()) 5144 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents, 5145 CurContext, Selectors, AtArgumentExpression, Results); 5146 } 5147 } 5148 // Handle messages to a qualified ID ("id<foo>"). 5149 else if (const ObjCObjectPointerType *QualID 5150 = ReceiverType->getAsObjCQualifiedIdType()) { 5151 // Search protocols for instance methods. 5152 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(), 5153 E = QualID->qual_end(); 5154 I != E; ++I) 5155 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext, 5156 Selectors, AtArgumentExpression, Results); 5157 } 5158 // Handle messages to a pointer to interface type. 5159 else if (const ObjCObjectPointerType *IFacePtr 5160 = ReceiverType->getAsObjCInterfacePointerType()) { 5161 // Search the class, its superclasses, etc., for instance methods. 5162 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents, 5163 NumSelIdents, CurContext, Selectors, AtArgumentExpression, 5164 Results); 5165 5166 // Search protocols for instance methods. 5167 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(), 5168 E = IFacePtr->qual_end(); 5169 I != E; ++I) 5170 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext, 5171 Selectors, AtArgumentExpression, Results); 5172 } 5173 // Handle messages to "id". 5174 else if (ReceiverType->isObjCIdType()) { 5175 // We're messaging "id", so provide all instance methods we know 5176 // about as code-completion results. 5177 5178 // If we have an external source, load the entire class method 5179 // pool from the AST file. 5180 if (ExternalSource) { 5181 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); 5182 I != N; ++I) { 5183 Selector Sel = ExternalSource->GetExternalSelector(I); 5184 if (Sel.isNull() || MethodPool.count(Sel)) 5185 continue; 5186 5187 ReadMethodPool(Sel); 5188 } 5189 } 5190 5191 for (GlobalMethodPool::iterator M = MethodPool.begin(), 5192 MEnd = MethodPool.end(); 5193 M != MEnd; ++M) { 5194 for (ObjCMethodList *MethList = &M->second.first; 5195 MethList && MethList->Method; 5196 MethList = MethList->Next) { 5197 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 5198 NumSelIdents)) 5199 continue; 5200 5201 if (!Selectors.insert(MethList->Method->getSelector())) 5202 continue; 5203 5204 Result R(MethList->Method, 0); 5205 R.StartParameter = NumSelIdents; 5206 R.AllParametersAreInformative = false; 5207 Results.MaybeAddResult(R, CurContext); 5208 } 5209 } 5210 } 5211 Results.ExitScope(); 5212 5213 5214 // If we're actually at the argument expression (rather than prior to the 5215 // selector), we're actually performing code completion for an expression. 5216 // Determine whether we have a single, best method. If so, we can 5217 // code-complete the expression using the corresponding parameter type as 5218 // our preferred type, improving completion results. 5219 if (AtArgumentExpression) { 5220 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results, 5221 NumSelIdents); 5222 if (PreferredType.isNull()) 5223 CodeCompleteOrdinaryName(S, PCC_Expression); 5224 else 5225 CodeCompleteExpression(S, PreferredType); 5226 return; 5227 } 5228 5229 HandleCodeCompleteResults(this, CodeCompleter, 5230 Results.getCompletionContext(), 5231 Results.data(),Results.size()); 5232 } 5233 5234 void Sema::CodeCompleteObjCForCollection(Scope *S, 5235 DeclGroupPtrTy IterationVar) { 5236 CodeCompleteExpressionData Data; 5237 Data.ObjCCollection = true; 5238 5239 if (IterationVar.getAsOpaquePtr()) { 5240 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>(); 5241 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) { 5242 if (*I) 5243 Data.IgnoreDecls.push_back(*I); 5244 } 5245 } 5246 5247 CodeCompleteExpression(S, Data); 5248 } 5249 5250 void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents, 5251 unsigned NumSelIdents) { 5252 // If we have an external source, load the entire class method 5253 // pool from the AST file. 5254 if (ExternalSource) { 5255 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); 5256 I != N; ++I) { 5257 Selector Sel = ExternalSource->GetExternalSelector(I); 5258 if (Sel.isNull() || MethodPool.count(Sel)) 5259 continue; 5260 5261 ReadMethodPool(Sel); 5262 } 5263 } 5264 5265 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5266 CodeCompletionContext::CCC_SelectorName); 5267 Results.EnterNewScope(); 5268 for (GlobalMethodPool::iterator M = MethodPool.begin(), 5269 MEnd = MethodPool.end(); 5270 M != MEnd; ++M) { 5271 5272 Selector Sel = M->first; 5273 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents)) 5274 continue; 5275 5276 CodeCompletionBuilder Builder(Results.getAllocator()); 5277 if (Sel.isUnarySelector()) { 5278 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 5279 Sel.getNameForSlot(0))); 5280 Results.AddResult(Builder.TakeString()); 5281 continue; 5282 } 5283 5284 std::string Accumulator; 5285 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) { 5286 if (I == NumSelIdents) { 5287 if (!Accumulator.empty()) { 5288 Builder.AddInformativeChunk(Builder.getAllocator().CopyString( 5289 Accumulator)); 5290 Accumulator.clear(); 5291 } 5292 } 5293 5294 Accumulator += Sel.getNameForSlot(I); 5295 Accumulator += ':'; 5296 } 5297 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( Accumulator)); 5298 Results.AddResult(Builder.TakeString()); 5299 } 5300 Results.ExitScope(); 5301 5302 HandleCodeCompleteResults(this, CodeCompleter, 5303 CodeCompletionContext::CCC_SelectorName, 5304 Results.data(), Results.size()); 5305 } 5306 5307 /// \brief Add all of the protocol declarations that we find in the given 5308 /// (translation unit) context. 5309 static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext, 5310 bool OnlyForwardDeclarations, 5311 ResultBuilder &Results) { 5312 typedef CodeCompletionResult Result; 5313 5314 for (DeclContext::decl_iterator D = Ctx->decls_begin(), 5315 DEnd = Ctx->decls_end(); 5316 D != DEnd; ++D) { 5317 // Record any protocols we find. 5318 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D)) 5319 if (!OnlyForwardDeclarations || Proto->isForwardDecl()) 5320 Results.AddResult(Result(Proto, 0), CurContext, 0, false); 5321 5322 // Record any forward-declared protocols we find. 5323 if (ObjCForwardProtocolDecl *Forward 5324 = dyn_cast<ObjCForwardProtocolDecl>(*D)) { 5325 for (ObjCForwardProtocolDecl::protocol_iterator 5326 P = Forward->protocol_begin(), 5327 PEnd = Forward->protocol_end(); 5328 P != PEnd; ++P) 5329 if (!OnlyForwardDeclarations || (*P)->isForwardDecl()) 5330 Results.AddResult(Result(*P, 0), CurContext, 0, false); 5331 } 5332 } 5333 } 5334 5335 void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols, 5336 unsigned NumProtocols) { 5337 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5338 CodeCompletionContext::CCC_ObjCProtocolName); 5339 5340 if (CodeCompleter && CodeCompleter->includeGlobals()) { 5341 Results.EnterNewScope(); 5342 5343 // Tell the result set to ignore all of the protocols we have 5344 // already seen. 5345 // FIXME: This doesn't work when caching code-completion results. 5346 for (unsigned I = 0; I != NumProtocols; ++I) 5347 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first, 5348 Protocols[I].second)) 5349 Results.Ignore(Protocol); 5350 5351 // Add all protocols. 5352 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false, 5353 Results); 5354 5355 Results.ExitScope(); 5356 } 5357 5358 HandleCodeCompleteResults(this, CodeCompleter, 5359 CodeCompletionContext::CCC_ObjCProtocolName, 5360 Results.data(),Results.size()); 5361 } 5362 5363 void Sema::CodeCompleteObjCProtocolDecl(Scope *) { 5364 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5365 CodeCompletionContext::CCC_ObjCProtocolName); 5366 5367 if (CodeCompleter && CodeCompleter->includeGlobals()) { 5368 Results.EnterNewScope(); 5369 5370 // Add all protocols. 5371 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true, 5372 Results); 5373 5374 Results.ExitScope(); 5375 } 5376 5377 HandleCodeCompleteResults(this, CodeCompleter, 5378 CodeCompletionContext::CCC_ObjCProtocolName, 5379 Results.data(),Results.size()); 5380 } 5381 5382 /// \brief Add all of the Objective-C interface declarations that we find in 5383 /// the given (translation unit) context. 5384 static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext, 5385 bool OnlyForwardDeclarations, 5386 bool OnlyUnimplemented, 5387 ResultBuilder &Results) { 5388 typedef CodeCompletionResult Result; 5389 5390 for (DeclContext::decl_iterator D = Ctx->decls_begin(), 5391 DEnd = Ctx->decls_end(); 5392 D != DEnd; ++D) { 5393 // Record any interfaces we find. 5394 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D)) 5395 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) && 5396 (!OnlyUnimplemented || !Class->getImplementation())) 5397 Results.AddResult(Result(Class, 0), CurContext, 0, false); 5398 5399 // Record any forward-declared interfaces we find. 5400 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) { 5401 ObjCInterfaceDecl *IDecl = Forward->getForwardInterfaceDecl(); 5402 if ((!OnlyForwardDeclarations || IDecl->isForwardDecl()) && 5403 (!OnlyUnimplemented || !IDecl->getImplementation())) 5404 Results.AddResult(Result(IDecl, 0), CurContext, 5405 0, false); 5406 } 5407 } 5408 } 5409 5410 void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { 5411 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5412 CodeCompletionContext::CCC_Other); 5413 Results.EnterNewScope(); 5414 5415 if (CodeCompleter->includeGlobals()) { 5416 // Add all classes. 5417 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false, 5418 false, Results); 5419 } 5420 5421 Results.ExitScope(); 5422 5423 HandleCodeCompleteResults(this, CodeCompleter, 5424 CodeCompletionContext::CCC_ObjCInterfaceName, 5425 Results.data(),Results.size()); 5426 } 5427 5428 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, 5429 SourceLocation ClassNameLoc) { 5430 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5431 CodeCompletionContext::CCC_ObjCInterfaceName); 5432 Results.EnterNewScope(); 5433 5434 // Make sure that we ignore the class we're currently defining. 5435 NamedDecl *CurClass 5436 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); 5437 if (CurClass && isa<ObjCInterfaceDecl>(CurClass)) 5438 Results.Ignore(CurClass); 5439 5440 if (CodeCompleter->includeGlobals()) { 5441 // Add all classes. 5442 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false, 5443 false, Results); 5444 } 5445 5446 Results.ExitScope(); 5447 5448 HandleCodeCompleteResults(this, CodeCompleter, 5449 CodeCompletionContext::CCC_ObjCInterfaceName, 5450 Results.data(),Results.size()); 5451 } 5452 5453 void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { 5454 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5455 CodeCompletionContext::CCC_Other); 5456 Results.EnterNewScope(); 5457 5458 if (CodeCompleter->includeGlobals()) { 5459 // Add all unimplemented classes. 5460 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false, 5461 true, Results); 5462 } 5463 5464 Results.ExitScope(); 5465 5466 HandleCodeCompleteResults(this, CodeCompleter, 5467 CodeCompletionContext::CCC_ObjCInterfaceName, 5468 Results.data(),Results.size()); 5469 } 5470 5471 void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, 5472 IdentifierInfo *ClassName, 5473 SourceLocation ClassNameLoc) { 5474 typedef CodeCompletionResult Result; 5475 5476 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5477 CodeCompletionContext::CCC_ObjCCategoryName); 5478 5479 // Ignore any categories we find that have already been implemented by this 5480 // interface. 5481 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames; 5482 NamedDecl *CurClass 5483 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); 5484 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)) 5485 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category; 5486 Category = Category->getNextClassCategory()) 5487 CategoryNames.insert(Category->getIdentifier()); 5488 5489 // Add all of the categories we know about. 5490 Results.EnterNewScope(); 5491 TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); 5492 for (DeclContext::decl_iterator D = TU->decls_begin(), 5493 DEnd = TU->decls_end(); 5494 D != DEnd; ++D) 5495 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D)) 5496 if (CategoryNames.insert(Category->getIdentifier())) 5497 Results.AddResult(Result(Category, 0), CurContext, 0, false); 5498 Results.ExitScope(); 5499 5500 HandleCodeCompleteResults(this, CodeCompleter, 5501 CodeCompletionContext::CCC_ObjCCategoryName, 5502 Results.data(),Results.size()); 5503 } 5504 5505 void Sema::CodeCompleteObjCImplementationCategory(Scope *S, 5506 IdentifierInfo *ClassName, 5507 SourceLocation ClassNameLoc) { 5508 typedef CodeCompletionResult Result; 5509 5510 // Find the corresponding interface. If we couldn't find the interface, the 5511 // program itself is ill-formed. However, we'll try to be helpful still by 5512 // providing the list of all of the categories we know about. 5513 NamedDecl *CurClass 5514 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); 5515 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass); 5516 if (!Class) 5517 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc); 5518 5519 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5520 CodeCompletionContext::CCC_ObjCCategoryName); 5521 5522 // Add all of the categories that have have corresponding interface 5523 // declarations in this class and any of its superclasses, except for 5524 // already-implemented categories in the class itself. 5525 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames; 5526 Results.EnterNewScope(); 5527 bool IgnoreImplemented = true; 5528 while (Class) { 5529 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category; 5530 Category = Category->getNextClassCategory()) 5531 if ((!IgnoreImplemented || !Category->getImplementation()) && 5532 CategoryNames.insert(Category->getIdentifier())) 5533 Results.AddResult(Result(Category, 0), CurContext, 0, false); 5534 5535 Class = Class->getSuperClass(); 5536 IgnoreImplemented = false; 5537 } 5538 Results.ExitScope(); 5539 5540 HandleCodeCompleteResults(this, CodeCompleter, 5541 CodeCompletionContext::CCC_ObjCCategoryName, 5542 Results.data(),Results.size()); 5543 } 5544 5545 void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) { 5546 typedef CodeCompletionResult Result; 5547 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5548 CodeCompletionContext::CCC_Other); 5549 5550 // Figure out where this @synthesize lives. 5551 ObjCContainerDecl *Container 5552 = dyn_cast_or_null<ObjCContainerDecl>(CurContext); 5553 if (!Container || 5554 (!isa<ObjCImplementationDecl>(Container) && 5555 !isa<ObjCCategoryImplDecl>(Container))) 5556 return; 5557 5558 // Ignore any properties that have already been implemented. 5559 for (DeclContext::decl_iterator D = Container->decls_begin(), 5560 DEnd = Container->decls_end(); 5561 D != DEnd; ++D) 5562 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D)) 5563 Results.Ignore(PropertyImpl->getPropertyDecl()); 5564 5565 // Add any properties that we find. 5566 AddedPropertiesSet AddedProperties; 5567 Results.EnterNewScope(); 5568 if (ObjCImplementationDecl *ClassImpl 5569 = dyn_cast<ObjCImplementationDecl>(Container)) 5570 AddObjCProperties(ClassImpl->getClassInterface(), false, 5571 /*AllowNullaryMethods=*/false, CurContext, 5572 AddedProperties, Results); 5573 else 5574 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(), 5575 false, /*AllowNullaryMethods=*/false, CurContext, 5576 AddedProperties, Results); 5577 Results.ExitScope(); 5578 5579 HandleCodeCompleteResults(this, CodeCompleter, 5580 CodeCompletionContext::CCC_Other, 5581 Results.data(),Results.size()); 5582 } 5583 5584 void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 5585 IdentifierInfo *PropertyName) { 5586 typedef CodeCompletionResult Result; 5587 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 5588 CodeCompletionContext::CCC_Other); 5589 5590 // Figure out where this @synthesize lives. 5591 ObjCContainerDecl *Container 5592 = dyn_cast_or_null<ObjCContainerDecl>(CurContext); 5593 if (!Container || 5594 (!isa<ObjCImplementationDecl>(Container) && 5595 !isa<ObjCCategoryImplDecl>(Container))) 5596 return; 5597 5598 // Figure out which interface we're looking into. 5599 ObjCInterfaceDecl *Class = 0; 5600 if (ObjCImplementationDecl *ClassImpl 5601 = dyn_cast<ObjCImplementationDecl>(Container)) 5602 Class = ClassImpl->getClassInterface(); 5603 else 5604 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl() 5605 ->getClassInterface(); 5606 5607 // Determine the type of the property we're synthesizing. 5608 QualType PropertyType = Context.getObjCIdType(); 5609 if (Class) { 5610 if (ObjCPropertyDecl *Property 5611 = Class->FindPropertyDeclaration(PropertyName)) { 5612 PropertyType 5613 = Property->getType().getNonReferenceType().getUnqualifiedType(); 5614 5615 // Give preference to ivars 5616 Results.setPreferredType(PropertyType); 5617 } 5618 } 5619 5620 // Add all of the instance variables in this class and its superclasses. 5621 Results.EnterNewScope(); 5622 bool SawSimilarlyNamedIvar = false; 5623 std::string NameWithPrefix; 5624 NameWithPrefix += '_'; 5625 NameWithPrefix += PropertyName->getName(); 5626 std::string NameWithSuffix = PropertyName->getName().str(); 5627 NameWithSuffix += '_'; 5628 for(; Class; Class = Class->getSuperClass()) { 5629 for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar; 5630 Ivar = Ivar->getNextIvar()) { 5631 Results.AddResult(Result(Ivar, 0), CurContext, 0, false); 5632 5633 // Determine whether we've seen an ivar with a name similar to the 5634 // property. 5635 if ((PropertyName == Ivar->getIdentifier() || 5636 NameWithPrefix == Ivar->getName() || 5637 NameWithSuffix == Ivar->getName())) { 5638 SawSimilarlyNamedIvar = true; 5639 5640 // Reduce the priority of this result by one, to give it a slight 5641 // advantage over other results whose names don't match so closely. 5642 if (Results.size() && 5643 Results.data()[Results.size() - 1].Kind 5644 == CodeCompletionResult::RK_Declaration && 5645 Results.data()[Results.size() - 1].Declaration == Ivar) 5646 Results.data()[Results.size() - 1].Priority--; 5647 } 5648 } 5649 } 5650 5651 if (!SawSimilarlyNamedIvar) { 5652 // Create ivar result _propName, that the user can use to synthesize 5653 // an ivar of the appropriate type. 5654 unsigned Priority = CCP_MemberDeclaration + 1; 5655 typedef CodeCompletionResult Result; 5656 CodeCompletionAllocator &Allocator = Results.getAllocator(); 5657 CodeCompletionBuilder Builder(Allocator, Priority,CXAvailability_Available); 5658 5659 PrintingPolicy Policy = getCompletionPrintingPolicy(*this); 5660 Builder.AddResultTypeChunk(GetCompletionTypeString(PropertyType, Context, 5661 Policy, Allocator)); 5662 Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix)); 5663 Results.AddResult(Result(Builder.TakeString(), Priority, 5664 CXCursor_ObjCIvarDecl)); 5665 } 5666 5667 Results.ExitScope(); 5668 5669 HandleCodeCompleteResults(this, CodeCompleter, 5670 CodeCompletionContext::CCC_Other, 5671 Results.data(),Results.size()); 5672 } 5673 5674 // Mapping from selectors to the methods that implement that selector, along 5675 // with the "in original class" flag. 5676 typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> > 5677 KnownMethodsMap; 5678 5679 /// \brief Find all of the methods that reside in the given container 5680 /// (and its superclasses, protocols, etc.) that meet the given 5681 /// criteria. Insert those methods into the map of known methods, 5682 /// indexed by selector so they can be easily found. 5683 static void FindImplementableMethods(ASTContext &Context, 5684 ObjCContainerDecl *Container, 5685 bool WantInstanceMethods, 5686 QualType ReturnType, 5687 KnownMethodsMap &KnownMethods, 5688 bool InOriginalClass = true) { 5689 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) { 5690 // Recurse into protocols. 5691 const ObjCList<ObjCProtocolDecl> &Protocols 5692 = IFace->getReferencedProtocols(); 5693 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 5694 E = Protocols.end(); 5695 I != E; ++I) 5696 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType, 5697 KnownMethods, InOriginalClass); 5698 5699 // Add methods from any class extensions and categories. 5700 for (const ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat; 5701 Cat = Cat->getNextClassCategory()) 5702 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat), 5703 WantInstanceMethods, ReturnType, 5704 KnownMethods, false); 5705 5706 // Visit the superclass. 5707 if (IFace->getSuperClass()) 5708 FindImplementableMethods(Context, IFace->getSuperClass(), 5709 WantInstanceMethods, ReturnType, 5710 KnownMethods, false); 5711 } 5712 5713 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) { 5714 // Recurse into protocols. 5715 const ObjCList<ObjCProtocolDecl> &Protocols 5716 = Category->getReferencedProtocols(); 5717 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 5718 E = Protocols.end(); 5719 I != E; ++I) 5720 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType, 5721 KnownMethods, InOriginalClass); 5722 5723 // If this category is the original class, jump to the interface. 5724 if (InOriginalClass && Category->getClassInterface()) 5725 FindImplementableMethods(Context, Category->getClassInterface(), 5726 WantInstanceMethods, ReturnType, KnownMethods, 5727 false); 5728 } 5729 5730 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 5731 // Recurse into protocols. 5732 const ObjCList<ObjCProtocolDecl> &Protocols 5733 = Protocol->getReferencedProtocols(); 5734 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 5735 E = Protocols.end(); 5736 I != E; ++I) 5737 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType, 5738 KnownMethods, false); 5739 } 5740 5741 // Add methods in this container. This operation occurs last because 5742 // we want the methods from this container to override any methods 5743 // we've previously seen with the same selector. 5744 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(), 5745 MEnd = Container->meth_end(); 5746 M != MEnd; ++M) { 5747 if ((*M)->isInstanceMethod() == WantInstanceMethods) { 5748 if (!ReturnType.isNull() && 5749 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType())) 5750 continue; 5751 5752 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass); 5753 } 5754 } 5755 } 5756 5757 /// \brief Add the parenthesized return or parameter type chunk to a code 5758 /// completion string. 5759 static void AddObjCPassingTypeChunk(QualType Type, 5760 ASTContext &Context, 5761 const PrintingPolicy &Policy, 5762 CodeCompletionBuilder &Builder) { 5763 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 5764 Builder.AddTextChunk(GetCompletionTypeString(Type, Context, Policy, 5765 Builder.getAllocator())); 5766 Builder.AddChunk(CodeCompletionString::CK_RightParen); 5767 } 5768 5769 /// \brief Determine whether the given class is or inherits from a class by 5770 /// the given name. 5771 static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, 5772 StringRef Name) { 5773 if (!Class) 5774 return false; 5775 5776 if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name) 5777 return true; 5778 5779 return InheritsFromClassNamed(Class->getSuperClass(), Name); 5780 } 5781 5782 /// \brief Add code completions for Objective-C Key-Value Coding (KVC) and 5783 /// Key-Value Observing (KVO). 5784 static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, 5785 bool IsInstanceMethod, 5786 QualType ReturnType, 5787 ASTContext &Context, 5788 VisitedSelectorSet &KnownSelectors, 5789 ResultBuilder &Results) { 5790 IdentifierInfo *PropName = Property->getIdentifier(); 5791 if (!PropName || PropName->getLength() == 0) 5792 return; 5793 5794 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema()); 5795 5796 // Builder that will create each code completion. 5797 typedef CodeCompletionResult Result; 5798 CodeCompletionAllocator &Allocator = Results.getAllocator(); 5799 CodeCompletionBuilder Builder(Allocator); 5800 5801 // The selector table. 5802 SelectorTable &Selectors = Context.Selectors; 5803 5804 // The property name, copied into the code completion allocation region 5805 // on demand. 5806 struct KeyHolder { 5807 CodeCompletionAllocator &Allocator; 5808 StringRef Key; 5809 const char *CopiedKey; 5810 5811 KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key) 5812 : Allocator(Allocator), Key(Key), CopiedKey(0) { } 5813 5814 operator const char *() { 5815 if (CopiedKey) 5816 return CopiedKey; 5817 5818 return CopiedKey = Allocator.CopyString(Key); 5819 } 5820 } Key(Allocator, PropName->getName()); 5821 5822 // The uppercased name of the property name. 5823 std::string UpperKey = PropName->getName(); 5824 if (!UpperKey.empty()) 5825 UpperKey[0] = toupper(UpperKey[0]); 5826 5827 bool ReturnTypeMatchesProperty = ReturnType.isNull() || 5828 Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(), 5829 Property->getType()); 5830 bool ReturnTypeMatchesVoid 5831 = ReturnType.isNull() || ReturnType->isVoidType(); 5832 5833 // Add the normal accessor -(type)key. 5834 if (IsInstanceMethod && 5835 KnownSelectors.insert(Selectors.getNullarySelector(PropName)) && 5836 ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) { 5837 if (ReturnType.isNull()) 5838 AddObjCPassingTypeChunk(Property->getType(), Context, Policy, Builder); 5839 5840 Builder.AddTypedTextChunk(Key); 5841 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 5842 CXCursor_ObjCInstanceMethodDecl)); 5843 } 5844 5845 // If we have an integral or boolean property (or the user has provided 5846 // an integral or boolean return type), add the accessor -(type)isKey. 5847 if (IsInstanceMethod && 5848 ((!ReturnType.isNull() && 5849 (ReturnType->isIntegerType() || ReturnType->isBooleanType())) || 5850 (ReturnType.isNull() && 5851 (Property->getType()->isIntegerType() || 5852 Property->getType()->isBooleanType())))) { 5853 std::string SelectorName = (Twine("is") + UpperKey).str(); 5854 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 5855 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 5856 if (ReturnType.isNull()) { 5857 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 5858 Builder.AddTextChunk("BOOL"); 5859 Builder.AddChunk(CodeCompletionString::CK_RightParen); 5860 } 5861 5862 Builder.AddTypedTextChunk( 5863 Allocator.CopyString(SelectorId->getName())); 5864 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 5865 CXCursor_ObjCInstanceMethodDecl)); 5866 } 5867 } 5868 5869 // Add the normal mutator. 5870 if (IsInstanceMethod && ReturnTypeMatchesVoid && 5871 !Property->getSetterMethodDecl()) { 5872 std::string SelectorName = (Twine("set") + UpperKey).str(); 5873 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 5874 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 5875 if (ReturnType.isNull()) { 5876 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 5877 Builder.AddTextChunk("void"); 5878 Builder.AddChunk(CodeCompletionString::CK_RightParen); 5879 } 5880 5881 Builder.AddTypedTextChunk( 5882 Allocator.CopyString(SelectorId->getName())); 5883 Builder.AddTypedTextChunk(":"); 5884 AddObjCPassingTypeChunk(Property->getType(), Context, Policy, Builder); 5885 Builder.AddTextChunk(Key); 5886 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 5887 CXCursor_ObjCInstanceMethodDecl)); 5888 } 5889 } 5890 5891 // Indexed and unordered accessors 5892 unsigned IndexedGetterPriority = CCP_CodePattern; 5893 unsigned IndexedSetterPriority = CCP_CodePattern; 5894 unsigned UnorderedGetterPriority = CCP_CodePattern; 5895 unsigned UnorderedSetterPriority = CCP_CodePattern; 5896 if (const ObjCObjectPointerType *ObjCPointer 5897 = Property->getType()->getAs<ObjCObjectPointerType>()) { 5898 if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) { 5899 // If this interface type is not provably derived from a known 5900 // collection, penalize the corresponding completions. 5901 if (!InheritsFromClassNamed(IFace, "NSMutableArray")) { 5902 IndexedSetterPriority += CCD_ProbablyNotObjCCollection; 5903 if (!InheritsFromClassNamed(IFace, "NSArray")) 5904 IndexedGetterPriority += CCD_ProbablyNotObjCCollection; 5905 } 5906 5907 if (!InheritsFromClassNamed(IFace, "NSMutableSet")) { 5908 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection; 5909 if (!InheritsFromClassNamed(IFace, "NSSet")) 5910 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection; 5911 } 5912 } 5913 } else { 5914 IndexedGetterPriority += CCD_ProbablyNotObjCCollection; 5915 IndexedSetterPriority += CCD_ProbablyNotObjCCollection; 5916 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection; 5917 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection; 5918 } 5919 5920 // Add -(NSUInteger)countOf<key> 5921 if (IsInstanceMethod && 5922 (ReturnType.isNull() || ReturnType->isIntegerType())) { 5923 std::string SelectorName = (Twine("countOf") + UpperKey).str(); 5924 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 5925 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 5926 if (ReturnType.isNull()) { 5927 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 5928 Builder.AddTextChunk("NSUInteger"); 5929 Builder.AddChunk(CodeCompletionString::CK_RightParen); 5930 } 5931 5932 Builder.AddTypedTextChunk( 5933 Allocator.CopyString(SelectorId->getName())); 5934 Results.AddResult(Result(Builder.TakeString(), 5935 std::min(IndexedGetterPriority, 5936 UnorderedGetterPriority), 5937 CXCursor_ObjCInstanceMethodDecl)); 5938 } 5939 } 5940 5941 // Indexed getters 5942 // Add -(id)objectInKeyAtIndex:(NSUInteger)index 5943 if (IsInstanceMethod && 5944 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) { 5945 std::string SelectorName 5946 = (Twine("objectIn") + UpperKey + "AtIndex").str(); 5947 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 5948 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 5949 if (ReturnType.isNull()) { 5950 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 5951 Builder.AddTextChunk("id"); 5952 Builder.AddChunk(CodeCompletionString::CK_RightParen); 5953 } 5954 5955 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 5956 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 5957 Builder.AddTextChunk("NSUInteger"); 5958 Builder.AddChunk(CodeCompletionString::CK_RightParen); 5959 Builder.AddTextChunk("index"); 5960 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority, 5961 CXCursor_ObjCInstanceMethodDecl)); 5962 } 5963 } 5964 5965 // Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes 5966 if (IsInstanceMethod && 5967 (ReturnType.isNull() || 5968 (ReturnType->isObjCObjectPointerType() && 5969 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() && 5970 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() 5971 ->getName() == "NSArray"))) { 5972 std::string SelectorName 5973 = (Twine(Property->getName()) + "AtIndexes").str(); 5974 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 5975 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 5976 if (ReturnType.isNull()) { 5977 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 5978 Builder.AddTextChunk("NSArray *"); 5979 Builder.AddChunk(CodeCompletionString::CK_RightParen); 5980 } 5981 5982 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 5983 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 5984 Builder.AddTextChunk("NSIndexSet *"); 5985 Builder.AddChunk(CodeCompletionString::CK_RightParen); 5986 Builder.AddTextChunk("indexes"); 5987 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority, 5988 CXCursor_ObjCInstanceMethodDecl)); 5989 } 5990 } 5991 5992 // Add -(void)getKey:(type **)buffer range:(NSRange)inRange 5993 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 5994 std::string SelectorName = (Twine("get") + UpperKey).str(); 5995 IdentifierInfo *SelectorIds[2] = { 5996 &Context.Idents.get(SelectorName), 5997 &Context.Idents.get("range") 5998 }; 5999 6000 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 6001 if (ReturnType.isNull()) { 6002 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6003 Builder.AddTextChunk("void"); 6004 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6005 } 6006 6007 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6008 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6009 Builder.AddPlaceholderChunk("object-type"); 6010 Builder.AddTextChunk(" **"); 6011 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6012 Builder.AddTextChunk("buffer"); 6013 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6014 Builder.AddTypedTextChunk("range:"); 6015 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6016 Builder.AddTextChunk("NSRange"); 6017 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6018 Builder.AddTextChunk("inRange"); 6019 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority, 6020 CXCursor_ObjCInstanceMethodDecl)); 6021 } 6022 } 6023 6024 // Mutable indexed accessors 6025 6026 // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index 6027 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6028 std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str(); 6029 IdentifierInfo *SelectorIds[2] = { 6030 &Context.Idents.get("insertObject"), 6031 &Context.Idents.get(SelectorName) 6032 }; 6033 6034 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 6035 if (ReturnType.isNull()) { 6036 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6037 Builder.AddTextChunk("void"); 6038 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6039 } 6040 6041 Builder.AddTypedTextChunk("insertObject:"); 6042 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6043 Builder.AddPlaceholderChunk("object-type"); 6044 Builder.AddTextChunk(" *"); 6045 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6046 Builder.AddTextChunk("object"); 6047 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6048 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6049 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6050 Builder.AddPlaceholderChunk("NSUInteger"); 6051 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6052 Builder.AddTextChunk("index"); 6053 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 6054 CXCursor_ObjCInstanceMethodDecl)); 6055 } 6056 } 6057 6058 // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes 6059 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6060 std::string SelectorName = (Twine("insert") + UpperKey).str(); 6061 IdentifierInfo *SelectorIds[2] = { 6062 &Context.Idents.get(SelectorName), 6063 &Context.Idents.get("atIndexes") 6064 }; 6065 6066 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 6067 if (ReturnType.isNull()) { 6068 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6069 Builder.AddTextChunk("void"); 6070 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6071 } 6072 6073 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6074 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6075 Builder.AddTextChunk("NSArray *"); 6076 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6077 Builder.AddTextChunk("array"); 6078 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6079 Builder.AddTypedTextChunk("atIndexes:"); 6080 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6081 Builder.AddPlaceholderChunk("NSIndexSet *"); 6082 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6083 Builder.AddTextChunk("indexes"); 6084 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 6085 CXCursor_ObjCInstanceMethodDecl)); 6086 } 6087 } 6088 6089 // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index 6090 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6091 std::string SelectorName 6092 = (Twine("removeObjectFrom") + UpperKey + "AtIndex").str(); 6093 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6094 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 6095 if (ReturnType.isNull()) { 6096 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6097 Builder.AddTextChunk("void"); 6098 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6099 } 6100 6101 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6102 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6103 Builder.AddTextChunk("NSUInteger"); 6104 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6105 Builder.AddTextChunk("index"); 6106 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 6107 CXCursor_ObjCInstanceMethodDecl)); 6108 } 6109 } 6110 6111 // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes 6112 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6113 std::string SelectorName 6114 = (Twine("remove") + UpperKey + "AtIndexes").str(); 6115 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6116 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 6117 if (ReturnType.isNull()) { 6118 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6119 Builder.AddTextChunk("void"); 6120 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6121 } 6122 6123 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6124 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6125 Builder.AddTextChunk("NSIndexSet *"); 6126 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6127 Builder.AddTextChunk("indexes"); 6128 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 6129 CXCursor_ObjCInstanceMethodDecl)); 6130 } 6131 } 6132 6133 // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object 6134 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6135 std::string SelectorName 6136 = (Twine("replaceObjectIn") + UpperKey + "AtIndex").str(); 6137 IdentifierInfo *SelectorIds[2] = { 6138 &Context.Idents.get(SelectorName), 6139 &Context.Idents.get("withObject") 6140 }; 6141 6142 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 6143 if (ReturnType.isNull()) { 6144 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6145 Builder.AddTextChunk("void"); 6146 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6147 } 6148 6149 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6150 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6151 Builder.AddPlaceholderChunk("NSUInteger"); 6152 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6153 Builder.AddTextChunk("index"); 6154 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6155 Builder.AddTypedTextChunk("withObject:"); 6156 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6157 Builder.AddTextChunk("id"); 6158 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6159 Builder.AddTextChunk("object"); 6160 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 6161 CXCursor_ObjCInstanceMethodDecl)); 6162 } 6163 } 6164 6165 // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array 6166 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6167 std::string SelectorName1 6168 = (Twine("replace") + UpperKey + "AtIndexes").str(); 6169 std::string SelectorName2 = (Twine("with") + UpperKey).str(); 6170 IdentifierInfo *SelectorIds[2] = { 6171 &Context.Idents.get(SelectorName1), 6172 &Context.Idents.get(SelectorName2) 6173 }; 6174 6175 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 6176 if (ReturnType.isNull()) { 6177 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6178 Builder.AddTextChunk("void"); 6179 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6180 } 6181 6182 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName1 + ":")); 6183 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6184 Builder.AddPlaceholderChunk("NSIndexSet *"); 6185 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6186 Builder.AddTextChunk("indexes"); 6187 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6188 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName2 + ":")); 6189 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6190 Builder.AddTextChunk("NSArray *"); 6191 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6192 Builder.AddTextChunk("array"); 6193 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 6194 CXCursor_ObjCInstanceMethodDecl)); 6195 } 6196 } 6197 6198 // Unordered getters 6199 // - (NSEnumerator *)enumeratorOfKey 6200 if (IsInstanceMethod && 6201 (ReturnType.isNull() || 6202 (ReturnType->isObjCObjectPointerType() && 6203 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() && 6204 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() 6205 ->getName() == "NSEnumerator"))) { 6206 std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str(); 6207 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6208 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 6209 if (ReturnType.isNull()) { 6210 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6211 Builder.AddTextChunk("NSEnumerator *"); 6212 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6213 } 6214 6215 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName)); 6216 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority, 6217 CXCursor_ObjCInstanceMethodDecl)); 6218 } 6219 } 6220 6221 // - (type *)memberOfKey:(type *)object 6222 if (IsInstanceMethod && 6223 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) { 6224 std::string SelectorName = (Twine("memberOf") + UpperKey).str(); 6225 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6226 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 6227 if (ReturnType.isNull()) { 6228 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6229 Builder.AddPlaceholderChunk("object-type"); 6230 Builder.AddTextChunk(" *"); 6231 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6232 } 6233 6234 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6235 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6236 if (ReturnType.isNull()) { 6237 Builder.AddPlaceholderChunk("object-type"); 6238 Builder.AddTextChunk(" *"); 6239 } else { 6240 Builder.AddTextChunk(GetCompletionTypeString(ReturnType, Context, 6241 Policy, 6242 Builder.getAllocator())); 6243 } 6244 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6245 Builder.AddTextChunk("object"); 6246 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority, 6247 CXCursor_ObjCInstanceMethodDecl)); 6248 } 6249 } 6250 6251 // Mutable unordered accessors 6252 // - (void)addKeyObject:(type *)object 6253 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6254 std::string SelectorName 6255 = (Twine("add") + UpperKey + Twine("Object")).str(); 6256 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6257 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 6258 if (ReturnType.isNull()) { 6259 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6260 Builder.AddTextChunk("void"); 6261 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6262 } 6263 6264 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6265 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6266 Builder.AddPlaceholderChunk("object-type"); 6267 Builder.AddTextChunk(" *"); 6268 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6269 Builder.AddTextChunk("object"); 6270 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 6271 CXCursor_ObjCInstanceMethodDecl)); 6272 } 6273 } 6274 6275 // - (void)addKey:(NSSet *)objects 6276 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6277 std::string SelectorName = (Twine("add") + UpperKey).str(); 6278 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6279 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 6280 if (ReturnType.isNull()) { 6281 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6282 Builder.AddTextChunk("void"); 6283 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6284 } 6285 6286 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6287 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6288 Builder.AddTextChunk("NSSet *"); 6289 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6290 Builder.AddTextChunk("objects"); 6291 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 6292 CXCursor_ObjCInstanceMethodDecl)); 6293 } 6294 } 6295 6296 // - (void)removeKeyObject:(type *)object 6297 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6298 std::string SelectorName 6299 = (Twine("remove") + UpperKey + Twine("Object")).str(); 6300 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6301 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 6302 if (ReturnType.isNull()) { 6303 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6304 Builder.AddTextChunk("void"); 6305 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6306 } 6307 6308 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6309 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6310 Builder.AddPlaceholderChunk("object-type"); 6311 Builder.AddTextChunk(" *"); 6312 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6313 Builder.AddTextChunk("object"); 6314 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 6315 CXCursor_ObjCInstanceMethodDecl)); 6316 } 6317 } 6318 6319 // - (void)removeKey:(NSSet *)objects 6320 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6321 std::string SelectorName = (Twine("remove") + UpperKey).str(); 6322 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6323 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 6324 if (ReturnType.isNull()) { 6325 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6326 Builder.AddTextChunk("void"); 6327 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6328 } 6329 6330 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6331 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6332 Builder.AddTextChunk("NSSet *"); 6333 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6334 Builder.AddTextChunk("objects"); 6335 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 6336 CXCursor_ObjCInstanceMethodDecl)); 6337 } 6338 } 6339 6340 // - (void)intersectKey:(NSSet *)objects 6341 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 6342 std::string SelectorName = (Twine("intersect") + UpperKey).str(); 6343 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6344 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 6345 if (ReturnType.isNull()) { 6346 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6347 Builder.AddTextChunk("void"); 6348 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6349 } 6350 6351 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 6352 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6353 Builder.AddTextChunk("NSSet *"); 6354 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6355 Builder.AddTextChunk("objects"); 6356 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 6357 CXCursor_ObjCInstanceMethodDecl)); 6358 } 6359 } 6360 6361 // Key-Value Observing 6362 // + (NSSet *)keyPathsForValuesAffectingKey 6363 if (!IsInstanceMethod && 6364 (ReturnType.isNull() || 6365 (ReturnType->isObjCObjectPointerType() && 6366 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() && 6367 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() 6368 ->getName() == "NSSet"))) { 6369 std::string SelectorName 6370 = (Twine("keyPathsForValuesAffecting") + UpperKey).str(); 6371 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6372 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 6373 if (ReturnType.isNull()) { 6374 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6375 Builder.AddTextChunk("NSSet *"); 6376 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6377 } 6378 6379 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName)); 6380 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 6381 CXCursor_ObjCClassMethodDecl)); 6382 } 6383 } 6384 6385 // + (BOOL)automaticallyNotifiesObserversForKey 6386 if (!IsInstanceMethod && 6387 (ReturnType.isNull() || 6388 ReturnType->isIntegerType() || 6389 ReturnType->isBooleanType())) { 6390 std::string SelectorName 6391 = (Twine("automaticallyNotifiesObserversOf") + UpperKey).str(); 6392 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 6393 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 6394 if (ReturnType.isNull()) { 6395 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6396 Builder.AddTextChunk("BOOL"); 6397 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6398 } 6399 6400 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName)); 6401 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 6402 CXCursor_ObjCClassMethodDecl)); 6403 } 6404 } 6405 } 6406 6407 void Sema::CodeCompleteObjCMethodDecl(Scope *S, 6408 bool IsInstanceMethod, 6409 ParsedType ReturnTy) { 6410 // Determine the return type of the method we're declaring, if 6411 // provided. 6412 QualType ReturnType = GetTypeFromParser(ReturnTy); 6413 Decl *IDecl = 0; 6414 if (CurContext->isObjCContainer()) { 6415 ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); 6416 IDecl = cast<Decl>(OCD); 6417 } 6418 // Determine where we should start searching for methods. 6419 ObjCContainerDecl *SearchDecl = 0; 6420 bool IsInImplementation = false; 6421 if (Decl *D = IDecl) { 6422 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) { 6423 SearchDecl = Impl->getClassInterface(); 6424 IsInImplementation = true; 6425 } else if (ObjCCategoryImplDecl *CatImpl 6426 = dyn_cast<ObjCCategoryImplDecl>(D)) { 6427 SearchDecl = CatImpl->getCategoryDecl(); 6428 IsInImplementation = true; 6429 } else 6430 SearchDecl = dyn_cast<ObjCContainerDecl>(D); 6431 } 6432 6433 if (!SearchDecl && S) { 6434 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) 6435 SearchDecl = dyn_cast<ObjCContainerDecl>(DC); 6436 } 6437 6438 if (!SearchDecl) { 6439 HandleCodeCompleteResults(this, CodeCompleter, 6440 CodeCompletionContext::CCC_Other, 6441 0, 0); 6442 return; 6443 } 6444 6445 // Find all of the methods that we could declare/implement here. 6446 KnownMethodsMap KnownMethods; 6447 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod, 6448 ReturnType, KnownMethods); 6449 6450 // Add declarations or definitions for each of the known methods. 6451 typedef CodeCompletionResult Result; 6452 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 6453 CodeCompletionContext::CCC_Other); 6454 Results.EnterNewScope(); 6455 PrintingPolicy Policy = getCompletionPrintingPolicy(*this); 6456 for (KnownMethodsMap::iterator M = KnownMethods.begin(), 6457 MEnd = KnownMethods.end(); 6458 M != MEnd; ++M) { 6459 ObjCMethodDecl *Method = M->second.first; 6460 CodeCompletionBuilder Builder(Results.getAllocator()); 6461 6462 // If the result type was not already provided, add it to the 6463 // pattern as (type). 6464 if (ReturnType.isNull()) 6465 AddObjCPassingTypeChunk(Method->getResultType(), Context, Policy, 6466 Builder); 6467 6468 Selector Sel = Method->getSelector(); 6469 6470 // Add the first part of the selector to the pattern. 6471 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 6472 Sel.getNameForSlot(0))); 6473 6474 // Add parameters to the pattern. 6475 unsigned I = 0; 6476 for (ObjCMethodDecl::param_iterator P = Method->param_begin(), 6477 PEnd = Method->param_end(); 6478 P != PEnd; (void)++P, ++I) { 6479 // Add the part of the selector name. 6480 if (I == 0) 6481 Builder.AddTypedTextChunk(":"); 6482 else if (I < Sel.getNumArgs()) { 6483 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6484 Builder.AddTypedTextChunk( 6485 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); 6486 } else 6487 break; 6488 6489 // Add the parameter type. 6490 AddObjCPassingTypeChunk((*P)->getOriginalType(), Context, Policy, 6491 Builder); 6492 6493 if (IdentifierInfo *Id = (*P)->getIdentifier()) 6494 Builder.AddTextChunk(Builder.getAllocator().CopyString( Id->getName())); 6495 } 6496 6497 if (Method->isVariadic()) { 6498 if (Method->param_size() > 0) 6499 Builder.AddChunk(CodeCompletionString::CK_Comma); 6500 Builder.AddTextChunk("..."); 6501 } 6502 6503 if (IsInImplementation && Results.includeCodePatterns()) { 6504 // We will be defining the method here, so add a compound statement. 6505 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6506 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 6507 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 6508 if (!Method->getResultType()->isVoidType()) { 6509 // If the result type is not void, add a return clause. 6510 Builder.AddTextChunk("return"); 6511 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6512 Builder.AddPlaceholderChunk("expression"); 6513 Builder.AddChunk(CodeCompletionString::CK_SemiColon); 6514 } else 6515 Builder.AddPlaceholderChunk("statements"); 6516 6517 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 6518 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 6519 } 6520 6521 unsigned Priority = CCP_CodePattern; 6522 if (!M->second.second) 6523 Priority += CCD_InBaseClass; 6524 6525 Results.AddResult(Result(Builder.TakeString(), Priority, 6526 Method->isInstanceMethod() 6527 ? CXCursor_ObjCInstanceMethodDecl 6528 : CXCursor_ObjCClassMethodDecl)); 6529 } 6530 6531 // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of 6532 // the properties in this class and its categories. 6533 if (Context.getLangOptions().ObjC2) { 6534 SmallVector<ObjCContainerDecl *, 4> Containers; 6535 Containers.push_back(SearchDecl); 6536 6537 VisitedSelectorSet KnownSelectors; 6538 for (KnownMethodsMap::iterator M = KnownMethods.begin(), 6539 MEnd = KnownMethods.end(); 6540 M != MEnd; ++M) 6541 KnownSelectors.insert(M->first); 6542 6543 6544 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl); 6545 if (!IFace) 6546 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl)) 6547 IFace = Category->getClassInterface(); 6548 6549 if (IFace) { 6550 for (ObjCCategoryDecl *Category = IFace->getCategoryList(); Category; 6551 Category = Category->getNextClassCategory()) 6552 Containers.push_back(Category); 6553 } 6554 6555 for (unsigned I = 0, N = Containers.size(); I != N; ++I) { 6556 for (ObjCContainerDecl::prop_iterator P = Containers[I]->prop_begin(), 6557 PEnd = Containers[I]->prop_end(); 6558 P != PEnd; ++P) { 6559 AddObjCKeyValueCompletions(*P, IsInstanceMethod, ReturnType, Context, 6560 KnownSelectors, Results); 6561 } 6562 } 6563 } 6564 6565 Results.ExitScope(); 6566 6567 HandleCodeCompleteResults(this, CodeCompleter, 6568 CodeCompletionContext::CCC_Other, 6569 Results.data(),Results.size()); 6570 } 6571 6572 void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, 6573 bool IsInstanceMethod, 6574 bool AtParameterName, 6575 ParsedType ReturnTy, 6576 IdentifierInfo **SelIdents, 6577 unsigned NumSelIdents) { 6578 // If we have an external source, load the entire class method 6579 // pool from the AST file. 6580 if (ExternalSource) { 6581 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); 6582 I != N; ++I) { 6583 Selector Sel = ExternalSource->GetExternalSelector(I); 6584 if (Sel.isNull() || MethodPool.count(Sel)) 6585 continue; 6586 6587 ReadMethodPool(Sel); 6588 } 6589 } 6590 6591 // Build the set of methods we can see. 6592 typedef CodeCompletionResult Result; 6593 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 6594 CodeCompletionContext::CCC_Other); 6595 6596 if (ReturnTy) 6597 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType()); 6598 6599 Results.EnterNewScope(); 6600 for (GlobalMethodPool::iterator M = MethodPool.begin(), 6601 MEnd = MethodPool.end(); 6602 M != MEnd; ++M) { 6603 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first : 6604 &M->second.second; 6605 MethList && MethList->Method; 6606 MethList = MethList->Next) { 6607 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 6608 NumSelIdents)) 6609 continue; 6610 6611 if (AtParameterName) { 6612 // Suggest parameter names we've seen before. 6613 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) { 6614 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1]; 6615 if (Param->getIdentifier()) { 6616 CodeCompletionBuilder Builder(Results.getAllocator()); 6617 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 6618 Param->getIdentifier()->getName())); 6619 Results.AddResult(Builder.TakeString()); 6620 } 6621 } 6622 6623 continue; 6624 } 6625 6626 Result R(MethList->Method, 0); 6627 R.StartParameter = NumSelIdents; 6628 R.AllParametersAreInformative = false; 6629 R.DeclaringEntity = true; 6630 Results.MaybeAddResult(R, CurContext); 6631 } 6632 } 6633 6634 Results.ExitScope(); 6635 HandleCodeCompleteResults(this, CodeCompleter, 6636 CodeCompletionContext::CCC_Other, 6637 Results.data(),Results.size()); 6638 } 6639 6640 void Sema::CodeCompletePreprocessorDirective(bool InConditional) { 6641 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 6642 CodeCompletionContext::CCC_PreprocessorDirective); 6643 Results.EnterNewScope(); 6644 6645 // #if <condition> 6646 CodeCompletionBuilder Builder(Results.getAllocator()); 6647 Builder.AddTypedTextChunk("if"); 6648 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6649 Builder.AddPlaceholderChunk("condition"); 6650 Results.AddResult(Builder.TakeString()); 6651 6652 // #ifdef <macro> 6653 Builder.AddTypedTextChunk("ifdef"); 6654 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6655 Builder.AddPlaceholderChunk("macro"); 6656 Results.AddResult(Builder.TakeString()); 6657 6658 // #ifndef <macro> 6659 Builder.AddTypedTextChunk("ifndef"); 6660 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6661 Builder.AddPlaceholderChunk("macro"); 6662 Results.AddResult(Builder.TakeString()); 6663 6664 if (InConditional) { 6665 // #elif <condition> 6666 Builder.AddTypedTextChunk("elif"); 6667 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6668 Builder.AddPlaceholderChunk("condition"); 6669 Results.AddResult(Builder.TakeString()); 6670 6671 // #else 6672 Builder.AddTypedTextChunk("else"); 6673 Results.AddResult(Builder.TakeString()); 6674 6675 // #endif 6676 Builder.AddTypedTextChunk("endif"); 6677 Results.AddResult(Builder.TakeString()); 6678 } 6679 6680 // #include "header" 6681 Builder.AddTypedTextChunk("include"); 6682 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6683 Builder.AddTextChunk("\""); 6684 Builder.AddPlaceholderChunk("header"); 6685 Builder.AddTextChunk("\""); 6686 Results.AddResult(Builder.TakeString()); 6687 6688 // #include <header> 6689 Builder.AddTypedTextChunk("include"); 6690 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6691 Builder.AddTextChunk("<"); 6692 Builder.AddPlaceholderChunk("header"); 6693 Builder.AddTextChunk(">"); 6694 Results.AddResult(Builder.TakeString()); 6695 6696 // #define <macro> 6697 Builder.AddTypedTextChunk("define"); 6698 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6699 Builder.AddPlaceholderChunk("macro"); 6700 Results.AddResult(Builder.TakeString()); 6701 6702 // #define <macro>(<args>) 6703 Builder.AddTypedTextChunk("define"); 6704 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6705 Builder.AddPlaceholderChunk("macro"); 6706 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6707 Builder.AddPlaceholderChunk("args"); 6708 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6709 Results.AddResult(Builder.TakeString()); 6710 6711 // #undef <macro> 6712 Builder.AddTypedTextChunk("undef"); 6713 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6714 Builder.AddPlaceholderChunk("macro"); 6715 Results.AddResult(Builder.TakeString()); 6716 6717 // #line <number> 6718 Builder.AddTypedTextChunk("line"); 6719 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6720 Builder.AddPlaceholderChunk("number"); 6721 Results.AddResult(Builder.TakeString()); 6722 6723 // #line <number> "filename" 6724 Builder.AddTypedTextChunk("line"); 6725 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6726 Builder.AddPlaceholderChunk("number"); 6727 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6728 Builder.AddTextChunk("\""); 6729 Builder.AddPlaceholderChunk("filename"); 6730 Builder.AddTextChunk("\""); 6731 Results.AddResult(Builder.TakeString()); 6732 6733 // #error <message> 6734 Builder.AddTypedTextChunk("error"); 6735 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6736 Builder.AddPlaceholderChunk("message"); 6737 Results.AddResult(Builder.TakeString()); 6738 6739 // #pragma <arguments> 6740 Builder.AddTypedTextChunk("pragma"); 6741 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6742 Builder.AddPlaceholderChunk("arguments"); 6743 Results.AddResult(Builder.TakeString()); 6744 6745 if (getLangOptions().ObjC1) { 6746 // #import "header" 6747 Builder.AddTypedTextChunk("import"); 6748 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6749 Builder.AddTextChunk("\""); 6750 Builder.AddPlaceholderChunk("header"); 6751 Builder.AddTextChunk("\""); 6752 Results.AddResult(Builder.TakeString()); 6753 6754 // #import <header> 6755 Builder.AddTypedTextChunk("import"); 6756 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6757 Builder.AddTextChunk("<"); 6758 Builder.AddPlaceholderChunk("header"); 6759 Builder.AddTextChunk(">"); 6760 Results.AddResult(Builder.TakeString()); 6761 } 6762 6763 // #include_next "header" 6764 Builder.AddTypedTextChunk("include_next"); 6765 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6766 Builder.AddTextChunk("\""); 6767 Builder.AddPlaceholderChunk("header"); 6768 Builder.AddTextChunk("\""); 6769 Results.AddResult(Builder.TakeString()); 6770 6771 // #include_next <header> 6772 Builder.AddTypedTextChunk("include_next"); 6773 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6774 Builder.AddTextChunk("<"); 6775 Builder.AddPlaceholderChunk("header"); 6776 Builder.AddTextChunk(">"); 6777 Results.AddResult(Builder.TakeString()); 6778 6779 // #warning <message> 6780 Builder.AddTypedTextChunk("warning"); 6781 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6782 Builder.AddPlaceholderChunk("message"); 6783 Results.AddResult(Builder.TakeString()); 6784 6785 // Note: #ident and #sccs are such crazy anachronisms that we don't provide 6786 // completions for them. And __include_macros is a Clang-internal extension 6787 // that we don't want to encourage anyone to use. 6788 6789 // FIXME: we don't support #assert or #unassert, so don't suggest them. 6790 Results.ExitScope(); 6791 6792 HandleCodeCompleteResults(this, CodeCompleter, 6793 CodeCompletionContext::CCC_PreprocessorDirective, 6794 Results.data(), Results.size()); 6795 } 6796 6797 void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) { 6798 CodeCompleteOrdinaryName(S, 6799 S->getFnParent()? Sema::PCC_RecoveryInFunction 6800 : Sema::PCC_Namespace); 6801 } 6802 6803 void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) { 6804 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 6805 IsDefinition? CodeCompletionContext::CCC_MacroName 6806 : CodeCompletionContext::CCC_MacroNameUse); 6807 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) { 6808 // Add just the names of macros, not their arguments. 6809 CodeCompletionBuilder Builder(Results.getAllocator()); 6810 Results.EnterNewScope(); 6811 for (Preprocessor::macro_iterator M = PP.macro_begin(), 6812 MEnd = PP.macro_end(); 6813 M != MEnd; ++M) { 6814 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 6815 M->first->getName())); 6816 Results.AddResult(Builder.TakeString()); 6817 } 6818 Results.ExitScope(); 6819 } else if (IsDefinition) { 6820 // FIXME: Can we detect when the user just wrote an include guard above? 6821 } 6822 6823 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 6824 Results.data(), Results.size()); 6825 } 6826 6827 void Sema::CodeCompletePreprocessorExpression() { 6828 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 6829 CodeCompletionContext::CCC_PreprocessorExpression); 6830 6831 if (!CodeCompleter || CodeCompleter->includeMacros()) 6832 AddMacroResults(PP, Results); 6833 6834 // defined (<macro>) 6835 Results.EnterNewScope(); 6836 CodeCompletionBuilder Builder(Results.getAllocator()); 6837 Builder.AddTypedTextChunk("defined"); 6838 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 6839 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 6840 Builder.AddPlaceholderChunk("macro"); 6841 Builder.AddChunk(CodeCompletionString::CK_RightParen); 6842 Results.AddResult(Builder.TakeString()); 6843 Results.ExitScope(); 6844 6845 HandleCodeCompleteResults(this, CodeCompleter, 6846 CodeCompletionContext::CCC_PreprocessorExpression, 6847 Results.data(), Results.size()); 6848 } 6849 6850 void Sema::CodeCompletePreprocessorMacroArgument(Scope *S, 6851 IdentifierInfo *Macro, 6852 MacroInfo *MacroInfo, 6853 unsigned Argument) { 6854 // FIXME: In the future, we could provide "overload" results, much like we 6855 // do for function calls. 6856 6857 // Now just ignore this. There will be another code-completion callback 6858 // for the expanded tokens. 6859 } 6860 6861 void Sema::CodeCompleteNaturalLanguage() { 6862 HandleCodeCompleteResults(this, CodeCompleter, 6863 CodeCompletionContext::CCC_NaturalLanguage, 6864 0, 0); 6865 } 6866 6867 void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, 6868 SmallVectorImpl<CodeCompletionResult> &Results) { 6869 ResultBuilder Builder(*this, Allocator, CodeCompletionContext::CCC_Recovery); 6870 if (!CodeCompleter || CodeCompleter->includeGlobals()) { 6871 CodeCompletionDeclConsumer Consumer(Builder, 6872 Context.getTranslationUnitDecl()); 6873 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName, 6874 Consumer); 6875 } 6876 6877 if (!CodeCompleter || CodeCompleter->includeMacros()) 6878 AddMacroResults(PP, Builder); 6879 6880 Results.clear(); 6881 Results.insert(Results.end(), 6882 Builder.data(), Builder.data() + Builder.size()); 6883 } 6884