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