blob: 3f6393724eeafc13d7443d3b0503b5a309e5e4f6 [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
John McCall2d887082010-08-25 22:03:47 +000013#include "clang/Sema/SemaInternal.h"
John McCall7cd088e2010-08-24 07:21:54 +000014#include "clang/AST/DeclObjC.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000015#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000016#include "clang/AST/ExprObjC.h"
Douglas Gregorc5b2e582012-01-29 18:15:03 +000017#include "clang/Lex/HeaderSearch.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000018#include "clang/Lex/MacroInfo.h"
19#include "clang/Lex/Preprocessor.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000020#include "clang/Sema/CodeCompleteConsumer.h"
21#include "clang/Sema/ExternalSemaSource.h"
22#include "clang/Sema/Lookup.h"
23#include "clang/Sema/Overload.h"
24#include "clang/Sema/Scope.h"
25#include "clang/Sema/ScopeInfo.h"
Douglas Gregord36adf52010-09-16 16:06:31 +000026#include "llvm/ADT/DenseSet.h"
Benjamin Kramer013b3662012-01-30 16:17:39 +000027#include "llvm/ADT/SmallBitVector.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000028#include "llvm/ADT/SmallPtrSet.h"
Benjamin Kramer8fe83e12012-02-04 13:45:25 +000029#include "llvm/ADT/SmallString.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000030#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000031#include "llvm/ADT/StringSwitch.h"
Douglas Gregor458433d2010-08-26 15:07:07 +000032#include "llvm/ADT/Twine.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000033#include <list>
34#include <map>
35#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000036
37using namespace clang;
John McCall781472f2010-08-25 08:40:02 +000038using namespace sema;
Douglas Gregor81b747b2009-09-17 21:32:03 +000039
Douglas Gregor86d9a522009-09-21 16:56:56 +000040namespace {
41 /// \brief A container of code-completion results.
42 class ResultBuilder {
43 public:
44 /// \brief The type of a name-lookup filter, which can be provided to the
45 /// name-lookup routines to specify which declarations should be included in
46 /// the result set (when it returns true) and which declarations should be
47 /// filtered out (returns false).
Dmitri Gribenko89cf4252013-01-23 17:21:11 +000048 typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +000049
John McCall0a2c5e22010-08-25 06:19:51 +000050 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +000051
52 private:
53 /// \brief The actual results we have found.
54 std::vector<Result> Results;
55
56 /// \brief A record of all of the declarations we have found and placed
57 /// into the result set, used to ensure that no declaration ever gets into
58 /// the result set twice.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +000059 llvm::SmallPtrSet<const Decl*, 16> AllDeclsFound;
Douglas Gregor86d9a522009-09-21 16:56:56 +000060
Dmitri Gribenko89cf4252013-01-23 17:21:11 +000061 typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair;
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000062
63 /// \brief An entry in the shadow map, which is optimized to store
64 /// a single (declaration, index) mapping (the common case) but
65 /// can also store a list of (declaration, index) mappings.
66 class ShadowMapEntry {
Chris Lattner5f9e2722011-07-23 10:55:15 +000067 typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000068
69 /// \brief Contains either the solitary NamedDecl * or a vector
70 /// of (declaration, index) pairs.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +000071 llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector*> DeclOrVector;
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000072
73 /// \brief When the entry contains a single declaration, this is
74 /// the index associated with that entry.
75 unsigned SingleDeclIndex;
76
77 public:
78 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
79
Dmitri Gribenko89cf4252013-01-23 17:21:11 +000080 void Add(const NamedDecl *ND, unsigned Index) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000081 if (DeclOrVector.isNull()) {
82 // 0 - > 1 elements: just set the single element information.
83 DeclOrVector = ND;
84 SingleDeclIndex = Index;
85 return;
86 }
87
Dmitri Gribenko89cf4252013-01-23 17:21:11 +000088 if (const NamedDecl *PrevND =
89 DeclOrVector.dyn_cast<const NamedDecl *>()) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000090 // 1 -> 2 elements: create the vector of results and push in the
91 // existing declaration.
92 DeclIndexPairVector *Vec = new DeclIndexPairVector;
93 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
94 DeclOrVector = Vec;
95 }
96
97 // Add the new element to the end of the vector.
98 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
99 DeclIndexPair(ND, Index));
100 }
101
102 void Destroy() {
103 if (DeclIndexPairVector *Vec
104 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
105 delete Vec;
106 DeclOrVector = ((NamedDecl *)0);
107 }
108 }
109
110 // Iteration.
111 class iterator;
112 iterator begin() const;
113 iterator end() const;
114 };
115
Douglas Gregor86d9a522009-09-21 16:56:56 +0000116 /// \brief A mapping from declaration names to the declarations that have
117 /// this name within a particular scope and their index within the list of
118 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000119 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000120
121 /// \brief The semantic analysis object for which results are being
122 /// produced.
123 Sema &SemaRef;
Douglas Gregor218937c2011-02-01 19:23:04 +0000124
125 /// \brief The allocator used to allocate new code-completion strings.
Douglas Gregordae68752011-02-01 22:57:45 +0000126 CodeCompletionAllocator &Allocator;
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +0000127
128 CodeCompletionTUInfo &CCTUInfo;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000129
130 /// \brief If non-NULL, a filter function used to remove any code-completion
131 /// results that are not desirable.
132 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000133
134 /// \brief Whether we should allow declarations as
135 /// nested-name-specifiers that would otherwise be filtered out.
136 bool AllowNestedNameSpecifiers;
137
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000138 /// \brief If set, the type that we would prefer our resulting value
139 /// declarations to have.
140 ///
141 /// Closely matching the preferred type gives a boost to a result's
142 /// priority.
143 CanQualType PreferredType;
144
Douglas Gregor86d9a522009-09-21 16:56:56 +0000145 /// \brief A list of shadow maps, which is used to model name hiding at
146 /// different levels of, e.g., the inheritance hierarchy.
147 std::list<ShadowMap> ShadowMaps;
148
Douglas Gregor3cdee122010-08-26 16:36:48 +0000149 /// \brief If we're potentially referring to a C++ member function, the set
150 /// of qualifiers applied to the object type.
151 Qualifiers ObjectTypeQualifiers;
152
153 /// \brief Whether the \p ObjectTypeQualifiers field is active.
154 bool HasObjectTypeQualifiers;
155
Douglas Gregor265f7492010-08-27 15:29:55 +0000156 /// \brief The selector that we prefer.
157 Selector PreferredSelector;
158
Douglas Gregorca45da02010-11-02 20:36:02 +0000159 /// \brief The completion context in which we are gathering results.
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000160 CodeCompletionContext CompletionContext;
161
James Dennetta40f7922012-06-14 03:11:41 +0000162 /// \brief If we are in an instance method definition, the \@implementation
Douglas Gregorca45da02010-11-02 20:36:02 +0000163 /// object.
164 ObjCImplementationDecl *ObjCImplementation;
Douglas Gregord1f09b42013-01-31 04:52:16 +0000165
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000166 void AdjustResultPriorityForDecl(Result &R);
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000167
Douglas Gregor6f942b22010-09-21 16:06:22 +0000168 void MaybeAddConstructorResults(Result R);
169
Douglas Gregor86d9a522009-09-21 16:56:56 +0000170 public:
Douglas Gregordae68752011-02-01 22:57:45 +0000171 explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +0000172 CodeCompletionTUInfo &CCTUInfo,
Douglas Gregor52779fb2010-09-23 23:01:17 +0000173 const CodeCompletionContext &CompletionContext,
174 LookupFilter Filter = 0)
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +0000175 : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo),
176 Filter(Filter),
Douglas Gregor218937c2011-02-01 19:23:04 +0000177 AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false),
Douglas Gregorca45da02010-11-02 20:36:02 +0000178 CompletionContext(CompletionContext),
179 ObjCImplementation(0)
180 {
181 // If this is an Objective-C instance method definition, dig out the
182 // corresponding implementation.
183 switch (CompletionContext.getKind()) {
184 case CodeCompletionContext::CCC_Expression:
185 case CodeCompletionContext::CCC_ObjCMessageReceiver:
186 case CodeCompletionContext::CCC_ParenthesizedExpression:
187 case CodeCompletionContext::CCC_Statement:
188 case CodeCompletionContext::CCC_Recovery:
189 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
190 if (Method->isInstanceMethod())
191 if (ObjCInterfaceDecl *Interface = Method->getClassInterface())
192 ObjCImplementation = Interface->getImplementation();
193 break;
194
195 default:
196 break;
197 }
198 }
Douglas Gregord1f09b42013-01-31 04:52:16 +0000199
200 /// \brief Determine the priority for a reference to the given declaration.
201 unsigned getBasePriority(const NamedDecl *D);
202
Douglas Gregord8e8a582010-05-25 21:41:55 +0000203 /// \brief Whether we should include code patterns in the completion
204 /// results.
205 bool includeCodePatterns() const {
206 return SemaRef.CodeCompleter &&
Douglas Gregorf6961522010-08-27 21:18:54 +0000207 SemaRef.CodeCompleter->includeCodePatterns();
Douglas Gregord8e8a582010-05-25 21:41:55 +0000208 }
209
Douglas Gregor86d9a522009-09-21 16:56:56 +0000210 /// \brief Set the filter used for code-completion results.
211 void setFilter(LookupFilter Filter) {
212 this->Filter = Filter;
213 }
214
Douglas Gregor86d9a522009-09-21 16:56:56 +0000215 Result *data() { return Results.empty()? 0 : &Results.front(); }
216 unsigned size() const { return Results.size(); }
217 bool empty() const { return Results.empty(); }
218
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000219 /// \brief Specify the preferred type.
220 void setPreferredType(QualType T) {
221 PreferredType = SemaRef.Context.getCanonicalType(T);
222 }
223
Douglas Gregor3cdee122010-08-26 16:36:48 +0000224 /// \brief Set the cv-qualifiers on the object type, for us in filtering
225 /// calls to member functions.
226 ///
227 /// When there are qualifiers in this set, they will be used to filter
228 /// out member functions that aren't available (because there will be a
229 /// cv-qualifier mismatch) or prefer functions with an exact qualifier
230 /// match.
231 void setObjectTypeQualifiers(Qualifiers Quals) {
232 ObjectTypeQualifiers = Quals;
233 HasObjectTypeQualifiers = true;
234 }
235
Douglas Gregor265f7492010-08-27 15:29:55 +0000236 /// \brief Set the preferred selector.
237 ///
238 /// When an Objective-C method declaration result is added, and that
239 /// method's selector matches this preferred selector, we give that method
240 /// a slight priority boost.
241 void setPreferredSelector(Selector Sel) {
242 PreferredSelector = Sel;
243 }
Douglas Gregorca45da02010-11-02 20:36:02 +0000244
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000245 /// \brief Retrieve the code-completion context for which results are
246 /// being collected.
247 const CodeCompletionContext &getCompletionContext() const {
248 return CompletionContext;
249 }
250
Douglas Gregor45bcd432010-01-14 03:21:49 +0000251 /// \brief Specify whether nested-name-specifiers are allowed.
252 void allowNestedNameSpecifiers(bool Allow = true) {
253 AllowNestedNameSpecifiers = Allow;
254 }
255
Douglas Gregorb9d77572010-09-21 00:03:25 +0000256 /// \brief Return the semantic analysis object for which we are collecting
257 /// code completion results.
258 Sema &getSema() const { return SemaRef; }
259
Douglas Gregor218937c2011-02-01 19:23:04 +0000260 /// \brief Retrieve the allocator used to allocate code completion strings.
Douglas Gregordae68752011-02-01 22:57:45 +0000261 CodeCompletionAllocator &getAllocator() const { return Allocator; }
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +0000262
263 CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
Douglas Gregor218937c2011-02-01 19:23:04 +0000264
Douglas Gregore495b7f2010-01-14 00:20:49 +0000265 /// \brief Determine whether the given declaration is at all interesting
266 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000267 ///
268 /// \param ND the declaration that we are inspecting.
269 ///
270 /// \param AsNestedNameSpecifier will be set true if this declaration is
271 /// only interesting when it is a nested-name-specifier.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000272 bool isInterestingDecl(const NamedDecl *ND,
273 bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000274
275 /// \brief Check whether the result is hidden by the Hiding declaration.
276 ///
277 /// \returns true if the result is hidden and cannot be found, false if
278 /// the hidden result could still be found. When false, \p R may be
279 /// modified to describe how the result can be found (e.g., via extra
280 /// qualification).
281 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000282 const NamedDecl *Hiding);
Douglas Gregor6660d842010-01-14 00:41:07 +0000283
Douglas Gregor86d9a522009-09-21 16:56:56 +0000284 /// \brief Add a new result to this result set (if it isn't already in one
285 /// of the shadow maps), or replace an existing result (for, e.g., a
286 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000287 ///
Douglas Gregor81f3bff2012-02-15 15:34:24 +0000288 /// \param R the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000289 ///
Douglas Gregor81f3bff2012-02-15 15:34:24 +0000290 /// \param CurContext the context in which this result will be named.
Douglas Gregor456c4a12009-09-21 20:12:40 +0000291 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000292
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000293 /// \brief Add a new result to this result set, where we already know
294 /// the hiding declation (if any).
295 ///
296 /// \param R the result to add (if it is unique).
297 ///
298 /// \param CurContext the context in which this result will be named.
299 ///
300 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000301 ///
302 /// \param InBaseClass whether the result was found in a base
303 /// class of the searched context.
304 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
305 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000306
Douglas Gregora4477812010-01-14 16:01:26 +0000307 /// \brief Add a new non-declaration result to this result set.
308 void AddResult(Result R);
309
Douglas Gregor86d9a522009-09-21 16:56:56 +0000310 /// \brief Enter into a new scope.
311 void EnterNewScope();
312
313 /// \brief Exit from the current scope.
314 void ExitScope();
315
Douglas Gregor55385fe2009-11-18 04:19:12 +0000316 /// \brief Ignore this declaration, if it is seen again.
317 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
318
Douglas Gregor86d9a522009-09-21 16:56:56 +0000319 /// \name Name lookup predicates
320 ///
321 /// These predicates can be passed to the name lookup functions to filter the
322 /// results of name lookup. All of the predicates have the same type, so that
323 ///
324 //@{
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000325 bool IsOrdinaryName(const NamedDecl *ND) const;
326 bool IsOrdinaryNonTypeName(const NamedDecl *ND) const;
327 bool IsIntegralConstantValue(const NamedDecl *ND) const;
328 bool IsOrdinaryNonValueName(const NamedDecl *ND) const;
329 bool IsNestedNameSpecifier(const NamedDecl *ND) const;
330 bool IsEnum(const NamedDecl *ND) const;
331 bool IsClassOrStruct(const NamedDecl *ND) const;
332 bool IsUnion(const NamedDecl *ND) const;
333 bool IsNamespace(const NamedDecl *ND) const;
334 bool IsNamespaceOrAlias(const NamedDecl *ND) const;
335 bool IsType(const NamedDecl *ND) const;
336 bool IsMember(const NamedDecl *ND) const;
337 bool IsObjCIvar(const NamedDecl *ND) const;
338 bool IsObjCMessageReceiver(const NamedDecl *ND) const;
339 bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const;
340 bool IsObjCCollection(const NamedDecl *ND) const;
341 bool IsImpossibleToSatisfy(const NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000342 //@}
343 };
344}
345
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000346class ResultBuilder::ShadowMapEntry::iterator {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000347 llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator;
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000348 unsigned SingleDeclIndex;
349
350public:
351 typedef DeclIndexPair value_type;
352 typedef value_type reference;
353 typedef std::ptrdiff_t difference_type;
354 typedef std::input_iterator_tag iterator_category;
355
356 class pointer {
357 DeclIndexPair Value;
358
359 public:
360 pointer(const DeclIndexPair &Value) : Value(Value) { }
361
362 const DeclIndexPair *operator->() const {
363 return &Value;
364 }
365 };
366
367 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
368
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000369 iterator(const NamedDecl *SingleDecl, unsigned Index)
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000370 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
371
372 iterator(const DeclIndexPair *Iterator)
373 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
374
375 iterator &operator++() {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000376 if (DeclOrIterator.is<const NamedDecl *>()) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000377 DeclOrIterator = (NamedDecl *)0;
378 SingleDeclIndex = 0;
379 return *this;
380 }
381
382 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
383 ++I;
384 DeclOrIterator = I;
385 return *this;
386 }
387
Chris Lattner66392d42010-09-04 18:12:20 +0000388 /*iterator operator++(int) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000389 iterator tmp(*this);
390 ++(*this);
391 return tmp;
Chris Lattner66392d42010-09-04 18:12:20 +0000392 }*/
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000393
394 reference operator*() const {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000395 if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>())
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000396 return reference(ND, SingleDeclIndex);
397
Douglas Gregord490f952009-12-06 21:27:58 +0000398 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000399 }
400
401 pointer operator->() const {
402 return pointer(**this);
403 }
404
405 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000406 return X.DeclOrIterator.getOpaqueValue()
407 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000408 X.SingleDeclIndex == Y.SingleDeclIndex;
409 }
410
411 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000412 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000413 }
414};
415
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000416ResultBuilder::ShadowMapEntry::iterator
417ResultBuilder::ShadowMapEntry::begin() const {
418 if (DeclOrVector.isNull())
419 return iterator();
420
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000421 if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>())
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000422 return iterator(ND, SingleDeclIndex);
423
424 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
425}
426
427ResultBuilder::ShadowMapEntry::iterator
428ResultBuilder::ShadowMapEntry::end() const {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000429 if (DeclOrVector.is<const NamedDecl *>() || DeclOrVector.isNull())
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000430 return iterator();
431
432 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
433}
434
Douglas Gregor456c4a12009-09-21 20:12:40 +0000435/// \brief Compute the qualification required to get from the current context
436/// (\p CurContext) to the target context (\p TargetContext).
437///
438/// \param Context the AST context in which the qualification will be used.
439///
440/// \param CurContext the context where an entity is being named, which is
441/// typically based on the current scope.
442///
443/// \param TargetContext the context in which the named entity actually
444/// resides.
445///
446/// \returns a nested name specifier that refers into the target context, or
447/// NULL if no qualification is needed.
448static NestedNameSpecifier *
449getRequiredQualification(ASTContext &Context,
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000450 const DeclContext *CurContext,
451 const DeclContext *TargetContext) {
452 SmallVector<const DeclContext *, 4> TargetParents;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000453
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000454 for (const DeclContext *CommonAncestor = TargetContext;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000455 CommonAncestor && !CommonAncestor->Encloses(CurContext);
456 CommonAncestor = CommonAncestor->getLookupParent()) {
457 if (CommonAncestor->isTransparentContext() ||
458 CommonAncestor->isFunctionOrMethod())
459 continue;
460
461 TargetParents.push_back(CommonAncestor);
462 }
463
464 NestedNameSpecifier *Result = 0;
465 while (!TargetParents.empty()) {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000466 const DeclContext *Parent = TargetParents.back();
Douglas Gregor456c4a12009-09-21 20:12:40 +0000467 TargetParents.pop_back();
468
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000469 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
Douglas Gregorfb629412010-08-23 21:17:50 +0000470 if (!Namespace->getIdentifier())
471 continue;
472
Douglas Gregor456c4a12009-09-21 20:12:40 +0000473 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000474 }
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000475 else if (const TagDecl *TD = dyn_cast<TagDecl>(Parent))
Douglas Gregor456c4a12009-09-21 20:12:40 +0000476 Result = NestedNameSpecifier::Create(Context, Result,
477 false,
478 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000479 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000480 return Result;
481}
482
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000483bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000484 bool &AsNestedNameSpecifier) const {
485 AsNestedNameSpecifier = false;
486
Douglas Gregore495b7f2010-01-14 00:20:49 +0000487 ND = ND->getUnderlyingDecl();
488 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000489
490 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000491 if (!ND->getDeclName())
492 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000493
494 // Friend declarations and declarations introduced due to friends are never
495 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000496 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000497 return false;
498
Douglas Gregor76282942009-12-11 17:31:05 +0000499 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000500 if (isa<ClassTemplateSpecializationDecl>(ND) ||
501 isa<ClassTemplatePartialSpecializationDecl>(ND))
502 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000503
Douglas Gregor76282942009-12-11 17:31:05 +0000504 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000505 if (isa<UsingDecl>(ND))
506 return false;
507
508 // Some declarations have reserved names that we don't want to ever show.
509 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000510 // __va_list_tag is a freak of nature. Find it and skip it.
511 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000512 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000513
Douglas Gregorf52cede2009-10-09 22:16:47 +0000514 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000515 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000516 //
517 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000518 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000519 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000520 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000521 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
522 (ND->getLocation().isInvalid() ||
523 SemaRef.SourceMgr.isInSystemHeader(
524 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000525 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000526 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000527 }
Douglas Gregor9b0ba872010-11-09 03:59:40 +0000528
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000529 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
530 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
531 Filter != &ResultBuilder::IsNamespace &&
Douglas Gregor52779fb2010-09-23 23:01:17 +0000532 Filter != &ResultBuilder::IsNamespaceOrAlias &&
533 Filter != 0))
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000534 AsNestedNameSpecifier = true;
535
Douglas Gregor86d9a522009-09-21 16:56:56 +0000536 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000537 if (Filter && !(this->*Filter)(ND)) {
538 // Check whether it is interesting as a nested-name-specifier.
David Blaikie4e4d0842012-03-11 07:00:24 +0000539 if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus &&
Douglas Gregor45bcd432010-01-14 03:21:49 +0000540 IsNestedNameSpecifier(ND) &&
541 (Filter != &ResultBuilder::IsMember ||
542 (isa<CXXRecordDecl>(ND) &&
543 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
544 AsNestedNameSpecifier = true;
545 return true;
546 }
547
Douglas Gregore495b7f2010-01-14 00:20:49 +0000548 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000549 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000550 // ... then it must be interesting!
551 return true;
552}
553
Douglas Gregor6660d842010-01-14 00:41:07 +0000554bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000555 const NamedDecl *Hiding) {
Douglas Gregor6660d842010-01-14 00:41:07 +0000556 // In C, there is no way to refer to a hidden name.
557 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
558 // name if we introduce the tag type.
David Blaikie4e4d0842012-03-11 07:00:24 +0000559 if (!SemaRef.getLangOpts().CPlusPlus)
Douglas Gregor6660d842010-01-14 00:41:07 +0000560 return true;
561
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000562 const DeclContext *HiddenCtx =
563 R.Declaration->getDeclContext()->getRedeclContext();
Douglas Gregor6660d842010-01-14 00:41:07 +0000564
565 // There is no way to qualify a name declared in a function or method.
566 if (HiddenCtx->isFunctionOrMethod())
567 return true;
568
Sebastian Redl7a126a42010-08-31 00:36:30 +0000569 if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
Douglas Gregor6660d842010-01-14 00:41:07 +0000570 return true;
571
572 // We can refer to the result with the appropriate qualification. Do it.
573 R.Hidden = true;
574 R.QualifierIsInformative = false;
575
576 if (!R.Qualifier)
577 R.Qualifier = getRequiredQualification(SemaRef.Context,
578 CurContext,
579 R.Declaration->getDeclContext());
580 return false;
581}
582
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000583/// \brief A simplified classification of types used to determine whether two
584/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000585SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000586 switch (T->getTypeClass()) {
587 case Type::Builtin:
588 switch (cast<BuiltinType>(T)->getKind()) {
589 case BuiltinType::Void:
590 return STC_Void;
591
592 case BuiltinType::NullPtr:
593 return STC_Pointer;
594
595 case BuiltinType::Overload:
596 case BuiltinType::Dependent:
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000597 return STC_Other;
598
599 case BuiltinType::ObjCId:
600 case BuiltinType::ObjCClass:
601 case BuiltinType::ObjCSel:
602 return STC_ObjectiveC;
603
604 default:
605 return STC_Arithmetic;
606 }
David Blaikie7530c032012-01-17 06:56:22 +0000607
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000608 case Type::Complex:
609 return STC_Arithmetic;
610
611 case Type::Pointer:
612 return STC_Pointer;
613
614 case Type::BlockPointer:
615 return STC_Block;
616
617 case Type::LValueReference:
618 case Type::RValueReference:
619 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
620
621 case Type::ConstantArray:
622 case Type::IncompleteArray:
623 case Type::VariableArray:
624 case Type::DependentSizedArray:
625 return STC_Array;
626
627 case Type::DependentSizedExtVector:
628 case Type::Vector:
629 case Type::ExtVector:
630 return STC_Arithmetic;
631
632 case Type::FunctionProto:
633 case Type::FunctionNoProto:
634 return STC_Function;
635
636 case Type::Record:
637 return STC_Record;
638
639 case Type::Enum:
640 return STC_Arithmetic;
641
642 case Type::ObjCObject:
643 case Type::ObjCInterface:
644 case Type::ObjCObjectPointer:
645 return STC_ObjectiveC;
646
647 default:
648 return STC_Other;
649 }
650}
651
652/// \brief Get the type that a given expression will have if this declaration
653/// is used as an expression in its "typical" code-completion form.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000654QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000655 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
656
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000657 if (const TypeDecl *Type = dyn_cast<TypeDecl>(ND))
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000658 return C.getTypeDeclType(Type);
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000659 if (const ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000660 return C.getObjCInterfaceType(Iface);
661
662 QualType T;
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000663 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000664 T = Function->getCallResultType();
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000665 else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000666 T = Method->getSendResultType();
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000667 else if (const FunctionTemplateDecl *FunTmpl =
668 dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000669 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000670 else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000671 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000672 else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000673 T = Property->getType();
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000674 else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND))
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000675 T = Value->getType();
676 else
677 return QualType();
Douglas Gregor3e64d562011-04-14 20:33:34 +0000678
679 // Dig through references, function pointers, and block pointers to
680 // get down to the likely type of an expression when the entity is
681 // used.
682 do {
683 if (const ReferenceType *Ref = T->getAs<ReferenceType>()) {
684 T = Ref->getPointeeType();
685 continue;
686 }
687
688 if (const PointerType *Pointer = T->getAs<PointerType>()) {
689 if (Pointer->getPointeeType()->isFunctionType()) {
690 T = Pointer->getPointeeType();
691 continue;
692 }
693
694 break;
695 }
696
697 if (const BlockPointerType *Block = T->getAs<BlockPointerType>()) {
698 T = Block->getPointeeType();
699 continue;
700 }
701
702 if (const FunctionType *Function = T->getAs<FunctionType>()) {
703 T = Function->getResultType();
704 continue;
705 }
706
707 break;
708 } while (true);
709
710 return T;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000711}
712
Douglas Gregord1f09b42013-01-31 04:52:16 +0000713unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) {
714 if (!ND)
715 return CCP_Unlikely;
716
717 // Context-based decisions.
718 const DeclContext *DC = ND->getDeclContext()->getRedeclContext();
719 if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC)) {
720 // _cmd is relatively rare
721 if (const ImplicitParamDecl *ImplicitParam =
722 dyn_cast<ImplicitParamDecl>(ND))
723 if (ImplicitParam->getIdentifier() &&
724 ImplicitParam->getIdentifier()->isStr("_cmd"))
725 return CCP_ObjC_cmd;
726
727 return CCP_LocalDeclaration;
728 }
729 if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
730 return CCP_MemberDeclaration;
731
732 // Content-based decisions.
733 if (isa<EnumConstantDecl>(ND))
734 return CCP_Constant;
735
736 if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)))
737 return CCP_Type;
738
739 return CCP_Declaration;
740}
741
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000742void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
743 // If this is an Objective-C method declaration whose selector matches our
744 // preferred selector, give it a priority boost.
745 if (!PreferredSelector.isNull())
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000746 if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000747 if (PreferredSelector == Method->getSelector())
748 R.Priority += CCD_SelectorMatch;
Douglas Gregor08f43cd2010-09-20 23:11:55 +0000749
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000750 // If we have a preferred type, adjust the priority for results with exactly-
751 // matching or nearly-matching types.
752 if (!PreferredType.isNull()) {
753 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
754 if (!T.isNull()) {
755 CanQualType TC = SemaRef.Context.getCanonicalType(T);
756 // Check for exactly-matching types (modulo qualifiers).
757 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
758 R.Priority /= CCF_ExactTypeMatch;
759 // Check for nearly-matching types, based on classification of each.
760 else if ((getSimplifiedTypeClass(PreferredType)
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000761 == getSimplifiedTypeClass(TC)) &&
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000762 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
763 R.Priority /= CCF_SimilarTypeMatch;
764 }
765 }
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000766}
767
Douglas Gregor6f942b22010-09-21 16:06:22 +0000768void ResultBuilder::MaybeAddConstructorResults(Result R) {
David Blaikie4e4d0842012-03-11 07:00:24 +0000769 if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration ||
Douglas Gregor6f942b22010-09-21 16:06:22 +0000770 !CompletionContext.wantConstructorResults())
771 return;
772
773 ASTContext &Context = SemaRef.Context;
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000774 const NamedDecl *D = R.Declaration;
775 const CXXRecordDecl *Record = 0;
776 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
Douglas Gregor6f942b22010-09-21 16:06:22 +0000777 Record = ClassTemplate->getTemplatedDecl();
778 else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
779 // Skip specializations and partial specializations.
780 if (isa<ClassTemplateSpecializationDecl>(Record))
781 return;
782 } else {
783 // There are no constructors here.
784 return;
785 }
786
787 Record = Record->getDefinition();
788 if (!Record)
789 return;
790
791
792 QualType RecordTy = Context.getTypeDeclType(Record);
793 DeclarationName ConstructorName
794 = Context.DeclarationNames.getCXXConstructorName(
795 Context.getCanonicalType(RecordTy));
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000796 DeclContext::lookup_const_result Ctors = Record->lookup(ConstructorName);
797 for (DeclContext::lookup_const_iterator I = Ctors.begin(),
798 E = Ctors.end();
799 I != E; ++I) {
David Blaikie3bc93e32012-12-19 00:45:41 +0000800 R.Declaration = *I;
Douglas Gregor6f942b22010-09-21 16:06:22 +0000801 R.CursorKind = getCursorKindForDecl(R.Declaration);
802 Results.push_back(R);
803 }
804}
805
Douglas Gregore495b7f2010-01-14 00:20:49 +0000806void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
807 assert(!ShadowMaps.empty() && "Must enter into a results scope");
808
809 if (R.Kind != Result::RK_Declaration) {
810 // For non-declaration results, just add the result.
811 Results.push_back(R);
812 return;
813 }
814
815 // Look through using declarations.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000816 if (const UsingShadowDecl *Using =
817 dyn_cast<UsingShadowDecl>(R.Declaration)) {
Douglas Gregord1f09b42013-01-31 04:52:16 +0000818 MaybeAddResult(Result(Using->getTargetDecl(),
819 getBasePriority(Using->getTargetDecl()),
820 R.Qualifier),
821 CurContext);
Douglas Gregore495b7f2010-01-14 00:20:49 +0000822 return;
823 }
824
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000825 const Decl *CanonDecl = R.Declaration->getCanonicalDecl();
Douglas Gregore495b7f2010-01-14 00:20:49 +0000826 unsigned IDNS = CanonDecl->getIdentifierNamespace();
827
Douglas Gregor45bcd432010-01-14 03:21:49 +0000828 bool AsNestedNameSpecifier = false;
829 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000830 return;
831
Douglas Gregor6f942b22010-09-21 16:06:22 +0000832 // C++ constructors are never found by name lookup.
833 if (isa<CXXConstructorDecl>(R.Declaration))
834 return;
835
Douglas Gregor86d9a522009-09-21 16:56:56 +0000836 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000837 ShadowMapEntry::iterator I, IEnd;
838 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
839 if (NamePos != SMap.end()) {
840 I = NamePos->second.begin();
841 IEnd = NamePos->second.end();
842 }
843
844 for (; I != IEnd; ++I) {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000845 const NamedDecl *ND = I->first;
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000846 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000847 if (ND->getCanonicalDecl() == CanonDecl) {
848 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000849 Results[Index].Declaration = R.Declaration;
850
Douglas Gregor86d9a522009-09-21 16:56:56 +0000851 // We're done.
852 return;
853 }
854 }
855
856 // This is a new declaration in this scope. However, check whether this
857 // declaration name is hidden by a similarly-named declaration in an outer
858 // scope.
859 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
860 --SMEnd;
861 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000862 ShadowMapEntry::iterator I, IEnd;
863 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
864 if (NamePos != SM->end()) {
865 I = NamePos->second.begin();
866 IEnd = NamePos->second.end();
867 }
868 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000869 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000870 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000871 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
872 Decl::IDNS_ObjCProtocol)))
873 continue;
874
875 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000876 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000877 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000878 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000879 continue;
880
881 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000882 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000883 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000884
885 break;
886 }
887 }
888
889 // Make sure that any given declaration only shows up in the result set once.
890 if (!AllDeclsFound.insert(CanonDecl))
891 return;
Douglas Gregor265f7492010-08-27 15:29:55 +0000892
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000893 // If the filter is for nested-name-specifiers, then this result starts a
894 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000895 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000896 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000897 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000898 } else
899 AdjustResultPriorityForDecl(R);
Douglas Gregor265f7492010-08-27 15:29:55 +0000900
Douglas Gregor0563c262009-09-22 23:15:58 +0000901 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000902 if (R.QualifierIsInformative && !R.Qualifier &&
903 !R.StartsNestedNameSpecifier) {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000904 const DeclContext *Ctx = R.Declaration->getDeclContext();
905 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
Douglas Gregor0563c262009-09-22 23:15:58 +0000906 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000907 else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
Douglas Gregor0563c262009-09-22 23:15:58 +0000908 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
909 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
910 else
911 R.QualifierIsInformative = false;
912 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000913
Douglas Gregor86d9a522009-09-21 16:56:56 +0000914 // Insert this result into the set of results and into the current shadow
915 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000916 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000917 Results.push_back(R);
Douglas Gregor6f942b22010-09-21 16:06:22 +0000918
919 if (!AsNestedNameSpecifier)
920 MaybeAddConstructorResults(R);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000921}
922
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000923void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000924 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000925 if (R.Kind != Result::RK_Declaration) {
926 // For non-declaration results, just add the result.
927 Results.push_back(R);
928 return;
929 }
930
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000931 // Look through using declarations.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000932 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
Douglas Gregord1f09b42013-01-31 04:52:16 +0000933 AddResult(Result(Using->getTargetDecl(),
934 getBasePriority(Using->getTargetDecl()),
935 R.Qualifier),
936 CurContext, Hiding);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000937 return;
938 }
939
Douglas Gregor45bcd432010-01-14 03:21:49 +0000940 bool AsNestedNameSpecifier = false;
941 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000942 return;
943
Douglas Gregor6f942b22010-09-21 16:06:22 +0000944 // C++ constructors are never found by name lookup.
945 if (isa<CXXConstructorDecl>(R.Declaration))
946 return;
947
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000948 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
949 return;
Nick Lewycky173a37a2012-04-03 21:44:08 +0000950
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000951 // Make sure that any given declaration only shows up in the result set once.
952 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
953 return;
954
955 // If the filter is for nested-name-specifiers, then this result starts a
956 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000957 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000958 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000959 R.Priority = CCP_NestedNameSpecifier;
960 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000961 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
962 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
Sebastian Redl7a126a42010-08-31 00:36:30 +0000963 ->getRedeclContext()))
Douglas Gregor0cc84042010-01-14 15:47:35 +0000964 R.QualifierIsInformative = true;
965
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000966 // If this result is supposed to have an informative qualifier, add one.
967 if (R.QualifierIsInformative && !R.Qualifier &&
968 !R.StartsNestedNameSpecifier) {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000969 const DeclContext *Ctx = R.Declaration->getDeclContext();
970 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000971 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000972 else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000973 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000974 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000975 else
976 R.QualifierIsInformative = false;
977 }
978
Douglas Gregor12e13132010-05-26 22:00:08 +0000979 // Adjust the priority if this result comes from a base class.
980 if (InBaseClass)
981 R.Priority += CCD_InBaseClass;
982
Douglas Gregorcee9ff12010-09-20 22:39:41 +0000983 AdjustResultPriorityForDecl(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000984
Douglas Gregor3cdee122010-08-26 16:36:48 +0000985 if (HasObjectTypeQualifiers)
Dmitri Gribenko89cf4252013-01-23 17:21:11 +0000986 if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
Douglas Gregor3cdee122010-08-26 16:36:48 +0000987 if (Method->isInstance()) {
988 Qualifiers MethodQuals
989 = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
990 if (ObjectTypeQualifiers == MethodQuals)
991 R.Priority += CCD_ObjectQualifierMatch;
992 else if (ObjectTypeQualifiers - MethodQuals) {
993 // The method cannot be invoked, because doing so would drop
994 // qualifiers.
995 return;
996 }
997 }
998
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000999 // Insert this result into the set of results.
1000 Results.push_back(R);
Douglas Gregor6f942b22010-09-21 16:06:22 +00001001
1002 if (!AsNestedNameSpecifier)
1003 MaybeAddConstructorResults(R);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001004}
1005
Douglas Gregora4477812010-01-14 16:01:26 +00001006void ResultBuilder::AddResult(Result R) {
1007 assert(R.Kind != Result::RK_Declaration &&
1008 "Declaration results need more context");
1009 Results.push_back(R);
1010}
1011
Douglas Gregor86d9a522009-09-21 16:56:56 +00001012/// \brief Enter into a new scope.
1013void ResultBuilder::EnterNewScope() {
1014 ShadowMaps.push_back(ShadowMap());
1015}
1016
1017/// \brief Exit from the current scope.
1018void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +00001019 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
1020 EEnd = ShadowMaps.back().end();
1021 E != EEnd;
1022 ++E)
1023 E->second.Destroy();
1024
Douglas Gregor86d9a522009-09-21 16:56:56 +00001025 ShadowMaps.pop_back();
1026}
1027
Douglas Gregor791215b2009-09-21 20:51:25 +00001028/// \brief Determines whether this given declaration will be found by
1029/// ordinary name lookup.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001030bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001031 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1032
Douglas Gregor791215b2009-09-21 20:51:25 +00001033 unsigned IDNS = Decl::IDNS_Ordinary;
David Blaikie4e4d0842012-03-11 07:00:24 +00001034 if (SemaRef.getLangOpts().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +00001035 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
David Blaikie4e4d0842012-03-11 07:00:24 +00001036 else if (SemaRef.getLangOpts().ObjC1) {
Douglas Gregorca45da02010-11-02 20:36:02 +00001037 if (isa<ObjCIvarDecl>(ND))
1038 return true;
Douglas Gregorca45da02010-11-02 20:36:02 +00001039 }
1040
Douglas Gregor791215b2009-09-21 20:51:25 +00001041 return ND->getIdentifierNamespace() & IDNS;
1042}
1043
Douglas Gregor01dfea02010-01-10 23:08:15 +00001044/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001045/// ordinary name lookup but is not a type name.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001046bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001047 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1048 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
1049 return false;
1050
1051 unsigned IDNS = Decl::IDNS_Ordinary;
David Blaikie4e4d0842012-03-11 07:00:24 +00001052 if (SemaRef.getLangOpts().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +00001053 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
David Blaikie4e4d0842012-03-11 07:00:24 +00001054 else if (SemaRef.getLangOpts().ObjC1) {
Douglas Gregorca45da02010-11-02 20:36:02 +00001055 if (isa<ObjCIvarDecl>(ND))
1056 return true;
Douglas Gregorca45da02010-11-02 20:36:02 +00001057 }
1058
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001059 return ND->getIdentifierNamespace() & IDNS;
1060}
1061
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001062bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const {
Douglas Gregorf9578432010-07-28 21:50:18 +00001063 if (!IsOrdinaryNonTypeName(ND))
1064 return 0;
1065
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001066 if (const ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
Douglas Gregorf9578432010-07-28 21:50:18 +00001067 if (VD->getType()->isIntegralOrEnumerationType())
1068 return true;
1069
1070 return false;
1071}
1072
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001073/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +00001074/// ordinary name lookup.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001075bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001076 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1077
Douglas Gregor01dfea02010-01-10 23:08:15 +00001078 unsigned IDNS = Decl::IDNS_Ordinary;
David Blaikie4e4d0842012-03-11 07:00:24 +00001079 if (SemaRef.getLangOpts().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +00001080 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001081
1082 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001083 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
1084 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001085}
1086
Douglas Gregor86d9a522009-09-21 16:56:56 +00001087/// \brief Determines whether the given declaration is suitable as the
1088/// start of a C++ nested-name-specifier, e.g., a class or namespace.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001089bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001090 // Allow us to find class templates, too.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001091 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
Douglas Gregor86d9a522009-09-21 16:56:56 +00001092 ND = ClassTemplate->getTemplatedDecl();
1093
1094 return SemaRef.isAcceptableNestedNameSpecifier(ND);
1095}
1096
1097/// \brief Determines whether the given declaration is an enumeration.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001098bool ResultBuilder::IsEnum(const NamedDecl *ND) const {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001099 return isa<EnumDecl>(ND);
1100}
1101
1102/// \brief Determines whether the given declaration is a class or struct.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001103bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001104 // Allow us to find class templates, too.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001105 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
Douglas Gregor86d9a522009-09-21 16:56:56 +00001106 ND = ClassTemplate->getTemplatedDecl();
Joao Matos6666ed42012-08-31 18:45:21 +00001107
1108 // For purposes of this check, interfaces match too.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001109 if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +00001110 return RD->getTagKind() == TTK_Class ||
Joao Matos6666ed42012-08-31 18:45:21 +00001111 RD->getTagKind() == TTK_Struct ||
1112 RD->getTagKind() == TTK_Interface;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001113
1114 return false;
1115}
1116
1117/// \brief Determines whether the given declaration is a union.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001118bool ResultBuilder::IsUnion(const NamedDecl *ND) const {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001119 // Allow us to find class templates, too.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001120 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
Douglas Gregor86d9a522009-09-21 16:56:56 +00001121 ND = ClassTemplate->getTemplatedDecl();
1122
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001123 if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +00001124 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001125
1126 return false;
1127}
1128
1129/// \brief Determines whether the given declaration is a namespace.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001130bool ResultBuilder::IsNamespace(const NamedDecl *ND) const {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001131 return isa<NamespaceDecl>(ND);
1132}
1133
1134/// \brief Determines whether the given declaration is a namespace or
1135/// namespace alias.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001136bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001137 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
1138}
1139
Douglas Gregor76282942009-12-11 17:31:05 +00001140/// \brief Determines whether the given declaration is a type.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001141bool ResultBuilder::IsType(const NamedDecl *ND) const {
1142 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
Douglas Gregord32b0222010-08-24 01:06:58 +00001143 ND = Using->getTargetDecl();
1144
1145 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001146}
1147
Douglas Gregor76282942009-12-11 17:31:05 +00001148/// \brief Determines which members of a class should be visible via
1149/// "." or "->". Only value declarations, nested name specifiers, and
1150/// using declarations thereof should show up.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001151bool ResultBuilder::IsMember(const NamedDecl *ND) const {
1152 if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
Douglas Gregor76282942009-12-11 17:31:05 +00001153 ND = Using->getTargetDecl();
1154
Douglas Gregorce821962009-12-11 18:14:22 +00001155 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1156 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001157}
1158
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001159static bool isObjCReceiverType(ASTContext &C, QualType T) {
1160 T = C.getCanonicalType(T);
1161 switch (T->getTypeClass()) {
1162 case Type::ObjCObject:
1163 case Type::ObjCInterface:
1164 case Type::ObjCObjectPointer:
1165 return true;
1166
1167 case Type::Builtin:
1168 switch (cast<BuiltinType>(T)->getKind()) {
1169 case BuiltinType::ObjCId:
1170 case BuiltinType::ObjCClass:
1171 case BuiltinType::ObjCSel:
1172 return true;
1173
1174 default:
1175 break;
1176 }
1177 return false;
1178
1179 default:
1180 break;
1181 }
1182
David Blaikie4e4d0842012-03-11 07:00:24 +00001183 if (!C.getLangOpts().CPlusPlus)
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001184 return false;
1185
1186 // FIXME: We could perform more analysis here to determine whether a
1187 // particular class type has any conversions to Objective-C types. For now,
1188 // just accept all class types.
1189 return T->isDependentType() || T->isRecordType();
1190}
1191
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001192bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001193 QualType T = getDeclUsageType(SemaRef.Context, ND);
1194 if (T.isNull())
1195 return false;
1196
1197 T = SemaRef.Context.getBaseElementType(T);
1198 return isObjCReceiverType(SemaRef.Context, T);
1199}
1200
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001201bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const {
Douglas Gregor81f3bff2012-02-15 15:34:24 +00001202 if (IsObjCMessageReceiver(ND))
1203 return true;
1204
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001205 const VarDecl *Var = dyn_cast<VarDecl>(ND);
Douglas Gregor81f3bff2012-02-15 15:34:24 +00001206 if (!Var)
1207 return false;
1208
1209 return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>();
1210}
1211
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001212bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {
David Blaikie4e4d0842012-03-11 07:00:24 +00001213 if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) ||
1214 (!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
Douglas Gregorfb629412010-08-23 21:17:50 +00001215 return false;
1216
1217 QualType T = getDeclUsageType(SemaRef.Context, ND);
1218 if (T.isNull())
1219 return false;
1220
1221 T = SemaRef.Context.getBaseElementType(T);
1222 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1223 T->isObjCIdType() ||
David Blaikie4e4d0842012-03-11 07:00:24 +00001224 (SemaRef.getLangOpts().CPlusPlus && T->isRecordType());
Douglas Gregorfb629412010-08-23 21:17:50 +00001225}
Douglas Gregor8e254cf2010-05-27 23:06:34 +00001226
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001227bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const {
Douglas Gregor52779fb2010-09-23 23:01:17 +00001228 return false;
1229}
1230
James Dennettde23c7e2012-06-17 05:33:25 +00001231/// \brief Determines whether the given declaration is an Objective-C
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001232/// instance variable.
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00001233bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const {
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00001234 return isa<ObjCIvarDecl>(ND);
1235}
1236
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001237namespace {
1238 /// \brief Visible declaration consumer that adds a code-completion result
1239 /// for each visible declaration.
1240 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1241 ResultBuilder &Results;
1242 DeclContext *CurContext;
1243
1244 public:
1245 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1246 : Results(Results), CurContext(CurContext) { }
1247
Erik Verbruggend1205962011-10-06 07:27:49 +00001248 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
1249 bool InBaseClass) {
1250 bool Accessible = true;
Douglas Gregor17015ef2011-11-03 16:51:37 +00001251 if (Ctx)
1252 Accessible = Results.getSema().IsSimplyAccessible(ND, Ctx);
1253
Douglas Gregord1f09b42013-01-31 04:52:16 +00001254 ResultBuilder::Result Result(ND, Results.getBasePriority(ND), 0, false,
1255 Accessible);
Erik Verbruggend1205962011-10-06 07:27:49 +00001256 Results.AddResult(Result, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001257 }
1258 };
1259}
1260
Douglas Gregor86d9a522009-09-21 16:56:56 +00001261/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001262static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001263 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001264 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001265 Results.AddResult(Result("short", CCP_Type));
1266 Results.AddResult(Result("long", CCP_Type));
1267 Results.AddResult(Result("signed", CCP_Type));
1268 Results.AddResult(Result("unsigned", CCP_Type));
1269 Results.AddResult(Result("void", CCP_Type));
1270 Results.AddResult(Result("char", CCP_Type));
1271 Results.AddResult(Result("int", CCP_Type));
1272 Results.AddResult(Result("float", CCP_Type));
1273 Results.AddResult(Result("double", CCP_Type));
1274 Results.AddResult(Result("enum", CCP_Type));
1275 Results.AddResult(Result("struct", CCP_Type));
1276 Results.AddResult(Result("union", CCP_Type));
1277 Results.AddResult(Result("const", CCP_Type));
1278 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001279
Douglas Gregor86d9a522009-09-21 16:56:56 +00001280 if (LangOpts.C99) {
1281 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001282 Results.AddResult(Result("_Complex", CCP_Type));
1283 Results.AddResult(Result("_Imaginary", CCP_Type));
1284 Results.AddResult(Result("_Bool", CCP_Type));
1285 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001286 }
1287
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00001288 CodeCompletionBuilder Builder(Results.getAllocator(),
1289 Results.getCodeCompletionTUInfo());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001290 if (LangOpts.CPlusPlus) {
1291 // C++-specific
Douglas Gregorb05496d2010-09-20 21:11:48 +00001292 Results.AddResult(Result("bool", CCP_Type +
1293 (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
Douglas Gregor12e13132010-05-26 22:00:08 +00001294 Results.AddResult(Result("class", CCP_Type));
1295 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001296
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001297 // typename qualified-id
Douglas Gregor218937c2011-02-01 19:23:04 +00001298 Builder.AddTypedTextChunk("typename");
1299 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1300 Builder.AddPlaceholderChunk("qualifier");
1301 Builder.AddTextChunk("::");
1302 Builder.AddPlaceholderChunk("name");
1303 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001304
Richard Smith80ad52f2013-01-02 11:42:31 +00001305 if (LangOpts.CPlusPlus11) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001306 Results.AddResult(Result("auto", CCP_Type));
1307 Results.AddResult(Result("char16_t", CCP_Type));
1308 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001309
Douglas Gregor218937c2011-02-01 19:23:04 +00001310 Builder.AddTypedTextChunk("decltype");
1311 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1312 Builder.AddPlaceholderChunk("expression");
1313 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1314 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001315 }
1316 }
1317
1318 // GNU extensions
1319 if (LangOpts.GNUMode) {
1320 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001321 // Results.AddResult(Result("_Decimal32"));
1322 // Results.AddResult(Result("_Decimal64"));
1323 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001324
Douglas Gregor218937c2011-02-01 19:23:04 +00001325 Builder.AddTypedTextChunk("typeof");
1326 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1327 Builder.AddPlaceholderChunk("expression");
1328 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001329
Douglas Gregor218937c2011-02-01 19:23:04 +00001330 Builder.AddTypedTextChunk("typeof");
1331 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1332 Builder.AddPlaceholderChunk("type");
1333 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1334 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001335 }
1336}
1337
John McCallf312b1e2010-08-26 23:41:50 +00001338static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001339 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001340 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001341 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001342 // Note: we don't suggest either "auto" or "register", because both
1343 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1344 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001345 Results.AddResult(Result("extern"));
1346 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001347}
1348
John McCallf312b1e2010-08-26 23:41:50 +00001349static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001350 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001351 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001352 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001353 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001354 case Sema::PCC_Class:
1355 case Sema::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001356 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001357 Results.AddResult(Result("explicit"));
1358 Results.AddResult(Result("friend"));
1359 Results.AddResult(Result("mutable"));
1360 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001361 }
1362 // Fall through
1363
John McCallf312b1e2010-08-26 23:41:50 +00001364 case Sema::PCC_ObjCInterface:
1365 case Sema::PCC_ObjCImplementation:
1366 case Sema::PCC_Namespace:
1367 case Sema::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001368 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001369 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001370 break;
1371
John McCallf312b1e2010-08-26 23:41:50 +00001372 case Sema::PCC_ObjCInstanceVariableList:
1373 case Sema::PCC_Expression:
1374 case Sema::PCC_Statement:
1375 case Sema::PCC_ForInit:
1376 case Sema::PCC_Condition:
1377 case Sema::PCC_RecoveryInFunction:
1378 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001379 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00001380 case Sema::PCC_LocalDeclarationSpecifiers:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001381 break;
1382 }
1383}
1384
Douglas Gregorbca403c2010-01-13 23:51:12 +00001385static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1386static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1387static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001388 ResultBuilder &Results,
1389 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001390static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001391 ResultBuilder &Results,
1392 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001393static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001394 ResultBuilder &Results,
1395 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001396static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001397
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001398static void AddTypedefResult(ResultBuilder &Results) {
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00001399 CodeCompletionBuilder Builder(Results.getAllocator(),
1400 Results.getCodeCompletionTUInfo());
Douglas Gregor218937c2011-02-01 19:23:04 +00001401 Builder.AddTypedTextChunk("typedef");
1402 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1403 Builder.AddPlaceholderChunk("type");
1404 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1405 Builder.AddPlaceholderChunk("name");
1406 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001407}
1408
John McCallf312b1e2010-08-26 23:41:50 +00001409static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001410 const LangOptions &LangOpts) {
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001411 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001412 case Sema::PCC_Namespace:
1413 case Sema::PCC_Class:
1414 case Sema::PCC_ObjCInstanceVariableList:
1415 case Sema::PCC_Template:
1416 case Sema::PCC_MemberTemplate:
1417 case Sema::PCC_Statement:
1418 case Sema::PCC_RecoveryInFunction:
1419 case Sema::PCC_Type:
Douglas Gregor02688102010-09-14 23:59:36 +00001420 case Sema::PCC_ParenthesizedExpression:
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00001421 case Sema::PCC_LocalDeclarationSpecifiers:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001422 return true;
1423
John McCallf312b1e2010-08-26 23:41:50 +00001424 case Sema::PCC_Expression:
1425 case Sema::PCC_Condition:
Douglas Gregor02688102010-09-14 23:59:36 +00001426 return LangOpts.CPlusPlus;
1427
1428 case Sema::PCC_ObjCInterface:
1429 case Sema::PCC_ObjCImplementation:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001430 return false;
1431
John McCallf312b1e2010-08-26 23:41:50 +00001432 case Sema::PCC_ForInit:
Douglas Gregor02688102010-09-14 23:59:36 +00001433 return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001434 }
David Blaikie7530c032012-01-17 06:56:22 +00001435
1436 llvm_unreachable("Invalid ParserCompletionContext!");
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001437}
1438
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00001439static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
1440 const Preprocessor &PP) {
1441 PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP);
Douglas Gregor8ca72082011-10-18 21:20:17 +00001442 Policy.AnonymousTagLocations = false;
1443 Policy.SuppressStrongLifetime = true;
Douglas Gregor25270b62011-11-03 00:16:13 +00001444 Policy.SuppressUnwrittenScope = true;
Douglas Gregor8ca72082011-10-18 21:20:17 +00001445 return Policy;
1446}
1447
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00001448/// \brief Retrieve a printing policy suitable for code completion.
1449static PrintingPolicy getCompletionPrintingPolicy(Sema &S) {
1450 return getCompletionPrintingPolicy(S.Context, S.PP);
1451}
1452
Douglas Gregor8ca72082011-10-18 21:20:17 +00001453/// \brief Retrieve the string representation of the given type as a string
1454/// that has the appropriate lifetime for code completion.
1455///
1456/// This routine provides a fast path where we provide constant strings for
1457/// common type names.
1458static const char *GetCompletionTypeString(QualType T,
1459 ASTContext &Context,
1460 const PrintingPolicy &Policy,
1461 CodeCompletionAllocator &Allocator) {
1462 if (!T.getLocalQualifiers()) {
1463 // Built-in type names are constant strings.
1464 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T))
Argyrios Kyrtzidis27a00972012-05-05 04:20:28 +00001465 return BT->getNameAsCString(Policy);
Douglas Gregor8ca72082011-10-18 21:20:17 +00001466
1467 // Anonymous tag types are constant strings.
1468 if (const TagType *TagT = dyn_cast<TagType>(T))
1469 if (TagDecl *Tag = TagT->getDecl())
1470 if (!Tag->getIdentifier() && !Tag->getTypedefNameForAnonDecl()) {
1471 switch (Tag->getTagKind()) {
1472 case TTK_Struct: return "struct <anonymous>";
Joao Matos6666ed42012-08-31 18:45:21 +00001473 case TTK_Interface: return "__interface <anonymous>";
1474 case TTK_Class: return "class <anonymous>";
Douglas Gregor8ca72082011-10-18 21:20:17 +00001475 case TTK_Union: return "union <anonymous>";
1476 case TTK_Enum: return "enum <anonymous>";
1477 }
1478 }
1479 }
1480
1481 // Slow path: format the type as a string.
1482 std::string Result;
1483 T.getAsStringInternal(Result, Policy);
1484 return Allocator.CopyString(Result);
1485}
1486
Douglas Gregor81f3bff2012-02-15 15:34:24 +00001487/// \brief Add a completion for "this", if we're in a member function.
1488static void addThisCompletion(Sema &S, ResultBuilder &Results) {
1489 QualType ThisTy = S.getCurrentThisType();
1490 if (ThisTy.isNull())
1491 return;
1492
1493 CodeCompletionAllocator &Allocator = Results.getAllocator();
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00001494 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
Douglas Gregor81f3bff2012-02-15 15:34:24 +00001495 PrintingPolicy Policy = getCompletionPrintingPolicy(S);
1496 Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy,
1497 S.Context,
1498 Policy,
1499 Allocator));
1500 Builder.AddTypedTextChunk("this");
Joao Matos6666ed42012-08-31 18:45:21 +00001501 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
Douglas Gregor81f3bff2012-02-15 15:34:24 +00001502}
1503
Douglas Gregor01dfea02010-01-10 23:08:15 +00001504/// \brief Add language constructs that show up for "ordinary" names.
John McCallf312b1e2010-08-26 23:41:50 +00001505static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001506 Scope *S,
1507 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001508 ResultBuilder &Results) {
Douglas Gregor8ca72082011-10-18 21:20:17 +00001509 CodeCompletionAllocator &Allocator = Results.getAllocator();
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00001510 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
Douglas Gregor8ca72082011-10-18 21:20:17 +00001511 PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef);
Douglas Gregor218937c2011-02-01 19:23:04 +00001512
John McCall0a2c5e22010-08-25 06:19:51 +00001513 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001514 switch (CCC) {
John McCallf312b1e2010-08-26 23:41:50 +00001515 case Sema::PCC_Namespace:
David Blaikie4e4d0842012-03-11 07:00:24 +00001516 if (SemaRef.getLangOpts().CPlusPlus) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001517 if (Results.includeCodePatterns()) {
1518 // namespace <identifier> { declarations }
Douglas Gregor218937c2011-02-01 19:23:04 +00001519 Builder.AddTypedTextChunk("namespace");
1520 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1521 Builder.AddPlaceholderChunk("identifier");
1522 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1523 Builder.AddPlaceholderChunk("declarations");
1524 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1525 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1526 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001527 }
1528
Douglas Gregor01dfea02010-01-10 23:08:15 +00001529 // namespace identifier = identifier ;
Douglas Gregor218937c2011-02-01 19:23:04 +00001530 Builder.AddTypedTextChunk("namespace");
1531 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1532 Builder.AddPlaceholderChunk("name");
1533 Builder.AddChunk(CodeCompletionString::CK_Equal);
1534 Builder.AddPlaceholderChunk("namespace");
1535 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001536
1537 // Using directives
Douglas Gregor218937c2011-02-01 19:23:04 +00001538 Builder.AddTypedTextChunk("using");
1539 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1540 Builder.AddTextChunk("namespace");
1541 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1542 Builder.AddPlaceholderChunk("identifier");
1543 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001544
1545 // asm(string-literal)
Douglas Gregor218937c2011-02-01 19:23:04 +00001546 Builder.AddTypedTextChunk("asm");
1547 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1548 Builder.AddPlaceholderChunk("string-literal");
1549 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1550 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001551
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001552 if (Results.includeCodePatterns()) {
1553 // Explicit template instantiation
Douglas Gregor218937c2011-02-01 19:23:04 +00001554 Builder.AddTypedTextChunk("template");
1555 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1556 Builder.AddPlaceholderChunk("declaration");
1557 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001558 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001559 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001560
David Blaikie4e4d0842012-03-11 07:00:24 +00001561 if (SemaRef.getLangOpts().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001562 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001563
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001564 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001565 // Fall through
1566
John McCallf312b1e2010-08-26 23:41:50 +00001567 case Sema::PCC_Class:
David Blaikie4e4d0842012-03-11 07:00:24 +00001568 if (SemaRef.getLangOpts().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001569 // Using declaration
Douglas Gregor218937c2011-02-01 19:23:04 +00001570 Builder.AddTypedTextChunk("using");
1571 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1572 Builder.AddPlaceholderChunk("qualifier");
1573 Builder.AddTextChunk("::");
1574 Builder.AddPlaceholderChunk("name");
1575 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001576
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001577 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001578 if (SemaRef.CurContext->isDependentContext()) {
Douglas Gregor218937c2011-02-01 19:23:04 +00001579 Builder.AddTypedTextChunk("using");
1580 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1581 Builder.AddTextChunk("typename");
1582 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1583 Builder.AddPlaceholderChunk("qualifier");
1584 Builder.AddTextChunk("::");
1585 Builder.AddPlaceholderChunk("name");
1586 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001587 }
1588
John McCallf312b1e2010-08-26 23:41:50 +00001589 if (CCC == Sema::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001590 AddTypedefResult(Results);
1591
Douglas Gregor01dfea02010-01-10 23:08:15 +00001592 // public:
Douglas Gregor218937c2011-02-01 19:23:04 +00001593 Builder.AddTypedTextChunk("public");
Douglas Gregor10ccf122012-04-10 17:56:28 +00001594 if (Results.includeCodePatterns())
1595 Builder.AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor218937c2011-02-01 19:23:04 +00001596 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001597
1598 // protected:
Douglas Gregor218937c2011-02-01 19:23:04 +00001599 Builder.AddTypedTextChunk("protected");
Douglas Gregor10ccf122012-04-10 17:56:28 +00001600 if (Results.includeCodePatterns())
1601 Builder.AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor218937c2011-02-01 19:23:04 +00001602 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001603
1604 // private:
Douglas Gregor218937c2011-02-01 19:23:04 +00001605 Builder.AddTypedTextChunk("private");
Douglas Gregor10ccf122012-04-10 17:56:28 +00001606 if (Results.includeCodePatterns())
1607 Builder.AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor218937c2011-02-01 19:23:04 +00001608 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001609 }
1610 }
1611 // Fall through
1612
John McCallf312b1e2010-08-26 23:41:50 +00001613 case Sema::PCC_Template:
1614 case Sema::PCC_MemberTemplate:
David Blaikie4e4d0842012-03-11 07:00:24 +00001615 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001616 // template < parameters >
Douglas Gregor218937c2011-02-01 19:23:04 +00001617 Builder.AddTypedTextChunk("template");
1618 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1619 Builder.AddPlaceholderChunk("parameters");
1620 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1621 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001622 }
1623
David Blaikie4e4d0842012-03-11 07:00:24 +00001624 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1625 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001626 break;
1627
John McCallf312b1e2010-08-26 23:41:50 +00001628 case Sema::PCC_ObjCInterface:
David Blaikie4e4d0842012-03-11 07:00:24 +00001629 AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true);
1630 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1631 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001632 break;
1633
John McCallf312b1e2010-08-26 23:41:50 +00001634 case Sema::PCC_ObjCImplementation:
David Blaikie4e4d0842012-03-11 07:00:24 +00001635 AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true);
1636 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1637 AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001638 break;
1639
John McCallf312b1e2010-08-26 23:41:50 +00001640 case Sema::PCC_ObjCInstanceVariableList:
David Blaikie4e4d0842012-03-11 07:00:24 +00001641 AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001642 break;
1643
John McCallf312b1e2010-08-26 23:41:50 +00001644 case Sema::PCC_RecoveryInFunction:
1645 case Sema::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001646 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001647
David Blaikie4e4d0842012-03-11 07:00:24 +00001648 if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() &&
1649 SemaRef.getLangOpts().CXXExceptions) {
Douglas Gregor218937c2011-02-01 19:23:04 +00001650 Builder.AddTypedTextChunk("try");
1651 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1652 Builder.AddPlaceholderChunk("statements");
1653 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1654 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1655 Builder.AddTextChunk("catch");
1656 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1657 Builder.AddPlaceholderChunk("declaration");
1658 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1659 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1660 Builder.AddPlaceholderChunk("statements");
1661 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1662 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1663 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001664 }
David Blaikie4e4d0842012-03-11 07:00:24 +00001665 if (SemaRef.getLangOpts().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001666 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001667
Douglas Gregord8e8a582010-05-25 21:41:55 +00001668 if (Results.includeCodePatterns()) {
1669 // if (condition) { statements }
Douglas Gregor218937c2011-02-01 19:23:04 +00001670 Builder.AddTypedTextChunk("if");
1671 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
David Blaikie4e4d0842012-03-11 07:00:24 +00001672 if (SemaRef.getLangOpts().CPlusPlus)
Douglas Gregor218937c2011-02-01 19:23:04 +00001673 Builder.AddPlaceholderChunk("condition");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001674 else
Douglas Gregor218937c2011-02-01 19:23:04 +00001675 Builder.AddPlaceholderChunk("expression");
1676 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1677 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1678 Builder.AddPlaceholderChunk("statements");
1679 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1680 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1681 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001682
Douglas Gregord8e8a582010-05-25 21:41:55 +00001683 // switch (condition) { }
Douglas Gregor218937c2011-02-01 19:23:04 +00001684 Builder.AddTypedTextChunk("switch");
1685 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
David Blaikie4e4d0842012-03-11 07:00:24 +00001686 if (SemaRef.getLangOpts().CPlusPlus)
Douglas Gregor218937c2011-02-01 19:23:04 +00001687 Builder.AddPlaceholderChunk("condition");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001688 else
Douglas Gregor218937c2011-02-01 19:23:04 +00001689 Builder.AddPlaceholderChunk("expression");
1690 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1691 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1692 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1693 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1694 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001695 }
1696
Douglas Gregor01dfea02010-01-10 23:08:15 +00001697 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001698 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001699 // case expression:
Douglas Gregor218937c2011-02-01 19:23:04 +00001700 Builder.AddTypedTextChunk("case");
1701 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1702 Builder.AddPlaceholderChunk("expression");
1703 Builder.AddChunk(CodeCompletionString::CK_Colon);
1704 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001705
1706 // default:
Douglas Gregor218937c2011-02-01 19:23:04 +00001707 Builder.AddTypedTextChunk("default");
1708 Builder.AddChunk(CodeCompletionString::CK_Colon);
1709 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001710 }
1711
Douglas Gregord8e8a582010-05-25 21:41:55 +00001712 if (Results.includeCodePatterns()) {
1713 /// while (condition) { statements }
Douglas Gregor218937c2011-02-01 19:23:04 +00001714 Builder.AddTypedTextChunk("while");
1715 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
David Blaikie4e4d0842012-03-11 07:00:24 +00001716 if (SemaRef.getLangOpts().CPlusPlus)
Douglas Gregor218937c2011-02-01 19:23:04 +00001717 Builder.AddPlaceholderChunk("condition");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001718 else
Douglas Gregor218937c2011-02-01 19:23:04 +00001719 Builder.AddPlaceholderChunk("expression");
1720 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1721 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1722 Builder.AddPlaceholderChunk("statements");
1723 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1724 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1725 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001726
1727 // do { statements } while ( expression );
Douglas Gregor218937c2011-02-01 19:23:04 +00001728 Builder.AddTypedTextChunk("do");
1729 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1730 Builder.AddPlaceholderChunk("statements");
1731 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1732 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1733 Builder.AddTextChunk("while");
1734 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1735 Builder.AddPlaceholderChunk("expression");
1736 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1737 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001738
Douglas Gregord8e8a582010-05-25 21:41:55 +00001739 // for ( for-init-statement ; condition ; expression ) { statements }
Douglas Gregor218937c2011-02-01 19:23:04 +00001740 Builder.AddTypedTextChunk("for");
1741 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
David Blaikie4e4d0842012-03-11 07:00:24 +00001742 if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99)
Douglas Gregor218937c2011-02-01 19:23:04 +00001743 Builder.AddPlaceholderChunk("init-statement");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001744 else
Douglas Gregor218937c2011-02-01 19:23:04 +00001745 Builder.AddPlaceholderChunk("init-expression");
1746 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1747 Builder.AddPlaceholderChunk("condition");
1748 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1749 Builder.AddPlaceholderChunk("inc-expression");
1750 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1751 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1752 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1753 Builder.AddPlaceholderChunk("statements");
1754 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1755 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1756 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001757 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001758
1759 if (S->getContinueParent()) {
1760 // continue ;
Douglas Gregor218937c2011-02-01 19:23:04 +00001761 Builder.AddTypedTextChunk("continue");
1762 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001763 }
1764
1765 if (S->getBreakParent()) {
1766 // break ;
Douglas Gregor218937c2011-02-01 19:23:04 +00001767 Builder.AddTypedTextChunk("break");
1768 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001769 }
1770
1771 // "return expression ;" or "return ;", depending on whether we
1772 // know the function is void or not.
1773 bool isVoid = false;
1774 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1775 isVoid = Function->getResultType()->isVoidType();
1776 else if (ObjCMethodDecl *Method
1777 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1778 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001779 else if (SemaRef.getCurBlock() &&
1780 !SemaRef.getCurBlock()->ReturnType.isNull())
1781 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor218937c2011-02-01 19:23:04 +00001782 Builder.AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001783 if (!isVoid) {
Douglas Gregor218937c2011-02-01 19:23:04 +00001784 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1785 Builder.AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001786 }
Douglas Gregor218937c2011-02-01 19:23:04 +00001787 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001788
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001789 // goto identifier ;
Douglas Gregor218937c2011-02-01 19:23:04 +00001790 Builder.AddTypedTextChunk("goto");
1791 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1792 Builder.AddPlaceholderChunk("label");
1793 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001794
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001795 // Using directives
Douglas Gregor218937c2011-02-01 19:23:04 +00001796 Builder.AddTypedTextChunk("using");
1797 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1798 Builder.AddTextChunk("namespace");
1799 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1800 Builder.AddPlaceholderChunk("identifier");
1801 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001802 }
1803
1804 // Fall through (for statement expressions).
John McCallf312b1e2010-08-26 23:41:50 +00001805 case Sema::PCC_ForInit:
1806 case Sema::PCC_Condition:
David Blaikie4e4d0842012-03-11 07:00:24 +00001807 AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001808 // Fall through: conditions and statements can have expressions.
1809
Douglas Gregor02688102010-09-14 23:59:36 +00001810 case Sema::PCC_ParenthesizedExpression:
David Blaikie4e4d0842012-03-11 07:00:24 +00001811 if (SemaRef.getLangOpts().ObjCAutoRefCount &&
John McCallf85e1932011-06-15 23:02:42 +00001812 CCC == Sema::PCC_ParenthesizedExpression) {
1813 // (__bridge <type>)<expression>
1814 Builder.AddTypedTextChunk("__bridge");
1815 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1816 Builder.AddPlaceholderChunk("type");
1817 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1818 Builder.AddPlaceholderChunk("expression");
1819 Results.AddResult(Result(Builder.TakeString()));
1820
1821 // (__bridge_transfer <Objective-C type>)<expression>
1822 Builder.AddTypedTextChunk("__bridge_transfer");
1823 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1824 Builder.AddPlaceholderChunk("Objective-C type");
1825 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1826 Builder.AddPlaceholderChunk("expression");
1827 Results.AddResult(Result(Builder.TakeString()));
1828
1829 // (__bridge_retained <CF type>)<expression>
1830 Builder.AddTypedTextChunk("__bridge_retained");
1831 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1832 Builder.AddPlaceholderChunk("CF type");
1833 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1834 Builder.AddPlaceholderChunk("expression");
1835 Results.AddResult(Result(Builder.TakeString()));
1836 }
1837 // Fall through
1838
John McCallf312b1e2010-08-26 23:41:50 +00001839 case Sema::PCC_Expression: {
David Blaikie4e4d0842012-03-11 07:00:24 +00001840 if (SemaRef.getLangOpts().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001841 // 'this', if we're in a non-static member function.
Douglas Gregor81f3bff2012-02-15 15:34:24 +00001842 addThisCompletion(SemaRef, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001843
Douglas Gregor8ca72082011-10-18 21:20:17 +00001844 // true
1845 Builder.AddResultTypeChunk("bool");
1846 Builder.AddTypedTextChunk("true");
1847 Results.AddResult(Result(Builder.TakeString()));
1848
1849 // false
1850 Builder.AddResultTypeChunk("bool");
1851 Builder.AddTypedTextChunk("false");
1852 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001853
David Blaikie4e4d0842012-03-11 07:00:24 +00001854 if (SemaRef.getLangOpts().RTTI) {
Douglas Gregorec3310a2011-04-12 02:47:21 +00001855 // dynamic_cast < type-id > ( expression )
1856 Builder.AddTypedTextChunk("dynamic_cast");
1857 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1858 Builder.AddPlaceholderChunk("type");
1859 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1860 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1861 Builder.AddPlaceholderChunk("expression");
1862 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1863 Results.AddResult(Result(Builder.TakeString()));
1864 }
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001865
1866 // static_cast < type-id > ( expression )
Douglas Gregor218937c2011-02-01 19:23:04 +00001867 Builder.AddTypedTextChunk("static_cast");
1868 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1869 Builder.AddPlaceholderChunk("type");
1870 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1871 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1872 Builder.AddPlaceholderChunk("expression");
1873 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1874 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001875
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001876 // reinterpret_cast < type-id > ( expression )
Douglas Gregor218937c2011-02-01 19:23:04 +00001877 Builder.AddTypedTextChunk("reinterpret_cast");
1878 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1879 Builder.AddPlaceholderChunk("type");
1880 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1881 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1882 Builder.AddPlaceholderChunk("expression");
1883 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1884 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001885
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001886 // const_cast < type-id > ( expression )
Douglas Gregor218937c2011-02-01 19:23:04 +00001887 Builder.AddTypedTextChunk("const_cast");
1888 Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1889 Builder.AddPlaceholderChunk("type");
1890 Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1891 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1892 Builder.AddPlaceholderChunk("expression");
1893 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1894 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001895
David Blaikie4e4d0842012-03-11 07:00:24 +00001896 if (SemaRef.getLangOpts().RTTI) {
Douglas Gregorec3310a2011-04-12 02:47:21 +00001897 // typeid ( expression-or-type )
Douglas Gregor8ca72082011-10-18 21:20:17 +00001898 Builder.AddResultTypeChunk("std::type_info");
Douglas Gregorec3310a2011-04-12 02:47:21 +00001899 Builder.AddTypedTextChunk("typeid");
1900 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1901 Builder.AddPlaceholderChunk("expression-or-type");
1902 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1903 Results.AddResult(Result(Builder.TakeString()));
1904 }
1905
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001906 // new T ( ... )
Douglas Gregor218937c2011-02-01 19:23:04 +00001907 Builder.AddTypedTextChunk("new");
1908 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1909 Builder.AddPlaceholderChunk("type");
1910 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1911 Builder.AddPlaceholderChunk("expressions");
1912 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1913 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001914
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001915 // new T [ ] ( ... )
Douglas Gregor218937c2011-02-01 19:23:04 +00001916 Builder.AddTypedTextChunk("new");
1917 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1918 Builder.AddPlaceholderChunk("type");
1919 Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
1920 Builder.AddPlaceholderChunk("size");
1921 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
1922 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1923 Builder.AddPlaceholderChunk("expressions");
1924 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1925 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001926
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001927 // delete expression
Douglas Gregor8ca72082011-10-18 21:20:17 +00001928 Builder.AddResultTypeChunk("void");
Douglas Gregor218937c2011-02-01 19:23:04 +00001929 Builder.AddTypedTextChunk("delete");
1930 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1931 Builder.AddPlaceholderChunk("expression");
1932 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001933
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001934 // delete [] expression
Douglas Gregor8ca72082011-10-18 21:20:17 +00001935 Builder.AddResultTypeChunk("void");
Douglas Gregor218937c2011-02-01 19:23:04 +00001936 Builder.AddTypedTextChunk("delete");
1937 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1938 Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
1939 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
1940 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1941 Builder.AddPlaceholderChunk("expression");
1942 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001943
David Blaikie4e4d0842012-03-11 07:00:24 +00001944 if (SemaRef.getLangOpts().CXXExceptions) {
Douglas Gregorec3310a2011-04-12 02:47:21 +00001945 // throw expression
Douglas Gregor8ca72082011-10-18 21:20:17 +00001946 Builder.AddResultTypeChunk("void");
Douglas Gregorec3310a2011-04-12 02:47:21 +00001947 Builder.AddTypedTextChunk("throw");
1948 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1949 Builder.AddPlaceholderChunk("expression");
1950 Results.AddResult(Result(Builder.TakeString()));
1951 }
Douglas Gregora50216c2011-10-18 16:29:03 +00001952
Douglas Gregor12e13132010-05-26 22:00:08 +00001953 // FIXME: Rethrow?
Douglas Gregora50216c2011-10-18 16:29:03 +00001954
Richard Smith80ad52f2013-01-02 11:42:31 +00001955 if (SemaRef.getLangOpts().CPlusPlus11) {
Douglas Gregora50216c2011-10-18 16:29:03 +00001956 // nullptr
Douglas Gregor8ca72082011-10-18 21:20:17 +00001957 Builder.AddResultTypeChunk("std::nullptr_t");
Douglas Gregora50216c2011-10-18 16:29:03 +00001958 Builder.AddTypedTextChunk("nullptr");
1959 Results.AddResult(Result(Builder.TakeString()));
1960
1961 // alignof
Douglas Gregor8ca72082011-10-18 21:20:17 +00001962 Builder.AddResultTypeChunk("size_t");
Douglas Gregora50216c2011-10-18 16:29:03 +00001963 Builder.AddTypedTextChunk("alignof");
1964 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1965 Builder.AddPlaceholderChunk("type");
1966 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1967 Results.AddResult(Result(Builder.TakeString()));
1968
1969 // noexcept
Douglas Gregor8ca72082011-10-18 21:20:17 +00001970 Builder.AddResultTypeChunk("bool");
Douglas Gregora50216c2011-10-18 16:29:03 +00001971 Builder.AddTypedTextChunk("noexcept");
1972 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1973 Builder.AddPlaceholderChunk("expression");
1974 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1975 Results.AddResult(Result(Builder.TakeString()));
1976
1977 // sizeof... expression
Douglas Gregor8ca72082011-10-18 21:20:17 +00001978 Builder.AddResultTypeChunk("size_t");
Douglas Gregora50216c2011-10-18 16:29:03 +00001979 Builder.AddTypedTextChunk("sizeof...");
1980 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1981 Builder.AddPlaceholderChunk("parameter-pack");
1982 Builder.AddChunk(CodeCompletionString::CK_RightParen);
1983 Results.AddResult(Result(Builder.TakeString()));
1984 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001985 }
1986
David Blaikie4e4d0842012-03-11 07:00:24 +00001987 if (SemaRef.getLangOpts().ObjC1) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001988 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001989 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1990 // The interface can be NULL.
1991 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
Douglas Gregor8ca72082011-10-18 21:20:17 +00001992 if (ID->getSuperClass()) {
1993 std::string SuperType;
1994 SuperType = ID->getSuperClass()->getNameAsString();
1995 if (Method->isInstanceMethod())
1996 SuperType += " *";
1997
1998 Builder.AddResultTypeChunk(Allocator.CopyString(SuperType));
1999 Builder.AddTypedTextChunk("super");
2000 Results.AddResult(Result(Builder.TakeString()));
2001 }
Ted Kremenek681e2562010-05-31 21:43:10 +00002002 }
2003
Douglas Gregorbca403c2010-01-13 23:51:12 +00002004 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002005 }
2006
Jordan Rosef70a8862012-06-30 21:33:57 +00002007 if (SemaRef.getLangOpts().C11) {
2008 // _Alignof
2009 Builder.AddResultTypeChunk("size_t");
2010 if (SemaRef.getASTContext().Idents.get("alignof").hasMacroDefinition())
2011 Builder.AddTypedTextChunk("alignof");
2012 else
2013 Builder.AddTypedTextChunk("_Alignof");
2014 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2015 Builder.AddPlaceholderChunk("type");
2016 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2017 Results.AddResult(Result(Builder.TakeString()));
2018 }
2019
Douglas Gregorc8bddde2010-05-28 00:22:41 +00002020 // sizeof expression
Douglas Gregor8ca72082011-10-18 21:20:17 +00002021 Builder.AddResultTypeChunk("size_t");
Douglas Gregor218937c2011-02-01 19:23:04 +00002022 Builder.AddTypedTextChunk("sizeof");
2023 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2024 Builder.AddPlaceholderChunk("expression-or-type");
2025 Builder.AddChunk(CodeCompletionString::CK_RightParen);
2026 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor01dfea02010-01-10 23:08:15 +00002027 break;
2028 }
Douglas Gregord32b0222010-08-24 01:06:58 +00002029
John McCallf312b1e2010-08-26 23:41:50 +00002030 case Sema::PCC_Type:
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00002031 case Sema::PCC_LocalDeclarationSpecifiers:
Douglas Gregord32b0222010-08-24 01:06:58 +00002032 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002033 }
2034
David Blaikie4e4d0842012-03-11 07:00:24 +00002035 if (WantTypesInContext(CCC, SemaRef.getLangOpts()))
2036 AddTypeSpecifierResults(SemaRef.getLangOpts(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002037
David Blaikie4e4d0842012-03-11 07:00:24 +00002038 if (SemaRef.getLangOpts().CPlusPlus && CCC != Sema::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00002039 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00002040}
2041
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002042/// \brief If the given declaration has an associated type, add it as a result
2043/// type chunk.
2044static void AddResultTypeChunk(ASTContext &Context,
Douglas Gregor8987b232011-09-27 23:30:47 +00002045 const PrintingPolicy &Policy,
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002046 const NamedDecl *ND,
Douglas Gregor218937c2011-02-01 19:23:04 +00002047 CodeCompletionBuilder &Result) {
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002048 if (!ND)
2049 return;
Douglas Gregor6f942b22010-09-21 16:06:22 +00002050
2051 // Skip constructors and conversion functions, which have their return types
2052 // built into their names.
2053 if (isa<CXXConstructorDecl>(ND) || isa<CXXConversionDecl>(ND))
2054 return;
2055
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002056 // Determine the type of the declaration (if it has a type).
Douglas Gregor6f942b22010-09-21 16:06:22 +00002057 QualType T;
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002058 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002059 T = Function->getResultType();
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002060 else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002061 T = Method->getResultType();
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002062 else if (const FunctionTemplateDecl *FunTmpl =
2063 dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002064 T = FunTmpl->getTemplatedDecl()->getResultType();
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002065 else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002066 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
2067 else if (isa<UnresolvedUsingValueDecl>(ND)) {
2068 /* Do nothing: ignore unresolved using declarations*/
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002069 } else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) {
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002070 T = Value->getType();
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002071 } else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002072 T = Property->getType();
2073
2074 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
2075 return;
2076
Douglas Gregor8987b232011-09-27 23:30:47 +00002077 Result.AddResultTypeChunk(GetCompletionTypeString(T, Context, Policy,
Douglas Gregora63f6de2011-02-01 21:15:40 +00002078 Result.getAllocator()));
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002079}
2080
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002081static void MaybeAddSentinel(ASTContext &Context,
2082 const NamedDecl *FunctionOrMethod,
Douglas Gregor218937c2011-02-01 19:23:04 +00002083 CodeCompletionBuilder &Result) {
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002084 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
2085 if (Sentinel->getSentinel() == 0) {
David Blaikie4e4d0842012-03-11 07:00:24 +00002086 if (Context.getLangOpts().ObjC1 &&
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002087 Context.Idents.get("nil").hasMacroDefinition())
Douglas Gregor218937c2011-02-01 19:23:04 +00002088 Result.AddTextChunk(", nil");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002089 else if (Context.Idents.get("NULL").hasMacroDefinition())
Douglas Gregor218937c2011-02-01 19:23:04 +00002090 Result.AddTextChunk(", NULL");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002091 else
Douglas Gregor218937c2011-02-01 19:23:04 +00002092 Result.AddTextChunk(", (void*)0");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002093 }
2094}
2095
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002096static std::string formatObjCParamQualifiers(unsigned ObjCQuals) {
2097 std::string Result;
2098 if (ObjCQuals & Decl::OBJC_TQ_In)
Douglas Gregor6ef92092011-11-09 02:13:45 +00002099 Result += "in ";
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002100 else if (ObjCQuals & Decl::OBJC_TQ_Inout)
Douglas Gregor6ef92092011-11-09 02:13:45 +00002101 Result += "inout ";
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002102 else if (ObjCQuals & Decl::OBJC_TQ_Out)
Douglas Gregor6ef92092011-11-09 02:13:45 +00002103 Result += "out ";
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002104 if (ObjCQuals & Decl::OBJC_TQ_Bycopy)
Douglas Gregor6ef92092011-11-09 02:13:45 +00002105 Result += "bycopy ";
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002106 else if (ObjCQuals & Decl::OBJC_TQ_Byref)
Douglas Gregor6ef92092011-11-09 02:13:45 +00002107 Result += "byref ";
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002108 if (ObjCQuals & Decl::OBJC_TQ_Oneway)
Douglas Gregor6ef92092011-11-09 02:13:45 +00002109 Result += "oneway ";
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002110 return Result;
2111}
2112
Douglas Gregor83482d12010-08-24 16:15:59 +00002113static std::string FormatFunctionParameter(ASTContext &Context,
Douglas Gregor8987b232011-09-27 23:30:47 +00002114 const PrintingPolicy &Policy,
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002115 const ParmVarDecl *Param,
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002116 bool SuppressName = false,
2117 bool SuppressBlock = false) {
Douglas Gregor83482d12010-08-24 16:15:59 +00002118 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
2119 if (Param->getType()->isDependentType() ||
2120 !Param->getType()->isBlockPointerType()) {
2121 // The argument for a dependent or non-block parameter is a placeholder
2122 // containing that parameter's type.
2123 std::string Result;
2124
Douglas Gregoraba48082010-08-29 19:47:46 +00002125 if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00002126 Result = Param->getIdentifier()->getName();
2127
John McCallf85e1932011-06-15 23:02:42 +00002128 Param->getType().getAsStringInternal(Result, Policy);
Douglas Gregor83482d12010-08-24 16:15:59 +00002129
2130 if (ObjCMethodParam) {
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002131 Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier())
2132 + Result + ")";
Douglas Gregoraba48082010-08-29 19:47:46 +00002133 if (Param->getIdentifier() && !SuppressName)
Douglas Gregor83482d12010-08-24 16:15:59 +00002134 Result += Param->getIdentifier()->getName();
2135 }
2136 return Result;
2137 }
2138
2139 // The argument for a block pointer parameter is a block literal with
2140 // the appropriate type.
Douglas Gregor830072c2011-02-15 22:37:09 +00002141 FunctionTypeLoc *Block = 0;
2142 FunctionProtoTypeLoc *BlockProto = 0;
Douglas Gregor83482d12010-08-24 16:15:59 +00002143 TypeLoc TL;
2144 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
2145 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
2146 while (true) {
2147 // Look through typedefs.
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002148 if (!SuppressBlock) {
2149 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
2150 if (TypeSourceInfo *InnerTSInfo
2151 = TypedefTL->getTypedefNameDecl()->getTypeSourceInfo()) {
2152 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
2153 continue;
2154 }
2155 }
2156
2157 // Look through qualified types
2158 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
2159 TL = QualifiedTL->getUnqualifiedLoc();
Douglas Gregor83482d12010-08-24 16:15:59 +00002160 continue;
2161 }
2162 }
2163
Douglas Gregor83482d12010-08-24 16:15:59 +00002164 // Try to get the function prototype behind the block pointer type,
2165 // then we're done.
2166 if (BlockPointerTypeLoc *BlockPtr
2167 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
Abramo Bagnara723df242010-12-14 22:11:44 +00002168 TL = BlockPtr->getPointeeLoc().IgnoreParens();
Douglas Gregor830072c2011-02-15 22:37:09 +00002169 Block = dyn_cast<FunctionTypeLoc>(&TL);
2170 BlockProto = dyn_cast<FunctionProtoTypeLoc>(&TL);
Douglas Gregor83482d12010-08-24 16:15:59 +00002171 }
2172 break;
2173 }
2174 }
2175
2176 if (!Block) {
2177 // We were unable to find a FunctionProtoTypeLoc with parameter names
2178 // for the block; just use the parameter type as a placeholder.
2179 std::string Result;
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002180 if (!ObjCMethodParam && Param->getIdentifier())
2181 Result = Param->getIdentifier()->getName();
2182
John McCallf85e1932011-06-15 23:02:42 +00002183 Param->getType().getUnqualifiedType().getAsStringInternal(Result, Policy);
Douglas Gregor83482d12010-08-24 16:15:59 +00002184
2185 if (ObjCMethodParam) {
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002186 Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier())
2187 + Result + ")";
Douglas Gregor83482d12010-08-24 16:15:59 +00002188 if (Param->getIdentifier())
2189 Result += Param->getIdentifier()->getName();
2190 }
2191
2192 return Result;
2193 }
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002194
Douglas Gregor83482d12010-08-24 16:15:59 +00002195 // We have the function prototype behind the block pointer type, as it was
2196 // written in the source.
Douglas Gregor38276252010-09-08 22:47:51 +00002197 std::string Result;
2198 QualType ResultType = Block->getTypePtr()->getResultType();
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002199 if (!ResultType->isVoidType() || SuppressBlock)
John McCallf85e1932011-06-15 23:02:42 +00002200 ResultType.getAsStringInternal(Result, Policy);
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002201
2202 // Format the parameter list.
2203 std::string Params;
Douglas Gregor830072c2011-02-15 22:37:09 +00002204 if (!BlockProto || Block->getNumArgs() == 0) {
2205 if (BlockProto && BlockProto->getTypePtr()->isVariadic())
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002206 Params = "(...)";
Douglas Gregorc2760bc2010-10-02 23:49:58 +00002207 else
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002208 Params = "(void)";
Douglas Gregor38276252010-09-08 22:47:51 +00002209 } else {
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002210 Params += "(";
Douglas Gregor38276252010-09-08 22:47:51 +00002211 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
2212 if (I)
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002213 Params += ", ";
2214 Params += FormatFunctionParameter(Context, Policy, Block->getArg(I),
2215 /*SuppressName=*/false,
2216 /*SuppressBlock=*/true);
Douglas Gregor38276252010-09-08 22:47:51 +00002217
Douglas Gregor830072c2011-02-15 22:37:09 +00002218 if (I == N - 1 && BlockProto->getTypePtr()->isVariadic())
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002219 Params += ", ...";
Douglas Gregor38276252010-09-08 22:47:51 +00002220 }
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002221 Params += ")";
Douglas Gregore17794f2010-08-31 05:13:43 +00002222 }
Douglas Gregor38276252010-09-08 22:47:51 +00002223
Douglas Gregoree1c68a2011-10-18 04:23:19 +00002224 if (SuppressBlock) {
2225 // Format as a parameter.
2226 Result = Result + " (^";
2227 if (Param->getIdentifier())
2228 Result += Param->getIdentifier()->getName();
2229 Result += ")";
2230 Result += Params;
2231 } else {
2232 // Format as a block literal argument.
2233 Result = '^' + Result;
2234 Result += Params;
2235
2236 if (Param->getIdentifier())
2237 Result += Param->getIdentifier()->getName();
2238 }
2239
Douglas Gregor83482d12010-08-24 16:15:59 +00002240 return Result;
2241}
2242
Douglas Gregor86d9a522009-09-21 16:56:56 +00002243/// \brief Add function parameter chunks to the given code completion string.
2244static void AddFunctionParameterChunks(ASTContext &Context,
Douglas Gregor8987b232011-09-27 23:30:47 +00002245 const PrintingPolicy &Policy,
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002246 const FunctionDecl *Function,
Douglas Gregor218937c2011-02-01 19:23:04 +00002247 CodeCompletionBuilder &Result,
2248 unsigned Start = 0,
2249 bool InOptional = false) {
Douglas Gregor218937c2011-02-01 19:23:04 +00002250 bool FirstParameter = true;
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002251
Douglas Gregor218937c2011-02-01 19:23:04 +00002252 for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002253 const ParmVarDecl *Param = Function->getParamDecl(P);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002254
Douglas Gregor218937c2011-02-01 19:23:04 +00002255 if (Param->hasDefaultArg() && !InOptional) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002256 // When we see an optional default argument, put that argument and
2257 // the remaining default arguments into a new, optional string.
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00002258 CodeCompletionBuilder Opt(Result.getAllocator(),
2259 Result.getCodeCompletionTUInfo());
Douglas Gregor218937c2011-02-01 19:23:04 +00002260 if (!FirstParameter)
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002261 Opt.AddChunk(CodeCompletionString::CK_Comma);
Douglas Gregor8987b232011-09-27 23:30:47 +00002262 AddFunctionParameterChunks(Context, Policy, Function, Opt, P, true);
Douglas Gregor218937c2011-02-01 19:23:04 +00002263 Result.AddOptionalChunk(Opt.TakeString());
2264 break;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002265 }
2266
Douglas Gregor218937c2011-02-01 19:23:04 +00002267 if (FirstParameter)
2268 FirstParameter = false;
2269 else
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002270 Result.AddChunk(CodeCompletionString::CK_Comma);
Douglas Gregor218937c2011-02-01 19:23:04 +00002271
2272 InOptional = false;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002273
2274 // Format the placeholder string.
Douglas Gregor8987b232011-09-27 23:30:47 +00002275 std::string PlaceholderStr = FormatFunctionParameter(Context, Policy,
2276 Param);
Douglas Gregor83482d12010-08-24 16:15:59 +00002277
Douglas Gregore17794f2010-08-31 05:13:43 +00002278 if (Function->isVariadic() && P == N - 1)
2279 PlaceholderStr += ", ...";
2280
Douglas Gregor86d9a522009-09-21 16:56:56 +00002281 // Add the placeholder string.
Douglas Gregordae68752011-02-01 22:57:45 +00002282 Result.AddPlaceholderChunk(
2283 Result.getAllocator().CopyString(PlaceholderStr));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002284 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00002285
2286 if (const FunctionProtoType *Proto
2287 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002288 if (Proto->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002289 if (Proto->getNumArgs() == 0)
Douglas Gregor218937c2011-02-01 19:23:04 +00002290 Result.AddPlaceholderChunk("...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002291
Douglas Gregor218937c2011-02-01 19:23:04 +00002292 MaybeAddSentinel(Context, Function, Result);
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002293 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002294}
2295
2296/// \brief Add template parameter chunks to the given code completion string.
2297static void AddTemplateParameterChunks(ASTContext &Context,
Douglas Gregor8987b232011-09-27 23:30:47 +00002298 const PrintingPolicy &Policy,
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002299 const TemplateDecl *Template,
Douglas Gregor218937c2011-02-01 19:23:04 +00002300 CodeCompletionBuilder &Result,
2301 unsigned MaxParameters = 0,
2302 unsigned Start = 0,
2303 bool InDefaultArg = false) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002304 bool FirstParameter = true;
2305
2306 TemplateParameterList *Params = Template->getTemplateParameters();
2307 TemplateParameterList::iterator PEnd = Params->end();
2308 if (MaxParameters)
2309 PEnd = Params->begin() + MaxParameters;
Douglas Gregor218937c2011-02-01 19:23:04 +00002310 for (TemplateParameterList::iterator P = Params->begin() + Start;
2311 P != PEnd; ++P) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002312 bool HasDefaultArg = false;
2313 std::string PlaceholderStr;
2314 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
2315 if (TTP->wasDeclaredWithTypename())
2316 PlaceholderStr = "typename";
2317 else
2318 PlaceholderStr = "class";
2319
2320 if (TTP->getIdentifier()) {
2321 PlaceholderStr += ' ';
2322 PlaceholderStr += TTP->getIdentifier()->getName();
2323 }
2324
2325 HasDefaultArg = TTP->hasDefaultArgument();
2326 } else if (NonTypeTemplateParmDecl *NTTP
Douglas Gregor218937c2011-02-01 19:23:04 +00002327 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002328 if (NTTP->getIdentifier())
2329 PlaceholderStr = NTTP->getIdentifier()->getName();
John McCallf85e1932011-06-15 23:02:42 +00002330 NTTP->getType().getAsStringInternal(PlaceholderStr, Policy);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002331 HasDefaultArg = NTTP->hasDefaultArgument();
2332 } else {
2333 assert(isa<TemplateTemplateParmDecl>(*P));
2334 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
2335
2336 // Since putting the template argument list into the placeholder would
2337 // be very, very long, we just use an abbreviation.
2338 PlaceholderStr = "template<...> class";
2339 if (TTP->getIdentifier()) {
2340 PlaceholderStr += ' ';
2341 PlaceholderStr += TTP->getIdentifier()->getName();
2342 }
2343
2344 HasDefaultArg = TTP->hasDefaultArgument();
2345 }
2346
Douglas Gregor218937c2011-02-01 19:23:04 +00002347 if (HasDefaultArg && !InDefaultArg) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002348 // When we see an optional default argument, put that argument and
2349 // the remaining default arguments into a new, optional string.
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00002350 CodeCompletionBuilder Opt(Result.getAllocator(),
2351 Result.getCodeCompletionTUInfo());
Douglas Gregor218937c2011-02-01 19:23:04 +00002352 if (!FirstParameter)
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002353 Opt.AddChunk(CodeCompletionString::CK_Comma);
Douglas Gregor8987b232011-09-27 23:30:47 +00002354 AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters,
Douglas Gregor218937c2011-02-01 19:23:04 +00002355 P - Params->begin(), true);
2356 Result.AddOptionalChunk(Opt.TakeString());
2357 break;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002358 }
2359
Douglas Gregor218937c2011-02-01 19:23:04 +00002360 InDefaultArg = false;
2361
Douglas Gregor86d9a522009-09-21 16:56:56 +00002362 if (FirstParameter)
2363 FirstParameter = false;
2364 else
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002365 Result.AddChunk(CodeCompletionString::CK_Comma);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002366
2367 // Add the placeholder string.
Douglas Gregordae68752011-02-01 22:57:45 +00002368 Result.AddPlaceholderChunk(
2369 Result.getAllocator().CopyString(PlaceholderStr));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002370 }
2371}
2372
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002373/// \brief Add a qualifier to the given code-completion string, if the
2374/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00002375static void
Douglas Gregor218937c2011-02-01 19:23:04 +00002376AddQualifierToCompletionString(CodeCompletionBuilder &Result,
Douglas Gregora61a8792009-12-11 18:44:16 +00002377 NestedNameSpecifier *Qualifier,
2378 bool QualifierIsInformative,
Douglas Gregor8987b232011-09-27 23:30:47 +00002379 ASTContext &Context,
2380 const PrintingPolicy &Policy) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002381 if (!Qualifier)
2382 return;
2383
2384 std::string PrintedNNS;
2385 {
2386 llvm::raw_string_ostream OS(PrintedNNS);
Douglas Gregor8987b232011-09-27 23:30:47 +00002387 Qualifier->print(OS, Policy);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002388 }
Douglas Gregor0563c262009-09-22 23:15:58 +00002389 if (QualifierIsInformative)
Douglas Gregordae68752011-02-01 22:57:45 +00002390 Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS));
Douglas Gregor0563c262009-09-22 23:15:58 +00002391 else
Douglas Gregordae68752011-02-01 22:57:45 +00002392 Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS));
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002393}
2394
Douglas Gregor218937c2011-02-01 19:23:04 +00002395static void
2396AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002397 const FunctionDecl *Function) {
Douglas Gregora61a8792009-12-11 18:44:16 +00002398 const FunctionProtoType *Proto
2399 = Function->getType()->getAs<FunctionProtoType>();
2400 if (!Proto || !Proto->getTypeQuals())
2401 return;
2402
Douglas Gregora63f6de2011-02-01 21:15:40 +00002403 // FIXME: Add ref-qualifier!
2404
2405 // Handle single qualifiers without copying
2406 if (Proto->getTypeQuals() == Qualifiers::Const) {
2407 Result.AddInformativeChunk(" const");
2408 return;
2409 }
2410
2411 if (Proto->getTypeQuals() == Qualifiers::Volatile) {
2412 Result.AddInformativeChunk(" volatile");
2413 return;
2414 }
2415
2416 if (Proto->getTypeQuals() == Qualifiers::Restrict) {
2417 Result.AddInformativeChunk(" restrict");
2418 return;
2419 }
2420
2421 // Handle multiple qualifiers.
Douglas Gregora61a8792009-12-11 18:44:16 +00002422 std::string QualsStr;
David Blaikie4ef832f2012-08-10 00:55:35 +00002423 if (Proto->isConst())
Douglas Gregora61a8792009-12-11 18:44:16 +00002424 QualsStr += " const";
David Blaikie4ef832f2012-08-10 00:55:35 +00002425 if (Proto->isVolatile())
Douglas Gregora61a8792009-12-11 18:44:16 +00002426 QualsStr += " volatile";
David Blaikie4ef832f2012-08-10 00:55:35 +00002427 if (Proto->isRestrict())
Douglas Gregora61a8792009-12-11 18:44:16 +00002428 QualsStr += " restrict";
Douglas Gregordae68752011-02-01 22:57:45 +00002429 Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr));
Douglas Gregora61a8792009-12-11 18:44:16 +00002430}
2431
Douglas Gregor6f942b22010-09-21 16:06:22 +00002432/// \brief Add the name of the given declaration
Douglas Gregor8987b232011-09-27 23:30:47 +00002433static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002434 const NamedDecl *ND,
2435 CodeCompletionBuilder &Result) {
Douglas Gregor6f942b22010-09-21 16:06:22 +00002436 DeclarationName Name = ND->getDeclName();
2437 if (!Name)
2438 return;
2439
2440 switch (Name.getNameKind()) {
Douglas Gregora63f6de2011-02-01 21:15:40 +00002441 case DeclarationName::CXXOperatorName: {
2442 const char *OperatorName = 0;
2443 switch (Name.getCXXOverloadedOperator()) {
2444 case OO_None:
2445 case OO_Conditional:
2446 case NUM_OVERLOADED_OPERATORS:
2447 OperatorName = "operator";
2448 break;
2449
2450#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2451 case OO_##Name: OperatorName = "operator" Spelling; break;
2452#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
2453#include "clang/Basic/OperatorKinds.def"
2454
2455 case OO_New: OperatorName = "operator new"; break;
2456 case OO_Delete: OperatorName = "operator delete"; break;
2457 case OO_Array_New: OperatorName = "operator new[]"; break;
2458 case OO_Array_Delete: OperatorName = "operator delete[]"; break;
2459 case OO_Call: OperatorName = "operator()"; break;
2460 case OO_Subscript: OperatorName = "operator[]"; break;
2461 }
2462 Result.AddTypedTextChunk(OperatorName);
2463 break;
2464 }
2465
Douglas Gregor6f942b22010-09-21 16:06:22 +00002466 case DeclarationName::Identifier:
2467 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor6f942b22010-09-21 16:06:22 +00002468 case DeclarationName::CXXDestructorName:
2469 case DeclarationName::CXXLiteralOperatorName:
Douglas Gregordae68752011-02-01 22:57:45 +00002470 Result.AddTypedTextChunk(
2471 Result.getAllocator().CopyString(ND->getNameAsString()));
Douglas Gregor6f942b22010-09-21 16:06:22 +00002472 break;
2473
2474 case DeclarationName::CXXUsingDirective:
2475 case DeclarationName::ObjCZeroArgSelector:
2476 case DeclarationName::ObjCOneArgSelector:
2477 case DeclarationName::ObjCMultiArgSelector:
2478 break;
2479
2480 case DeclarationName::CXXConstructorName: {
2481 CXXRecordDecl *Record = 0;
2482 QualType Ty = Name.getCXXNameType();
2483 if (const RecordType *RecordTy = Ty->getAs<RecordType>())
2484 Record = cast<CXXRecordDecl>(RecordTy->getDecl());
2485 else if (const InjectedClassNameType *InjectedTy
2486 = Ty->getAs<InjectedClassNameType>())
2487 Record = InjectedTy->getDecl();
2488 else {
Douglas Gregordae68752011-02-01 22:57:45 +00002489 Result.AddTypedTextChunk(
2490 Result.getAllocator().CopyString(ND->getNameAsString()));
Douglas Gregor6f942b22010-09-21 16:06:22 +00002491 break;
2492 }
2493
Douglas Gregordae68752011-02-01 22:57:45 +00002494 Result.AddTypedTextChunk(
2495 Result.getAllocator().CopyString(Record->getNameAsString()));
Douglas Gregor6f942b22010-09-21 16:06:22 +00002496 if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002497 Result.AddChunk(CodeCompletionString::CK_LeftAngle);
Douglas Gregor8987b232011-09-27 23:30:47 +00002498 AddTemplateParameterChunks(Context, Policy, Template, Result);
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002499 Result.AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor6f942b22010-09-21 16:06:22 +00002500 }
2501 break;
2502 }
2503 }
2504}
2505
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002506CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00002507 CodeCompletionAllocator &Allocator,
Dmitri Gribenkod99ef532012-07-02 17:35:10 +00002508 CodeCompletionTUInfo &CCTUInfo,
2509 bool IncludeBriefComments) {
2510 return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo,
2511 IncludeBriefComments);
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002512}
2513
Douglas Gregor86d9a522009-09-21 16:56:56 +00002514/// \brief If possible, create a new code completion string for the given
2515/// result.
2516///
2517/// \returns Either a new, heap-allocated code completion string describing
2518/// how to use this result, or NULL to indicate that the string or name of the
2519/// result is all that is needed.
2520CodeCompletionString *
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002521CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
2522 Preprocessor &PP,
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00002523 CodeCompletionAllocator &Allocator,
Dmitri Gribenkod99ef532012-07-02 17:35:10 +00002524 CodeCompletionTUInfo &CCTUInfo,
2525 bool IncludeBriefComments) {
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00002526 CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002527
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002528 PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
Douglas Gregor218937c2011-02-01 19:23:04 +00002529 if (Kind == RK_Pattern) {
2530 Pattern->Priority = Priority;
2531 Pattern->Availability = Availability;
Douglas Gregorba103062012-03-27 23:34:16 +00002532
2533 if (Declaration) {
2534 Result.addParentContext(Declaration->getDeclContext());
Douglas Gregorba103062012-03-27 23:34:16 +00002535 Pattern->ParentName = Result.getParentName();
2536 }
2537
Douglas Gregor218937c2011-02-01 19:23:04 +00002538 return Pattern;
2539 }
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002540
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002541 if (Kind == RK_Keyword) {
Douglas Gregor218937c2011-02-01 19:23:04 +00002542 Result.AddTypedTextChunk(Keyword);
2543 return Result.TakeString();
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002544 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002545
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002546 if (Kind == RK_Macro) {
Douglas Gregor3644d972012-10-09 16:01:50 +00002547 MacroInfo *MI = PP.getMacroInfoHistory(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002548 assert(MI && "Not a macro?");
2549
Douglas Gregordae68752011-02-01 22:57:45 +00002550 Result.AddTypedTextChunk(
2551 Result.getAllocator().CopyString(Macro->getName()));
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002552
2553 if (!MI->isFunctionLike())
Douglas Gregor218937c2011-02-01 19:23:04 +00002554 return Result.TakeString();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002555
2556 // Format a function-like macro with placeholders for the arguments.
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002557 Result.AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregore4244702011-07-30 08:17:44 +00002558 MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
Douglas Gregorc8dc1352012-01-21 00:43:38 +00002559
2560 // C99 variadic macros add __VA_ARGS__ at the end. Skip it.
2561 if (MI->isC99Varargs()) {
2562 --AEnd;
2563
2564 if (A == AEnd) {
2565 Result.AddPlaceholderChunk("...");
2566 }
Douglas Gregore4244702011-07-30 08:17:44 +00002567 }
Douglas Gregorc8dc1352012-01-21 00:43:38 +00002568
Douglas Gregore4244702011-07-30 08:17:44 +00002569 for (MacroInfo::arg_iterator A = MI->arg_begin(); A != AEnd; ++A) {
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002570 if (A != MI->arg_begin())
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002571 Result.AddChunk(CodeCompletionString::CK_Comma);
Douglas Gregorc8dc1352012-01-21 00:43:38 +00002572
2573 if (MI->isVariadic() && (A+1) == AEnd) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00002574 SmallString<32> Arg = (*A)->getName();
Douglas Gregorc8dc1352012-01-21 00:43:38 +00002575 if (MI->isC99Varargs())
2576 Arg += ", ...";
2577 else
2578 Arg += "...";
Douglas Gregordae68752011-02-01 22:57:45 +00002579 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
Douglas Gregorc8dc1352012-01-21 00:43:38 +00002580 break;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002581 }
Douglas Gregorc8dc1352012-01-21 00:43:38 +00002582
2583 // Non-variadic macros are simple.
2584 Result.AddPlaceholderChunk(
2585 Result.getAllocator().CopyString((*A)->getName()));
Douglas Gregore4244702011-07-30 08:17:44 +00002586 }
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002587 Result.AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor218937c2011-02-01 19:23:04 +00002588 return Result.TakeString();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002589 }
2590
Douglas Gregord8e8a582010-05-25 21:41:55 +00002591 assert(Kind == RK_Declaration && "Missed a result kind?");
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002592 const NamedDecl *ND = Declaration;
Douglas Gregorba103062012-03-27 23:34:16 +00002593 Result.addParentContext(ND->getDeclContext());
Dmitri Gribenkod99ef532012-07-02 17:35:10 +00002594
2595 if (IncludeBriefComments) {
2596 // Add documentation comment, if it exists.
Dmitri Gribenkof50555e2012-08-11 00:51:43 +00002597 if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(ND)) {
Dmitri Gribenkod99ef532012-07-02 17:35:10 +00002598 Result.addBriefComment(RC->getBriefText(Ctx));
2599 }
2600 }
2601
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002602 if (StartsNestedNameSpecifier) {
Douglas Gregordae68752011-02-01 22:57:45 +00002603 Result.AddTypedTextChunk(
2604 Result.getAllocator().CopyString(ND->getNameAsString()));
Douglas Gregor218937c2011-02-01 19:23:04 +00002605 Result.AddTextChunk("::");
2606 return Result.TakeString();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002607 }
Erik Verbruggen6164ea12011-10-14 15:31:08 +00002608
2609 for (Decl::attr_iterator i = ND->attr_begin(); i != ND->attr_end(); ++i) {
2610 if (AnnotateAttr *Attr = dyn_cast_or_null<AnnotateAttr>(*i)) {
2611 Result.AddAnnotation(Result.getAllocator().CopyString(Attr->getAnnotation()));
2612 }
2613 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002614
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002615 AddResultTypeChunk(Ctx, Policy, ND, Result);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002616
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002617 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002618 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002619 Ctx, Policy);
2620 AddTypedNameChunk(Ctx, Policy, ND, Result);
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002621 Result.AddChunk(CodeCompletionString::CK_LeftParen);
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002622 AddFunctionParameterChunks(Ctx, Policy, Function, Result);
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002623 Result.AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora61a8792009-12-11 18:44:16 +00002624 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor218937c2011-02-01 19:23:04 +00002625 return Result.TakeString();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002626 }
2627
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002628 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002629 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002630 Ctx, Policy);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002631 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002632 AddTypedNameChunk(Ctx, Policy, Function, Result);
Douglas Gregor6f942b22010-09-21 16:06:22 +00002633
Douglas Gregor86d9a522009-09-21 16:56:56 +00002634 // Figure out which template parameters are deduced (or have default
2635 // arguments).
Benjamin Kramer013b3662012-01-30 16:17:39 +00002636 llvm::SmallBitVector Deduced;
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002637 Sema::MarkDeducedTemplateParameters(Ctx, FunTmpl, Deduced);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002638 unsigned LastDeducibleArgument;
2639 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2640 --LastDeducibleArgument) {
2641 if (!Deduced[LastDeducibleArgument - 1]) {
2642 // C++0x: Figure out if the template argument has a default. If so,
2643 // the user doesn't need to type this argument.
2644 // FIXME: We need to abstract template parameters better!
2645 bool HasDefaultArg = false;
2646 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
Douglas Gregor218937c2011-02-01 19:23:04 +00002647 LastDeducibleArgument - 1);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002648 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2649 HasDefaultArg = TTP->hasDefaultArgument();
2650 else if (NonTypeTemplateParmDecl *NTTP
2651 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2652 HasDefaultArg = NTTP->hasDefaultArgument();
2653 else {
2654 assert(isa<TemplateTemplateParmDecl>(Param));
2655 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002656 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002657 }
2658
2659 if (!HasDefaultArg)
2660 break;
2661 }
2662 }
2663
2664 if (LastDeducibleArgument) {
2665 // Some of the function template arguments cannot be deduced from a
2666 // function call, so we introduce an explicit template argument list
2667 // containing all of the arguments up to the first deducible argument.
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002668 Result.AddChunk(CodeCompletionString::CK_LeftAngle);
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002669 AddTemplateParameterChunks(Ctx, Policy, FunTmpl, Result,
Douglas Gregor86d9a522009-09-21 16:56:56 +00002670 LastDeducibleArgument);
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002671 Result.AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002672 }
2673
2674 // Add the function parameters
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002675 Result.AddChunk(CodeCompletionString::CK_LeftParen);
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002676 AddFunctionParameterChunks(Ctx, Policy, Function, Result);
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002677 Result.AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora61a8792009-12-11 18:44:16 +00002678 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor218937c2011-02-01 19:23:04 +00002679 return Result.TakeString();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002680 }
2681
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002682 if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002683 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002684 Ctx, Policy);
Douglas Gregordae68752011-02-01 22:57:45 +00002685 Result.AddTypedTextChunk(
2686 Result.getAllocator().CopyString(Template->getNameAsString()));
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002687 Result.AddChunk(CodeCompletionString::CK_LeftAngle);
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002688 AddTemplateParameterChunks(Ctx, Policy, Template, Result);
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002689 Result.AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor218937c2011-02-01 19:23:04 +00002690 return Result.TakeString();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002691 }
2692
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002693 if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002694 Selector Sel = Method->getSelector();
2695 if (Sel.isUnarySelector()) {
Douglas Gregordae68752011-02-01 22:57:45 +00002696 Result.AddTypedTextChunk(Result.getAllocator().CopyString(
Douglas Gregor813d8342011-02-18 22:29:55 +00002697 Sel.getNameForSlot(0)));
Douglas Gregor218937c2011-02-01 19:23:04 +00002698 return Result.TakeString();
Douglas Gregor9630eb62009-11-17 16:44:22 +00002699 }
2700
Douglas Gregor813d8342011-02-18 22:29:55 +00002701 std::string SelName = Sel.getNameForSlot(0).str();
Douglas Gregord3c68542009-11-19 01:08:35 +00002702 SelName += ':';
2703 if (StartParameter == 0)
Douglas Gregordae68752011-02-01 22:57:45 +00002704 Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName));
Douglas Gregord3c68542009-11-19 01:08:35 +00002705 else {
Douglas Gregordae68752011-02-01 22:57:45 +00002706 Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName));
Douglas Gregord3c68542009-11-19 01:08:35 +00002707
2708 // If there is only one parameter, and we're past it, add an empty
2709 // typed-text chunk since there is nothing to type.
2710 if (Method->param_size() == 1)
Douglas Gregor218937c2011-02-01 19:23:04 +00002711 Result.AddTypedTextChunk("");
Douglas Gregord3c68542009-11-19 01:08:35 +00002712 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002713 unsigned Idx = 0;
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00002714 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
2715 PEnd = Method->param_end();
Douglas Gregor9630eb62009-11-17 16:44:22 +00002716 P != PEnd; (void)++P, ++Idx) {
2717 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002718 std::string Keyword;
2719 if (Idx > StartParameter)
Douglas Gregor218937c2011-02-01 19:23:04 +00002720 Result.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002721 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
Benjamin Kramera0651c52011-07-26 16:59:25 +00002722 Keyword += II->getName();
Douglas Gregor9630eb62009-11-17 16:44:22 +00002723 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002724 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregordae68752011-02-01 22:57:45 +00002725 Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword));
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002726 else
Douglas Gregordae68752011-02-01 22:57:45 +00002727 Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword));
Douglas Gregor9630eb62009-11-17 16:44:22 +00002728 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002729
2730 // If we're before the starting parameter, skip the placeholder.
2731 if (Idx < StartParameter)
2732 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002733
2734 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002735
2736 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002737 Arg = FormatFunctionParameter(Ctx, Policy, *P, true);
Douglas Gregor83482d12010-08-24 16:15:59 +00002738 else {
John McCallf85e1932011-06-15 23:02:42 +00002739 (*P)->getType().getAsStringInternal(Arg, Policy);
Douglas Gregor6fa14dd2011-07-30 07:55:26 +00002740 Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier())
2741 + Arg + ")";
Douglas Gregor83482d12010-08-24 16:15:59 +00002742 if (IdentifierInfo *II = (*P)->getIdentifier())
Douglas Gregoraba48082010-08-29 19:47:46 +00002743 if (DeclaringEntity || AllParametersAreInformative)
Benjamin Kramera0651c52011-07-26 16:59:25 +00002744 Arg += II->getName();
Douglas Gregor83482d12010-08-24 16:15:59 +00002745 }
2746
Douglas Gregore17794f2010-08-31 05:13:43 +00002747 if (Method->isVariadic() && (P + 1) == PEnd)
2748 Arg += ", ...";
2749
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002750 if (DeclaringEntity)
Douglas Gregordae68752011-02-01 22:57:45 +00002751 Result.AddTextChunk(Result.getAllocator().CopyString(Arg));
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002752 else if (AllParametersAreInformative)
Douglas Gregordae68752011-02-01 22:57:45 +00002753 Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg));
Douglas Gregor4ad96852009-11-19 07:41:15 +00002754 else
Douglas Gregordae68752011-02-01 22:57:45 +00002755 Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
Douglas Gregor9630eb62009-11-17 16:44:22 +00002756 }
2757
Douglas Gregor2a17af02009-12-23 00:21:46 +00002758 if (Method->isVariadic()) {
Douglas Gregore17794f2010-08-31 05:13:43 +00002759 if (Method->param_size() == 0) {
2760 if (DeclaringEntity)
Douglas Gregor218937c2011-02-01 19:23:04 +00002761 Result.AddTextChunk(", ...");
Douglas Gregore17794f2010-08-31 05:13:43 +00002762 else if (AllParametersAreInformative)
Douglas Gregor218937c2011-02-01 19:23:04 +00002763 Result.AddInformativeChunk(", ...");
Douglas Gregore17794f2010-08-31 05:13:43 +00002764 else
Douglas Gregor218937c2011-02-01 19:23:04 +00002765 Result.AddPlaceholderChunk(", ...");
Douglas Gregore17794f2010-08-31 05:13:43 +00002766 }
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002767
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002768 MaybeAddSentinel(Ctx, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002769 }
2770
Douglas Gregor218937c2011-02-01 19:23:04 +00002771 return Result.TakeString();
Douglas Gregor9630eb62009-11-17 16:44:22 +00002772 }
2773
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002774 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002775 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
Argyrios Kyrtzidisea8c59a2012-01-17 02:15:51 +00002776 Ctx, Policy);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002777
Douglas Gregordae68752011-02-01 22:57:45 +00002778 Result.AddTypedTextChunk(
2779 Result.getAllocator().CopyString(ND->getNameAsString()));
Douglas Gregor218937c2011-02-01 19:23:04 +00002780 return Result.TakeString();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002781}
2782
Douglas Gregor86d802e2009-09-23 00:34:09 +00002783CodeCompletionString *
2784CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2785 unsigned CurrentArg,
Douglas Gregor32be4a52010-10-11 21:37:58 +00002786 Sema &S,
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00002787 CodeCompletionAllocator &Allocator,
2788 CodeCompletionTUInfo &CCTUInfo) const {
Douglas Gregor8987b232011-09-27 23:30:47 +00002789 PrintingPolicy Policy = getCompletionPrintingPolicy(S);
John McCallf85e1932011-06-15 23:02:42 +00002790
Douglas Gregor218937c2011-02-01 19:23:04 +00002791 // FIXME: Set priority, availability appropriately.
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00002792 CodeCompletionBuilder Result(Allocator,CCTUInfo, 1, CXAvailability_Available);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002793 FunctionDecl *FDecl = getFunction();
Douglas Gregor8987b232011-09-27 23:30:47 +00002794 AddResultTypeChunk(S.Context, Policy, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002795 const FunctionProtoType *Proto
2796 = dyn_cast<FunctionProtoType>(getFunctionType());
2797 if (!FDecl && !Proto) {
2798 // Function without a prototype. Just give the return type and a
2799 // highlighted ellipsis.
2800 const FunctionType *FT = getFunctionType();
Douglas Gregora63f6de2011-02-01 21:15:40 +00002801 Result.AddTextChunk(GetCompletionTypeString(FT->getResultType(),
Douglas Gregor8987b232011-09-27 23:30:47 +00002802 S.Context, Policy,
Douglas Gregora63f6de2011-02-01 21:15:40 +00002803 Result.getAllocator()));
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002804 Result.AddChunk(CodeCompletionString::CK_LeftParen);
2805 Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
2806 Result.AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor218937c2011-02-01 19:23:04 +00002807 return Result.TakeString();
Douglas Gregor86d802e2009-09-23 00:34:09 +00002808 }
2809
2810 if (FDecl)
Douglas Gregordae68752011-02-01 22:57:45 +00002811 Result.AddTextChunk(
2812 Result.getAllocator().CopyString(FDecl->getNameAsString()));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002813 else
Douglas Gregor218937c2011-02-01 19:23:04 +00002814 Result.AddTextChunk(
Douglas Gregordae68752011-02-01 22:57:45 +00002815 Result.getAllocator().CopyString(
John McCallf85e1932011-06-15 23:02:42 +00002816 Proto->getResultType().getAsString(Policy)));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002817
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002818 Result.AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002819 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2820 for (unsigned I = 0; I != NumParams; ++I) {
2821 if (I)
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002822 Result.AddChunk(CodeCompletionString::CK_Comma);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002823
2824 std::string ArgString;
2825 QualType ArgType;
2826
2827 if (FDecl) {
2828 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2829 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2830 } else {
2831 ArgType = Proto->getArgType(I);
2832 }
2833
John McCallf85e1932011-06-15 23:02:42 +00002834 ArgType.getAsStringInternal(ArgString, Policy);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002835
2836 if (I == CurrentArg)
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002837 Result.AddChunk(CodeCompletionString::CK_CurrentParameter,
2838 Result.getAllocator().CopyString(ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002839 else
Douglas Gregordae68752011-02-01 22:57:45 +00002840 Result.AddTextChunk(Result.getAllocator().CopyString(ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002841 }
2842
2843 if (Proto && Proto->isVariadic()) {
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002844 Result.AddChunk(CodeCompletionString::CK_Comma);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002845 if (CurrentArg < NumParams)
Douglas Gregor218937c2011-02-01 19:23:04 +00002846 Result.AddTextChunk("...");
Douglas Gregor86d802e2009-09-23 00:34:09 +00002847 else
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002848 Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
Douglas Gregor86d802e2009-09-23 00:34:09 +00002849 }
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00002850 Result.AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002851
Douglas Gregor218937c2011-02-01 19:23:04 +00002852 return Result.TakeString();
Douglas Gregor86d802e2009-09-23 00:34:09 +00002853}
2854
Chris Lattner5f9e2722011-07-23 10:55:15 +00002855unsigned clang::getMacroUsagePriority(StringRef MacroName,
Douglas Gregorb05496d2010-09-20 21:11:48 +00002856 const LangOptions &LangOpts,
Douglas Gregor1827e102010-08-16 16:18:59 +00002857 bool PreferredTypeIsPointer) {
2858 unsigned Priority = CCP_Macro;
2859
Douglas Gregorb05496d2010-09-20 21:11:48 +00002860 // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
2861 if (MacroName.equals("nil") || MacroName.equals("NULL") ||
2862 MacroName.equals("Nil")) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002863 Priority = CCP_Constant;
2864 if (PreferredTypeIsPointer)
2865 Priority = Priority / CCF_SimilarTypeMatch;
Douglas Gregorb05496d2010-09-20 21:11:48 +00002866 }
2867 // Treat "YES", "NO", "true", and "false" as constants.
2868 else if (MacroName.equals("YES") || MacroName.equals("NO") ||
2869 MacroName.equals("true") || MacroName.equals("false"))
2870 Priority = CCP_Constant;
2871 // Treat "bool" as a type.
2872 else if (MacroName.equals("bool"))
2873 Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
2874
Douglas Gregor1827e102010-08-16 16:18:59 +00002875
2876 return Priority;
2877}
2878
Dmitri Gribenko06d8c602013-01-11 20:32:41 +00002879CXCursorKind clang::getCursorKindForDecl(const Decl *D) {
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002880 if (!D)
2881 return CXCursor_UnexposedDecl;
2882
2883 switch (D->getKind()) {
2884 case Decl::Enum: return CXCursor_EnumDecl;
2885 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
2886 case Decl::Field: return CXCursor_FieldDecl;
2887 case Decl::Function:
2888 return CXCursor_FunctionDecl;
2889 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
2890 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002891 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
Douglas Gregor375bb142011-12-27 22:43:10 +00002892
Argyrios Kyrtzidisc15707d2012-01-24 21:39:26 +00002893 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002894 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
2895 case Decl::ObjCMethod:
2896 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2897 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2898 case Decl::CXXMethod: return CXCursor_CXXMethod;
2899 case Decl::CXXConstructor: return CXCursor_Constructor;
2900 case Decl::CXXDestructor: return CXCursor_Destructor;
2901 case Decl::CXXConversion: return CXCursor_ConversionFunction;
2902 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
Argyrios Kyrtzidisc15707d2012-01-24 21:39:26 +00002903 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002904 case Decl::ParmVar: return CXCursor_ParmDecl;
2905 case Decl::Typedef: return CXCursor_TypedefDecl;
Richard Smith162e1c12011-04-15 14:24:37 +00002906 case Decl::TypeAlias: return CXCursor_TypeAliasDecl;
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002907 case Decl::Var: return CXCursor_VarDecl;
2908 case Decl::Namespace: return CXCursor_Namespace;
2909 case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
2910 case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
2911 case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2912 case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2913 case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
2914 case Decl::ClassTemplate: return CXCursor_ClassTemplate;
Argyrios Kyrtzidis2dfdb942011-09-30 17:58:23 +00002915 case Decl::AccessSpec: return CXCursor_CXXAccessSpecifier;
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002916 case Decl::ClassTemplatePartialSpecialization:
2917 return CXCursor_ClassTemplatePartialSpecialization;
2918 case Decl::UsingDirective: return CXCursor_UsingDirective;
Douglas Gregor8e5900c2012-04-30 23:41:16 +00002919 case Decl::TranslationUnit: return CXCursor_TranslationUnit;
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002920
2921 case Decl::Using:
2922 case Decl::UnresolvedUsingValue:
2923 case Decl::UnresolvedUsingTypename:
2924 return CXCursor_UsingDeclaration;
2925
Douglas Gregor352697a2011-06-03 23:08:58 +00002926 case Decl::ObjCPropertyImpl:
2927 switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) {
2928 case ObjCPropertyImplDecl::Dynamic:
2929 return CXCursor_ObjCDynamicDecl;
2930
2931 case ObjCPropertyImplDecl::Synthesize:
2932 return CXCursor_ObjCSynthesizeDecl;
2933 }
Argyrios Kyrtzidis6a010122012-10-05 00:22:24 +00002934
2935 case Decl::Import:
2936 return CXCursor_ModuleImportDecl;
Douglas Gregor352697a2011-06-03 23:08:58 +00002937
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002938 default:
Dmitri Gribenko06d8c602013-01-11 20:32:41 +00002939 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002940 switch (TD->getTagKind()) {
Joao Matos6666ed42012-08-31 18:45:21 +00002941 case TTK_Interface: // fall through
Douglas Gregore8d7beb2010-09-03 23:30:36 +00002942 case TTK_Struct: return CXCursor_StructDecl;
2943 case TTK_Class: return CXCursor_ClassDecl;
2944 case TTK_Union: return CXCursor_UnionDecl;
2945 case TTK_Enum: return CXCursor_EnumDecl;
2946 }
2947 }
2948 }
2949
2950 return CXCursor_UnexposedDecl;
2951}
2952
Douglas Gregor590c7d52010-07-08 20:55:51 +00002953static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
Douglas Gregor3644d972012-10-09 16:01:50 +00002954 bool IncludeUndefined,
Douglas Gregor590c7d52010-07-08 20:55:51 +00002955 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002956 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002957
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002958 Results.EnterNewScope();
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002959
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002960 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2961 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002962 M != MEnd; ++M) {
Douglas Gregor3644d972012-10-09 16:01:50 +00002963 if (IncludeUndefined || M->first->hasMacroDefinition())
2964 Results.AddResult(Result(M->first,
Douglas Gregor1827e102010-08-16 16:18:59 +00002965 getMacroUsagePriority(M->first->getName(),
David Blaikie4e4d0842012-03-11 07:00:24 +00002966 PP.getLangOpts(),
Douglas Gregor1827e102010-08-16 16:18:59 +00002967 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002968 }
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002969
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002970 Results.ExitScope();
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002971
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002972}
2973
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002974static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2975 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002976 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002977
2978 Results.EnterNewScope();
Douglas Gregorc7b7b7a2010-10-18 21:05:04 +00002979
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002980 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2981 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
Richard Smith80ad52f2013-01-02 11:42:31 +00002982 if (LangOpts.C99 || LangOpts.CPlusPlus11)
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002983 Results.AddResult(Result("__func__", CCP_Constant));
2984 Results.ExitScope();
2985}
2986
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002987static void HandleCodeCompleteResults(Sema *S,
2988 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002989 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002990 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002991 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002992 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002993 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002994}
2995
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002996static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2997 Sema::ParserCompletionContext PCC) {
2998 switch (PCC) {
John McCallf312b1e2010-08-26 23:41:50 +00002999 case Sema::PCC_Namespace:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003000 return CodeCompletionContext::CCC_TopLevel;
3001
John McCallf312b1e2010-08-26 23:41:50 +00003002 case Sema::PCC_Class:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003003 return CodeCompletionContext::CCC_ClassStructUnion;
3004
John McCallf312b1e2010-08-26 23:41:50 +00003005 case Sema::PCC_ObjCInterface:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003006 return CodeCompletionContext::CCC_ObjCInterface;
3007
John McCallf312b1e2010-08-26 23:41:50 +00003008 case Sema::PCC_ObjCImplementation:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003009 return CodeCompletionContext::CCC_ObjCImplementation;
3010
John McCallf312b1e2010-08-26 23:41:50 +00003011 case Sema::PCC_ObjCInstanceVariableList:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003012 return CodeCompletionContext::CCC_ObjCIvarList;
3013
John McCallf312b1e2010-08-26 23:41:50 +00003014 case Sema::PCC_Template:
3015 case Sema::PCC_MemberTemplate:
Douglas Gregor52779fb2010-09-23 23:01:17 +00003016 if (S.CurContext->isFileContext())
3017 return CodeCompletionContext::CCC_TopLevel;
David Blaikie7530c032012-01-17 06:56:22 +00003018 if (S.CurContext->isRecord())
Douglas Gregor52779fb2010-09-23 23:01:17 +00003019 return CodeCompletionContext::CCC_ClassStructUnion;
David Blaikie7530c032012-01-17 06:56:22 +00003020 return CodeCompletionContext::CCC_Other;
Douglas Gregor52779fb2010-09-23 23:01:17 +00003021
John McCallf312b1e2010-08-26 23:41:50 +00003022 case Sema::PCC_RecoveryInFunction:
Douglas Gregor52779fb2010-09-23 23:01:17 +00003023 return CodeCompletionContext::CCC_Recovery;
Douglas Gregora5450a02010-10-18 22:01:46 +00003024
John McCallf312b1e2010-08-26 23:41:50 +00003025 case Sema::PCC_ForInit:
David Blaikie4e4d0842012-03-11 07:00:24 +00003026 if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 ||
3027 S.getLangOpts().ObjC1)
Douglas Gregora5450a02010-10-18 22:01:46 +00003028 return CodeCompletionContext::CCC_ParenthesizedExpression;
3029 else
3030 return CodeCompletionContext::CCC_Expression;
3031
3032 case Sema::PCC_Expression:
John McCallf312b1e2010-08-26 23:41:50 +00003033 case Sema::PCC_Condition:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003034 return CodeCompletionContext::CCC_Expression;
3035
John McCallf312b1e2010-08-26 23:41:50 +00003036 case Sema::PCC_Statement:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003037 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00003038
John McCallf312b1e2010-08-26 23:41:50 +00003039 case Sema::PCC_Type:
Douglas Gregor72db1082010-08-24 01:11:00 +00003040 return CodeCompletionContext::CCC_Type;
Douglas Gregor02688102010-09-14 23:59:36 +00003041
3042 case Sema::PCC_ParenthesizedExpression:
3043 return CodeCompletionContext::CCC_ParenthesizedExpression;
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00003044
3045 case Sema::PCC_LocalDeclarationSpecifiers:
3046 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003047 }
David Blaikie7530c032012-01-17 06:56:22 +00003048
3049 llvm_unreachable("Invalid ParserCompletionContext!");
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003050}
3051
Douglas Gregorf6961522010-08-27 21:18:54 +00003052/// \brief If we're in a C++ virtual member function, add completion results
3053/// that invoke the functions we override, since it's common to invoke the
3054/// overridden function as well as adding new functionality.
3055///
3056/// \param S The semantic analysis object for which we are generating results.
3057///
3058/// \param InContext This context in which the nested-name-specifier preceding
3059/// the code-completion point
3060static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
3061 ResultBuilder &Results) {
3062 // Look through blocks.
3063 DeclContext *CurContext = S.CurContext;
3064 while (isa<BlockDecl>(CurContext))
3065 CurContext = CurContext->getParent();
3066
3067
3068 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
3069 if (!Method || !Method->isVirtual())
3070 return;
3071
3072 // We need to have names for all of the parameters, if we're going to
3073 // generate a forwarding call.
3074 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
3075 PEnd = Method->param_end();
3076 P != PEnd;
3077 ++P) {
3078 if (!(*P)->getDeclName())
3079 return;
3080 }
3081
Douglas Gregor8987b232011-09-27 23:30:47 +00003082 PrintingPolicy Policy = getCompletionPrintingPolicy(S);
Douglas Gregorf6961522010-08-27 21:18:54 +00003083 for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
3084 MEnd = Method->end_overridden_methods();
3085 M != MEnd; ++M) {
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003086 CodeCompletionBuilder Builder(Results.getAllocator(),
3087 Results.getCodeCompletionTUInfo());
Douglas Gregorf6961522010-08-27 21:18:54 +00003088 CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
3089 if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
3090 continue;
3091
3092 // If we need a nested-name-specifier, add one now.
3093 if (!InContext) {
3094 NestedNameSpecifier *NNS
3095 = getRequiredQualification(S.Context, CurContext,
3096 Overridden->getDeclContext());
3097 if (NNS) {
3098 std::string Str;
3099 llvm::raw_string_ostream OS(Str);
Douglas Gregor8987b232011-09-27 23:30:47 +00003100 NNS->print(OS, Policy);
Douglas Gregordae68752011-02-01 22:57:45 +00003101 Builder.AddTextChunk(Results.getAllocator().CopyString(OS.str()));
Douglas Gregorf6961522010-08-27 21:18:54 +00003102 }
3103 } else if (!InContext->Equals(Overridden->getDeclContext()))
3104 continue;
3105
Douglas Gregordae68752011-02-01 22:57:45 +00003106 Builder.AddTypedTextChunk(Results.getAllocator().CopyString(
Douglas Gregor218937c2011-02-01 19:23:04 +00003107 Overridden->getNameAsString()));
3108 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregorf6961522010-08-27 21:18:54 +00003109 bool FirstParam = true;
3110 for (CXXMethodDecl::param_iterator P = Method->param_begin(),
3111 PEnd = Method->param_end();
3112 P != PEnd; ++P) {
3113 if (FirstParam)
3114 FirstParam = false;
3115 else
Douglas Gregor218937c2011-02-01 19:23:04 +00003116 Builder.AddChunk(CodeCompletionString::CK_Comma);
Douglas Gregorf6961522010-08-27 21:18:54 +00003117
Douglas Gregordae68752011-02-01 22:57:45 +00003118 Builder.AddPlaceholderChunk(Results.getAllocator().CopyString(
Douglas Gregor218937c2011-02-01 19:23:04 +00003119 (*P)->getIdentifier()->getName()));
Douglas Gregorf6961522010-08-27 21:18:54 +00003120 }
Douglas Gregor218937c2011-02-01 19:23:04 +00003121 Builder.AddChunk(CodeCompletionString::CK_RightParen);
3122 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
Douglas Gregorf6961522010-08-27 21:18:54 +00003123 CCP_SuperCompletion,
Douglas Gregorba103062012-03-27 23:34:16 +00003124 CXCursor_CXXMethod,
3125 CXAvailability_Available,
3126 Overridden));
Douglas Gregorf6961522010-08-27 21:18:54 +00003127 Results.Ignore(Overridden);
3128 }
3129}
3130
Douglas Gregorc5b2e582012-01-29 18:15:03 +00003131void Sema::CodeCompleteModuleImport(SourceLocation ImportLoc,
3132 ModuleIdPath Path) {
3133 typedef CodeCompletionResult Result;
3134 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003135 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregorc5b2e582012-01-29 18:15:03 +00003136 CodeCompletionContext::CCC_Other);
3137 Results.EnterNewScope();
3138
3139 CodeCompletionAllocator &Allocator = Results.getAllocator();
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003140 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
Douglas Gregorc5b2e582012-01-29 18:15:03 +00003141 typedef CodeCompletionResult Result;
3142 if (Path.empty()) {
3143 // Enumerate all top-level modules.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00003144 SmallVector<Module *, 8> Modules;
Douglas Gregorc5b2e582012-01-29 18:15:03 +00003145 PP.getHeaderSearchInfo().collectAllModules(Modules);
3146 for (unsigned I = 0, N = Modules.size(); I != N; ++I) {
3147 Builder.AddTypedTextChunk(
3148 Builder.getAllocator().CopyString(Modules[I]->Name));
3149 Results.AddResult(Result(Builder.TakeString(),
3150 CCP_Declaration,
3151 CXCursor_NotImplemented,
3152 Modules[I]->isAvailable()
3153 ? CXAvailability_Available
3154 : CXAvailability_NotAvailable));
3155 }
3156 } else {
3157 // Load the named module.
3158 Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path,
3159 Module::AllVisible,
3160 /*IsInclusionDirective=*/false);
3161 // Enumerate submodules.
3162 if (Mod) {
3163 for (Module::submodule_iterator Sub = Mod->submodule_begin(),
3164 SubEnd = Mod->submodule_end();
3165 Sub != SubEnd; ++Sub) {
3166
3167 Builder.AddTypedTextChunk(
3168 Builder.getAllocator().CopyString((*Sub)->Name));
3169 Results.AddResult(Result(Builder.TakeString(),
3170 CCP_Declaration,
3171 CXCursor_NotImplemented,
3172 (*Sub)->isAvailable()
3173 ? CXAvailability_Available
3174 : CXAvailability_NotAvailable));
3175 }
3176 }
3177 }
3178 Results.ExitScope();
3179 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3180 Results.data(),Results.size());
3181}
3182
Douglas Gregor01dfea02010-01-10 23:08:15 +00003183void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003184 ParserCompletionContext CompletionContext) {
Douglas Gregor218937c2011-02-01 19:23:04 +00003185 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003186 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor52779fb2010-09-23 23:01:17 +00003187 mapCodeCompletionContext(*this, CompletionContext));
Douglas Gregorf6961522010-08-27 21:18:54 +00003188 Results.EnterNewScope();
Douglas Gregorcee9ff12010-09-20 22:39:41 +00003189
Douglas Gregor01dfea02010-01-10 23:08:15 +00003190 // Determine how to filter results, e.g., so that the names of
3191 // values (functions, enumerators, function templates, etc.) are
3192 // only allowed where we can have an expression.
3193 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003194 case PCC_Namespace:
3195 case PCC_Class:
3196 case PCC_ObjCInterface:
3197 case PCC_ObjCImplementation:
3198 case PCC_ObjCInstanceVariableList:
3199 case PCC_Template:
3200 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00003201 case PCC_Type:
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00003202 case PCC_LocalDeclarationSpecifiers:
Douglas Gregor01dfea02010-01-10 23:08:15 +00003203 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3204 break;
3205
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003206 case PCC_Statement:
Douglas Gregor02688102010-09-14 23:59:36 +00003207 case PCC_ParenthesizedExpression:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00003208 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003209 case PCC_ForInit:
3210 case PCC_Condition:
David Blaikie4e4d0842012-03-11 07:00:24 +00003211 if (WantTypesInContext(CompletionContext, getLangOpts()))
Douglas Gregor4710e5b2010-05-28 00:49:12 +00003212 Results.setFilter(&ResultBuilder::IsOrdinaryName);
3213 else
3214 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorf6961522010-08-27 21:18:54 +00003215
David Blaikie4e4d0842012-03-11 07:00:24 +00003216 if (getLangOpts().CPlusPlus)
Douglas Gregorf6961522010-08-27 21:18:54 +00003217 MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00003218 break;
Douglas Gregordc845342010-05-25 05:58:43 +00003219
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003220 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00003221 // Unfiltered
3222 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00003223 }
3224
Douglas Gregor3cdee122010-08-26 16:36:48 +00003225 // If we are in a C++ non-static member function, check the qualifiers on
3226 // the member function to filter/prioritize the results list.
3227 if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
3228 if (CurMethod->isInstance())
3229 Results.setObjectTypeQualifiers(
3230 Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
3231
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00003232 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003233 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3234 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00003235
Douglas Gregorbca403c2010-01-13 23:51:12 +00003236 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00003237 Results.ExitScope();
3238
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00003239 switch (CompletionContext) {
Douglas Gregor02688102010-09-14 23:59:36 +00003240 case PCC_ParenthesizedExpression:
Douglas Gregor72db1082010-08-24 01:11:00 +00003241 case PCC_Expression:
3242 case PCC_Statement:
3243 case PCC_RecoveryInFunction:
3244 if (S->getFnParent())
David Blaikie4e4d0842012-03-11 07:00:24 +00003245 AddPrettyFunctionResults(PP.getLangOpts(), Results);
Douglas Gregor72db1082010-08-24 01:11:00 +00003246 break;
3247
3248 case PCC_Namespace:
3249 case PCC_Class:
3250 case PCC_ObjCInterface:
3251 case PCC_ObjCImplementation:
3252 case PCC_ObjCInstanceVariableList:
3253 case PCC_Template:
3254 case PCC_MemberTemplate:
3255 case PCC_ForInit:
3256 case PCC_Condition:
3257 case PCC_Type:
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00003258 case PCC_LocalDeclarationSpecifiers:
Douglas Gregor72db1082010-08-24 01:11:00 +00003259 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00003260 }
3261
Douglas Gregor0c8296d2009-11-07 00:00:49 +00003262 if (CodeCompleter->includeMacros())
Douglas Gregor3644d972012-10-09 16:01:50 +00003263 AddMacroResults(PP, Results, false);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00003264
Douglas Gregorcee9ff12010-09-20 22:39:41 +00003265 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003266 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00003267}
3268
Douglas Gregorc7b6d882010-09-16 15:14:18 +00003269static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
3270 ParsedType Receiver,
3271 IdentifierInfo **SelIdents,
3272 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00003273 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00003274 bool IsSuper,
3275 ResultBuilder &Results);
3276
3277void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
3278 bool AllowNonIdentifiers,
3279 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00003280 typedef CodeCompletionResult Result;
Douglas Gregor218937c2011-02-01 19:23:04 +00003281 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003282 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor52779fb2010-09-23 23:01:17 +00003283 AllowNestedNameSpecifiers
3284 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
3285 : CodeCompletionContext::CCC_Name);
Douglas Gregor2ccccb32010-08-23 18:23:48 +00003286 Results.EnterNewScope();
3287
3288 // Type qualifiers can come after names.
3289 Results.AddResult(Result("const"));
3290 Results.AddResult(Result("volatile"));
David Blaikie4e4d0842012-03-11 07:00:24 +00003291 if (getLangOpts().C99)
Douglas Gregor2ccccb32010-08-23 18:23:48 +00003292 Results.AddResult(Result("restrict"));
3293
David Blaikie4e4d0842012-03-11 07:00:24 +00003294 if (getLangOpts().CPlusPlus) {
Douglas Gregor2ccccb32010-08-23 18:23:48 +00003295 if (AllowNonIdentifiers) {
3296 Results.AddResult(Result("operator"));
3297 }
3298
3299 // Add nested-name-specifiers.
3300 if (AllowNestedNameSpecifiers) {
3301 Results.allowNestedNameSpecifiers();
Douglas Gregor52779fb2010-09-23 23:01:17 +00003302 Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
Douglas Gregor2ccccb32010-08-23 18:23:48 +00003303 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3304 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
3305 CodeCompleter->includeGlobals());
Douglas Gregor52779fb2010-09-23 23:01:17 +00003306 Results.setFilter(0);
Douglas Gregor2ccccb32010-08-23 18:23:48 +00003307 }
3308 }
3309 Results.ExitScope();
3310
Douglas Gregorc7b6d882010-09-16 15:14:18 +00003311 // If we're in a context where we might have an expression (rather than a
3312 // declaration), and what we've seen so far is an Objective-C type that could
3313 // be a receiver of a class message, this may be a class message send with
3314 // the initial opening bracket '[' missing. Add appropriate completions.
3315 if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
3316 DS.getTypeSpecType() == DeclSpec::TST_typename &&
3317 DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified &&
3318 !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
3319 DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
3320 DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
3321 DS.getTypeQualifiers() == 0 &&
3322 S &&
3323 (S->getFlags() & Scope::DeclScope) != 0 &&
3324 (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
3325 Scope::FunctionPrototypeScope |
3326 Scope::AtCatchScope)) == 0) {
3327 ParsedType T = DS.getRepAsType();
3328 if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
Douglas Gregor70c5ac72010-09-20 23:34:21 +00003329 AddClassMessageCompletions(*this, S, T, 0, 0, false, false, Results);
Douglas Gregorc7b6d882010-09-16 15:14:18 +00003330 }
3331
Douglas Gregor4497dd42010-08-24 04:59:56 +00003332 // Note that we intentionally suppress macro results here, since we do not
3333 // encourage using macros to produce the names of entities.
3334
Douglas Gregor52779fb2010-09-23 23:01:17 +00003335 HandleCodeCompleteResults(this, CodeCompleter,
3336 Results.getCompletionContext(),
Douglas Gregor2ccccb32010-08-23 18:23:48 +00003337 Results.data(), Results.size());
3338}
3339
Douglas Gregorfb629412010-08-23 21:17:50 +00003340struct Sema::CodeCompleteExpressionData {
3341 CodeCompleteExpressionData(QualType PreferredType = QualType())
3342 : PreferredType(PreferredType), IntegralConstantExpression(false),
3343 ObjCCollection(false) { }
3344
3345 QualType PreferredType;
3346 bool IntegralConstantExpression;
3347 bool ObjCCollection;
Chris Lattner5f9e2722011-07-23 10:55:15 +00003348 SmallVector<Decl *, 4> IgnoreDecls;
Douglas Gregorfb629412010-08-23 21:17:50 +00003349};
3350
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003351/// \brief Perform code-completion in an expression context when we know what
3352/// type we're looking for.
Douglas Gregorfb629412010-08-23 21:17:50 +00003353void Sema::CodeCompleteExpression(Scope *S,
3354 const CodeCompleteExpressionData &Data) {
Douglas Gregor218937c2011-02-01 19:23:04 +00003355 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003356 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00003357 CodeCompletionContext::CCC_Expression);
Douglas Gregorfb629412010-08-23 21:17:50 +00003358 if (Data.ObjCCollection)
3359 Results.setFilter(&ResultBuilder::IsObjCCollection);
3360 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00003361 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
David Blaikie4e4d0842012-03-11 07:00:24 +00003362 else if (WantTypesInContext(PCC_Expression, getLangOpts()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003363 Results.setFilter(&ResultBuilder::IsOrdinaryName);
3364 else
3365 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00003366
3367 if (!Data.PreferredType.isNull())
3368 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
3369
3370 // Ignore any declarations that we were told that we don't care about.
3371 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
3372 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003373
3374 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003375 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3376 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003377
3378 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003379 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003380 Results.ExitScope();
3381
Douglas Gregor590c7d52010-07-08 20:55:51 +00003382 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00003383 if (!Data.PreferredType.isNull())
3384 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
3385 || Data.PreferredType->isMemberPointerType()
3386 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00003387
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00003388 if (S->getFnParent() &&
3389 !Data.ObjCCollection &&
3390 !Data.IntegralConstantExpression)
David Blaikie4e4d0842012-03-11 07:00:24 +00003391 AddPrettyFunctionResults(PP.getLangOpts(), Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00003392
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003393 if (CodeCompleter->includeMacros())
Douglas Gregor3644d972012-10-09 16:01:50 +00003394 AddMacroResults(PP, Results, false, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003395 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00003396 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
3397 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003398 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003399}
3400
Douglas Gregorac5fd842010-09-18 01:28:11 +00003401void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
3402 if (E.isInvalid())
3403 CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
David Blaikie4e4d0842012-03-11 07:00:24 +00003404 else if (getLangOpts().ObjC1)
Douglas Gregorac5fd842010-09-18 01:28:11 +00003405 CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
Douglas Gregor78edf512010-09-15 16:23:04 +00003406}
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003407
Douglas Gregor73449212010-12-09 23:01:55 +00003408/// \brief The set of properties that have already been added, referenced by
3409/// property name.
3410typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
3411
Douglas Gregorb92a4082012-06-12 13:44:08 +00003412/// \brief Retrieve the container definition, if any?
3413static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) {
3414 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
3415 if (Interface->hasDefinition())
3416 return Interface->getDefinition();
3417
3418 return Interface;
3419 }
3420
3421 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3422 if (Protocol->hasDefinition())
3423 return Protocol->getDefinition();
3424
3425 return Protocol;
3426 }
3427 return Container;
3428}
3429
3430static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00003431 bool AllowCategories,
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003432 bool AllowNullaryMethods,
Douglas Gregor95ac6552009-11-18 01:29:26 +00003433 DeclContext *CurContext,
Douglas Gregor73449212010-12-09 23:01:55 +00003434 AddedPropertiesSet &AddedProperties,
Douglas Gregor95ac6552009-11-18 01:29:26 +00003435 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00003436 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00003437
Douglas Gregorb92a4082012-06-12 13:44:08 +00003438 // Retrieve the definition.
3439 Container = getContainerDef(Container);
3440
Douglas Gregor95ac6552009-11-18 01:29:26 +00003441 // Add properties in this container.
3442 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
3443 PEnd = Container->prop_end();
3444 P != PEnd;
Douglas Gregor73449212010-12-09 23:01:55 +00003445 ++P) {
3446 if (AddedProperties.insert(P->getIdentifier()))
Douglas Gregord1f09b42013-01-31 04:52:16 +00003447 Results.MaybeAddResult(Result(*P, Results.getBasePriority(*P), 0),
3448 CurContext);
Douglas Gregor73449212010-12-09 23:01:55 +00003449 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00003450
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003451 // Add nullary methods
3452 if (AllowNullaryMethods) {
3453 ASTContext &Context = Container->getASTContext();
Douglas Gregor8987b232011-09-27 23:30:47 +00003454 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003455 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3456 MEnd = Container->meth_end();
3457 M != MEnd; ++M) {
3458 if (M->getSelector().isUnarySelector())
3459 if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0))
3460 if (AddedProperties.insert(Name)) {
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003461 CodeCompletionBuilder Builder(Results.getAllocator(),
3462 Results.getCodeCompletionTUInfo());
David Blaikie581deb32012-06-06 20:45:41 +00003463 AddResultTypeChunk(Context, Policy, *M, Builder);
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003464 Builder.AddTypedTextChunk(
3465 Results.getAllocator().CopyString(Name->getName()));
3466
David Blaikie581deb32012-06-06 20:45:41 +00003467 Results.MaybeAddResult(Result(Builder.TakeString(), *M,
Douglas Gregorba103062012-03-27 23:34:16 +00003468 CCP_MemberDeclaration + CCD_MethodAsProperty),
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003469 CurContext);
3470 }
3471 }
3472 }
3473
3474
Douglas Gregor95ac6552009-11-18 01:29:26 +00003475 // Add properties in referenced protocols.
3476 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3477 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
3478 PEnd = Protocol->protocol_end();
3479 P != PEnd; ++P)
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003480 AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
3481 AddedProperties, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003482 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00003483 if (AllowCategories) {
3484 // Look through categories.
Douglas Gregord3297242013-01-16 23:00:23 +00003485 for (ObjCInterfaceDecl::known_categories_iterator
3486 Cat = IFace->known_categories_begin(),
3487 CatEnd = IFace->known_categories_end();
3488 Cat != CatEnd; ++Cat)
3489 AddObjCProperties(*Cat, AllowCategories, AllowNullaryMethods,
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003490 CurContext, AddedProperties, Results);
Douglas Gregor322328b2009-11-18 22:32:06 +00003491 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00003492
3493 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00003494 for (ObjCInterfaceDecl::all_protocol_iterator
3495 I = IFace->all_referenced_protocol_begin(),
3496 E = IFace->all_referenced_protocol_end(); I != E; ++I)
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003497 AddObjCProperties(*I, AllowCategories, AllowNullaryMethods, CurContext,
3498 AddedProperties, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003499
3500 // Look in the superclass.
3501 if (IFace->getSuperClass())
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003502 AddObjCProperties(IFace->getSuperClass(), AllowCategories,
3503 AllowNullaryMethods, CurContext,
Douglas Gregor73449212010-12-09 23:01:55 +00003504 AddedProperties, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003505 } else if (const ObjCCategoryDecl *Category
3506 = dyn_cast<ObjCCategoryDecl>(Container)) {
3507 // Look through protocols.
Ted Kremenek53b94412010-09-01 01:21:15 +00003508 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
3509 PEnd = Category->protocol_end();
Douglas Gregor95ac6552009-11-18 01:29:26 +00003510 P != PEnd; ++P)
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003511 AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
3512 AddedProperties, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003513 }
3514}
3515
Douglas Gregorf5cd27d2012-01-23 15:59:30 +00003516void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003517 SourceLocation OpLoc,
3518 bool IsArrow) {
Douglas Gregorf5cd27d2012-01-23 15:59:30 +00003519 if (!Base || !CodeCompleter)
Douglas Gregor81b747b2009-09-17 21:32:03 +00003520 return;
3521
Douglas Gregorf5cd27d2012-01-23 15:59:30 +00003522 ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
3523 if (ConvertedBase.isInvalid())
3524 return;
3525 Base = ConvertedBase.get();
3526
John McCall0a2c5e22010-08-25 06:19:51 +00003527 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003528
Douglas Gregor81b747b2009-09-17 21:32:03 +00003529 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003530
3531 if (IsArrow) {
3532 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
3533 BaseType = Ptr->getPointeeType();
3534 else if (BaseType->isObjCObjectPointerType())
Douglas Gregor3cdee122010-08-26 16:36:48 +00003535 /*Do nothing*/ ;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003536 else
3537 return;
3538 }
3539
Douglas Gregor3da626b2011-07-07 16:03:39 +00003540 enum CodeCompletionContext::Kind contextKind;
3541
3542 if (IsArrow) {
3543 contextKind = CodeCompletionContext::CCC_ArrowMemberAccess;
3544 }
3545 else {
3546 if (BaseType->isObjCObjectPointerType() ||
3547 BaseType->isObjCObjectOrInterfaceType()) {
3548 contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess;
3549 }
3550 else {
3551 contextKind = CodeCompletionContext::CCC_DotMemberAccess;
3552 }
3553 }
3554
Douglas Gregor218937c2011-02-01 19:23:04 +00003555 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003556 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor3da626b2011-07-07 16:03:39 +00003557 CodeCompletionContext(contextKind,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003558 BaseType),
3559 &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003560 Results.EnterNewScope();
3561 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregor3cdee122010-08-26 16:36:48 +00003562 // Indicate that we are performing a member access, and the cv-qualifiers
3563 // for the base object type.
3564 Results.setObjectTypeQualifiers(BaseType.getQualifiers());
3565
Douglas Gregor95ac6552009-11-18 01:29:26 +00003566 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00003567 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00003568 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003569 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
3570 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003571
David Blaikie4e4d0842012-03-11 07:00:24 +00003572 if (getLangOpts().CPlusPlus) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00003573 if (!Results.empty()) {
3574 // The "template" keyword can follow "->" or "." in the grammar.
3575 // However, we only want to suggest the template keyword if something
3576 // is dependent.
3577 bool IsDependent = BaseType->isDependentType();
3578 if (!IsDependent) {
3579 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
3580 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
3581 IsDependent = Ctx->isDependentContext();
3582 break;
3583 }
3584 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003585
Douglas Gregor95ac6552009-11-18 01:29:26 +00003586 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00003587 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003588 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003589 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00003590 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
3591 // Objective-C property reference.
Douglas Gregor73449212010-12-09 23:01:55 +00003592 AddedPropertiesSet AddedProperties;
Douglas Gregor95ac6552009-11-18 01:29:26 +00003593
3594 // Add property results based on our interface.
3595 const ObjCObjectPointerType *ObjCPtr
3596 = BaseType->getAsObjCInterfacePointerType();
3597 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003598 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true,
3599 /*AllowNullaryMethods=*/true, CurContext,
Douglas Gregor73449212010-12-09 23:01:55 +00003600 AddedProperties, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003601
3602 // Add properties from the protocols in a qualified interface.
3603 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
3604 E = ObjCPtr->qual_end();
3605 I != E; ++I)
Douglas Gregor4b81cde2011-05-05 15:50:42 +00003606 AddObjCProperties(*I, true, /*AllowNullaryMethods=*/true, CurContext,
3607 AddedProperties, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00003608 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00003609 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00003610 // Objective-C instance variable access.
3611 ObjCInterfaceDecl *Class = 0;
3612 if (const ObjCObjectPointerType *ObjCPtr
3613 = BaseType->getAs<ObjCObjectPointerType>())
3614 Class = ObjCPtr->getInterfaceDecl();
3615 else
John McCallc12c5bb2010-05-15 11:32:37 +00003616 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00003617
3618 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00003619 if (Class) {
3620 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3621 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00003622 LookupVisibleDecls(Class, LookupMemberName, Consumer,
3623 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00003624 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003625 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00003626
3627 // FIXME: How do we cope with isa?
3628
3629 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003630
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003631 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003632 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003633 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003634 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003635}
3636
Douglas Gregor374929f2009-09-18 15:37:17 +00003637void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
3638 if (!CodeCompleter)
3639 return;
3640
Douglas Gregor86d9a522009-09-21 16:56:56 +00003641 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003642 enum CodeCompletionContext::Kind ContextKind
3643 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00003644 switch ((DeclSpec::TST)TagSpec) {
3645 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003646 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003647 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003648 break;
3649
3650 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003651 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003652 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003653 break;
3654
3655 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00003656 case DeclSpec::TST_class:
Joao Matos6666ed42012-08-31 18:45:21 +00003657 case DeclSpec::TST_interface:
Douglas Gregor86d9a522009-09-21 16:56:56 +00003658 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003659 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00003660 break;
3661
3662 default:
David Blaikieb219cfc2011-09-23 05:06:16 +00003663 llvm_unreachable("Unknown type specifier kind in CodeCompleteTag");
Douglas Gregor374929f2009-09-18 15:37:17 +00003664 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003665
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003666 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3667 CodeCompleter->getCodeCompletionTUInfo(), ContextKind);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003668 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00003669
3670 // First pass: look for tags.
3671 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00003672 LookupVisibleDecls(S, LookupTagName, Consumer,
3673 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00003674
Douglas Gregor8071e422010-08-15 06:18:01 +00003675 if (CodeCompleter->includeGlobals()) {
3676 // Second pass: look for nested name specifiers.
3677 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
3678 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
3679 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00003680
Douglas Gregor52779fb2010-09-23 23:01:17 +00003681 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003682 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00003683}
3684
Douglas Gregor1a480c42010-08-27 17:35:51 +00003685void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
Douglas Gregor218937c2011-02-01 19:23:04 +00003686 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003687 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00003688 CodeCompletionContext::CCC_TypeQualifiers);
Douglas Gregor1a480c42010-08-27 17:35:51 +00003689 Results.EnterNewScope();
3690 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
3691 Results.AddResult("const");
3692 if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
3693 Results.AddResult("volatile");
David Blaikie4e4d0842012-03-11 07:00:24 +00003694 if (getLangOpts().C99 &&
Douglas Gregor1a480c42010-08-27 17:35:51 +00003695 !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
3696 Results.AddResult("restrict");
3697 Results.ExitScope();
3698 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00003699 Results.getCompletionContext(),
Douglas Gregor1a480c42010-08-27 17:35:51 +00003700 Results.data(), Results.size());
3701}
3702
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003703void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00003704 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003705 return;
John McCalla8e0cd82011-08-06 07:30:58 +00003706
John McCall781472f2010-08-25 08:40:02 +00003707 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
John McCalla8e0cd82011-08-06 07:30:58 +00003708 QualType type = Switch->getCond()->IgnoreImplicit()->getType();
3709 if (!type->isEnumeralType()) {
3710 CodeCompleteExpressionData Data(type);
Douglas Gregorfb629412010-08-23 21:17:50 +00003711 Data.IntegralConstantExpression = true;
3712 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003713 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00003714 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003715
3716 // Code-complete the cases of a switch statement over an enumeration type
3717 // by providing the list of
John McCalla8e0cd82011-08-06 07:30:58 +00003718 EnumDecl *Enum = type->castAs<EnumType>()->getDecl();
Douglas Gregorb92a4082012-06-12 13:44:08 +00003719 if (EnumDecl *Def = Enum->getDefinition())
3720 Enum = Def;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003721
3722 // Determine which enumerators we have already seen in the switch statement.
3723 // FIXME: Ideally, we would also be able to look *past* the code-completion
3724 // token, in case we are code-completing in the middle of the switch and not
3725 // at the end. However, we aren't able to do so at the moment.
3726 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003727 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003728 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3729 SC = SC->getNextSwitchCase()) {
3730 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3731 if (!Case)
3732 continue;
3733
3734 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3735 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3736 if (EnumConstantDecl *Enumerator
3737 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3738 // We look into the AST of the case statement to determine which
3739 // enumerator was named. Alternatively, we could compute the value of
3740 // the integral constant expression, then compare it against the
3741 // values of each enumerator. However, value-based approach would not
3742 // work as well with C++ templates where enumerators declared within a
3743 // template are type- and value-dependent.
3744 EnumeratorsSeen.insert(Enumerator);
3745
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003746 // If this is a qualified-id, keep track of the nested-name-specifier
3747 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003748 //
3749 // switch (TagD.getKind()) {
3750 // case TagDecl::TK_enum:
3751 // break;
3752 // case XXX
3753 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003754 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003755 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3756 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00003757 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003758 }
3759 }
3760
David Blaikie4e4d0842012-03-11 07:00:24 +00003761 if (getLangOpts().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003762 // If there are no prior enumerators in C++, check whether we have to
3763 // qualify the names of the enumerators that we suggest, because they
3764 // may not be visible in this scope.
Douglas Gregorb223d8c2012-02-01 05:02:47 +00003765 Qualifier = getRequiredQualification(Context, CurContext, Enum);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00003766 }
3767
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003768 // Add any enumerators that have not yet been mentioned.
Douglas Gregor218937c2011-02-01 19:23:04 +00003769 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003770 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00003771 CodeCompletionContext::CCC_Expression);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003772 Results.EnterNewScope();
3773 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3774 EEnd = Enum->enumerator_end();
3775 E != EEnd; ++E) {
David Blaikie581deb32012-06-06 20:45:41 +00003776 if (EnumeratorsSeen.count(*E))
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003777 continue;
3778
Douglas Gregord1f09b42013-01-31 04:52:16 +00003779 CodeCompletionResult R(*E, CCP_EnumInCase, Qualifier);
Douglas Gregor5c722c702011-02-18 23:30:37 +00003780 Results.AddResult(R, CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003781 }
3782 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00003783
Douglas Gregor3da626b2011-07-07 16:03:39 +00003784 //We need to make sure we're setting the right context,
3785 //so only say we include macros if the code completer says we do
3786 enum CodeCompletionContext::Kind kind = CodeCompletionContext::CCC_Other;
3787 if (CodeCompleter->includeMacros()) {
Douglas Gregor3644d972012-10-09 16:01:50 +00003788 AddMacroResults(PP, Results, false);
Douglas Gregor3da626b2011-07-07 16:03:39 +00003789 kind = CodeCompletionContext::CCC_OtherWithMacros;
3790 }
3791
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003792 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor3da626b2011-07-07 16:03:39 +00003793 kind,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003794 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00003795}
3796
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003797namespace {
3798 struct IsBetterOverloadCandidate {
3799 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00003800 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003801
3802 public:
John McCall5769d612010-02-08 23:07:23 +00003803 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3804 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003805
3806 bool
3807 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00003808 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003809 }
3810 };
3811}
3812
Ahmed Charles13a140c2012-02-25 11:00:22 +00003813static bool anyNullArguments(llvm::ArrayRef<Expr*> Args) {
3814 if (Args.size() && !Args.data())
Douglas Gregord28dcd72010-05-30 06:10:08 +00003815 return true;
Ahmed Charles13a140c2012-02-25 11:00:22 +00003816
3817 for (unsigned I = 0; I != Args.size(); ++I)
Douglas Gregord28dcd72010-05-30 06:10:08 +00003818 if (!Args[I])
3819 return true;
Ahmed Charles13a140c2012-02-25 11:00:22 +00003820
Douglas Gregord28dcd72010-05-30 06:10:08 +00003821 return false;
3822}
3823
Richard Trieuf81e5a92011-09-09 02:00:50 +00003824void Sema::CodeCompleteCall(Scope *S, Expr *FnIn,
Ahmed Charles13a140c2012-02-25 11:00:22 +00003825 llvm::ArrayRef<Expr *> Args) {
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003826 if (!CodeCompleter)
3827 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003828
3829 // When we're code-completing for a call, we fall back to ordinary
3830 // name code-completion whenever we can't produce specific
3831 // results. We may want to revisit this strategy in the future,
3832 // e.g., by merging the two kinds of results.
3833
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003834 Expr *Fn = (Expr *)FnIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003835
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003836 // Ignore type-dependent call expressions entirely.
Ahmed Charles13a140c2012-02-25 11:00:22 +00003837 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||
3838 Expr::hasAnyTypeDependentArguments(Args)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003839 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003840 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00003841 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003842
John McCall3b4294e2009-12-16 12:17:52 +00003843 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00003844 SourceLocation Loc = Fn->getExprLoc();
3845 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00003846
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003847 // FIXME: What if we're calling something that isn't a function declaration?
3848 // FIXME: What if we're calling a pseudo-destructor?
3849 // FIXME: What if we're calling a member function?
3850
Douglas Gregorc0265402010-01-21 15:46:19 +00003851 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
Chris Lattner5f9e2722011-07-23 10:55:15 +00003852 SmallVector<ResultCandidate, 8> Results;
Douglas Gregorc0265402010-01-21 15:46:19 +00003853
John McCall3b4294e2009-12-16 12:17:52 +00003854 Expr *NakedFn = Fn->IgnoreParenCasts();
3855 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
Ahmed Charles13a140c2012-02-25 11:00:22 +00003856 AddOverloadedCallCandidates(ULE, Args, CandidateSet,
John McCall3b4294e2009-12-16 12:17:52 +00003857 /*PartialOverloading=*/ true);
3858 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3859 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00003860 if (FDecl) {
David Blaikie4e4d0842012-03-11 07:00:24 +00003861 if (!getLangOpts().CPlusPlus ||
Douglas Gregord28dcd72010-05-30 06:10:08 +00003862 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00003863 Results.push_back(ResultCandidate(FDecl));
3864 else
John McCall86820f52010-01-26 01:37:31 +00003865 // FIXME: access?
Ahmed Charles13a140c2012-02-25 11:00:22 +00003866 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none), Args,
3867 CandidateSet, false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00003868 }
John McCall3b4294e2009-12-16 12:17:52 +00003869 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003870
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003871 QualType ParamType;
3872
Douglas Gregorc0265402010-01-21 15:46:19 +00003873 if (!CandidateSet.empty()) {
3874 // Sort the overload candidate set by placing the best overloads first.
3875 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00003876 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003877
Douglas Gregorc0265402010-01-21 15:46:19 +00003878 // Add the remaining viable overload candidates as code-completion reslults.
3879 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3880 CandEnd = CandidateSet.end();
3881 Cand != CandEnd; ++Cand) {
3882 if (Cand->Viable)
3883 Results.push_back(ResultCandidate(Cand->Function));
3884 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003885
3886 // From the viable candidates, try to determine the type of this parameter.
3887 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3888 if (const FunctionType *FType = Results[I].getFunctionType())
3889 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
Ahmed Charles13a140c2012-02-25 11:00:22 +00003890 if (Args.size() < Proto->getNumArgs()) {
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003891 if (ParamType.isNull())
Ahmed Charles13a140c2012-02-25 11:00:22 +00003892 ParamType = Proto->getArgType(Args.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003893 else if (!Context.hasSameUnqualifiedType(
3894 ParamType.getNonReferenceType(),
Ahmed Charles13a140c2012-02-25 11:00:22 +00003895 Proto->getArgType(Args.size()).getNonReferenceType())) {
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003896 ParamType = QualType();
3897 break;
3898 }
3899 }
3900 }
3901 } else {
3902 // Try to determine the parameter type from the type of the expression
3903 // being called.
3904 QualType FunctionType = Fn->getType();
3905 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3906 FunctionType = Ptr->getPointeeType();
3907 else if (const BlockPointerType *BlockPtr
3908 = FunctionType->getAs<BlockPointerType>())
3909 FunctionType = BlockPtr->getPointeeType();
3910 else if (const MemberPointerType *MemPtr
3911 = FunctionType->getAs<MemberPointerType>())
3912 FunctionType = MemPtr->getPointeeType();
3913
3914 if (const FunctionProtoType *Proto
3915 = FunctionType->getAs<FunctionProtoType>()) {
Ahmed Charles13a140c2012-02-25 11:00:22 +00003916 if (Args.size() < Proto->getNumArgs())
3917 ParamType = Proto->getArgType(Args.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003918 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003919 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00003920
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003921 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003922 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003923 else
3924 CodeCompleteExpression(S, ParamType);
3925
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00003926 if (!Results.empty())
Ahmed Charles13a140c2012-02-25 11:00:22 +00003927 CodeCompleter->ProcessOverloadCandidates(*this, Args.size(), Results.data(),
Douglas Gregoref96eac2009-12-11 19:06:04 +00003928 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00003929}
3930
John McCalld226f652010-08-21 09:40:31 +00003931void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3932 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003933 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003934 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003935 return;
3936 }
3937
3938 CodeCompleteExpression(S, VD->getType());
3939}
3940
3941void Sema::CodeCompleteReturn(Scope *S) {
3942 QualType ResultType;
3943 if (isa<BlockDecl>(CurContext)) {
3944 if (BlockScopeInfo *BSI = getCurBlock())
3945 ResultType = BSI->ReturnType;
3946 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3947 ResultType = Function->getResultType();
3948 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3949 ResultType = Method->getResultType();
3950
3951 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003952 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003953 else
3954 CodeCompleteExpression(S, ResultType);
3955}
3956
Douglas Gregord2d8be62011-07-30 08:36:53 +00003957void Sema::CodeCompleteAfterIf(Scope *S) {
Douglas Gregord2d8be62011-07-30 08:36:53 +00003958 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003959 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregord2d8be62011-07-30 08:36:53 +00003960 mapCodeCompletionContext(*this, PCC_Statement));
3961 Results.setFilter(&ResultBuilder::IsOrdinaryName);
3962 Results.EnterNewScope();
3963
3964 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3965 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3966 CodeCompleter->includeGlobals());
3967
3968 AddOrdinaryNameResults(PCC_Statement, S, *this, Results);
3969
3970 // "else" block
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00003971 CodeCompletionBuilder Builder(Results.getAllocator(),
3972 Results.getCodeCompletionTUInfo());
Douglas Gregord2d8be62011-07-30 08:36:53 +00003973 Builder.AddTypedTextChunk("else");
Douglas Gregorf11641a2012-02-16 17:49:04 +00003974 if (Results.includeCodePatterns()) {
3975 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
3976 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
3977 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
3978 Builder.AddPlaceholderChunk("statements");
3979 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
3980 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
3981 }
Douglas Gregord2d8be62011-07-30 08:36:53 +00003982 Results.AddResult(Builder.TakeString());
3983
3984 // "else if" block
3985 Builder.AddTypedTextChunk("else");
3986 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
3987 Builder.AddTextChunk("if");
3988 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
3989 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
David Blaikie4e4d0842012-03-11 07:00:24 +00003990 if (getLangOpts().CPlusPlus)
Douglas Gregord2d8be62011-07-30 08:36:53 +00003991 Builder.AddPlaceholderChunk("condition");
3992 else
3993 Builder.AddPlaceholderChunk("expression");
3994 Builder.AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorf11641a2012-02-16 17:49:04 +00003995 if (Results.includeCodePatterns()) {
3996 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
3997 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
3998 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
3999 Builder.AddPlaceholderChunk("statements");
4000 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4001 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4002 }
Douglas Gregord2d8be62011-07-30 08:36:53 +00004003 Results.AddResult(Builder.TakeString());
4004
4005 Results.ExitScope();
4006
4007 if (S->getFnParent())
David Blaikie4e4d0842012-03-11 07:00:24 +00004008 AddPrettyFunctionResults(PP.getLangOpts(), Results);
Douglas Gregord2d8be62011-07-30 08:36:53 +00004009
4010 if (CodeCompleter->includeMacros())
Douglas Gregor3644d972012-10-09 16:01:50 +00004011 AddMacroResults(PP, Results, false);
Douglas Gregord2d8be62011-07-30 08:36:53 +00004012
4013 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4014 Results.data(),Results.size());
4015}
4016
Richard Trieuf81e5a92011-09-09 02:00:50 +00004017void Sema::CodeCompleteAssignmentRHS(Scope *S, Expr *LHS) {
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00004018 if (LHS)
4019 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
4020 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004021 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00004022}
4023
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004024void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00004025 bool EnteringContext) {
4026 if (!SS.getScopeRep() || !CodeCompleter)
4027 return;
4028
Douglas Gregor86d9a522009-09-21 16:56:56 +00004029 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
4030 if (!Ctx)
4031 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00004032
4033 // Try to instantiate any non-dependent declaration contexts before
4034 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00004035 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00004036 return;
4037
Douglas Gregor218937c2011-02-01 19:23:04 +00004038 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004039 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004040 CodeCompletionContext::CCC_Name);
Douglas Gregorf6961522010-08-27 21:18:54 +00004041 Results.EnterNewScope();
Douglas Gregor52779fb2010-09-23 23:01:17 +00004042
Douglas Gregor86d9a522009-09-21 16:56:56 +00004043 // The "template" keyword can follow "::" in the grammar, but only
4044 // put it into the grammar if the nested-name-specifier is dependent.
4045 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
4046 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00004047 Results.AddResult("template");
Douglas Gregorf6961522010-08-27 21:18:54 +00004048
4049 // Add calls to overridden virtual functions, if there are any.
4050 //
4051 // FIXME: This isn't wonderful, because we don't know whether we're actually
4052 // in a context that permits expressions. This is a general issue with
4053 // qualified-id completions.
4054 if (!EnteringContext)
4055 MaybeAddOverrideCalls(*this, Ctx, Results);
4056 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00004057
Douglas Gregorf6961522010-08-27 21:18:54 +00004058 CodeCompletionDeclConsumer Consumer(Results, CurContext);
4059 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
4060
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004061 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor430d7a12011-07-25 17:48:11 +00004062 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004063 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00004064}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00004065
4066void Sema::CodeCompleteUsing(Scope *S) {
4067 if (!CodeCompleter)
4068 return;
4069
Douglas Gregor218937c2011-02-01 19:23:04 +00004070 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004071 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor52779fb2010-09-23 23:01:17 +00004072 CodeCompletionContext::CCC_PotentiallyQualifiedName,
4073 &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00004074 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00004075
4076 // If we aren't in class scope, we could see the "namespace" keyword.
4077 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00004078 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00004079
4080 // After "using", we can see anything that would start a
4081 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00004082 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00004083 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4084 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00004085 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00004086
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004087 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00004088 CodeCompletionContext::CCC_PotentiallyQualifiedName,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004089 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00004090}
4091
4092void Sema::CodeCompleteUsingDirective(Scope *S) {
4093 if (!CodeCompleter)
4094 return;
4095
Douglas Gregor86d9a522009-09-21 16:56:56 +00004096 // After "using namespace", we expect to see a namespace name or namespace
4097 // alias.
Douglas Gregor218937c2011-02-01 19:23:04 +00004098 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004099 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004100 CodeCompletionContext::CCC_Namespace,
Douglas Gregor52779fb2010-09-23 23:01:17 +00004101 &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00004102 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00004103 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00004104 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4105 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00004106 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004107 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00004108 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004109 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00004110}
4111
4112void Sema::CodeCompleteNamespaceDecl(Scope *S) {
4113 if (!CodeCompleter)
4114 return;
4115
Douglas Gregor86d9a522009-09-21 16:56:56 +00004116 DeclContext *Ctx = (DeclContext *)S->getEntity();
4117 if (!S->getParent())
4118 Ctx = Context.getTranslationUnitDecl();
4119
Douglas Gregor52779fb2010-09-23 23:01:17 +00004120 bool SuppressedGlobalResults
4121 = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
4122
Douglas Gregor218937c2011-02-01 19:23:04 +00004123 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004124 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor52779fb2010-09-23 23:01:17 +00004125 SuppressedGlobalResults
4126 ? CodeCompletionContext::CCC_Namespace
4127 : CodeCompletionContext::CCC_Other,
4128 &ResultBuilder::IsNamespace);
4129
4130 if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00004131 // We only want to see those namespaces that have already been defined
4132 // within this scope, because its likely that the user is creating an
4133 // extended namespace declaration. Keep track of the most recent
4134 // definition of each namespace.
4135 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
4136 for (DeclContext::specific_decl_iterator<NamespaceDecl>
4137 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
4138 NS != NSEnd; ++NS)
David Blaikie581deb32012-06-06 20:45:41 +00004139 OrigToLatest[NS->getOriginalNamespace()] = *NS;
Douglas Gregor86d9a522009-09-21 16:56:56 +00004140
4141 // Add the most recent definition (or extended definition) of each
4142 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00004143 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00004144 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
Douglas Gregorba103062012-03-27 23:34:16 +00004145 NS = OrigToLatest.begin(),
4146 NSEnd = OrigToLatest.end();
Douglas Gregor86d9a522009-09-21 16:56:56 +00004147 NS != NSEnd; ++NS)
Douglas Gregord1f09b42013-01-31 04:52:16 +00004148 Results.AddResult(CodeCompletionResult(
4149 NS->second, Results.getBasePriority(NS->second), 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00004150 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00004151 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00004152 }
4153
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004154 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00004155 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004156 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00004157}
4158
4159void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
4160 if (!CodeCompleter)
4161 return;
4162
Douglas Gregor86d9a522009-09-21 16:56:56 +00004163 // After "namespace", we expect to see a namespace or alias.
Douglas Gregor218937c2011-02-01 19:23:04 +00004164 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004165 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004166 CodeCompletionContext::CCC_Namespace,
Douglas Gregor52779fb2010-09-23 23:01:17 +00004167 &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00004168 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00004169 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4170 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004171 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor52779fb2010-09-23 23:01:17 +00004172 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004173 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00004174}
4175
Douglas Gregored8d3222009-09-18 20:05:18 +00004176void Sema::CodeCompleteOperatorName(Scope *S) {
4177 if (!CodeCompleter)
4178 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00004179
John McCall0a2c5e22010-08-25 06:19:51 +00004180 typedef CodeCompletionResult Result;
Douglas Gregor218937c2011-02-01 19:23:04 +00004181 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004182 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004183 CodeCompletionContext::CCC_Type,
Douglas Gregor52779fb2010-09-23 23:01:17 +00004184 &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00004185 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00004186
Douglas Gregor86d9a522009-09-21 16:56:56 +00004187 // Add the names of overloadable operators.
4188#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
4189 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00004190 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00004191#include "clang/Basic/OperatorKinds.def"
4192
4193 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00004194 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00004195 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00004196 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4197 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00004198
4199 // Add any type specifiers
David Blaikie4e4d0842012-03-11 07:00:24 +00004200 AddTypeSpecifierResults(getLangOpts(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00004201 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00004202
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004203 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00004204 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004205 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00004206}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00004207
Douglas Gregor0133f522010-08-28 00:00:50 +00004208void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
Sean Huntcbb67482011-01-08 20:30:50 +00004209 CXXCtorInitializer** Initializers,
Douglas Gregor0133f522010-08-28 00:00:50 +00004210 unsigned NumInitializers) {
Douglas Gregor8987b232011-09-27 23:30:47 +00004211 PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
Douglas Gregor0133f522010-08-28 00:00:50 +00004212 CXXConstructorDecl *Constructor
4213 = static_cast<CXXConstructorDecl *>(ConstructorD);
4214 if (!Constructor)
4215 return;
4216
Douglas Gregor218937c2011-02-01 19:23:04 +00004217 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004218 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor52779fb2010-09-23 23:01:17 +00004219 CodeCompletionContext::CCC_PotentiallyQualifiedName);
Douglas Gregor0133f522010-08-28 00:00:50 +00004220 Results.EnterNewScope();
4221
4222 // Fill in any already-initialized fields or base classes.
4223 llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
4224 llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
4225 for (unsigned I = 0; I != NumInitializers; ++I) {
4226 if (Initializers[I]->isBaseInitializer())
4227 InitializedBases.insert(
4228 Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
4229 else
Francois Pichet00eb3f92010-12-04 09:14:42 +00004230 InitializedFields.insert(cast<FieldDecl>(
4231 Initializers[I]->getAnyMember()));
Douglas Gregor0133f522010-08-28 00:00:50 +00004232 }
4233
4234 // Add completions for base classes.
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004235 CodeCompletionBuilder Builder(Results.getAllocator(),
4236 Results.getCodeCompletionTUInfo());
Douglas Gregor0c431c82010-08-29 19:27:27 +00004237 bool SawLastInitializer = (NumInitializers == 0);
Douglas Gregor0133f522010-08-28 00:00:50 +00004238 CXXRecordDecl *ClassDecl = Constructor->getParent();
4239 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
4240 BaseEnd = ClassDecl->bases_end();
4241 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00004242 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
4243 SawLastInitializer
4244 = NumInitializers > 0 &&
4245 Initializers[NumInitializers - 1]->isBaseInitializer() &&
4246 Context.hasSameUnqualifiedType(Base->getType(),
4247 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00004248 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00004249 }
Douglas Gregor0133f522010-08-28 00:00:50 +00004250
Douglas Gregor218937c2011-02-01 19:23:04 +00004251 Builder.AddTypedTextChunk(
Douglas Gregordae68752011-02-01 22:57:45 +00004252 Results.getAllocator().CopyString(
John McCallf85e1932011-06-15 23:02:42 +00004253 Base->getType().getAsString(Policy)));
Douglas Gregor218937c2011-02-01 19:23:04 +00004254 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4255 Builder.AddPlaceholderChunk("args");
4256 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4257 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
Douglas Gregor0c431c82010-08-29 19:27:27 +00004258 SawLastInitializer? CCP_NextInitializer
4259 : CCP_MemberDeclaration));
4260 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00004261 }
4262
4263 // Add completions for virtual base classes.
4264 for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
4265 BaseEnd = ClassDecl->vbases_end();
4266 Base != BaseEnd; ++Base) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00004267 if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
4268 SawLastInitializer
4269 = NumInitializers > 0 &&
4270 Initializers[NumInitializers - 1]->isBaseInitializer() &&
4271 Context.hasSameUnqualifiedType(Base->getType(),
4272 QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
Douglas Gregor0133f522010-08-28 00:00:50 +00004273 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00004274 }
Douglas Gregor0133f522010-08-28 00:00:50 +00004275
Douglas Gregor218937c2011-02-01 19:23:04 +00004276 Builder.AddTypedTextChunk(
Douglas Gregordae68752011-02-01 22:57:45 +00004277 Builder.getAllocator().CopyString(
John McCallf85e1932011-06-15 23:02:42 +00004278 Base->getType().getAsString(Policy)));
Douglas Gregor218937c2011-02-01 19:23:04 +00004279 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4280 Builder.AddPlaceholderChunk("args");
4281 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4282 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
Douglas Gregor0c431c82010-08-29 19:27:27 +00004283 SawLastInitializer? CCP_NextInitializer
4284 : CCP_MemberDeclaration));
4285 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00004286 }
4287
4288 // Add completions for members.
4289 for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
4290 FieldEnd = ClassDecl->field_end();
4291 Field != FieldEnd; ++Field) {
Douglas Gregor0c431c82010-08-29 19:27:27 +00004292 if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
4293 SawLastInitializer
4294 = NumInitializers > 0 &&
Francois Pichet00eb3f92010-12-04 09:14:42 +00004295 Initializers[NumInitializers - 1]->isAnyMemberInitializer() &&
David Blaikie581deb32012-06-06 20:45:41 +00004296 Initializers[NumInitializers - 1]->getAnyMember() == *Field;
Douglas Gregor0133f522010-08-28 00:00:50 +00004297 continue;
Douglas Gregor0c431c82010-08-29 19:27:27 +00004298 }
Douglas Gregor0133f522010-08-28 00:00:50 +00004299
4300 if (!Field->getDeclName())
4301 continue;
4302
Douglas Gregordae68752011-02-01 22:57:45 +00004303 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
Douglas Gregor218937c2011-02-01 19:23:04 +00004304 Field->getIdentifier()->getName()));
4305 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4306 Builder.AddPlaceholderChunk("args");
4307 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4308 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
Douglas Gregor0c431c82010-08-29 19:27:27 +00004309 SawLastInitializer? CCP_NextInitializer
Douglas Gregora67e03f2010-09-09 21:42:20 +00004310 : CCP_MemberDeclaration,
Douglas Gregorba103062012-03-27 23:34:16 +00004311 CXCursor_MemberRef,
4312 CXAvailability_Available,
David Blaikie581deb32012-06-06 20:45:41 +00004313 *Field));
Douglas Gregor0c431c82010-08-29 19:27:27 +00004314 SawLastInitializer = false;
Douglas Gregor0133f522010-08-28 00:00:50 +00004315 }
4316 Results.ExitScope();
4317
Douglas Gregor52779fb2010-09-23 23:01:17 +00004318 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor0133f522010-08-28 00:00:50 +00004319 Results.data(), Results.size());
4320}
4321
Douglas Gregor81f3bff2012-02-15 15:34:24 +00004322/// \brief Determine whether this scope denotes a namespace.
4323static bool isNamespaceScope(Scope *S) {
4324 DeclContext *DC = static_cast<DeclContext *>(S->getEntity());
4325 if (!DC)
4326 return false;
4327
4328 return DC->isFileContext();
4329}
4330
4331void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
4332 bool AfterAmpersand) {
4333 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004334 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor81f3bff2012-02-15 15:34:24 +00004335 CodeCompletionContext::CCC_Other);
4336 Results.EnterNewScope();
4337
4338 // Note what has already been captured.
4339 llvm::SmallPtrSet<IdentifierInfo *, 4> Known;
4340 bool IncludedThis = false;
4341 for (SmallVectorImpl<LambdaCapture>::iterator C = Intro.Captures.begin(),
4342 CEnd = Intro.Captures.end();
4343 C != CEnd; ++C) {
4344 if (C->Kind == LCK_This) {
4345 IncludedThis = true;
4346 continue;
4347 }
4348
4349 Known.insert(C->Id);
4350 }
4351
4352 // Look for other capturable variables.
4353 for (; S && !isNamespaceScope(S); S = S->getParent()) {
4354 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
4355 D != DEnd; ++D) {
4356 VarDecl *Var = dyn_cast<VarDecl>(*D);
4357 if (!Var ||
4358 !Var->hasLocalStorage() ||
4359 Var->hasAttr<BlocksAttr>())
4360 continue;
4361
4362 if (Known.insert(Var->getIdentifier()))
Douglas Gregord1f09b42013-01-31 04:52:16 +00004363 Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration),
4364 CurContext, 0, false);
Douglas Gregor81f3bff2012-02-15 15:34:24 +00004365 }
4366 }
4367
4368 // Add 'this', if it would be valid.
4369 if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy)
4370 addThisCompletion(*this, Results);
4371
4372 Results.ExitScope();
4373
4374 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4375 Results.data(), Results.size());
4376}
4377
James Dennetta40f7922012-06-14 03:11:41 +00004378/// Macro that optionally prepends an "@" to the string literal passed in via
4379/// Keyword, depending on whether NeedAt is true or false.
4380#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) ((NeedAt)? "@" Keyword : Keyword)
4381
Douglas Gregorbca403c2010-01-13 23:51:12 +00004382static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004383 ResultBuilder &Results,
4384 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00004385 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004386 // Since we have an implementation, we can end it.
James Dennetta40f7922012-06-14 03:11:41 +00004387 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end")));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004388
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004389 CodeCompletionBuilder Builder(Results.getAllocator(),
4390 Results.getCodeCompletionTUInfo());
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004391 if (LangOpts.ObjC2) {
4392 // @dynamic
James Dennetta40f7922012-06-14 03:11:41 +00004393 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"dynamic"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004394 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4395 Builder.AddPlaceholderChunk("property");
4396 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004397
4398 // @synthesize
James Dennetta40f7922012-06-14 03:11:41 +00004399 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synthesize"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004400 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4401 Builder.AddPlaceholderChunk("property");
4402 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004403 }
4404}
4405
Douglas Gregorbca403c2010-01-13 23:51:12 +00004406static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004407 ResultBuilder &Results,
4408 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00004409 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004410
4411 // Since we have an interface or protocol, we can end it.
James Dennetta40f7922012-06-14 03:11:41 +00004412 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end")));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004413
4414 if (LangOpts.ObjC2) {
4415 // @property
James Dennetta40f7922012-06-14 03:11:41 +00004416 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"property")));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004417
4418 // @required
James Dennetta40f7922012-06-14 03:11:41 +00004419 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"required")));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004420
4421 // @optional
James Dennetta40f7922012-06-14 03:11:41 +00004422 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"optional")));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004423 }
4424}
4425
Douglas Gregorbca403c2010-01-13 23:51:12 +00004426static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00004427 typedef CodeCompletionResult Result;
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004428 CodeCompletionBuilder Builder(Results.getAllocator(),
4429 Results.getCodeCompletionTUInfo());
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004430
4431 // @class name ;
James Dennetta40f7922012-06-14 03:11:41 +00004432 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"class"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004433 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4434 Builder.AddPlaceholderChunk("name");
4435 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004436
Douglas Gregorc8bddde2010-05-28 00:22:41 +00004437 if (Results.includeCodePatterns()) {
4438 // @interface name
4439 // FIXME: Could introduce the whole pattern, including superclasses and
4440 // such.
James Dennetta40f7922012-06-14 03:11:41 +00004441 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"interface"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004442 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4443 Builder.AddPlaceholderChunk("class");
4444 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004445
Douglas Gregorc8bddde2010-05-28 00:22:41 +00004446 // @protocol name
James Dennetta40f7922012-06-14 03:11:41 +00004447 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004448 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4449 Builder.AddPlaceholderChunk("protocol");
4450 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00004451
4452 // @implementation name
James Dennetta40f7922012-06-14 03:11:41 +00004453 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"implementation"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004454 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4455 Builder.AddPlaceholderChunk("class");
4456 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00004457 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004458
4459 // @compatibility_alias name
James Dennetta40f7922012-06-14 03:11:41 +00004460 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"compatibility_alias"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004461 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4462 Builder.AddPlaceholderChunk("alias");
4463 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4464 Builder.AddPlaceholderChunk("class");
4465 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004466}
4467
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00004468void Sema::CodeCompleteObjCAtDirective(Scope *S) {
Douglas Gregor218937c2011-02-01 19:23:04 +00004469 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004470 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004471 CodeCompletionContext::CCC_Other);
Douglas Gregorc464ae82009-12-07 09:27:33 +00004472 Results.EnterNewScope();
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00004473 if (isa<ObjCImplDecl>(CurContext))
David Blaikie4e4d0842012-03-11 07:00:24 +00004474 AddObjCImplementationResults(getLangOpts(), Results, false);
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00004475 else if (CurContext->isObjCContainer())
David Blaikie4e4d0842012-03-11 07:00:24 +00004476 AddObjCInterfaceResults(getLangOpts(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004477 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00004478 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00004479 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004480 HandleCodeCompleteResults(this, CodeCompleter,
4481 CodeCompletionContext::CCC_Other,
4482 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00004483}
4484
Douglas Gregorbca403c2010-01-13 23:51:12 +00004485static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00004486 typedef CodeCompletionResult Result;
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004487 CodeCompletionBuilder Builder(Results.getAllocator(),
4488 Results.getCodeCompletionTUInfo());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004489
4490 // @encode ( type-name )
Douglas Gregor8ca72082011-10-18 21:20:17 +00004491 const char *EncodeType = "char[]";
David Blaikie4e4d0842012-03-11 07:00:24 +00004492 if (Results.getSema().getLangOpts().CPlusPlus ||
4493 Results.getSema().getLangOpts().ConstStrings)
Jordan Rose1f6e22d2012-06-15 18:19:56 +00004494 EncodeType = "const char[]";
Douglas Gregor8ca72082011-10-18 21:20:17 +00004495 Builder.AddResultTypeChunk(EncodeType);
James Dennetta40f7922012-06-14 03:11:41 +00004496 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"encode"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004497 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4498 Builder.AddPlaceholderChunk("type-name");
4499 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4500 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004501
4502 // @protocol ( protocol-name )
Douglas Gregor8ca72082011-10-18 21:20:17 +00004503 Builder.AddResultTypeChunk("Protocol *");
James Dennetta40f7922012-06-14 03:11:41 +00004504 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004505 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4506 Builder.AddPlaceholderChunk("protocol-name");
4507 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4508 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004509
4510 // @selector ( selector )
Douglas Gregor8ca72082011-10-18 21:20:17 +00004511 Builder.AddResultTypeChunk("SEL");
James Dennetta40f7922012-06-14 03:11:41 +00004512 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"selector"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004513 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4514 Builder.AddPlaceholderChunk("selector");
4515 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4516 Results.AddResult(Result(Builder.TakeString()));
Jordan Rose1f6e22d2012-06-15 18:19:56 +00004517
4518 // @"string"
4519 Builder.AddResultTypeChunk("NSString *");
4520 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"\""));
4521 Builder.AddPlaceholderChunk("string");
4522 Builder.AddTextChunk("\"");
4523 Results.AddResult(Result(Builder.TakeString()));
4524
Douglas Gregor79615892012-07-17 23:24:47 +00004525 // @[objects, ...]
Jordan Rose1f6e22d2012-06-15 18:19:56 +00004526 Builder.AddResultTypeChunk("NSArray *");
James Dennetta40f7922012-06-14 03:11:41 +00004527 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"["));
Ted Kremenekebcb57a2012-03-06 20:05:56 +00004528 Builder.AddPlaceholderChunk("objects, ...");
Ted Kremenekebcb57a2012-03-06 20:05:56 +00004529 Builder.AddChunk(CodeCompletionString::CK_RightBracket);
4530 Results.AddResult(Result(Builder.TakeString()));
4531
Douglas Gregor79615892012-07-17 23:24:47 +00004532 // @{key : object, ...}
Jordan Rose1f6e22d2012-06-15 18:19:56 +00004533 Builder.AddResultTypeChunk("NSDictionary *");
James Dennetta40f7922012-06-14 03:11:41 +00004534 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"{"));
Ted Kremenekebcb57a2012-03-06 20:05:56 +00004535 Builder.AddPlaceholderChunk("key");
Ted Kremenekebcb57a2012-03-06 20:05:56 +00004536 Builder.AddChunk(CodeCompletionString::CK_Colon);
4537 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4538 Builder.AddPlaceholderChunk("object, ...");
Ted Kremenekebcb57a2012-03-06 20:05:56 +00004539 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4540 Results.AddResult(Result(Builder.TakeString()));
Jordan Rose1f6e22d2012-06-15 18:19:56 +00004541
Douglas Gregor79615892012-07-17 23:24:47 +00004542 // @(expression)
Jordan Rose1f6e22d2012-06-15 18:19:56 +00004543 Builder.AddResultTypeChunk("id");
4544 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "("));
Jordan Rose1f6e22d2012-06-15 18:19:56 +00004545 Builder.AddPlaceholderChunk("expression");
Jordan Rose1f6e22d2012-06-15 18:19:56 +00004546 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4547 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004548}
4549
Douglas Gregorbca403c2010-01-13 23:51:12 +00004550static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00004551 typedef CodeCompletionResult Result;
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004552 CodeCompletionBuilder Builder(Results.getAllocator(),
4553 Results.getCodeCompletionTUInfo());
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004554
Douglas Gregorc8bddde2010-05-28 00:22:41 +00004555 if (Results.includeCodePatterns()) {
4556 // @try { statements } @catch ( declaration ) { statements } @finally
4557 // { statements }
James Dennetta40f7922012-06-14 03:11:41 +00004558 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"try"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004559 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4560 Builder.AddPlaceholderChunk("statements");
4561 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4562 Builder.AddTextChunk("@catch");
4563 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4564 Builder.AddPlaceholderChunk("parameter");
4565 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4566 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4567 Builder.AddPlaceholderChunk("statements");
4568 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4569 Builder.AddTextChunk("@finally");
4570 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4571 Builder.AddPlaceholderChunk("statements");
4572 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4573 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00004574 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004575
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004576 // @throw
James Dennetta40f7922012-06-14 03:11:41 +00004577 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"throw"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004578 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4579 Builder.AddPlaceholderChunk("expression");
4580 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004581
Douglas Gregorc8bddde2010-05-28 00:22:41 +00004582 if (Results.includeCodePatterns()) {
4583 // @synchronized ( expression ) { statements }
James Dennetta40f7922012-06-14 03:11:41 +00004584 Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synchronized"));
Douglas Gregor218937c2011-02-01 19:23:04 +00004585 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4586 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4587 Builder.AddPlaceholderChunk("expression");
4588 Builder.AddChunk(CodeCompletionString::CK_RightParen);
4589 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4590 Builder.AddPlaceholderChunk("statements");
4591 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4592 Results.AddResult(Result(Builder.TakeString()));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00004593 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004594}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004595
Douglas Gregorbca403c2010-01-13 23:51:12 +00004596static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00004597 ResultBuilder &Results,
4598 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00004599 typedef CodeCompletionResult Result;
James Dennetta40f7922012-06-14 03:11:41 +00004600 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"private")));
4601 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"protected")));
4602 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"public")));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00004603 if (LangOpts.ObjC2)
James Dennetta40f7922012-06-14 03:11:41 +00004604 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"package")));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00004605}
4606
4607void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
Douglas Gregor218937c2011-02-01 19:23:04 +00004608 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004609 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004610 CodeCompletionContext::CCC_Other);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00004611 Results.EnterNewScope();
David Blaikie4e4d0842012-03-11 07:00:24 +00004612 AddObjCVisibilityResults(getLangOpts(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00004613 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004614 HandleCodeCompleteResults(this, CodeCompleter,
4615 CodeCompletionContext::CCC_Other,
4616 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00004617}
4618
4619void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregor218937c2011-02-01 19:23:04 +00004620 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004621 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004622 CodeCompletionContext::CCC_Other);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00004623 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00004624 AddObjCStatementResults(Results, false);
4625 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004626 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004627 HandleCodeCompleteResults(this, CodeCompleter,
4628 CodeCompletionContext::CCC_Other,
4629 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004630}
4631
4632void Sema::CodeCompleteObjCAtExpression(Scope *S) {
Douglas Gregor218937c2011-02-01 19:23:04 +00004633 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004634 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004635 CodeCompletionContext::CCC_Other);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004636 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00004637 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004638 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004639 HandleCodeCompleteResults(this, CodeCompleter,
4640 CodeCompletionContext::CCC_Other,
4641 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00004642}
4643
Douglas Gregor988358f2009-11-19 00:14:45 +00004644/// \brief Determine whether the addition of the given flag to an Objective-C
4645/// property's attributes will cause a conflict.
Bill Wendlingad017fa2012-12-20 19:22:21 +00004646static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
Douglas Gregor988358f2009-11-19 00:14:45 +00004647 // Check if we've already added this flag.
Bill Wendlingad017fa2012-12-20 19:22:21 +00004648 if (Attributes & NewFlag)
Douglas Gregor988358f2009-11-19 00:14:45 +00004649 return true;
4650
Bill Wendlingad017fa2012-12-20 19:22:21 +00004651 Attributes |= NewFlag;
Douglas Gregor988358f2009-11-19 00:14:45 +00004652
4653 // Check for collisions with "readonly".
Bill Wendlingad017fa2012-12-20 19:22:21 +00004654 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
4655 (Attributes & ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor988358f2009-11-19 00:14:45 +00004656 return true;
4657
Jordan Rosed7403a72012-08-20 20:01:13 +00004658 // Check for more than one of { assign, copy, retain, strong, weak }.
Bill Wendlingad017fa2012-12-20 19:22:21 +00004659 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
John McCallf85e1932011-06-15 23:02:42 +00004660 ObjCDeclSpec::DQ_PR_unsafe_unretained |
Douglas Gregor988358f2009-11-19 00:14:45 +00004661 ObjCDeclSpec::DQ_PR_copy |
Jordan Rosed7403a72012-08-20 20:01:13 +00004662 ObjCDeclSpec::DQ_PR_retain |
4663 ObjCDeclSpec::DQ_PR_strong |
4664 ObjCDeclSpec::DQ_PR_weak);
Douglas Gregor988358f2009-11-19 00:14:45 +00004665 if (AssignCopyRetMask &&
4666 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
John McCallf85e1932011-06-15 23:02:42 +00004667 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained &&
Douglas Gregor988358f2009-11-19 00:14:45 +00004668 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
John McCallf85e1932011-06-15 23:02:42 +00004669 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain &&
Jordan Rosed7403a72012-08-20 20:01:13 +00004670 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong &&
4671 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_weak)
Douglas Gregor988358f2009-11-19 00:14:45 +00004672 return true;
4673
4674 return false;
4675}
4676
Douglas Gregora93b1082009-11-18 23:08:07 +00004677void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00004678 if (!CodeCompleter)
4679 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00004680
Bill Wendlingad017fa2012-12-20 19:22:21 +00004681 unsigned Attributes = ODS.getPropertyAttributes();
Steve Naroffece8e712009-10-08 21:55:05 +00004682
Douglas Gregor218937c2011-02-01 19:23:04 +00004683 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004684 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004685 CodeCompletionContext::CCC_Other);
Steve Naroffece8e712009-10-08 21:55:05 +00004686 Results.EnterNewScope();
Bill Wendlingad017fa2012-12-20 19:22:21 +00004687 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00004688 Results.AddResult(CodeCompletionResult("readonly"));
Bill Wendlingad017fa2012-12-20 19:22:21 +00004689 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00004690 Results.AddResult(CodeCompletionResult("assign"));
Bill Wendlingad017fa2012-12-20 19:22:21 +00004691 if (!ObjCPropertyFlagConflicts(Attributes,
John McCallf85e1932011-06-15 23:02:42 +00004692 ObjCDeclSpec::DQ_PR_unsafe_unretained))
4693 Results.AddResult(CodeCompletionResult("unsafe_unretained"));
Bill Wendlingad017fa2012-12-20 19:22:21 +00004694 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00004695 Results.AddResult(CodeCompletionResult("readwrite"));
Bill Wendlingad017fa2012-12-20 19:22:21 +00004696 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00004697 Results.AddResult(CodeCompletionResult("retain"));
Bill Wendlingad017fa2012-12-20 19:22:21 +00004698 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_strong))
John McCallf85e1932011-06-15 23:02:42 +00004699 Results.AddResult(CodeCompletionResult("strong"));
Bill Wendlingad017fa2012-12-20 19:22:21 +00004700 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00004701 Results.AddResult(CodeCompletionResult("copy"));
Bill Wendlingad017fa2012-12-20 19:22:21 +00004702 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00004703 Results.AddResult(CodeCompletionResult("nonatomic"));
Bill Wendlingad017fa2012-12-20 19:22:21 +00004704 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic))
Fariborz Jahanian27f45232011-06-11 17:14:27 +00004705 Results.AddResult(CodeCompletionResult("atomic"));
Jordan Rosed7403a72012-08-20 20:01:13 +00004706
4707 // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
John McCall0a7dd782012-08-21 02:47:43 +00004708 if (getLangOpts().ObjCARCWeak || getLangOpts().getGC() != LangOptions::NonGC)
Bill Wendlingad017fa2012-12-20 19:22:21 +00004709 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak))
Jordan Rosed7403a72012-08-20 20:01:13 +00004710 Results.AddResult(CodeCompletionResult("weak"));
4711
Bill Wendlingad017fa2012-12-20 19:22:21 +00004712 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004713 CodeCompletionBuilder Setter(Results.getAllocator(),
4714 Results.getCodeCompletionTUInfo());
Douglas Gregor218937c2011-02-01 19:23:04 +00004715 Setter.AddTypedTextChunk("setter");
4716 Setter.AddTextChunk(" = ");
4717 Setter.AddPlaceholderChunk("method");
4718 Results.AddResult(CodeCompletionResult(Setter.TakeString()));
Douglas Gregor54f01612009-11-19 00:01:57 +00004719 }
Bill Wendlingad017fa2012-12-20 19:22:21 +00004720 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004721 CodeCompletionBuilder Getter(Results.getAllocator(),
4722 Results.getCodeCompletionTUInfo());
Douglas Gregor218937c2011-02-01 19:23:04 +00004723 Getter.AddTypedTextChunk("getter");
4724 Getter.AddTextChunk(" = ");
4725 Getter.AddPlaceholderChunk("method");
4726 Results.AddResult(CodeCompletionResult(Getter.TakeString()));
Douglas Gregor54f01612009-11-19 00:01:57 +00004727 }
Steve Naroffece8e712009-10-08 21:55:05 +00004728 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004729 HandleCodeCompleteResults(this, CodeCompleter,
4730 CodeCompletionContext::CCC_Other,
4731 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00004732}
Steve Naroffc4df6d22009-11-07 02:08:14 +00004733
James Dennettde23c7e2012-06-17 05:33:25 +00004734/// \brief Describes the kind of Objective-C method that we want to find
Douglas Gregor4ad96852009-11-19 07:41:15 +00004735/// via code completion.
4736enum ObjCMethodKind {
Dmitri Gribenko49fdccb2012-06-08 23:13:42 +00004737 MK_Any, ///< Any kind of method, provided it means other specified criteria.
4738 MK_ZeroArgSelector, ///< Zero-argument (unary) selector.
4739 MK_OneArgSelector ///< One-argument selector.
Douglas Gregor4ad96852009-11-19 07:41:15 +00004740};
4741
Douglas Gregor458433d2010-08-26 15:07:07 +00004742static bool isAcceptableObjCSelector(Selector Sel,
4743 ObjCMethodKind WantKind,
4744 IdentifierInfo **SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004745 unsigned NumSelIdents,
4746 bool AllowSameLength = true) {
Douglas Gregor458433d2010-08-26 15:07:07 +00004747 if (NumSelIdents > Sel.getNumArgs())
4748 return false;
4749
4750 switch (WantKind) {
4751 case MK_Any: break;
4752 case MK_ZeroArgSelector: return Sel.isUnarySelector();
4753 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
4754 }
4755
Douglas Gregorcf544262010-11-17 21:36:08 +00004756 if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
4757 return false;
4758
Douglas Gregor458433d2010-08-26 15:07:07 +00004759 for (unsigned I = 0; I != NumSelIdents; ++I)
4760 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
4761 return false;
4762
4763 return true;
4764}
4765
Douglas Gregor4ad96852009-11-19 07:41:15 +00004766static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
4767 ObjCMethodKind WantKind,
4768 IdentifierInfo **SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004769 unsigned NumSelIdents,
4770 bool AllowSameLength = true) {
Douglas Gregor458433d2010-08-26 15:07:07 +00004771 return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004772 NumSelIdents, AllowSameLength);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004773}
Douglas Gregord36adf52010-09-16 16:06:31 +00004774
4775namespace {
4776 /// \brief A set of selectors, which is used to avoid introducing multiple
4777 /// completions with the same selector into the result set.
4778 typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
4779}
4780
Douglas Gregor36ecb042009-11-17 23:22:23 +00004781/// \brief Add all of the Objective-C methods in the given Objective-C
4782/// container to the set of results.
4783///
4784/// The container will be a class, protocol, category, or implementation of
4785/// any of the above. This mether will recurse to include methods from
4786/// the superclasses of classes along with their categories, protocols, and
4787/// implementations.
4788///
4789/// \param Container the container in which we'll look to find methods.
4790///
James Dennetta40f7922012-06-14 03:11:41 +00004791/// \param WantInstanceMethods Whether to add instance methods (only); if
4792/// false, this routine will add factory methods (only).
Douglas Gregor36ecb042009-11-17 23:22:23 +00004793///
4794/// \param CurContext the context in which we're performing the lookup that
4795/// finds methods.
4796///
Douglas Gregorcf544262010-11-17 21:36:08 +00004797/// \param AllowSameLength Whether we allow a method to be added to the list
4798/// when it has the same number of parameters as we have selector identifiers.
4799///
Douglas Gregor36ecb042009-11-17 23:22:23 +00004800/// \param Results the structure into which we'll add results.
4801static void AddObjCMethods(ObjCContainerDecl *Container,
4802 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00004803 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00004804 IdentifierInfo **SelIdents,
4805 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00004806 DeclContext *CurContext,
Douglas Gregord36adf52010-09-16 16:06:31 +00004807 VisitedSelectorSet &Selectors,
Douglas Gregorcf544262010-11-17 21:36:08 +00004808 bool AllowSameLength,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004809 ResultBuilder &Results,
4810 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00004811 typedef CodeCompletionResult Result;
Douglas Gregorb92a4082012-06-12 13:44:08 +00004812 Container = getContainerDef(Container);
Douglas Gregor5824b802013-01-30 06:58:39 +00004813 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
4814 bool isRootClass = IFace && !IFace->getSuperClass();
Douglas Gregor36ecb042009-11-17 23:22:23 +00004815 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4816 MEnd = Container->meth_end();
4817 M != MEnd; ++M) {
Douglas Gregor5824b802013-01-30 06:58:39 +00004818 // The instance methods on the root class can be messaged via the
4819 // metaclass.
4820 if (M->isInstanceMethod() == WantInstanceMethods ||
4821 (isRootClass && !WantInstanceMethods)) {
Douglas Gregord3c68542009-11-19 01:08:35 +00004822 // Check whether the selector identifiers we've been given are a
4823 // subset of the identifiers for this particular method.
David Blaikie581deb32012-06-06 20:45:41 +00004824 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004825 AllowSameLength))
Douglas Gregord3c68542009-11-19 01:08:35 +00004826 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004827
David Blaikie262bc182012-04-30 02:36:29 +00004828 if (!Selectors.insert(M->getSelector()))
Douglas Gregord36adf52010-09-16 16:06:31 +00004829 continue;
4830
Douglas Gregord1f09b42013-01-31 04:52:16 +00004831 Result R = Result(*M, Results.getBasePriority(*M), 0);
Douglas Gregord3c68542009-11-19 01:08:35 +00004832 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00004833 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00004834 if (!InOriginalClass)
4835 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00004836 Results.MaybeAddResult(R, CurContext);
4837 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00004838 }
4839
Douglas Gregore396c7b2010-09-16 15:34:59 +00004840 // Visit the protocols of protocols.
4841 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
Douglas Gregor5e2a1ff2012-01-01 19:29:29 +00004842 if (Protocol->hasDefinition()) {
4843 const ObjCList<ObjCProtocolDecl> &Protocols
4844 = Protocol->getReferencedProtocols();
4845 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4846 E = Protocols.end();
4847 I != E; ++I)
4848 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
4849 NumSelIdents, CurContext, Selectors, AllowSameLength,
4850 Results, false);
4851 }
Douglas Gregore396c7b2010-09-16 15:34:59 +00004852 }
4853
Douglas Gregor2e5c15b2011-12-15 05:27:12 +00004854 if (!IFace || !IFace->hasDefinition())
Douglas Gregor36ecb042009-11-17 23:22:23 +00004855 return;
4856
4857 // Add methods in protocols.
Argyrios Kyrtzidisa5f44412012-03-13 01:09:41 +00004858 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
4859 E = IFace->protocol_end();
Douglas Gregor36ecb042009-11-17 23:22:23 +00004860 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004861 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004862 CurContext, Selectors, AllowSameLength, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004863
4864 // Add methods in categories.
Douglas Gregord3297242013-01-16 23:00:23 +00004865 for (ObjCInterfaceDecl::known_categories_iterator
4866 Cat = IFace->known_categories_begin(),
4867 CatEnd = IFace->known_categories_end();
4868 Cat != CatEnd; ++Cat) {
4869 ObjCCategoryDecl *CatDecl = *Cat;
4870
4871 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004872 NumSelIdents, CurContext, Selectors, AllowSameLength,
4873 Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004874
4875 // Add a categories protocol methods.
4876 const ObjCList<ObjCProtocolDecl> &Protocols
4877 = CatDecl->getReferencedProtocols();
4878 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4879 E = Protocols.end();
4880 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00004881 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004882 NumSelIdents, CurContext, Selectors, AllowSameLength,
4883 Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004884
4885 // Add methods in category implementations.
4886 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004887 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004888 NumSelIdents, CurContext, Selectors, AllowSameLength,
4889 Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004890 }
4891
4892 // Add methods in superclass.
4893 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004894 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregorcf544262010-11-17 21:36:08 +00004895 SelIdents, NumSelIdents, CurContext, Selectors,
4896 AllowSameLength, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00004897
4898 // Add methods in our implementation, if any.
4899 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00004900 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00004901 NumSelIdents, CurContext, Selectors, AllowSameLength,
4902 Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004903}
4904
4905
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00004906void Sema::CodeCompleteObjCPropertyGetter(Scope *S) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00004907 // Try to find the interface where getters might live.
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00004908 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004909 if (!Class) {
4910 if (ObjCCategoryDecl *Category
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00004911 = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004912 Class = Category->getClassInterface();
4913
4914 if (!Class)
4915 return;
4916 }
4917
4918 // Find all of the potential getters.
Douglas Gregor218937c2011-02-01 19:23:04 +00004919 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004920 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004921 CodeCompletionContext::CCC_Other);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004922 Results.EnterNewScope();
4923
Douglas Gregord36adf52010-09-16 16:06:31 +00004924 VisitedSelectorSet Selectors;
4925 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
Douglas Gregorcf544262010-11-17 21:36:08 +00004926 /*AllowSameLength=*/true, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004927 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004928 HandleCodeCompleteResults(this, CodeCompleter,
4929 CodeCompletionContext::CCC_Other,
4930 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00004931}
4932
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00004933void Sema::CodeCompleteObjCPropertySetter(Scope *S) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00004934 // Try to find the interface where setters might live.
4935 ObjCInterfaceDecl *Class
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00004936 = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004937 if (!Class) {
4938 if (ObjCCategoryDecl *Category
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00004939 = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
Douglas Gregor4ad96852009-11-19 07:41:15 +00004940 Class = Category->getClassInterface();
4941
4942 if (!Class)
4943 return;
4944 }
4945
4946 // Find all of the potential getters.
Douglas Gregor218937c2011-02-01 19:23:04 +00004947 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004948 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004949 CodeCompletionContext::CCC_Other);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004950 Results.EnterNewScope();
4951
Douglas Gregord36adf52010-09-16 16:06:31 +00004952 VisitedSelectorSet Selectors;
4953 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
Douglas Gregorcf544262010-11-17 21:36:08 +00004954 Selectors, /*AllowSameLength=*/true, Results);
Douglas Gregor4ad96852009-11-19 07:41:15 +00004955
4956 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004957 HandleCodeCompleteResults(this, CodeCompleter,
4958 CodeCompletionContext::CCC_Other,
4959 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00004960}
4961
Douglas Gregorafc45782011-02-15 22:19:42 +00004962void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
4963 bool IsParameter) {
Douglas Gregor218937c2011-02-01 19:23:04 +00004964 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004965 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00004966 CodeCompletionContext::CCC_Type);
Douglas Gregord32b0222010-08-24 01:06:58 +00004967 Results.EnterNewScope();
4968
4969 // Add context-sensitive, Objective-C parameter-passing keywords.
4970 bool AddedInOut = false;
4971 if ((DS.getObjCDeclQualifier() &
4972 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
4973 Results.AddResult("in");
4974 Results.AddResult("inout");
4975 AddedInOut = true;
4976 }
4977 if ((DS.getObjCDeclQualifier() &
4978 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
4979 Results.AddResult("out");
4980 if (!AddedInOut)
4981 Results.AddResult("inout");
4982 }
4983 if ((DS.getObjCDeclQualifier() &
4984 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
4985 ObjCDeclSpec::DQ_Oneway)) == 0) {
4986 Results.AddResult("bycopy");
4987 Results.AddResult("byref");
4988 Results.AddResult("oneway");
4989 }
4990
Douglas Gregorafc45782011-02-15 22:19:42 +00004991 // If we're completing the return type of an Objective-C method and the
4992 // identifier IBAction refers to a macro, provide a completion item for
4993 // an action, e.g.,
4994 // IBAction)<#selector#>:(id)sender
4995 if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
4996 Context.Idents.get("IBAction").hasMacroDefinition()) {
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00004997 CodeCompletionBuilder Builder(Results.getAllocator(),
4998 Results.getCodeCompletionTUInfo(),
4999 CCP_CodePattern, CXAvailability_Available);
Douglas Gregorafc45782011-02-15 22:19:42 +00005000 Builder.AddTypedTextChunk("IBAction");
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00005001 Builder.AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorafc45782011-02-15 22:19:42 +00005002 Builder.AddPlaceholderChunk("selector");
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00005003 Builder.AddChunk(CodeCompletionString::CK_Colon);
5004 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregorafc45782011-02-15 22:19:42 +00005005 Builder.AddTextChunk("id");
Benjamin Kramer1eb18af2012-03-26 16:57:36 +00005006 Builder.AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorafc45782011-02-15 22:19:42 +00005007 Builder.AddTextChunk("sender");
5008 Results.AddResult(CodeCompletionResult(Builder.TakeString()));
5009 }
Douglas Gregor31aa5772013-01-30 07:11:43 +00005010
5011 // If we're completing the return type, provide 'instancetype'.
5012 if (!IsParameter) {
5013 Results.AddResult(CodeCompletionResult("instancetype"));
5014 }
Douglas Gregorafc45782011-02-15 22:19:42 +00005015
Douglas Gregord32b0222010-08-24 01:06:58 +00005016 // Add various builtin type names and specifiers.
5017 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
5018 Results.ExitScope();
5019
5020 // Add the various type names
5021 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
5022 CodeCompletionDeclConsumer Consumer(Results, CurContext);
5023 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5024 CodeCompleter->includeGlobals());
5025
5026 if (CodeCompleter->includeMacros())
Douglas Gregor3644d972012-10-09 16:01:50 +00005027 AddMacroResults(PP, Results, false);
Douglas Gregord32b0222010-08-24 01:06:58 +00005028
5029 HandleCodeCompleteResults(this, CodeCompleter,
5030 CodeCompletionContext::CCC_Type,
5031 Results.data(), Results.size());
5032}
5033
Douglas Gregor22f56992010-04-06 19:22:33 +00005034/// \brief When we have an expression with type "id", we may assume
5035/// that it has some more-specific class type based on knowledge of
5036/// common uses of Objective-C. This routine returns that class type,
5037/// or NULL if no better result could be determined.
5038static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
Douglas Gregor78edf512010-09-15 16:23:04 +00005039 ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
Douglas Gregor22f56992010-04-06 19:22:33 +00005040 if (!Msg)
5041 return 0;
5042
5043 Selector Sel = Msg->getSelector();
5044 if (Sel.isNull())
5045 return 0;
5046
5047 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
5048 if (!Id)
5049 return 0;
5050
5051 ObjCMethodDecl *Method = Msg->getMethodDecl();
5052 if (!Method)
5053 return 0;
5054
5055 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00005056 ObjCInterfaceDecl *IFace = 0;
5057 switch (Msg->getReceiverKind()) {
5058 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00005059 if (const ObjCObjectType *ObjType
5060 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
5061 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00005062 break;
5063
5064 case ObjCMessageExpr::Instance: {
5065 QualType T = Msg->getInstanceReceiver()->getType();
5066 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
5067 IFace = Ptr->getInterfaceDecl();
5068 break;
5069 }
5070
5071 case ObjCMessageExpr::SuperInstance:
5072 case ObjCMessageExpr::SuperClass:
5073 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00005074 }
5075
5076 if (!IFace)
5077 return 0;
5078
5079 ObjCInterfaceDecl *Super = IFace->getSuperClass();
5080 if (Method->isInstanceMethod())
5081 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
5082 .Case("retain", IFace)
John McCallf85e1932011-06-15 23:02:42 +00005083 .Case("strong", IFace)
Douglas Gregor22f56992010-04-06 19:22:33 +00005084 .Case("autorelease", IFace)
5085 .Case("copy", IFace)
5086 .Case("copyWithZone", IFace)
5087 .Case("mutableCopy", IFace)
5088 .Case("mutableCopyWithZone", IFace)
5089 .Case("awakeFromCoder", IFace)
5090 .Case("replacementObjectFromCoder", IFace)
5091 .Case("class", IFace)
5092 .Case("classForCoder", IFace)
5093 .Case("superclass", Super)
5094 .Default(0);
5095
5096 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
5097 .Case("new", IFace)
5098 .Case("alloc", IFace)
5099 .Case("allocWithZone", IFace)
5100 .Case("class", IFace)
5101 .Case("superclass", Super)
5102 .Default(0);
5103}
5104
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005105// Add a special completion for a message send to "super", which fills in the
5106// most likely case of forwarding all of our arguments to the superclass
5107// function.
5108///
5109/// \param S The semantic analysis object.
5110///
Dmitri Gribenko70517ca2012-08-23 17:58:28 +00005111/// \param NeedSuperKeyword Whether we need to prefix this completion with
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005112/// the "super" keyword. Otherwise, we just need to provide the arguments.
5113///
5114/// \param SelIdents The identifiers in the selector that have already been
5115/// provided as arguments for a send to "super".
5116///
5117/// \param NumSelIdents The number of identifiers in \p SelIdents.
5118///
5119/// \param Results The set of results to augment.
5120///
5121/// \returns the Objective-C method declaration that would be invoked by
5122/// this "super" completion. If NULL, no completion was added.
5123static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
5124 IdentifierInfo **SelIdents,
5125 unsigned NumSelIdents,
5126 ResultBuilder &Results) {
5127 ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
5128 if (!CurMethod)
5129 return 0;
5130
5131 ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
5132 if (!Class)
5133 return 0;
5134
5135 // Try to find a superclass method with the same selector.
5136 ObjCMethodDecl *SuperMethod = 0;
Douglas Gregor78bcd912011-02-16 00:51:18 +00005137 while ((Class = Class->getSuperClass()) && !SuperMethod) {
5138 // Check in the class
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005139 SuperMethod = Class->getMethod(CurMethod->getSelector(),
5140 CurMethod->isInstanceMethod());
5141
Douglas Gregor78bcd912011-02-16 00:51:18 +00005142 // Check in categories or class extensions.
5143 if (!SuperMethod) {
Douglas Gregord3297242013-01-16 23:00:23 +00005144 for (ObjCInterfaceDecl::known_categories_iterator
5145 Cat = Class->known_categories_begin(),
5146 CatEnd = Class->known_categories_end();
5147 Cat != CatEnd; ++Cat) {
5148 if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(),
Douglas Gregor78bcd912011-02-16 00:51:18 +00005149 CurMethod->isInstanceMethod())))
5150 break;
Douglas Gregord3297242013-01-16 23:00:23 +00005151 }
Douglas Gregor78bcd912011-02-16 00:51:18 +00005152 }
5153 }
5154
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005155 if (!SuperMethod)
5156 return 0;
5157
5158 // Check whether the superclass method has the same signature.
5159 if (CurMethod->param_size() != SuperMethod->param_size() ||
5160 CurMethod->isVariadic() != SuperMethod->isVariadic())
5161 return 0;
5162
5163 for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
5164 CurPEnd = CurMethod->param_end(),
5165 SuperP = SuperMethod->param_begin();
5166 CurP != CurPEnd; ++CurP, ++SuperP) {
5167 // Make sure the parameter types are compatible.
5168 if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
5169 (*SuperP)->getType()))
5170 return 0;
5171
5172 // Make sure we have a parameter name to forward!
5173 if (!(*CurP)->getIdentifier())
5174 return 0;
5175 }
5176
5177 // We have a superclass method. Now, form the send-to-super completion.
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005178 CodeCompletionBuilder Builder(Results.getAllocator(),
5179 Results.getCodeCompletionTUInfo());
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005180
5181 // Give this completion a return type.
Douglas Gregor8987b232011-09-27 23:30:47 +00005182 AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod,
5183 Builder);
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005184
5185 // If we need the "super" keyword, add it (plus some spacing).
5186 if (NeedSuperKeyword) {
Douglas Gregor218937c2011-02-01 19:23:04 +00005187 Builder.AddTypedTextChunk("super");
5188 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005189 }
5190
5191 Selector Sel = CurMethod->getSelector();
5192 if (Sel.isUnarySelector()) {
5193 if (NeedSuperKeyword)
Douglas Gregordae68752011-02-01 22:57:45 +00005194 Builder.AddTextChunk(Builder.getAllocator().CopyString(
Douglas Gregor813d8342011-02-18 22:29:55 +00005195 Sel.getNameForSlot(0)));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005196 else
Douglas Gregordae68752011-02-01 22:57:45 +00005197 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
Douglas Gregor813d8342011-02-18 22:29:55 +00005198 Sel.getNameForSlot(0)));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005199 } else {
5200 ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
5201 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
5202 if (I > NumSelIdents)
Douglas Gregor218937c2011-02-01 19:23:04 +00005203 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005204
5205 if (I < NumSelIdents)
Douglas Gregor218937c2011-02-01 19:23:04 +00005206 Builder.AddInformativeChunk(
Douglas Gregordae68752011-02-01 22:57:45 +00005207 Builder.getAllocator().CopyString(
Douglas Gregor813d8342011-02-18 22:29:55 +00005208 Sel.getNameForSlot(I) + ":"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005209 else if (NeedSuperKeyword || I > NumSelIdents) {
Douglas Gregor218937c2011-02-01 19:23:04 +00005210 Builder.AddTextChunk(
Douglas Gregordae68752011-02-01 22:57:45 +00005211 Builder.getAllocator().CopyString(
Douglas Gregor813d8342011-02-18 22:29:55 +00005212 Sel.getNameForSlot(I) + ":"));
Douglas Gregordae68752011-02-01 22:57:45 +00005213 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
Douglas Gregor218937c2011-02-01 19:23:04 +00005214 (*CurP)->getIdentifier()->getName()));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005215 } else {
Douglas Gregor218937c2011-02-01 19:23:04 +00005216 Builder.AddTypedTextChunk(
Douglas Gregordae68752011-02-01 22:57:45 +00005217 Builder.getAllocator().CopyString(
Douglas Gregor813d8342011-02-18 22:29:55 +00005218 Sel.getNameForSlot(I) + ":"));
Douglas Gregordae68752011-02-01 22:57:45 +00005219 Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
Douglas Gregor218937c2011-02-01 19:23:04 +00005220 (*CurP)->getIdentifier()->getName()));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005221 }
5222 }
5223 }
5224
Douglas Gregorba103062012-03-27 23:34:16 +00005225 Results.AddResult(CodeCompletionResult(Builder.TakeString(), SuperMethod,
5226 CCP_SuperCompletion));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005227 return SuperMethod;
5228}
5229
Douglas Gregor8e254cf2010-05-27 23:06:34 +00005230void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00005231 typedef CodeCompletionResult Result;
Douglas Gregor218937c2011-02-01 19:23:04 +00005232 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005233 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00005234 CodeCompletionContext::CCC_ObjCMessageReceiver,
Richard Smith80ad52f2013-01-02 11:42:31 +00005235 getLangOpts().CPlusPlus11
Douglas Gregor81f3bff2012-02-15 15:34:24 +00005236 ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
5237 : &ResultBuilder::IsObjCMessageReceiver);
Douglas Gregor8e254cf2010-05-27 23:06:34 +00005238
Douglas Gregor8e254cf2010-05-27 23:06:34 +00005239 CodeCompletionDeclConsumer Consumer(Results, CurContext);
5240 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00005241 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5242 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00005243
5244 // If we are in an Objective-C method inside a class that has a superclass,
5245 // add "super" as an option.
5246 if (ObjCMethodDecl *Method = getCurMethodDecl())
5247 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005248 if (Iface->getSuperClass()) {
Douglas Gregor8e254cf2010-05-27 23:06:34 +00005249 Results.AddResult(Result("super"));
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005250
5251 AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
5252 }
Douglas Gregor8e254cf2010-05-27 23:06:34 +00005253
Richard Smith80ad52f2013-01-02 11:42:31 +00005254 if (getLangOpts().CPlusPlus11)
Douglas Gregor81f3bff2012-02-15 15:34:24 +00005255 addThisCompletion(*this, Results);
5256
Douglas Gregor8e254cf2010-05-27 23:06:34 +00005257 Results.ExitScope();
5258
5259 if (CodeCompleter->includeMacros())
Douglas Gregor3644d972012-10-09 16:01:50 +00005260 AddMacroResults(PP, Results, false);
Douglas Gregorcee9ff12010-09-20 22:39:41 +00005261 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005262 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00005263
5264}
5265
Douglas Gregor2725ca82010-04-21 19:57:20 +00005266void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
5267 IdentifierInfo **SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00005268 unsigned NumSelIdents,
5269 bool AtArgumentExpression) {
Douglas Gregor2725ca82010-04-21 19:57:20 +00005270 ObjCInterfaceDecl *CDecl = 0;
5271 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
5272 // Figure out which interface we're in.
5273 CDecl = CurMethod->getClassInterface();
5274 if (!CDecl)
5275 return;
5276
5277 // Find the superclass of this class.
5278 CDecl = CDecl->getSuperClass();
5279 if (!CDecl)
5280 return;
5281
5282 if (CurMethod->isInstanceMethod()) {
5283 // We are inside an instance method, which means that the message
5284 // send [super ...] is actually calling an instance method on the
Douglas Gregor6b0656a2010-10-13 21:24:53 +00005285 // current object.
5286 return CodeCompleteObjCInstanceMessage(S, 0,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005287 SelIdents, NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00005288 AtArgumentExpression,
Douglas Gregor6b0656a2010-10-13 21:24:53 +00005289 CDecl);
Douglas Gregor2725ca82010-04-21 19:57:20 +00005290 }
5291
5292 // Fall through to send to the superclass in CDecl.
5293 } else {
5294 // "super" may be the name of a type or variable. Figure out which
5295 // it is.
5296 IdentifierInfo *Super = &Context.Idents.get("super");
5297 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
5298 LookupOrdinaryName);
5299 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
5300 // "super" names an interface. Use it.
5301 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00005302 if (const ObjCObjectType *Iface
5303 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
5304 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00005305 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
5306 // "super" names an unresolved type; we can't be more specific.
5307 } else {
5308 // Assume that "super" names some kind of value and parse that way.
5309 CXXScopeSpec SS;
Abramo Bagnarae4b92762012-01-27 09:46:47 +00005310 SourceLocation TemplateKWLoc;
Douglas Gregor2725ca82010-04-21 19:57:20 +00005311 UnqualifiedId id;
5312 id.setIdentifier(Super, SuperLoc);
Abramo Bagnarae4b92762012-01-27 09:46:47 +00005313 ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id,
5314 false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00005315 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
Douglas Gregor70c5ac72010-09-20 23:34:21 +00005316 SelIdents, NumSelIdents,
5317 AtArgumentExpression);
Douglas Gregor2725ca82010-04-21 19:57:20 +00005318 }
5319
5320 // Fall through
5321 }
5322
John McCallb3d87482010-08-24 05:47:05 +00005323 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00005324 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00005325 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00005326 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00005327 NumSelIdents, AtArgumentExpression,
5328 /*IsSuper=*/true);
Douglas Gregor2725ca82010-04-21 19:57:20 +00005329}
5330
Douglas Gregorb9d77572010-09-21 00:03:25 +00005331/// \brief Given a set of code-completion results for the argument of a message
5332/// send, determine the preferred type (if any) for that argument expression.
5333static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
5334 unsigned NumSelIdents) {
5335 typedef CodeCompletionResult Result;
5336 ASTContext &Context = Results.getSema().Context;
5337
5338 QualType PreferredType;
5339 unsigned BestPriority = CCP_Unlikely * 2;
5340 Result *ResultsData = Results.data();
5341 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
5342 Result &R = ResultsData[I];
5343 if (R.Kind == Result::RK_Declaration &&
5344 isa<ObjCMethodDecl>(R.Declaration)) {
5345 if (R.Priority <= BestPriority) {
Dmitri Gribenko89cf4252013-01-23 17:21:11 +00005346 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
Douglas Gregorb9d77572010-09-21 00:03:25 +00005347 if (NumSelIdents <= Method->param_size()) {
5348 QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
5349 ->getType();
5350 if (R.Priority < BestPriority || PreferredType.isNull()) {
5351 BestPriority = R.Priority;
5352 PreferredType = MyPreferredType;
5353 } else if (!Context.hasSameUnqualifiedType(PreferredType,
5354 MyPreferredType)) {
5355 PreferredType = QualType();
5356 }
5357 }
5358 }
5359 }
5360 }
5361
5362 return PreferredType;
5363}
5364
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005365static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
5366 ParsedType Receiver,
5367 IdentifierInfo **SelIdents,
5368 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00005369 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005370 bool IsSuper,
5371 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00005372 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00005373 ObjCInterfaceDecl *CDecl = 0;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005374
Douglas Gregor24a069f2009-11-17 17:59:40 +00005375 // If the given name refers to an interface type, retrieve the
5376 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00005377 if (Receiver) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005378 QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
Douglas Gregor2725ca82010-04-21 19:57:20 +00005379 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00005380 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
5381 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00005382 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005383
Douglas Gregor36ecb042009-11-17 23:22:23 +00005384 // Add all of the factory methods in this Objective-C class, its protocols,
5385 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00005386 Results.EnterNewScope();
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005387
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005388 // If this is a send-to-super, try to add the special "super" send
5389 // completion.
5390 if (IsSuper) {
5391 if (ObjCMethodDecl *SuperMethod
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005392 = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
5393 Results))
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005394 Results.Ignore(SuperMethod);
5395 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005396
Douglas Gregor265f7492010-08-27 15:29:55 +00005397 // If we're inside an Objective-C method definition, prefer its selector to
5398 // others.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005399 if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
Douglas Gregor265f7492010-08-27 15:29:55 +00005400 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005401
Douglas Gregord36adf52010-09-16 16:06:31 +00005402 VisitedSelectorSet Selectors;
Douglas Gregor13438f92010-04-06 16:40:00 +00005403 if (CDecl)
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005404 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00005405 SemaRef.CurContext, Selectors, AtArgumentExpression,
5406 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00005407 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00005408 // We're messaging "id" as a type; provide all class/factory methods.
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005409
Douglas Gregor719770d2010-04-06 17:30:22 +00005410 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005411 // pool from the AST file.
Axel Naumann0ec56b72012-10-18 19:05:02 +00005412 if (SemaRef.getExternalSource()) {
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005413 for (uint32_t I = 0,
Axel Naumann0ec56b72012-10-18 19:05:02 +00005414 N = SemaRef.getExternalSource()->GetNumExternalSelectors();
John McCall76bd1f32010-06-01 09:23:16 +00005415 I != N; ++I) {
Axel Naumann0ec56b72012-10-18 19:05:02 +00005416 Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I);
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005417 if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00005418 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005419
5420 SemaRef.ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00005421 }
5422 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005423
5424 for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
5425 MEnd = SemaRef.MethodPool.end();
Sebastian Redldb9d2142010-08-02 23:18:59 +00005426 M != MEnd; ++M) {
5427 for (ObjCMethodList *MethList = &M->second.second;
5428 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00005429 MethList = MethList->Next) {
5430 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5431 NumSelIdents))
5432 continue;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005433
Douglas Gregord1f09b42013-01-31 04:52:16 +00005434 Result R(MethList->Method, Results.getBasePriority(MethList->Method),0);
Douglas Gregor13438f92010-04-06 16:40:00 +00005435 R.StartParameter = NumSelIdents;
5436 R.AllParametersAreInformative = false;
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005437 Results.MaybeAddResult(R, SemaRef.CurContext);
Douglas Gregor13438f92010-04-06 16:40:00 +00005438 }
5439 }
5440 }
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005441
5442 Results.ExitScope();
5443}
Douglas Gregor13438f92010-04-06 16:40:00 +00005444
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005445void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
5446 IdentifierInfo **SelIdents,
5447 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00005448 bool AtArgumentExpression,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00005449 bool IsSuper) {
Douglas Gregore081a612011-07-21 01:05:26 +00005450
5451 QualType T = this->GetTypeFromParser(Receiver);
5452
Douglas Gregor218937c2011-02-01 19:23:04 +00005453 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005454 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregore081a612011-07-21 01:05:26 +00005455 CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage,
Douglas Gregor0a47d692011-07-26 15:24:30 +00005456 T, SelIdents, NumSelIdents));
Douglas Gregore081a612011-07-21 01:05:26 +00005457
Douglas Gregor70c5ac72010-09-20 23:34:21 +00005458 AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
5459 AtArgumentExpression, IsSuper, Results);
Douglas Gregorb9d77572010-09-21 00:03:25 +00005460
5461 // If we're actually at the argument expression (rather than prior to the
5462 // selector), we're actually performing code completion for an expression.
5463 // Determine whether we have a single, best method. If so, we can
5464 // code-complete the expression using the corresponding parameter type as
5465 // our preferred type, improving completion results.
5466 if (AtArgumentExpression) {
5467 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
Douglas Gregore081a612011-07-21 01:05:26 +00005468 NumSelIdents);
Douglas Gregorb9d77572010-09-21 00:03:25 +00005469 if (PreferredType.isNull())
5470 CodeCompleteOrdinaryName(S, PCC_Expression);
5471 else
5472 CodeCompleteExpression(S, PreferredType);
5473 return;
5474 }
5475
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005476 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregore081a612011-07-21 01:05:26 +00005477 Results.getCompletionContext(),
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005478 Results.data(), Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00005479}
5480
Richard Trieuf81e5a92011-09-09 02:00:50 +00005481void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00005482 IdentifierInfo **SelIdents,
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005483 unsigned NumSelIdents,
Douglas Gregor70c5ac72010-09-20 23:34:21 +00005484 bool AtArgumentExpression,
Douglas Gregor6b0656a2010-10-13 21:24:53 +00005485 ObjCInterfaceDecl *Super) {
John McCall0a2c5e22010-08-25 06:19:51 +00005486 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00005487
5488 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00005489
Douglas Gregor36ecb042009-11-17 23:22:23 +00005490 // If necessary, apply function/array conversion to the receiver.
5491 // C99 6.7.5.3p[7,8].
John Wiegley429bb272011-04-08 18:41:53 +00005492 if (RecExpr) {
5493 ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr);
5494 if (Conv.isInvalid()) // conversion failed. bail.
5495 return;
5496 RecExpr = Conv.take();
5497 }
Douglas Gregor6b0656a2010-10-13 21:24:53 +00005498 QualType ReceiverType = RecExpr? RecExpr->getType()
5499 : Super? Context.getObjCObjectPointerType(
5500 Context.getObjCInterfaceType(Super))
5501 : Context.getObjCIdType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00005502
Douglas Gregorda892642010-11-08 21:12:30 +00005503 // If we're messaging an expression with type "id" or "Class", check
5504 // whether we know something special about the receiver that allows
5505 // us to assume a more-specific receiver type.
5506 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
5507 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
5508 if (ReceiverType->isObjCClassType())
5509 return CodeCompleteObjCClassMessage(S,
5510 ParsedType::make(Context.getObjCInterfaceType(IFace)),
5511 SelIdents, NumSelIdents,
5512 AtArgumentExpression, Super);
5513
5514 ReceiverType = Context.getObjCObjectPointerType(
5515 Context.getObjCInterfaceType(IFace));
5516 }
5517
Douglas Gregor36ecb042009-11-17 23:22:23 +00005518 // Build the set of methods we can see.
Douglas Gregor218937c2011-02-01 19:23:04 +00005519 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005520 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregore081a612011-07-21 01:05:26 +00005521 CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
Douglas Gregor0a47d692011-07-26 15:24:30 +00005522 ReceiverType, SelIdents, NumSelIdents));
Douglas Gregore081a612011-07-21 01:05:26 +00005523
Douglas Gregor36ecb042009-11-17 23:22:23 +00005524 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00005525
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005526 // If this is a send-to-super, try to add the special "super" send
5527 // completion.
Douglas Gregor6b0656a2010-10-13 21:24:53 +00005528 if (Super) {
Douglas Gregor03d8aec2010-08-27 15:10:57 +00005529 if (ObjCMethodDecl *SuperMethod
5530 = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
5531 Results))
5532 Results.Ignore(SuperMethod);
5533 }
5534
Douglas Gregor265f7492010-08-27 15:29:55 +00005535 // If we're inside an Objective-C method definition, prefer its selector to
5536 // others.
5537 if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
5538 Results.setPreferredSelector(CurMethod->getSelector());
Douglas Gregor36ecb042009-11-17 23:22:23 +00005539
Douglas Gregord36adf52010-09-16 16:06:31 +00005540 // Keep track of the selectors we've already added.
5541 VisitedSelectorSet Selectors;
5542
Douglas Gregorf74a4192009-11-18 00:06:18 +00005543 // Handle messages to Class. This really isn't a message to an instance
5544 // method, so we treat it the same way we would treat a message send to a
5545 // class method.
5546 if (ReceiverType->isObjCClassType() ||
5547 ReceiverType->isObjCQualifiedClassType()) {
5548 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
5549 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00005550 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00005551 CurContext, Selectors, AtArgumentExpression, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00005552 }
5553 }
5554 // Handle messages to a qualified ID ("id<foo>").
5555 else if (const ObjCObjectPointerType *QualID
5556 = ReceiverType->getAsObjCQualifiedIdType()) {
5557 // Search protocols for instance methods.
5558 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
5559 E = QualID->qual_end();
5560 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00005561 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregorcf544262010-11-17 21:36:08 +00005562 Selectors, AtArgumentExpression, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00005563 }
5564 // Handle messages to a pointer to interface type.
5565 else if (const ObjCObjectPointerType *IFacePtr
5566 = ReceiverType->getAsObjCInterfacePointerType()) {
5567 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00005568 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
Douglas Gregorcf544262010-11-17 21:36:08 +00005569 NumSelIdents, CurContext, Selectors, AtArgumentExpression,
5570 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00005571
5572 // Search protocols for instance methods.
5573 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
5574 E = IFacePtr->qual_end();
5575 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00005576 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
Douglas Gregorcf544262010-11-17 21:36:08 +00005577 Selectors, AtArgumentExpression, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00005578 }
Douglas Gregor13438f92010-04-06 16:40:00 +00005579 // Handle messages to "id".
5580 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00005581 // We're messaging "id", so provide all instance methods we know
5582 // about as code-completion results.
5583
5584 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00005585 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00005586 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00005587 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5588 I != N; ++I) {
5589 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00005590 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00005591 continue;
5592
Sebastian Redldb9d2142010-08-02 23:18:59 +00005593 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00005594 }
5595 }
5596
Sebastian Redldb9d2142010-08-02 23:18:59 +00005597 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5598 MEnd = MethodPool.end();
5599 M != MEnd; ++M) {
5600 for (ObjCMethodList *MethList = &M->second.first;
5601 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00005602 MethList = MethList->Next) {
5603 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5604 NumSelIdents))
5605 continue;
Douglas Gregord36adf52010-09-16 16:06:31 +00005606
5607 if (!Selectors.insert(MethList->Method->getSelector()))
5608 continue;
5609
Douglas Gregord1f09b42013-01-31 04:52:16 +00005610 Result R(MethList->Method, Results.getBasePriority(MethList->Method),0);
Douglas Gregor13438f92010-04-06 16:40:00 +00005611 R.StartParameter = NumSelIdents;
5612 R.AllParametersAreInformative = false;
5613 Results.MaybeAddResult(R, CurContext);
5614 }
5615 }
5616 }
Steve Naroffc4df6d22009-11-07 02:08:14 +00005617 Results.ExitScope();
Douglas Gregorb9d77572010-09-21 00:03:25 +00005618
5619
5620 // If we're actually at the argument expression (rather than prior to the
5621 // selector), we're actually performing code completion for an expression.
5622 // Determine whether we have a single, best method. If so, we can
5623 // code-complete the expression using the corresponding parameter type as
5624 // our preferred type, improving completion results.
5625 if (AtArgumentExpression) {
5626 QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
5627 NumSelIdents);
5628 if (PreferredType.isNull())
5629 CodeCompleteOrdinaryName(S, PCC_Expression);
5630 else
5631 CodeCompleteExpression(S, PreferredType);
5632 return;
5633 }
5634
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005635 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregore081a612011-07-21 01:05:26 +00005636 Results.getCompletionContext(),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005637 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00005638}
Douglas Gregor55385fe2009-11-18 04:19:12 +00005639
Douglas Gregorfb629412010-08-23 21:17:50 +00005640void Sema::CodeCompleteObjCForCollection(Scope *S,
5641 DeclGroupPtrTy IterationVar) {
5642 CodeCompleteExpressionData Data;
5643 Data.ObjCCollection = true;
5644
5645 if (IterationVar.getAsOpaquePtr()) {
5646 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
5647 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
5648 if (*I)
5649 Data.IgnoreDecls.push_back(*I);
5650 }
5651 }
5652
5653 CodeCompleteExpression(S, Data);
5654}
5655
Douglas Gregor458433d2010-08-26 15:07:07 +00005656void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
5657 unsigned NumSelIdents) {
5658 // If we have an external source, load the entire class method
5659 // pool from the AST file.
5660 if (ExternalSource) {
5661 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5662 I != N; ++I) {
5663 Selector Sel = ExternalSource->GetExternalSelector(I);
5664 if (Sel.isNull() || MethodPool.count(Sel))
5665 continue;
5666
5667 ReadMethodPool(Sel);
5668 }
5669 }
5670
Douglas Gregor218937c2011-02-01 19:23:04 +00005671 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005672 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00005673 CodeCompletionContext::CCC_SelectorName);
Douglas Gregor458433d2010-08-26 15:07:07 +00005674 Results.EnterNewScope();
5675 for (GlobalMethodPool::iterator M = MethodPool.begin(),
5676 MEnd = MethodPool.end();
5677 M != MEnd; ++M) {
5678
5679 Selector Sel = M->first;
5680 if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
5681 continue;
5682
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005683 CodeCompletionBuilder Builder(Results.getAllocator(),
5684 Results.getCodeCompletionTUInfo());
Douglas Gregor458433d2010-08-26 15:07:07 +00005685 if (Sel.isUnarySelector()) {
Douglas Gregordae68752011-02-01 22:57:45 +00005686 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
Douglas Gregor813d8342011-02-18 22:29:55 +00005687 Sel.getNameForSlot(0)));
Douglas Gregor218937c2011-02-01 19:23:04 +00005688 Results.AddResult(Builder.TakeString());
Douglas Gregor458433d2010-08-26 15:07:07 +00005689 continue;
5690 }
5691
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00005692 std::string Accumulator;
Douglas Gregor458433d2010-08-26 15:07:07 +00005693 for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00005694 if (I == NumSelIdents) {
5695 if (!Accumulator.empty()) {
Douglas Gregordae68752011-02-01 22:57:45 +00005696 Builder.AddInformativeChunk(Builder.getAllocator().CopyString(
Douglas Gregor218937c2011-02-01 19:23:04 +00005697 Accumulator));
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00005698 Accumulator.clear();
5699 }
5700 }
5701
Benjamin Kramera0651c52011-07-26 16:59:25 +00005702 Accumulator += Sel.getNameForSlot(I);
Douglas Gregor2d9e21f2010-08-26 16:46:39 +00005703 Accumulator += ':';
Douglas Gregor458433d2010-08-26 15:07:07 +00005704 }
Douglas Gregordae68752011-02-01 22:57:45 +00005705 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( Accumulator));
Douglas Gregor218937c2011-02-01 19:23:04 +00005706 Results.AddResult(Builder.TakeString());
Douglas Gregor458433d2010-08-26 15:07:07 +00005707 }
5708 Results.ExitScope();
5709
5710 HandleCodeCompleteResults(this, CodeCompleter,
5711 CodeCompletionContext::CCC_SelectorName,
5712 Results.data(), Results.size());
5713}
5714
Douglas Gregor55385fe2009-11-18 04:19:12 +00005715/// \brief Add all of the protocol declarations that we find in the given
5716/// (translation unit) context.
5717static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00005718 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00005719 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00005720 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00005721
5722 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
5723 DEnd = Ctx->decls_end();
5724 D != DEnd; ++D) {
5725 // Record any protocols we find.
5726 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5e2a1ff2012-01-01 19:29:29 +00005727 if (!OnlyForwardDeclarations || !Proto->hasDefinition())
Douglas Gregord1f09b42013-01-31 04:52:16 +00005728 Results.AddResult(Result(Proto, Results.getBasePriority(Proto), 0),
5729 CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00005730 }
5731}
5732
5733void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
5734 unsigned NumProtocols) {
Douglas Gregor218937c2011-02-01 19:23:04 +00005735 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005736 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00005737 CodeCompletionContext::CCC_ObjCProtocolName);
Douglas Gregor55385fe2009-11-18 04:19:12 +00005738
Douglas Gregor70c23352010-12-09 21:44:02 +00005739 if (CodeCompleter && CodeCompleter->includeGlobals()) {
5740 Results.EnterNewScope();
5741
5742 // Tell the result set to ignore all of the protocols we have
5743 // already seen.
5744 // FIXME: This doesn't work when caching code-completion results.
5745 for (unsigned I = 0; I != NumProtocols; ++I)
5746 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
5747 Protocols[I].second))
5748 Results.Ignore(Protocol);
Douglas Gregor55385fe2009-11-18 04:19:12 +00005749
Douglas Gregor70c23352010-12-09 21:44:02 +00005750 // Add all protocols.
5751 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
5752 Results);
Douglas Gregor083128f2009-11-18 04:49:41 +00005753
Douglas Gregor70c23352010-12-09 21:44:02 +00005754 Results.ExitScope();
5755 }
5756
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005757 HandleCodeCompleteResults(this, CodeCompleter,
5758 CodeCompletionContext::CCC_ObjCProtocolName,
5759 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00005760}
5761
5762void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
Douglas Gregor218937c2011-02-01 19:23:04 +00005763 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005764 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00005765 CodeCompletionContext::CCC_ObjCProtocolName);
Douglas Gregor083128f2009-11-18 04:49:41 +00005766
Douglas Gregor70c23352010-12-09 21:44:02 +00005767 if (CodeCompleter && CodeCompleter->includeGlobals()) {
5768 Results.EnterNewScope();
5769
5770 // Add all protocols.
5771 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
5772 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00005773
Douglas Gregor70c23352010-12-09 21:44:02 +00005774 Results.ExitScope();
5775 }
5776
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005777 HandleCodeCompleteResults(this, CodeCompleter,
5778 CodeCompletionContext::CCC_ObjCProtocolName,
5779 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00005780}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005781
5782/// \brief Add all of the Objective-C interface declarations that we find in
5783/// the given (translation unit) context.
5784static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
5785 bool OnlyForwardDeclarations,
5786 bool OnlyUnimplemented,
5787 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00005788 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005789
5790 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
5791 DEnd = Ctx->decls_end();
5792 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00005793 // Record any interfaces we find.
5794 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
Douglas Gregor7723fec2011-12-15 20:29:51 +00005795 if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
Douglas Gregordeacbdc2010-08-11 12:19:30 +00005796 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregord1f09b42013-01-31 04:52:16 +00005797 Results.AddResult(Result(Class, Results.getBasePriority(Class), 0),
5798 CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005799 }
5800}
5801
5802void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
Douglas Gregor218937c2011-02-01 19:23:04 +00005803 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005804 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00005805 CodeCompletionContext::CCC_Other);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005806 Results.EnterNewScope();
5807
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005808 if (CodeCompleter->includeGlobals()) {
5809 // Add all classes.
5810 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5811 false, Results);
5812 }
5813
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005814 Results.ExitScope();
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005815
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005816 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005817 CodeCompletionContext::CCC_ObjCInterfaceName,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005818 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005819}
5820
Douglas Gregorc83c6872010-04-15 22:33:43 +00005821void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
5822 SourceLocation ClassNameLoc) {
Douglas Gregor218937c2011-02-01 19:23:04 +00005823 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005824 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005825 CodeCompletionContext::CCC_ObjCInterfaceName);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005826 Results.EnterNewScope();
5827
5828 // Make sure that we ignore the class we're currently defining.
5829 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005830 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005831 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005832 Results.Ignore(CurClass);
5833
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005834 if (CodeCompleter->includeGlobals()) {
5835 // Add all classes.
5836 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5837 false, Results);
5838 }
5839
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005840 Results.ExitScope();
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005841
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005842 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005843 CodeCompletionContext::CCC_ObjCInterfaceName,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005844 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005845}
5846
5847void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
Douglas Gregor218937c2011-02-01 19:23:04 +00005848 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005849 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00005850 CodeCompletionContext::CCC_Other);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005851 Results.EnterNewScope();
5852
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005853 if (CodeCompleter->includeGlobals()) {
5854 // Add all unimplemented classes.
5855 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5856 true, Results);
5857 }
5858
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005859 Results.ExitScope();
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005860
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005861 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor0f91c8c2011-07-30 06:55:39 +00005862 CodeCompletionContext::CCC_ObjCInterfaceName,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005863 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00005864}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005865
5866void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00005867 IdentifierInfo *ClassName,
5868 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00005869 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005870
Douglas Gregor218937c2011-02-01 19:23:04 +00005871 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005872 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor3da626b2011-07-07 16:03:39 +00005873 CodeCompletionContext::CCC_ObjCCategoryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005874
5875 // Ignore any categories we find that have already been implemented by this
5876 // interface.
5877 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5878 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005879 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregord3297242013-01-16 23:00:23 +00005880 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)){
5881 for (ObjCInterfaceDecl::visible_categories_iterator
5882 Cat = Class->visible_categories_begin(),
5883 CatEnd = Class->visible_categories_end();
5884 Cat != CatEnd; ++Cat) {
5885 CategoryNames.insert(Cat->getIdentifier());
5886 }
5887 }
5888
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005889 // Add all of the categories we know about.
5890 Results.EnterNewScope();
5891 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
5892 for (DeclContext::decl_iterator D = TU->decls_begin(),
5893 DEnd = TU->decls_end();
5894 D != DEnd; ++D)
5895 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
5896 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregord1f09b42013-01-31 04:52:16 +00005897 Results.AddResult(Result(Category, Results.getBasePriority(Category),0),
5898 CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005899 Results.ExitScope();
5900
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005901 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor3da626b2011-07-07 16:03:39 +00005902 CodeCompletionContext::CCC_ObjCCategoryName,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005903 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005904}
5905
5906void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00005907 IdentifierInfo *ClassName,
5908 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00005909 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005910
5911 // Find the corresponding interface. If we couldn't find the interface, the
5912 // program itself is ill-formed. However, we'll try to be helpful still by
5913 // providing the list of all of the categories we know about.
5914 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00005915 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005916 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
5917 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00005918 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005919
Douglas Gregor218937c2011-02-01 19:23:04 +00005920 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005921 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor3da626b2011-07-07 16:03:39 +00005922 CodeCompletionContext::CCC_ObjCCategoryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005923
5924 // Add all of the categories that have have corresponding interface
5925 // declarations in this class and any of its superclasses, except for
5926 // already-implemented categories in the class itself.
5927 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5928 Results.EnterNewScope();
5929 bool IgnoreImplemented = true;
5930 while (Class) {
Douglas Gregord3297242013-01-16 23:00:23 +00005931 for (ObjCInterfaceDecl::visible_categories_iterator
5932 Cat = Class->visible_categories_begin(),
5933 CatEnd = Class->visible_categories_end();
5934 Cat != CatEnd; ++Cat) {
5935 if ((!IgnoreImplemented || !Cat->getImplementation()) &&
5936 CategoryNames.insert(Cat->getIdentifier()))
Douglas Gregord1f09b42013-01-31 04:52:16 +00005937 Results.AddResult(Result(*Cat, Results.getBasePriority(*Cat), 0),
5938 CurContext, 0, false);
Douglas Gregord3297242013-01-16 23:00:23 +00005939 }
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005940
5941 Class = Class->getSuperClass();
5942 IgnoreImplemented = false;
5943 }
5944 Results.ExitScope();
5945
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005946 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor3da626b2011-07-07 16:03:39 +00005947 CodeCompletionContext::CCC_ObjCCategoryName,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005948 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00005949}
Douglas Gregor322328b2009-11-18 22:32:06 +00005950
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00005951void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
Douglas Gregor218937c2011-02-01 19:23:04 +00005952 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005953 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00005954 CodeCompletionContext::CCC_Other);
Douglas Gregor322328b2009-11-18 22:32:06 +00005955
5956 // Figure out where this @synthesize lives.
5957 ObjCContainerDecl *Container
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00005958 = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
Douglas Gregor322328b2009-11-18 22:32:06 +00005959 if (!Container ||
5960 (!isa<ObjCImplementationDecl>(Container) &&
5961 !isa<ObjCCategoryImplDecl>(Container)))
5962 return;
5963
5964 // Ignore any properties that have already been implemented.
Douglas Gregorb92a4082012-06-12 13:44:08 +00005965 Container = getContainerDef(Container);
5966 for (DeclContext::decl_iterator D = Container->decls_begin(),
Douglas Gregor322328b2009-11-18 22:32:06 +00005967 DEnd = Container->decls_end();
5968 D != DEnd; ++D)
5969 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
5970 Results.Ignore(PropertyImpl->getPropertyDecl());
5971
5972 // Add any properties that we find.
Douglas Gregor73449212010-12-09 23:01:55 +00005973 AddedPropertiesSet AddedProperties;
Douglas Gregor322328b2009-11-18 22:32:06 +00005974 Results.EnterNewScope();
5975 if (ObjCImplementationDecl *ClassImpl
5976 = dyn_cast<ObjCImplementationDecl>(Container))
Douglas Gregor4b81cde2011-05-05 15:50:42 +00005977 AddObjCProperties(ClassImpl->getClassInterface(), false,
5978 /*AllowNullaryMethods=*/false, CurContext,
Douglas Gregor73449212010-12-09 23:01:55 +00005979 AddedProperties, Results);
Douglas Gregor322328b2009-11-18 22:32:06 +00005980 else
5981 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
Douglas Gregor4b81cde2011-05-05 15:50:42 +00005982 false, /*AllowNullaryMethods=*/false, CurContext,
5983 AddedProperties, Results);
Douglas Gregor322328b2009-11-18 22:32:06 +00005984 Results.ExitScope();
5985
Douglas Gregore6b1bb62010-08-11 21:23:17 +00005986 HandleCodeCompleteResults(this, CodeCompleter,
5987 CodeCompletionContext::CCC_Other,
5988 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00005989}
5990
5991void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00005992 IdentifierInfo *PropertyName) {
John McCall0a2c5e22010-08-25 06:19:51 +00005993 typedef CodeCompletionResult Result;
Douglas Gregor218937c2011-02-01 19:23:04 +00005994 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00005995 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00005996 CodeCompletionContext::CCC_Other);
Douglas Gregor322328b2009-11-18 22:32:06 +00005997
5998 // Figure out where this @synthesize lives.
5999 ObjCContainerDecl *Container
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00006000 = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
Douglas Gregor322328b2009-11-18 22:32:06 +00006001 if (!Container ||
6002 (!isa<ObjCImplementationDecl>(Container) &&
6003 !isa<ObjCCategoryImplDecl>(Container)))
6004 return;
6005
6006 // Figure out which interface we're looking into.
6007 ObjCInterfaceDecl *Class = 0;
6008 if (ObjCImplementationDecl *ClassImpl
6009 = dyn_cast<ObjCImplementationDecl>(Container))
6010 Class = ClassImpl->getClassInterface();
6011 else
6012 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
6013 ->getClassInterface();
6014
Douglas Gregore8426052011-04-18 14:40:46 +00006015 // Determine the type of the property we're synthesizing.
6016 QualType PropertyType = Context.getObjCIdType();
6017 if (Class) {
6018 if (ObjCPropertyDecl *Property
6019 = Class->FindPropertyDeclaration(PropertyName)) {
6020 PropertyType
6021 = Property->getType().getNonReferenceType().getUnqualifiedType();
6022
6023 // Give preference to ivars
6024 Results.setPreferredType(PropertyType);
6025 }
6026 }
6027
Douglas Gregor322328b2009-11-18 22:32:06 +00006028 // Add all of the instance variables in this class and its superclasses.
6029 Results.EnterNewScope();
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006030 bool SawSimilarlyNamedIvar = false;
6031 std::string NameWithPrefix;
6032 NameWithPrefix += '_';
Benjamin Kramera0651c52011-07-26 16:59:25 +00006033 NameWithPrefix += PropertyName->getName();
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006034 std::string NameWithSuffix = PropertyName->getName().str();
6035 NameWithSuffix += '_';
Douglas Gregor322328b2009-11-18 22:32:06 +00006036 for(; Class; Class = Class->getSuperClass()) {
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006037 for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar;
6038 Ivar = Ivar->getNextIvar()) {
Douglas Gregord1f09b42013-01-31 04:52:16 +00006039 Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), 0),
6040 CurContext, 0, false);
Douglas Gregore8426052011-04-18 14:40:46 +00006041
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006042 // Determine whether we've seen an ivar with a name similar to the
6043 // property.
Douglas Gregore8426052011-04-18 14:40:46 +00006044 if ((PropertyName == Ivar->getIdentifier() ||
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006045 NameWithPrefix == Ivar->getName() ||
Douglas Gregore8426052011-04-18 14:40:46 +00006046 NameWithSuffix == Ivar->getName())) {
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006047 SawSimilarlyNamedIvar = true;
Douglas Gregore8426052011-04-18 14:40:46 +00006048
6049 // Reduce the priority of this result by one, to give it a slight
6050 // advantage over other results whose names don't match so closely.
6051 if (Results.size() &&
6052 Results.data()[Results.size() - 1].Kind
6053 == CodeCompletionResult::RK_Declaration &&
6054 Results.data()[Results.size() - 1].Declaration == Ivar)
6055 Results.data()[Results.size() - 1].Priority--;
6056 }
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006057 }
Douglas Gregor322328b2009-11-18 22:32:06 +00006058 }
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006059
6060 if (!SawSimilarlyNamedIvar) {
6061 // Create ivar result _propName, that the user can use to synthesize
Douglas Gregore8426052011-04-18 14:40:46 +00006062 // an ivar of the appropriate type.
6063 unsigned Priority = CCP_MemberDeclaration + 1;
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006064 typedef CodeCompletionResult Result;
6065 CodeCompletionAllocator &Allocator = Results.getAllocator();
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00006066 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(),
6067 Priority,CXAvailability_Available);
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006068
Douglas Gregor8987b232011-09-27 23:30:47 +00006069 PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
Douglas Gregore8426052011-04-18 14:40:46 +00006070 Builder.AddResultTypeChunk(GetCompletionTypeString(PropertyType, Context,
Douglas Gregor8987b232011-09-27 23:30:47 +00006071 Policy, Allocator));
Douglas Gregoraa490cb2011-04-18 14:13:53 +00006072 Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix));
6073 Results.AddResult(Result(Builder.TakeString(), Priority,
6074 CXCursor_ObjCIvarDecl));
6075 }
6076
Douglas Gregor322328b2009-11-18 22:32:06 +00006077 Results.ExitScope();
6078
Douglas Gregore6b1bb62010-08-11 21:23:17 +00006079 HandleCodeCompleteResults(this, CodeCompleter,
6080 CodeCompletionContext::CCC_Other,
6081 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00006082}
Douglas Gregore8f5a172010-04-07 00:21:17 +00006083
Douglas Gregor408be5a2010-08-25 01:08:01 +00006084// Mapping from selectors to the methods that implement that selector, along
6085// with the "in original class" flag.
6086typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
6087 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00006088
6089/// \brief Find all of the methods that reside in the given container
6090/// (and its superclasses, protocols, etc.) that meet the given
6091/// criteria. Insert those methods into the map of known methods,
6092/// indexed by selector so they can be easily found.
6093static void FindImplementableMethods(ASTContext &Context,
6094 ObjCContainerDecl *Container,
6095 bool WantInstanceMethods,
6096 QualType ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00006097 KnownMethodsMap &KnownMethods,
6098 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00006099 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
Douglas Gregorb92a4082012-06-12 13:44:08 +00006100 // Make sure we have a definition; that's what we'll walk.
Douglas Gregor2e5c15b2011-12-15 05:27:12 +00006101 if (!IFace->hasDefinition())
6102 return;
Douglas Gregorb92a4082012-06-12 13:44:08 +00006103
6104 IFace = IFace->getDefinition();
6105 Container = IFace;
Douglas Gregor2e5c15b2011-12-15 05:27:12 +00006106
Douglas Gregore8f5a172010-04-07 00:21:17 +00006107 const ObjCList<ObjCProtocolDecl> &Protocols
6108 = IFace->getReferencedProtocols();
6109 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
Douglas Gregorea766182010-10-18 18:21:28 +00006110 E = Protocols.end();
Douglas Gregore8f5a172010-04-07 00:21:17 +00006111 I != E; ++I)
6112 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00006113 KnownMethods, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006114
Douglas Gregorea766182010-10-18 18:21:28 +00006115 // Add methods from any class extensions and categories.
Douglas Gregord3297242013-01-16 23:00:23 +00006116 for (ObjCInterfaceDecl::visible_categories_iterator
6117 Cat = IFace->visible_categories_begin(),
6118 CatEnd = IFace->visible_categories_end();
6119 Cat != CatEnd; ++Cat) {
6120 FindImplementableMethods(Context, *Cat, WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00006121 KnownMethods, false);
Douglas Gregord3297242013-01-16 23:00:23 +00006122 }
6123
Douglas Gregorea766182010-10-18 18:21:28 +00006124 // Visit the superclass.
6125 if (IFace->getSuperClass())
6126 FindImplementableMethods(Context, IFace->getSuperClass(),
6127 WantInstanceMethods, ReturnType,
6128 KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006129 }
6130
6131 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
6132 // Recurse into protocols.
6133 const ObjCList<ObjCProtocolDecl> &Protocols
6134 = Category->getReferencedProtocols();
6135 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
Douglas Gregorea766182010-10-18 18:21:28 +00006136 E = Protocols.end();
Douglas Gregore8f5a172010-04-07 00:21:17 +00006137 I != E; ++I)
6138 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregorea766182010-10-18 18:21:28 +00006139 KnownMethods, InOriginalClass);
6140
6141 // If this category is the original class, jump to the interface.
6142 if (InOriginalClass && Category->getClassInterface())
6143 FindImplementableMethods(Context, Category->getClassInterface(),
6144 WantInstanceMethods, ReturnType, KnownMethods,
6145 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006146 }
6147
6148 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
Douglas Gregorb92a4082012-06-12 13:44:08 +00006149 // Make sure we have a definition; that's what we'll walk.
6150 if (!Protocol->hasDefinition())
6151 return;
6152 Protocol = Protocol->getDefinition();
6153 Container = Protocol;
6154
6155 // Recurse into protocols.
6156 const ObjCList<ObjCProtocolDecl> &Protocols
6157 = Protocol->getReferencedProtocols();
6158 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6159 E = Protocols.end();
6160 I != E; ++I)
6161 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6162 KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006163 }
6164
6165 // Add methods in this container. This operation occurs last because
6166 // we want the methods from this container to override any methods
6167 // we've previously seen with the same selector.
6168 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
6169 MEnd = Container->meth_end();
6170 M != MEnd; ++M) {
David Blaikie262bc182012-04-30 02:36:29 +00006171 if (M->isInstanceMethod() == WantInstanceMethods) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00006172 if (!ReturnType.isNull() &&
David Blaikie262bc182012-04-30 02:36:29 +00006173 !Context.hasSameUnqualifiedType(ReturnType, M->getResultType()))
Douglas Gregore8f5a172010-04-07 00:21:17 +00006174 continue;
6175
David Blaikie581deb32012-06-06 20:45:41 +00006176 KnownMethods[M->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006177 }
6178 }
6179}
6180
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006181/// \brief Add the parenthesized return or parameter type chunk to a code
6182/// completion string.
6183static void AddObjCPassingTypeChunk(QualType Type,
Douglas Gregor90f5f472012-04-10 18:35:07 +00006184 unsigned ObjCDeclQuals,
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006185 ASTContext &Context,
Douglas Gregor8987b232011-09-27 23:30:47 +00006186 const PrintingPolicy &Policy,
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006187 CodeCompletionBuilder &Builder) {
6188 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor90f5f472012-04-10 18:35:07 +00006189 std::string Quals = formatObjCParamQualifiers(ObjCDeclQuals);
6190 if (!Quals.empty())
6191 Builder.AddTextChunk(Builder.getAllocator().CopyString(Quals));
Douglas Gregor8987b232011-09-27 23:30:47 +00006192 Builder.AddTextChunk(GetCompletionTypeString(Type, Context, Policy,
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006193 Builder.getAllocator()));
6194 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6195}
6196
6197/// \brief Determine whether the given class is or inherits from a class by
6198/// the given name.
6199static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class,
Chris Lattner5f9e2722011-07-23 10:55:15 +00006200 StringRef Name) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006201 if (!Class)
6202 return false;
6203
6204 if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name)
6205 return true;
6206
6207 return InheritsFromClassNamed(Class->getSuperClass(), Name);
6208}
6209
6210/// \brief Add code completions for Objective-C Key-Value Coding (KVC) and
6211/// Key-Value Observing (KVO).
6212static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
6213 bool IsInstanceMethod,
6214 QualType ReturnType,
6215 ASTContext &Context,
Douglas Gregore74c25c2011-05-04 23:50:46 +00006216 VisitedSelectorSet &KnownSelectors,
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006217 ResultBuilder &Results) {
6218 IdentifierInfo *PropName = Property->getIdentifier();
6219 if (!PropName || PropName->getLength() == 0)
6220 return;
6221
Douglas Gregor8987b232011-09-27 23:30:47 +00006222 PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
6223
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006224 // Builder that will create each code completion.
6225 typedef CodeCompletionResult Result;
6226 CodeCompletionAllocator &Allocator = Results.getAllocator();
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00006227 CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006228
6229 // The selector table.
6230 SelectorTable &Selectors = Context.Selectors;
6231
6232 // The property name, copied into the code completion allocation region
6233 // on demand.
6234 struct KeyHolder {
6235 CodeCompletionAllocator &Allocator;
Chris Lattner5f9e2722011-07-23 10:55:15 +00006236 StringRef Key;
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006237 const char *CopiedKey;
6238
Chris Lattner5f9e2722011-07-23 10:55:15 +00006239 KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key)
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006240 : Allocator(Allocator), Key(Key), CopiedKey(0) { }
6241
6242 operator const char *() {
6243 if (CopiedKey)
6244 return CopiedKey;
6245
6246 return CopiedKey = Allocator.CopyString(Key);
6247 }
6248 } Key(Allocator, PropName->getName());
6249
6250 // The uppercased name of the property name.
6251 std::string UpperKey = PropName->getName();
6252 if (!UpperKey.empty())
6253 UpperKey[0] = toupper(UpperKey[0]);
6254
6255 bool ReturnTypeMatchesProperty = ReturnType.isNull() ||
6256 Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(),
6257 Property->getType());
6258 bool ReturnTypeMatchesVoid
6259 = ReturnType.isNull() || ReturnType->isVoidType();
6260
6261 // Add the normal accessor -(type)key.
6262 if (IsInstanceMethod &&
Douglas Gregore74c25c2011-05-04 23:50:46 +00006263 KnownSelectors.insert(Selectors.getNullarySelector(PropName)) &&
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006264 ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) {
6265 if (ReturnType.isNull())
Douglas Gregor90f5f472012-04-10 18:35:07 +00006266 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0,
6267 Context, Policy, Builder);
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006268
6269 Builder.AddTypedTextChunk(Key);
6270 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6271 CXCursor_ObjCInstanceMethodDecl));
6272 }
6273
6274 // If we have an integral or boolean property (or the user has provided
6275 // an integral or boolean return type), add the accessor -(type)isKey.
6276 if (IsInstanceMethod &&
6277 ((!ReturnType.isNull() &&
6278 (ReturnType->isIntegerType() || ReturnType->isBooleanType())) ||
6279 (ReturnType.isNull() &&
6280 (Property->getType()->isIntegerType() ||
6281 Property->getType()->isBooleanType())))) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006282 std::string SelectorName = (Twine("is") + UpperKey).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006283 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006284 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006285 if (ReturnType.isNull()) {
6286 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6287 Builder.AddTextChunk("BOOL");
6288 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6289 }
6290
6291 Builder.AddTypedTextChunk(
6292 Allocator.CopyString(SelectorId->getName()));
6293 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6294 CXCursor_ObjCInstanceMethodDecl));
6295 }
6296 }
6297
6298 // Add the normal mutator.
6299 if (IsInstanceMethod && ReturnTypeMatchesVoid &&
6300 !Property->getSetterMethodDecl()) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006301 std::string SelectorName = (Twine("set") + UpperKey).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006302 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006303 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006304 if (ReturnType.isNull()) {
6305 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6306 Builder.AddTextChunk("void");
6307 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6308 }
6309
6310 Builder.AddTypedTextChunk(
6311 Allocator.CopyString(SelectorId->getName()));
6312 Builder.AddTypedTextChunk(":");
Douglas Gregor90f5f472012-04-10 18:35:07 +00006313 AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0,
6314 Context, Policy, Builder);
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006315 Builder.AddTextChunk(Key);
6316 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6317 CXCursor_ObjCInstanceMethodDecl));
6318 }
6319 }
6320
6321 // Indexed and unordered accessors
6322 unsigned IndexedGetterPriority = CCP_CodePattern;
6323 unsigned IndexedSetterPriority = CCP_CodePattern;
6324 unsigned UnorderedGetterPriority = CCP_CodePattern;
6325 unsigned UnorderedSetterPriority = CCP_CodePattern;
6326 if (const ObjCObjectPointerType *ObjCPointer
6327 = Property->getType()->getAs<ObjCObjectPointerType>()) {
6328 if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) {
6329 // If this interface type is not provably derived from a known
6330 // collection, penalize the corresponding completions.
6331 if (!InheritsFromClassNamed(IFace, "NSMutableArray")) {
6332 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
6333 if (!InheritsFromClassNamed(IFace, "NSArray"))
6334 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
6335 }
6336
6337 if (!InheritsFromClassNamed(IFace, "NSMutableSet")) {
6338 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
6339 if (!InheritsFromClassNamed(IFace, "NSSet"))
6340 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
6341 }
6342 }
6343 } else {
6344 IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
6345 IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
6346 UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
6347 UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
6348 }
6349
6350 // Add -(NSUInteger)countOf<key>
6351 if (IsInstanceMethod &&
6352 (ReturnType.isNull() || ReturnType->isIntegerType())) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006353 std::string SelectorName = (Twine("countOf") + UpperKey).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006354 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006355 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006356 if (ReturnType.isNull()) {
6357 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6358 Builder.AddTextChunk("NSUInteger");
6359 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6360 }
6361
6362 Builder.AddTypedTextChunk(
6363 Allocator.CopyString(SelectorId->getName()));
6364 Results.AddResult(Result(Builder.TakeString(),
6365 std::min(IndexedGetterPriority,
6366 UnorderedGetterPriority),
6367 CXCursor_ObjCInstanceMethodDecl));
6368 }
6369 }
6370
6371 // Indexed getters
6372 // Add -(id)objectInKeyAtIndex:(NSUInteger)index
6373 if (IsInstanceMethod &&
6374 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
Douglas Gregor62041592011-02-17 03:19:26 +00006375 std::string SelectorName
Chris Lattner5f9e2722011-07-23 10:55:15 +00006376 = (Twine("objectIn") + UpperKey + "AtIndex").str();
Douglas Gregor62041592011-02-17 03:19:26 +00006377 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006378 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006379 if (ReturnType.isNull()) {
6380 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6381 Builder.AddTextChunk("id");
6382 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6383 }
6384
6385 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6386 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6387 Builder.AddTextChunk("NSUInteger");
6388 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6389 Builder.AddTextChunk("index");
6390 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6391 CXCursor_ObjCInstanceMethodDecl));
6392 }
6393 }
6394
6395 // Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes
6396 if (IsInstanceMethod &&
6397 (ReturnType.isNull() ||
6398 (ReturnType->isObjCObjectPointerType() &&
6399 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6400 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6401 ->getName() == "NSArray"))) {
Douglas Gregor62041592011-02-17 03:19:26 +00006402 std::string SelectorName
Chris Lattner5f9e2722011-07-23 10:55:15 +00006403 = (Twine(Property->getName()) + "AtIndexes").str();
Douglas Gregor62041592011-02-17 03:19:26 +00006404 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006405 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006406 if (ReturnType.isNull()) {
6407 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6408 Builder.AddTextChunk("NSArray *");
6409 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6410 }
6411
6412 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6413 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6414 Builder.AddTextChunk("NSIndexSet *");
6415 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6416 Builder.AddTextChunk("indexes");
6417 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6418 CXCursor_ObjCInstanceMethodDecl));
6419 }
6420 }
6421
6422 // Add -(void)getKey:(type **)buffer range:(NSRange)inRange
6423 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006424 std::string SelectorName = (Twine("get") + UpperKey).str();
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006425 IdentifierInfo *SelectorIds[2] = {
Douglas Gregor62041592011-02-17 03:19:26 +00006426 &Context.Idents.get(SelectorName),
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006427 &Context.Idents.get("range")
6428 };
6429
Douglas Gregore74c25c2011-05-04 23:50:46 +00006430 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006431 if (ReturnType.isNull()) {
6432 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6433 Builder.AddTextChunk("void");
6434 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6435 }
6436
6437 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6438 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6439 Builder.AddPlaceholderChunk("object-type");
6440 Builder.AddTextChunk(" **");
6441 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6442 Builder.AddTextChunk("buffer");
6443 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6444 Builder.AddTypedTextChunk("range:");
6445 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6446 Builder.AddTextChunk("NSRange");
6447 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6448 Builder.AddTextChunk("inRange");
6449 Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6450 CXCursor_ObjCInstanceMethodDecl));
6451 }
6452 }
6453
6454 // Mutable indexed accessors
6455
6456 // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index
6457 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006458 std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str();
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006459 IdentifierInfo *SelectorIds[2] = {
6460 &Context.Idents.get("insertObject"),
Douglas Gregor62041592011-02-17 03:19:26 +00006461 &Context.Idents.get(SelectorName)
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006462 };
6463
Douglas Gregore74c25c2011-05-04 23:50:46 +00006464 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006465 if (ReturnType.isNull()) {
6466 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6467 Builder.AddTextChunk("void");
6468 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6469 }
6470
6471 Builder.AddTypedTextChunk("insertObject:");
6472 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6473 Builder.AddPlaceholderChunk("object-type");
6474 Builder.AddTextChunk(" *");
6475 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6476 Builder.AddTextChunk("object");
6477 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6478 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6479 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6480 Builder.AddPlaceholderChunk("NSUInteger");
6481 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6482 Builder.AddTextChunk("index");
6483 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6484 CXCursor_ObjCInstanceMethodDecl));
6485 }
6486 }
6487
6488 // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes
6489 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006490 std::string SelectorName = (Twine("insert") + UpperKey).str();
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006491 IdentifierInfo *SelectorIds[2] = {
Douglas Gregor62041592011-02-17 03:19:26 +00006492 &Context.Idents.get(SelectorName),
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006493 &Context.Idents.get("atIndexes")
6494 };
6495
Douglas Gregore74c25c2011-05-04 23:50:46 +00006496 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006497 if (ReturnType.isNull()) {
6498 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6499 Builder.AddTextChunk("void");
6500 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6501 }
6502
6503 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6504 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6505 Builder.AddTextChunk("NSArray *");
6506 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6507 Builder.AddTextChunk("array");
6508 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6509 Builder.AddTypedTextChunk("atIndexes:");
6510 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6511 Builder.AddPlaceholderChunk("NSIndexSet *");
6512 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6513 Builder.AddTextChunk("indexes");
6514 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6515 CXCursor_ObjCInstanceMethodDecl));
6516 }
6517 }
6518
6519 // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index
6520 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Douglas Gregor62041592011-02-17 03:19:26 +00006521 std::string SelectorName
Chris Lattner5f9e2722011-07-23 10:55:15 +00006522 = (Twine("removeObjectFrom") + UpperKey + "AtIndex").str();
Douglas Gregor62041592011-02-17 03:19:26 +00006523 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006524 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006525 if (ReturnType.isNull()) {
6526 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6527 Builder.AddTextChunk("void");
6528 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6529 }
6530
6531 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6532 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6533 Builder.AddTextChunk("NSUInteger");
6534 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6535 Builder.AddTextChunk("index");
6536 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6537 CXCursor_ObjCInstanceMethodDecl));
6538 }
6539 }
6540
6541 // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes
6542 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Douglas Gregor62041592011-02-17 03:19:26 +00006543 std::string SelectorName
Chris Lattner5f9e2722011-07-23 10:55:15 +00006544 = (Twine("remove") + UpperKey + "AtIndexes").str();
Douglas Gregor62041592011-02-17 03:19:26 +00006545 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006546 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006547 if (ReturnType.isNull()) {
6548 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6549 Builder.AddTextChunk("void");
6550 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6551 }
6552
6553 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6554 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6555 Builder.AddTextChunk("NSIndexSet *");
6556 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6557 Builder.AddTextChunk("indexes");
6558 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6559 CXCursor_ObjCInstanceMethodDecl));
6560 }
6561 }
6562
6563 // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object
6564 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Douglas Gregor62041592011-02-17 03:19:26 +00006565 std::string SelectorName
Chris Lattner5f9e2722011-07-23 10:55:15 +00006566 = (Twine("replaceObjectIn") + UpperKey + "AtIndex").str();
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006567 IdentifierInfo *SelectorIds[2] = {
Douglas Gregor62041592011-02-17 03:19:26 +00006568 &Context.Idents.get(SelectorName),
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006569 &Context.Idents.get("withObject")
6570 };
6571
Douglas Gregore74c25c2011-05-04 23:50:46 +00006572 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006573 if (ReturnType.isNull()) {
6574 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6575 Builder.AddTextChunk("void");
6576 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6577 }
6578
6579 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6580 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6581 Builder.AddPlaceholderChunk("NSUInteger");
6582 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6583 Builder.AddTextChunk("index");
6584 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6585 Builder.AddTypedTextChunk("withObject:");
6586 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6587 Builder.AddTextChunk("id");
6588 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6589 Builder.AddTextChunk("object");
6590 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6591 CXCursor_ObjCInstanceMethodDecl));
6592 }
6593 }
6594
6595 // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array
6596 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Douglas Gregor62041592011-02-17 03:19:26 +00006597 std::string SelectorName1
Chris Lattner5f9e2722011-07-23 10:55:15 +00006598 = (Twine("replace") + UpperKey + "AtIndexes").str();
6599 std::string SelectorName2 = (Twine("with") + UpperKey).str();
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006600 IdentifierInfo *SelectorIds[2] = {
Douglas Gregor62041592011-02-17 03:19:26 +00006601 &Context.Idents.get(SelectorName1),
6602 &Context.Idents.get(SelectorName2)
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006603 };
6604
Douglas Gregore74c25c2011-05-04 23:50:46 +00006605 if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006606 if (ReturnType.isNull()) {
6607 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6608 Builder.AddTextChunk("void");
6609 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6610 }
6611
6612 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName1 + ":"));
6613 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6614 Builder.AddPlaceholderChunk("NSIndexSet *");
6615 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6616 Builder.AddTextChunk("indexes");
6617 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6618 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName2 + ":"));
6619 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6620 Builder.AddTextChunk("NSArray *");
6621 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6622 Builder.AddTextChunk("array");
6623 Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6624 CXCursor_ObjCInstanceMethodDecl));
6625 }
6626 }
6627
6628 // Unordered getters
6629 // - (NSEnumerator *)enumeratorOfKey
6630 if (IsInstanceMethod &&
6631 (ReturnType.isNull() ||
6632 (ReturnType->isObjCObjectPointerType() &&
6633 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6634 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6635 ->getName() == "NSEnumerator"))) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006636 std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006637 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006638 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006639 if (ReturnType.isNull()) {
6640 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6641 Builder.AddTextChunk("NSEnumerator *");
6642 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6643 }
6644
6645 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6646 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
6647 CXCursor_ObjCInstanceMethodDecl));
6648 }
6649 }
6650
6651 // - (type *)memberOfKey:(type *)object
6652 if (IsInstanceMethod &&
6653 (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006654 std::string SelectorName = (Twine("memberOf") + UpperKey).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006655 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006656 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006657 if (ReturnType.isNull()) {
6658 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6659 Builder.AddPlaceholderChunk("object-type");
6660 Builder.AddTextChunk(" *");
6661 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6662 }
6663
6664 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6665 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6666 if (ReturnType.isNull()) {
6667 Builder.AddPlaceholderChunk("object-type");
6668 Builder.AddTextChunk(" *");
6669 } else {
6670 Builder.AddTextChunk(GetCompletionTypeString(ReturnType, Context,
Douglas Gregor8987b232011-09-27 23:30:47 +00006671 Policy,
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006672 Builder.getAllocator()));
6673 }
6674 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6675 Builder.AddTextChunk("object");
6676 Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
6677 CXCursor_ObjCInstanceMethodDecl));
6678 }
6679 }
6680
6681 // Mutable unordered accessors
6682 // - (void)addKeyObject:(type *)object
6683 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Douglas Gregor62041592011-02-17 03:19:26 +00006684 std::string SelectorName
Chris Lattner5f9e2722011-07-23 10:55:15 +00006685 = (Twine("add") + UpperKey + Twine("Object")).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006686 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006687 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006688 if (ReturnType.isNull()) {
6689 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6690 Builder.AddTextChunk("void");
6691 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6692 }
6693
6694 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6695 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6696 Builder.AddPlaceholderChunk("object-type");
6697 Builder.AddTextChunk(" *");
6698 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6699 Builder.AddTextChunk("object");
6700 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6701 CXCursor_ObjCInstanceMethodDecl));
6702 }
6703 }
6704
6705 // - (void)addKey:(NSSet *)objects
6706 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006707 std::string SelectorName = (Twine("add") + UpperKey).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006708 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006709 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006710 if (ReturnType.isNull()) {
6711 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6712 Builder.AddTextChunk("void");
6713 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6714 }
6715
6716 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6717 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6718 Builder.AddTextChunk("NSSet *");
6719 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6720 Builder.AddTextChunk("objects");
6721 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6722 CXCursor_ObjCInstanceMethodDecl));
6723 }
6724 }
6725
6726 // - (void)removeKeyObject:(type *)object
6727 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Douglas Gregor62041592011-02-17 03:19:26 +00006728 std::string SelectorName
Chris Lattner5f9e2722011-07-23 10:55:15 +00006729 = (Twine("remove") + UpperKey + Twine("Object")).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006730 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006731 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006732 if (ReturnType.isNull()) {
6733 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6734 Builder.AddTextChunk("void");
6735 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6736 }
6737
6738 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6739 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6740 Builder.AddPlaceholderChunk("object-type");
6741 Builder.AddTextChunk(" *");
6742 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6743 Builder.AddTextChunk("object");
6744 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6745 CXCursor_ObjCInstanceMethodDecl));
6746 }
6747 }
6748
6749 // - (void)removeKey:(NSSet *)objects
6750 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006751 std::string SelectorName = (Twine("remove") + UpperKey).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006752 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006753 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006754 if (ReturnType.isNull()) {
6755 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6756 Builder.AddTextChunk("void");
6757 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6758 }
6759
6760 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6761 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6762 Builder.AddTextChunk("NSSet *");
6763 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6764 Builder.AddTextChunk("objects");
6765 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6766 CXCursor_ObjCInstanceMethodDecl));
6767 }
6768 }
6769
6770 // - (void)intersectKey:(NSSet *)objects
6771 if (IsInstanceMethod && ReturnTypeMatchesVoid) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006772 std::string SelectorName = (Twine("intersect") + UpperKey).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006773 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006774 if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006775 if (ReturnType.isNull()) {
6776 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6777 Builder.AddTextChunk("void");
6778 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6779 }
6780
6781 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6782 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6783 Builder.AddTextChunk("NSSet *");
6784 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6785 Builder.AddTextChunk("objects");
6786 Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6787 CXCursor_ObjCInstanceMethodDecl));
6788 }
6789 }
6790
6791 // Key-Value Observing
6792 // + (NSSet *)keyPathsForValuesAffectingKey
6793 if (!IsInstanceMethod &&
6794 (ReturnType.isNull() ||
6795 (ReturnType->isObjCObjectPointerType() &&
6796 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6797 ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6798 ->getName() == "NSSet"))) {
Douglas Gregor62041592011-02-17 03:19:26 +00006799 std::string SelectorName
Chris Lattner5f9e2722011-07-23 10:55:15 +00006800 = (Twine("keyPathsForValuesAffecting") + UpperKey).str();
Douglas Gregor62041592011-02-17 03:19:26 +00006801 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
Douglas Gregore74c25c2011-05-04 23:50:46 +00006802 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006803 if (ReturnType.isNull()) {
6804 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6805 Builder.AddTextChunk("NSSet *");
6806 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6807 }
6808
6809 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6810 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
Douglas Gregor3f828d12011-06-02 04:02:27 +00006811 CXCursor_ObjCClassMethodDecl));
6812 }
6813 }
6814
6815 // + (BOOL)automaticallyNotifiesObserversForKey
6816 if (!IsInstanceMethod &&
6817 (ReturnType.isNull() ||
6818 ReturnType->isIntegerType() ||
6819 ReturnType->isBooleanType())) {
6820 std::string SelectorName
Chris Lattner5f9e2722011-07-23 10:55:15 +00006821 = (Twine("automaticallyNotifiesObserversOf") + UpperKey).str();
Douglas Gregor3f828d12011-06-02 04:02:27 +00006822 IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6823 if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6824 if (ReturnType.isNull()) {
6825 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6826 Builder.AddTextChunk("BOOL");
6827 Builder.AddChunk(CodeCompletionString::CK_RightParen);
6828 }
6829
6830 Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6831 Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6832 CXCursor_ObjCClassMethodDecl));
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006833 }
6834 }
6835}
6836
Douglas Gregore8f5a172010-04-07 00:21:17 +00006837void Sema::CodeCompleteObjCMethodDecl(Scope *S,
6838 bool IsInstanceMethod,
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00006839 ParsedType ReturnTy) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00006840 // Determine the return type of the method we're declaring, if
6841 // provided.
6842 QualType ReturnType = GetTypeFromParser(ReturnTy);
Fariborz Jahaniana28948f2011-08-22 15:54:49 +00006843 Decl *IDecl = 0;
6844 if (CurContext->isObjCContainer()) {
6845 ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
6846 IDecl = cast<Decl>(OCD);
6847 }
Douglas Gregorea766182010-10-18 18:21:28 +00006848 // Determine where we should start searching for methods.
6849 ObjCContainerDecl *SearchDecl = 0;
Douglas Gregore8f5a172010-04-07 00:21:17 +00006850 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00006851 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00006852 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
6853 SearchDecl = Impl->getClassInterface();
Douglas Gregore8f5a172010-04-07 00:21:17 +00006854 IsInImplementation = true;
6855 } else if (ObjCCategoryImplDecl *CatImpl
Douglas Gregorea766182010-10-18 18:21:28 +00006856 = dyn_cast<ObjCCategoryImplDecl>(D)) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00006857 SearchDecl = CatImpl->getCategoryDecl();
Douglas Gregore8f5a172010-04-07 00:21:17 +00006858 IsInImplementation = true;
Douglas Gregorea766182010-10-18 18:21:28 +00006859 } else
Douglas Gregore8f5a172010-04-07 00:21:17 +00006860 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006861 }
6862
6863 if (!SearchDecl && S) {
Douglas Gregorea766182010-10-18 18:21:28 +00006864 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity()))
Douglas Gregore8f5a172010-04-07 00:21:17 +00006865 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006866 }
6867
Douglas Gregorea766182010-10-18 18:21:28 +00006868 if (!SearchDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00006869 HandleCodeCompleteResults(this, CodeCompleter,
6870 CodeCompletionContext::CCC_Other,
6871 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006872 return;
6873 }
6874
6875 // Find all of the methods that we could declare/implement here.
6876 KnownMethodsMap KnownMethods;
6877 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
Douglas Gregorea766182010-10-18 18:21:28 +00006878 ReturnType, KnownMethods);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006879
Douglas Gregore8f5a172010-04-07 00:21:17 +00006880 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00006881 typedef CodeCompletionResult Result;
Douglas Gregor218937c2011-02-01 19:23:04 +00006882 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00006883 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00006884 CodeCompletionContext::CCC_Other);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006885 Results.EnterNewScope();
Douglas Gregor8987b232011-09-27 23:30:47 +00006886 PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006887 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
6888 MEnd = KnownMethods.end();
6889 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00006890 ObjCMethodDecl *Method = M->second.first;
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00006891 CodeCompletionBuilder Builder(Results.getAllocator(),
6892 Results.getCodeCompletionTUInfo());
Douglas Gregore8f5a172010-04-07 00:21:17 +00006893
6894 // If the result type was not already provided, add it to the
6895 // pattern as (type).
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006896 if (ReturnType.isNull())
Douglas Gregor90f5f472012-04-10 18:35:07 +00006897 AddObjCPassingTypeChunk(Method->getResultType(),
6898 Method->getObjCDeclQualifier(),
6899 Context, Policy,
6900 Builder);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006901
6902 Selector Sel = Method->getSelector();
6903
6904 // Add the first part of the selector to the pattern.
Douglas Gregordae68752011-02-01 22:57:45 +00006905 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
Douglas Gregor813d8342011-02-18 22:29:55 +00006906 Sel.getNameForSlot(0)));
Douglas Gregore8f5a172010-04-07 00:21:17 +00006907
6908 // Add parameters to the pattern.
6909 unsigned I = 0;
6910 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
6911 PEnd = Method->param_end();
6912 P != PEnd; (void)++P, ++I) {
6913 // Add the part of the selector name.
6914 if (I == 0)
Douglas Gregor218937c2011-02-01 19:23:04 +00006915 Builder.AddTypedTextChunk(":");
Douglas Gregore8f5a172010-04-07 00:21:17 +00006916 else if (I < Sel.getNumArgs()) {
Douglas Gregor218937c2011-02-01 19:23:04 +00006917 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6918 Builder.AddTypedTextChunk(
Douglas Gregor813d8342011-02-18 22:29:55 +00006919 Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
Douglas Gregore8f5a172010-04-07 00:21:17 +00006920 } else
6921 break;
6922
6923 // Add the parameter type.
Douglas Gregor90f5f472012-04-10 18:35:07 +00006924 AddObjCPassingTypeChunk((*P)->getOriginalType(),
6925 (*P)->getObjCDeclQualifier(),
6926 Context, Policy,
Douglas Gregor8987b232011-09-27 23:30:47 +00006927 Builder);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006928
6929 if (IdentifierInfo *Id = (*P)->getIdentifier())
Douglas Gregordae68752011-02-01 22:57:45 +00006930 Builder.AddTextChunk(Builder.getAllocator().CopyString( Id->getName()));
Douglas Gregore8f5a172010-04-07 00:21:17 +00006931 }
6932
6933 if (Method->isVariadic()) {
6934 if (Method->param_size() > 0)
Douglas Gregor218937c2011-02-01 19:23:04 +00006935 Builder.AddChunk(CodeCompletionString::CK_Comma);
6936 Builder.AddTextChunk("...");
Douglas Gregore17794f2010-08-31 05:13:43 +00006937 }
Douglas Gregore8f5a172010-04-07 00:21:17 +00006938
Douglas Gregor447107d2010-05-28 00:57:46 +00006939 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00006940 // We will be defining the method here, so add a compound statement.
Douglas Gregor218937c2011-02-01 19:23:04 +00006941 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6942 Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
6943 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006944 if (!Method->getResultType()->isVoidType()) {
6945 // If the result type is not void, add a return clause.
Douglas Gregor218937c2011-02-01 19:23:04 +00006946 Builder.AddTextChunk("return");
6947 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6948 Builder.AddPlaceholderChunk("expression");
6949 Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006950 } else
Douglas Gregor218937c2011-02-01 19:23:04 +00006951 Builder.AddPlaceholderChunk("statements");
Douglas Gregore8f5a172010-04-07 00:21:17 +00006952
Douglas Gregor218937c2011-02-01 19:23:04 +00006953 Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6954 Builder.AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregore8f5a172010-04-07 00:21:17 +00006955 }
6956
Douglas Gregor408be5a2010-08-25 01:08:01 +00006957 unsigned Priority = CCP_CodePattern;
6958 if (!M->second.second)
6959 Priority += CCD_InBaseClass;
6960
Douglas Gregorba103062012-03-27 23:34:16 +00006961 Results.AddResult(Result(Builder.TakeString(), Method, Priority));
Douglas Gregore8f5a172010-04-07 00:21:17 +00006962 }
6963
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006964 // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of
6965 // the properties in this class and its categories.
David Blaikie4e4d0842012-03-11 07:00:24 +00006966 if (Context.getLangOpts().ObjC2) {
Chris Lattner5f9e2722011-07-23 10:55:15 +00006967 SmallVector<ObjCContainerDecl *, 4> Containers;
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006968 Containers.push_back(SearchDecl);
6969
Douglas Gregore74c25c2011-05-04 23:50:46 +00006970 VisitedSelectorSet KnownSelectors;
6971 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
6972 MEnd = KnownMethods.end();
6973 M != MEnd; ++M)
6974 KnownSelectors.insert(M->first);
6975
6976
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006977 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl);
6978 if (!IFace)
6979 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl))
6980 IFace = Category->getClassInterface();
6981
6982 if (IFace) {
Douglas Gregord3297242013-01-16 23:00:23 +00006983 for (ObjCInterfaceDecl::visible_categories_iterator
6984 Cat = IFace->visible_categories_begin(),
6985 CatEnd = IFace->visible_categories_end();
6986 Cat != CatEnd; ++Cat) {
6987 Containers.push_back(*Cat);
6988 }
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006989 }
6990
6991 for (unsigned I = 0, N = Containers.size(); I != N; ++I) {
6992 for (ObjCContainerDecl::prop_iterator P = Containers[I]->prop_begin(),
6993 PEnd = Containers[I]->prop_end();
6994 P != PEnd; ++P) {
David Blaikie581deb32012-06-06 20:45:41 +00006995 AddObjCKeyValueCompletions(*P, IsInstanceMethod, ReturnType, Context,
Douglas Gregore74c25c2011-05-04 23:50:46 +00006996 KnownSelectors, Results);
Douglas Gregor577cdfd2011-02-17 00:22:45 +00006997 }
6998 }
6999 }
7000
Douglas Gregore8f5a172010-04-07 00:21:17 +00007001 Results.ExitScope();
7002
Douglas Gregore6b1bb62010-08-11 21:23:17 +00007003 HandleCodeCompleteResults(this, CodeCompleter,
7004 CodeCompletionContext::CCC_Other,
7005 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00007006}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007007
7008void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
7009 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00007010 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00007011 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007012 IdentifierInfo **SelIdents,
7013 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007014 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00007015 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007016 if (ExternalSource) {
7017 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
7018 I != N; ++I) {
7019 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00007020 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007021 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00007022
7023 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007024 }
7025 }
7026
7027 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00007028 typedef CodeCompletionResult Result;
Douglas Gregor218937c2011-02-01 19:23:04 +00007029 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007030 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor218937c2011-02-01 19:23:04 +00007031 CodeCompletionContext::CCC_Other);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007032
7033 if (ReturnTy)
7034 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00007035
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007036 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00007037 for (GlobalMethodPool::iterator M = MethodPool.begin(),
7038 MEnd = MethodPool.end();
7039 M != MEnd; ++M) {
7040 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
7041 &M->second.second;
7042 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007043 MethList = MethList->Next) {
7044 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
7045 NumSelIdents))
7046 continue;
7047
Douglas Gregor40ed9a12010-07-08 23:37:41 +00007048 if (AtParameterName) {
7049 // Suggest parameter names we've seen before.
7050 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
7051 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
7052 if (Param->getIdentifier()) {
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007053 CodeCompletionBuilder Builder(Results.getAllocator(),
7054 Results.getCodeCompletionTUInfo());
Douglas Gregordae68752011-02-01 22:57:45 +00007055 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
Douglas Gregor218937c2011-02-01 19:23:04 +00007056 Param->getIdentifier()->getName()));
7057 Results.AddResult(Builder.TakeString());
Douglas Gregor40ed9a12010-07-08 23:37:41 +00007058 }
7059 }
7060
7061 continue;
7062 }
7063
Douglas Gregord1f09b42013-01-31 04:52:16 +00007064 Result R(MethList->Method, Results.getBasePriority(MethList->Method), 0);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007065 R.StartParameter = NumSelIdents;
7066 R.AllParametersAreInformative = false;
7067 R.DeclaringEntity = true;
7068 Results.MaybeAddResult(R, CurContext);
7069 }
7070 }
7071
7072 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00007073 HandleCodeCompleteResults(this, CodeCompleter,
7074 CodeCompletionContext::CCC_Other,
7075 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00007076}
Douglas Gregor87c08a52010-08-13 22:48:40 +00007077
Douglas Gregorf29c5232010-08-24 22:20:20 +00007078void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregor218937c2011-02-01 19:23:04 +00007079 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007080 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor52779fb2010-09-23 23:01:17 +00007081 CodeCompletionContext::CCC_PreprocessorDirective);
Douglas Gregorf44e8542010-08-24 19:08:16 +00007082 Results.EnterNewScope();
7083
7084 // #if <condition>
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007085 CodeCompletionBuilder Builder(Results.getAllocator(),
7086 Results.getCodeCompletionTUInfo());
Douglas Gregor218937c2011-02-01 19:23:04 +00007087 Builder.AddTypedTextChunk("if");
7088 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7089 Builder.AddPlaceholderChunk("condition");
7090 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007091
7092 // #ifdef <macro>
Douglas Gregor218937c2011-02-01 19:23:04 +00007093 Builder.AddTypedTextChunk("ifdef");
7094 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7095 Builder.AddPlaceholderChunk("macro");
7096 Results.AddResult(Builder.TakeString());
7097
Douglas Gregorf44e8542010-08-24 19:08:16 +00007098 // #ifndef <macro>
Douglas Gregor218937c2011-02-01 19:23:04 +00007099 Builder.AddTypedTextChunk("ifndef");
7100 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7101 Builder.AddPlaceholderChunk("macro");
7102 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007103
7104 if (InConditional) {
7105 // #elif <condition>
Douglas Gregor218937c2011-02-01 19:23:04 +00007106 Builder.AddTypedTextChunk("elif");
7107 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7108 Builder.AddPlaceholderChunk("condition");
7109 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007110
7111 // #else
Douglas Gregor218937c2011-02-01 19:23:04 +00007112 Builder.AddTypedTextChunk("else");
7113 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007114
7115 // #endif
Douglas Gregor218937c2011-02-01 19:23:04 +00007116 Builder.AddTypedTextChunk("endif");
7117 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007118 }
7119
7120 // #include "header"
Douglas Gregor218937c2011-02-01 19:23:04 +00007121 Builder.AddTypedTextChunk("include");
7122 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7123 Builder.AddTextChunk("\"");
7124 Builder.AddPlaceholderChunk("header");
7125 Builder.AddTextChunk("\"");
7126 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007127
7128 // #include <header>
Douglas Gregor218937c2011-02-01 19:23:04 +00007129 Builder.AddTypedTextChunk("include");
7130 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7131 Builder.AddTextChunk("<");
7132 Builder.AddPlaceholderChunk("header");
7133 Builder.AddTextChunk(">");
7134 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007135
7136 // #define <macro>
Douglas Gregor218937c2011-02-01 19:23:04 +00007137 Builder.AddTypedTextChunk("define");
7138 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7139 Builder.AddPlaceholderChunk("macro");
7140 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007141
7142 // #define <macro>(<args>)
Douglas Gregor218937c2011-02-01 19:23:04 +00007143 Builder.AddTypedTextChunk("define");
7144 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7145 Builder.AddPlaceholderChunk("macro");
7146 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7147 Builder.AddPlaceholderChunk("args");
7148 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7149 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007150
7151 // #undef <macro>
Douglas Gregor218937c2011-02-01 19:23:04 +00007152 Builder.AddTypedTextChunk("undef");
7153 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7154 Builder.AddPlaceholderChunk("macro");
7155 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007156
7157 // #line <number>
Douglas Gregor218937c2011-02-01 19:23:04 +00007158 Builder.AddTypedTextChunk("line");
7159 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7160 Builder.AddPlaceholderChunk("number");
7161 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007162
7163 // #line <number> "filename"
Douglas Gregor218937c2011-02-01 19:23:04 +00007164 Builder.AddTypedTextChunk("line");
7165 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7166 Builder.AddPlaceholderChunk("number");
7167 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7168 Builder.AddTextChunk("\"");
7169 Builder.AddPlaceholderChunk("filename");
7170 Builder.AddTextChunk("\"");
7171 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007172
7173 // #error <message>
Douglas Gregor218937c2011-02-01 19:23:04 +00007174 Builder.AddTypedTextChunk("error");
7175 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7176 Builder.AddPlaceholderChunk("message");
7177 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007178
7179 // #pragma <arguments>
Douglas Gregor218937c2011-02-01 19:23:04 +00007180 Builder.AddTypedTextChunk("pragma");
7181 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7182 Builder.AddPlaceholderChunk("arguments");
7183 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007184
David Blaikie4e4d0842012-03-11 07:00:24 +00007185 if (getLangOpts().ObjC1) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00007186 // #import "header"
Douglas Gregor218937c2011-02-01 19:23:04 +00007187 Builder.AddTypedTextChunk("import");
7188 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7189 Builder.AddTextChunk("\"");
7190 Builder.AddPlaceholderChunk("header");
7191 Builder.AddTextChunk("\"");
7192 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007193
7194 // #import <header>
Douglas Gregor218937c2011-02-01 19:23:04 +00007195 Builder.AddTypedTextChunk("import");
7196 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7197 Builder.AddTextChunk("<");
7198 Builder.AddPlaceholderChunk("header");
7199 Builder.AddTextChunk(">");
7200 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007201 }
7202
7203 // #include_next "header"
Douglas Gregor218937c2011-02-01 19:23:04 +00007204 Builder.AddTypedTextChunk("include_next");
7205 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7206 Builder.AddTextChunk("\"");
7207 Builder.AddPlaceholderChunk("header");
7208 Builder.AddTextChunk("\"");
7209 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007210
7211 // #include_next <header>
Douglas Gregor218937c2011-02-01 19:23:04 +00007212 Builder.AddTypedTextChunk("include_next");
7213 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7214 Builder.AddTextChunk("<");
7215 Builder.AddPlaceholderChunk("header");
7216 Builder.AddTextChunk(">");
7217 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007218
7219 // #warning <message>
Douglas Gregor218937c2011-02-01 19:23:04 +00007220 Builder.AddTypedTextChunk("warning");
7221 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7222 Builder.AddPlaceholderChunk("message");
7223 Results.AddResult(Builder.TakeString());
Douglas Gregorf44e8542010-08-24 19:08:16 +00007224
7225 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
7226 // completions for them. And __include_macros is a Clang-internal extension
7227 // that we don't want to encourage anyone to use.
7228
7229 // FIXME: we don't support #assert or #unassert, so don't suggest them.
7230 Results.ExitScope();
7231
Douglas Gregorf44e8542010-08-24 19:08:16 +00007232 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00007233 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00007234 Results.data(), Results.size());
7235}
7236
7237void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00007238 CodeCompleteOrdinaryName(S,
John McCallf312b1e2010-08-26 23:41:50 +00007239 S->getFnParent()? Sema::PCC_RecoveryInFunction
7240 : Sema::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00007241}
7242
Douglas Gregorf29c5232010-08-24 22:20:20 +00007243void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor218937c2011-02-01 19:23:04 +00007244 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007245 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor52779fb2010-09-23 23:01:17 +00007246 IsDefinition? CodeCompletionContext::CCC_MacroName
7247 : CodeCompletionContext::CCC_MacroNameUse);
Douglas Gregor1fbb4472010-08-24 20:21:13 +00007248 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
7249 // Add just the names of macros, not their arguments.
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007250 CodeCompletionBuilder Builder(Results.getAllocator(),
7251 Results.getCodeCompletionTUInfo());
Douglas Gregor1fbb4472010-08-24 20:21:13 +00007252 Results.EnterNewScope();
7253 for (Preprocessor::macro_iterator M = PP.macro_begin(),
7254 MEnd = PP.macro_end();
7255 M != MEnd; ++M) {
Douglas Gregordae68752011-02-01 22:57:45 +00007256 Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
Douglas Gregor218937c2011-02-01 19:23:04 +00007257 M->first->getName()));
Argyrios Kyrtzidisc04bb922012-09-27 00:24:09 +00007258 Results.AddResult(CodeCompletionResult(Builder.TakeString(),
7259 CCP_CodePattern,
7260 CXCursor_MacroDefinition));
Douglas Gregor1fbb4472010-08-24 20:21:13 +00007261 }
7262 Results.ExitScope();
7263 } else if (IsDefinition) {
7264 // FIXME: Can we detect when the user just wrote an include guard above?
7265 }
7266
Douglas Gregor52779fb2010-09-23 23:01:17 +00007267 HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
Douglas Gregor1fbb4472010-08-24 20:21:13 +00007268 Results.data(), Results.size());
7269}
7270
Douglas Gregorf29c5232010-08-24 22:20:20 +00007271void Sema::CodeCompletePreprocessorExpression() {
Douglas Gregor218937c2011-02-01 19:23:04 +00007272 ResultBuilder Results(*this, CodeCompleter->getAllocator(),
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007273 CodeCompleter->getCodeCompletionTUInfo(),
Douglas Gregor52779fb2010-09-23 23:01:17 +00007274 CodeCompletionContext::CCC_PreprocessorExpression);
Douglas Gregorf29c5232010-08-24 22:20:20 +00007275
7276 if (!CodeCompleter || CodeCompleter->includeMacros())
Douglas Gregor3644d972012-10-09 16:01:50 +00007277 AddMacroResults(PP, Results, true);
Douglas Gregorf29c5232010-08-24 22:20:20 +00007278
7279 // defined (<macro>)
7280 Results.EnterNewScope();
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007281 CodeCompletionBuilder Builder(Results.getAllocator(),
7282 Results.getCodeCompletionTUInfo());
Douglas Gregor218937c2011-02-01 19:23:04 +00007283 Builder.AddTypedTextChunk("defined");
7284 Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7285 Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7286 Builder.AddPlaceholderChunk("macro");
7287 Builder.AddChunk(CodeCompletionString::CK_RightParen);
7288 Results.AddResult(Builder.TakeString());
Douglas Gregorf29c5232010-08-24 22:20:20 +00007289 Results.ExitScope();
7290
7291 HandleCodeCompleteResults(this, CodeCompleter,
7292 CodeCompletionContext::CCC_PreprocessorExpression,
7293 Results.data(), Results.size());
7294}
7295
7296void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
7297 IdentifierInfo *Macro,
7298 MacroInfo *MacroInfo,
7299 unsigned Argument) {
7300 // FIXME: In the future, we could provide "overload" results, much like we
7301 // do for function calls.
7302
Argyrios Kyrtzidis5c5f03e2011-08-18 19:41:28 +00007303 // Now just ignore this. There will be another code-completion callback
7304 // for the expanded tokens.
Douglas Gregorf29c5232010-08-24 22:20:20 +00007305}
7306
Douglas Gregor55817af2010-08-25 17:04:25 +00007307void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00007308 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00007309 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00007310 0, 0);
7311}
7312
Douglas Gregordae68752011-02-01 22:57:45 +00007313void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007314 CodeCompletionTUInfo &CCTUInfo,
Chris Lattner5f9e2722011-07-23 10:55:15 +00007315 SmallVectorImpl<CodeCompletionResult> &Results) {
Argyrios Kyrtzidis28a83f52012-04-10 17:23:48 +00007316 ResultBuilder Builder(*this, Allocator, CCTUInfo,
7317 CodeCompletionContext::CCC_Recovery);
Douglas Gregor8071e422010-08-15 06:18:01 +00007318 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
7319 CodeCompletionDeclConsumer Consumer(Builder,
7320 Context.getTranslationUnitDecl());
7321 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
7322 Consumer);
7323 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00007324
7325 if (!CodeCompleter || CodeCompleter->includeMacros())
Douglas Gregor3644d972012-10-09 16:01:50 +00007326 AddMacroResults(PP, Builder, true);
Douglas Gregor87c08a52010-08-13 22:48:40 +00007327
7328 Results.clear();
7329 Results.insert(Results.end(),
7330 Builder.data(), Builder.data() + Builder.size());
7331}