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