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