clang API Documentation
00001 //===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the code-completion semantic actions. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 #include "clang/Sema/SemaInternal.h" 00014 #include "clang/AST/DeclObjC.h" 00015 #include "clang/AST/ExprCXX.h" 00016 #include "clang/AST/ExprObjC.h" 00017 #include "clang/Basic/CharInfo.h" 00018 #include "clang/Lex/HeaderSearch.h" 00019 #include "clang/Lex/MacroInfo.h" 00020 #include "clang/Lex/Preprocessor.h" 00021 #include "clang/Sema/CodeCompleteConsumer.h" 00022 #include "clang/Sema/ExternalSemaSource.h" 00023 #include "clang/Sema/Lookup.h" 00024 #include "clang/Sema/Overload.h" 00025 #include "clang/Sema/Scope.h" 00026 #include "clang/Sema/ScopeInfo.h" 00027 #include "llvm/ADT/DenseSet.h" 00028 #include "llvm/ADT/SmallBitVector.h" 00029 #include "llvm/ADT/SmallPtrSet.h" 00030 #include "llvm/ADT/SmallString.h" 00031 #include "llvm/ADT/StringExtras.h" 00032 #include "llvm/ADT/StringSwitch.h" 00033 #include "llvm/ADT/Twine.h" 00034 #include <list> 00035 #include <map> 00036 #include <vector> 00037 00038 using namespace clang; 00039 using namespace sema; 00040 00041 namespace { 00042 /// \brief A container of code-completion results. 00043 class ResultBuilder { 00044 public: 00045 /// \brief The type of a name-lookup filter, which can be provided to the 00046 /// name-lookup routines to specify which declarations should be included in 00047 /// the result set (when it returns true) and which declarations should be 00048 /// filtered out (returns false). 00049 typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const; 00050 00051 typedef CodeCompletionResult Result; 00052 00053 private: 00054 /// \brief The actual results we have found. 00055 std::vector<Result> Results; 00056 00057 /// \brief A record of all of the declarations we have found and placed 00058 /// into the result set, used to ensure that no declaration ever gets into 00059 /// the result set twice. 00060 llvm::SmallPtrSet<const Decl*, 16> AllDeclsFound; 00061 00062 typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair; 00063 00064 /// \brief An entry in the shadow map, which is optimized to store 00065 /// a single (declaration, index) mapping (the common case) but 00066 /// can also store a list of (declaration, index) mappings. 00067 class ShadowMapEntry { 00068 typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector; 00069 00070 /// \brief Contains either the solitary NamedDecl * or a vector 00071 /// of (declaration, index) pairs. 00072 llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector*> DeclOrVector; 00073 00074 /// \brief When the entry contains a single declaration, this is 00075 /// the index associated with that entry. 00076 unsigned SingleDeclIndex; 00077 00078 public: 00079 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { } 00080 00081 void Add(const NamedDecl *ND, unsigned Index) { 00082 if (DeclOrVector.isNull()) { 00083 // 0 - > 1 elements: just set the single element information. 00084 DeclOrVector = ND; 00085 SingleDeclIndex = Index; 00086 return; 00087 } 00088 00089 if (const NamedDecl *PrevND = 00090 DeclOrVector.dyn_cast<const NamedDecl *>()) { 00091 // 1 -> 2 elements: create the vector of results and push in the 00092 // existing declaration. 00093 DeclIndexPairVector *Vec = new DeclIndexPairVector; 00094 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex)); 00095 DeclOrVector = Vec; 00096 } 00097 00098 // Add the new element to the end of the vector. 00099 DeclOrVector.get<DeclIndexPairVector*>()->push_back( 00100 DeclIndexPair(ND, Index)); 00101 } 00102 00103 void Destroy() { 00104 if (DeclIndexPairVector *Vec 00105 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) { 00106 delete Vec; 00107 DeclOrVector = ((NamedDecl *)nullptr); 00108 } 00109 } 00110 00111 // Iteration. 00112 class iterator; 00113 iterator begin() const; 00114 iterator end() const; 00115 }; 00116 00117 /// \brief A mapping from declaration names to the declarations that have 00118 /// this name within a particular scope and their index within the list of 00119 /// results. 00120 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap; 00121 00122 /// \brief The semantic analysis object for which results are being 00123 /// produced. 00124 Sema &SemaRef; 00125 00126 /// \brief The allocator used to allocate new code-completion strings. 00127 CodeCompletionAllocator &Allocator; 00128 00129 CodeCompletionTUInfo &CCTUInfo; 00130 00131 /// \brief If non-NULL, a filter function used to remove any code-completion 00132 /// results that are not desirable. 00133 LookupFilter Filter; 00134 00135 /// \brief Whether we should allow declarations as 00136 /// nested-name-specifiers that would otherwise be filtered out. 00137 bool AllowNestedNameSpecifiers; 00138 00139 /// \brief If set, the type that we would prefer our resulting value 00140 /// declarations to have. 00141 /// 00142 /// Closely matching the preferred type gives a boost to a result's 00143 /// priority. 00144 CanQualType PreferredType; 00145 00146 /// \brief A list of shadow maps, which is used to model name hiding at 00147 /// different levels of, e.g., the inheritance hierarchy. 00148 std::list<ShadowMap> ShadowMaps; 00149 00150 /// \brief If we're potentially referring to a C++ member function, the set 00151 /// of qualifiers applied to the object type. 00152 Qualifiers ObjectTypeQualifiers; 00153 00154 /// \brief Whether the \p ObjectTypeQualifiers field is active. 00155 bool HasObjectTypeQualifiers; 00156 00157 /// \brief The selector that we prefer. 00158 Selector PreferredSelector; 00159 00160 /// \brief The completion context in which we are gathering results. 00161 CodeCompletionContext CompletionContext; 00162 00163 /// \brief If we are in an instance method definition, the \@implementation 00164 /// object. 00165 ObjCImplementationDecl *ObjCImplementation; 00166 00167 void AdjustResultPriorityForDecl(Result &R); 00168 00169 void MaybeAddConstructorResults(Result R); 00170 00171 public: 00172 explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator, 00173 CodeCompletionTUInfo &CCTUInfo, 00174 const CodeCompletionContext &CompletionContext, 00175 LookupFilter Filter = nullptr) 00176 : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo), 00177 Filter(Filter), 00178 AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false), 00179 CompletionContext(CompletionContext), 00180 ObjCImplementation(nullptr) 00181 { 00182 // If this is an Objective-C instance method definition, dig out the 00183 // corresponding implementation. 00184 switch (CompletionContext.getKind()) { 00185 case CodeCompletionContext::CCC_Expression: 00186 case CodeCompletionContext::CCC_ObjCMessageReceiver: 00187 case CodeCompletionContext::CCC_ParenthesizedExpression: 00188 case CodeCompletionContext::CCC_Statement: 00189 case CodeCompletionContext::CCC_Recovery: 00190 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) 00191 if (Method->isInstanceMethod()) 00192 if (ObjCInterfaceDecl *Interface = Method->getClassInterface()) 00193 ObjCImplementation = Interface->getImplementation(); 00194 break; 00195 00196 default: 00197 break; 00198 } 00199 } 00200 00201 /// \brief Determine the priority for a reference to the given declaration. 00202 unsigned getBasePriority(const NamedDecl *D); 00203 00204 /// \brief Whether we should include code patterns in the completion 00205 /// results. 00206 bool includeCodePatterns() const { 00207 return SemaRef.CodeCompleter && 00208 SemaRef.CodeCompleter->includeCodePatterns(); 00209 } 00210 00211 /// \brief Set the filter used for code-completion results. 00212 void setFilter(LookupFilter Filter) { 00213 this->Filter = Filter; 00214 } 00215 00216 Result *data() { return Results.empty()? nullptr : &Results.front(); } 00217 unsigned size() const { return Results.size(); } 00218 bool empty() const { return Results.empty(); } 00219 00220 /// \brief Specify the preferred type. 00221 void setPreferredType(QualType T) { 00222 PreferredType = SemaRef.Context.getCanonicalType(T); 00223 } 00224 00225 /// \brief Set the cv-qualifiers on the object type, for us in filtering 00226 /// calls to member functions. 00227 /// 00228 /// When there are qualifiers in this set, they will be used to filter 00229 /// out member functions that aren't available (because there will be a 00230 /// cv-qualifier mismatch) or prefer functions with an exact qualifier 00231 /// match. 00232 void setObjectTypeQualifiers(Qualifiers Quals) { 00233 ObjectTypeQualifiers = Quals; 00234 HasObjectTypeQualifiers = true; 00235 } 00236 00237 /// \brief Set the preferred selector. 00238 /// 00239 /// When an Objective-C method declaration result is added, and that 00240 /// method's selector matches this preferred selector, we give that method 00241 /// a slight priority boost. 00242 void setPreferredSelector(Selector Sel) { 00243 PreferredSelector = Sel; 00244 } 00245 00246 /// \brief Retrieve the code-completion context for which results are 00247 /// being collected. 00248 const CodeCompletionContext &getCompletionContext() const { 00249 return CompletionContext; 00250 } 00251 00252 /// \brief Specify whether nested-name-specifiers are allowed. 00253 void allowNestedNameSpecifiers(bool Allow = true) { 00254 AllowNestedNameSpecifiers = Allow; 00255 } 00256 00257 /// \brief Return the semantic analysis object for which we are collecting 00258 /// code completion results. 00259 Sema &getSema() const { return SemaRef; } 00260 00261 /// \brief Retrieve the allocator used to allocate code completion strings. 00262 CodeCompletionAllocator &getAllocator() const { return Allocator; } 00263 00264 CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; } 00265 00266 /// \brief Determine whether the given declaration is at all interesting 00267 /// as a code-completion result. 00268 /// 00269 /// \param ND the declaration that we are inspecting. 00270 /// 00271 /// \param AsNestedNameSpecifier will be set true if this declaration is 00272 /// only interesting when it is a nested-name-specifier. 00273 bool isInterestingDecl(const NamedDecl *ND, 00274 bool &AsNestedNameSpecifier) const; 00275 00276 /// \brief Check whether the result is hidden by the Hiding declaration. 00277 /// 00278 /// \returns true if the result is hidden and cannot be found, false if 00279 /// the hidden result could still be found. When false, \p R may be 00280 /// modified to describe how the result can be found (e.g., via extra 00281 /// qualification). 00282 bool CheckHiddenResult(Result &R, DeclContext *CurContext, 00283 const NamedDecl *Hiding); 00284 00285 /// \brief Add a new result to this result set (if it isn't already in one 00286 /// of the shadow maps), or replace an existing result (for, e.g., a 00287 /// redeclaration). 00288 /// 00289 /// \param R the result to add (if it is unique). 00290 /// 00291 /// \param CurContext the context in which this result will be named. 00292 void MaybeAddResult(Result R, DeclContext *CurContext = nullptr); 00293 00294 /// \brief Add a new result to this result set, where we already know 00295 /// the hiding declaration (if any). 00296 /// 00297 /// \param R the result to add (if it is unique). 00298 /// 00299 /// \param CurContext the context in which this result will be named. 00300 /// 00301 /// \param Hiding the declaration that hides the result. 00302 /// 00303 /// \param InBaseClass whether the result was found in a base 00304 /// class of the searched context. 00305 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding, 00306 bool InBaseClass); 00307 00308 /// \brief Add a new non-declaration result to this result set. 00309 void AddResult(Result R); 00310 00311 /// \brief Enter into a new scope. 00312 void EnterNewScope(); 00313 00314 /// \brief Exit from the current scope. 00315 void ExitScope(); 00316 00317 /// \brief Ignore this declaration, if it is seen again. 00318 void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); } 00319 00320 /// \name Name lookup predicates 00321 /// 00322 /// These predicates can be passed to the name lookup functions to filter the 00323 /// results of name lookup. All of the predicates have the same type, so that 00324 /// 00325 //@{ 00326 bool IsOrdinaryName(const NamedDecl *ND) const; 00327 bool IsOrdinaryNonTypeName(const NamedDecl *ND) const; 00328 bool IsIntegralConstantValue(const NamedDecl *ND) const; 00329 bool IsOrdinaryNonValueName(const NamedDecl *ND) const; 00330 bool IsNestedNameSpecifier(const NamedDecl *ND) const; 00331 bool IsEnum(const NamedDecl *ND) const; 00332 bool IsClassOrStruct(const NamedDecl *ND) const; 00333 bool IsUnion(const NamedDecl *ND) const; 00334 bool IsNamespace(const NamedDecl *ND) const; 00335 bool IsNamespaceOrAlias(const NamedDecl *ND) const; 00336 bool IsType(const NamedDecl *ND) const; 00337 bool IsMember(const NamedDecl *ND) const; 00338 bool IsObjCIvar(const NamedDecl *ND) const; 00339 bool IsObjCMessageReceiver(const NamedDecl *ND) const; 00340 bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const; 00341 bool IsObjCCollection(const NamedDecl *ND) const; 00342 bool IsImpossibleToSatisfy(const NamedDecl *ND) const; 00343 //@} 00344 }; 00345 } 00346 00347 class ResultBuilder::ShadowMapEntry::iterator { 00348 llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator; 00349 unsigned SingleDeclIndex; 00350 00351 public: 00352 typedef DeclIndexPair value_type; 00353 typedef value_type reference; 00354 typedef std::ptrdiff_t difference_type; 00355 typedef std::input_iterator_tag iterator_category; 00356 00357 class pointer { 00358 DeclIndexPair Value; 00359 00360 public: 00361 pointer(const DeclIndexPair &Value) : Value(Value) { } 00362 00363 const DeclIndexPair *operator->() const { 00364 return &Value; 00365 } 00366 }; 00367 00368 iterator() : DeclOrIterator((NamedDecl *)nullptr), SingleDeclIndex(0) {} 00369 00370 iterator(const NamedDecl *SingleDecl, unsigned Index) 00371 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { } 00372 00373 iterator(const DeclIndexPair *Iterator) 00374 : DeclOrIterator(Iterator), SingleDeclIndex(0) { } 00375 00376 iterator &operator++() { 00377 if (DeclOrIterator.is<const NamedDecl *>()) { 00378 DeclOrIterator = (NamedDecl *)nullptr; 00379 SingleDeclIndex = 0; 00380 return *this; 00381 } 00382 00383 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>(); 00384 ++I; 00385 DeclOrIterator = I; 00386 return *this; 00387 } 00388 00389 /*iterator operator++(int) { 00390 iterator tmp(*this); 00391 ++(*this); 00392 return tmp; 00393 }*/ 00394 00395 reference operator*() const { 00396 if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>()) 00397 return reference(ND, SingleDeclIndex); 00398 00399 return *DeclOrIterator.get<const DeclIndexPair*>(); 00400 } 00401 00402 pointer operator->() const { 00403 return pointer(**this); 00404 } 00405 00406 friend bool operator==(const iterator &X, const iterator &Y) { 00407 return X.DeclOrIterator.getOpaqueValue() 00408 == Y.DeclOrIterator.getOpaqueValue() && 00409 X.SingleDeclIndex == Y.SingleDeclIndex; 00410 } 00411 00412 friend bool operator!=(const iterator &X, const iterator &Y) { 00413 return !(X == Y); 00414 } 00415 }; 00416 00417 ResultBuilder::ShadowMapEntry::iterator 00418 ResultBuilder::ShadowMapEntry::begin() const { 00419 if (DeclOrVector.isNull()) 00420 return iterator(); 00421 00422 if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>()) 00423 return iterator(ND, SingleDeclIndex); 00424 00425 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin()); 00426 } 00427 00428 ResultBuilder::ShadowMapEntry::iterator 00429 ResultBuilder::ShadowMapEntry::end() const { 00430 if (DeclOrVector.is<const NamedDecl *>() || DeclOrVector.isNull()) 00431 return iterator(); 00432 00433 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end()); 00434 } 00435 00436 /// \brief Compute the qualification required to get from the current context 00437 /// (\p CurContext) to the target context (\p TargetContext). 00438 /// 00439 /// \param Context the AST context in which the qualification will be used. 00440 /// 00441 /// \param CurContext the context where an entity is being named, which is 00442 /// typically based on the current scope. 00443 /// 00444 /// \param TargetContext the context in which the named entity actually 00445 /// resides. 00446 /// 00447 /// \returns a nested name specifier that refers into the target context, or 00448 /// NULL if no qualification is needed. 00449 static NestedNameSpecifier * 00450 getRequiredQualification(ASTContext &Context, 00451 const DeclContext *CurContext, 00452 const DeclContext *TargetContext) { 00453 SmallVector<const DeclContext *, 4> TargetParents; 00454 00455 for (const DeclContext *CommonAncestor = TargetContext; 00456 CommonAncestor && !CommonAncestor->Encloses(CurContext); 00457 CommonAncestor = CommonAncestor->getLookupParent()) { 00458 if (CommonAncestor->isTransparentContext() || 00459 CommonAncestor->isFunctionOrMethod()) 00460 continue; 00461 00462 TargetParents.push_back(CommonAncestor); 00463 } 00464 00465 NestedNameSpecifier *Result = nullptr; 00466 while (!TargetParents.empty()) { 00467 const DeclContext *Parent = TargetParents.pop_back_val(); 00468 00469 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) { 00470 if (!Namespace->getIdentifier()) 00471 continue; 00472 00473 Result = NestedNameSpecifier::Create(Context, Result, Namespace); 00474 } 00475 else if (const TagDecl *TD = dyn_cast<TagDecl>(Parent)) 00476 Result = NestedNameSpecifier::Create(Context, Result, 00477 false, 00478 Context.getTypeDeclType(TD).getTypePtr()); 00479 } 00480 return Result; 00481 } 00482 00483 /// Determine whether \p Id is a name reserved for the implementation (C99 00484 /// 7.1.3, C++ [lib.global.names]). 00485 static bool isReservedName(const IdentifierInfo *Id) { 00486 if (Id->getLength() < 2) 00487 return false; 00488 const char *Name = Id->getNameStart(); 00489 return Name[0] == '_' && 00490 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')); 00491 } 00492 00493 bool ResultBuilder::isInterestingDecl(const NamedDecl *ND, 00494 bool &AsNestedNameSpecifier) const { 00495 AsNestedNameSpecifier = false; 00496 00497 ND = ND->getUnderlyingDecl(); 00498 unsigned IDNS = ND->getIdentifierNamespace(); 00499 00500 // Skip unnamed entities. 00501 if (!ND->getDeclName()) 00502 return false; 00503 00504 // Friend declarations and declarations introduced due to friends are never 00505 // added as results. 00506 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)) 00507 return false; 00508 00509 // Class template (partial) specializations are never added as results. 00510 if (isa<ClassTemplateSpecializationDecl>(ND) || 00511 isa<ClassTemplatePartialSpecializationDecl>(ND)) 00512 return false; 00513 00514 // Using declarations themselves are never added as results. 00515 if (isa<UsingDecl>(ND)) 00516 return false; 00517 00518 // Some declarations have reserved names that we don't want to ever show. 00519 // Filter out names reserved for the implementation if they come from a 00520 // system header. 00521 // TODO: Add a predicate for this. 00522 if (const IdentifierInfo *Id = ND->getIdentifier()) 00523 if (isReservedName(Id) && 00524 (ND->getLocation().isInvalid() || 00525 SemaRef.SourceMgr.isInSystemHeader( 00526 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation())))) 00527 return false; 00528 00529 if (Filter == &ResultBuilder::IsNestedNameSpecifier || 00530 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) && 00531 Filter != &ResultBuilder::IsNamespace && 00532 Filter != &ResultBuilder::IsNamespaceOrAlias && 00533 Filter != nullptr)) 00534 AsNestedNameSpecifier = true; 00535 00536 // Filter out any unwanted results. 00537 if (Filter && !(this->*Filter)(ND)) { 00538 // Check whether it is interesting as a nested-name-specifier. 00539 if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus && 00540 IsNestedNameSpecifier(ND) && 00541 (Filter != &ResultBuilder::IsMember || 00542 (isa<CXXRecordDecl>(ND) && 00543 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) { 00544 AsNestedNameSpecifier = true; 00545 return true; 00546 } 00547 00548 return false; 00549 } 00550 // ... then it must be interesting! 00551 return true; 00552 } 00553 00554 bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext, 00555 const NamedDecl *Hiding) { 00556 // In C, there is no way to refer to a hidden name. 00557 // FIXME: This isn't true; we can find a tag name hidden by an ordinary 00558 // name if we introduce the tag type. 00559 if (!SemaRef.getLangOpts().CPlusPlus) 00560 return true; 00561 00562 const DeclContext *HiddenCtx = 00563 R.Declaration->getDeclContext()->getRedeclContext(); 00564 00565 // There is no way to qualify a name declared in a function or method. 00566 if (HiddenCtx->isFunctionOrMethod()) 00567 return true; 00568 00569 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext()) 00570 return true; 00571 00572 // We can refer to the result with the appropriate qualification. Do it. 00573 R.Hidden = true; 00574 R.QualifierIsInformative = false; 00575 00576 if (!R.Qualifier) 00577 R.Qualifier = getRequiredQualification(SemaRef.Context, 00578 CurContext, 00579 R.Declaration->getDeclContext()); 00580 return false; 00581 } 00582 00583 /// \brief A simplified classification of types used to determine whether two 00584 /// types are "similar enough" when adjusting priorities. 00585 SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) { 00586 switch (T->getTypeClass()) { 00587 case Type::Builtin: 00588 switch (cast<BuiltinType>(T)->getKind()) { 00589 case BuiltinType::Void: 00590 return STC_Void; 00591 00592 case BuiltinType::NullPtr: 00593 return STC_Pointer; 00594 00595 case BuiltinType::Overload: 00596 case BuiltinType::Dependent: 00597 return STC_Other; 00598 00599 case BuiltinType::ObjCId: 00600 case BuiltinType::ObjCClass: 00601 case BuiltinType::ObjCSel: 00602 return STC_ObjectiveC; 00603 00604 default: 00605 return STC_Arithmetic; 00606 } 00607 00608 case Type::Complex: 00609 return STC_Arithmetic; 00610 00611 case Type::Pointer: 00612 return STC_Pointer; 00613 00614 case Type::BlockPointer: 00615 return STC_Block; 00616 00617 case Type::LValueReference: 00618 case Type::RValueReference: 00619 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType()); 00620 00621 case Type::ConstantArray: 00622 case Type::IncompleteArray: 00623 case Type::VariableArray: 00624 case Type::DependentSizedArray: 00625 return STC_Array; 00626 00627 case Type::DependentSizedExtVector: 00628 case Type::Vector: 00629 case Type::ExtVector: 00630 return STC_Arithmetic; 00631 00632 case Type::FunctionProto: 00633 case Type::FunctionNoProto: 00634 return STC_Function; 00635 00636 case Type::Record: 00637 return STC_Record; 00638 00639 case Type::Enum: 00640 return STC_Arithmetic; 00641 00642 case Type::ObjCObject: 00643 case Type::ObjCInterface: 00644 case Type::ObjCObjectPointer: 00645 return STC_ObjectiveC; 00646 00647 default: 00648 return STC_Other; 00649 } 00650 } 00651 00652 /// \brief Get the type that a given expression will have if this declaration 00653 /// is used as an expression in its "typical" code-completion form. 00654 QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) { 00655 ND = cast<NamedDecl>(ND->getUnderlyingDecl()); 00656 00657 if (const TypeDecl *Type = dyn_cast<TypeDecl>(ND)) 00658 return C.getTypeDeclType(Type); 00659 if (const ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND)) 00660 return C.getObjCInterfaceType(Iface); 00661 00662 QualType T; 00663 if (const FunctionDecl *Function = ND->getAsFunction()) 00664 T = Function->getCallResultType(); 00665 else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) 00666 T = Method->getSendResultType(); 00667 else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) 00668 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext())); 00669 else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) 00670 T = Property->getType(); 00671 else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) 00672 T = Value->getType(); 00673 else 00674 return QualType(); 00675 00676 // Dig through references, function pointers, and block pointers to 00677 // get down to the likely type of an expression when the entity is 00678 // used. 00679 do { 00680 if (const ReferenceType *Ref = T->getAs<ReferenceType>()) { 00681 T = Ref->getPointeeType(); 00682 continue; 00683 } 00684 00685 if (const PointerType *Pointer = T->getAs<PointerType>()) { 00686 if (Pointer->getPointeeType()->isFunctionType()) { 00687 T = Pointer->getPointeeType(); 00688 continue; 00689 } 00690 00691 break; 00692 } 00693 00694 if (const BlockPointerType *Block = T->getAs<BlockPointerType>()) { 00695 T = Block->getPointeeType(); 00696 continue; 00697 } 00698 00699 if (const FunctionType *Function = T->getAs<FunctionType>()) { 00700 T = Function->getReturnType(); 00701 continue; 00702 } 00703 00704 break; 00705 } while (true); 00706 00707 return T; 00708 } 00709 00710 unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) { 00711 if (!ND) 00712 return CCP_Unlikely; 00713 00714 // Context-based decisions. 00715 const DeclContext *LexicalDC = ND->getLexicalDeclContext(); 00716 if (LexicalDC->isFunctionOrMethod()) { 00717 // _cmd is relatively rare 00718 if (const ImplicitParamDecl *ImplicitParam = 00719 dyn_cast<ImplicitParamDecl>(ND)) 00720 if (ImplicitParam->getIdentifier() && 00721 ImplicitParam->getIdentifier()->isStr("_cmd")) 00722 return CCP_ObjC_cmd; 00723 00724 return CCP_LocalDeclaration; 00725 } 00726 00727 const DeclContext *DC = ND->getDeclContext()->getRedeclContext(); 00728 if (DC->isRecord() || isa<ObjCContainerDecl>(DC)) 00729 return CCP_MemberDeclaration; 00730 00731 // Content-based decisions. 00732 if (isa<EnumConstantDecl>(ND)) 00733 return CCP_Constant; 00734 00735 // Use CCP_Type for type declarations unless we're in a statement, Objective-C 00736 // message receiver, or parenthesized expression context. There, it's as 00737 // likely that the user will want to write a type as other declarations. 00738 if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) && 00739 !(CompletionContext.getKind() == CodeCompletionContext::CCC_Statement || 00740 CompletionContext.getKind() 00741 == CodeCompletionContext::CCC_ObjCMessageReceiver || 00742 CompletionContext.getKind() 00743 == CodeCompletionContext::CCC_ParenthesizedExpression)) 00744 return CCP_Type; 00745 00746 return CCP_Declaration; 00747 } 00748 00749 void ResultBuilder::AdjustResultPriorityForDecl(Result &R) { 00750 // If this is an Objective-C method declaration whose selector matches our 00751 // preferred selector, give it a priority boost. 00752 if (!PreferredSelector.isNull()) 00753 if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration)) 00754 if (PreferredSelector == Method->getSelector()) 00755 R.Priority += CCD_SelectorMatch; 00756 00757 // If we have a preferred type, adjust the priority for results with exactly- 00758 // matching or nearly-matching types. 00759 if (!PreferredType.isNull()) { 00760 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration); 00761 if (!T.isNull()) { 00762 CanQualType TC = SemaRef.Context.getCanonicalType(T); 00763 // Check for exactly-matching types (modulo qualifiers). 00764 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) 00765 R.Priority /= CCF_ExactTypeMatch; 00766 // Check for nearly-matching types, based on classification of each. 00767 else if ((getSimplifiedTypeClass(PreferredType) 00768 == getSimplifiedTypeClass(TC)) && 00769 !(PreferredType->isEnumeralType() && TC->isEnumeralType())) 00770 R.Priority /= CCF_SimilarTypeMatch; 00771 } 00772 } 00773 } 00774 00775 void ResultBuilder::MaybeAddConstructorResults(Result R) { 00776 if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration || 00777 !CompletionContext.wantConstructorResults()) 00778 return; 00779 00780 ASTContext &Context = SemaRef.Context; 00781 const NamedDecl *D = R.Declaration; 00782 const CXXRecordDecl *Record = nullptr; 00783 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) 00784 Record = ClassTemplate->getTemplatedDecl(); 00785 else if ((Record = dyn_cast<CXXRecordDecl>(D))) { 00786 // Skip specializations and partial specializations. 00787 if (isa<ClassTemplateSpecializationDecl>(Record)) 00788 return; 00789 } else { 00790 // There are no constructors here. 00791 return; 00792 } 00793 00794 Record = Record->getDefinition(); 00795 if (!Record) 00796 return; 00797 00798 00799 QualType RecordTy = Context.getTypeDeclType(Record); 00800 DeclarationName ConstructorName 00801 = Context.DeclarationNames.getCXXConstructorName( 00802 Context.getCanonicalType(RecordTy)); 00803 DeclContext::lookup_const_result Ctors = Record->lookup(ConstructorName); 00804 for (DeclContext::lookup_const_iterator I = Ctors.begin(), 00805 E = Ctors.end(); 00806 I != E; ++I) { 00807 R.Declaration = *I; 00808 R.CursorKind = getCursorKindForDecl(R.Declaration); 00809 Results.push_back(R); 00810 } 00811 } 00812 00813 void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) { 00814 assert(!ShadowMaps.empty() && "Must enter into a results scope"); 00815 00816 if (R.Kind != Result::RK_Declaration) { 00817 // For non-declaration results, just add the result. 00818 Results.push_back(R); 00819 return; 00820 } 00821 00822 // Look through using declarations. 00823 if (const UsingShadowDecl *Using = 00824 dyn_cast<UsingShadowDecl>(R.Declaration)) { 00825 MaybeAddResult(Result(Using->getTargetDecl(), 00826 getBasePriority(Using->getTargetDecl()), 00827 R.Qualifier), 00828 CurContext); 00829 return; 00830 } 00831 00832 const Decl *CanonDecl = R.Declaration->getCanonicalDecl(); 00833 unsigned IDNS = CanonDecl->getIdentifierNamespace(); 00834 00835 bool AsNestedNameSpecifier = false; 00836 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier)) 00837 return; 00838 00839 // C++ constructors are never found by name lookup. 00840 if (isa<CXXConstructorDecl>(R.Declaration)) 00841 return; 00842 00843 ShadowMap &SMap = ShadowMaps.back(); 00844 ShadowMapEntry::iterator I, IEnd; 00845 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName()); 00846 if (NamePos != SMap.end()) { 00847 I = NamePos->second.begin(); 00848 IEnd = NamePos->second.end(); 00849 } 00850 00851 for (; I != IEnd; ++I) { 00852 const NamedDecl *ND = I->first; 00853 unsigned Index = I->second; 00854 if (ND->getCanonicalDecl() == CanonDecl) { 00855 // This is a redeclaration. Always pick the newer declaration. 00856 Results[Index].Declaration = R.Declaration; 00857 00858 // We're done. 00859 return; 00860 } 00861 } 00862 00863 // This is a new declaration in this scope. However, check whether this 00864 // declaration name is hidden by a similarly-named declaration in an outer 00865 // scope. 00866 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end(); 00867 --SMEnd; 00868 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) { 00869 ShadowMapEntry::iterator I, IEnd; 00870 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName()); 00871 if (NamePos != SM->end()) { 00872 I = NamePos->second.begin(); 00873 IEnd = NamePos->second.end(); 00874 } 00875 for (; I != IEnd; ++I) { 00876 // A tag declaration does not hide a non-tag declaration. 00877 if (I->first->hasTagIdentifierNamespace() && 00878 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary | 00879 Decl::IDNS_LocalExtern | Decl::IDNS_ObjCProtocol))) 00880 continue; 00881 00882 // Protocols are in distinct namespaces from everything else. 00883 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol) 00884 || (IDNS & Decl::IDNS_ObjCProtocol)) && 00885 I->first->getIdentifierNamespace() != IDNS) 00886 continue; 00887 00888 // The newly-added result is hidden by an entry in the shadow map. 00889 if (CheckHiddenResult(R, CurContext, I->first)) 00890 return; 00891 00892 break; 00893 } 00894 } 00895 00896 // Make sure that any given declaration only shows up in the result set once. 00897 if (!AllDeclsFound.insert(CanonDecl)) 00898 return; 00899 00900 // If the filter is for nested-name-specifiers, then this result starts a 00901 // nested-name-specifier. 00902 if (AsNestedNameSpecifier) { 00903 R.StartsNestedNameSpecifier = true; 00904 R.Priority = CCP_NestedNameSpecifier; 00905 } else 00906 AdjustResultPriorityForDecl(R); 00907 00908 // If this result is supposed to have an informative qualifier, add one. 00909 if (R.QualifierIsInformative && !R.Qualifier && 00910 !R.StartsNestedNameSpecifier) { 00911 const DeclContext *Ctx = R.Declaration->getDeclContext(); 00912 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx)) 00913 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, 00914 Namespace); 00915 else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx)) 00916 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, 00917 false, SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); 00918 else 00919 R.QualifierIsInformative = false; 00920 } 00921 00922 // Insert this result into the set of results and into the current shadow 00923 // map. 00924 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size()); 00925 Results.push_back(R); 00926 00927 if (!AsNestedNameSpecifier) 00928 MaybeAddConstructorResults(R); 00929 } 00930 00931 void ResultBuilder::AddResult(Result R, DeclContext *CurContext, 00932 NamedDecl *Hiding, bool InBaseClass = false) { 00933 if (R.Kind != Result::RK_Declaration) { 00934 // For non-declaration results, just add the result. 00935 Results.push_back(R); 00936 return; 00937 } 00938 00939 // Look through using declarations. 00940 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) { 00941 AddResult(Result(Using->getTargetDecl(), 00942 getBasePriority(Using->getTargetDecl()), 00943 R.Qualifier), 00944 CurContext, Hiding); 00945 return; 00946 } 00947 00948 bool AsNestedNameSpecifier = false; 00949 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier)) 00950 return; 00951 00952 // C++ constructors are never found by name lookup. 00953 if (isa<CXXConstructorDecl>(R.Declaration)) 00954 return; 00955 00956 if (Hiding && CheckHiddenResult(R, CurContext, Hiding)) 00957 return; 00958 00959 // Make sure that any given declaration only shows up in the result set once. 00960 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl())) 00961 return; 00962 00963 // If the filter is for nested-name-specifiers, then this result starts a 00964 // nested-name-specifier. 00965 if (AsNestedNameSpecifier) { 00966 R.StartsNestedNameSpecifier = true; 00967 R.Priority = CCP_NestedNameSpecifier; 00968 } 00969 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass && 00970 isa<CXXRecordDecl>(R.Declaration->getDeclContext() 00971 ->getRedeclContext())) 00972 R.QualifierIsInformative = true; 00973 00974 // If this result is supposed to have an informative qualifier, add one. 00975 if (R.QualifierIsInformative && !R.Qualifier && 00976 !R.StartsNestedNameSpecifier) { 00977 const DeclContext *Ctx = R.Declaration->getDeclContext(); 00978 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx)) 00979 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, 00980 Namespace); 00981 else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx)) 00982 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, false, 00983 SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); 00984 else 00985 R.QualifierIsInformative = false; 00986 } 00987 00988 // Adjust the priority if this result comes from a base class. 00989 if (InBaseClass) 00990 R.Priority += CCD_InBaseClass; 00991 00992 AdjustResultPriorityForDecl(R); 00993 00994 if (HasObjectTypeQualifiers) 00995 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration)) 00996 if (Method->isInstance()) { 00997 Qualifiers MethodQuals 00998 = Qualifiers::fromCVRMask(Method->getTypeQualifiers()); 00999 if (ObjectTypeQualifiers == MethodQuals) 01000 R.Priority += CCD_ObjectQualifierMatch; 01001 else if (ObjectTypeQualifiers - MethodQuals) { 01002 // The method cannot be invoked, because doing so would drop 01003 // qualifiers. 01004 return; 01005 } 01006 } 01007 01008 // Insert this result into the set of results. 01009 Results.push_back(R); 01010 01011 if (!AsNestedNameSpecifier) 01012 MaybeAddConstructorResults(R); 01013 } 01014 01015 void ResultBuilder::AddResult(Result R) { 01016 assert(R.Kind != Result::RK_Declaration && 01017 "Declaration results need more context"); 01018 Results.push_back(R); 01019 } 01020 01021 /// \brief Enter into a new scope. 01022 void ResultBuilder::EnterNewScope() { 01023 ShadowMaps.push_back(ShadowMap()); 01024 } 01025 01026 /// \brief Exit from the current scope. 01027 void ResultBuilder::ExitScope() { 01028 for (ShadowMap::iterator E = ShadowMaps.back().begin(), 01029 EEnd = ShadowMaps.back().end(); 01030 E != EEnd; 01031 ++E) 01032 E->second.Destroy(); 01033 01034 ShadowMaps.pop_back(); 01035 } 01036 01037 /// \brief Determines whether this given declaration will be found by 01038 /// ordinary name lookup. 01039 bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const { 01040 ND = cast<NamedDecl>(ND->getUnderlyingDecl()); 01041 01042 // If name lookup finds a local extern declaration, then we are in a 01043 // context where it behaves like an ordinary name. 01044 unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; 01045 if (SemaRef.getLangOpts().CPlusPlus) 01046 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; 01047 else if (SemaRef.getLangOpts().ObjC1) { 01048 if (isa<ObjCIvarDecl>(ND)) 01049 return true; 01050 } 01051 01052 return ND->getIdentifierNamespace() & IDNS; 01053 } 01054 01055 /// \brief Determines whether this given declaration will be found by 01056 /// ordinary name lookup but is not a type name. 01057 bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const { 01058 ND = cast<NamedDecl>(ND->getUnderlyingDecl()); 01059 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) 01060 return false; 01061 01062 unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; 01063 if (SemaRef.getLangOpts().CPlusPlus) 01064 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; 01065 else if (SemaRef.getLangOpts().ObjC1) { 01066 if (isa<ObjCIvarDecl>(ND)) 01067 return true; 01068 } 01069 01070 return ND->getIdentifierNamespace() & IDNS; 01071 } 01072 01073 bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const { 01074 if (!IsOrdinaryNonTypeName(ND)) 01075 return 0; 01076 01077 if (const ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl())) 01078 if (VD->getType()->isIntegralOrEnumerationType()) 01079 return true; 01080 01081 return false; 01082 } 01083 01084 /// \brief Determines whether this given declaration will be found by 01085 /// ordinary name lookup. 01086 bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const { 01087 ND = cast<NamedDecl>(ND->getUnderlyingDecl()); 01088 01089 unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; 01090 if (SemaRef.getLangOpts().CPlusPlus) 01091 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace; 01092 01093 return (ND->getIdentifierNamespace() & IDNS) && 01094 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) && 01095 !isa<ObjCPropertyDecl>(ND); 01096 } 01097 01098 /// \brief Determines whether the given declaration is suitable as the 01099 /// start of a C++ nested-name-specifier, e.g., a class or namespace. 01100 bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const { 01101 // Allow us to find class templates, too. 01102 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) 01103 ND = ClassTemplate->getTemplatedDecl(); 01104 01105 return SemaRef.isAcceptableNestedNameSpecifier(ND); 01106 } 01107 01108 /// \brief Determines whether the given declaration is an enumeration. 01109 bool ResultBuilder::IsEnum(const NamedDecl *ND) const { 01110 return isa<EnumDecl>(ND); 01111 } 01112 01113 /// \brief Determines whether the given declaration is a class or struct. 01114 bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const { 01115 // Allow us to find class templates, too. 01116 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) 01117 ND = ClassTemplate->getTemplatedDecl(); 01118 01119 // For purposes of this check, interfaces match too. 01120 if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND)) 01121 return RD->getTagKind() == TTK_Class || 01122 RD->getTagKind() == TTK_Struct || 01123 RD->getTagKind() == TTK_Interface; 01124 01125 return false; 01126 } 01127 01128 /// \brief Determines whether the given declaration is a union. 01129 bool ResultBuilder::IsUnion(const NamedDecl *ND) const { 01130 // Allow us to find class templates, too. 01131 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) 01132 ND = ClassTemplate->getTemplatedDecl(); 01133 01134 if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND)) 01135 return RD->getTagKind() == TTK_Union; 01136 01137 return false; 01138 } 01139 01140 /// \brief Determines whether the given declaration is a namespace. 01141 bool ResultBuilder::IsNamespace(const NamedDecl *ND) const { 01142 return isa<NamespaceDecl>(ND); 01143 } 01144 01145 /// \brief Determines whether the given declaration is a namespace or 01146 /// namespace alias. 01147 bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const { 01148 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND); 01149 } 01150 01151 /// \brief Determines whether the given declaration is a type. 01152 bool ResultBuilder::IsType(const NamedDecl *ND) const { 01153 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND)) 01154 ND = Using->getTargetDecl(); 01155 01156 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND); 01157 } 01158 01159 /// \brief Determines which members of a class should be visible via 01160 /// "." or "->". Only value declarations, nested name specifiers, and 01161 /// using declarations thereof should show up. 01162 bool ResultBuilder::IsMember(const NamedDecl *ND) const { 01163 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND)) 01164 ND = Using->getTargetDecl(); 01165 01166 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) || 01167 isa<ObjCPropertyDecl>(ND); 01168 } 01169 01170 static bool isObjCReceiverType(ASTContext &C, QualType T) { 01171 T = C.getCanonicalType(T); 01172 switch (T->getTypeClass()) { 01173 case Type::ObjCObject: 01174 case Type::ObjCInterface: 01175 case Type::ObjCObjectPointer: 01176 return true; 01177 01178 case Type::Builtin: 01179 switch (cast<BuiltinType>(T)->getKind()) { 01180 case BuiltinType::ObjCId: 01181 case BuiltinType::ObjCClass: 01182 case BuiltinType::ObjCSel: 01183 return true; 01184 01185 default: 01186 break; 01187 } 01188 return false; 01189 01190 default: 01191 break; 01192 } 01193 01194 if (!C.getLangOpts().CPlusPlus) 01195 return false; 01196 01197 // FIXME: We could perform more analysis here to determine whether a 01198 // particular class type has any conversions to Objective-C types. For now, 01199 // just accept all class types. 01200 return T->isDependentType() || T->isRecordType(); 01201 } 01202 01203 bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const { 01204 QualType T = getDeclUsageType(SemaRef.Context, ND); 01205 if (T.isNull()) 01206 return false; 01207 01208 T = SemaRef.Context.getBaseElementType(T); 01209 return isObjCReceiverType(SemaRef.Context, T); 01210 } 01211 01212 bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const { 01213 if (IsObjCMessageReceiver(ND)) 01214 return true; 01215 01216 const VarDecl *Var = dyn_cast<VarDecl>(ND); 01217 if (!Var) 01218 return false; 01219 01220 return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>(); 01221 } 01222 01223 bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const { 01224 if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) || 01225 (!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND))) 01226 return false; 01227 01228 QualType T = getDeclUsageType(SemaRef.Context, ND); 01229 if (T.isNull()) 01230 return false; 01231 01232 T = SemaRef.Context.getBaseElementType(T); 01233 return T->isObjCObjectType() || T->isObjCObjectPointerType() || 01234 T->isObjCIdType() || 01235 (SemaRef.getLangOpts().CPlusPlus && T->isRecordType()); 01236 } 01237 01238 bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const { 01239 return false; 01240 } 01241 01242 /// \brief Determines whether the given declaration is an Objective-C 01243 /// instance variable. 01244 bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const { 01245 return isa<ObjCIvarDecl>(ND); 01246 } 01247 01248 namespace { 01249 /// \brief Visible declaration consumer that adds a code-completion result 01250 /// for each visible declaration. 01251 class CodeCompletionDeclConsumer : public VisibleDeclConsumer { 01252 ResultBuilder &Results; 01253 DeclContext *CurContext; 01254 01255 public: 01256 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext) 01257 : Results(Results), CurContext(CurContext) { } 01258 01259 void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, 01260 bool InBaseClass) override { 01261 bool Accessible = true; 01262 if (Ctx) 01263 Accessible = Results.getSema().IsSimplyAccessible(ND, Ctx); 01264 01265 ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr, 01266 false, Accessible); 01267 Results.AddResult(Result, CurContext, Hiding, InBaseClass); 01268 } 01269 }; 01270 } 01271 01272 /// \brief Add type specifiers for the current language as keyword results. 01273 static void AddTypeSpecifierResults(const LangOptions &LangOpts, 01274 ResultBuilder &Results) { 01275 typedef CodeCompletionResult Result; 01276 Results.AddResult(Result("short", CCP_Type)); 01277 Results.AddResult(Result("long", CCP_Type)); 01278 Results.AddResult(Result("signed", CCP_Type)); 01279 Results.AddResult(Result("unsigned", CCP_Type)); 01280 Results.AddResult(Result("void", CCP_Type)); 01281 Results.AddResult(Result("char", CCP_Type)); 01282 Results.AddResult(Result("int", CCP_Type)); 01283 Results.AddResult(Result("float", CCP_Type)); 01284 Results.AddResult(Result("double", CCP_Type)); 01285 Results.AddResult(Result("enum", CCP_Type)); 01286 Results.AddResult(Result("struct", CCP_Type)); 01287 Results.AddResult(Result("union", CCP_Type)); 01288 Results.AddResult(Result("const", CCP_Type)); 01289 Results.AddResult(Result("volatile", CCP_Type)); 01290 01291 if (LangOpts.C99) { 01292 // C99-specific 01293 Results.AddResult(Result("_Complex", CCP_Type)); 01294 Results.AddResult(Result("_Imaginary", CCP_Type)); 01295 Results.AddResult(Result("_Bool", CCP_Type)); 01296 Results.AddResult(Result("restrict", CCP_Type)); 01297 } 01298 01299 CodeCompletionBuilder Builder(Results.getAllocator(), 01300 Results.getCodeCompletionTUInfo()); 01301 if (LangOpts.CPlusPlus) { 01302 // C++-specific 01303 Results.AddResult(Result("bool", CCP_Type + 01304 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0))); 01305 Results.AddResult(Result("class", CCP_Type)); 01306 Results.AddResult(Result("wchar_t", CCP_Type)); 01307 01308 // typename qualified-id 01309 Builder.AddTypedTextChunk("typename"); 01310 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01311 Builder.AddPlaceholderChunk("qualifier"); 01312 Builder.AddTextChunk("::"); 01313 Builder.AddPlaceholderChunk("name"); 01314 Results.AddResult(Result(Builder.TakeString())); 01315 01316 if (LangOpts.CPlusPlus11) { 01317 Results.AddResult(Result("auto", CCP_Type)); 01318 Results.AddResult(Result("char16_t", CCP_Type)); 01319 Results.AddResult(Result("char32_t", CCP_Type)); 01320 01321 Builder.AddTypedTextChunk("decltype"); 01322 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01323 Builder.AddPlaceholderChunk("expression"); 01324 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01325 Results.AddResult(Result(Builder.TakeString())); 01326 } 01327 } 01328 01329 // GNU extensions 01330 if (LangOpts.GNUMode) { 01331 // FIXME: Enable when we actually support decimal floating point. 01332 // Results.AddResult(Result("_Decimal32")); 01333 // Results.AddResult(Result("_Decimal64")); 01334 // Results.AddResult(Result("_Decimal128")); 01335 01336 Builder.AddTypedTextChunk("typeof"); 01337 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01338 Builder.AddPlaceholderChunk("expression"); 01339 Results.AddResult(Result(Builder.TakeString())); 01340 01341 Builder.AddTypedTextChunk("typeof"); 01342 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01343 Builder.AddPlaceholderChunk("type"); 01344 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01345 Results.AddResult(Result(Builder.TakeString())); 01346 } 01347 } 01348 01349 static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC, 01350 const LangOptions &LangOpts, 01351 ResultBuilder &Results) { 01352 typedef CodeCompletionResult Result; 01353 // Note: we don't suggest either "auto" or "register", because both 01354 // are pointless as storage specifiers. Elsewhere, we suggest "auto" 01355 // in C++0x as a type specifier. 01356 Results.AddResult(Result("extern")); 01357 Results.AddResult(Result("static")); 01358 } 01359 01360 static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC, 01361 const LangOptions &LangOpts, 01362 ResultBuilder &Results) { 01363 typedef CodeCompletionResult Result; 01364 switch (CCC) { 01365 case Sema::PCC_Class: 01366 case Sema::PCC_MemberTemplate: 01367 if (LangOpts.CPlusPlus) { 01368 Results.AddResult(Result("explicit")); 01369 Results.AddResult(Result("friend")); 01370 Results.AddResult(Result("mutable")); 01371 Results.AddResult(Result("virtual")); 01372 } 01373 // Fall through 01374 01375 case Sema::PCC_ObjCInterface: 01376 case Sema::PCC_ObjCImplementation: 01377 case Sema::PCC_Namespace: 01378 case Sema::PCC_Template: 01379 if (LangOpts.CPlusPlus || LangOpts.C99) 01380 Results.AddResult(Result("inline")); 01381 break; 01382 01383 case Sema::PCC_ObjCInstanceVariableList: 01384 case Sema::PCC_Expression: 01385 case Sema::PCC_Statement: 01386 case Sema::PCC_ForInit: 01387 case Sema::PCC_Condition: 01388 case Sema::PCC_RecoveryInFunction: 01389 case Sema::PCC_Type: 01390 case Sema::PCC_ParenthesizedExpression: 01391 case Sema::PCC_LocalDeclarationSpecifiers: 01392 break; 01393 } 01394 } 01395 01396 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt); 01397 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt); 01398 static void AddObjCVisibilityResults(const LangOptions &LangOpts, 01399 ResultBuilder &Results, 01400 bool NeedAt); 01401 static void AddObjCImplementationResults(const LangOptions &LangOpts, 01402 ResultBuilder &Results, 01403 bool NeedAt); 01404 static void AddObjCInterfaceResults(const LangOptions &LangOpts, 01405 ResultBuilder &Results, 01406 bool NeedAt); 01407 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt); 01408 01409 static void AddTypedefResult(ResultBuilder &Results) { 01410 CodeCompletionBuilder Builder(Results.getAllocator(), 01411 Results.getCodeCompletionTUInfo()); 01412 Builder.AddTypedTextChunk("typedef"); 01413 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01414 Builder.AddPlaceholderChunk("type"); 01415 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01416 Builder.AddPlaceholderChunk("name"); 01417 Results.AddResult(CodeCompletionResult(Builder.TakeString())); 01418 } 01419 01420 static bool WantTypesInContext(Sema::ParserCompletionContext CCC, 01421 const LangOptions &LangOpts) { 01422 switch (CCC) { 01423 case Sema::PCC_Namespace: 01424 case Sema::PCC_Class: 01425 case Sema::PCC_ObjCInstanceVariableList: 01426 case Sema::PCC_Template: 01427 case Sema::PCC_MemberTemplate: 01428 case Sema::PCC_Statement: 01429 case Sema::PCC_RecoveryInFunction: 01430 case Sema::PCC_Type: 01431 case Sema::PCC_ParenthesizedExpression: 01432 case Sema::PCC_LocalDeclarationSpecifiers: 01433 return true; 01434 01435 case Sema::PCC_Expression: 01436 case Sema::PCC_Condition: 01437 return LangOpts.CPlusPlus; 01438 01439 case Sema::PCC_ObjCInterface: 01440 case Sema::PCC_ObjCImplementation: 01441 return false; 01442 01443 case Sema::PCC_ForInit: 01444 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99; 01445 } 01446 01447 llvm_unreachable("Invalid ParserCompletionContext!"); 01448 } 01449 01450 static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context, 01451 const Preprocessor &PP) { 01452 PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP); 01453 Policy.AnonymousTagLocations = false; 01454 Policy.SuppressStrongLifetime = true; 01455 Policy.SuppressUnwrittenScope = true; 01456 return Policy; 01457 } 01458 01459 /// \brief Retrieve a printing policy suitable for code completion. 01460 static PrintingPolicy getCompletionPrintingPolicy(Sema &S) { 01461 return getCompletionPrintingPolicy(S.Context, S.PP); 01462 } 01463 01464 /// \brief Retrieve the string representation of the given type as a string 01465 /// that has the appropriate lifetime for code completion. 01466 /// 01467 /// This routine provides a fast path where we provide constant strings for 01468 /// common type names. 01469 static const char *GetCompletionTypeString(QualType T, 01470 ASTContext &Context, 01471 const PrintingPolicy &Policy, 01472 CodeCompletionAllocator &Allocator) { 01473 if (!T.getLocalQualifiers()) { 01474 // Built-in type names are constant strings. 01475 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T)) 01476 return BT->getNameAsCString(Policy); 01477 01478 // Anonymous tag types are constant strings. 01479 if (const TagType *TagT = dyn_cast<TagType>(T)) 01480 if (TagDecl *Tag = TagT->getDecl()) 01481 if (!Tag->hasNameForLinkage()) { 01482 switch (Tag->getTagKind()) { 01483 case TTK_Struct: return "struct <anonymous>"; 01484 case TTK_Interface: return "__interface <anonymous>"; 01485 case TTK_Class: return "class <anonymous>"; 01486 case TTK_Union: return "union <anonymous>"; 01487 case TTK_Enum: return "enum <anonymous>"; 01488 } 01489 } 01490 } 01491 01492 // Slow path: format the type as a string. 01493 std::string Result; 01494 T.getAsStringInternal(Result, Policy); 01495 return Allocator.CopyString(Result); 01496 } 01497 01498 /// \brief Add a completion for "this", if we're in a member function. 01499 static void addThisCompletion(Sema &S, ResultBuilder &Results) { 01500 QualType ThisTy = S.getCurrentThisType(); 01501 if (ThisTy.isNull()) 01502 return; 01503 01504 CodeCompletionAllocator &Allocator = Results.getAllocator(); 01505 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); 01506 PrintingPolicy Policy = getCompletionPrintingPolicy(S); 01507 Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy, 01508 S.Context, 01509 Policy, 01510 Allocator)); 01511 Builder.AddTypedTextChunk("this"); 01512 Results.AddResult(CodeCompletionResult(Builder.TakeString())); 01513 } 01514 01515 /// \brief Add language constructs that show up for "ordinary" names. 01516 static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, 01517 Scope *S, 01518 Sema &SemaRef, 01519 ResultBuilder &Results) { 01520 CodeCompletionAllocator &Allocator = Results.getAllocator(); 01521 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); 01522 PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef); 01523 01524 typedef CodeCompletionResult Result; 01525 switch (CCC) { 01526 case Sema::PCC_Namespace: 01527 if (SemaRef.getLangOpts().CPlusPlus) { 01528 if (Results.includeCodePatterns()) { 01529 // namespace <identifier> { declarations } 01530 Builder.AddTypedTextChunk("namespace"); 01531 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01532 Builder.AddPlaceholderChunk("identifier"); 01533 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 01534 Builder.AddPlaceholderChunk("declarations"); 01535 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 01536 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 01537 Results.AddResult(Result(Builder.TakeString())); 01538 } 01539 01540 // namespace identifier = identifier ; 01541 Builder.AddTypedTextChunk("namespace"); 01542 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01543 Builder.AddPlaceholderChunk("name"); 01544 Builder.AddChunk(CodeCompletionString::CK_Equal); 01545 Builder.AddPlaceholderChunk("namespace"); 01546 Results.AddResult(Result(Builder.TakeString())); 01547 01548 // Using directives 01549 Builder.AddTypedTextChunk("using"); 01550 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01551 Builder.AddTextChunk("namespace"); 01552 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01553 Builder.AddPlaceholderChunk("identifier"); 01554 Results.AddResult(Result(Builder.TakeString())); 01555 01556 // asm(string-literal) 01557 Builder.AddTypedTextChunk("asm"); 01558 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01559 Builder.AddPlaceholderChunk("string-literal"); 01560 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01561 Results.AddResult(Result(Builder.TakeString())); 01562 01563 if (Results.includeCodePatterns()) { 01564 // Explicit template instantiation 01565 Builder.AddTypedTextChunk("template"); 01566 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01567 Builder.AddPlaceholderChunk("declaration"); 01568 Results.AddResult(Result(Builder.TakeString())); 01569 } 01570 } 01571 01572 if (SemaRef.getLangOpts().ObjC1) 01573 AddObjCTopLevelResults(Results, true); 01574 01575 AddTypedefResult(Results); 01576 // Fall through 01577 01578 case Sema::PCC_Class: 01579 if (SemaRef.getLangOpts().CPlusPlus) { 01580 // Using declaration 01581 Builder.AddTypedTextChunk("using"); 01582 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01583 Builder.AddPlaceholderChunk("qualifier"); 01584 Builder.AddTextChunk("::"); 01585 Builder.AddPlaceholderChunk("name"); 01586 Results.AddResult(Result(Builder.TakeString())); 01587 01588 // using typename qualifier::name (only in a dependent context) 01589 if (SemaRef.CurContext->isDependentContext()) { 01590 Builder.AddTypedTextChunk("using"); 01591 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01592 Builder.AddTextChunk("typename"); 01593 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01594 Builder.AddPlaceholderChunk("qualifier"); 01595 Builder.AddTextChunk("::"); 01596 Builder.AddPlaceholderChunk("name"); 01597 Results.AddResult(Result(Builder.TakeString())); 01598 } 01599 01600 if (CCC == Sema::PCC_Class) { 01601 AddTypedefResult(Results); 01602 01603 // public: 01604 Builder.AddTypedTextChunk("public"); 01605 if (Results.includeCodePatterns()) 01606 Builder.AddChunk(CodeCompletionString::CK_Colon); 01607 Results.AddResult(Result(Builder.TakeString())); 01608 01609 // protected: 01610 Builder.AddTypedTextChunk("protected"); 01611 if (Results.includeCodePatterns()) 01612 Builder.AddChunk(CodeCompletionString::CK_Colon); 01613 Results.AddResult(Result(Builder.TakeString())); 01614 01615 // private: 01616 Builder.AddTypedTextChunk("private"); 01617 if (Results.includeCodePatterns()) 01618 Builder.AddChunk(CodeCompletionString::CK_Colon); 01619 Results.AddResult(Result(Builder.TakeString())); 01620 } 01621 } 01622 // Fall through 01623 01624 case Sema::PCC_Template: 01625 case Sema::PCC_MemberTemplate: 01626 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) { 01627 // template < parameters > 01628 Builder.AddTypedTextChunk("template"); 01629 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 01630 Builder.AddPlaceholderChunk("parameters"); 01631 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 01632 Results.AddResult(Result(Builder.TakeString())); 01633 } 01634 01635 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); 01636 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results); 01637 break; 01638 01639 case Sema::PCC_ObjCInterface: 01640 AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true); 01641 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); 01642 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results); 01643 break; 01644 01645 case Sema::PCC_ObjCImplementation: 01646 AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true); 01647 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); 01648 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results); 01649 break; 01650 01651 case Sema::PCC_ObjCInstanceVariableList: 01652 AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true); 01653 break; 01654 01655 case Sema::PCC_RecoveryInFunction: 01656 case Sema::PCC_Statement: { 01657 AddTypedefResult(Results); 01658 01659 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() && 01660 SemaRef.getLangOpts().CXXExceptions) { 01661 Builder.AddTypedTextChunk("try"); 01662 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 01663 Builder.AddPlaceholderChunk("statements"); 01664 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 01665 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 01666 Builder.AddTextChunk("catch"); 01667 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01668 Builder.AddPlaceholderChunk("declaration"); 01669 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01670 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 01671 Builder.AddPlaceholderChunk("statements"); 01672 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 01673 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 01674 Results.AddResult(Result(Builder.TakeString())); 01675 } 01676 if (SemaRef.getLangOpts().ObjC1) 01677 AddObjCStatementResults(Results, true); 01678 01679 if (Results.includeCodePatterns()) { 01680 // if (condition) { statements } 01681 Builder.AddTypedTextChunk("if"); 01682 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01683 if (SemaRef.getLangOpts().CPlusPlus) 01684 Builder.AddPlaceholderChunk("condition"); 01685 else 01686 Builder.AddPlaceholderChunk("expression"); 01687 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01688 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 01689 Builder.AddPlaceholderChunk("statements"); 01690 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 01691 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 01692 Results.AddResult(Result(Builder.TakeString())); 01693 01694 // switch (condition) { } 01695 Builder.AddTypedTextChunk("switch"); 01696 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01697 if (SemaRef.getLangOpts().CPlusPlus) 01698 Builder.AddPlaceholderChunk("condition"); 01699 else 01700 Builder.AddPlaceholderChunk("expression"); 01701 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01702 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 01703 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 01704 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 01705 Results.AddResult(Result(Builder.TakeString())); 01706 } 01707 01708 // Switch-specific statements. 01709 if (!SemaRef.getCurFunction()->SwitchStack.empty()) { 01710 // case expression: 01711 Builder.AddTypedTextChunk("case"); 01712 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01713 Builder.AddPlaceholderChunk("expression"); 01714 Builder.AddChunk(CodeCompletionString::CK_Colon); 01715 Results.AddResult(Result(Builder.TakeString())); 01716 01717 // default: 01718 Builder.AddTypedTextChunk("default"); 01719 Builder.AddChunk(CodeCompletionString::CK_Colon); 01720 Results.AddResult(Result(Builder.TakeString())); 01721 } 01722 01723 if (Results.includeCodePatterns()) { 01724 /// while (condition) { statements } 01725 Builder.AddTypedTextChunk("while"); 01726 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01727 if (SemaRef.getLangOpts().CPlusPlus) 01728 Builder.AddPlaceholderChunk("condition"); 01729 else 01730 Builder.AddPlaceholderChunk("expression"); 01731 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01732 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 01733 Builder.AddPlaceholderChunk("statements"); 01734 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 01735 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 01736 Results.AddResult(Result(Builder.TakeString())); 01737 01738 // do { statements } while ( expression ); 01739 Builder.AddTypedTextChunk("do"); 01740 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 01741 Builder.AddPlaceholderChunk("statements"); 01742 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 01743 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 01744 Builder.AddTextChunk("while"); 01745 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01746 Builder.AddPlaceholderChunk("expression"); 01747 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01748 Results.AddResult(Result(Builder.TakeString())); 01749 01750 // for ( for-init-statement ; condition ; expression ) { statements } 01751 Builder.AddTypedTextChunk("for"); 01752 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01753 if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99) 01754 Builder.AddPlaceholderChunk("init-statement"); 01755 else 01756 Builder.AddPlaceholderChunk("init-expression"); 01757 Builder.AddChunk(CodeCompletionString::CK_SemiColon); 01758 Builder.AddPlaceholderChunk("condition"); 01759 Builder.AddChunk(CodeCompletionString::CK_SemiColon); 01760 Builder.AddPlaceholderChunk("inc-expression"); 01761 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01762 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 01763 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 01764 Builder.AddPlaceholderChunk("statements"); 01765 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 01766 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 01767 Results.AddResult(Result(Builder.TakeString())); 01768 } 01769 01770 if (S->getContinueParent()) { 01771 // continue ; 01772 Builder.AddTypedTextChunk("continue"); 01773 Results.AddResult(Result(Builder.TakeString())); 01774 } 01775 01776 if (S->getBreakParent()) { 01777 // break ; 01778 Builder.AddTypedTextChunk("break"); 01779 Results.AddResult(Result(Builder.TakeString())); 01780 } 01781 01782 // "return expression ;" or "return ;", depending on whether we 01783 // know the function is void or not. 01784 bool isVoid = false; 01785 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext)) 01786 isVoid = Function->getReturnType()->isVoidType(); 01787 else if (ObjCMethodDecl *Method 01788 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext)) 01789 isVoid = Method->getReturnType()->isVoidType(); 01790 else if (SemaRef.getCurBlock() && 01791 !SemaRef.getCurBlock()->ReturnType.isNull()) 01792 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType(); 01793 Builder.AddTypedTextChunk("return"); 01794 if (!isVoid) { 01795 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01796 Builder.AddPlaceholderChunk("expression"); 01797 } 01798 Results.AddResult(Result(Builder.TakeString())); 01799 01800 // goto identifier ; 01801 Builder.AddTypedTextChunk("goto"); 01802 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01803 Builder.AddPlaceholderChunk("label"); 01804 Results.AddResult(Result(Builder.TakeString())); 01805 01806 // Using directives 01807 Builder.AddTypedTextChunk("using"); 01808 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01809 Builder.AddTextChunk("namespace"); 01810 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01811 Builder.AddPlaceholderChunk("identifier"); 01812 Results.AddResult(Result(Builder.TakeString())); 01813 } 01814 01815 // Fall through (for statement expressions). 01816 case Sema::PCC_ForInit: 01817 case Sema::PCC_Condition: 01818 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); 01819 // Fall through: conditions and statements can have expressions. 01820 01821 case Sema::PCC_ParenthesizedExpression: 01822 if (SemaRef.getLangOpts().ObjCAutoRefCount && 01823 CCC == Sema::PCC_ParenthesizedExpression) { 01824 // (__bridge <type>)<expression> 01825 Builder.AddTypedTextChunk("__bridge"); 01826 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01827 Builder.AddPlaceholderChunk("type"); 01828 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01829 Builder.AddPlaceholderChunk("expression"); 01830 Results.AddResult(Result(Builder.TakeString())); 01831 01832 // (__bridge_transfer <Objective-C type>)<expression> 01833 Builder.AddTypedTextChunk("__bridge_transfer"); 01834 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01835 Builder.AddPlaceholderChunk("Objective-C type"); 01836 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01837 Builder.AddPlaceholderChunk("expression"); 01838 Results.AddResult(Result(Builder.TakeString())); 01839 01840 // (__bridge_retained <CF type>)<expression> 01841 Builder.AddTypedTextChunk("__bridge_retained"); 01842 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01843 Builder.AddPlaceholderChunk("CF type"); 01844 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01845 Builder.AddPlaceholderChunk("expression"); 01846 Results.AddResult(Result(Builder.TakeString())); 01847 } 01848 // Fall through 01849 01850 case Sema::PCC_Expression: { 01851 if (SemaRef.getLangOpts().CPlusPlus) { 01852 // 'this', if we're in a non-static member function. 01853 addThisCompletion(SemaRef, Results); 01854 01855 // true 01856 Builder.AddResultTypeChunk("bool"); 01857 Builder.AddTypedTextChunk("true"); 01858 Results.AddResult(Result(Builder.TakeString())); 01859 01860 // false 01861 Builder.AddResultTypeChunk("bool"); 01862 Builder.AddTypedTextChunk("false"); 01863 Results.AddResult(Result(Builder.TakeString())); 01864 01865 if (SemaRef.getLangOpts().RTTI) { 01866 // dynamic_cast < type-id > ( expression ) 01867 Builder.AddTypedTextChunk("dynamic_cast"); 01868 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 01869 Builder.AddPlaceholderChunk("type"); 01870 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 01871 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01872 Builder.AddPlaceholderChunk("expression"); 01873 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01874 Results.AddResult(Result(Builder.TakeString())); 01875 } 01876 01877 // static_cast < type-id > ( expression ) 01878 Builder.AddTypedTextChunk("static_cast"); 01879 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 01880 Builder.AddPlaceholderChunk("type"); 01881 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 01882 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01883 Builder.AddPlaceholderChunk("expression"); 01884 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01885 Results.AddResult(Result(Builder.TakeString())); 01886 01887 // reinterpret_cast < type-id > ( expression ) 01888 Builder.AddTypedTextChunk("reinterpret_cast"); 01889 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 01890 Builder.AddPlaceholderChunk("type"); 01891 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 01892 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01893 Builder.AddPlaceholderChunk("expression"); 01894 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01895 Results.AddResult(Result(Builder.TakeString())); 01896 01897 // const_cast < type-id > ( expression ) 01898 Builder.AddTypedTextChunk("const_cast"); 01899 Builder.AddChunk(CodeCompletionString::CK_LeftAngle); 01900 Builder.AddPlaceholderChunk("type"); 01901 Builder.AddChunk(CodeCompletionString::CK_RightAngle); 01902 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01903 Builder.AddPlaceholderChunk("expression"); 01904 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01905 Results.AddResult(Result(Builder.TakeString())); 01906 01907 if (SemaRef.getLangOpts().RTTI) { 01908 // typeid ( expression-or-type ) 01909 Builder.AddResultTypeChunk("std::type_info"); 01910 Builder.AddTypedTextChunk("typeid"); 01911 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01912 Builder.AddPlaceholderChunk("expression-or-type"); 01913 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01914 Results.AddResult(Result(Builder.TakeString())); 01915 } 01916 01917 // new T ( ... ) 01918 Builder.AddTypedTextChunk("new"); 01919 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01920 Builder.AddPlaceholderChunk("type"); 01921 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01922 Builder.AddPlaceholderChunk("expressions"); 01923 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01924 Results.AddResult(Result(Builder.TakeString())); 01925 01926 // new T [ ] ( ... ) 01927 Builder.AddTypedTextChunk("new"); 01928 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01929 Builder.AddPlaceholderChunk("type"); 01930 Builder.AddChunk(CodeCompletionString::CK_LeftBracket); 01931 Builder.AddPlaceholderChunk("size"); 01932 Builder.AddChunk(CodeCompletionString::CK_RightBracket); 01933 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01934 Builder.AddPlaceholderChunk("expressions"); 01935 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01936 Results.AddResult(Result(Builder.TakeString())); 01937 01938 // delete expression 01939 Builder.AddResultTypeChunk("void"); 01940 Builder.AddTypedTextChunk("delete"); 01941 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01942 Builder.AddPlaceholderChunk("expression"); 01943 Results.AddResult(Result(Builder.TakeString())); 01944 01945 // delete [] expression 01946 Builder.AddResultTypeChunk("void"); 01947 Builder.AddTypedTextChunk("delete"); 01948 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01949 Builder.AddChunk(CodeCompletionString::CK_LeftBracket); 01950 Builder.AddChunk(CodeCompletionString::CK_RightBracket); 01951 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01952 Builder.AddPlaceholderChunk("expression"); 01953 Results.AddResult(Result(Builder.TakeString())); 01954 01955 if (SemaRef.getLangOpts().CXXExceptions) { 01956 // throw expression 01957 Builder.AddResultTypeChunk("void"); 01958 Builder.AddTypedTextChunk("throw"); 01959 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 01960 Builder.AddPlaceholderChunk("expression"); 01961 Results.AddResult(Result(Builder.TakeString())); 01962 } 01963 01964 // FIXME: Rethrow? 01965 01966 if (SemaRef.getLangOpts().CPlusPlus11) { 01967 // nullptr 01968 Builder.AddResultTypeChunk("std::nullptr_t"); 01969 Builder.AddTypedTextChunk("nullptr"); 01970 Results.AddResult(Result(Builder.TakeString())); 01971 01972 // alignof 01973 Builder.AddResultTypeChunk("size_t"); 01974 Builder.AddTypedTextChunk("alignof"); 01975 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01976 Builder.AddPlaceholderChunk("type"); 01977 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01978 Results.AddResult(Result(Builder.TakeString())); 01979 01980 // noexcept 01981 Builder.AddResultTypeChunk("bool"); 01982 Builder.AddTypedTextChunk("noexcept"); 01983 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01984 Builder.AddPlaceholderChunk("expression"); 01985 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01986 Results.AddResult(Result(Builder.TakeString())); 01987 01988 // sizeof... expression 01989 Builder.AddResultTypeChunk("size_t"); 01990 Builder.AddTypedTextChunk("sizeof..."); 01991 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 01992 Builder.AddPlaceholderChunk("parameter-pack"); 01993 Builder.AddChunk(CodeCompletionString::CK_RightParen); 01994 Results.AddResult(Result(Builder.TakeString())); 01995 } 01996 } 01997 01998 if (SemaRef.getLangOpts().ObjC1) { 01999 // Add "super", if we're in an Objective-C class with a superclass. 02000 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) { 02001 // The interface can be NULL. 02002 if (ObjCInterfaceDecl *ID = Method->getClassInterface()) 02003 if (ID->getSuperClass()) { 02004 std::string SuperType; 02005 SuperType = ID->getSuperClass()->getNameAsString(); 02006 if (Method->isInstanceMethod()) 02007 SuperType += " *"; 02008 02009 Builder.AddResultTypeChunk(Allocator.CopyString(SuperType)); 02010 Builder.AddTypedTextChunk("super"); 02011 Results.AddResult(Result(Builder.TakeString())); 02012 } 02013 } 02014 02015 AddObjCExpressionResults(Results, true); 02016 } 02017 02018 if (SemaRef.getLangOpts().C11) { 02019 // _Alignof 02020 Builder.AddResultTypeChunk("size_t"); 02021 if (SemaRef.getASTContext().Idents.get("alignof").hasMacroDefinition()) 02022 Builder.AddTypedTextChunk("alignof"); 02023 else 02024 Builder.AddTypedTextChunk("_Alignof"); 02025 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 02026 Builder.AddPlaceholderChunk("type"); 02027 Builder.AddChunk(CodeCompletionString::CK_RightParen); 02028 Results.AddResult(Result(Builder.TakeString())); 02029 } 02030 02031 // sizeof expression 02032 Builder.AddResultTypeChunk("size_t"); 02033 Builder.AddTypedTextChunk("sizeof"); 02034 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 02035 Builder.AddPlaceholderChunk("expression-or-type"); 02036 Builder.AddChunk(CodeCompletionString::CK_RightParen); 02037 Results.AddResult(Result(Builder.TakeString())); 02038 break; 02039 } 02040 02041 case Sema::PCC_Type: 02042 case Sema::PCC_LocalDeclarationSpecifiers: 02043 break; 02044 } 02045 02046 if (WantTypesInContext(CCC, SemaRef.getLangOpts())) 02047 AddTypeSpecifierResults(SemaRef.getLangOpts(), Results); 02048 02049 if (SemaRef.getLangOpts().CPlusPlus && CCC != Sema::PCC_Type) 02050 Results.AddResult(Result("operator")); 02051 } 02052 02053 /// \brief If the given declaration has an associated type, add it as a result 02054 /// type chunk. 02055 static void AddResultTypeChunk(ASTContext &Context, 02056 const PrintingPolicy &Policy, 02057 const NamedDecl *ND, 02058 CodeCompletionBuilder &Result) { 02059 if (!ND) 02060 return; 02061 02062 // Skip constructors and conversion functions, which have their return types 02063 // built into their names. 02064 if (isa<CXXConstructorDecl>(ND) || isa<CXXConversionDecl>(ND)) 02065 return; 02066 02067 // Determine the type of the declaration (if it has a type). 02068 QualType T; 02069 if (const FunctionDecl *Function = ND->getAsFunction()) 02070 T = Function->getReturnType(); 02071 else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) 02072 T = Method->getReturnType(); 02073 else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) 02074 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext())); 02075 else if (isa<UnresolvedUsingValueDecl>(ND)) { 02076 /* Do nothing: ignore unresolved using declarations*/ 02077 } else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) { 02078 T = Value->getType(); 02079 } else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) 02080 T = Property->getType(); 02081 02082 if (T.isNull() || Context.hasSameType(T, Context.DependentTy)) 02083 return; 02084 02085 Result.AddResultTypeChunk(GetCompletionTypeString(T, Context, Policy, 02086 Result.getAllocator())); 02087 } 02088 02089 static void MaybeAddSentinel(ASTContext &Context, 02090 const NamedDecl *FunctionOrMethod, 02091 CodeCompletionBuilder &Result) { 02092 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>()) 02093 if (Sentinel->getSentinel() == 0) { 02094 if (Context.getLangOpts().ObjC1 && 02095 Context.Idents.get("nil").hasMacroDefinition()) 02096 Result.AddTextChunk(", nil"); 02097 else if (Context.Idents.get("NULL").hasMacroDefinition()) 02098 Result.AddTextChunk(", NULL"); 02099 else 02100 Result.AddTextChunk(", (void*)0"); 02101 } 02102 } 02103 02104 static std::string formatObjCParamQualifiers(unsigned ObjCQuals) { 02105 std::string Result; 02106 if (ObjCQuals & Decl::OBJC_TQ_In) 02107 Result += "in "; 02108 else if (ObjCQuals & Decl::OBJC_TQ_Inout) 02109 Result += "inout "; 02110 else if (ObjCQuals & Decl::OBJC_TQ_Out) 02111 Result += "out "; 02112 if (ObjCQuals & Decl::OBJC_TQ_Bycopy) 02113 Result += "bycopy "; 02114 else if (ObjCQuals & Decl::OBJC_TQ_Byref) 02115 Result += "byref "; 02116 if (ObjCQuals & Decl::OBJC_TQ_Oneway) 02117 Result += "oneway "; 02118 return Result; 02119 } 02120 02121 static std::string FormatFunctionParameter(ASTContext &Context, 02122 const PrintingPolicy &Policy, 02123 const ParmVarDecl *Param, 02124 bool SuppressName = false, 02125 bool SuppressBlock = false) { 02126 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext()); 02127 if (Param->getType()->isDependentType() || 02128 !Param->getType()->isBlockPointerType()) { 02129 // The argument for a dependent or non-block parameter is a placeholder 02130 // containing that parameter's type. 02131 std::string Result; 02132 02133 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName) 02134 Result = Param->getIdentifier()->getName(); 02135 02136 Param->getType().getAsStringInternal(Result, Policy); 02137 02138 if (ObjCMethodParam) { 02139 Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier()) 02140 + Result + ")"; 02141 if (Param->getIdentifier() && !SuppressName) 02142 Result += Param->getIdentifier()->getName(); 02143 } 02144 return Result; 02145 } 02146 02147 // The argument for a block pointer parameter is a block literal with 02148 // the appropriate type. 02149 FunctionTypeLoc Block; 02150 FunctionProtoTypeLoc BlockProto; 02151 TypeLoc TL; 02152 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) { 02153 TL = TSInfo->getTypeLoc().getUnqualifiedLoc(); 02154 while (true) { 02155 // Look through typedefs. 02156 if (!SuppressBlock) { 02157 if (TypedefTypeLoc TypedefTL = TL.getAs<TypedefTypeLoc>()) { 02158 if (TypeSourceInfo *InnerTSInfo = 02159 TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) { 02160 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc(); 02161 continue; 02162 } 02163 } 02164 02165 // Look through qualified types 02166 if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) { 02167 TL = QualifiedTL.getUnqualifiedLoc(); 02168 continue; 02169 } 02170 } 02171 02172 // Try to get the function prototype behind the block pointer type, 02173 // then we're done. 02174 if (BlockPointerTypeLoc BlockPtr = TL.getAs<BlockPointerTypeLoc>()) { 02175 TL = BlockPtr.getPointeeLoc().IgnoreParens(); 02176 Block = TL.getAs<FunctionTypeLoc>(); 02177 BlockProto = TL.getAs<FunctionProtoTypeLoc>(); 02178 } 02179 break; 02180 } 02181 } 02182 02183 if (!Block) { 02184 // We were unable to find a FunctionProtoTypeLoc with parameter names 02185 // for the block; just use the parameter type as a placeholder. 02186 std::string Result; 02187 if (!ObjCMethodParam && Param->getIdentifier()) 02188 Result = Param->getIdentifier()->getName(); 02189 02190 Param->getType().getUnqualifiedType().getAsStringInternal(Result, Policy); 02191 02192 if (ObjCMethodParam) { 02193 Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier()) 02194 + Result + ")"; 02195 if (Param->getIdentifier()) 02196 Result += Param->getIdentifier()->getName(); 02197 } 02198 02199 return Result; 02200 } 02201 02202 // We have the function prototype behind the block pointer type, as it was 02203 // written in the source. 02204 std::string Result; 02205 QualType ResultType = Block.getTypePtr()->getReturnType(); 02206 if (!ResultType->isVoidType() || SuppressBlock) 02207 ResultType.getAsStringInternal(Result, Policy); 02208 02209 // Format the parameter list. 02210 std::string Params; 02211 if (!BlockProto || Block.getNumParams() == 0) { 02212 if (BlockProto && BlockProto.getTypePtr()->isVariadic()) 02213 Params = "(...)"; 02214 else 02215 Params = "(void)"; 02216 } else { 02217 Params += "("; 02218 for (unsigned I = 0, N = Block.getNumParams(); I != N; ++I) { 02219 if (I) 02220 Params += ", "; 02221 Params += FormatFunctionParameter(Context, Policy, Block.getParam(I), 02222 /*SuppressName=*/false, 02223 /*SuppressBlock=*/true); 02224 02225 if (I == N - 1 && BlockProto.getTypePtr()->isVariadic()) 02226 Params += ", ..."; 02227 } 02228 Params += ")"; 02229 } 02230 02231 if (SuppressBlock) { 02232 // Format as a parameter. 02233 Result = Result + " (^"; 02234 if (Param->getIdentifier()) 02235 Result += Param->getIdentifier()->getName(); 02236 Result += ")"; 02237 Result += Params; 02238 } else { 02239 // Format as a block literal argument. 02240 Result = '^' + Result; 02241 Result += Params; 02242 02243 if (Param->getIdentifier()) 02244 Result += Param->getIdentifier()->getName(); 02245 } 02246 02247 return Result; 02248 } 02249 02250 /// \brief Add function parameter chunks to the given code completion string. 02251 static void AddFunctionParameterChunks(ASTContext &Context, 02252 const PrintingPolicy &Policy, 02253 const FunctionDecl *Function, 02254 CodeCompletionBuilder &Result, 02255 unsigned Start = 0, 02256 bool InOptional = false) { 02257 bool FirstParameter = true; 02258 02259 for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) { 02260 const ParmVarDecl *Param = Function->getParamDecl(P); 02261 02262 if (Param->hasDefaultArg() && !InOptional) { 02263 // When we see an optional default argument, put that argument and 02264 // the remaining default arguments into a new, optional string. 02265 CodeCompletionBuilder Opt(Result.getAllocator(), 02266 Result.getCodeCompletionTUInfo()); 02267 if (!FirstParameter) 02268 Opt.AddChunk(CodeCompletionString::CK_Comma); 02269 AddFunctionParameterChunks(Context, Policy, Function, Opt, P, true); 02270 Result.AddOptionalChunk(Opt.TakeString()); 02271 break; 02272 } 02273 02274 if (FirstParameter) 02275 FirstParameter = false; 02276 else 02277 Result.AddChunk(CodeCompletionString::CK_Comma); 02278 02279 InOptional = false; 02280 02281 // Format the placeholder string. 02282 std::string PlaceholderStr = FormatFunctionParameter(Context, Policy, 02283 Param); 02284 02285 if (Function->isVariadic() && P == N - 1) 02286 PlaceholderStr += ", ..."; 02287 02288 // Add the placeholder string. 02289 Result.AddPlaceholderChunk( 02290 Result.getAllocator().CopyString(PlaceholderStr)); 02291 } 02292 02293 if (const FunctionProtoType *Proto 02294 = Function->getType()->getAs<FunctionProtoType>()) 02295 if (Proto->isVariadic()) { 02296 if (Proto->getNumParams() == 0) 02297 Result.AddPlaceholderChunk("..."); 02298 02299 MaybeAddSentinel(Context, Function, Result); 02300 } 02301 } 02302 02303 /// \brief Add template parameter chunks to the given code completion string. 02304 static void AddTemplateParameterChunks(ASTContext &Context, 02305 const PrintingPolicy &Policy, 02306 const TemplateDecl *Template, 02307 CodeCompletionBuilder &Result, 02308 unsigned MaxParameters = 0, 02309 unsigned Start = 0, 02310 bool InDefaultArg = false) { 02311 bool FirstParameter = true; 02312 02313 TemplateParameterList *Params = Template->getTemplateParameters(); 02314 TemplateParameterList::iterator PEnd = Params->end(); 02315 if (MaxParameters) 02316 PEnd = Params->begin() + MaxParameters; 02317 for (TemplateParameterList::iterator P = Params->begin() + Start; 02318 P != PEnd; ++P) { 02319 bool HasDefaultArg = false; 02320 std::string PlaceholderStr; 02321 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { 02322 if (TTP->wasDeclaredWithTypename()) 02323 PlaceholderStr = "typename"; 02324 else 02325 PlaceholderStr = "class"; 02326 02327 if (TTP->getIdentifier()) { 02328 PlaceholderStr += ' '; 02329 PlaceholderStr += TTP->getIdentifier()->getName(); 02330 } 02331 02332 HasDefaultArg = TTP->hasDefaultArgument(); 02333 } else if (NonTypeTemplateParmDecl *NTTP 02334 = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 02335 if (NTTP->getIdentifier()) 02336 PlaceholderStr = NTTP->getIdentifier()->getName(); 02337 NTTP->getType().getAsStringInternal(PlaceholderStr, Policy); 02338 HasDefaultArg = NTTP->hasDefaultArgument(); 02339 } else { 02340 assert(isa<TemplateTemplateParmDecl>(*P)); 02341 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P); 02342 02343 // Since putting the template argument list into the placeholder would 02344 // be very, very long, we just use an abbreviation. 02345 PlaceholderStr = "template<...> class"; 02346 if (TTP->getIdentifier()) { 02347 PlaceholderStr += ' '; 02348 PlaceholderStr += TTP->getIdentifier()->getName(); 02349 } 02350 02351 HasDefaultArg = TTP->hasDefaultArgument(); 02352 } 02353 02354 if (HasDefaultArg && !InDefaultArg) { 02355 // When we see an optional default argument, put that argument and 02356 // the remaining default arguments into a new, optional string. 02357 CodeCompletionBuilder Opt(Result.getAllocator(), 02358 Result.getCodeCompletionTUInfo()); 02359 if (!FirstParameter) 02360 Opt.AddChunk(CodeCompletionString::CK_Comma); 02361 AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters, 02362 P - Params->begin(), true); 02363 Result.AddOptionalChunk(Opt.TakeString()); 02364 break; 02365 } 02366 02367 InDefaultArg = false; 02368 02369 if (FirstParameter) 02370 FirstParameter = false; 02371 else 02372 Result.AddChunk(CodeCompletionString::CK_Comma); 02373 02374 // Add the placeholder string. 02375 Result.AddPlaceholderChunk( 02376 Result.getAllocator().CopyString(PlaceholderStr)); 02377 } 02378 } 02379 02380 /// \brief Add a qualifier to the given code-completion string, if the 02381 /// provided nested-name-specifier is non-NULL. 02382 static void 02383 AddQualifierToCompletionString(CodeCompletionBuilder &Result, 02384 NestedNameSpecifier *Qualifier, 02385 bool QualifierIsInformative, 02386 ASTContext &Context, 02387 const PrintingPolicy &Policy) { 02388 if (!Qualifier) 02389 return; 02390 02391 std::string PrintedNNS; 02392 { 02393 llvm::raw_string_ostream OS(PrintedNNS); 02394 Qualifier->print(OS, Policy); 02395 } 02396 if (QualifierIsInformative) 02397 Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS)); 02398 else 02399 Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS)); 02400 } 02401 02402 static void 02403 AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result, 02404 const FunctionDecl *Function) { 02405 const FunctionProtoType *Proto 02406 = Function->getType()->getAs<FunctionProtoType>(); 02407 if (!Proto || !Proto->getTypeQuals()) 02408 return; 02409 02410 // FIXME: Add ref-qualifier! 02411 02412 // Handle single qualifiers without copying 02413 if (Proto->getTypeQuals() == Qualifiers::Const) { 02414 Result.AddInformativeChunk(" const"); 02415 return; 02416 } 02417 02418 if (Proto->getTypeQuals() == Qualifiers::Volatile) { 02419 Result.AddInformativeChunk(" volatile"); 02420 return; 02421 } 02422 02423 if (Proto->getTypeQuals() == Qualifiers::Restrict) { 02424 Result.AddInformativeChunk(" restrict"); 02425 return; 02426 } 02427 02428 // Handle multiple qualifiers. 02429 std::string QualsStr; 02430 if (Proto->isConst()) 02431 QualsStr += " const"; 02432 if (Proto->isVolatile()) 02433 QualsStr += " volatile"; 02434 if (Proto->isRestrict()) 02435 QualsStr += " restrict"; 02436 Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr)); 02437 } 02438 02439 /// \brief Add the name of the given declaration 02440 static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, 02441 const NamedDecl *ND, 02442 CodeCompletionBuilder &Result) { 02443 DeclarationName Name = ND->getDeclName(); 02444 if (!Name) 02445 return; 02446 02447 switch (Name.getNameKind()) { 02448 case DeclarationName::CXXOperatorName: { 02449 const char *OperatorName = nullptr; 02450 switch (Name.getCXXOverloadedOperator()) { 02451 case OO_None: 02452 case OO_Conditional: 02453 case NUM_OVERLOADED_OPERATORS: 02454 OperatorName = "operator"; 02455 break; 02456 02457 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 02458 case OO_##Name: OperatorName = "operator" Spelling; break; 02459 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 02460 #include "clang/Basic/OperatorKinds.def" 02461 02462 case OO_New: OperatorName = "operator new"; break; 02463 case OO_Delete: OperatorName = "operator delete"; break; 02464 case OO_Array_New: OperatorName = "operator new[]"; break; 02465 case OO_Array_Delete: OperatorName = "operator delete[]"; break; 02466 case OO_Call: OperatorName = "operator()"; break; 02467 case OO_Subscript: OperatorName = "operator[]"; break; 02468 } 02469 Result.AddTypedTextChunk(OperatorName); 02470 break; 02471 } 02472 02473 case DeclarationName::Identifier: 02474 case DeclarationName::CXXConversionFunctionName: 02475 case DeclarationName::CXXDestructorName: 02476 case DeclarationName::CXXLiteralOperatorName: 02477 Result.AddTypedTextChunk( 02478 Result.getAllocator().CopyString(ND->getNameAsString())); 02479 break; 02480 02481 case DeclarationName::CXXUsingDirective: 02482 case DeclarationName::ObjCZeroArgSelector: 02483 case DeclarationName::ObjCOneArgSelector: 02484 case DeclarationName::ObjCMultiArgSelector: 02485 break; 02486 02487 case DeclarationName::CXXConstructorName: { 02488 CXXRecordDecl *Record = nullptr; 02489 QualType Ty = Name.getCXXNameType(); 02490 if (const RecordType *RecordTy = Ty->getAs<RecordType>()) 02491 Record = cast<CXXRecordDecl>(RecordTy->getDecl()); 02492 else if (const InjectedClassNameType *InjectedTy 02493 = Ty->getAs<InjectedClassNameType>()) 02494 Record = InjectedTy->getDecl(); 02495 else { 02496 Result.AddTypedTextChunk( 02497 Result.getAllocator().CopyString(ND->getNameAsString())); 02498 break; 02499 } 02500 02501 Result.AddTypedTextChunk( 02502 Result.getAllocator().CopyString(Record->getNameAsString())); 02503 if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) { 02504 Result.AddChunk(CodeCompletionString::CK_LeftAngle); 02505 AddTemplateParameterChunks(Context, Policy, Template, Result); 02506 Result.AddChunk(CodeCompletionString::CK_RightAngle); 02507 } 02508 break; 02509 } 02510 } 02511 } 02512 02513 CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S, 02514 CodeCompletionAllocator &Allocator, 02515 CodeCompletionTUInfo &CCTUInfo, 02516 bool IncludeBriefComments) { 02517 return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo, 02518 IncludeBriefComments); 02519 } 02520 02521 /// \brief If possible, create a new code completion string for the given 02522 /// result. 02523 /// 02524 /// \returns Either a new, heap-allocated code completion string describing 02525 /// how to use this result, or NULL to indicate that the string or name of the 02526 /// result is all that is needed. 02527 CodeCompletionString * 02528 CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, 02529 Preprocessor &PP, 02530 CodeCompletionAllocator &Allocator, 02531 CodeCompletionTUInfo &CCTUInfo, 02532 bool IncludeBriefComments) { 02533 CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability); 02534 02535 PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP); 02536 if (Kind == RK_Pattern) { 02537 Pattern->Priority = Priority; 02538 Pattern->Availability = Availability; 02539 02540 if (Declaration) { 02541 Result.addParentContext(Declaration->getDeclContext()); 02542 Pattern->ParentName = Result.getParentName(); 02543 // Provide code completion comment for self.GetterName where 02544 // GetterName is the getter method for a property with name 02545 // different from the property name (declared via a property 02546 // getter attribute. 02547 const NamedDecl *ND = Declaration; 02548 if (const ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(ND)) 02549 if (M->isPropertyAccessor()) 02550 if (const ObjCPropertyDecl *PDecl = M->findPropertyDecl()) 02551 if (PDecl->getGetterName() == M->getSelector() && 02552 PDecl->getIdentifier() != M->getIdentifier()) { 02553 if (const RawComment *RC = 02554 Ctx.getRawCommentForAnyRedecl(M)) { 02555 Result.addBriefComment(RC->getBriefText(Ctx)); 02556 Pattern->BriefComment = Result.getBriefComment(); 02557 } 02558 else if (const RawComment *RC = 02559 Ctx.getRawCommentForAnyRedecl(PDecl)) { 02560 Result.addBriefComment(RC->getBriefText(Ctx)); 02561 Pattern->BriefComment = Result.getBriefComment(); 02562 } 02563 } 02564 } 02565 02566 return Pattern; 02567 } 02568 02569 if (Kind == RK_Keyword) { 02570 Result.AddTypedTextChunk(Keyword); 02571 return Result.TakeString(); 02572 } 02573 02574 if (Kind == RK_Macro) { 02575 const MacroDirective *MD = PP.getMacroDirectiveHistory(Macro); 02576 assert(MD && "Not a macro?"); 02577 const MacroInfo *MI = MD->getMacroInfo(); 02578 assert((!MD->isDefined() || MI) && "missing MacroInfo for define"); 02579 02580 Result.AddTypedTextChunk( 02581 Result.getAllocator().CopyString(Macro->getName())); 02582 02583 if (!MI || !MI->isFunctionLike()) 02584 return Result.TakeString(); 02585 02586 // Format a function-like macro with placeholders for the arguments. 02587 Result.AddChunk(CodeCompletionString::CK_LeftParen); 02588 MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end(); 02589 02590 // C99 variadic macros add __VA_ARGS__ at the end. Skip it. 02591 if (MI->isC99Varargs()) { 02592 --AEnd; 02593 02594 if (A == AEnd) { 02595 Result.AddPlaceholderChunk("..."); 02596 } 02597 } 02598 02599 for (MacroInfo::arg_iterator A = MI->arg_begin(); A != AEnd; ++A) { 02600 if (A != MI->arg_begin()) 02601 Result.AddChunk(CodeCompletionString::CK_Comma); 02602 02603 if (MI->isVariadic() && (A+1) == AEnd) { 02604 SmallString<32> Arg = (*A)->getName(); 02605 if (MI->isC99Varargs()) 02606 Arg += ", ..."; 02607 else 02608 Arg += "..."; 02609 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg)); 02610 break; 02611 } 02612 02613 // Non-variadic macros are simple. 02614 Result.AddPlaceholderChunk( 02615 Result.getAllocator().CopyString((*A)->getName())); 02616 } 02617 Result.AddChunk(CodeCompletionString::CK_RightParen); 02618 return Result.TakeString(); 02619 } 02620 02621 assert(Kind == RK_Declaration && "Missed a result kind?"); 02622 const NamedDecl *ND = Declaration; 02623 Result.addParentContext(ND->getDeclContext()); 02624 02625 if (IncludeBriefComments) { 02626 // Add documentation comment, if it exists. 02627 if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(ND)) { 02628 Result.addBriefComment(RC->getBriefText(Ctx)); 02629 } 02630 else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) 02631 if (OMD->isPropertyAccessor()) 02632 if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl()) 02633 if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(PDecl)) 02634 Result.addBriefComment(RC->getBriefText(Ctx)); 02635 } 02636 02637 if (StartsNestedNameSpecifier) { 02638 Result.AddTypedTextChunk( 02639 Result.getAllocator().CopyString(ND->getNameAsString())); 02640 Result.AddTextChunk("::"); 02641 return Result.TakeString(); 02642 } 02643 02644 for (const auto *I : ND->specific_attrs<AnnotateAttr>()) 02645 Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation())); 02646 02647 AddResultTypeChunk(Ctx, Policy, ND, Result); 02648 02649 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) { 02650 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 02651 Ctx, Policy); 02652 AddTypedNameChunk(Ctx, Policy, ND, Result); 02653 Result.AddChunk(CodeCompletionString::CK_LeftParen); 02654 AddFunctionParameterChunks(Ctx, Policy, Function, Result); 02655 Result.AddChunk(CodeCompletionString::CK_RightParen); 02656 AddFunctionTypeQualsToCompletionString(Result, Function); 02657 return Result.TakeString(); 02658 } 02659 02660 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) { 02661 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 02662 Ctx, Policy); 02663 FunctionDecl *Function = FunTmpl->getTemplatedDecl(); 02664 AddTypedNameChunk(Ctx, Policy, Function, Result); 02665 02666 // Figure out which template parameters are deduced (or have default 02667 // arguments). 02668 llvm::SmallBitVector Deduced; 02669 Sema::MarkDeducedTemplateParameters(Ctx, FunTmpl, Deduced); 02670 unsigned LastDeducibleArgument; 02671 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0; 02672 --LastDeducibleArgument) { 02673 if (!Deduced[LastDeducibleArgument - 1]) { 02674 // C++0x: Figure out if the template argument has a default. If so, 02675 // the user doesn't need to type this argument. 02676 // FIXME: We need to abstract template parameters better! 02677 bool HasDefaultArg = false; 02678 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam( 02679 LastDeducibleArgument - 1); 02680 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) 02681 HasDefaultArg = TTP->hasDefaultArgument(); 02682 else if (NonTypeTemplateParmDecl *NTTP 02683 = dyn_cast<NonTypeTemplateParmDecl>(Param)) 02684 HasDefaultArg = NTTP->hasDefaultArgument(); 02685 else { 02686 assert(isa<TemplateTemplateParmDecl>(Param)); 02687 HasDefaultArg 02688 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument(); 02689 } 02690 02691 if (!HasDefaultArg) 02692 break; 02693 } 02694 } 02695 02696 if (LastDeducibleArgument) { 02697 // Some of the function template arguments cannot be deduced from a 02698 // function call, so we introduce an explicit template argument list 02699 // containing all of the arguments up to the first deducible argument. 02700 Result.AddChunk(CodeCompletionString::CK_LeftAngle); 02701 AddTemplateParameterChunks(Ctx, Policy, FunTmpl, Result, 02702 LastDeducibleArgument); 02703 Result.AddChunk(CodeCompletionString::CK_RightAngle); 02704 } 02705 02706 // Add the function parameters 02707 Result.AddChunk(CodeCompletionString::CK_LeftParen); 02708 AddFunctionParameterChunks(Ctx, Policy, Function, Result); 02709 Result.AddChunk(CodeCompletionString::CK_RightParen); 02710 AddFunctionTypeQualsToCompletionString(Result, Function); 02711 return Result.TakeString(); 02712 } 02713 02714 if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) { 02715 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 02716 Ctx, Policy); 02717 Result.AddTypedTextChunk( 02718 Result.getAllocator().CopyString(Template->getNameAsString())); 02719 Result.AddChunk(CodeCompletionString::CK_LeftAngle); 02720 AddTemplateParameterChunks(Ctx, Policy, Template, Result); 02721 Result.AddChunk(CodeCompletionString::CK_RightAngle); 02722 return Result.TakeString(); 02723 } 02724 02725 if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) { 02726 Selector Sel = Method->getSelector(); 02727 if (Sel.isUnarySelector()) { 02728 Result.AddTypedTextChunk(Result.getAllocator().CopyString( 02729 Sel.getNameForSlot(0))); 02730 return Result.TakeString(); 02731 } 02732 02733 std::string SelName = Sel.getNameForSlot(0).str(); 02734 SelName += ':'; 02735 if (StartParameter == 0) 02736 Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName)); 02737 else { 02738 Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName)); 02739 02740 // If there is only one parameter, and we're past it, add an empty 02741 // typed-text chunk since there is nothing to type. 02742 if (Method->param_size() == 1) 02743 Result.AddTypedTextChunk(""); 02744 } 02745 unsigned Idx = 0; 02746 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(), 02747 PEnd = Method->param_end(); 02748 P != PEnd; (void)++P, ++Idx) { 02749 if (Idx > 0) { 02750 std::string Keyword; 02751 if (Idx > StartParameter) 02752 Result.AddChunk(CodeCompletionString::CK_HorizontalSpace); 02753 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx)) 02754 Keyword += II->getName(); 02755 Keyword += ":"; 02756 if (Idx < StartParameter || AllParametersAreInformative) 02757 Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword)); 02758 else 02759 Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword)); 02760 } 02761 02762 // If we're before the starting parameter, skip the placeholder. 02763 if (Idx < StartParameter) 02764 continue; 02765 02766 std::string Arg; 02767 02768 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity) 02769 Arg = FormatFunctionParameter(Ctx, Policy, *P, true); 02770 else { 02771 (*P)->getType().getAsStringInternal(Arg, Policy); 02772 Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier()) 02773 + Arg + ")"; 02774 if (IdentifierInfo *II = (*P)->getIdentifier()) 02775 if (DeclaringEntity || AllParametersAreInformative) 02776 Arg += II->getName(); 02777 } 02778 02779 if (Method->isVariadic() && (P + 1) == PEnd) 02780 Arg += ", ..."; 02781 02782 if (DeclaringEntity) 02783 Result.AddTextChunk(Result.getAllocator().CopyString(Arg)); 02784 else if (AllParametersAreInformative) 02785 Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg)); 02786 else 02787 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg)); 02788 } 02789 02790 if (Method->isVariadic()) { 02791 if (Method->param_size() == 0) { 02792 if (DeclaringEntity) 02793 Result.AddTextChunk(", ..."); 02794 else if (AllParametersAreInformative) 02795 Result.AddInformativeChunk(", ..."); 02796 else 02797 Result.AddPlaceholderChunk(", ..."); 02798 } 02799 02800 MaybeAddSentinel(Ctx, Method, Result); 02801 } 02802 02803 return Result.TakeString(); 02804 } 02805 02806 if (Qualifier) 02807 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, 02808 Ctx, Policy); 02809 02810 Result.AddTypedTextChunk( 02811 Result.getAllocator().CopyString(ND->getNameAsString())); 02812 return Result.TakeString(); 02813 } 02814 02815 CodeCompletionString * 02816 CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( 02817 unsigned CurrentArg, 02818 Sema &S, 02819 CodeCompletionAllocator &Allocator, 02820 CodeCompletionTUInfo &CCTUInfo) const { 02821 PrintingPolicy Policy = getCompletionPrintingPolicy(S); 02822 02823 // FIXME: Set priority, availability appropriately. 02824 CodeCompletionBuilder Result(Allocator,CCTUInfo, 1, CXAvailability_Available); 02825 FunctionDecl *FDecl = getFunction(); 02826 AddResultTypeChunk(S.Context, Policy, FDecl, Result); 02827 const FunctionProtoType *Proto 02828 = dyn_cast<FunctionProtoType>(getFunctionType()); 02829 if (!FDecl && !Proto) { 02830 // Function without a prototype. Just give the return type and a 02831 // highlighted ellipsis. 02832 const FunctionType *FT = getFunctionType(); 02833 Result.AddTextChunk(GetCompletionTypeString(FT->getReturnType(), S.Context, 02834 Policy, Result.getAllocator())); 02835 Result.AddChunk(CodeCompletionString::CK_LeftParen); 02836 Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "..."); 02837 Result.AddChunk(CodeCompletionString::CK_RightParen); 02838 return Result.TakeString(); 02839 } 02840 02841 if (FDecl) 02842 Result.AddTextChunk( 02843 Result.getAllocator().CopyString(FDecl->getNameAsString())); 02844 else 02845 Result.AddTextChunk(Result.getAllocator().CopyString( 02846 Proto->getReturnType().getAsString(Policy))); 02847 02848 Result.AddChunk(CodeCompletionString::CK_LeftParen); 02849 unsigned NumParams = FDecl ? FDecl->getNumParams() : Proto->getNumParams(); 02850 for (unsigned I = 0; I != NumParams; ++I) { 02851 if (I) 02852 Result.AddChunk(CodeCompletionString::CK_Comma); 02853 02854 std::string ArgString; 02855 QualType ArgType; 02856 02857 if (FDecl) { 02858 ArgString = FDecl->getParamDecl(I)->getNameAsString(); 02859 ArgType = FDecl->getParamDecl(I)->getOriginalType(); 02860 } else { 02861 ArgType = Proto->getParamType(I); 02862 } 02863 02864 ArgType.getAsStringInternal(ArgString, Policy); 02865 02866 if (I == CurrentArg) 02867 Result.AddChunk(CodeCompletionString::CK_CurrentParameter, 02868 Result.getAllocator().CopyString(ArgString)); 02869 else 02870 Result.AddTextChunk(Result.getAllocator().CopyString(ArgString)); 02871 } 02872 02873 if (Proto && Proto->isVariadic()) { 02874 Result.AddChunk(CodeCompletionString::CK_Comma); 02875 if (CurrentArg < NumParams) 02876 Result.AddTextChunk("..."); 02877 else 02878 Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "..."); 02879 } 02880 Result.AddChunk(CodeCompletionString::CK_RightParen); 02881 02882 return Result.TakeString(); 02883 } 02884 02885 unsigned clang::getMacroUsagePriority(StringRef MacroName, 02886 const LangOptions &LangOpts, 02887 bool PreferredTypeIsPointer) { 02888 unsigned Priority = CCP_Macro; 02889 02890 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants. 02891 if (MacroName.equals("nil") || MacroName.equals("NULL") || 02892 MacroName.equals("Nil")) { 02893 Priority = CCP_Constant; 02894 if (PreferredTypeIsPointer) 02895 Priority = Priority / CCF_SimilarTypeMatch; 02896 } 02897 // Treat "YES", "NO", "true", and "false" as constants. 02898 else if (MacroName.equals("YES") || MacroName.equals("NO") || 02899 MacroName.equals("true") || MacroName.equals("false")) 02900 Priority = CCP_Constant; 02901 // Treat "bool" as a type. 02902 else if (MacroName.equals("bool")) 02903 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0); 02904 02905 02906 return Priority; 02907 } 02908 02909 CXCursorKind clang::getCursorKindForDecl(const Decl *D) { 02910 if (!D) 02911 return CXCursor_UnexposedDecl; 02912 02913 switch (D->getKind()) { 02914 case Decl::Enum: return CXCursor_EnumDecl; 02915 case Decl::EnumConstant: return CXCursor_EnumConstantDecl; 02916 case Decl::Field: return CXCursor_FieldDecl; 02917 case Decl::Function: 02918 return CXCursor_FunctionDecl; 02919 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl; 02920 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl; 02921 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl; 02922 02923 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl; 02924 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl; 02925 case Decl::ObjCMethod: 02926 return cast<ObjCMethodDecl>(D)->isInstanceMethod() 02927 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl; 02928 case Decl::CXXMethod: return CXCursor_CXXMethod; 02929 case Decl::CXXConstructor: return CXCursor_Constructor; 02930 case Decl::CXXDestructor: return CXCursor_Destructor; 02931 case Decl::CXXConversion: return CXCursor_ConversionFunction; 02932 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl; 02933 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl; 02934 case Decl::ParmVar: return CXCursor_ParmDecl; 02935 case Decl::Typedef: return CXCursor_TypedefDecl; 02936 case Decl::TypeAlias: return CXCursor_TypeAliasDecl; 02937 case Decl::Var: return CXCursor_VarDecl; 02938 case Decl::Namespace: return CXCursor_Namespace; 02939 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias; 02940 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter; 02941 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter; 02942 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter; 02943 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate; 02944 case Decl::ClassTemplate: return CXCursor_ClassTemplate; 02945 case Decl::AccessSpec: return CXCursor_CXXAccessSpecifier; 02946 case Decl::ClassTemplatePartialSpecialization: 02947 return CXCursor_ClassTemplatePartialSpecialization; 02948 case Decl::UsingDirective: return CXCursor_UsingDirective; 02949 case Decl::TranslationUnit: return CXCursor_TranslationUnit; 02950 02951 case Decl::Using: 02952 case Decl::UnresolvedUsingValue: 02953 case Decl::UnresolvedUsingTypename: 02954 return CXCursor_UsingDeclaration; 02955 02956 case Decl::ObjCPropertyImpl: 02957 switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) { 02958 case ObjCPropertyImplDecl::Dynamic: 02959 return CXCursor_ObjCDynamicDecl; 02960 02961 case ObjCPropertyImplDecl::Synthesize: 02962 return CXCursor_ObjCSynthesizeDecl; 02963 } 02964 02965 case Decl::Import: 02966 return CXCursor_ModuleImportDecl; 02967 02968 default: 02969 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) { 02970 switch (TD->getTagKind()) { 02971 case TTK_Interface: // fall through 02972 case TTK_Struct: return CXCursor_StructDecl; 02973 case TTK_Class: return CXCursor_ClassDecl; 02974 case TTK_Union: return CXCursor_UnionDecl; 02975 case TTK_Enum: return CXCursor_EnumDecl; 02976 } 02977 } 02978 } 02979 02980 return CXCursor_UnexposedDecl; 02981 } 02982 02983 static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results, 02984 bool IncludeUndefined, 02985 bool TargetTypeIsPointer = false) { 02986 typedef CodeCompletionResult Result; 02987 02988 Results.EnterNewScope(); 02989 02990 for (Preprocessor::macro_iterator M = PP.macro_begin(), 02991 MEnd = PP.macro_end(); 02992 M != MEnd; ++M) { 02993 if (IncludeUndefined || M->first->hasMacroDefinition()) { 02994 if (MacroInfo *MI = M->second->getMacroInfo()) 02995 if (MI->isUsedForHeaderGuard()) 02996 continue; 02997 02998 Results.AddResult(Result(M->first, 02999 getMacroUsagePriority(M->first->getName(), 03000 PP.getLangOpts(), 03001 TargetTypeIsPointer))); 03002 } 03003 } 03004 03005 Results.ExitScope(); 03006 03007 } 03008 03009 static void AddPrettyFunctionResults(const LangOptions &LangOpts, 03010 ResultBuilder &Results) { 03011 typedef CodeCompletionResult Result; 03012 03013 Results.EnterNewScope(); 03014 03015 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant)); 03016 Results.AddResult(Result("__FUNCTION__", CCP_Constant)); 03017 if (LangOpts.C99 || LangOpts.CPlusPlus11) 03018 Results.AddResult(Result("__func__", CCP_Constant)); 03019 Results.ExitScope(); 03020 } 03021 03022 static void HandleCodeCompleteResults(Sema *S, 03023 CodeCompleteConsumer *CodeCompleter, 03024 CodeCompletionContext Context, 03025 CodeCompletionResult *Results, 03026 unsigned NumResults) { 03027 if (CodeCompleter) 03028 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults); 03029 } 03030 03031 static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S, 03032 Sema::ParserCompletionContext PCC) { 03033 switch (PCC) { 03034 case Sema::PCC_Namespace: 03035 return CodeCompletionContext::CCC_TopLevel; 03036 03037 case Sema::PCC_Class: 03038 return CodeCompletionContext::CCC_ClassStructUnion; 03039 03040 case Sema::PCC_ObjCInterface: 03041 return CodeCompletionContext::CCC_ObjCInterface; 03042 03043 case Sema::PCC_ObjCImplementation: 03044 return CodeCompletionContext::CCC_ObjCImplementation; 03045 03046 case Sema::PCC_ObjCInstanceVariableList: 03047 return CodeCompletionContext::CCC_ObjCIvarList; 03048 03049 case Sema::PCC_Template: 03050 case Sema::PCC_MemberTemplate: 03051 if (S.CurContext->isFileContext()) 03052 return CodeCompletionContext::CCC_TopLevel; 03053 if (S.CurContext->isRecord()) 03054 return CodeCompletionContext::CCC_ClassStructUnion; 03055 return CodeCompletionContext::CCC_Other; 03056 03057 case Sema::PCC_RecoveryInFunction: 03058 return CodeCompletionContext::CCC_Recovery; 03059 03060 case Sema::PCC_ForInit: 03061 if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 || 03062 S.getLangOpts().ObjC1) 03063 return CodeCompletionContext::CCC_ParenthesizedExpression; 03064 else 03065 return CodeCompletionContext::CCC_Expression; 03066 03067 case Sema::PCC_Expression: 03068 case Sema::PCC_Condition: 03069 return CodeCompletionContext::CCC_Expression; 03070 03071 case Sema::PCC_Statement: 03072 return CodeCompletionContext::CCC_Statement; 03073 03074 case Sema::PCC_Type: 03075 return CodeCompletionContext::CCC_Type; 03076 03077 case Sema::PCC_ParenthesizedExpression: 03078 return CodeCompletionContext::CCC_ParenthesizedExpression; 03079 03080 case Sema::PCC_LocalDeclarationSpecifiers: 03081 return CodeCompletionContext::CCC_Type; 03082 } 03083 03084 llvm_unreachable("Invalid ParserCompletionContext!"); 03085 } 03086 03087 /// \brief If we're in a C++ virtual member function, add completion results 03088 /// that invoke the functions we override, since it's common to invoke the 03089 /// overridden function as well as adding new functionality. 03090 /// 03091 /// \param S The semantic analysis object for which we are generating results. 03092 /// 03093 /// \param InContext This context in which the nested-name-specifier preceding 03094 /// the code-completion point 03095 static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext, 03096 ResultBuilder &Results) { 03097 // Look through blocks. 03098 DeclContext *CurContext = S.CurContext; 03099 while (isa<BlockDecl>(CurContext)) 03100 CurContext = CurContext->getParent(); 03101 03102 03103 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext); 03104 if (!Method || !Method->isVirtual()) 03105 return; 03106 03107 // We need to have names for all of the parameters, if we're going to 03108 // generate a forwarding call. 03109 for (auto P : Method->params()) 03110 if (!P->getDeclName()) 03111 return; 03112 03113 PrintingPolicy Policy = getCompletionPrintingPolicy(S); 03114 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(), 03115 MEnd = Method->end_overridden_methods(); 03116 M != MEnd; ++M) { 03117 CodeCompletionBuilder Builder(Results.getAllocator(), 03118 Results.getCodeCompletionTUInfo()); 03119 const CXXMethodDecl *Overridden = *M; 03120 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl()) 03121 continue; 03122 03123 // If we need a nested-name-specifier, add one now. 03124 if (!InContext) { 03125 NestedNameSpecifier *NNS 03126 = getRequiredQualification(S.Context, CurContext, 03127 Overridden->getDeclContext()); 03128 if (NNS) { 03129 std::string Str; 03130 llvm::raw_string_ostream OS(Str); 03131 NNS->print(OS, Policy); 03132 Builder.AddTextChunk(Results.getAllocator().CopyString(OS.str())); 03133 } 03134 } else if (!InContext->Equals(Overridden->getDeclContext())) 03135 continue; 03136 03137 Builder.AddTypedTextChunk(Results.getAllocator().CopyString( 03138 Overridden->getNameAsString())); 03139 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 03140 bool FirstParam = true; 03141 for (auto P : Method->params()) { 03142 if (FirstParam) 03143 FirstParam = false; 03144 else 03145 Builder.AddChunk(CodeCompletionString::CK_Comma); 03146 03147 Builder.AddPlaceholderChunk( 03148 Results.getAllocator().CopyString(P->getIdentifier()->getName())); 03149 } 03150 Builder.AddChunk(CodeCompletionString::CK_RightParen); 03151 Results.AddResult(CodeCompletionResult(Builder.TakeString(), 03152 CCP_SuperCompletion, 03153 CXCursor_CXXMethod, 03154 CXAvailability_Available, 03155 Overridden)); 03156 Results.Ignore(Overridden); 03157 } 03158 } 03159 03160 void Sema::CodeCompleteModuleImport(SourceLocation ImportLoc, 03161 ModuleIdPath Path) { 03162 typedef CodeCompletionResult Result; 03163 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 03164 CodeCompleter->getCodeCompletionTUInfo(), 03165 CodeCompletionContext::CCC_Other); 03166 Results.EnterNewScope(); 03167 03168 CodeCompletionAllocator &Allocator = Results.getAllocator(); 03169 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); 03170 typedef CodeCompletionResult Result; 03171 if (Path.empty()) { 03172 // Enumerate all top-level modules. 03173 SmallVector<Module *, 8> Modules; 03174 PP.getHeaderSearchInfo().collectAllModules(Modules); 03175 for (unsigned I = 0, N = Modules.size(); I != N; ++I) { 03176 Builder.AddTypedTextChunk( 03177 Builder.getAllocator().CopyString(Modules[I]->Name)); 03178 Results.AddResult(Result(Builder.TakeString(), 03179 CCP_Declaration, 03180 CXCursor_ModuleImportDecl, 03181 Modules[I]->isAvailable() 03182 ? CXAvailability_Available 03183 : CXAvailability_NotAvailable)); 03184 } 03185 } else if (getLangOpts().Modules) { 03186 // Load the named module. 03187 Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path, 03188 Module::AllVisible, 03189 /*IsInclusionDirective=*/false); 03190 // Enumerate submodules. 03191 if (Mod) { 03192 for (Module::submodule_iterator Sub = Mod->submodule_begin(), 03193 SubEnd = Mod->submodule_end(); 03194 Sub != SubEnd; ++Sub) { 03195 03196 Builder.AddTypedTextChunk( 03197 Builder.getAllocator().CopyString((*Sub)->Name)); 03198 Results.AddResult(Result(Builder.TakeString(), 03199 CCP_Declaration, 03200 CXCursor_ModuleImportDecl, 03201 (*Sub)->isAvailable() 03202 ? CXAvailability_Available 03203 : CXAvailability_NotAvailable)); 03204 } 03205 } 03206 } 03207 Results.ExitScope(); 03208 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 03209 Results.data(),Results.size()); 03210 } 03211 03212 void Sema::CodeCompleteOrdinaryName(Scope *S, 03213 ParserCompletionContext CompletionContext) { 03214 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 03215 CodeCompleter->getCodeCompletionTUInfo(), 03216 mapCodeCompletionContext(*this, CompletionContext)); 03217 Results.EnterNewScope(); 03218 03219 // Determine how to filter results, e.g., so that the names of 03220 // values (functions, enumerators, function templates, etc.) are 03221 // only allowed where we can have an expression. 03222 switch (CompletionContext) { 03223 case PCC_Namespace: 03224 case PCC_Class: 03225 case PCC_ObjCInterface: 03226 case PCC_ObjCImplementation: 03227 case PCC_ObjCInstanceVariableList: 03228 case PCC_Template: 03229 case PCC_MemberTemplate: 03230 case PCC_Type: 03231 case PCC_LocalDeclarationSpecifiers: 03232 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName); 03233 break; 03234 03235 case PCC_Statement: 03236 case PCC_ParenthesizedExpression: 03237 case PCC_Expression: 03238 case PCC_ForInit: 03239 case PCC_Condition: 03240 if (WantTypesInContext(CompletionContext, getLangOpts())) 03241 Results.setFilter(&ResultBuilder::IsOrdinaryName); 03242 else 03243 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); 03244 03245 if (getLangOpts().CPlusPlus) 03246 MaybeAddOverrideCalls(*this, /*InContext=*/nullptr, Results); 03247 break; 03248 03249 case PCC_RecoveryInFunction: 03250 // Unfiltered 03251 break; 03252 } 03253 03254 // If we are in a C++ non-static member function, check the qualifiers on 03255 // the member function to filter/prioritize the results list. 03256 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext)) 03257 if (CurMethod->isInstance()) 03258 Results.setObjectTypeQualifiers( 03259 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers())); 03260 03261 CodeCompletionDeclConsumer Consumer(Results, CurContext); 03262 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 03263 CodeCompleter->includeGlobals()); 03264 03265 AddOrdinaryNameResults(CompletionContext, S, *this, Results); 03266 Results.ExitScope(); 03267 03268 switch (CompletionContext) { 03269 case PCC_ParenthesizedExpression: 03270 case PCC_Expression: 03271 case PCC_Statement: 03272 case PCC_RecoveryInFunction: 03273 if (S->getFnParent()) 03274 AddPrettyFunctionResults(PP.getLangOpts(), Results); 03275 break; 03276 03277 case PCC_Namespace: 03278 case PCC_Class: 03279 case PCC_ObjCInterface: 03280 case PCC_ObjCImplementation: 03281 case PCC_ObjCInstanceVariableList: 03282 case PCC_Template: 03283 case PCC_MemberTemplate: 03284 case PCC_ForInit: 03285 case PCC_Condition: 03286 case PCC_Type: 03287 case PCC_LocalDeclarationSpecifiers: 03288 break; 03289 } 03290 03291 if (CodeCompleter->includeMacros()) 03292 AddMacroResults(PP, Results, false); 03293 03294 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 03295 Results.data(),Results.size()); 03296 } 03297 03298 static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, 03299 ParsedType Receiver, 03300 ArrayRef<IdentifierInfo *> SelIdents, 03301 bool AtArgumentExpression, 03302 bool IsSuper, 03303 ResultBuilder &Results); 03304 03305 void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, 03306 bool AllowNonIdentifiers, 03307 bool AllowNestedNameSpecifiers) { 03308 typedef CodeCompletionResult Result; 03309 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 03310 CodeCompleter->getCodeCompletionTUInfo(), 03311 AllowNestedNameSpecifiers 03312 ? CodeCompletionContext::CCC_PotentiallyQualifiedName 03313 : CodeCompletionContext::CCC_Name); 03314 Results.EnterNewScope(); 03315 03316 // Type qualifiers can come after names. 03317 Results.AddResult(Result("const")); 03318 Results.AddResult(Result("volatile")); 03319 if (getLangOpts().C99) 03320 Results.AddResult(Result("restrict")); 03321 03322 if (getLangOpts().CPlusPlus) { 03323 if (AllowNonIdentifiers) { 03324 Results.AddResult(Result("operator")); 03325 } 03326 03327 // Add nested-name-specifiers. 03328 if (AllowNestedNameSpecifiers) { 03329 Results.allowNestedNameSpecifiers(); 03330 Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy); 03331 CodeCompletionDeclConsumer Consumer(Results, CurContext); 03332 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer, 03333 CodeCompleter->includeGlobals()); 03334 Results.setFilter(nullptr); 03335 } 03336 } 03337 Results.ExitScope(); 03338 03339 // If we're in a context where we might have an expression (rather than a 03340 // declaration), and what we've seen so far is an Objective-C type that could 03341 // be a receiver of a class message, this may be a class message send with 03342 // the initial opening bracket '[' missing. Add appropriate completions. 03343 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers && 03344 DS.getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier && 03345 DS.getTypeSpecType() == DeclSpec::TST_typename && 03346 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified && 03347 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified && 03348 !DS.isTypeAltiVecVector() && 03349 S && 03350 (S->getFlags() & Scope::DeclScope) != 0 && 03351 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope | 03352 Scope::FunctionPrototypeScope | 03353 Scope::AtCatchScope)) == 0) { 03354 ParsedType T = DS.getRepAsType(); 03355 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType()) 03356 AddClassMessageCompletions(*this, S, T, None, false, false, Results); 03357 } 03358 03359 // Note that we intentionally suppress macro results here, since we do not 03360 // encourage using macros to produce the names of entities. 03361 03362 HandleCodeCompleteResults(this, CodeCompleter, 03363 Results.getCompletionContext(), 03364 Results.data(), Results.size()); 03365 } 03366 03367 struct Sema::CodeCompleteExpressionData { 03368 CodeCompleteExpressionData(QualType PreferredType = QualType()) 03369 : PreferredType(PreferredType), IntegralConstantExpression(false), 03370 ObjCCollection(false) { } 03371 03372 QualType PreferredType; 03373 bool IntegralConstantExpression; 03374 bool ObjCCollection; 03375 SmallVector<Decl *, 4> IgnoreDecls; 03376 }; 03377 03378 /// \brief Perform code-completion in an expression context when we know what 03379 /// type we're looking for. 03380 void Sema::CodeCompleteExpression(Scope *S, 03381 const CodeCompleteExpressionData &Data) { 03382 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 03383 CodeCompleter->getCodeCompletionTUInfo(), 03384 CodeCompletionContext::CCC_Expression); 03385 if (Data.ObjCCollection) 03386 Results.setFilter(&ResultBuilder::IsObjCCollection); 03387 else if (Data.IntegralConstantExpression) 03388 Results.setFilter(&ResultBuilder::IsIntegralConstantValue); 03389 else if (WantTypesInContext(PCC_Expression, getLangOpts())) 03390 Results.setFilter(&ResultBuilder::IsOrdinaryName); 03391 else 03392 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); 03393 03394 if (!Data.PreferredType.isNull()) 03395 Results.setPreferredType(Data.PreferredType.getNonReferenceType()); 03396 03397 // Ignore any declarations that we were told that we don't care about. 03398 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I) 03399 Results.Ignore(Data.IgnoreDecls[I]); 03400 03401 CodeCompletionDeclConsumer Consumer(Results, CurContext); 03402 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 03403 CodeCompleter->includeGlobals()); 03404 03405 Results.EnterNewScope(); 03406 AddOrdinaryNameResults(PCC_Expression, S, *this, Results); 03407 Results.ExitScope(); 03408 03409 bool PreferredTypeIsPointer = false; 03410 if (!Data.PreferredType.isNull()) 03411 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType() 03412 || Data.PreferredType->isMemberPointerType() 03413 || Data.PreferredType->isBlockPointerType(); 03414 03415 if (S->getFnParent() && 03416 !Data.ObjCCollection && 03417 !Data.IntegralConstantExpression) 03418 AddPrettyFunctionResults(PP.getLangOpts(), Results); 03419 03420 if (CodeCompleter->includeMacros()) 03421 AddMacroResults(PP, Results, false, PreferredTypeIsPointer); 03422 HandleCodeCompleteResults(this, CodeCompleter, 03423 CodeCompletionContext(CodeCompletionContext::CCC_Expression, 03424 Data.PreferredType), 03425 Results.data(),Results.size()); 03426 } 03427 03428 void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) { 03429 if (E.isInvalid()) 03430 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction); 03431 else if (getLangOpts().ObjC1) 03432 CodeCompleteObjCInstanceMessage(S, E.get(), None, false); 03433 } 03434 03435 /// \brief The set of properties that have already been added, referenced by 03436 /// property name. 03437 typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet; 03438 03439 /// \brief Retrieve the container definition, if any? 03440 static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) { 03441 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) { 03442 if (Interface->hasDefinition()) 03443 return Interface->getDefinition(); 03444 03445 return Interface; 03446 } 03447 03448 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 03449 if (Protocol->hasDefinition()) 03450 return Protocol->getDefinition(); 03451 03452 return Protocol; 03453 } 03454 return Container; 03455 } 03456 03457 static void AddObjCProperties(ObjCContainerDecl *Container, 03458 bool AllowCategories, 03459 bool AllowNullaryMethods, 03460 DeclContext *CurContext, 03461 AddedPropertiesSet &AddedProperties, 03462 ResultBuilder &Results) { 03463 typedef CodeCompletionResult Result; 03464 03465 // Retrieve the definition. 03466 Container = getContainerDef(Container); 03467 03468 // Add properties in this container. 03469 for (const auto *P : Container->properties()) 03470 if (AddedProperties.insert(P->getIdentifier())) 03471 Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr), 03472 CurContext); 03473 03474 // Add nullary methods 03475 if (AllowNullaryMethods) { 03476 ASTContext &Context = Container->getASTContext(); 03477 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema()); 03478 for (auto *M : Container->methods()) { 03479 if (M->getSelector().isUnarySelector()) 03480 if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0)) 03481 if (AddedProperties.insert(Name)) { 03482 CodeCompletionBuilder Builder(Results.getAllocator(), 03483 Results.getCodeCompletionTUInfo()); 03484 AddResultTypeChunk(Context, Policy, M, Builder); 03485 Builder.AddTypedTextChunk( 03486 Results.getAllocator().CopyString(Name->getName())); 03487 03488 Results.MaybeAddResult(Result(Builder.TakeString(), M, 03489 CCP_MemberDeclaration + CCD_MethodAsProperty), 03490 CurContext); 03491 } 03492 } 03493 } 03494 03495 03496 // Add properties in referenced protocols. 03497 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 03498 for (auto *P : Protocol->protocols()) 03499 AddObjCProperties(P, AllowCategories, AllowNullaryMethods, CurContext, 03500 AddedProperties, Results); 03501 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){ 03502 if (AllowCategories) { 03503 // Look through categories. 03504 for (auto *Cat : IFace->known_categories()) 03505 AddObjCProperties(Cat, AllowCategories, AllowNullaryMethods, CurContext, 03506 AddedProperties, Results); 03507 } 03508 03509 // Look through protocols. 03510 for (auto *I : IFace->all_referenced_protocols()) 03511 AddObjCProperties(I, AllowCategories, AllowNullaryMethods, CurContext, 03512 AddedProperties, Results); 03513 03514 // Look in the superclass. 03515 if (IFace->getSuperClass()) 03516 AddObjCProperties(IFace->getSuperClass(), AllowCategories, 03517 AllowNullaryMethods, CurContext, 03518 AddedProperties, Results); 03519 } else if (const ObjCCategoryDecl *Category 03520 = dyn_cast<ObjCCategoryDecl>(Container)) { 03521 // Look through protocols. 03522 for (auto *P : Category->protocols()) 03523 AddObjCProperties(P, AllowCategories, AllowNullaryMethods, CurContext, 03524 AddedProperties, Results); 03525 } 03526 } 03527 03528 void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, 03529 SourceLocation OpLoc, 03530 bool IsArrow) { 03531 if (!Base || !CodeCompleter) 03532 return; 03533 03534 ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow); 03535 if (ConvertedBase.isInvalid()) 03536 return; 03537 Base = ConvertedBase.get(); 03538 03539 typedef CodeCompletionResult Result; 03540 03541 QualType BaseType = Base->getType(); 03542 03543 if (IsArrow) { 03544 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) 03545 BaseType = Ptr->getPointeeType(); 03546 else if (BaseType->isObjCObjectPointerType()) 03547 /*Do nothing*/ ; 03548 else 03549 return; 03550 } 03551 03552 enum CodeCompletionContext::Kind contextKind; 03553 03554 if (IsArrow) { 03555 contextKind = CodeCompletionContext::CCC_ArrowMemberAccess; 03556 } 03557 else { 03558 if (BaseType->isObjCObjectPointerType() || 03559 BaseType->isObjCObjectOrInterfaceType()) { 03560 contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess; 03561 } 03562 else { 03563 contextKind = CodeCompletionContext::CCC_DotMemberAccess; 03564 } 03565 } 03566 03567 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 03568 CodeCompleter->getCodeCompletionTUInfo(), 03569 CodeCompletionContext(contextKind, 03570 BaseType), 03571 &ResultBuilder::IsMember); 03572 Results.EnterNewScope(); 03573 if (const RecordType *Record = BaseType->getAs<RecordType>()) { 03574 // Indicate that we are performing a member access, and the cv-qualifiers 03575 // for the base object type. 03576 Results.setObjectTypeQualifiers(BaseType.getQualifiers()); 03577 03578 // Access to a C/C++ class, struct, or union. 03579 Results.allowNestedNameSpecifiers(); 03580 CodeCompletionDeclConsumer Consumer(Results, CurContext); 03581 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer, 03582 CodeCompleter->includeGlobals()); 03583 03584 if (getLangOpts().CPlusPlus) { 03585 if (!Results.empty()) { 03586 // The "template" keyword can follow "->" or "." in the grammar. 03587 // However, we only want to suggest the template keyword if something 03588 // is dependent. 03589 bool IsDependent = BaseType->isDependentType(); 03590 if (!IsDependent) { 03591 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent()) 03592 if (DeclContext *Ctx = DepScope->getEntity()) { 03593 IsDependent = Ctx->isDependentContext(); 03594 break; 03595 } 03596 } 03597 03598 if (IsDependent) 03599 Results.AddResult(Result("template")); 03600 } 03601 } 03602 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) { 03603 // Objective-C property reference. 03604 AddedPropertiesSet AddedProperties; 03605 03606 // Add property results based on our interface. 03607 const ObjCObjectPointerType *ObjCPtr 03608 = BaseType->getAsObjCInterfacePointerType(); 03609 assert(ObjCPtr && "Non-NULL pointer guaranteed above!"); 03610 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, 03611 /*AllowNullaryMethods=*/true, CurContext, 03612 AddedProperties, Results); 03613 03614 // Add properties from the protocols in a qualified interface. 03615 for (auto *I : ObjCPtr->quals()) 03616 AddObjCProperties(I, true, /*AllowNullaryMethods=*/true, CurContext, 03617 AddedProperties, Results); 03618 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) || 03619 (!IsArrow && BaseType->isObjCObjectType())) { 03620 // Objective-C instance variable access. 03621 ObjCInterfaceDecl *Class = nullptr; 03622 if (const ObjCObjectPointerType *ObjCPtr 03623 = BaseType->getAs<ObjCObjectPointerType>()) 03624 Class = ObjCPtr->getInterfaceDecl(); 03625 else 03626 Class = BaseType->getAs<ObjCObjectType>()->getInterface(); 03627 03628 // Add all ivars from this class and its superclasses. 03629 if (Class) { 03630 CodeCompletionDeclConsumer Consumer(Results, CurContext); 03631 Results.setFilter(&ResultBuilder::IsObjCIvar); 03632 LookupVisibleDecls(Class, LookupMemberName, Consumer, 03633 CodeCompleter->includeGlobals()); 03634 } 03635 } 03636 03637 // FIXME: How do we cope with isa? 03638 03639 Results.ExitScope(); 03640 03641 // Hand off the results found for code completion. 03642 HandleCodeCompleteResults(this, CodeCompleter, 03643 Results.getCompletionContext(), 03644 Results.data(),Results.size()); 03645 } 03646 03647 void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { 03648 if (!CodeCompleter) 03649 return; 03650 03651 ResultBuilder::LookupFilter Filter = nullptr; 03652 enum CodeCompletionContext::Kind ContextKind 03653 = CodeCompletionContext::CCC_Other; 03654 switch ((DeclSpec::TST)TagSpec) { 03655 case DeclSpec::TST_enum: 03656 Filter = &ResultBuilder::IsEnum; 03657 ContextKind = CodeCompletionContext::CCC_EnumTag; 03658 break; 03659 03660 case DeclSpec::TST_union: 03661 Filter = &ResultBuilder::IsUnion; 03662 ContextKind = CodeCompletionContext::CCC_UnionTag; 03663 break; 03664 03665 case DeclSpec::TST_struct: 03666 case DeclSpec::TST_class: 03667 case DeclSpec::TST_interface: 03668 Filter = &ResultBuilder::IsClassOrStruct; 03669 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag; 03670 break; 03671 03672 default: 03673 llvm_unreachable("Unknown type specifier kind in CodeCompleteTag"); 03674 } 03675 03676 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 03677 CodeCompleter->getCodeCompletionTUInfo(), ContextKind); 03678 CodeCompletionDeclConsumer Consumer(Results, CurContext); 03679 03680 // First pass: look for tags. 03681 Results.setFilter(Filter); 03682 LookupVisibleDecls(S, LookupTagName, Consumer, 03683 CodeCompleter->includeGlobals()); 03684 03685 if (CodeCompleter->includeGlobals()) { 03686 // Second pass: look for nested name specifiers. 03687 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier); 03688 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer); 03689 } 03690 03691 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 03692 Results.data(),Results.size()); 03693 } 03694 03695 void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) { 03696 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 03697 CodeCompleter->getCodeCompletionTUInfo(), 03698 CodeCompletionContext::CCC_TypeQualifiers); 03699 Results.EnterNewScope(); 03700 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const)) 03701 Results.AddResult("const"); 03702 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile)) 03703 Results.AddResult("volatile"); 03704 if (getLangOpts().C99 && 03705 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict)) 03706 Results.AddResult("restrict"); 03707 if (getLangOpts().C11 && 03708 !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic)) 03709 Results.AddResult("_Atomic"); 03710 Results.ExitScope(); 03711 HandleCodeCompleteResults(this, CodeCompleter, 03712 Results.getCompletionContext(), 03713 Results.data(), Results.size()); 03714 } 03715 03716 void Sema::CodeCompleteCase(Scope *S) { 03717 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter) 03718 return; 03719 03720 SwitchStmt *Switch = getCurFunction()->SwitchStack.back(); 03721 QualType type = Switch->getCond()->IgnoreImplicit()->getType(); 03722 if (!type->isEnumeralType()) { 03723 CodeCompleteExpressionData Data(type); 03724 Data.IntegralConstantExpression = true; 03725 CodeCompleteExpression(S, Data); 03726 return; 03727 } 03728 03729 // Code-complete the cases of a switch statement over an enumeration type 03730 // by providing the list of 03731 EnumDecl *Enum = type->castAs<EnumType>()->getDecl(); 03732 if (EnumDecl *Def = Enum->getDefinition()) 03733 Enum = Def; 03734 03735 // Determine which enumerators we have already seen in the switch statement. 03736 // FIXME: Ideally, we would also be able to look *past* the code-completion 03737 // token, in case we are code-completing in the middle of the switch and not 03738 // at the end. However, we aren't able to do so at the moment. 03739 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen; 03740 NestedNameSpecifier *Qualifier = nullptr; 03741 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC; 03742 SC = SC->getNextSwitchCase()) { 03743 CaseStmt *Case = dyn_cast<CaseStmt>(SC); 03744 if (!Case) 03745 continue; 03746 03747 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts(); 03748 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal)) 03749 if (EnumConstantDecl *Enumerator 03750 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { 03751 // We look into the AST of the case statement to determine which 03752 // enumerator was named. Alternatively, we could compute the value of 03753 // the integral constant expression, then compare it against the 03754 // values of each enumerator. However, value-based approach would not 03755 // work as well with C++ templates where enumerators declared within a 03756 // template are type- and value-dependent. 03757 EnumeratorsSeen.insert(Enumerator); 03758 03759 // If this is a qualified-id, keep track of the nested-name-specifier 03760 // so that we can reproduce it as part of code completion, e.g., 03761 // 03762 // switch (TagD.getKind()) { 03763 // case TagDecl::TK_enum: 03764 // break; 03765 // case XXX 03766 // 03767 // At the XXX, our completions are TagDecl::TK_union, 03768 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union, 03769 // TK_struct, and TK_class. 03770 Qualifier = DRE->getQualifier(); 03771 } 03772 } 03773 03774 if (getLangOpts().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) { 03775 // If there are no prior enumerators in C++, check whether we have to 03776 // qualify the names of the enumerators that we suggest, because they 03777 // may not be visible in this scope. 03778 Qualifier = getRequiredQualification(Context, CurContext, Enum); 03779 } 03780 03781 // Add any enumerators that have not yet been mentioned. 03782 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 03783 CodeCompleter->getCodeCompletionTUInfo(), 03784 CodeCompletionContext::CCC_Expression); 03785 Results.EnterNewScope(); 03786 for (auto *E : Enum->enumerators()) { 03787 if (EnumeratorsSeen.count(E)) 03788 continue; 03789 03790 CodeCompletionResult R(E, CCP_EnumInCase, Qualifier); 03791 Results.AddResult(R, CurContext, nullptr, false); 03792 } 03793 Results.ExitScope(); 03794 03795 //We need to make sure we're setting the right context, 03796 //so only say we include macros if the code completer says we do 03797 enum CodeCompletionContext::Kind kind = CodeCompletionContext::CCC_Other; 03798 if (CodeCompleter->includeMacros()) { 03799 AddMacroResults(PP, Results, false); 03800 kind = CodeCompletionContext::CCC_OtherWithMacros; 03801 } 03802 03803 HandleCodeCompleteResults(this, CodeCompleter, 03804 kind, 03805 Results.data(),Results.size()); 03806 } 03807 03808 static bool anyNullArguments(ArrayRef<Expr *> Args) { 03809 if (Args.size() && !Args.data()) 03810 return true; 03811 03812 for (unsigned I = 0; I != Args.size(); ++I) 03813 if (!Args[I]) 03814 return true; 03815 03816 return false; 03817 } 03818 03819 void Sema::CodeCompleteCall(Scope *S, Expr *FnIn, ArrayRef<Expr *> Args) { 03820 if (!CodeCompleter) 03821 return; 03822 03823 // When we're code-completing for a call, we fall back to ordinary 03824 // name code-completion whenever we can't produce specific 03825 // results. We may want to revisit this strategy in the future, 03826 // e.g., by merging the two kinds of results. 03827 03828 Expr *Fn = (Expr *)FnIn; 03829 03830 // Ignore type-dependent call expressions entirely. 03831 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) || 03832 Expr::hasAnyTypeDependentArguments(Args)) { 03833 CodeCompleteOrdinaryName(S, PCC_Expression); 03834 return; 03835 } 03836 03837 // Build an overload candidate set based on the functions we find. 03838 SourceLocation Loc = Fn->getExprLoc(); 03839 OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); 03840 03841 // FIXME: What if we're calling something that isn't a function declaration? 03842 // FIXME: What if we're calling a pseudo-destructor? 03843 // FIXME: What if we're calling a member function? 03844 03845 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate; 03846 SmallVector<ResultCandidate, 8> Results; 03847 03848 Expr *NakedFn = Fn->IgnoreParenCasts(); 03849 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn)) 03850 AddOverloadedCallCandidates(ULE, Args, CandidateSet, 03851 /*PartialOverloading=*/ true); 03852 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) { 03853 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl()); 03854 if (FDecl) { 03855 if (!getLangOpts().CPlusPlus || 03856 !FDecl->getType()->getAs<FunctionProtoType>()) 03857 Results.push_back(ResultCandidate(FDecl)); 03858 else 03859 // FIXME: access? 03860 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none), Args, 03861 CandidateSet, false, /*PartialOverloading*/true); 03862 } 03863 } 03864 03865 QualType ParamType; 03866 03867 if (!CandidateSet.empty()) { 03868 // Sort the overload candidate set by placing the best overloads first. 03869 std::stable_sort( 03870 CandidateSet.begin(), CandidateSet.end(), 03871 [&](const OverloadCandidate &X, const OverloadCandidate &Y) { 03872 return isBetterOverloadCandidate(*this, X, Y, Loc); 03873 }); 03874 03875 // Add the remaining viable overload candidates as code-completion reslults. 03876 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(), 03877 CandEnd = CandidateSet.end(); 03878 Cand != CandEnd; ++Cand) { 03879 if (Cand->Viable) 03880 Results.push_back(ResultCandidate(Cand->Function)); 03881 } 03882 03883 // From the viable candidates, try to determine the type of this parameter. 03884 for (unsigned I = 0, N = Results.size(); I != N; ++I) { 03885 if (const FunctionType *FType = Results[I].getFunctionType()) 03886 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType)) 03887 if (Args.size() < Proto->getNumParams()) { 03888 if (ParamType.isNull()) 03889 ParamType = Proto->getParamType(Args.size()); 03890 else if (!Context.hasSameUnqualifiedType( 03891 ParamType.getNonReferenceType(), 03892 Proto->getParamType(Args.size()) 03893 .getNonReferenceType())) { 03894 ParamType = QualType(); 03895 break; 03896 } 03897 } 03898 } 03899 } else { 03900 // Try to determine the parameter type from the type of the expression 03901 // being called. 03902 QualType FunctionType = Fn->getType(); 03903 if (const PointerType *Ptr = FunctionType->getAs<PointerType>()) 03904 FunctionType = Ptr->getPointeeType(); 03905 else if (const BlockPointerType *BlockPtr 03906 = FunctionType->getAs<BlockPointerType>()) 03907 FunctionType = BlockPtr->getPointeeType(); 03908 else if (const MemberPointerType *MemPtr 03909 = FunctionType->getAs<MemberPointerType>()) 03910 FunctionType = MemPtr->getPointeeType(); 03911 03912 if (const FunctionProtoType *Proto 03913 = FunctionType->getAs<FunctionProtoType>()) { 03914 if (Args.size() < Proto->getNumParams()) 03915 ParamType = Proto->getParamType(Args.size()); 03916 } 03917 } 03918 03919 if (ParamType.isNull()) 03920 CodeCompleteOrdinaryName(S, PCC_Expression); 03921 else 03922 CodeCompleteExpression(S, ParamType); 03923 03924 if (!Results.empty()) 03925 CodeCompleter->ProcessOverloadCandidates(*this, Args.size(), Results.data(), 03926 Results.size()); 03927 } 03928 03929 void Sema::CodeCompleteInitializer(Scope *S, Decl *D) { 03930 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D); 03931 if (!VD) { 03932 CodeCompleteOrdinaryName(S, PCC_Expression); 03933 return; 03934 } 03935 03936 CodeCompleteExpression(S, VD->getType()); 03937 } 03938 03939 void Sema::CodeCompleteReturn(Scope *S) { 03940 QualType ResultType; 03941 if (isa<BlockDecl>(CurContext)) { 03942 if (BlockScopeInfo *BSI = getCurBlock()) 03943 ResultType = BSI->ReturnType; 03944 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext)) 03945 ResultType = Function->getReturnType(); 03946 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext)) 03947 ResultType = Method->getReturnType(); 03948 03949 if (ResultType.isNull()) 03950 CodeCompleteOrdinaryName(S, PCC_Expression); 03951 else 03952 CodeCompleteExpression(S, ResultType); 03953 } 03954 03955 void Sema::CodeCompleteAfterIf(Scope *S) { 03956 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 03957 CodeCompleter->getCodeCompletionTUInfo(), 03958 mapCodeCompletionContext(*this, PCC_Statement)); 03959 Results.setFilter(&ResultBuilder::IsOrdinaryName); 03960 Results.EnterNewScope(); 03961 03962 CodeCompletionDeclConsumer Consumer(Results, CurContext); 03963 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 03964 CodeCompleter->includeGlobals()); 03965 03966 AddOrdinaryNameResults(PCC_Statement, S, *this, Results); 03967 03968 // "else" block 03969 CodeCompletionBuilder Builder(Results.getAllocator(), 03970 Results.getCodeCompletionTUInfo()); 03971 Builder.AddTypedTextChunk("else"); 03972 if (Results.includeCodePatterns()) { 03973 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 03974 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 03975 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 03976 Builder.AddPlaceholderChunk("statements"); 03977 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 03978 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 03979 } 03980 Results.AddResult(Builder.TakeString()); 03981 03982 // "else if" block 03983 Builder.AddTypedTextChunk("else"); 03984 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 03985 Builder.AddTextChunk("if"); 03986 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 03987 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 03988 if (getLangOpts().CPlusPlus) 03989 Builder.AddPlaceholderChunk("condition"); 03990 else 03991 Builder.AddPlaceholderChunk("expression"); 03992 Builder.AddChunk(CodeCompletionString::CK_RightParen); 03993 if (Results.includeCodePatterns()) { 03994 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 03995 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 03996 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 03997 Builder.AddPlaceholderChunk("statements"); 03998 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 03999 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 04000 } 04001 Results.AddResult(Builder.TakeString()); 04002 04003 Results.ExitScope(); 04004 04005 if (S->getFnParent()) 04006 AddPrettyFunctionResults(PP.getLangOpts(), Results); 04007 04008 if (CodeCompleter->includeMacros()) 04009 AddMacroResults(PP, Results, false); 04010 04011 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 04012 Results.data(),Results.size()); 04013 } 04014 04015 void Sema::CodeCompleteAssignmentRHS(Scope *S, Expr *LHS) { 04016 if (LHS) 04017 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType()); 04018 else 04019 CodeCompleteOrdinaryName(S, PCC_Expression); 04020 } 04021 04022 void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, 04023 bool EnteringContext) { 04024 if (!SS.getScopeRep() || !CodeCompleter) 04025 return; 04026 04027 DeclContext *Ctx = computeDeclContext(SS, EnteringContext); 04028 if (!Ctx) 04029 return; 04030 04031 // Try to instantiate any non-dependent declaration contexts before 04032 // we look in them. 04033 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx)) 04034 return; 04035 04036 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04037 CodeCompleter->getCodeCompletionTUInfo(), 04038 CodeCompletionContext::CCC_Name); 04039 Results.EnterNewScope(); 04040 04041 // The "template" keyword can follow "::" in the grammar, but only 04042 // put it into the grammar if the nested-name-specifier is dependent. 04043 NestedNameSpecifier *NNS = SS.getScopeRep(); 04044 if (!Results.empty() && NNS->isDependent()) 04045 Results.AddResult("template"); 04046 04047 // Add calls to overridden virtual functions, if there are any. 04048 // 04049 // FIXME: This isn't wonderful, because we don't know whether we're actually 04050 // in a context that permits expressions. This is a general issue with 04051 // qualified-id completions. 04052 if (!EnteringContext) 04053 MaybeAddOverrideCalls(*this, Ctx, Results); 04054 Results.ExitScope(); 04055 04056 CodeCompletionDeclConsumer Consumer(Results, CurContext); 04057 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer); 04058 04059 HandleCodeCompleteResults(this, CodeCompleter, 04060 Results.getCompletionContext(), 04061 Results.data(),Results.size()); 04062 } 04063 04064 void Sema::CodeCompleteUsing(Scope *S) { 04065 if (!CodeCompleter) 04066 return; 04067 04068 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04069 CodeCompleter->getCodeCompletionTUInfo(), 04070 CodeCompletionContext::CCC_PotentiallyQualifiedName, 04071 &ResultBuilder::IsNestedNameSpecifier); 04072 Results.EnterNewScope(); 04073 04074 // If we aren't in class scope, we could see the "namespace" keyword. 04075 if (!S->isClassScope()) 04076 Results.AddResult(CodeCompletionResult("namespace")); 04077 04078 // After "using", we can see anything that would start a 04079 // nested-name-specifier. 04080 CodeCompletionDeclConsumer Consumer(Results, CurContext); 04081 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 04082 CodeCompleter->includeGlobals()); 04083 Results.ExitScope(); 04084 04085 HandleCodeCompleteResults(this, CodeCompleter, 04086 CodeCompletionContext::CCC_PotentiallyQualifiedName, 04087 Results.data(),Results.size()); 04088 } 04089 04090 void Sema::CodeCompleteUsingDirective(Scope *S) { 04091 if (!CodeCompleter) 04092 return; 04093 04094 // After "using namespace", we expect to see a namespace name or namespace 04095 // alias. 04096 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04097 CodeCompleter->getCodeCompletionTUInfo(), 04098 CodeCompletionContext::CCC_Namespace, 04099 &ResultBuilder::IsNamespaceOrAlias); 04100 Results.EnterNewScope(); 04101 CodeCompletionDeclConsumer Consumer(Results, CurContext); 04102 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 04103 CodeCompleter->includeGlobals()); 04104 Results.ExitScope(); 04105 HandleCodeCompleteResults(this, CodeCompleter, 04106 CodeCompletionContext::CCC_Namespace, 04107 Results.data(),Results.size()); 04108 } 04109 04110 void Sema::CodeCompleteNamespaceDecl(Scope *S) { 04111 if (!CodeCompleter) 04112 return; 04113 04114 DeclContext *Ctx = S->getEntity(); 04115 if (!S->getParent()) 04116 Ctx = Context.getTranslationUnitDecl(); 04117 04118 bool SuppressedGlobalResults 04119 = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx); 04120 04121 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04122 CodeCompleter->getCodeCompletionTUInfo(), 04123 SuppressedGlobalResults 04124 ? CodeCompletionContext::CCC_Namespace 04125 : CodeCompletionContext::CCC_Other, 04126 &ResultBuilder::IsNamespace); 04127 04128 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) { 04129 // We only want to see those namespaces that have already been defined 04130 // within this scope, because its likely that the user is creating an 04131 // extended namespace declaration. Keep track of the most recent 04132 // definition of each namespace. 04133 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest; 04134 for (DeclContext::specific_decl_iterator<NamespaceDecl> 04135 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end()); 04136 NS != NSEnd; ++NS) 04137 OrigToLatest[NS->getOriginalNamespace()] = *NS; 04138 04139 // Add the most recent definition (or extended definition) of each 04140 // namespace to the list of results. 04141 Results.EnterNewScope(); 04142 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator 04143 NS = OrigToLatest.begin(), 04144 NSEnd = OrigToLatest.end(); 04145 NS != NSEnd; ++NS) 04146 Results.AddResult(CodeCompletionResult( 04147 NS->second, Results.getBasePriority(NS->second), 04148 nullptr), 04149 CurContext, nullptr, false); 04150 Results.ExitScope(); 04151 } 04152 04153 HandleCodeCompleteResults(this, CodeCompleter, 04154 Results.getCompletionContext(), 04155 Results.data(),Results.size()); 04156 } 04157 04158 void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { 04159 if (!CodeCompleter) 04160 return; 04161 04162 // After "namespace", we expect to see a namespace or alias. 04163 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04164 CodeCompleter->getCodeCompletionTUInfo(), 04165 CodeCompletionContext::CCC_Namespace, 04166 &ResultBuilder::IsNamespaceOrAlias); 04167 CodeCompletionDeclConsumer Consumer(Results, CurContext); 04168 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 04169 CodeCompleter->includeGlobals()); 04170 HandleCodeCompleteResults(this, CodeCompleter, 04171 Results.getCompletionContext(), 04172 Results.data(),Results.size()); 04173 } 04174 04175 void Sema::CodeCompleteOperatorName(Scope *S) { 04176 if (!CodeCompleter) 04177 return; 04178 04179 typedef CodeCompletionResult Result; 04180 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04181 CodeCompleter->getCodeCompletionTUInfo(), 04182 CodeCompletionContext::CCC_Type, 04183 &ResultBuilder::IsType); 04184 Results.EnterNewScope(); 04185 04186 // Add the names of overloadable operators. 04187 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 04188 if (std::strcmp(Spelling, "?")) \ 04189 Results.AddResult(Result(Spelling)); 04190 #include "clang/Basic/OperatorKinds.def" 04191 04192 // Add any type names visible from the current scope 04193 Results.allowNestedNameSpecifiers(); 04194 CodeCompletionDeclConsumer Consumer(Results, CurContext); 04195 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 04196 CodeCompleter->includeGlobals()); 04197 04198 // Add any type specifiers 04199 AddTypeSpecifierResults(getLangOpts(), Results); 04200 Results.ExitScope(); 04201 04202 HandleCodeCompleteResults(this, CodeCompleter, 04203 CodeCompletionContext::CCC_Type, 04204 Results.data(),Results.size()); 04205 } 04206 04207 void Sema::CodeCompleteConstructorInitializer( 04208 Decl *ConstructorD, 04209 ArrayRef <CXXCtorInitializer *> Initializers) { 04210 PrintingPolicy Policy = getCompletionPrintingPolicy(*this); 04211 CXXConstructorDecl *Constructor 04212 = static_cast<CXXConstructorDecl *>(ConstructorD); 04213 if (!Constructor) 04214 return; 04215 04216 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04217 CodeCompleter->getCodeCompletionTUInfo(), 04218 CodeCompletionContext::CCC_PotentiallyQualifiedName); 04219 Results.EnterNewScope(); 04220 04221 // Fill in any already-initialized fields or base classes. 04222 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields; 04223 llvm::SmallPtrSet<CanQualType, 4> InitializedBases; 04224 for (unsigned I = 0, E = Initializers.size(); I != E; ++I) { 04225 if (Initializers[I]->isBaseInitializer()) 04226 InitializedBases.insert( 04227 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0))); 04228 else 04229 InitializedFields.insert(cast<FieldDecl>( 04230 Initializers[I]->getAnyMember())); 04231 } 04232 04233 // Add completions for base classes. 04234 CodeCompletionBuilder Builder(Results.getAllocator(), 04235 Results.getCodeCompletionTUInfo()); 04236 bool SawLastInitializer = Initializers.empty(); 04237 CXXRecordDecl *ClassDecl = Constructor->getParent(); 04238 for (const auto &Base : ClassDecl->bases()) { 04239 if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))) { 04240 SawLastInitializer 04241 = !Initializers.empty() && 04242 Initializers.back()->isBaseInitializer() && 04243 Context.hasSameUnqualifiedType(Base.getType(), 04244 QualType(Initializers.back()->getBaseClass(), 0)); 04245 continue; 04246 } 04247 04248 Builder.AddTypedTextChunk( 04249 Results.getAllocator().CopyString( 04250 Base.getType().getAsString(Policy))); 04251 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 04252 Builder.AddPlaceholderChunk("args"); 04253 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04254 Results.AddResult(CodeCompletionResult(Builder.TakeString(), 04255 SawLastInitializer? CCP_NextInitializer 04256 : CCP_MemberDeclaration)); 04257 SawLastInitializer = false; 04258 } 04259 04260 // Add completions for virtual base classes. 04261 for (const auto &Base : ClassDecl->vbases()) { 04262 if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))) { 04263 SawLastInitializer 04264 = !Initializers.empty() && 04265 Initializers.back()->isBaseInitializer() && 04266 Context.hasSameUnqualifiedType(Base.getType(), 04267 QualType(Initializers.back()->getBaseClass(), 0)); 04268 continue; 04269 } 04270 04271 Builder.AddTypedTextChunk( 04272 Builder.getAllocator().CopyString( 04273 Base.getType().getAsString(Policy))); 04274 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 04275 Builder.AddPlaceholderChunk("args"); 04276 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04277 Results.AddResult(CodeCompletionResult(Builder.TakeString(), 04278 SawLastInitializer? CCP_NextInitializer 04279 : CCP_MemberDeclaration)); 04280 SawLastInitializer = false; 04281 } 04282 04283 // Add completions for members. 04284 for (auto *Field : ClassDecl->fields()) { 04285 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) { 04286 SawLastInitializer 04287 = !Initializers.empty() && 04288 Initializers.back()->isAnyMemberInitializer() && 04289 Initializers.back()->getAnyMember() == Field; 04290 continue; 04291 } 04292 04293 if (!Field->getDeclName()) 04294 continue; 04295 04296 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 04297 Field->getIdentifier()->getName())); 04298 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 04299 Builder.AddPlaceholderChunk("args"); 04300 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04301 Results.AddResult(CodeCompletionResult(Builder.TakeString(), 04302 SawLastInitializer? CCP_NextInitializer 04303 : CCP_MemberDeclaration, 04304 CXCursor_MemberRef, 04305 CXAvailability_Available, 04306 Field)); 04307 SawLastInitializer = false; 04308 } 04309 Results.ExitScope(); 04310 04311 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 04312 Results.data(), Results.size()); 04313 } 04314 04315 /// \brief Determine whether this scope denotes a namespace. 04316 static bool isNamespaceScope(Scope *S) { 04317 DeclContext *DC = S->getEntity(); 04318 if (!DC) 04319 return false; 04320 04321 return DC->isFileContext(); 04322 } 04323 04324 void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, 04325 bool AfterAmpersand) { 04326 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04327 CodeCompleter->getCodeCompletionTUInfo(), 04328 CodeCompletionContext::CCC_Other); 04329 Results.EnterNewScope(); 04330 04331 // Note what has already been captured. 04332 llvm::SmallPtrSet<IdentifierInfo *, 4> Known; 04333 bool IncludedThis = false; 04334 for (const auto &C : Intro.Captures) { 04335 if (C.Kind == LCK_This) { 04336 IncludedThis = true; 04337 continue; 04338 } 04339 04340 Known.insert(C.Id); 04341 } 04342 04343 // Look for other capturable variables. 04344 for (; S && !isNamespaceScope(S); S = S->getParent()) { 04345 for (const auto *D : S->decls()) { 04346 const auto *Var = dyn_cast<VarDecl>(D); 04347 if (!Var || 04348 !Var->hasLocalStorage() || 04349 Var->hasAttr<BlocksAttr>()) 04350 continue; 04351 04352 if (Known.insert(Var->getIdentifier())) 04353 Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration), 04354 CurContext, nullptr, false); 04355 } 04356 } 04357 04358 // Add 'this', if it would be valid. 04359 if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy) 04360 addThisCompletion(*this, Results); 04361 04362 Results.ExitScope(); 04363 04364 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 04365 Results.data(), Results.size()); 04366 } 04367 04368 /// Macro that optionally prepends an "@" to the string literal passed in via 04369 /// Keyword, depending on whether NeedAt is true or false. 04370 #define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) ((NeedAt)? "@" Keyword : Keyword) 04371 04372 static void AddObjCImplementationResults(const LangOptions &LangOpts, 04373 ResultBuilder &Results, 04374 bool NeedAt) { 04375 typedef CodeCompletionResult Result; 04376 // Since we have an implementation, we can end it. 04377 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end"))); 04378 04379 CodeCompletionBuilder Builder(Results.getAllocator(), 04380 Results.getCodeCompletionTUInfo()); 04381 if (LangOpts.ObjC2) { 04382 // @dynamic 04383 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"dynamic")); 04384 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04385 Builder.AddPlaceholderChunk("property"); 04386 Results.AddResult(Result(Builder.TakeString())); 04387 04388 // @synthesize 04389 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synthesize")); 04390 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04391 Builder.AddPlaceholderChunk("property"); 04392 Results.AddResult(Result(Builder.TakeString())); 04393 } 04394 } 04395 04396 static void AddObjCInterfaceResults(const LangOptions &LangOpts, 04397 ResultBuilder &Results, 04398 bool NeedAt) { 04399 typedef CodeCompletionResult Result; 04400 04401 // Since we have an interface or protocol, we can end it. 04402 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end"))); 04403 04404 if (LangOpts.ObjC2) { 04405 // @property 04406 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"property"))); 04407 04408 // @required 04409 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"required"))); 04410 04411 // @optional 04412 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"optional"))); 04413 } 04414 } 04415 04416 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) { 04417 typedef CodeCompletionResult Result; 04418 CodeCompletionBuilder Builder(Results.getAllocator(), 04419 Results.getCodeCompletionTUInfo()); 04420 04421 // @class name ; 04422 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"class")); 04423 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04424 Builder.AddPlaceholderChunk("name"); 04425 Results.AddResult(Result(Builder.TakeString())); 04426 04427 if (Results.includeCodePatterns()) { 04428 // @interface name 04429 // FIXME: Could introduce the whole pattern, including superclasses and 04430 // such. 04431 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"interface")); 04432 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04433 Builder.AddPlaceholderChunk("class"); 04434 Results.AddResult(Result(Builder.TakeString())); 04435 04436 // @protocol name 04437 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol")); 04438 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04439 Builder.AddPlaceholderChunk("protocol"); 04440 Results.AddResult(Result(Builder.TakeString())); 04441 04442 // @implementation name 04443 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"implementation")); 04444 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04445 Builder.AddPlaceholderChunk("class"); 04446 Results.AddResult(Result(Builder.TakeString())); 04447 } 04448 04449 // @compatibility_alias name 04450 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"compatibility_alias")); 04451 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04452 Builder.AddPlaceholderChunk("alias"); 04453 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04454 Builder.AddPlaceholderChunk("class"); 04455 Results.AddResult(Result(Builder.TakeString())); 04456 04457 if (Results.getSema().getLangOpts().Modules) { 04458 // @import name 04459 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "import")); 04460 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04461 Builder.AddPlaceholderChunk("module"); 04462 Results.AddResult(Result(Builder.TakeString())); 04463 } 04464 } 04465 04466 void Sema::CodeCompleteObjCAtDirective(Scope *S) { 04467 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04468 CodeCompleter->getCodeCompletionTUInfo(), 04469 CodeCompletionContext::CCC_Other); 04470 Results.EnterNewScope(); 04471 if (isa<ObjCImplDecl>(CurContext)) 04472 AddObjCImplementationResults(getLangOpts(), Results, false); 04473 else if (CurContext->isObjCContainer()) 04474 AddObjCInterfaceResults(getLangOpts(), Results, false); 04475 else 04476 AddObjCTopLevelResults(Results, false); 04477 Results.ExitScope(); 04478 HandleCodeCompleteResults(this, CodeCompleter, 04479 CodeCompletionContext::CCC_Other, 04480 Results.data(),Results.size()); 04481 } 04482 04483 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) { 04484 typedef CodeCompletionResult Result; 04485 CodeCompletionBuilder Builder(Results.getAllocator(), 04486 Results.getCodeCompletionTUInfo()); 04487 04488 // @encode ( type-name ) 04489 const char *EncodeType = "char[]"; 04490 if (Results.getSema().getLangOpts().CPlusPlus || 04491 Results.getSema().getLangOpts().ConstStrings) 04492 EncodeType = "const char[]"; 04493 Builder.AddResultTypeChunk(EncodeType); 04494 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"encode")); 04495 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 04496 Builder.AddPlaceholderChunk("type-name"); 04497 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04498 Results.AddResult(Result(Builder.TakeString())); 04499 04500 // @protocol ( protocol-name ) 04501 Builder.AddResultTypeChunk("Protocol *"); 04502 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol")); 04503 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 04504 Builder.AddPlaceholderChunk("protocol-name"); 04505 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04506 Results.AddResult(Result(Builder.TakeString())); 04507 04508 // @selector ( selector ) 04509 Builder.AddResultTypeChunk("SEL"); 04510 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"selector")); 04511 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 04512 Builder.AddPlaceholderChunk("selector"); 04513 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04514 Results.AddResult(Result(Builder.TakeString())); 04515 04516 // @"string" 04517 Builder.AddResultTypeChunk("NSString *"); 04518 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"\"")); 04519 Builder.AddPlaceholderChunk("string"); 04520 Builder.AddTextChunk("\""); 04521 Results.AddResult(Result(Builder.TakeString())); 04522 04523 // @[objects, ...] 04524 Builder.AddResultTypeChunk("NSArray *"); 04525 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"[")); 04526 Builder.AddPlaceholderChunk("objects, ..."); 04527 Builder.AddChunk(CodeCompletionString::CK_RightBracket); 04528 Results.AddResult(Result(Builder.TakeString())); 04529 04530 // @{key : object, ...} 04531 Builder.AddResultTypeChunk("NSDictionary *"); 04532 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"{")); 04533 Builder.AddPlaceholderChunk("key"); 04534 Builder.AddChunk(CodeCompletionString::CK_Colon); 04535 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04536 Builder.AddPlaceholderChunk("object, ..."); 04537 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 04538 Results.AddResult(Result(Builder.TakeString())); 04539 04540 // @(expression) 04541 Builder.AddResultTypeChunk("id"); 04542 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "(")); 04543 Builder.AddPlaceholderChunk("expression"); 04544 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04545 Results.AddResult(Result(Builder.TakeString())); 04546 } 04547 04548 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) { 04549 typedef CodeCompletionResult Result; 04550 CodeCompletionBuilder Builder(Results.getAllocator(), 04551 Results.getCodeCompletionTUInfo()); 04552 04553 if (Results.includeCodePatterns()) { 04554 // @try { statements } @catch ( declaration ) { statements } @finally 04555 // { statements } 04556 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"try")); 04557 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 04558 Builder.AddPlaceholderChunk("statements"); 04559 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 04560 Builder.AddTextChunk("@catch"); 04561 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 04562 Builder.AddPlaceholderChunk("parameter"); 04563 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04564 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 04565 Builder.AddPlaceholderChunk("statements"); 04566 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 04567 Builder.AddTextChunk("@finally"); 04568 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 04569 Builder.AddPlaceholderChunk("statements"); 04570 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 04571 Results.AddResult(Result(Builder.TakeString())); 04572 } 04573 04574 // @throw 04575 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"throw")); 04576 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04577 Builder.AddPlaceholderChunk("expression"); 04578 Results.AddResult(Result(Builder.TakeString())); 04579 04580 if (Results.includeCodePatterns()) { 04581 // @synchronized ( expression ) { statements } 04582 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synchronized")); 04583 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 04584 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 04585 Builder.AddPlaceholderChunk("expression"); 04586 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04587 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 04588 Builder.AddPlaceholderChunk("statements"); 04589 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 04590 Results.AddResult(Result(Builder.TakeString())); 04591 } 04592 } 04593 04594 static void AddObjCVisibilityResults(const LangOptions &LangOpts, 04595 ResultBuilder &Results, 04596 bool NeedAt) { 04597 typedef CodeCompletionResult Result; 04598 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"private"))); 04599 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"protected"))); 04600 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"public"))); 04601 if (LangOpts.ObjC2) 04602 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"package"))); 04603 } 04604 04605 void Sema::CodeCompleteObjCAtVisibility(Scope *S) { 04606 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04607 CodeCompleter->getCodeCompletionTUInfo(), 04608 CodeCompletionContext::CCC_Other); 04609 Results.EnterNewScope(); 04610 AddObjCVisibilityResults(getLangOpts(), Results, false); 04611 Results.ExitScope(); 04612 HandleCodeCompleteResults(this, CodeCompleter, 04613 CodeCompletionContext::CCC_Other, 04614 Results.data(),Results.size()); 04615 } 04616 04617 void Sema::CodeCompleteObjCAtStatement(Scope *S) { 04618 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04619 CodeCompleter->getCodeCompletionTUInfo(), 04620 CodeCompletionContext::CCC_Other); 04621 Results.EnterNewScope(); 04622 AddObjCStatementResults(Results, false); 04623 AddObjCExpressionResults(Results, false); 04624 Results.ExitScope(); 04625 HandleCodeCompleteResults(this, CodeCompleter, 04626 CodeCompletionContext::CCC_Other, 04627 Results.data(),Results.size()); 04628 } 04629 04630 void Sema::CodeCompleteObjCAtExpression(Scope *S) { 04631 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04632 CodeCompleter->getCodeCompletionTUInfo(), 04633 CodeCompletionContext::CCC_Other); 04634 Results.EnterNewScope(); 04635 AddObjCExpressionResults(Results, false); 04636 Results.ExitScope(); 04637 HandleCodeCompleteResults(this, CodeCompleter, 04638 CodeCompletionContext::CCC_Other, 04639 Results.data(),Results.size()); 04640 } 04641 04642 /// \brief Determine whether the addition of the given flag to an Objective-C 04643 /// property's attributes will cause a conflict. 04644 static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) { 04645 // Check if we've already added this flag. 04646 if (Attributes & NewFlag) 04647 return true; 04648 04649 Attributes |= NewFlag; 04650 04651 // Check for collisions with "readonly". 04652 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 04653 (Attributes & ObjCDeclSpec::DQ_PR_readwrite)) 04654 return true; 04655 04656 // Check for more than one of { assign, copy, retain, strong, weak }. 04657 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign | 04658 ObjCDeclSpec::DQ_PR_unsafe_unretained | 04659 ObjCDeclSpec::DQ_PR_copy | 04660 ObjCDeclSpec::DQ_PR_retain | 04661 ObjCDeclSpec::DQ_PR_strong | 04662 ObjCDeclSpec::DQ_PR_weak); 04663 if (AssignCopyRetMask && 04664 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign && 04665 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained && 04666 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy && 04667 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain && 04668 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong && 04669 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_weak) 04670 return true; 04671 04672 return false; 04673 } 04674 04675 void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { 04676 if (!CodeCompleter) 04677 return; 04678 04679 unsigned Attributes = ODS.getPropertyAttributes(); 04680 04681 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04682 CodeCompleter->getCodeCompletionTUInfo(), 04683 CodeCompletionContext::CCC_Other); 04684 Results.EnterNewScope(); 04685 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly)) 04686 Results.AddResult(CodeCompletionResult("readonly")); 04687 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign)) 04688 Results.AddResult(CodeCompletionResult("assign")); 04689 if (!ObjCPropertyFlagConflicts(Attributes, 04690 ObjCDeclSpec::DQ_PR_unsafe_unretained)) 04691 Results.AddResult(CodeCompletionResult("unsafe_unretained")); 04692 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite)) 04693 Results.AddResult(CodeCompletionResult("readwrite")); 04694 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain)) 04695 Results.AddResult(CodeCompletionResult("retain")); 04696 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_strong)) 04697 Results.AddResult(CodeCompletionResult("strong")); 04698 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy)) 04699 Results.AddResult(CodeCompletionResult("copy")); 04700 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic)) 04701 Results.AddResult(CodeCompletionResult("nonatomic")); 04702 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic)) 04703 Results.AddResult(CodeCompletionResult("atomic")); 04704 04705 // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC. 04706 if (getLangOpts().ObjCARCWeak || getLangOpts().getGC() != LangOptions::NonGC) 04707 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak)) 04708 Results.AddResult(CodeCompletionResult("weak")); 04709 04710 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) { 04711 CodeCompletionBuilder Setter(Results.getAllocator(), 04712 Results.getCodeCompletionTUInfo()); 04713 Setter.AddTypedTextChunk("setter"); 04714 Setter.AddTextChunk("="); 04715 Setter.AddPlaceholderChunk("method"); 04716 Results.AddResult(CodeCompletionResult(Setter.TakeString())); 04717 } 04718 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) { 04719 CodeCompletionBuilder Getter(Results.getAllocator(), 04720 Results.getCodeCompletionTUInfo()); 04721 Getter.AddTypedTextChunk("getter"); 04722 Getter.AddTextChunk("="); 04723 Getter.AddPlaceholderChunk("method"); 04724 Results.AddResult(CodeCompletionResult(Getter.TakeString())); 04725 } 04726 Results.ExitScope(); 04727 HandleCodeCompleteResults(this, CodeCompleter, 04728 CodeCompletionContext::CCC_Other, 04729 Results.data(),Results.size()); 04730 } 04731 04732 /// \brief Describes the kind of Objective-C method that we want to find 04733 /// via code completion. 04734 enum ObjCMethodKind { 04735 MK_Any, ///< Any kind of method, provided it means other specified criteria. 04736 MK_ZeroArgSelector, ///< Zero-argument (unary) selector. 04737 MK_OneArgSelector ///< One-argument selector. 04738 }; 04739 04740 static bool isAcceptableObjCSelector(Selector Sel, 04741 ObjCMethodKind WantKind, 04742 ArrayRef<IdentifierInfo *> SelIdents, 04743 bool AllowSameLength = true) { 04744 unsigned NumSelIdents = SelIdents.size(); 04745 if (NumSelIdents > Sel.getNumArgs()) 04746 return false; 04747 04748 switch (WantKind) { 04749 case MK_Any: break; 04750 case MK_ZeroArgSelector: return Sel.isUnarySelector(); 04751 case MK_OneArgSelector: return Sel.getNumArgs() == 1; 04752 } 04753 04754 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs()) 04755 return false; 04756 04757 for (unsigned I = 0; I != NumSelIdents; ++I) 04758 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I)) 04759 return false; 04760 04761 return true; 04762 } 04763 04764 static bool isAcceptableObjCMethod(ObjCMethodDecl *Method, 04765 ObjCMethodKind WantKind, 04766 ArrayRef<IdentifierInfo *> SelIdents, 04767 bool AllowSameLength = true) { 04768 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents, 04769 AllowSameLength); 04770 } 04771 04772 namespace { 04773 /// \brief A set of selectors, which is used to avoid introducing multiple 04774 /// completions with the same selector into the result set. 04775 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet; 04776 } 04777 04778 /// \brief Add all of the Objective-C methods in the given Objective-C 04779 /// container to the set of results. 04780 /// 04781 /// The container will be a class, protocol, category, or implementation of 04782 /// any of the above. This mether will recurse to include methods from 04783 /// the superclasses of classes along with their categories, protocols, and 04784 /// implementations. 04785 /// 04786 /// \param Container the container in which we'll look to find methods. 04787 /// 04788 /// \param WantInstanceMethods Whether to add instance methods (only); if 04789 /// false, this routine will add factory methods (only). 04790 /// 04791 /// \param CurContext the context in which we're performing the lookup that 04792 /// finds methods. 04793 /// 04794 /// \param AllowSameLength Whether we allow a method to be added to the list 04795 /// when it has the same number of parameters as we have selector identifiers. 04796 /// 04797 /// \param Results the structure into which we'll add results. 04798 static void AddObjCMethods(ObjCContainerDecl *Container, 04799 bool WantInstanceMethods, 04800 ObjCMethodKind WantKind, 04801 ArrayRef<IdentifierInfo *> SelIdents, 04802 DeclContext *CurContext, 04803 VisitedSelectorSet &Selectors, 04804 bool AllowSameLength, 04805 ResultBuilder &Results, 04806 bool InOriginalClass = true) { 04807 typedef CodeCompletionResult Result; 04808 Container = getContainerDef(Container); 04809 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container); 04810 bool isRootClass = IFace && !IFace->getSuperClass(); 04811 for (auto *M : Container->methods()) { 04812 // The instance methods on the root class can be messaged via the 04813 // metaclass. 04814 if (M->isInstanceMethod() == WantInstanceMethods || 04815 (isRootClass && !WantInstanceMethods)) { 04816 // Check whether the selector identifiers we've been given are a 04817 // subset of the identifiers for this particular method. 04818 if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength)) 04819 continue; 04820 04821 if (!Selectors.insert(M->getSelector())) 04822 continue; 04823 04824 Result R = Result(M, Results.getBasePriority(M), nullptr); 04825 R.StartParameter = SelIdents.size(); 04826 R.AllParametersAreInformative = (WantKind != MK_Any); 04827 if (!InOriginalClass) 04828 R.Priority += CCD_InBaseClass; 04829 Results.MaybeAddResult(R, CurContext); 04830 } 04831 } 04832 04833 // Visit the protocols of protocols. 04834 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 04835 if (Protocol->hasDefinition()) { 04836 const ObjCList<ObjCProtocolDecl> &Protocols 04837 = Protocol->getReferencedProtocols(); 04838 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 04839 E = Protocols.end(); 04840 I != E; ++I) 04841 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 04842 CurContext, Selectors, AllowSameLength, Results, false); 04843 } 04844 } 04845 04846 if (!IFace || !IFace->hasDefinition()) 04847 return; 04848 04849 // Add methods in protocols. 04850 for (auto *I : IFace->protocols()) 04851 AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, 04852 CurContext, Selectors, AllowSameLength, Results, false); 04853 04854 // Add methods in categories. 04855 for (auto *CatDecl : IFace->known_categories()) { 04856 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents, 04857 CurContext, Selectors, AllowSameLength, 04858 Results, InOriginalClass); 04859 04860 // Add a categories protocol methods. 04861 const ObjCList<ObjCProtocolDecl> &Protocols 04862 = CatDecl->getReferencedProtocols(); 04863 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 04864 E = Protocols.end(); 04865 I != E; ++I) 04866 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 04867 CurContext, Selectors, AllowSameLength, 04868 Results, false); 04869 04870 // Add methods in category implementations. 04871 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation()) 04872 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 04873 CurContext, Selectors, AllowSameLength, 04874 Results, InOriginalClass); 04875 } 04876 04877 // Add methods in superclass. 04878 if (IFace->getSuperClass()) 04879 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, 04880 SelIdents, CurContext, Selectors, 04881 AllowSameLength, Results, false); 04882 04883 // Add methods in our implementation, if any. 04884 if (ObjCImplementationDecl *Impl = IFace->getImplementation()) 04885 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 04886 CurContext, Selectors, AllowSameLength, 04887 Results, InOriginalClass); 04888 } 04889 04890 04891 void Sema::CodeCompleteObjCPropertyGetter(Scope *S) { 04892 // Try to find the interface where getters might live. 04893 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext); 04894 if (!Class) { 04895 if (ObjCCategoryDecl *Category 04896 = dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) 04897 Class = Category->getClassInterface(); 04898 04899 if (!Class) 04900 return; 04901 } 04902 04903 // Find all of the potential getters. 04904 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04905 CodeCompleter->getCodeCompletionTUInfo(), 04906 CodeCompletionContext::CCC_Other); 04907 Results.EnterNewScope(); 04908 04909 VisitedSelectorSet Selectors; 04910 AddObjCMethods(Class, true, MK_ZeroArgSelector, None, CurContext, Selectors, 04911 /*AllowSameLength=*/true, Results); 04912 Results.ExitScope(); 04913 HandleCodeCompleteResults(this, CodeCompleter, 04914 CodeCompletionContext::CCC_Other, 04915 Results.data(),Results.size()); 04916 } 04917 04918 void Sema::CodeCompleteObjCPropertySetter(Scope *S) { 04919 // Try to find the interface where setters might live. 04920 ObjCInterfaceDecl *Class 04921 = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext); 04922 if (!Class) { 04923 if (ObjCCategoryDecl *Category 04924 = dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) 04925 Class = Category->getClassInterface(); 04926 04927 if (!Class) 04928 return; 04929 } 04930 04931 // Find all of the potential getters. 04932 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04933 CodeCompleter->getCodeCompletionTUInfo(), 04934 CodeCompletionContext::CCC_Other); 04935 Results.EnterNewScope(); 04936 04937 VisitedSelectorSet Selectors; 04938 AddObjCMethods(Class, true, MK_OneArgSelector, None, CurContext, 04939 Selectors, /*AllowSameLength=*/true, Results); 04940 04941 Results.ExitScope(); 04942 HandleCodeCompleteResults(this, CodeCompleter, 04943 CodeCompletionContext::CCC_Other, 04944 Results.data(),Results.size()); 04945 } 04946 04947 void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, 04948 bool IsParameter) { 04949 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 04950 CodeCompleter->getCodeCompletionTUInfo(), 04951 CodeCompletionContext::CCC_Type); 04952 Results.EnterNewScope(); 04953 04954 // Add context-sensitive, Objective-C parameter-passing keywords. 04955 bool AddedInOut = false; 04956 if ((DS.getObjCDeclQualifier() & 04957 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) { 04958 Results.AddResult("in"); 04959 Results.AddResult("inout"); 04960 AddedInOut = true; 04961 } 04962 if ((DS.getObjCDeclQualifier() & 04963 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) { 04964 Results.AddResult("out"); 04965 if (!AddedInOut) 04966 Results.AddResult("inout"); 04967 } 04968 if ((DS.getObjCDeclQualifier() & 04969 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref | 04970 ObjCDeclSpec::DQ_Oneway)) == 0) { 04971 Results.AddResult("bycopy"); 04972 Results.AddResult("byref"); 04973 Results.AddResult("oneway"); 04974 } 04975 04976 // If we're completing the return type of an Objective-C method and the 04977 // identifier IBAction refers to a macro, provide a completion item for 04978 // an action, e.g., 04979 // IBAction)<#selector#>:(id)sender 04980 if (DS.getObjCDeclQualifier() == 0 && !IsParameter && 04981 Context.Idents.get("IBAction").hasMacroDefinition()) { 04982 CodeCompletionBuilder Builder(Results.getAllocator(), 04983 Results.getCodeCompletionTUInfo(), 04984 CCP_CodePattern, CXAvailability_Available); 04985 Builder.AddTypedTextChunk("IBAction"); 04986 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04987 Builder.AddPlaceholderChunk("selector"); 04988 Builder.AddChunk(CodeCompletionString::CK_Colon); 04989 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 04990 Builder.AddTextChunk("id"); 04991 Builder.AddChunk(CodeCompletionString::CK_RightParen); 04992 Builder.AddTextChunk("sender"); 04993 Results.AddResult(CodeCompletionResult(Builder.TakeString())); 04994 } 04995 04996 // If we're completing the return type, provide 'instancetype'. 04997 if (!IsParameter) { 04998 Results.AddResult(CodeCompletionResult("instancetype")); 04999 } 05000 05001 // Add various builtin type names and specifiers. 05002 AddOrdinaryNameResults(PCC_Type, S, *this, Results); 05003 Results.ExitScope(); 05004 05005 // Add the various type names 05006 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName); 05007 CodeCompletionDeclConsumer Consumer(Results, CurContext); 05008 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 05009 CodeCompleter->includeGlobals()); 05010 05011 if (CodeCompleter->includeMacros()) 05012 AddMacroResults(PP, Results, false); 05013 05014 HandleCodeCompleteResults(this, CodeCompleter, 05015 CodeCompletionContext::CCC_Type, 05016 Results.data(), Results.size()); 05017 } 05018 05019 /// \brief When we have an expression with type "id", we may assume 05020 /// that it has some more-specific class type based on knowledge of 05021 /// common uses of Objective-C. This routine returns that class type, 05022 /// or NULL if no better result could be determined. 05023 static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) { 05024 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E); 05025 if (!Msg) 05026 return nullptr; 05027 05028 Selector Sel = Msg->getSelector(); 05029 if (Sel.isNull()) 05030 return nullptr; 05031 05032 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0); 05033 if (!Id) 05034 return nullptr; 05035 05036 ObjCMethodDecl *Method = Msg->getMethodDecl(); 05037 if (!Method) 05038 return nullptr; 05039 05040 // Determine the class that we're sending the message to. 05041 ObjCInterfaceDecl *IFace = nullptr; 05042 switch (Msg->getReceiverKind()) { 05043 case ObjCMessageExpr::Class: 05044 if (const ObjCObjectType *ObjType 05045 = Msg->getClassReceiver()->getAs<ObjCObjectType>()) 05046 IFace = ObjType->getInterface(); 05047 break; 05048 05049 case ObjCMessageExpr::Instance: { 05050 QualType T = Msg->getInstanceReceiver()->getType(); 05051 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>()) 05052 IFace = Ptr->getInterfaceDecl(); 05053 break; 05054 } 05055 05056 case ObjCMessageExpr::SuperInstance: 05057 case ObjCMessageExpr::SuperClass: 05058 break; 05059 } 05060 05061 if (!IFace) 05062 return nullptr; 05063 05064 ObjCInterfaceDecl *Super = IFace->getSuperClass(); 05065 if (Method->isInstanceMethod()) 05066 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName()) 05067 .Case("retain", IFace) 05068 .Case("strong", IFace) 05069 .Case("autorelease", IFace) 05070 .Case("copy", IFace) 05071 .Case("copyWithZone", IFace) 05072 .Case("mutableCopy", IFace) 05073 .Case("mutableCopyWithZone", IFace) 05074 .Case("awakeFromCoder", IFace) 05075 .Case("replacementObjectFromCoder", IFace) 05076 .Case("class", IFace) 05077 .Case("classForCoder", IFace) 05078 .Case("superclass", Super) 05079 .Default(nullptr); 05080 05081 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName()) 05082 .Case("new", IFace) 05083 .Case("alloc", IFace) 05084 .Case("allocWithZone", IFace) 05085 .Case("class", IFace) 05086 .Case("superclass", Super) 05087 .Default(nullptr); 05088 } 05089 05090 // Add a special completion for a message send to "super", which fills in the 05091 // most likely case of forwarding all of our arguments to the superclass 05092 // function. 05093 /// 05094 /// \param S The semantic analysis object. 05095 /// 05096 /// \param NeedSuperKeyword Whether we need to prefix this completion with 05097 /// the "super" keyword. Otherwise, we just need to provide the arguments. 05098 /// 05099 /// \param SelIdents The identifiers in the selector that have already been 05100 /// provided as arguments for a send to "super". 05101 /// 05102 /// \param Results The set of results to augment. 05103 /// 05104 /// \returns the Objective-C method declaration that would be invoked by 05105 /// this "super" completion. If NULL, no completion was added. 05106 static ObjCMethodDecl *AddSuperSendCompletion( 05107 Sema &S, bool NeedSuperKeyword, 05108 ArrayRef<IdentifierInfo *> SelIdents, 05109 ResultBuilder &Results) { 05110 ObjCMethodDecl *CurMethod = S.getCurMethodDecl(); 05111 if (!CurMethod) 05112 return nullptr; 05113 05114 ObjCInterfaceDecl *Class = CurMethod->getClassInterface(); 05115 if (!Class) 05116 return nullptr; 05117 05118 // Try to find a superclass method with the same selector. 05119 ObjCMethodDecl *SuperMethod = nullptr; 05120 while ((Class = Class->getSuperClass()) && !SuperMethod) { 05121 // Check in the class 05122 SuperMethod = Class->getMethod(CurMethod->getSelector(), 05123 CurMethod->isInstanceMethod()); 05124 05125 // Check in categories or class extensions. 05126 if (!SuperMethod) { 05127 for (const auto *Cat : Class->known_categories()) { 05128 if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(), 05129 CurMethod->isInstanceMethod()))) 05130 break; 05131 } 05132 } 05133 } 05134 05135 if (!SuperMethod) 05136 return nullptr; 05137 05138 // Check whether the superclass method has the same signature. 05139 if (CurMethod->param_size() != SuperMethod->param_size() || 05140 CurMethod->isVariadic() != SuperMethod->isVariadic()) 05141 return nullptr; 05142 05143 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(), 05144 CurPEnd = CurMethod->param_end(), 05145 SuperP = SuperMethod->param_begin(); 05146 CurP != CurPEnd; ++CurP, ++SuperP) { 05147 // Make sure the parameter types are compatible. 05148 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(), 05149 (*SuperP)->getType())) 05150 return nullptr; 05151 05152 // Make sure we have a parameter name to forward! 05153 if (!(*CurP)->getIdentifier()) 05154 return nullptr; 05155 } 05156 05157 // We have a superclass method. Now, form the send-to-super completion. 05158 CodeCompletionBuilder Builder(Results.getAllocator(), 05159 Results.getCodeCompletionTUInfo()); 05160 05161 // Give this completion a return type. 05162 AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod, 05163 Builder); 05164 05165 // If we need the "super" keyword, add it (plus some spacing). 05166 if (NeedSuperKeyword) { 05167 Builder.AddTypedTextChunk("super"); 05168 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 05169 } 05170 05171 Selector Sel = CurMethod->getSelector(); 05172 if (Sel.isUnarySelector()) { 05173 if (NeedSuperKeyword) 05174 Builder.AddTextChunk(Builder.getAllocator().CopyString( 05175 Sel.getNameForSlot(0))); 05176 else 05177 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 05178 Sel.getNameForSlot(0))); 05179 } else { 05180 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(); 05181 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) { 05182 if (I > SelIdents.size()) 05183 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 05184 05185 if (I < SelIdents.size()) 05186 Builder.AddInformativeChunk( 05187 Builder.getAllocator().CopyString( 05188 Sel.getNameForSlot(I) + ":")); 05189 else if (NeedSuperKeyword || I > SelIdents.size()) { 05190 Builder.AddTextChunk( 05191 Builder.getAllocator().CopyString( 05192 Sel.getNameForSlot(I) + ":")); 05193 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString( 05194 (*CurP)->getIdentifier()->getName())); 05195 } else { 05196 Builder.AddTypedTextChunk( 05197 Builder.getAllocator().CopyString( 05198 Sel.getNameForSlot(I) + ":")); 05199 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString( 05200 (*CurP)->getIdentifier()->getName())); 05201 } 05202 } 05203 } 05204 05205 Results.AddResult(CodeCompletionResult(Builder.TakeString(), SuperMethod, 05206 CCP_SuperCompletion)); 05207 return SuperMethod; 05208 } 05209 05210 void Sema::CodeCompleteObjCMessageReceiver(Scope *S) { 05211 typedef CodeCompletionResult Result; 05212 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05213 CodeCompleter->getCodeCompletionTUInfo(), 05214 CodeCompletionContext::CCC_ObjCMessageReceiver, 05215 getLangOpts().CPlusPlus11 05216 ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture 05217 : &ResultBuilder::IsObjCMessageReceiver); 05218 05219 CodeCompletionDeclConsumer Consumer(Results, CurContext); 05220 Results.EnterNewScope(); 05221 LookupVisibleDecls(S, LookupOrdinaryName, Consumer, 05222 CodeCompleter->includeGlobals()); 05223 05224 // If we are in an Objective-C method inside a class that has a superclass, 05225 // add "super" as an option. 05226 if (ObjCMethodDecl *Method = getCurMethodDecl()) 05227 if (ObjCInterfaceDecl *Iface = Method->getClassInterface()) 05228 if (Iface->getSuperClass()) { 05229 Results.AddResult(Result("super")); 05230 05231 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, None, Results); 05232 } 05233 05234 if (getLangOpts().CPlusPlus11) 05235 addThisCompletion(*this, Results); 05236 05237 Results.ExitScope(); 05238 05239 if (CodeCompleter->includeMacros()) 05240 AddMacroResults(PP, Results, false); 05241 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 05242 Results.data(), Results.size()); 05243 05244 } 05245 05246 void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, 05247 ArrayRef<IdentifierInfo *> SelIdents, 05248 bool AtArgumentExpression) { 05249 ObjCInterfaceDecl *CDecl = nullptr; 05250 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) { 05251 // Figure out which interface we're in. 05252 CDecl = CurMethod->getClassInterface(); 05253 if (!CDecl) 05254 return; 05255 05256 // Find the superclass of this class. 05257 CDecl = CDecl->getSuperClass(); 05258 if (!CDecl) 05259 return; 05260 05261 if (CurMethod->isInstanceMethod()) { 05262 // We are inside an instance method, which means that the message 05263 // send [super ...] is actually calling an instance method on the 05264 // current object. 05265 return CodeCompleteObjCInstanceMessage(S, nullptr, SelIdents, 05266 AtArgumentExpression, 05267 CDecl); 05268 } 05269 05270 // Fall through to send to the superclass in CDecl. 05271 } else { 05272 // "super" may be the name of a type or variable. Figure out which 05273 // it is. 05274 IdentifierInfo *Super = getSuperIdentifier(); 05275 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc, 05276 LookupOrdinaryName); 05277 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) { 05278 // "super" names an interface. Use it. 05279 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) { 05280 if (const ObjCObjectType *Iface 05281 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>()) 05282 CDecl = Iface->getInterface(); 05283 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) { 05284 // "super" names an unresolved type; we can't be more specific. 05285 } else { 05286 // Assume that "super" names some kind of value and parse that way. 05287 CXXScopeSpec SS; 05288 SourceLocation TemplateKWLoc; 05289 UnqualifiedId id; 05290 id.setIdentifier(Super, SuperLoc); 05291 ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id, 05292 false, false); 05293 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(), 05294 SelIdents, 05295 AtArgumentExpression); 05296 } 05297 05298 // Fall through 05299 } 05300 05301 ParsedType Receiver; 05302 if (CDecl) 05303 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl)); 05304 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents, 05305 AtArgumentExpression, 05306 /*IsSuper=*/true); 05307 } 05308 05309 /// \brief Given a set of code-completion results for the argument of a message 05310 /// send, determine the preferred type (if any) for that argument expression. 05311 static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results, 05312 unsigned NumSelIdents) { 05313 typedef CodeCompletionResult Result; 05314 ASTContext &Context = Results.getSema().Context; 05315 05316 QualType PreferredType; 05317 unsigned BestPriority = CCP_Unlikely * 2; 05318 Result *ResultsData = Results.data(); 05319 for (unsigned I = 0, N = Results.size(); I != N; ++I) { 05320 Result &R = ResultsData[I]; 05321 if (R.Kind == Result::RK_Declaration && 05322 isa<ObjCMethodDecl>(R.Declaration)) { 05323 if (R.Priority <= BestPriority) { 05324 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration); 05325 if (NumSelIdents <= Method->param_size()) { 05326 QualType MyPreferredType = Method->parameters()[NumSelIdents - 1] 05327 ->getType(); 05328 if (R.Priority < BestPriority || PreferredType.isNull()) { 05329 BestPriority = R.Priority; 05330 PreferredType = MyPreferredType; 05331 } else if (!Context.hasSameUnqualifiedType(PreferredType, 05332 MyPreferredType)) { 05333 PreferredType = QualType(); 05334 } 05335 } 05336 } 05337 } 05338 } 05339 05340 return PreferredType; 05341 } 05342 05343 static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, 05344 ParsedType Receiver, 05345 ArrayRef<IdentifierInfo *> SelIdents, 05346 bool AtArgumentExpression, 05347 bool IsSuper, 05348 ResultBuilder &Results) { 05349 typedef CodeCompletionResult Result; 05350 ObjCInterfaceDecl *CDecl = nullptr; 05351 05352 // If the given name refers to an interface type, retrieve the 05353 // corresponding declaration. 05354 if (Receiver) { 05355 QualType T = SemaRef.GetTypeFromParser(Receiver, nullptr); 05356 if (!T.isNull()) 05357 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>()) 05358 CDecl = Interface->getInterface(); 05359 } 05360 05361 // Add all of the factory methods in this Objective-C class, its protocols, 05362 // superclasses, categories, implementation, etc. 05363 Results.EnterNewScope(); 05364 05365 // If this is a send-to-super, try to add the special "super" send 05366 // completion. 05367 if (IsSuper) { 05368 if (ObjCMethodDecl *SuperMethod 05369 = AddSuperSendCompletion(SemaRef, false, SelIdents, Results)) 05370 Results.Ignore(SuperMethod); 05371 } 05372 05373 // If we're inside an Objective-C method definition, prefer its selector to 05374 // others. 05375 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl()) 05376 Results.setPreferredSelector(CurMethod->getSelector()); 05377 05378 VisitedSelectorSet Selectors; 05379 if (CDecl) 05380 AddObjCMethods(CDecl, false, MK_Any, SelIdents, 05381 SemaRef.CurContext, Selectors, AtArgumentExpression, 05382 Results); 05383 else { 05384 // We're messaging "id" as a type; provide all class/factory methods. 05385 05386 // If we have an external source, load the entire class method 05387 // pool from the AST file. 05388 if (SemaRef.getExternalSource()) { 05389 for (uint32_t I = 0, 05390 N = SemaRef.getExternalSource()->GetNumExternalSelectors(); 05391 I != N; ++I) { 05392 Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I); 05393 if (Sel.isNull() || SemaRef.MethodPool.count(Sel)) 05394 continue; 05395 05396 SemaRef.ReadMethodPool(Sel); 05397 } 05398 } 05399 05400 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(), 05401 MEnd = SemaRef.MethodPool.end(); 05402 M != MEnd; ++M) { 05403 for (ObjCMethodList *MethList = &M->second.second; 05404 MethList && MethList->Method; 05405 MethList = MethList->getNext()) { 05406 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents)) 05407 continue; 05408 05409 Result R(MethList->Method, Results.getBasePriority(MethList->Method), 05410 nullptr); 05411 R.StartParameter = SelIdents.size(); 05412 R.AllParametersAreInformative = false; 05413 Results.MaybeAddResult(R, SemaRef.CurContext); 05414 } 05415 } 05416 } 05417 05418 Results.ExitScope(); 05419 } 05420 05421 void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, 05422 ArrayRef<IdentifierInfo *> SelIdents, 05423 bool AtArgumentExpression, 05424 bool IsSuper) { 05425 05426 QualType T = this->GetTypeFromParser(Receiver); 05427 05428 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05429 CodeCompleter->getCodeCompletionTUInfo(), 05430 CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage, 05431 T, SelIdents)); 05432 05433 AddClassMessageCompletions(*this, S, Receiver, SelIdents, 05434 AtArgumentExpression, IsSuper, Results); 05435 05436 // If we're actually at the argument expression (rather than prior to the 05437 // selector), we're actually performing code completion for an expression. 05438 // Determine whether we have a single, best method. If so, we can 05439 // code-complete the expression using the corresponding parameter type as 05440 // our preferred type, improving completion results. 05441 if (AtArgumentExpression) { 05442 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results, 05443 SelIdents.size()); 05444 if (PreferredType.isNull()) 05445 CodeCompleteOrdinaryName(S, PCC_Expression); 05446 else 05447 CodeCompleteExpression(S, PreferredType); 05448 return; 05449 } 05450 05451 HandleCodeCompleteResults(this, CodeCompleter, 05452 Results.getCompletionContext(), 05453 Results.data(), Results.size()); 05454 } 05455 05456 void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, 05457 ArrayRef<IdentifierInfo *> SelIdents, 05458 bool AtArgumentExpression, 05459 ObjCInterfaceDecl *Super) { 05460 typedef CodeCompletionResult Result; 05461 05462 Expr *RecExpr = static_cast<Expr *>(Receiver); 05463 05464 // If necessary, apply function/array conversion to the receiver. 05465 // C99 6.7.5.3p[7,8]. 05466 if (RecExpr) { 05467 ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr); 05468 if (Conv.isInvalid()) // conversion failed. bail. 05469 return; 05470 RecExpr = Conv.get(); 05471 } 05472 QualType ReceiverType = RecExpr? RecExpr->getType() 05473 : Super? Context.getObjCObjectPointerType( 05474 Context.getObjCInterfaceType(Super)) 05475 : Context.getObjCIdType(); 05476 05477 // If we're messaging an expression with type "id" or "Class", check 05478 // whether we know something special about the receiver that allows 05479 // us to assume a more-specific receiver type. 05480 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) { 05481 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) { 05482 if (ReceiverType->isObjCClassType()) 05483 return CodeCompleteObjCClassMessage(S, 05484 ParsedType::make(Context.getObjCInterfaceType(IFace)), 05485 SelIdents, 05486 AtArgumentExpression, Super); 05487 05488 ReceiverType = Context.getObjCObjectPointerType( 05489 Context.getObjCInterfaceType(IFace)); 05490 } 05491 } else if (RecExpr && getLangOpts().CPlusPlus) { 05492 ExprResult Conv = PerformContextuallyConvertToObjCPointer(RecExpr); 05493 if (Conv.isUsable()) { 05494 RecExpr = Conv.get(); 05495 ReceiverType = RecExpr->getType(); 05496 } 05497 } 05498 05499 // Build the set of methods we can see. 05500 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05501 CodeCompleter->getCodeCompletionTUInfo(), 05502 CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage, 05503 ReceiverType, SelIdents)); 05504 05505 Results.EnterNewScope(); 05506 05507 // If this is a send-to-super, try to add the special "super" send 05508 // completion. 05509 if (Super) { 05510 if (ObjCMethodDecl *SuperMethod 05511 = AddSuperSendCompletion(*this, false, SelIdents, Results)) 05512 Results.Ignore(SuperMethod); 05513 } 05514 05515 // If we're inside an Objective-C method definition, prefer its selector to 05516 // others. 05517 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) 05518 Results.setPreferredSelector(CurMethod->getSelector()); 05519 05520 // Keep track of the selectors we've already added. 05521 VisitedSelectorSet Selectors; 05522 05523 // Handle messages to Class. This really isn't a message to an instance 05524 // method, so we treat it the same way we would treat a message send to a 05525 // class method. 05526 if (ReceiverType->isObjCClassType() || 05527 ReceiverType->isObjCQualifiedClassType()) { 05528 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) { 05529 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface()) 05530 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, 05531 CurContext, Selectors, AtArgumentExpression, Results); 05532 } 05533 } 05534 // Handle messages to a qualified ID ("id<foo>"). 05535 else if (const ObjCObjectPointerType *QualID 05536 = ReceiverType->getAsObjCQualifiedIdType()) { 05537 // Search protocols for instance methods. 05538 for (auto *I : QualID->quals()) 05539 AddObjCMethods(I, true, MK_Any, SelIdents, CurContext, 05540 Selectors, AtArgumentExpression, Results); 05541 } 05542 // Handle messages to a pointer to interface type. 05543 else if (const ObjCObjectPointerType *IFacePtr 05544 = ReceiverType->getAsObjCInterfacePointerType()) { 05545 // Search the class, its superclasses, etc., for instance methods. 05546 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents, 05547 CurContext, Selectors, AtArgumentExpression, 05548 Results); 05549 05550 // Search protocols for instance methods. 05551 for (auto *I : IFacePtr->quals()) 05552 AddObjCMethods(I, true, MK_Any, SelIdents, CurContext, 05553 Selectors, AtArgumentExpression, Results); 05554 } 05555 // Handle messages to "id". 05556 else if (ReceiverType->isObjCIdType()) { 05557 // We're messaging "id", so provide all instance methods we know 05558 // about as code-completion results. 05559 05560 // If we have an external source, load the entire class method 05561 // pool from the AST file. 05562 if (ExternalSource) { 05563 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); 05564 I != N; ++I) { 05565 Selector Sel = ExternalSource->GetExternalSelector(I); 05566 if (Sel.isNull() || MethodPool.count(Sel)) 05567 continue; 05568 05569 ReadMethodPool(Sel); 05570 } 05571 } 05572 05573 for (GlobalMethodPool::iterator M = MethodPool.begin(), 05574 MEnd = MethodPool.end(); 05575 M != MEnd; ++M) { 05576 for (ObjCMethodList *MethList = &M->second.first; 05577 MethList && MethList->Method; 05578 MethList = MethList->getNext()) { 05579 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents)) 05580 continue; 05581 05582 if (!Selectors.insert(MethList->Method->getSelector())) 05583 continue; 05584 05585 Result R(MethList->Method, Results.getBasePriority(MethList->Method), 05586 nullptr); 05587 R.StartParameter = SelIdents.size(); 05588 R.AllParametersAreInformative = false; 05589 Results.MaybeAddResult(R, CurContext); 05590 } 05591 } 05592 } 05593 Results.ExitScope(); 05594 05595 05596 // If we're actually at the argument expression (rather than prior to the 05597 // selector), we're actually performing code completion for an expression. 05598 // Determine whether we have a single, best method. If so, we can 05599 // code-complete the expression using the corresponding parameter type as 05600 // our preferred type, improving completion results. 05601 if (AtArgumentExpression) { 05602 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results, 05603 SelIdents.size()); 05604 if (PreferredType.isNull()) 05605 CodeCompleteOrdinaryName(S, PCC_Expression); 05606 else 05607 CodeCompleteExpression(S, PreferredType); 05608 return; 05609 } 05610 05611 HandleCodeCompleteResults(this, CodeCompleter, 05612 Results.getCompletionContext(), 05613 Results.data(),Results.size()); 05614 } 05615 05616 void Sema::CodeCompleteObjCForCollection(Scope *S, 05617 DeclGroupPtrTy IterationVar) { 05618 CodeCompleteExpressionData Data; 05619 Data.ObjCCollection = true; 05620 05621 if (IterationVar.getAsOpaquePtr()) { 05622 DeclGroupRef DG = IterationVar.get(); 05623 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) { 05624 if (*I) 05625 Data.IgnoreDecls.push_back(*I); 05626 } 05627 } 05628 05629 CodeCompleteExpression(S, Data); 05630 } 05631 05632 void Sema::CodeCompleteObjCSelector(Scope *S, 05633 ArrayRef<IdentifierInfo *> SelIdents) { 05634 // If we have an external source, load the entire class method 05635 // pool from the AST file. 05636 if (ExternalSource) { 05637 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); 05638 I != N; ++I) { 05639 Selector Sel = ExternalSource->GetExternalSelector(I); 05640 if (Sel.isNull() || MethodPool.count(Sel)) 05641 continue; 05642 05643 ReadMethodPool(Sel); 05644 } 05645 } 05646 05647 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05648 CodeCompleter->getCodeCompletionTUInfo(), 05649 CodeCompletionContext::CCC_SelectorName); 05650 Results.EnterNewScope(); 05651 for (GlobalMethodPool::iterator M = MethodPool.begin(), 05652 MEnd = MethodPool.end(); 05653 M != MEnd; ++M) { 05654 05655 Selector Sel = M->first; 05656 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents)) 05657 continue; 05658 05659 CodeCompletionBuilder Builder(Results.getAllocator(), 05660 Results.getCodeCompletionTUInfo()); 05661 if (Sel.isUnarySelector()) { 05662 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 05663 Sel.getNameForSlot(0))); 05664 Results.AddResult(Builder.TakeString()); 05665 continue; 05666 } 05667 05668 std::string Accumulator; 05669 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) { 05670 if (I == SelIdents.size()) { 05671 if (!Accumulator.empty()) { 05672 Builder.AddInformativeChunk(Builder.getAllocator().CopyString( 05673 Accumulator)); 05674 Accumulator.clear(); 05675 } 05676 } 05677 05678 Accumulator += Sel.getNameForSlot(I); 05679 Accumulator += ':'; 05680 } 05681 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( Accumulator)); 05682 Results.AddResult(Builder.TakeString()); 05683 } 05684 Results.ExitScope(); 05685 05686 HandleCodeCompleteResults(this, CodeCompleter, 05687 CodeCompletionContext::CCC_SelectorName, 05688 Results.data(), Results.size()); 05689 } 05690 05691 /// \brief Add all of the protocol declarations that we find in the given 05692 /// (translation unit) context. 05693 static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext, 05694 bool OnlyForwardDeclarations, 05695 ResultBuilder &Results) { 05696 typedef CodeCompletionResult Result; 05697 05698 for (const auto *D : Ctx->decls()) { 05699 // Record any protocols we find. 05700 if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(D)) 05701 if (!OnlyForwardDeclarations || !Proto->hasDefinition()) 05702 Results.AddResult(Result(Proto, Results.getBasePriority(Proto),nullptr), 05703 CurContext, nullptr, false); 05704 } 05705 } 05706 05707 void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols, 05708 unsigned NumProtocols) { 05709 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05710 CodeCompleter->getCodeCompletionTUInfo(), 05711 CodeCompletionContext::CCC_ObjCProtocolName); 05712 05713 if (CodeCompleter && CodeCompleter->includeGlobals()) { 05714 Results.EnterNewScope(); 05715 05716 // Tell the result set to ignore all of the protocols we have 05717 // already seen. 05718 // FIXME: This doesn't work when caching code-completion results. 05719 for (unsigned I = 0; I != NumProtocols; ++I) 05720 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first, 05721 Protocols[I].second)) 05722 Results.Ignore(Protocol); 05723 05724 // Add all protocols. 05725 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false, 05726 Results); 05727 05728 Results.ExitScope(); 05729 } 05730 05731 HandleCodeCompleteResults(this, CodeCompleter, 05732 CodeCompletionContext::CCC_ObjCProtocolName, 05733 Results.data(),Results.size()); 05734 } 05735 05736 void Sema::CodeCompleteObjCProtocolDecl(Scope *) { 05737 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05738 CodeCompleter->getCodeCompletionTUInfo(), 05739 CodeCompletionContext::CCC_ObjCProtocolName); 05740 05741 if (CodeCompleter && CodeCompleter->includeGlobals()) { 05742 Results.EnterNewScope(); 05743 05744 // Add all protocols. 05745 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true, 05746 Results); 05747 05748 Results.ExitScope(); 05749 } 05750 05751 HandleCodeCompleteResults(this, CodeCompleter, 05752 CodeCompletionContext::CCC_ObjCProtocolName, 05753 Results.data(),Results.size()); 05754 } 05755 05756 /// \brief Add all of the Objective-C interface declarations that we find in 05757 /// the given (translation unit) context. 05758 static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext, 05759 bool OnlyForwardDeclarations, 05760 bool OnlyUnimplemented, 05761 ResultBuilder &Results) { 05762 typedef CodeCompletionResult Result; 05763 05764 for (const auto *D : Ctx->decls()) { 05765 // Record any interfaces we find. 05766 if (const auto *Class = dyn_cast<ObjCInterfaceDecl>(D)) 05767 if ((!OnlyForwardDeclarations || !Class->hasDefinition()) && 05768 (!OnlyUnimplemented || !Class->getImplementation())) 05769 Results.AddResult(Result(Class, Results.getBasePriority(Class),nullptr), 05770 CurContext, nullptr, false); 05771 } 05772 } 05773 05774 void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) { 05775 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05776 CodeCompleter->getCodeCompletionTUInfo(), 05777 CodeCompletionContext::CCC_Other); 05778 Results.EnterNewScope(); 05779 05780 if (CodeCompleter->includeGlobals()) { 05781 // Add all classes. 05782 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false, 05783 false, Results); 05784 } 05785 05786 Results.ExitScope(); 05787 05788 HandleCodeCompleteResults(this, CodeCompleter, 05789 CodeCompletionContext::CCC_ObjCInterfaceName, 05790 Results.data(),Results.size()); 05791 } 05792 05793 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, 05794 SourceLocation ClassNameLoc) { 05795 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05796 CodeCompleter->getCodeCompletionTUInfo(), 05797 CodeCompletionContext::CCC_ObjCInterfaceName); 05798 Results.EnterNewScope(); 05799 05800 // Make sure that we ignore the class we're currently defining. 05801 NamedDecl *CurClass 05802 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); 05803 if (CurClass && isa<ObjCInterfaceDecl>(CurClass)) 05804 Results.Ignore(CurClass); 05805 05806 if (CodeCompleter->includeGlobals()) { 05807 // Add all classes. 05808 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false, 05809 false, Results); 05810 } 05811 05812 Results.ExitScope(); 05813 05814 HandleCodeCompleteResults(this, CodeCompleter, 05815 CodeCompletionContext::CCC_ObjCInterfaceName, 05816 Results.data(),Results.size()); 05817 } 05818 05819 void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { 05820 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05821 CodeCompleter->getCodeCompletionTUInfo(), 05822 CodeCompletionContext::CCC_Other); 05823 Results.EnterNewScope(); 05824 05825 if (CodeCompleter->includeGlobals()) { 05826 // Add all unimplemented classes. 05827 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false, 05828 true, Results); 05829 } 05830 05831 Results.ExitScope(); 05832 05833 HandleCodeCompleteResults(this, CodeCompleter, 05834 CodeCompletionContext::CCC_ObjCInterfaceName, 05835 Results.data(),Results.size()); 05836 } 05837 05838 void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, 05839 IdentifierInfo *ClassName, 05840 SourceLocation ClassNameLoc) { 05841 typedef CodeCompletionResult Result; 05842 05843 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05844 CodeCompleter->getCodeCompletionTUInfo(), 05845 CodeCompletionContext::CCC_ObjCCategoryName); 05846 05847 // Ignore any categories we find that have already been implemented by this 05848 // interface. 05849 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames; 05850 NamedDecl *CurClass 05851 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); 05852 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)){ 05853 for (const auto *Cat : Class->visible_categories()) 05854 CategoryNames.insert(Cat->getIdentifier()); 05855 } 05856 05857 // Add all of the categories we know about. 05858 Results.EnterNewScope(); 05859 TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); 05860 for (const auto *D : TU->decls()) 05861 if (const auto *Category = dyn_cast<ObjCCategoryDecl>(D)) 05862 if (CategoryNames.insert(Category->getIdentifier())) 05863 Results.AddResult(Result(Category, Results.getBasePriority(Category), 05864 nullptr), 05865 CurContext, nullptr, false); 05866 Results.ExitScope(); 05867 05868 HandleCodeCompleteResults(this, CodeCompleter, 05869 CodeCompletionContext::CCC_ObjCCategoryName, 05870 Results.data(),Results.size()); 05871 } 05872 05873 void Sema::CodeCompleteObjCImplementationCategory(Scope *S, 05874 IdentifierInfo *ClassName, 05875 SourceLocation ClassNameLoc) { 05876 typedef CodeCompletionResult Result; 05877 05878 // Find the corresponding interface. If we couldn't find the interface, the 05879 // program itself is ill-formed. However, we'll try to be helpful still by 05880 // providing the list of all of the categories we know about. 05881 NamedDecl *CurClass 05882 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); 05883 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass); 05884 if (!Class) 05885 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc); 05886 05887 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05888 CodeCompleter->getCodeCompletionTUInfo(), 05889 CodeCompletionContext::CCC_ObjCCategoryName); 05890 05891 // Add all of the categories that have have corresponding interface 05892 // declarations in this class and any of its superclasses, except for 05893 // already-implemented categories in the class itself. 05894 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames; 05895 Results.EnterNewScope(); 05896 bool IgnoreImplemented = true; 05897 while (Class) { 05898 for (const auto *Cat : Class->visible_categories()) { 05899 if ((!IgnoreImplemented || !Cat->getImplementation()) && 05900 CategoryNames.insert(Cat->getIdentifier())) 05901 Results.AddResult(Result(Cat, Results.getBasePriority(Cat), nullptr), 05902 CurContext, nullptr, false); 05903 } 05904 05905 Class = Class->getSuperClass(); 05906 IgnoreImplemented = false; 05907 } 05908 Results.ExitScope(); 05909 05910 HandleCodeCompleteResults(this, CodeCompleter, 05911 CodeCompletionContext::CCC_ObjCCategoryName, 05912 Results.data(),Results.size()); 05913 } 05914 05915 void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) { 05916 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05917 CodeCompleter->getCodeCompletionTUInfo(), 05918 CodeCompletionContext::CCC_Other); 05919 05920 // Figure out where this @synthesize lives. 05921 ObjCContainerDecl *Container 05922 = dyn_cast_or_null<ObjCContainerDecl>(CurContext); 05923 if (!Container || 05924 (!isa<ObjCImplementationDecl>(Container) && 05925 !isa<ObjCCategoryImplDecl>(Container))) 05926 return; 05927 05928 // Ignore any properties that have already been implemented. 05929 Container = getContainerDef(Container); 05930 for (const auto *D : Container->decls()) 05931 if (const auto *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(D)) 05932 Results.Ignore(PropertyImpl->getPropertyDecl()); 05933 05934 // Add any properties that we find. 05935 AddedPropertiesSet AddedProperties; 05936 Results.EnterNewScope(); 05937 if (ObjCImplementationDecl *ClassImpl 05938 = dyn_cast<ObjCImplementationDecl>(Container)) 05939 AddObjCProperties(ClassImpl->getClassInterface(), false, 05940 /*AllowNullaryMethods=*/false, CurContext, 05941 AddedProperties, Results); 05942 else 05943 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(), 05944 false, /*AllowNullaryMethods=*/false, CurContext, 05945 AddedProperties, Results); 05946 Results.ExitScope(); 05947 05948 HandleCodeCompleteResults(this, CodeCompleter, 05949 CodeCompletionContext::CCC_Other, 05950 Results.data(),Results.size()); 05951 } 05952 05953 void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 05954 IdentifierInfo *PropertyName) { 05955 typedef CodeCompletionResult Result; 05956 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 05957 CodeCompleter->getCodeCompletionTUInfo(), 05958 CodeCompletionContext::CCC_Other); 05959 05960 // Figure out where this @synthesize lives. 05961 ObjCContainerDecl *Container 05962 = dyn_cast_or_null<ObjCContainerDecl>(CurContext); 05963 if (!Container || 05964 (!isa<ObjCImplementationDecl>(Container) && 05965 !isa<ObjCCategoryImplDecl>(Container))) 05966 return; 05967 05968 // Figure out which interface we're looking into. 05969 ObjCInterfaceDecl *Class = nullptr; 05970 if (ObjCImplementationDecl *ClassImpl 05971 = dyn_cast<ObjCImplementationDecl>(Container)) 05972 Class = ClassImpl->getClassInterface(); 05973 else 05974 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl() 05975 ->getClassInterface(); 05976 05977 // Determine the type of the property we're synthesizing. 05978 QualType PropertyType = Context.getObjCIdType(); 05979 if (Class) { 05980 if (ObjCPropertyDecl *Property 05981 = Class->FindPropertyDeclaration(PropertyName)) { 05982 PropertyType 05983 = Property->getType().getNonReferenceType().getUnqualifiedType(); 05984 05985 // Give preference to ivars 05986 Results.setPreferredType(PropertyType); 05987 } 05988 } 05989 05990 // Add all of the instance variables in this class and its superclasses. 05991 Results.EnterNewScope(); 05992 bool SawSimilarlyNamedIvar = false; 05993 std::string NameWithPrefix; 05994 NameWithPrefix += '_'; 05995 NameWithPrefix += PropertyName->getName(); 05996 std::string NameWithSuffix = PropertyName->getName().str(); 05997 NameWithSuffix += '_'; 05998 for(; Class; Class = Class->getSuperClass()) { 05999 for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar; 06000 Ivar = Ivar->getNextIvar()) { 06001 Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), nullptr), 06002 CurContext, nullptr, false); 06003 06004 // Determine whether we've seen an ivar with a name similar to the 06005 // property. 06006 if ((PropertyName == Ivar->getIdentifier() || 06007 NameWithPrefix == Ivar->getName() || 06008 NameWithSuffix == Ivar->getName())) { 06009 SawSimilarlyNamedIvar = true; 06010 06011 // Reduce the priority of this result by one, to give it a slight 06012 // advantage over other results whose names don't match so closely. 06013 if (Results.size() && 06014 Results.data()[Results.size() - 1].Kind 06015 == CodeCompletionResult::RK_Declaration && 06016 Results.data()[Results.size() - 1].Declaration == Ivar) 06017 Results.data()[Results.size() - 1].Priority--; 06018 } 06019 } 06020 } 06021 06022 if (!SawSimilarlyNamedIvar) { 06023 // Create ivar result _propName, that the user can use to synthesize 06024 // an ivar of the appropriate type. 06025 unsigned Priority = CCP_MemberDeclaration + 1; 06026 typedef CodeCompletionResult Result; 06027 CodeCompletionAllocator &Allocator = Results.getAllocator(); 06028 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(), 06029 Priority,CXAvailability_Available); 06030 06031 PrintingPolicy Policy = getCompletionPrintingPolicy(*this); 06032 Builder.AddResultTypeChunk(GetCompletionTypeString(PropertyType, Context, 06033 Policy, Allocator)); 06034 Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix)); 06035 Results.AddResult(Result(Builder.TakeString(), Priority, 06036 CXCursor_ObjCIvarDecl)); 06037 } 06038 06039 Results.ExitScope(); 06040 06041 HandleCodeCompleteResults(this, CodeCompleter, 06042 CodeCompletionContext::CCC_Other, 06043 Results.data(),Results.size()); 06044 } 06045 06046 // Mapping from selectors to the methods that implement that selector, along 06047 // with the "in original class" flag. 06048 typedef llvm::DenseMap< 06049 Selector, llvm::PointerIntPair<ObjCMethodDecl *, 1, bool> > KnownMethodsMap; 06050 06051 /// \brief Find all of the methods that reside in the given container 06052 /// (and its superclasses, protocols, etc.) that meet the given 06053 /// criteria. Insert those methods into the map of known methods, 06054 /// indexed by selector so they can be easily found. 06055 static void FindImplementableMethods(ASTContext &Context, 06056 ObjCContainerDecl *Container, 06057 bool WantInstanceMethods, 06058 QualType ReturnType, 06059 KnownMethodsMap &KnownMethods, 06060 bool InOriginalClass = true) { 06061 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) { 06062 // Make sure we have a definition; that's what we'll walk. 06063 if (!IFace->hasDefinition()) 06064 return; 06065 06066 IFace = IFace->getDefinition(); 06067 Container = IFace; 06068 06069 const ObjCList<ObjCProtocolDecl> &Protocols 06070 = IFace->getReferencedProtocols(); 06071 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 06072 E = Protocols.end(); 06073 I != E; ++I) 06074 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType, 06075 KnownMethods, InOriginalClass); 06076 06077 // Add methods from any class extensions and categories. 06078 for (auto *Cat : IFace->visible_categories()) { 06079 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType, 06080 KnownMethods, false); 06081 } 06082 06083 // Visit the superclass. 06084 if (IFace->getSuperClass()) 06085 FindImplementableMethods(Context, IFace->getSuperClass(), 06086 WantInstanceMethods, ReturnType, 06087 KnownMethods, false); 06088 } 06089 06090 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) { 06091 // Recurse into protocols. 06092 const ObjCList<ObjCProtocolDecl> &Protocols 06093 = Category->getReferencedProtocols(); 06094 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 06095 E = Protocols.end(); 06096 I != E; ++I) 06097 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType, 06098 KnownMethods, InOriginalClass); 06099 06100 // If this category is the original class, jump to the interface. 06101 if (InOriginalClass && Category->getClassInterface()) 06102 FindImplementableMethods(Context, Category->getClassInterface(), 06103 WantInstanceMethods, ReturnType, KnownMethods, 06104 false); 06105 } 06106 06107 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 06108 // Make sure we have a definition; that's what we'll walk. 06109 if (!Protocol->hasDefinition()) 06110 return; 06111 Protocol = Protocol->getDefinition(); 06112 Container = Protocol; 06113 06114 // Recurse into protocols. 06115 const ObjCList<ObjCProtocolDecl> &Protocols 06116 = Protocol->getReferencedProtocols(); 06117 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 06118 E = Protocols.end(); 06119 I != E; ++I) 06120 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType, 06121 KnownMethods, false); 06122 } 06123 06124 // Add methods in this container. This operation occurs last because 06125 // we want the methods from this container to override any methods 06126 // we've previously seen with the same selector. 06127 for (auto *M : Container->methods()) { 06128 if (M->isInstanceMethod() == WantInstanceMethods) { 06129 if (!ReturnType.isNull() && 06130 !Context.hasSameUnqualifiedType(ReturnType, M->getReturnType())) 06131 continue; 06132 06133 KnownMethods[M->getSelector()] = 06134 KnownMethodsMap::mapped_type(M, InOriginalClass); 06135 } 06136 } 06137 } 06138 06139 /// \brief Add the parenthesized return or parameter type chunk to a code 06140 /// completion string. 06141 static void AddObjCPassingTypeChunk(QualType Type, 06142 unsigned ObjCDeclQuals, 06143 ASTContext &Context, 06144 const PrintingPolicy &Policy, 06145 CodeCompletionBuilder &Builder) { 06146 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06147 std::string Quals = formatObjCParamQualifiers(ObjCDeclQuals); 06148 if (!Quals.empty()) 06149 Builder.AddTextChunk(Builder.getAllocator().CopyString(Quals)); 06150 Builder.AddTextChunk(GetCompletionTypeString(Type, Context, Policy, 06151 Builder.getAllocator())); 06152 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06153 } 06154 06155 /// \brief Determine whether the given class is or inherits from a class by 06156 /// the given name. 06157 static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, 06158 StringRef Name) { 06159 if (!Class) 06160 return false; 06161 06162 if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name) 06163 return true; 06164 06165 return InheritsFromClassNamed(Class->getSuperClass(), Name); 06166 } 06167 06168 /// \brief Add code completions for Objective-C Key-Value Coding (KVC) and 06169 /// Key-Value Observing (KVO). 06170 static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, 06171 bool IsInstanceMethod, 06172 QualType ReturnType, 06173 ASTContext &Context, 06174 VisitedSelectorSet &KnownSelectors, 06175 ResultBuilder &Results) { 06176 IdentifierInfo *PropName = Property->getIdentifier(); 06177 if (!PropName || PropName->getLength() == 0) 06178 return; 06179 06180 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema()); 06181 06182 // Builder that will create each code completion. 06183 typedef CodeCompletionResult Result; 06184 CodeCompletionAllocator &Allocator = Results.getAllocator(); 06185 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); 06186 06187 // The selector table. 06188 SelectorTable &Selectors = Context.Selectors; 06189 06190 // The property name, copied into the code completion allocation region 06191 // on demand. 06192 struct KeyHolder { 06193 CodeCompletionAllocator &Allocator; 06194 StringRef Key; 06195 const char *CopiedKey; 06196 06197 KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key) 06198 : Allocator(Allocator), Key(Key), CopiedKey(nullptr) {} 06199 06200 operator const char *() { 06201 if (CopiedKey) 06202 return CopiedKey; 06203 06204 return CopiedKey = Allocator.CopyString(Key); 06205 } 06206 } Key(Allocator, PropName->getName()); 06207 06208 // The uppercased name of the property name. 06209 std::string UpperKey = PropName->getName(); 06210 if (!UpperKey.empty()) 06211 UpperKey[0] = toUppercase(UpperKey[0]); 06212 06213 bool ReturnTypeMatchesProperty = ReturnType.isNull() || 06214 Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(), 06215 Property->getType()); 06216 bool ReturnTypeMatchesVoid 06217 = ReturnType.isNull() || ReturnType->isVoidType(); 06218 06219 // Add the normal accessor -(type)key. 06220 if (IsInstanceMethod && 06221 KnownSelectors.insert(Selectors.getNullarySelector(PropName)) && 06222 ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) { 06223 if (ReturnType.isNull()) 06224 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, 06225 Context, Policy, Builder); 06226 06227 Builder.AddTypedTextChunk(Key); 06228 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 06229 CXCursor_ObjCInstanceMethodDecl)); 06230 } 06231 06232 // If we have an integral or boolean property (or the user has provided 06233 // an integral or boolean return type), add the accessor -(type)isKey. 06234 if (IsInstanceMethod && 06235 ((!ReturnType.isNull() && 06236 (ReturnType->isIntegerType() || ReturnType->isBooleanType())) || 06237 (ReturnType.isNull() && 06238 (Property->getType()->isIntegerType() || 06239 Property->getType()->isBooleanType())))) { 06240 std::string SelectorName = (Twine("is") + UpperKey).str(); 06241 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06242 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 06243 if (ReturnType.isNull()) { 06244 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06245 Builder.AddTextChunk("BOOL"); 06246 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06247 } 06248 06249 Builder.AddTypedTextChunk( 06250 Allocator.CopyString(SelectorId->getName())); 06251 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 06252 CXCursor_ObjCInstanceMethodDecl)); 06253 } 06254 } 06255 06256 // Add the normal mutator. 06257 if (IsInstanceMethod && ReturnTypeMatchesVoid && 06258 !Property->getSetterMethodDecl()) { 06259 std::string SelectorName = (Twine("set") + UpperKey).str(); 06260 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06261 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06262 if (ReturnType.isNull()) { 06263 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06264 Builder.AddTextChunk("void"); 06265 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06266 } 06267 06268 Builder.AddTypedTextChunk( 06269 Allocator.CopyString(SelectorId->getName())); 06270 Builder.AddTypedTextChunk(":"); 06271 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, 06272 Context, Policy, Builder); 06273 Builder.AddTextChunk(Key); 06274 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 06275 CXCursor_ObjCInstanceMethodDecl)); 06276 } 06277 } 06278 06279 // Indexed and unordered accessors 06280 unsigned IndexedGetterPriority = CCP_CodePattern; 06281 unsigned IndexedSetterPriority = CCP_CodePattern; 06282 unsigned UnorderedGetterPriority = CCP_CodePattern; 06283 unsigned UnorderedSetterPriority = CCP_CodePattern; 06284 if (const ObjCObjectPointerType *ObjCPointer 06285 = Property->getType()->getAs<ObjCObjectPointerType>()) { 06286 if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) { 06287 // If this interface type is not provably derived from a known 06288 // collection, penalize the corresponding completions. 06289 if (!InheritsFromClassNamed(IFace, "NSMutableArray")) { 06290 IndexedSetterPriority += CCD_ProbablyNotObjCCollection; 06291 if (!InheritsFromClassNamed(IFace, "NSArray")) 06292 IndexedGetterPriority += CCD_ProbablyNotObjCCollection; 06293 } 06294 06295 if (!InheritsFromClassNamed(IFace, "NSMutableSet")) { 06296 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection; 06297 if (!InheritsFromClassNamed(IFace, "NSSet")) 06298 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection; 06299 } 06300 } 06301 } else { 06302 IndexedGetterPriority += CCD_ProbablyNotObjCCollection; 06303 IndexedSetterPriority += CCD_ProbablyNotObjCCollection; 06304 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection; 06305 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection; 06306 } 06307 06308 // Add -(NSUInteger)countOf<key> 06309 if (IsInstanceMethod && 06310 (ReturnType.isNull() || ReturnType->isIntegerType())) { 06311 std::string SelectorName = (Twine("countOf") + UpperKey).str(); 06312 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06313 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 06314 if (ReturnType.isNull()) { 06315 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06316 Builder.AddTextChunk("NSUInteger"); 06317 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06318 } 06319 06320 Builder.AddTypedTextChunk( 06321 Allocator.CopyString(SelectorId->getName())); 06322 Results.AddResult(Result(Builder.TakeString(), 06323 std::min(IndexedGetterPriority, 06324 UnorderedGetterPriority), 06325 CXCursor_ObjCInstanceMethodDecl)); 06326 } 06327 } 06328 06329 // Indexed getters 06330 // Add -(id)objectInKeyAtIndex:(NSUInteger)index 06331 if (IsInstanceMethod && 06332 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) { 06333 std::string SelectorName 06334 = (Twine("objectIn") + UpperKey + "AtIndex").str(); 06335 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06336 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06337 if (ReturnType.isNull()) { 06338 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06339 Builder.AddTextChunk("id"); 06340 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06341 } 06342 06343 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06344 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06345 Builder.AddTextChunk("NSUInteger"); 06346 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06347 Builder.AddTextChunk("index"); 06348 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority, 06349 CXCursor_ObjCInstanceMethodDecl)); 06350 } 06351 } 06352 06353 // Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes 06354 if (IsInstanceMethod && 06355 (ReturnType.isNull() || 06356 (ReturnType->isObjCObjectPointerType() && 06357 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() && 06358 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() 06359 ->getName() == "NSArray"))) { 06360 std::string SelectorName 06361 = (Twine(Property->getName()) + "AtIndexes").str(); 06362 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06363 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06364 if (ReturnType.isNull()) { 06365 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06366 Builder.AddTextChunk("NSArray *"); 06367 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06368 } 06369 06370 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06371 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06372 Builder.AddTextChunk("NSIndexSet *"); 06373 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06374 Builder.AddTextChunk("indexes"); 06375 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority, 06376 CXCursor_ObjCInstanceMethodDecl)); 06377 } 06378 } 06379 06380 // Add -(void)getKey:(type **)buffer range:(NSRange)inRange 06381 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06382 std::string SelectorName = (Twine("get") + UpperKey).str(); 06383 IdentifierInfo *SelectorIds[2] = { 06384 &Context.Idents.get(SelectorName), 06385 &Context.Idents.get("range") 06386 }; 06387 06388 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 06389 if (ReturnType.isNull()) { 06390 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06391 Builder.AddTextChunk("void"); 06392 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06393 } 06394 06395 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06396 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06397 Builder.AddPlaceholderChunk("object-type"); 06398 Builder.AddTextChunk(" **"); 06399 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06400 Builder.AddTextChunk("buffer"); 06401 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 06402 Builder.AddTypedTextChunk("range:"); 06403 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06404 Builder.AddTextChunk("NSRange"); 06405 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06406 Builder.AddTextChunk("inRange"); 06407 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority, 06408 CXCursor_ObjCInstanceMethodDecl)); 06409 } 06410 } 06411 06412 // Mutable indexed accessors 06413 06414 // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index 06415 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06416 std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str(); 06417 IdentifierInfo *SelectorIds[2] = { 06418 &Context.Idents.get("insertObject"), 06419 &Context.Idents.get(SelectorName) 06420 }; 06421 06422 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 06423 if (ReturnType.isNull()) { 06424 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06425 Builder.AddTextChunk("void"); 06426 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06427 } 06428 06429 Builder.AddTypedTextChunk("insertObject:"); 06430 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06431 Builder.AddPlaceholderChunk("object-type"); 06432 Builder.AddTextChunk(" *"); 06433 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06434 Builder.AddTextChunk("object"); 06435 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 06436 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06437 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06438 Builder.AddPlaceholderChunk("NSUInteger"); 06439 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06440 Builder.AddTextChunk("index"); 06441 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 06442 CXCursor_ObjCInstanceMethodDecl)); 06443 } 06444 } 06445 06446 // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes 06447 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06448 std::string SelectorName = (Twine("insert") + UpperKey).str(); 06449 IdentifierInfo *SelectorIds[2] = { 06450 &Context.Idents.get(SelectorName), 06451 &Context.Idents.get("atIndexes") 06452 }; 06453 06454 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 06455 if (ReturnType.isNull()) { 06456 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06457 Builder.AddTextChunk("void"); 06458 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06459 } 06460 06461 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06462 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06463 Builder.AddTextChunk("NSArray *"); 06464 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06465 Builder.AddTextChunk("array"); 06466 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 06467 Builder.AddTypedTextChunk("atIndexes:"); 06468 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06469 Builder.AddPlaceholderChunk("NSIndexSet *"); 06470 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06471 Builder.AddTextChunk("indexes"); 06472 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 06473 CXCursor_ObjCInstanceMethodDecl)); 06474 } 06475 } 06476 06477 // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index 06478 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06479 std::string SelectorName 06480 = (Twine("removeObjectFrom") + UpperKey + "AtIndex").str(); 06481 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06482 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06483 if (ReturnType.isNull()) { 06484 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06485 Builder.AddTextChunk("void"); 06486 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06487 } 06488 06489 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06490 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06491 Builder.AddTextChunk("NSUInteger"); 06492 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06493 Builder.AddTextChunk("index"); 06494 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 06495 CXCursor_ObjCInstanceMethodDecl)); 06496 } 06497 } 06498 06499 // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes 06500 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06501 std::string SelectorName 06502 = (Twine("remove") + UpperKey + "AtIndexes").str(); 06503 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06504 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06505 if (ReturnType.isNull()) { 06506 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06507 Builder.AddTextChunk("void"); 06508 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06509 } 06510 06511 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06512 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06513 Builder.AddTextChunk("NSIndexSet *"); 06514 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06515 Builder.AddTextChunk("indexes"); 06516 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 06517 CXCursor_ObjCInstanceMethodDecl)); 06518 } 06519 } 06520 06521 // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object 06522 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06523 std::string SelectorName 06524 = (Twine("replaceObjectIn") + UpperKey + "AtIndex").str(); 06525 IdentifierInfo *SelectorIds[2] = { 06526 &Context.Idents.get(SelectorName), 06527 &Context.Idents.get("withObject") 06528 }; 06529 06530 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 06531 if (ReturnType.isNull()) { 06532 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06533 Builder.AddTextChunk("void"); 06534 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06535 } 06536 06537 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06538 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06539 Builder.AddPlaceholderChunk("NSUInteger"); 06540 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06541 Builder.AddTextChunk("index"); 06542 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 06543 Builder.AddTypedTextChunk("withObject:"); 06544 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06545 Builder.AddTextChunk("id"); 06546 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06547 Builder.AddTextChunk("object"); 06548 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 06549 CXCursor_ObjCInstanceMethodDecl)); 06550 } 06551 } 06552 06553 // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array 06554 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06555 std::string SelectorName1 06556 = (Twine("replace") + UpperKey + "AtIndexes").str(); 06557 std::string SelectorName2 = (Twine("with") + UpperKey).str(); 06558 IdentifierInfo *SelectorIds[2] = { 06559 &Context.Idents.get(SelectorName1), 06560 &Context.Idents.get(SelectorName2) 06561 }; 06562 06563 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) { 06564 if (ReturnType.isNull()) { 06565 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06566 Builder.AddTextChunk("void"); 06567 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06568 } 06569 06570 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName1 + ":")); 06571 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06572 Builder.AddPlaceholderChunk("NSIndexSet *"); 06573 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06574 Builder.AddTextChunk("indexes"); 06575 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 06576 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName2 + ":")); 06577 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06578 Builder.AddTextChunk("NSArray *"); 06579 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06580 Builder.AddTextChunk("array"); 06581 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority, 06582 CXCursor_ObjCInstanceMethodDecl)); 06583 } 06584 } 06585 06586 // Unordered getters 06587 // - (NSEnumerator *)enumeratorOfKey 06588 if (IsInstanceMethod && 06589 (ReturnType.isNull() || 06590 (ReturnType->isObjCObjectPointerType() && 06591 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() && 06592 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() 06593 ->getName() == "NSEnumerator"))) { 06594 std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str(); 06595 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06596 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 06597 if (ReturnType.isNull()) { 06598 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06599 Builder.AddTextChunk("NSEnumerator *"); 06600 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06601 } 06602 06603 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName)); 06604 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority, 06605 CXCursor_ObjCInstanceMethodDecl)); 06606 } 06607 } 06608 06609 // - (type *)memberOfKey:(type *)object 06610 if (IsInstanceMethod && 06611 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) { 06612 std::string SelectorName = (Twine("memberOf") + UpperKey).str(); 06613 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06614 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06615 if (ReturnType.isNull()) { 06616 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06617 Builder.AddPlaceholderChunk("object-type"); 06618 Builder.AddTextChunk(" *"); 06619 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06620 } 06621 06622 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06623 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06624 if (ReturnType.isNull()) { 06625 Builder.AddPlaceholderChunk("object-type"); 06626 Builder.AddTextChunk(" *"); 06627 } else { 06628 Builder.AddTextChunk(GetCompletionTypeString(ReturnType, Context, 06629 Policy, 06630 Builder.getAllocator())); 06631 } 06632 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06633 Builder.AddTextChunk("object"); 06634 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority, 06635 CXCursor_ObjCInstanceMethodDecl)); 06636 } 06637 } 06638 06639 // Mutable unordered accessors 06640 // - (void)addKeyObject:(type *)object 06641 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06642 std::string SelectorName 06643 = (Twine("add") + UpperKey + Twine("Object")).str(); 06644 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06645 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06646 if (ReturnType.isNull()) { 06647 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06648 Builder.AddTextChunk("void"); 06649 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06650 } 06651 06652 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06653 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06654 Builder.AddPlaceholderChunk("object-type"); 06655 Builder.AddTextChunk(" *"); 06656 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06657 Builder.AddTextChunk("object"); 06658 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 06659 CXCursor_ObjCInstanceMethodDecl)); 06660 } 06661 } 06662 06663 // - (void)addKey:(NSSet *)objects 06664 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06665 std::string SelectorName = (Twine("add") + UpperKey).str(); 06666 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06667 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06668 if (ReturnType.isNull()) { 06669 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06670 Builder.AddTextChunk("void"); 06671 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06672 } 06673 06674 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06675 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06676 Builder.AddTextChunk("NSSet *"); 06677 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06678 Builder.AddTextChunk("objects"); 06679 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 06680 CXCursor_ObjCInstanceMethodDecl)); 06681 } 06682 } 06683 06684 // - (void)removeKeyObject:(type *)object 06685 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06686 std::string SelectorName 06687 = (Twine("remove") + UpperKey + Twine("Object")).str(); 06688 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06689 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06690 if (ReturnType.isNull()) { 06691 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06692 Builder.AddTextChunk("void"); 06693 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06694 } 06695 06696 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06697 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06698 Builder.AddPlaceholderChunk("object-type"); 06699 Builder.AddTextChunk(" *"); 06700 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06701 Builder.AddTextChunk("object"); 06702 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 06703 CXCursor_ObjCInstanceMethodDecl)); 06704 } 06705 } 06706 06707 // - (void)removeKey:(NSSet *)objects 06708 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06709 std::string SelectorName = (Twine("remove") + UpperKey).str(); 06710 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06711 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06712 if (ReturnType.isNull()) { 06713 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06714 Builder.AddTextChunk("void"); 06715 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06716 } 06717 06718 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06719 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06720 Builder.AddTextChunk("NSSet *"); 06721 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06722 Builder.AddTextChunk("objects"); 06723 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 06724 CXCursor_ObjCInstanceMethodDecl)); 06725 } 06726 } 06727 06728 // - (void)intersectKey:(NSSet *)objects 06729 if (IsInstanceMethod && ReturnTypeMatchesVoid) { 06730 std::string SelectorName = (Twine("intersect") + UpperKey).str(); 06731 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06732 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) { 06733 if (ReturnType.isNull()) { 06734 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06735 Builder.AddTextChunk("void"); 06736 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06737 } 06738 06739 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":")); 06740 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06741 Builder.AddTextChunk("NSSet *"); 06742 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06743 Builder.AddTextChunk("objects"); 06744 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority, 06745 CXCursor_ObjCInstanceMethodDecl)); 06746 } 06747 } 06748 06749 // Key-Value Observing 06750 // + (NSSet *)keyPathsForValuesAffectingKey 06751 if (!IsInstanceMethod && 06752 (ReturnType.isNull() || 06753 (ReturnType->isObjCObjectPointerType() && 06754 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() && 06755 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() 06756 ->getName() == "NSSet"))) { 06757 std::string SelectorName 06758 = (Twine("keyPathsForValuesAffecting") + UpperKey).str(); 06759 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06760 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 06761 if (ReturnType.isNull()) { 06762 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06763 Builder.AddTextChunk("NSSet *"); 06764 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06765 } 06766 06767 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName)); 06768 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 06769 CXCursor_ObjCClassMethodDecl)); 06770 } 06771 } 06772 06773 // + (BOOL)automaticallyNotifiesObserversForKey 06774 if (!IsInstanceMethod && 06775 (ReturnType.isNull() || 06776 ReturnType->isIntegerType() || 06777 ReturnType->isBooleanType())) { 06778 std::string SelectorName 06779 = (Twine("automaticallyNotifiesObserversOf") + UpperKey).str(); 06780 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); 06781 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) { 06782 if (ReturnType.isNull()) { 06783 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 06784 Builder.AddTextChunk("BOOL"); 06785 Builder.AddChunk(CodeCompletionString::CK_RightParen); 06786 } 06787 06788 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName)); 06789 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, 06790 CXCursor_ObjCClassMethodDecl)); 06791 } 06792 } 06793 } 06794 06795 void Sema::CodeCompleteObjCMethodDecl(Scope *S, 06796 bool IsInstanceMethod, 06797 ParsedType ReturnTy) { 06798 // Determine the return type of the method we're declaring, if 06799 // provided. 06800 QualType ReturnType = GetTypeFromParser(ReturnTy); 06801 Decl *IDecl = nullptr; 06802 if (CurContext->isObjCContainer()) { 06803 ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); 06804 IDecl = cast<Decl>(OCD); 06805 } 06806 // Determine where we should start searching for methods. 06807 ObjCContainerDecl *SearchDecl = nullptr; 06808 bool IsInImplementation = false; 06809 if (Decl *D = IDecl) { 06810 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) { 06811 SearchDecl = Impl->getClassInterface(); 06812 IsInImplementation = true; 06813 } else if (ObjCCategoryImplDecl *CatImpl 06814 = dyn_cast<ObjCCategoryImplDecl>(D)) { 06815 SearchDecl = CatImpl->getCategoryDecl(); 06816 IsInImplementation = true; 06817 } else 06818 SearchDecl = dyn_cast<ObjCContainerDecl>(D); 06819 } 06820 06821 if (!SearchDecl && S) { 06822 if (DeclContext *DC = S->getEntity()) 06823 SearchDecl = dyn_cast<ObjCContainerDecl>(DC); 06824 } 06825 06826 if (!SearchDecl) { 06827 HandleCodeCompleteResults(this, CodeCompleter, 06828 CodeCompletionContext::CCC_Other, 06829 nullptr, 0); 06830 return; 06831 } 06832 06833 // Find all of the methods that we could declare/implement here. 06834 KnownMethodsMap KnownMethods; 06835 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod, 06836 ReturnType, KnownMethods); 06837 06838 // Add declarations or definitions for each of the known methods. 06839 typedef CodeCompletionResult Result; 06840 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 06841 CodeCompleter->getCodeCompletionTUInfo(), 06842 CodeCompletionContext::CCC_Other); 06843 Results.EnterNewScope(); 06844 PrintingPolicy Policy = getCompletionPrintingPolicy(*this); 06845 for (KnownMethodsMap::iterator M = KnownMethods.begin(), 06846 MEnd = KnownMethods.end(); 06847 M != MEnd; ++M) { 06848 ObjCMethodDecl *Method = M->second.getPointer(); 06849 CodeCompletionBuilder Builder(Results.getAllocator(), 06850 Results.getCodeCompletionTUInfo()); 06851 06852 // If the result type was not already provided, add it to the 06853 // pattern as (type). 06854 if (ReturnType.isNull()) 06855 AddObjCPassingTypeChunk(Method->getReturnType(), 06856 Method->getObjCDeclQualifier(), Context, Policy, 06857 Builder); 06858 06859 Selector Sel = Method->getSelector(); 06860 06861 // Add the first part of the selector to the pattern. 06862 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 06863 Sel.getNameForSlot(0))); 06864 06865 // Add parameters to the pattern. 06866 unsigned I = 0; 06867 for (ObjCMethodDecl::param_iterator P = Method->param_begin(), 06868 PEnd = Method->param_end(); 06869 P != PEnd; (void)++P, ++I) { 06870 // Add the part of the selector name. 06871 if (I == 0) 06872 Builder.AddTypedTextChunk(":"); 06873 else if (I < Sel.getNumArgs()) { 06874 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 06875 Builder.AddTypedTextChunk( 06876 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); 06877 } else 06878 break; 06879 06880 // Add the parameter type. 06881 AddObjCPassingTypeChunk((*P)->getOriginalType(), 06882 (*P)->getObjCDeclQualifier(), 06883 Context, Policy, 06884 Builder); 06885 06886 if (IdentifierInfo *Id = (*P)->getIdentifier()) 06887 Builder.AddTextChunk(Builder.getAllocator().CopyString( Id->getName())); 06888 } 06889 06890 if (Method->isVariadic()) { 06891 if (Method->param_size() > 0) 06892 Builder.AddChunk(CodeCompletionString::CK_Comma); 06893 Builder.AddTextChunk("..."); 06894 } 06895 06896 if (IsInImplementation && Results.includeCodePatterns()) { 06897 // We will be defining the method here, so add a compound statement. 06898 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 06899 Builder.AddChunk(CodeCompletionString::CK_LeftBrace); 06900 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 06901 if (!Method->getReturnType()->isVoidType()) { 06902 // If the result type is not void, add a return clause. 06903 Builder.AddTextChunk("return"); 06904 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 06905 Builder.AddPlaceholderChunk("expression"); 06906 Builder.AddChunk(CodeCompletionString::CK_SemiColon); 06907 } else 06908 Builder.AddPlaceholderChunk("statements"); 06909 06910 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); 06911 Builder.AddChunk(CodeCompletionString::CK_RightBrace); 06912 } 06913 06914 unsigned Priority = CCP_CodePattern; 06915 if (!M->second.getInt()) 06916 Priority += CCD_InBaseClass; 06917 06918 Results.AddResult(Result(Builder.TakeString(), Method, Priority)); 06919 } 06920 06921 // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of 06922 // the properties in this class and its categories. 06923 if (Context.getLangOpts().ObjC2) { 06924 SmallVector<ObjCContainerDecl *, 4> Containers; 06925 Containers.push_back(SearchDecl); 06926 06927 VisitedSelectorSet KnownSelectors; 06928 for (KnownMethodsMap::iterator M = KnownMethods.begin(), 06929 MEnd = KnownMethods.end(); 06930 M != MEnd; ++M) 06931 KnownSelectors.insert(M->first); 06932 06933 06934 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl); 06935 if (!IFace) 06936 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl)) 06937 IFace = Category->getClassInterface(); 06938 06939 if (IFace) 06940 for (auto *Cat : IFace->visible_categories()) 06941 Containers.push_back(Cat); 06942 06943 for (unsigned I = 0, N = Containers.size(); I != N; ++I) 06944 for (auto *P : Containers[I]->properties()) 06945 AddObjCKeyValueCompletions(P, IsInstanceMethod, ReturnType, Context, 06946 KnownSelectors, Results); 06947 } 06948 06949 Results.ExitScope(); 06950 06951 HandleCodeCompleteResults(this, CodeCompleter, 06952 CodeCompletionContext::CCC_Other, 06953 Results.data(),Results.size()); 06954 } 06955 06956 void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, 06957 bool IsInstanceMethod, 06958 bool AtParameterName, 06959 ParsedType ReturnTy, 06960 ArrayRef<IdentifierInfo *> SelIdents) { 06961 // If we have an external source, load the entire class method 06962 // pool from the AST file. 06963 if (ExternalSource) { 06964 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); 06965 I != N; ++I) { 06966 Selector Sel = ExternalSource->GetExternalSelector(I); 06967 if (Sel.isNull() || MethodPool.count(Sel)) 06968 continue; 06969 06970 ReadMethodPool(Sel); 06971 } 06972 } 06973 06974 // Build the set of methods we can see. 06975 typedef CodeCompletionResult Result; 06976 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 06977 CodeCompleter->getCodeCompletionTUInfo(), 06978 CodeCompletionContext::CCC_Other); 06979 06980 if (ReturnTy) 06981 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType()); 06982 06983 Results.EnterNewScope(); 06984 for (GlobalMethodPool::iterator M = MethodPool.begin(), 06985 MEnd = MethodPool.end(); 06986 M != MEnd; ++M) { 06987 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first : 06988 &M->second.second; 06989 MethList && MethList->Method; 06990 MethList = MethList->getNext()) { 06991 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents)) 06992 continue; 06993 06994 if (AtParameterName) { 06995 // Suggest parameter names we've seen before. 06996 unsigned NumSelIdents = SelIdents.size(); 06997 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) { 06998 ParmVarDecl *Param = MethList->Method->parameters()[NumSelIdents-1]; 06999 if (Param->getIdentifier()) { 07000 CodeCompletionBuilder Builder(Results.getAllocator(), 07001 Results.getCodeCompletionTUInfo()); 07002 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 07003 Param->getIdentifier()->getName())); 07004 Results.AddResult(Builder.TakeString()); 07005 } 07006 } 07007 07008 continue; 07009 } 07010 07011 Result R(MethList->Method, Results.getBasePriority(MethList->Method), 07012 nullptr); 07013 R.StartParameter = SelIdents.size(); 07014 R.AllParametersAreInformative = false; 07015 R.DeclaringEntity = true; 07016 Results.MaybeAddResult(R, CurContext); 07017 } 07018 } 07019 07020 Results.ExitScope(); 07021 HandleCodeCompleteResults(this, CodeCompleter, 07022 CodeCompletionContext::CCC_Other, 07023 Results.data(),Results.size()); 07024 } 07025 07026 void Sema::CodeCompletePreprocessorDirective(bool InConditional) { 07027 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 07028 CodeCompleter->getCodeCompletionTUInfo(), 07029 CodeCompletionContext::CCC_PreprocessorDirective); 07030 Results.EnterNewScope(); 07031 07032 // #if <condition> 07033 CodeCompletionBuilder Builder(Results.getAllocator(), 07034 Results.getCodeCompletionTUInfo()); 07035 Builder.AddTypedTextChunk("if"); 07036 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07037 Builder.AddPlaceholderChunk("condition"); 07038 Results.AddResult(Builder.TakeString()); 07039 07040 // #ifdef <macro> 07041 Builder.AddTypedTextChunk("ifdef"); 07042 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07043 Builder.AddPlaceholderChunk("macro"); 07044 Results.AddResult(Builder.TakeString()); 07045 07046 // #ifndef <macro> 07047 Builder.AddTypedTextChunk("ifndef"); 07048 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07049 Builder.AddPlaceholderChunk("macro"); 07050 Results.AddResult(Builder.TakeString()); 07051 07052 if (InConditional) { 07053 // #elif <condition> 07054 Builder.AddTypedTextChunk("elif"); 07055 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07056 Builder.AddPlaceholderChunk("condition"); 07057 Results.AddResult(Builder.TakeString()); 07058 07059 // #else 07060 Builder.AddTypedTextChunk("else"); 07061 Results.AddResult(Builder.TakeString()); 07062 07063 // #endif 07064 Builder.AddTypedTextChunk("endif"); 07065 Results.AddResult(Builder.TakeString()); 07066 } 07067 07068 // #include "header" 07069 Builder.AddTypedTextChunk("include"); 07070 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07071 Builder.AddTextChunk("\""); 07072 Builder.AddPlaceholderChunk("header"); 07073 Builder.AddTextChunk("\""); 07074 Results.AddResult(Builder.TakeString()); 07075 07076 // #include <header> 07077 Builder.AddTypedTextChunk("include"); 07078 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07079 Builder.AddTextChunk("<"); 07080 Builder.AddPlaceholderChunk("header"); 07081 Builder.AddTextChunk(">"); 07082 Results.AddResult(Builder.TakeString()); 07083 07084 // #define <macro> 07085 Builder.AddTypedTextChunk("define"); 07086 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07087 Builder.AddPlaceholderChunk("macro"); 07088 Results.AddResult(Builder.TakeString()); 07089 07090 // #define <macro>(<args>) 07091 Builder.AddTypedTextChunk("define"); 07092 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07093 Builder.AddPlaceholderChunk("macro"); 07094 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 07095 Builder.AddPlaceholderChunk("args"); 07096 Builder.AddChunk(CodeCompletionString::CK_RightParen); 07097 Results.AddResult(Builder.TakeString()); 07098 07099 // #undef <macro> 07100 Builder.AddTypedTextChunk("undef"); 07101 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07102 Builder.AddPlaceholderChunk("macro"); 07103 Results.AddResult(Builder.TakeString()); 07104 07105 // #line <number> 07106 Builder.AddTypedTextChunk("line"); 07107 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07108 Builder.AddPlaceholderChunk("number"); 07109 Results.AddResult(Builder.TakeString()); 07110 07111 // #line <number> "filename" 07112 Builder.AddTypedTextChunk("line"); 07113 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07114 Builder.AddPlaceholderChunk("number"); 07115 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07116 Builder.AddTextChunk("\""); 07117 Builder.AddPlaceholderChunk("filename"); 07118 Builder.AddTextChunk("\""); 07119 Results.AddResult(Builder.TakeString()); 07120 07121 // #error <message> 07122 Builder.AddTypedTextChunk("error"); 07123 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07124 Builder.AddPlaceholderChunk("message"); 07125 Results.AddResult(Builder.TakeString()); 07126 07127 // #pragma <arguments> 07128 Builder.AddTypedTextChunk("pragma"); 07129 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07130 Builder.AddPlaceholderChunk("arguments"); 07131 Results.AddResult(Builder.TakeString()); 07132 07133 if (getLangOpts().ObjC1) { 07134 // #import "header" 07135 Builder.AddTypedTextChunk("import"); 07136 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07137 Builder.AddTextChunk("\""); 07138 Builder.AddPlaceholderChunk("header"); 07139 Builder.AddTextChunk("\""); 07140 Results.AddResult(Builder.TakeString()); 07141 07142 // #import <header> 07143 Builder.AddTypedTextChunk("import"); 07144 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07145 Builder.AddTextChunk("<"); 07146 Builder.AddPlaceholderChunk("header"); 07147 Builder.AddTextChunk(">"); 07148 Results.AddResult(Builder.TakeString()); 07149 } 07150 07151 // #include_next "header" 07152 Builder.AddTypedTextChunk("include_next"); 07153 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07154 Builder.AddTextChunk("\""); 07155 Builder.AddPlaceholderChunk("header"); 07156 Builder.AddTextChunk("\""); 07157 Results.AddResult(Builder.TakeString()); 07158 07159 // #include_next <header> 07160 Builder.AddTypedTextChunk("include_next"); 07161 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07162 Builder.AddTextChunk("<"); 07163 Builder.AddPlaceholderChunk("header"); 07164 Builder.AddTextChunk(">"); 07165 Results.AddResult(Builder.TakeString()); 07166 07167 // #warning <message> 07168 Builder.AddTypedTextChunk("warning"); 07169 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07170 Builder.AddPlaceholderChunk("message"); 07171 Results.AddResult(Builder.TakeString()); 07172 07173 // Note: #ident and #sccs are such crazy anachronisms that we don't provide 07174 // completions for them. And __include_macros is a Clang-internal extension 07175 // that we don't want to encourage anyone to use. 07176 07177 // FIXME: we don't support #assert or #unassert, so don't suggest them. 07178 Results.ExitScope(); 07179 07180 HandleCodeCompleteResults(this, CodeCompleter, 07181 CodeCompletionContext::CCC_PreprocessorDirective, 07182 Results.data(), Results.size()); 07183 } 07184 07185 void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) { 07186 CodeCompleteOrdinaryName(S, 07187 S->getFnParent()? Sema::PCC_RecoveryInFunction 07188 : Sema::PCC_Namespace); 07189 } 07190 07191 void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) { 07192 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 07193 CodeCompleter->getCodeCompletionTUInfo(), 07194 IsDefinition? CodeCompletionContext::CCC_MacroName 07195 : CodeCompletionContext::CCC_MacroNameUse); 07196 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) { 07197 // Add just the names of macros, not their arguments. 07198 CodeCompletionBuilder Builder(Results.getAllocator(), 07199 Results.getCodeCompletionTUInfo()); 07200 Results.EnterNewScope(); 07201 for (Preprocessor::macro_iterator M = PP.macro_begin(), 07202 MEnd = PP.macro_end(); 07203 M != MEnd; ++M) { 07204 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( 07205 M->first->getName())); 07206 Results.AddResult(CodeCompletionResult(Builder.TakeString(), 07207 CCP_CodePattern, 07208 CXCursor_MacroDefinition)); 07209 } 07210 Results.ExitScope(); 07211 } else if (IsDefinition) { 07212 // FIXME: Can we detect when the user just wrote an include guard above? 07213 } 07214 07215 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), 07216 Results.data(), Results.size()); 07217 } 07218 07219 void Sema::CodeCompletePreprocessorExpression() { 07220 ResultBuilder Results(*this, CodeCompleter->getAllocator(), 07221 CodeCompleter->getCodeCompletionTUInfo(), 07222 CodeCompletionContext::CCC_PreprocessorExpression); 07223 07224 if (!CodeCompleter || CodeCompleter->includeMacros()) 07225 AddMacroResults(PP, Results, true); 07226 07227 // defined (<macro>) 07228 Results.EnterNewScope(); 07229 CodeCompletionBuilder Builder(Results.getAllocator(), 07230 Results.getCodeCompletionTUInfo()); 07231 Builder.AddTypedTextChunk("defined"); 07232 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); 07233 Builder.AddChunk(CodeCompletionString::CK_LeftParen); 07234 Builder.AddPlaceholderChunk("macro"); 07235 Builder.AddChunk(CodeCompletionString::CK_RightParen); 07236 Results.AddResult(Builder.TakeString()); 07237 Results.ExitScope(); 07238 07239 HandleCodeCompleteResults(this, CodeCompleter, 07240 CodeCompletionContext::CCC_PreprocessorExpression, 07241 Results.data(), Results.size()); 07242 } 07243 07244 void Sema::CodeCompletePreprocessorMacroArgument(Scope *S, 07245 IdentifierInfo *Macro, 07246 MacroInfo *MacroInfo, 07247 unsigned Argument) { 07248 // FIXME: In the future, we could provide "overload" results, much like we 07249 // do for function calls. 07250 07251 // Now just ignore this. There will be another code-completion callback 07252 // for the expanded tokens. 07253 } 07254 07255 void Sema::CodeCompleteNaturalLanguage() { 07256 HandleCodeCompleteResults(this, CodeCompleter, 07257 CodeCompletionContext::CCC_NaturalLanguage, 07258 nullptr, 0); 07259 } 07260 07261 void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, 07262 CodeCompletionTUInfo &CCTUInfo, 07263 SmallVectorImpl<CodeCompletionResult> &Results) { 07264 ResultBuilder Builder(*this, Allocator, CCTUInfo, 07265 CodeCompletionContext::CCC_Recovery); 07266 if (!CodeCompleter || CodeCompleter->includeGlobals()) { 07267 CodeCompletionDeclConsumer Consumer(Builder, 07268 Context.getTranslationUnitDecl()); 07269 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName, 07270 Consumer); 07271 } 07272 07273 if (!CodeCompleter || CodeCompleter->includeMacros()) 07274 AddMacroResults(PP, Builder, true); 07275 07276 Results.clear(); 07277 Results.insert(Results.end(), 07278 Builder.data(), Builder.data() + Builder.size()); 07279 }