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