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