blob: d61ddcdf758a31e259a89c57ee915bd4e82182e0 [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"
Douglas Gregore737f502010-08-12 20:07:10 +000014#include "clang/Sema/Lookup.h"
John McCall120d63c2010-08-24 20:38:10 +000015#include "clang/Sema/Overload.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000016#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000017#include "clang/Sema/ExternalSemaSource.h"
John McCall5f1e0942010-08-24 08:50:51 +000018#include "clang/Sema/Scope.h"
John McCall781472f2010-08-25 08:40:02 +000019#include "clang/Sema/ScopeInfo.h"
John McCall7cd088e2010-08-24 07:21:54 +000020#include "clang/AST/DeclObjC.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000021#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000022#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000023#include "clang/Lex/MacroInfo.h"
24#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000025#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000026#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000027#include "llvm/ADT/StringSwitch.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000028#include <list>
29#include <map>
30#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000031
32using namespace clang;
John McCall781472f2010-08-25 08:40:02 +000033using namespace sema;
Douglas Gregor81b747b2009-09-17 21:32:03 +000034
Douglas Gregor86d9a522009-09-21 16:56:56 +000035namespace {
36 /// \brief A container of code-completion results.
37 class ResultBuilder {
38 public:
39 /// \brief The type of a name-lookup filter, which can be provided to the
40 /// name-lookup routines to specify which declarations should be included in
41 /// the result set (when it returns true) and which declarations should be
42 /// filtered out (returns false).
43 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
44
John McCall0a2c5e22010-08-25 06:19:51 +000045 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +000046
47 private:
48 /// \brief The actual results we have found.
49 std::vector<Result> Results;
50
51 /// \brief A record of all of the declarations we have found and placed
52 /// into the result set, used to ensure that no declaration ever gets into
53 /// the result set twice.
54 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
55
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000056 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
57
58 /// \brief An entry in the shadow map, which is optimized to store
59 /// a single (declaration, index) mapping (the common case) but
60 /// can also store a list of (declaration, index) mappings.
61 class ShadowMapEntry {
62 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
63
64 /// \brief Contains either the solitary NamedDecl * or a vector
65 /// of (declaration, index) pairs.
66 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
67
68 /// \brief When the entry contains a single declaration, this is
69 /// the index associated with that entry.
70 unsigned SingleDeclIndex;
71
72 public:
73 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
74
75 void Add(NamedDecl *ND, unsigned Index) {
76 if (DeclOrVector.isNull()) {
77 // 0 - > 1 elements: just set the single element information.
78 DeclOrVector = ND;
79 SingleDeclIndex = Index;
80 return;
81 }
82
83 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
84 // 1 -> 2 elements: create the vector of results and push in the
85 // existing declaration.
86 DeclIndexPairVector *Vec = new DeclIndexPairVector;
87 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
88 DeclOrVector = Vec;
89 }
90
91 // Add the new element to the end of the vector.
92 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
93 DeclIndexPair(ND, Index));
94 }
95
96 void Destroy() {
97 if (DeclIndexPairVector *Vec
98 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
99 delete Vec;
100 DeclOrVector = ((NamedDecl *)0);
101 }
102 }
103
104 // Iteration.
105 class iterator;
106 iterator begin() const;
107 iterator end() const;
108 };
109
Douglas Gregor86d9a522009-09-21 16:56:56 +0000110 /// \brief A mapping from declaration names to the declarations that have
111 /// this name within a particular scope and their index within the list of
112 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000113 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000114
115 /// \brief The semantic analysis object for which results are being
116 /// produced.
117 Sema &SemaRef;
118
119 /// \brief If non-NULL, a filter function used to remove any code-completion
120 /// results that are not desirable.
121 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000122
123 /// \brief Whether we should allow declarations as
124 /// nested-name-specifiers that would otherwise be filtered out.
125 bool AllowNestedNameSpecifiers;
126
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000127 /// \brief If set, the type that we would prefer our resulting value
128 /// declarations to have.
129 ///
130 /// Closely matching the preferred type gives a boost to a result's
131 /// priority.
132 CanQualType PreferredType;
133
Douglas Gregor86d9a522009-09-21 16:56:56 +0000134 /// \brief A list of shadow maps, which is used to model name hiding at
135 /// different levels of, e.g., the inheritance hierarchy.
136 std::list<ShadowMap> ShadowMaps;
137
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000138 void AdjustResultPriorityForPreferredType(Result &R);
139
Douglas Gregor86d9a522009-09-21 16:56:56 +0000140 public:
141 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor45bcd432010-01-14 03:21:49 +0000142 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000143
Douglas Gregord8e8a582010-05-25 21:41:55 +0000144 /// \brief Whether we should include code patterns in the completion
145 /// results.
146 bool includeCodePatterns() const {
147 return SemaRef.CodeCompleter &&
148 SemaRef.CodeCompleter->includeCodePatterns();
149 }
150
Douglas Gregor86d9a522009-09-21 16:56:56 +0000151 /// \brief Set the filter used for code-completion results.
152 void setFilter(LookupFilter Filter) {
153 this->Filter = Filter;
154 }
155
156 typedef std::vector<Result>::iterator iterator;
157 iterator begin() { return Results.begin(); }
158 iterator end() { return Results.end(); }
159
160 Result *data() { return Results.empty()? 0 : &Results.front(); }
161 unsigned size() const { return Results.size(); }
162 bool empty() const { return Results.empty(); }
163
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000164 /// \brief Specify the preferred type.
165 void setPreferredType(QualType T) {
166 PreferredType = SemaRef.Context.getCanonicalType(T);
167 }
168
Douglas Gregor45bcd432010-01-14 03:21:49 +0000169 /// \brief Specify whether nested-name-specifiers are allowed.
170 void allowNestedNameSpecifiers(bool Allow = true) {
171 AllowNestedNameSpecifiers = Allow;
172 }
173
Douglas Gregore495b7f2010-01-14 00:20:49 +0000174 /// \brief Determine whether the given declaration is at all interesting
175 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000176 ///
177 /// \param ND the declaration that we are inspecting.
178 ///
179 /// \param AsNestedNameSpecifier will be set true if this declaration is
180 /// only interesting when it is a nested-name-specifier.
181 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000182
183 /// \brief Check whether the result is hidden by the Hiding declaration.
184 ///
185 /// \returns true if the result is hidden and cannot be found, false if
186 /// the hidden result could still be found. When false, \p R may be
187 /// modified to describe how the result can be found (e.g., via extra
188 /// qualification).
189 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
190 NamedDecl *Hiding);
191
Douglas Gregor86d9a522009-09-21 16:56:56 +0000192 /// \brief Add a new result to this result set (if it isn't already in one
193 /// of the shadow maps), or replace an existing result (for, e.g., a
194 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000195 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000196 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000197 ///
198 /// \param R the context in which this result will be named.
199 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000200
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000201 /// \brief Add a new result to this result set, where we already know
202 /// the hiding declation (if any).
203 ///
204 /// \param R the result to add (if it is unique).
205 ///
206 /// \param CurContext the context in which this result will be named.
207 ///
208 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000209 ///
210 /// \param InBaseClass whether the result was found in a base
211 /// class of the searched context.
212 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
213 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000214
Douglas Gregora4477812010-01-14 16:01:26 +0000215 /// \brief Add a new non-declaration result to this result set.
216 void AddResult(Result R);
217
Douglas Gregor86d9a522009-09-21 16:56:56 +0000218 /// \brief Enter into a new scope.
219 void EnterNewScope();
220
221 /// \brief Exit from the current scope.
222 void ExitScope();
223
Douglas Gregor55385fe2009-11-18 04:19:12 +0000224 /// \brief Ignore this declaration, if it is seen again.
225 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
226
Douglas Gregor86d9a522009-09-21 16:56:56 +0000227 /// \name Name lookup predicates
228 ///
229 /// These predicates can be passed to the name lookup functions to filter the
230 /// results of name lookup. All of the predicates have the same type, so that
231 ///
232 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000233 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000234 bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
Douglas Gregorf9578432010-07-28 21:50:18 +0000235 bool IsIntegralConstantValue(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000236 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000237 bool IsNestedNameSpecifier(NamedDecl *ND) const;
238 bool IsEnum(NamedDecl *ND) const;
239 bool IsClassOrStruct(NamedDecl *ND) const;
240 bool IsUnion(NamedDecl *ND) const;
241 bool IsNamespace(NamedDecl *ND) const;
242 bool IsNamespaceOrAlias(NamedDecl *ND) const;
243 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000244 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000245 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000246 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregorfb629412010-08-23 21:17:50 +0000247 bool IsObjCCollection(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000248 //@}
249 };
250}
251
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000252class ResultBuilder::ShadowMapEntry::iterator {
253 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
254 unsigned SingleDeclIndex;
255
256public:
257 typedef DeclIndexPair value_type;
258 typedef value_type reference;
259 typedef std::ptrdiff_t difference_type;
260 typedef std::input_iterator_tag iterator_category;
261
262 class pointer {
263 DeclIndexPair Value;
264
265 public:
266 pointer(const DeclIndexPair &Value) : Value(Value) { }
267
268 const DeclIndexPair *operator->() const {
269 return &Value;
270 }
271 };
272
273 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
274
275 iterator(NamedDecl *SingleDecl, unsigned Index)
276 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
277
278 iterator(const DeclIndexPair *Iterator)
279 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
280
281 iterator &operator++() {
282 if (DeclOrIterator.is<NamedDecl *>()) {
283 DeclOrIterator = (NamedDecl *)0;
284 SingleDeclIndex = 0;
285 return *this;
286 }
287
288 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
289 ++I;
290 DeclOrIterator = I;
291 return *this;
292 }
293
294 iterator operator++(int) {
295 iterator tmp(*this);
296 ++(*this);
297 return tmp;
298 }
299
300 reference operator*() const {
301 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
302 return reference(ND, SingleDeclIndex);
303
Douglas Gregord490f952009-12-06 21:27:58 +0000304 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000305 }
306
307 pointer operator->() const {
308 return pointer(**this);
309 }
310
311 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000312 return X.DeclOrIterator.getOpaqueValue()
313 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000314 X.SingleDeclIndex == Y.SingleDeclIndex;
315 }
316
317 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000318 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000319 }
320};
321
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000322ResultBuilder::ShadowMapEntry::iterator
323ResultBuilder::ShadowMapEntry::begin() const {
324 if (DeclOrVector.isNull())
325 return iterator();
326
327 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
328 return iterator(ND, SingleDeclIndex);
329
330 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
331}
332
333ResultBuilder::ShadowMapEntry::iterator
334ResultBuilder::ShadowMapEntry::end() const {
335 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
336 return iterator();
337
338 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
339}
340
Douglas Gregor456c4a12009-09-21 20:12:40 +0000341/// \brief Compute the qualification required to get from the current context
342/// (\p CurContext) to the target context (\p TargetContext).
343///
344/// \param Context the AST context in which the qualification will be used.
345///
346/// \param CurContext the context where an entity is being named, which is
347/// typically based on the current scope.
348///
349/// \param TargetContext the context in which the named entity actually
350/// resides.
351///
352/// \returns a nested name specifier that refers into the target context, or
353/// NULL if no qualification is needed.
354static NestedNameSpecifier *
355getRequiredQualification(ASTContext &Context,
356 DeclContext *CurContext,
357 DeclContext *TargetContext) {
358 llvm::SmallVector<DeclContext *, 4> TargetParents;
359
360 for (DeclContext *CommonAncestor = TargetContext;
361 CommonAncestor && !CommonAncestor->Encloses(CurContext);
362 CommonAncestor = CommonAncestor->getLookupParent()) {
363 if (CommonAncestor->isTransparentContext() ||
364 CommonAncestor->isFunctionOrMethod())
365 continue;
366
367 TargetParents.push_back(CommonAncestor);
368 }
369
370 NestedNameSpecifier *Result = 0;
371 while (!TargetParents.empty()) {
372 DeclContext *Parent = TargetParents.back();
373 TargetParents.pop_back();
374
Douglas Gregorfb629412010-08-23 21:17:50 +0000375 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
376 if (!Namespace->getIdentifier())
377 continue;
378
Douglas Gregor456c4a12009-09-21 20:12:40 +0000379 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
Douglas Gregorfb629412010-08-23 21:17:50 +0000380 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000381 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
382 Result = NestedNameSpecifier::Create(Context, Result,
383 false,
384 Context.getTypeDeclType(TD).getTypePtr());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000385 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000386 return Result;
387}
388
Douglas Gregor45bcd432010-01-14 03:21:49 +0000389bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
390 bool &AsNestedNameSpecifier) const {
391 AsNestedNameSpecifier = false;
392
Douglas Gregore495b7f2010-01-14 00:20:49 +0000393 ND = ND->getUnderlyingDecl();
394 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000395
396 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000397 if (!ND->getDeclName())
398 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000399
400 // Friend declarations and declarations introduced due to friends are never
401 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000402 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000403 return false;
404
Douglas Gregor76282942009-12-11 17:31:05 +0000405 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000406 if (isa<ClassTemplateSpecializationDecl>(ND) ||
407 isa<ClassTemplatePartialSpecializationDecl>(ND))
408 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000409
Douglas Gregor76282942009-12-11 17:31:05 +0000410 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000411 if (isa<UsingDecl>(ND))
412 return false;
413
414 // Some declarations have reserved names that we don't want to ever show.
415 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000416 // __va_list_tag is a freak of nature. Find it and skip it.
417 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000418 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000419
Douglas Gregorf52cede2009-10-09 22:16:47 +0000420 // Filter out names reserved for the implementation (C99 7.1.3,
Douglas Gregor797efb52010-07-14 17:44:04 +0000421 // C++ [lib.global.names]) if they come from a system header.
Daniel Dunbare013d682009-10-18 20:26:12 +0000422 //
423 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000424 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000425 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000426 if (Name[0] == '_' &&
Douglas Gregor797efb52010-07-14 17:44:04 +0000427 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
428 (ND->getLocation().isInvalid() ||
429 SemaRef.SourceMgr.isInSystemHeader(
430 SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000431 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000432 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000433 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000434
Douglas Gregor86d9a522009-09-21 16:56:56 +0000435 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000436 if (isa<CXXConstructorDecl>(ND))
437 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000438
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000439 if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
440 ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
441 Filter != &ResultBuilder::IsNamespace &&
442 Filter != &ResultBuilder::IsNamespaceOrAlias))
443 AsNestedNameSpecifier = true;
444
Douglas Gregor86d9a522009-09-21 16:56:56 +0000445 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000446 if (Filter && !(this->*Filter)(ND)) {
447 // Check whether it is interesting as a nested-name-specifier.
448 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
449 IsNestedNameSpecifier(ND) &&
450 (Filter != &ResultBuilder::IsMember ||
451 (isa<CXXRecordDecl>(ND) &&
452 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
453 AsNestedNameSpecifier = true;
454 return true;
455 }
456
Douglas Gregore495b7f2010-01-14 00:20:49 +0000457 return false;
Douglas Gregora5fb7c32010-08-16 23:05:20 +0000458 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000459 // ... then it must be interesting!
460 return true;
461}
462
Douglas Gregor6660d842010-01-14 00:41:07 +0000463bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
464 NamedDecl *Hiding) {
465 // In C, there is no way to refer to a hidden name.
466 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
467 // name if we introduce the tag type.
468 if (!SemaRef.getLangOptions().CPlusPlus)
469 return true;
470
471 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
472
473 // There is no way to qualify a name declared in a function or method.
474 if (HiddenCtx->isFunctionOrMethod())
475 return true;
476
477 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
478 return true;
479
480 // We can refer to the result with the appropriate qualification. Do it.
481 R.Hidden = true;
482 R.QualifierIsInformative = false;
483
484 if (!R.Qualifier)
485 R.Qualifier = getRequiredQualification(SemaRef.Context,
486 CurContext,
487 R.Declaration->getDeclContext());
488 return false;
489}
490
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000491/// \brief A simplified classification of types used to determine whether two
492/// types are "similar enough" when adjusting priorities.
Douglas Gregor1827e102010-08-16 16:18:59 +0000493SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000494 switch (T->getTypeClass()) {
495 case Type::Builtin:
496 switch (cast<BuiltinType>(T)->getKind()) {
497 case BuiltinType::Void:
498 return STC_Void;
499
500 case BuiltinType::NullPtr:
501 return STC_Pointer;
502
503 case BuiltinType::Overload:
504 case BuiltinType::Dependent:
505 case BuiltinType::UndeducedAuto:
506 return STC_Other;
507
508 case BuiltinType::ObjCId:
509 case BuiltinType::ObjCClass:
510 case BuiltinType::ObjCSel:
511 return STC_ObjectiveC;
512
513 default:
514 return STC_Arithmetic;
515 }
516 return STC_Other;
517
518 case Type::Complex:
519 return STC_Arithmetic;
520
521 case Type::Pointer:
522 return STC_Pointer;
523
524 case Type::BlockPointer:
525 return STC_Block;
526
527 case Type::LValueReference:
528 case Type::RValueReference:
529 return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
530
531 case Type::ConstantArray:
532 case Type::IncompleteArray:
533 case Type::VariableArray:
534 case Type::DependentSizedArray:
535 return STC_Array;
536
537 case Type::DependentSizedExtVector:
538 case Type::Vector:
539 case Type::ExtVector:
540 return STC_Arithmetic;
541
542 case Type::FunctionProto:
543 case Type::FunctionNoProto:
544 return STC_Function;
545
546 case Type::Record:
547 return STC_Record;
548
549 case Type::Enum:
550 return STC_Arithmetic;
551
552 case Type::ObjCObject:
553 case Type::ObjCInterface:
554 case Type::ObjCObjectPointer:
555 return STC_ObjectiveC;
556
557 default:
558 return STC_Other;
559 }
560}
561
562/// \brief Get the type that a given expression will have if this declaration
563/// is used as an expression in its "typical" code-completion form.
Douglas Gregor1827e102010-08-16 16:18:59 +0000564QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000565 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
566
567 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
568 return C.getTypeDeclType(Type);
569 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
570 return C.getObjCInterfaceType(Iface);
571
572 QualType T;
573 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000574 T = Function->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000575 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000576 T = Method->getSendResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000577 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
Douglas Gregor5291c3c2010-07-13 08:18:22 +0000578 T = FunTmpl->getTemplatedDecl()->getCallResultType();
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000579 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
580 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
581 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
582 T = Property->getType();
583 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
584 T = Value->getType();
585 else
586 return QualType();
587
588 return T.getNonReferenceType();
589}
590
591void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
592 QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
593 if (T.isNull())
594 return;
595
596 CanQualType TC = SemaRef.Context.getCanonicalType(T);
597 // Check for exactly-matching types (modulo qualifiers).
Douglas Gregoreb0d0142010-08-24 23:58:17 +0000598 if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
599 if (PreferredType->isVoidType())
600 R.Priority += CCD_VoidMatch;
601 else
602 R.Priority /= CCF_ExactTypeMatch;
603 } // Check for nearly-matching types, based on classification of each.
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000604 else if ((getSimplifiedTypeClass(PreferredType)
605 == getSimplifiedTypeClass(TC)) &&
606 !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
607 R.Priority /= CCF_SimilarTypeMatch;
608}
609
Douglas Gregore495b7f2010-01-14 00:20:49 +0000610void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
611 assert(!ShadowMaps.empty() && "Must enter into a results scope");
612
613 if (R.Kind != Result::RK_Declaration) {
614 // For non-declaration results, just add the result.
615 Results.push_back(R);
616 return;
617 }
618
619 // Look through using declarations.
620 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
621 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
622 return;
623 }
624
625 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
626 unsigned IDNS = CanonDecl->getIdentifierNamespace();
627
Douglas Gregor45bcd432010-01-14 03:21:49 +0000628 bool AsNestedNameSpecifier = false;
629 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000630 return;
631
Douglas Gregor86d9a522009-09-21 16:56:56 +0000632 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000633 ShadowMapEntry::iterator I, IEnd;
634 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
635 if (NamePos != SMap.end()) {
636 I = NamePos->second.begin();
637 IEnd = NamePos->second.end();
638 }
639
640 for (; I != IEnd; ++I) {
641 NamedDecl *ND = I->first;
642 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000643 if (ND->getCanonicalDecl() == CanonDecl) {
644 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000645 Results[Index].Declaration = R.Declaration;
646
Douglas Gregor86d9a522009-09-21 16:56:56 +0000647 // We're done.
648 return;
649 }
650 }
651
652 // This is a new declaration in this scope. However, check whether this
653 // declaration name is hidden by a similarly-named declaration in an outer
654 // scope.
655 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
656 --SMEnd;
657 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000658 ShadowMapEntry::iterator I, IEnd;
659 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
660 if (NamePos != SM->end()) {
661 I = NamePos->second.begin();
662 IEnd = NamePos->second.end();
663 }
664 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000665 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000666 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000667 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
668 Decl::IDNS_ObjCProtocol)))
669 continue;
670
671 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000672 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000673 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000674 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000675 continue;
676
677 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000678 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000679 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000680
681 break;
682 }
683 }
684
685 // Make sure that any given declaration only shows up in the result set once.
686 if (!AllDeclsFound.insert(CanonDecl))
687 return;
688
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000689 // If the filter is for nested-name-specifiers, then this result starts a
690 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000691 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000692 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000693 R.Priority = CCP_NestedNameSpecifier;
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000694 } else if (!PreferredType.isNull())
695 AdjustResultPriorityForPreferredType(R);
696
Douglas Gregor0563c262009-09-22 23:15:58 +0000697 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000698 if (R.QualifierIsInformative && !R.Qualifier &&
699 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000700 DeclContext *Ctx = R.Declaration->getDeclContext();
701 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
702 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
703 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
704 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
705 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
706 else
707 R.QualifierIsInformative = false;
708 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000709
Douglas Gregor86d9a522009-09-21 16:56:56 +0000710 // Insert this result into the set of results and into the current shadow
711 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000712 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000713 Results.push_back(R);
714}
715
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000716void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000717 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000718 if (R.Kind != Result::RK_Declaration) {
719 // For non-declaration results, just add the result.
720 Results.push_back(R);
721 return;
722 }
723
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000724 // Look through using declarations.
725 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
726 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
727 return;
728 }
729
Douglas Gregor45bcd432010-01-14 03:21:49 +0000730 bool AsNestedNameSpecifier = false;
731 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000732 return;
733
734 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
735 return;
736
737 // Make sure that any given declaration only shows up in the result set once.
738 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
739 return;
740
741 // If the filter is for nested-name-specifiers, then this result starts a
742 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000743 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000744 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000745 R.Priority = CCP_NestedNameSpecifier;
746 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000747 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
748 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
749 ->getLookupContext()))
750 R.QualifierIsInformative = true;
751
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000752 // If this result is supposed to have an informative qualifier, add one.
753 if (R.QualifierIsInformative && !R.Qualifier &&
754 !R.StartsNestedNameSpecifier) {
755 DeclContext *Ctx = R.Declaration->getDeclContext();
756 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
757 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
758 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
759 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000760 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000761 else
762 R.QualifierIsInformative = false;
763 }
764
Douglas Gregor12e13132010-05-26 22:00:08 +0000765 // Adjust the priority if this result comes from a base class.
766 if (InBaseClass)
767 R.Priority += CCD_InBaseClass;
768
Douglas Gregor1f5537a2010-07-08 23:20:03 +0000769 if (!PreferredType.isNull())
770 AdjustResultPriorityForPreferredType(R);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +0000771
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000772 // Insert this result into the set of results.
773 Results.push_back(R);
774}
775
Douglas Gregora4477812010-01-14 16:01:26 +0000776void ResultBuilder::AddResult(Result R) {
777 assert(R.Kind != Result::RK_Declaration &&
778 "Declaration results need more context");
779 Results.push_back(R);
780}
781
Douglas Gregor86d9a522009-09-21 16:56:56 +0000782/// \brief Enter into a new scope.
783void ResultBuilder::EnterNewScope() {
784 ShadowMaps.push_back(ShadowMap());
785}
786
787/// \brief Exit from the current scope.
788void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000789 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
790 EEnd = ShadowMaps.back().end();
791 E != EEnd;
792 ++E)
793 E->second.Destroy();
794
Douglas Gregor86d9a522009-09-21 16:56:56 +0000795 ShadowMaps.pop_back();
796}
797
Douglas Gregor791215b2009-09-21 20:51:25 +0000798/// \brief Determines whether this given declaration will be found by
799/// ordinary name lookup.
800bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000801 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
802
Douglas Gregor791215b2009-09-21 20:51:25 +0000803 unsigned IDNS = Decl::IDNS_Ordinary;
804 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000805 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000806 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
807 return true;
808
Douglas Gregor791215b2009-09-21 20:51:25 +0000809 return ND->getIdentifierNamespace() & IDNS;
810}
811
Douglas Gregor01dfea02010-01-10 23:08:15 +0000812/// \brief Determines whether this given declaration will be found by
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000813/// ordinary name lookup but is not a type name.
814bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
815 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
816 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
817 return false;
818
819 unsigned IDNS = Decl::IDNS_Ordinary;
820 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor9b30b262010-06-15 20:26:51 +0000821 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000822 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
823 return true;
824
825 return ND->getIdentifierNamespace() & IDNS;
826}
827
Douglas Gregorf9578432010-07-28 21:50:18 +0000828bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
829 if (!IsOrdinaryNonTypeName(ND))
830 return 0;
831
832 if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
833 if (VD->getType()->isIntegralOrEnumerationType())
834 return true;
835
836 return false;
837}
838
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000839/// \brief Determines whether this given declaration will be found by
Douglas Gregor01dfea02010-01-10 23:08:15 +0000840/// ordinary name lookup.
841bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000842 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
843
Douglas Gregor01dfea02010-01-10 23:08:15 +0000844 unsigned IDNS = Decl::IDNS_Ordinary;
845 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000846 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000847
848 return (ND->getIdentifierNamespace() & IDNS) &&
Douglas Gregor4710e5b2010-05-28 00:49:12 +0000849 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
850 !isa<ObjCPropertyDecl>(ND);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000851}
852
Douglas Gregor86d9a522009-09-21 16:56:56 +0000853/// \brief Determines whether the given declaration is suitable as the
854/// start of a C++ nested-name-specifier, e.g., a class or namespace.
855bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
856 // Allow us to find class templates, too.
857 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
858 ND = ClassTemplate->getTemplatedDecl();
859
860 return SemaRef.isAcceptableNestedNameSpecifier(ND);
861}
862
863/// \brief Determines whether the given declaration is an enumeration.
864bool ResultBuilder::IsEnum(NamedDecl *ND) const {
865 return isa<EnumDecl>(ND);
866}
867
868/// \brief Determines whether the given declaration is a class or struct.
869bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
870 // Allow us to find class templates, too.
871 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
872 ND = ClassTemplate->getTemplatedDecl();
873
874 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000875 return RD->getTagKind() == TTK_Class ||
876 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000877
878 return false;
879}
880
881/// \brief Determines whether the given declaration is a union.
882bool ResultBuilder::IsUnion(NamedDecl *ND) const {
883 // Allow us to find class templates, too.
884 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
885 ND = ClassTemplate->getTemplatedDecl();
886
887 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000888 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000889
890 return false;
891}
892
893/// \brief Determines whether the given declaration is a namespace.
894bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
895 return isa<NamespaceDecl>(ND);
896}
897
898/// \brief Determines whether the given declaration is a namespace or
899/// namespace alias.
900bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
901 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
902}
903
Douglas Gregor76282942009-12-11 17:31:05 +0000904/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000905bool ResultBuilder::IsType(NamedDecl *ND) const {
Douglas Gregord32b0222010-08-24 01:06:58 +0000906 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
907 ND = Using->getTargetDecl();
908
909 return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000910}
911
Douglas Gregor76282942009-12-11 17:31:05 +0000912/// \brief Determines which members of a class should be visible via
913/// "." or "->". Only value declarations, nested name specifiers, and
914/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000915bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000916 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
917 ND = Using->getTargetDecl();
918
Douglas Gregorce821962009-12-11 18:14:22 +0000919 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
920 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000921}
922
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000923static bool isObjCReceiverType(ASTContext &C, QualType T) {
924 T = C.getCanonicalType(T);
925 switch (T->getTypeClass()) {
926 case Type::ObjCObject:
927 case Type::ObjCInterface:
928 case Type::ObjCObjectPointer:
929 return true;
930
931 case Type::Builtin:
932 switch (cast<BuiltinType>(T)->getKind()) {
933 case BuiltinType::ObjCId:
934 case BuiltinType::ObjCClass:
935 case BuiltinType::ObjCSel:
936 return true;
937
938 default:
939 break;
940 }
941 return false;
942
943 default:
944 break;
945 }
946
947 if (!C.getLangOptions().CPlusPlus)
948 return false;
949
950 // FIXME: We could perform more analysis here to determine whether a
951 // particular class type has any conversions to Objective-C types. For now,
952 // just accept all class types.
953 return T->isDependentType() || T->isRecordType();
954}
955
956bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
957 QualType T = getDeclUsageType(SemaRef.Context, ND);
958 if (T.isNull())
959 return false;
960
961 T = SemaRef.Context.getBaseElementType(T);
962 return isObjCReceiverType(SemaRef.Context, T);
963}
964
Douglas Gregorfb629412010-08-23 21:17:50 +0000965bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
966 if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
967 (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
968 return false;
969
970 QualType T = getDeclUsageType(SemaRef.Context, ND);
971 if (T.isNull())
972 return false;
973
974 T = SemaRef.Context.getBaseElementType(T);
975 return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
976 T->isObjCIdType() ||
977 (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
978}
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000979
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000980/// \rief Determines whether the given declaration is an Objective-C
981/// instance variable.
982bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
983 return isa<ObjCIvarDecl>(ND);
984}
985
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000986namespace {
987 /// \brief Visible declaration consumer that adds a code-completion result
988 /// for each visible declaration.
989 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
990 ResultBuilder &Results;
991 DeclContext *CurContext;
992
993 public:
994 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
995 : Results(Results), CurContext(CurContext) { }
996
Douglas Gregor0cc84042010-01-14 15:47:35 +0000997 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
998 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000999 }
1000 };
1001}
1002
Douglas Gregor86d9a522009-09-21 16:56:56 +00001003/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +00001004static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +00001005 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001006 typedef CodeCompletionResult Result;
Douglas Gregor12e13132010-05-26 22:00:08 +00001007 Results.AddResult(Result("short", CCP_Type));
1008 Results.AddResult(Result("long", CCP_Type));
1009 Results.AddResult(Result("signed", CCP_Type));
1010 Results.AddResult(Result("unsigned", CCP_Type));
1011 Results.AddResult(Result("void", CCP_Type));
1012 Results.AddResult(Result("char", CCP_Type));
1013 Results.AddResult(Result("int", CCP_Type));
1014 Results.AddResult(Result("float", CCP_Type));
1015 Results.AddResult(Result("double", CCP_Type));
1016 Results.AddResult(Result("enum", CCP_Type));
1017 Results.AddResult(Result("struct", CCP_Type));
1018 Results.AddResult(Result("union", CCP_Type));
1019 Results.AddResult(Result("const", CCP_Type));
1020 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001021
Douglas Gregor86d9a522009-09-21 16:56:56 +00001022 if (LangOpts.C99) {
1023 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001024 Results.AddResult(Result("_Complex", CCP_Type));
1025 Results.AddResult(Result("_Imaginary", CCP_Type));
1026 Results.AddResult(Result("_Bool", CCP_Type));
1027 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001028 }
1029
1030 if (LangOpts.CPlusPlus) {
1031 // C++-specific
Douglas Gregor12e13132010-05-26 22:00:08 +00001032 Results.AddResult(Result("bool", CCP_Type));
1033 Results.AddResult(Result("class", CCP_Type));
1034 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001035
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001036 // typename qualified-id
1037 CodeCompletionString *Pattern = new CodeCompletionString;
1038 Pattern->AddTypedTextChunk("typename");
1039 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1040 Pattern->AddPlaceholderChunk("qualifier");
1041 Pattern->AddTextChunk("::");
1042 Pattern->AddPlaceholderChunk("name");
1043 Results.AddResult(Result(Pattern));
Douglas Gregord8e8a582010-05-25 21:41:55 +00001044
Douglas Gregor86d9a522009-09-21 16:56:56 +00001045 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +00001046 Results.AddResult(Result("auto", CCP_Type));
1047 Results.AddResult(Result("char16_t", CCP_Type));
1048 Results.AddResult(Result("char32_t", CCP_Type));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001049
1050 CodeCompletionString *Pattern = new CodeCompletionString;
1051 Pattern->AddTypedTextChunk("decltype");
1052 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1053 Pattern->AddPlaceholderChunk("expression");
1054 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1055 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001056 }
1057 }
1058
1059 // GNU extensions
1060 if (LangOpts.GNUMode) {
1061 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +00001062 // Results.AddResult(Result("_Decimal32"));
1063 // Results.AddResult(Result("_Decimal64"));
1064 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001065
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001066 CodeCompletionString *Pattern = new CodeCompletionString;
1067 Pattern->AddTypedTextChunk("typeof");
1068 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1069 Pattern->AddPlaceholderChunk("expression");
1070 Results.AddResult(Result(Pattern));
1071
1072 Pattern = new CodeCompletionString;
1073 Pattern->AddTypedTextChunk("typeof");
1074 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1075 Pattern->AddPlaceholderChunk("type");
1076 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1077 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001078 }
1079}
1080
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001081static void AddStorageSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001082 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001083 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001084 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001085 // Note: we don't suggest either "auto" or "register", because both
1086 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1087 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +00001088 Results.AddResult(Result("extern"));
1089 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001090}
1091
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001092static void AddFunctionSpecifiers(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001093 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001094 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001095 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001096 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001097 case Action::PCC_Class:
1098 case Action::PCC_MemberTemplate:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001099 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +00001100 Results.AddResult(Result("explicit"));
1101 Results.AddResult(Result("friend"));
1102 Results.AddResult(Result("mutable"));
1103 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001104 }
1105 // Fall through
1106
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001107 case Action::PCC_ObjCInterface:
1108 case Action::PCC_ObjCImplementation:
1109 case Action::PCC_Namespace:
1110 case Action::PCC_Template:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001111 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +00001112 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001113 break;
1114
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001115 case Action::PCC_ObjCInstanceVariableList:
1116 case Action::PCC_Expression:
1117 case Action::PCC_Statement:
1118 case Action::PCC_ForInit:
1119 case Action::PCC_Condition:
1120 case Action::PCC_RecoveryInFunction:
Douglas Gregord32b0222010-08-24 01:06:58 +00001121 case Action::PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001122 break;
1123 }
1124}
1125
Douglas Gregorbca403c2010-01-13 23:51:12 +00001126static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1127static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1128static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001129 ResultBuilder &Results,
1130 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001131static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001132 ResultBuilder &Results,
1133 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001134static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001135 ResultBuilder &Results,
1136 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001137static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001138
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001139static void AddTypedefResult(ResultBuilder &Results) {
1140 CodeCompletionString *Pattern = new CodeCompletionString;
1141 Pattern->AddTypedTextChunk("typedef");
1142 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1143 Pattern->AddPlaceholderChunk("type");
1144 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1145 Pattern->AddPlaceholderChunk("name");
John McCall0a2c5e22010-08-25 06:19:51 +00001146 Results.AddResult(CodeCompletionResult(Pattern));
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001147}
1148
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001149static bool WantTypesInContext(Action::ParserCompletionContext CCC,
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001150 const LangOptions &LangOpts) {
1151 if (LangOpts.CPlusPlus)
1152 return true;
1153
1154 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001155 case Action::PCC_Namespace:
1156 case Action::PCC_Class:
1157 case Action::PCC_ObjCInstanceVariableList:
1158 case Action::PCC_Template:
1159 case Action::PCC_MemberTemplate:
1160 case Action::PCC_Statement:
1161 case Action::PCC_RecoveryInFunction:
Douglas Gregord32b0222010-08-24 01:06:58 +00001162 case Action::PCC_Type:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001163 return true;
1164
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001165 case Action::PCC_ObjCInterface:
1166 case Action::PCC_ObjCImplementation:
1167 case Action::PCC_Expression:
1168 case Action::PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001169 return false;
1170
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001171 case Action::PCC_ForInit:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001172 return LangOpts.ObjC1 || LangOpts.C99;
1173 }
1174
1175 return false;
1176}
1177
Douglas Gregor01dfea02010-01-10 23:08:15 +00001178/// \brief Add language constructs that show up for "ordinary" names.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001179static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001180 Scope *S,
1181 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +00001182 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00001183 typedef CodeCompletionResult Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001184 switch (CCC) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001185 case Action::PCC_Namespace:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001186 if (SemaRef.getLangOptions().CPlusPlus) {
1187 CodeCompletionString *Pattern = 0;
1188
1189 if (Results.includeCodePatterns()) {
1190 // namespace <identifier> { declarations }
1191 CodeCompletionString *Pattern = new CodeCompletionString;
1192 Pattern->AddTypedTextChunk("namespace");
1193 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1194 Pattern->AddPlaceholderChunk("identifier");
1195 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1196 Pattern->AddPlaceholderChunk("declarations");
1197 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1198 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1199 Results.AddResult(Result(Pattern));
1200 }
1201
Douglas Gregor01dfea02010-01-10 23:08:15 +00001202 // namespace identifier = identifier ;
1203 Pattern = new CodeCompletionString;
1204 Pattern->AddTypedTextChunk("namespace");
1205 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001206 Pattern->AddPlaceholderChunk("name");
Douglas Gregor01dfea02010-01-10 23:08:15 +00001207 Pattern->AddChunk(CodeCompletionString::CK_Equal);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001208 Pattern->AddPlaceholderChunk("namespace");
Douglas Gregora4477812010-01-14 16:01:26 +00001209 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001210
1211 // Using directives
1212 Pattern = new CodeCompletionString;
1213 Pattern->AddTypedTextChunk("using");
1214 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1215 Pattern->AddTextChunk("namespace");
1216 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1217 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001218 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001219
1220 // asm(string-literal)
1221 Pattern = new CodeCompletionString;
1222 Pattern->AddTypedTextChunk("asm");
1223 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1224 Pattern->AddPlaceholderChunk("string-literal");
1225 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001226 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001227
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001228 if (Results.includeCodePatterns()) {
1229 // Explicit template instantiation
1230 Pattern = new CodeCompletionString;
1231 Pattern->AddTypedTextChunk("template");
1232 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1233 Pattern->AddPlaceholderChunk("declaration");
1234 Results.AddResult(Result(Pattern));
1235 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001236 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001237
1238 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001239 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001240
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001241 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001242 // Fall through
1243
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001244 case Action::PCC_Class:
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001245 if (SemaRef.getLangOptions().CPlusPlus) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001246 // Using declaration
1247 CodeCompletionString *Pattern = new CodeCompletionString;
1248 Pattern->AddTypedTextChunk("using");
1249 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001250 Pattern->AddPlaceholderChunk("qualifier");
1251 Pattern->AddTextChunk("::");
1252 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001253 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001254
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001255 // using typename qualifier::name (only in a dependent context)
Douglas Gregor01dfea02010-01-10 23:08:15 +00001256 if (SemaRef.CurContext->isDependentContext()) {
1257 Pattern = new CodeCompletionString;
1258 Pattern->AddTypedTextChunk("using");
1259 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1260 Pattern->AddTextChunk("typename");
1261 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001262 Pattern->AddPlaceholderChunk("qualifier");
1263 Pattern->AddTextChunk("::");
1264 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00001265 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001266 }
1267
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001268 if (CCC == Action::PCC_Class) {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001269 AddTypedefResult(Results);
1270
Douglas Gregor01dfea02010-01-10 23:08:15 +00001271 // public:
1272 Pattern = new CodeCompletionString;
1273 Pattern->AddTypedTextChunk("public");
1274 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001275 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001276
1277 // protected:
1278 Pattern = new CodeCompletionString;
1279 Pattern->AddTypedTextChunk("protected");
1280 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001281 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001282
1283 // private:
1284 Pattern = new CodeCompletionString;
1285 Pattern->AddTypedTextChunk("private");
1286 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001287 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001288 }
1289 }
1290 // Fall through
1291
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001292 case Action::PCC_Template:
1293 case Action::PCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001294 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001295 // template < parameters >
1296 CodeCompletionString *Pattern = new CodeCompletionString;
1297 Pattern->AddTypedTextChunk("template");
1298 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1299 Pattern->AddPlaceholderChunk("parameters");
1300 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001301 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001302 }
1303
Douglas Gregorbca403c2010-01-13 23:51:12 +00001304 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1305 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001306 break;
1307
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001308 case Action::PCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001309 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1310 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1311 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001312 break;
1313
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001314 case Action::PCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001315 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1316 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1317 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001318 break;
1319
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001320 case Action::PCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001321 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001322 break;
1323
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001324 case Action::PCC_RecoveryInFunction:
1325 case Action::PCC_Statement: {
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001326 AddTypedefResult(Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001327
1328 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001329 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001330 Pattern = new CodeCompletionString;
1331 Pattern->AddTypedTextChunk("try");
1332 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1333 Pattern->AddPlaceholderChunk("statements");
1334 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1335 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1336 Pattern->AddTextChunk("catch");
1337 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1338 Pattern->AddPlaceholderChunk("declaration");
1339 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1340 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1341 Pattern->AddPlaceholderChunk("statements");
1342 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1343 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001344 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001345 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001346 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001347 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001348
Douglas Gregord8e8a582010-05-25 21:41:55 +00001349 if (Results.includeCodePatterns()) {
1350 // if (condition) { statements }
1351 Pattern = new CodeCompletionString;
1352 Pattern->AddTypedTextChunk("if");
1353 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1354 if (SemaRef.getLangOptions().CPlusPlus)
1355 Pattern->AddPlaceholderChunk("condition");
1356 else
1357 Pattern->AddPlaceholderChunk("expression");
1358 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1359 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1360 Pattern->AddPlaceholderChunk("statements");
1361 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1362 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1363 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001364
Douglas Gregord8e8a582010-05-25 21:41:55 +00001365 // switch (condition) { }
1366 Pattern = new CodeCompletionString;
1367 Pattern->AddTypedTextChunk("switch");
1368 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1369 if (SemaRef.getLangOptions().CPlusPlus)
1370 Pattern->AddPlaceholderChunk("condition");
1371 else
1372 Pattern->AddPlaceholderChunk("expression");
1373 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1374 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1375 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1376 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1377 Results.AddResult(Result(Pattern));
1378 }
1379
Douglas Gregor01dfea02010-01-10 23:08:15 +00001380 // Switch-specific statements.
John McCall781472f2010-08-25 08:40:02 +00001381 if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001382 // case expression:
1383 Pattern = new CodeCompletionString;
1384 Pattern->AddTypedTextChunk("case");
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001385 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001386 Pattern->AddPlaceholderChunk("expression");
1387 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001388 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001389
1390 // default:
1391 Pattern = new CodeCompletionString;
1392 Pattern->AddTypedTextChunk("default");
1393 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001394 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001395 }
1396
Douglas Gregord8e8a582010-05-25 21:41:55 +00001397 if (Results.includeCodePatterns()) {
1398 /// while (condition) { statements }
1399 Pattern = new CodeCompletionString;
1400 Pattern->AddTypedTextChunk("while");
1401 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1402 if (SemaRef.getLangOptions().CPlusPlus)
1403 Pattern->AddPlaceholderChunk("condition");
1404 else
1405 Pattern->AddPlaceholderChunk("expression");
1406 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1407 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1408 Pattern->AddPlaceholderChunk("statements");
1409 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1410 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1411 Results.AddResult(Result(Pattern));
1412
1413 // do { statements } while ( expression );
1414 Pattern = new CodeCompletionString;
1415 Pattern->AddTypedTextChunk("do");
1416 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1417 Pattern->AddPlaceholderChunk("statements");
1418 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1419 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1420 Pattern->AddTextChunk("while");
1421 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001422 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001423 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1424 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001425
Douglas Gregord8e8a582010-05-25 21:41:55 +00001426 // for ( for-init-statement ; condition ; expression ) { statements }
1427 Pattern = new CodeCompletionString;
1428 Pattern->AddTypedTextChunk("for");
1429 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1430 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1431 Pattern->AddPlaceholderChunk("init-statement");
1432 else
1433 Pattern->AddPlaceholderChunk("init-expression");
1434 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1435 Pattern->AddPlaceholderChunk("condition");
1436 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1437 Pattern->AddPlaceholderChunk("inc-expression");
1438 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1439 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1440 Pattern->AddPlaceholderChunk("statements");
1441 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1442 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1443 Results.AddResult(Result(Pattern));
1444 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001445
1446 if (S->getContinueParent()) {
1447 // continue ;
1448 Pattern = new CodeCompletionString;
1449 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001450 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001451 }
1452
1453 if (S->getBreakParent()) {
1454 // break ;
1455 Pattern = new CodeCompletionString;
1456 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001457 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001458 }
1459
1460 // "return expression ;" or "return ;", depending on whether we
1461 // know the function is void or not.
1462 bool isVoid = false;
1463 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1464 isVoid = Function->getResultType()->isVoidType();
1465 else if (ObjCMethodDecl *Method
1466 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1467 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001468 else if (SemaRef.getCurBlock() &&
1469 !SemaRef.getCurBlock()->ReturnType.isNull())
1470 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001471 Pattern = new CodeCompletionString;
1472 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001473 if (!isVoid) {
1474 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001475 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001476 }
Douglas Gregora4477812010-01-14 16:01:26 +00001477 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001478
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001479 // goto identifier ;
1480 Pattern = new CodeCompletionString;
1481 Pattern->AddTypedTextChunk("goto");
1482 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1483 Pattern->AddPlaceholderChunk("label");
1484 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001485
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001486 // Using directives
1487 Pattern = new CodeCompletionString;
1488 Pattern->AddTypedTextChunk("using");
1489 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1490 Pattern->AddTextChunk("namespace");
1491 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1492 Pattern->AddPlaceholderChunk("identifier");
1493 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001494 }
1495
1496 // Fall through (for statement expressions).
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001497 case Action::PCC_ForInit:
1498 case Action::PCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001499 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001500 // Fall through: conditions and statements can have expressions.
1501
Douglas Gregore6b1bb62010-08-11 21:23:17 +00001502 case Action::PCC_Expression: {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001503 CodeCompletionString *Pattern = 0;
1504 if (SemaRef.getLangOptions().CPlusPlus) {
1505 // 'this', if we're in a non-static member function.
1506 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1507 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001508 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001509
1510 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001511 Results.AddResult(Result("true"));
1512 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001513
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001514 // dynamic_cast < type-id > ( expression )
1515 Pattern = new CodeCompletionString;
1516 Pattern->AddTypedTextChunk("dynamic_cast");
1517 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1518 Pattern->AddPlaceholderChunk("type");
1519 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1520 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1521 Pattern->AddPlaceholderChunk("expression");
1522 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1523 Results.AddResult(Result(Pattern));
1524
1525 // static_cast < type-id > ( expression )
1526 Pattern = new CodeCompletionString;
1527 Pattern->AddTypedTextChunk("static_cast");
1528 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1529 Pattern->AddPlaceholderChunk("type");
1530 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1531 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1532 Pattern->AddPlaceholderChunk("expression");
1533 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1534 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001535
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001536 // reinterpret_cast < type-id > ( expression )
1537 Pattern = new CodeCompletionString;
1538 Pattern->AddTypedTextChunk("reinterpret_cast");
1539 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1540 Pattern->AddPlaceholderChunk("type");
1541 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1542 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1543 Pattern->AddPlaceholderChunk("expression");
1544 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1545 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001546
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001547 // const_cast < type-id > ( expression )
1548 Pattern = new CodeCompletionString;
1549 Pattern->AddTypedTextChunk("const_cast");
1550 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1551 Pattern->AddPlaceholderChunk("type");
1552 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1553 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1554 Pattern->AddPlaceholderChunk("expression");
1555 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1556 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001557
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001558 // typeid ( expression-or-type )
1559 Pattern = new CodeCompletionString;
1560 Pattern->AddTypedTextChunk("typeid");
1561 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1562 Pattern->AddPlaceholderChunk("expression-or-type");
1563 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1564 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001565
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001566 // new T ( ... )
1567 Pattern = new CodeCompletionString;
1568 Pattern->AddTypedTextChunk("new");
1569 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1570 Pattern->AddPlaceholderChunk("type");
1571 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1572 Pattern->AddPlaceholderChunk("expressions");
1573 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1574 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001575
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001576 // new T [ ] ( ... )
1577 Pattern = new CodeCompletionString;
1578 Pattern->AddTypedTextChunk("new");
1579 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1580 Pattern->AddPlaceholderChunk("type");
1581 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1582 Pattern->AddPlaceholderChunk("size");
1583 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1584 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1585 Pattern->AddPlaceholderChunk("expressions");
1586 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1587 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001588
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001589 // delete expression
1590 Pattern = new CodeCompletionString;
1591 Pattern->AddTypedTextChunk("delete");
1592 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1593 Pattern->AddPlaceholderChunk("expression");
1594 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001595
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001596 // delete [] expression
1597 Pattern = new CodeCompletionString;
1598 Pattern->AddTypedTextChunk("delete");
1599 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1600 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1601 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1602 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1603 Pattern->AddPlaceholderChunk("expression");
1604 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001605
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001606 // throw expression
1607 Pattern = new CodeCompletionString;
1608 Pattern->AddTypedTextChunk("throw");
1609 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1610 Pattern->AddPlaceholderChunk("expression");
1611 Results.AddResult(Result(Pattern));
Douglas Gregor12e13132010-05-26 22:00:08 +00001612
1613 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001614 }
1615
1616 if (SemaRef.getLangOptions().ObjC1) {
1617 // Add "super", if we're in an Objective-C class with a superclass.
Ted Kremenek681e2562010-05-31 21:43:10 +00001618 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1619 // The interface can be NULL.
1620 if (ObjCInterfaceDecl *ID = Method->getClassInterface())
1621 if (ID->getSuperClass())
1622 Results.AddResult(Result("super"));
1623 }
1624
Douglas Gregorbca403c2010-01-13 23:51:12 +00001625 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001626 }
1627
Douglas Gregorc8bddde2010-05-28 00:22:41 +00001628 // sizeof expression
1629 Pattern = new CodeCompletionString;
1630 Pattern->AddTypedTextChunk("sizeof");
1631 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1632 Pattern->AddPlaceholderChunk("expression-or-type");
1633 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1634 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001635 break;
1636 }
Douglas Gregord32b0222010-08-24 01:06:58 +00001637
1638 case Action::PCC_Type:
1639 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001640 }
1641
Douglas Gregor4710e5b2010-05-28 00:49:12 +00001642 if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
1643 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001644
Douglas Gregord32b0222010-08-24 01:06:58 +00001645 if (SemaRef.getLangOptions().CPlusPlus && CCC != Action::PCC_Type)
Douglas Gregora4477812010-01-14 16:01:26 +00001646 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001647}
1648
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001649/// \brief If the given declaration has an associated type, add it as a result
1650/// type chunk.
1651static void AddResultTypeChunk(ASTContext &Context,
1652 NamedDecl *ND,
1653 CodeCompletionString *Result) {
1654 if (!ND)
1655 return;
1656
1657 // Determine the type of the declaration (if it has a type).
1658 QualType T;
1659 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1660 T = Function->getResultType();
1661 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1662 T = Method->getResultType();
1663 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1664 T = FunTmpl->getTemplatedDecl()->getResultType();
1665 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1666 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1667 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1668 /* Do nothing: ignore unresolved using declarations*/
1669 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1670 T = Value->getType();
1671 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1672 T = Property->getType();
1673
1674 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1675 return;
1676
Douglas Gregor84139d62010-04-05 21:25:31 +00001677 PrintingPolicy Policy(Context.PrintingPolicy);
1678 Policy.AnonymousTagLocations = false;
1679
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001680 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001681 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001682 Result->AddResultTypeChunk(TypeStr);
1683}
1684
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001685static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
1686 CodeCompletionString *Result) {
1687 if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
1688 if (Sentinel->getSentinel() == 0) {
1689 if (Context.getLangOptions().ObjC1 &&
1690 Context.Idents.get("nil").hasMacroDefinition())
1691 Result->AddTextChunk(", nil");
1692 else if (Context.Idents.get("NULL").hasMacroDefinition())
1693 Result->AddTextChunk(", NULL");
1694 else
1695 Result->AddTextChunk(", (void*)0");
1696 }
1697}
1698
Douglas Gregor83482d12010-08-24 16:15:59 +00001699static std::string FormatFunctionParameter(ASTContext &Context,
1700 ParmVarDecl *Param) {
1701 bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
1702 if (Param->getType()->isDependentType() ||
1703 !Param->getType()->isBlockPointerType()) {
1704 // The argument for a dependent or non-block parameter is a placeholder
1705 // containing that parameter's type.
1706 std::string Result;
1707
1708 if (Param->getIdentifier() && !ObjCMethodParam)
1709 Result = Param->getIdentifier()->getName();
1710
1711 Param->getType().getAsStringInternal(Result,
1712 Context.PrintingPolicy);
1713
1714 if (ObjCMethodParam) {
1715 Result = "(" + Result;
1716 Result += ")";
1717 if (Param->getIdentifier())
1718 Result += Param->getIdentifier()->getName();
1719 }
1720 return Result;
1721 }
1722
1723 // The argument for a block pointer parameter is a block literal with
1724 // the appropriate type.
1725 FunctionProtoTypeLoc *Block = 0;
1726 TypeLoc TL;
1727 if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
1728 TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
1729 while (true) {
1730 // Look through typedefs.
1731 if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
1732 if (TypeSourceInfo *InnerTSInfo
1733 = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
1734 TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
1735 continue;
1736 }
1737 }
1738
1739 // Look through qualified types
1740 if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
1741 TL = QualifiedTL->getUnqualifiedLoc();
1742 continue;
1743 }
1744
1745 // Try to get the function prototype behind the block pointer type,
1746 // then we're done.
1747 if (BlockPointerTypeLoc *BlockPtr
1748 = dyn_cast<BlockPointerTypeLoc>(&TL)) {
1749 TL = BlockPtr->getPointeeLoc();
1750 Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
1751 }
1752 break;
1753 }
1754 }
1755
1756 if (!Block) {
1757 // We were unable to find a FunctionProtoTypeLoc with parameter names
1758 // for the block; just use the parameter type as a placeholder.
1759 std::string Result;
1760 Param->getType().getUnqualifiedType().
1761 getAsStringInternal(Result, Context.PrintingPolicy);
1762
1763 if (ObjCMethodParam) {
1764 Result = "(" + Result;
1765 Result += ")";
1766 if (Param->getIdentifier())
1767 Result += Param->getIdentifier()->getName();
1768 }
1769
1770 return Result;
1771 }
1772
1773 // We have the function prototype behind the block pointer type, as it was
1774 // written in the source.
1775 std::string Result = "(^)(";
1776 for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
1777 if (I)
1778 Result += ", ";
1779 Result += FormatFunctionParameter(Context, Block->getArg(I));
1780 }
1781 if (Block->getTypePtr()->isVariadic()) {
1782 if (Block->getNumArgs() > 0)
1783 Result += ", ...";
1784 else
1785 Result += "...";
1786 } else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus)
1787 Result += "void";
1788
1789 Result += ")";
1790 Block->getTypePtr()->getResultType().getAsStringInternal(Result,
1791 Context.PrintingPolicy);
1792 return Result;
1793}
1794
Douglas Gregor86d9a522009-09-21 16:56:56 +00001795/// \brief Add function parameter chunks to the given code completion string.
1796static void AddFunctionParameterChunks(ASTContext &Context,
1797 FunctionDecl *Function,
1798 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001799 typedef CodeCompletionString::Chunk Chunk;
1800
Douglas Gregor86d9a522009-09-21 16:56:56 +00001801 CodeCompletionString *CCStr = Result;
1802
1803 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1804 ParmVarDecl *Param = Function->getParamDecl(P);
1805
1806 if (Param->hasDefaultArg()) {
1807 // When we see an optional default argument, put that argument and
1808 // the remaining default arguments into a new, optional string.
1809 CodeCompletionString *Opt = new CodeCompletionString;
1810 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1811 CCStr = Opt;
1812 }
1813
1814 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001815 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001816
1817 // Format the placeholder string.
Douglas Gregor83482d12010-08-24 16:15:59 +00001818 std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
1819
Douglas Gregor86d9a522009-09-21 16:56:56 +00001820 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001821 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001822 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001823
1824 if (const FunctionProtoType *Proto
1825 = Function->getType()->getAs<FunctionProtoType>())
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001826 if (Proto->isVariadic()) {
Douglas Gregorb3d45252009-09-22 21:42:17 +00001827 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00001828
1829 MaybeAddSentinel(Context, Function, CCStr);
1830 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001831}
1832
1833/// \brief Add template parameter chunks to the given code completion string.
1834static void AddTemplateParameterChunks(ASTContext &Context,
1835 TemplateDecl *Template,
1836 CodeCompletionString *Result,
1837 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001838 typedef CodeCompletionString::Chunk Chunk;
1839
Douglas Gregor86d9a522009-09-21 16:56:56 +00001840 CodeCompletionString *CCStr = Result;
1841 bool FirstParameter = true;
1842
1843 TemplateParameterList *Params = Template->getTemplateParameters();
1844 TemplateParameterList::iterator PEnd = Params->end();
1845 if (MaxParameters)
1846 PEnd = Params->begin() + MaxParameters;
1847 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1848 bool HasDefaultArg = false;
1849 std::string PlaceholderStr;
1850 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1851 if (TTP->wasDeclaredWithTypename())
1852 PlaceholderStr = "typename";
1853 else
1854 PlaceholderStr = "class";
1855
1856 if (TTP->getIdentifier()) {
1857 PlaceholderStr += ' ';
1858 PlaceholderStr += TTP->getIdentifier()->getName();
1859 }
1860
1861 HasDefaultArg = TTP->hasDefaultArgument();
1862 } else if (NonTypeTemplateParmDecl *NTTP
1863 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1864 if (NTTP->getIdentifier())
1865 PlaceholderStr = NTTP->getIdentifier()->getName();
1866 NTTP->getType().getAsStringInternal(PlaceholderStr,
1867 Context.PrintingPolicy);
1868 HasDefaultArg = NTTP->hasDefaultArgument();
1869 } else {
1870 assert(isa<TemplateTemplateParmDecl>(*P));
1871 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1872
1873 // Since putting the template argument list into the placeholder would
1874 // be very, very long, we just use an abbreviation.
1875 PlaceholderStr = "template<...> class";
1876 if (TTP->getIdentifier()) {
1877 PlaceholderStr += ' ';
1878 PlaceholderStr += TTP->getIdentifier()->getName();
1879 }
1880
1881 HasDefaultArg = TTP->hasDefaultArgument();
1882 }
1883
1884 if (HasDefaultArg) {
1885 // When we see an optional default argument, put that argument and
1886 // the remaining default arguments into a new, optional string.
1887 CodeCompletionString *Opt = new CodeCompletionString;
1888 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1889 CCStr = Opt;
1890 }
1891
1892 if (FirstParameter)
1893 FirstParameter = false;
1894 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001895 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001896
1897 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001898 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001899 }
1900}
1901
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001902/// \brief Add a qualifier to the given code-completion string, if the
1903/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001904static void
1905AddQualifierToCompletionString(CodeCompletionString *Result,
1906 NestedNameSpecifier *Qualifier,
1907 bool QualifierIsInformative,
1908 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001909 if (!Qualifier)
1910 return;
1911
1912 std::string PrintedNNS;
1913 {
1914 llvm::raw_string_ostream OS(PrintedNNS);
1915 Qualifier->print(OS, Context.PrintingPolicy);
1916 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001917 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001918 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001919 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001920 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001921}
1922
Douglas Gregora61a8792009-12-11 18:44:16 +00001923static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1924 FunctionDecl *Function) {
1925 const FunctionProtoType *Proto
1926 = Function->getType()->getAs<FunctionProtoType>();
1927 if (!Proto || !Proto->getTypeQuals())
1928 return;
1929
1930 std::string QualsStr;
1931 if (Proto->getTypeQuals() & Qualifiers::Const)
1932 QualsStr += " const";
1933 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1934 QualsStr += " volatile";
1935 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1936 QualsStr += " restrict";
1937 Result->AddInformativeChunk(QualsStr);
1938}
1939
Douglas Gregor86d9a522009-09-21 16:56:56 +00001940/// \brief If possible, create a new code completion string for the given
1941/// result.
1942///
1943/// \returns Either a new, heap-allocated code completion string describing
1944/// how to use this result, or NULL to indicate that the string or name of the
1945/// result is all that is needed.
1946CodeCompletionString *
John McCall0a2c5e22010-08-25 06:19:51 +00001947CodeCompletionResult::CreateCodeCompletionString(Sema &S,
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001948 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001949 typedef CodeCompletionString::Chunk Chunk;
1950
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001951 if (Kind == RK_Pattern)
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001952 return Pattern->Clone(Result);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001953
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00001954 if (!Result)
1955 Result = new CodeCompletionString;
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001956
1957 if (Kind == RK_Keyword) {
1958 Result->AddTypedTextChunk(Keyword);
1959 return Result;
1960 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001961
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001962 if (Kind == RK_Macro) {
1963 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001964 assert(MI && "Not a macro?");
1965
1966 Result->AddTypedTextChunk(Macro->getName());
1967
1968 if (!MI->isFunctionLike())
1969 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001970
1971 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001972 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001973 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1974 A != AEnd; ++A) {
1975 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001976 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001977
1978 if (!MI->isVariadic() || A != AEnd - 1) {
1979 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001980 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001981 continue;
1982 }
1983
1984 // Variadic argument; cope with the different between GNU and C99
1985 // variadic macros, providing a single placeholder for the rest of the
1986 // arguments.
1987 if ((*A)->isStr("__VA_ARGS__"))
1988 Result->AddPlaceholderChunk("...");
1989 else {
1990 std::string Arg = (*A)->getName();
1991 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001992 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001993 }
1994 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001995 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001996 return Result;
1997 }
1998
Douglas Gregord8e8a582010-05-25 21:41:55 +00001999 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002000 NamedDecl *ND = Declaration;
2001
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002002 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00002003 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002004 Result->AddTextChunk("::");
2005 return Result;
2006 }
2007
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002008 AddResultTypeChunk(S.Context, ND, Result);
2009
Douglas Gregor86d9a522009-09-21 16:56:56 +00002010 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002011 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2012 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002013 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002014 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002015 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002016 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002017 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002018 return Result;
2019 }
2020
2021 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002022 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2023 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002024 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00002025 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00002026
2027 // Figure out which template parameters are deduced (or have default
2028 // arguments).
2029 llvm::SmallVector<bool, 16> Deduced;
2030 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
2031 unsigned LastDeducibleArgument;
2032 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2033 --LastDeducibleArgument) {
2034 if (!Deduced[LastDeducibleArgument - 1]) {
2035 // C++0x: Figure out if the template argument has a default. If so,
2036 // the user doesn't need to type this argument.
2037 // FIXME: We need to abstract template parameters better!
2038 bool HasDefaultArg = false;
2039 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2040 LastDeducibleArgument - 1);
2041 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2042 HasDefaultArg = TTP->hasDefaultArgument();
2043 else if (NonTypeTemplateParmDecl *NTTP
2044 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2045 HasDefaultArg = NTTP->hasDefaultArgument();
2046 else {
2047 assert(isa<TemplateTemplateParmDecl>(Param));
2048 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002049 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002050 }
2051
2052 if (!HasDefaultArg)
2053 break;
2054 }
2055 }
2056
2057 if (LastDeducibleArgument) {
2058 // Some of the function template arguments cannot be deduced from a
2059 // function call, so we introduce an explicit template argument list
2060 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002061 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002062 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
2063 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002064 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002065 }
2066
2067 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002068 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002069 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002070 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00002071 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002072 return Result;
2073 }
2074
2075 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00002076 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2077 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00002078 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002079 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002080 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002081 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002082 return Result;
2083 }
2084
Douglas Gregor9630eb62009-11-17 16:44:22 +00002085 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00002086 Selector Sel = Method->getSelector();
2087 if (Sel.isUnarySelector()) {
2088 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
2089 return Result;
2090 }
2091
Douglas Gregord3c68542009-11-19 01:08:35 +00002092 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
2093 SelName += ':';
2094 if (StartParameter == 0)
2095 Result->AddTypedTextChunk(SelName);
2096 else {
2097 Result->AddInformativeChunk(SelName);
2098
2099 // If there is only one parameter, and we're past it, add an empty
2100 // typed-text chunk since there is nothing to type.
2101 if (Method->param_size() == 1)
2102 Result->AddTypedTextChunk("");
2103 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00002104 unsigned Idx = 0;
2105 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
2106 PEnd = Method->param_end();
2107 P != PEnd; (void)++P, ++Idx) {
2108 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002109 std::string Keyword;
2110 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00002111 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002112 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2113 Keyword += II->getName().str();
2114 Keyword += ":";
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002115 if (Idx < StartParameter || AllParametersAreInformative)
Douglas Gregord3c68542009-11-19 01:08:35 +00002116 Result->AddInformativeChunk(Keyword);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002117 else if (Idx == StartParameter)
Douglas Gregord3c68542009-11-19 01:08:35 +00002118 Result->AddTypedTextChunk(Keyword);
2119 else
2120 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002121 }
Douglas Gregord3c68542009-11-19 01:08:35 +00002122
2123 // If we're before the starting parameter, skip the placeholder.
2124 if (Idx < StartParameter)
2125 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00002126
2127 std::string Arg;
Douglas Gregor83482d12010-08-24 16:15:59 +00002128
2129 if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
2130 Arg = FormatFunctionParameter(S.Context, *P);
2131 else {
2132 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
2133 Arg = "(" + Arg + ")";
2134 if (IdentifierInfo *II = (*P)->getIdentifier())
2135 Arg += II->getName().str();
2136 }
2137
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002138 if (DeclaringEntity)
2139 Result->AddTextChunk(Arg);
2140 else if (AllParametersAreInformative)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002141 Result->AddInformativeChunk(Arg);
2142 else
2143 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00002144 }
2145
Douglas Gregor2a17af02009-12-23 00:21:46 +00002146 if (Method->isVariadic()) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00002147 if (DeclaringEntity)
2148 Result->AddTextChunk(", ...");
2149 else if (AllParametersAreInformative)
Douglas Gregor2a17af02009-12-23 00:21:46 +00002150 Result->AddInformativeChunk(", ...");
2151 else
2152 Result->AddPlaceholderChunk(", ...");
Douglas Gregoraaa107a2010-08-23 23:51:41 +00002153
2154 MaybeAddSentinel(S.Context, Method, Result);
Douglas Gregor2a17af02009-12-23 00:21:46 +00002155 }
2156
Douglas Gregor9630eb62009-11-17 16:44:22 +00002157 return Result;
2158 }
2159
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002160 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00002161 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2162 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00002163
2164 Result->AddTypedTextChunk(ND->getNameAsString());
2165 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002166}
2167
Douglas Gregor86d802e2009-09-23 00:34:09 +00002168CodeCompletionString *
2169CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2170 unsigned CurrentArg,
2171 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002172 typedef CodeCompletionString::Chunk Chunk;
2173
Douglas Gregor86d802e2009-09-23 00:34:09 +00002174 CodeCompletionString *Result = new CodeCompletionString;
2175 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00002176 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002177 const FunctionProtoType *Proto
2178 = dyn_cast<FunctionProtoType>(getFunctionType());
2179 if (!FDecl && !Proto) {
2180 // Function without a prototype. Just give the return type and a
2181 // highlighted ellipsis.
2182 const FunctionType *FT = getFunctionType();
2183 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002184 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002185 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
2186 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
2187 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002188 return Result;
2189 }
2190
2191 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00002192 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00002193 else
2194 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00002195 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002196
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002197 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002198 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2199 for (unsigned I = 0; I != NumParams; ++I) {
2200 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002201 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002202
2203 std::string ArgString;
2204 QualType ArgType;
2205
2206 if (FDecl) {
2207 ArgString = FDecl->getParamDecl(I)->getNameAsString();
2208 ArgType = FDecl->getParamDecl(I)->getOriginalType();
2209 } else {
2210 ArgType = Proto->getArgType(I);
2211 }
2212
2213 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
2214
2215 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002216 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00002217 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002218 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00002219 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00002220 }
2221
2222 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002223 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002224 if (CurrentArg < NumParams)
2225 Result->AddTextChunk("...");
2226 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002227 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002228 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002229 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00002230
2231 return Result;
2232}
2233
Douglas Gregor1827e102010-08-16 16:18:59 +00002234unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2235 bool PreferredTypeIsPointer) {
2236 unsigned Priority = CCP_Macro;
2237
2238 // Treat the "nil" and "NULL" macros as null pointer constants.
2239 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2240 Priority = CCP_Constant;
2241 if (PreferredTypeIsPointer)
2242 Priority = Priority / CCF_SimilarTypeMatch;
2243 }
2244
2245 return Priority;
2246}
2247
Douglas Gregor590c7d52010-07-08 20:55:51 +00002248static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2249 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002250 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002251
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002252 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002253 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2254 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002255 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002256 Results.AddResult(Result(M->first,
2257 getMacroUsagePriority(M->first->getName(),
2258 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002259 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002260 Results.ExitScope();
2261}
2262
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002263static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2264 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002265 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002266
2267 Results.EnterNewScope();
2268 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2269 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2270 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2271 Results.AddResult(Result("__func__", CCP_Constant));
2272 Results.ExitScope();
2273}
2274
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002275static void HandleCodeCompleteResults(Sema *S,
2276 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002277 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002278 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002279 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002280 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002281 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002282
2283 for (unsigned I = 0; I != NumResults; ++I)
2284 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002285}
2286
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002287static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2288 Sema::ParserCompletionContext PCC) {
2289 switch (PCC) {
2290 case Action::PCC_Namespace:
2291 return CodeCompletionContext::CCC_TopLevel;
2292
2293 case Action::PCC_Class:
2294 return CodeCompletionContext::CCC_ClassStructUnion;
2295
2296 case Action::PCC_ObjCInterface:
2297 return CodeCompletionContext::CCC_ObjCInterface;
2298
2299 case Action::PCC_ObjCImplementation:
2300 return CodeCompletionContext::CCC_ObjCImplementation;
2301
2302 case Action::PCC_ObjCInstanceVariableList:
2303 return CodeCompletionContext::CCC_ObjCIvarList;
2304
2305 case Action::PCC_Template:
2306 case Action::PCC_MemberTemplate:
2307 case Action::PCC_RecoveryInFunction:
2308 return CodeCompletionContext::CCC_Other;
2309
2310 case Action::PCC_Expression:
2311 case Action::PCC_ForInit:
2312 case Action::PCC_Condition:
2313 return CodeCompletionContext::CCC_Expression;
2314
2315 case Action::PCC_Statement:
2316 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002317
2318 case Action::PCC_Type:
2319 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002320 }
2321
2322 return CodeCompletionContext::CCC_Other;
2323}
2324
Douglas Gregor01dfea02010-01-10 23:08:15 +00002325void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002326 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002327 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002328 ResultBuilder Results(*this);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002329
2330 // Determine how to filter results, e.g., so that the names of
2331 // values (functions, enumerators, function templates, etc.) are
2332 // only allowed where we can have an expression.
2333 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002334 case PCC_Namespace:
2335 case PCC_Class:
2336 case PCC_ObjCInterface:
2337 case PCC_ObjCImplementation:
2338 case PCC_ObjCInstanceVariableList:
2339 case PCC_Template:
2340 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002341 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002342 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2343 break;
2344
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002345 case PCC_Statement:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002346 // For statements that are expressions, we prefer to call 'void' functions
2347 // rather than functions that return a result, since then the result would
2348 // be ignored.
2349 Results.setPreferredType(Context.VoidTy);
2350 // Fall through
2351
2352 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002353 case PCC_ForInit:
2354 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002355 if (WantTypesInContext(CompletionContext, getLangOptions()))
2356 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2357 else
2358 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002359 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002360
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002361 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002362 // Unfiltered
2363 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002364 }
2365
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002366 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002367 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2368 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002369
2370 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002371 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002372 Results.ExitScope();
2373
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002374 switch (CompletionContext) {
Douglas Gregor72db1082010-08-24 01:11:00 +00002375 case PCC_Expression:
2376 case PCC_Statement:
2377 case PCC_RecoveryInFunction:
2378 if (S->getFnParent())
2379 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2380 break;
2381
2382 case PCC_Namespace:
2383 case PCC_Class:
2384 case PCC_ObjCInterface:
2385 case PCC_ObjCImplementation:
2386 case PCC_ObjCInstanceVariableList:
2387 case PCC_Template:
2388 case PCC_MemberTemplate:
2389 case PCC_ForInit:
2390 case PCC_Condition:
2391 case PCC_Type:
2392 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002393 }
2394
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002395 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002396 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002397
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002398 HandleCodeCompleteResults(this, CodeCompleter,
2399 mapCodeCompletionContext(*this, CompletionContext),
2400 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002401}
2402
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002403void Sema::CodeCompleteDeclarator(Scope *S,
2404 bool AllowNonIdentifiers,
2405 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002406 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002407 ResultBuilder Results(*this);
2408 Results.EnterNewScope();
2409
2410 // Type qualifiers can come after names.
2411 Results.AddResult(Result("const"));
2412 Results.AddResult(Result("volatile"));
2413 if (getLangOptions().C99)
2414 Results.AddResult(Result("restrict"));
2415
2416 if (getLangOptions().CPlusPlus) {
2417 if (AllowNonIdentifiers) {
2418 Results.AddResult(Result("operator"));
2419 }
2420
2421 // Add nested-name-specifiers.
2422 if (AllowNestedNameSpecifiers) {
2423 Results.allowNestedNameSpecifiers();
2424 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2425 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2426 CodeCompleter->includeGlobals());
2427 }
2428 }
2429 Results.ExitScope();
2430
Douglas Gregor4497dd42010-08-24 04:59:56 +00002431 // Note that we intentionally suppress macro results here, since we do not
2432 // encourage using macros to produce the names of entities.
2433
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002434 HandleCodeCompleteResults(this, CodeCompleter,
2435 AllowNestedNameSpecifiers
2436 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2437 : CodeCompletionContext::CCC_Name,
2438 Results.data(), Results.size());
2439}
2440
Douglas Gregorfb629412010-08-23 21:17:50 +00002441struct Sema::CodeCompleteExpressionData {
2442 CodeCompleteExpressionData(QualType PreferredType = QualType())
2443 : PreferredType(PreferredType), IntegralConstantExpression(false),
2444 ObjCCollection(false) { }
2445
2446 QualType PreferredType;
2447 bool IntegralConstantExpression;
2448 bool ObjCCollection;
2449 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2450};
2451
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002452/// \brief Perform code-completion in an expression context when we know what
2453/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002454///
2455/// \param IntegralConstantExpression Only permit integral constant
2456/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002457void Sema::CodeCompleteExpression(Scope *S,
2458 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002459 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002460 ResultBuilder Results(*this);
2461
Douglas Gregorfb629412010-08-23 21:17:50 +00002462 if (Data.ObjCCollection)
2463 Results.setFilter(&ResultBuilder::IsObjCCollection);
2464 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002465 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002466 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002467 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2468 else
2469 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002470
2471 if (!Data.PreferredType.isNull())
2472 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2473
2474 // Ignore any declarations that we were told that we don't care about.
2475 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2476 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002477
2478 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002479 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2480 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002481
2482 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002483 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002484 Results.ExitScope();
2485
Douglas Gregor590c7d52010-07-08 20:55:51 +00002486 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002487 if (!Data.PreferredType.isNull())
2488 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2489 || Data.PreferredType->isMemberPointerType()
2490 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002491
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002492 if (S->getFnParent() &&
2493 !Data.ObjCCollection &&
2494 !Data.IntegralConstantExpression)
2495 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2496
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002497 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002498 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002499 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002500 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2501 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002502 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002503}
2504
2505
Douglas Gregor95ac6552009-11-18 01:29:26 +00002506static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002507 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002508 DeclContext *CurContext,
2509 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002510 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002511
2512 // Add properties in this container.
2513 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2514 PEnd = Container->prop_end();
2515 P != PEnd;
2516 ++P)
2517 Results.MaybeAddResult(Result(*P, 0), CurContext);
2518
2519 // Add properties in referenced protocols.
2520 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2521 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2522 PEnd = Protocol->protocol_end();
2523 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002524 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002525 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002526 if (AllowCategories) {
2527 // Look through categories.
2528 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2529 Category; Category = Category->getNextClassCategory())
2530 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2531 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002532
2533 // Look through protocols.
2534 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2535 E = IFace->protocol_end();
2536 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002537 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002538
2539 // Look in the superclass.
2540 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002541 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2542 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002543 } else if (const ObjCCategoryDecl *Category
2544 = dyn_cast<ObjCCategoryDecl>(Container)) {
2545 // Look through protocols.
2546 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2547 PEnd = Category->protocol_end();
2548 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002549 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002550 }
2551}
2552
Douglas Gregor81b747b2009-09-17 21:32:03 +00002553void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2554 SourceLocation OpLoc,
2555 bool IsArrow) {
2556 if (!BaseE || !CodeCompleter)
2557 return;
2558
John McCall0a2c5e22010-08-25 06:19:51 +00002559 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002560
Douglas Gregor81b747b2009-09-17 21:32:03 +00002561 Expr *Base = static_cast<Expr *>(BaseE);
2562 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002563
2564 if (IsArrow) {
2565 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2566 BaseType = Ptr->getPointeeType();
2567 else if (BaseType->isObjCObjectPointerType())
2568 /*Do nothing*/ ;
2569 else
2570 return;
2571 }
2572
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002573 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002574 Results.EnterNewScope();
2575 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2576 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002577 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002578 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002579 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2580 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002581
Douglas Gregor95ac6552009-11-18 01:29:26 +00002582 if (getLangOptions().CPlusPlus) {
2583 if (!Results.empty()) {
2584 // The "template" keyword can follow "->" or "." in the grammar.
2585 // However, we only want to suggest the template keyword if something
2586 // is dependent.
2587 bool IsDependent = BaseType->isDependentType();
2588 if (!IsDependent) {
2589 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2590 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2591 IsDependent = Ctx->isDependentContext();
2592 break;
2593 }
2594 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002595
Douglas Gregor95ac6552009-11-18 01:29:26 +00002596 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002597 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002598 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002599 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002600 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2601 // Objective-C property reference.
2602
2603 // Add property results based on our interface.
2604 const ObjCObjectPointerType *ObjCPtr
2605 = BaseType->getAsObjCInterfacePointerType();
2606 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002607 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002608
2609 // Add properties from the protocols in a qualified interface.
2610 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2611 E = ObjCPtr->qual_end();
2612 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002613 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002614 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002615 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002616 // Objective-C instance variable access.
2617 ObjCInterfaceDecl *Class = 0;
2618 if (const ObjCObjectPointerType *ObjCPtr
2619 = BaseType->getAs<ObjCObjectPointerType>())
2620 Class = ObjCPtr->getInterfaceDecl();
2621 else
John McCallc12c5bb2010-05-15 11:32:37 +00002622 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002623
2624 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002625 if (Class) {
2626 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2627 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002628 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2629 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002630 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002631 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002632
2633 // FIXME: How do we cope with isa?
2634
2635 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002636
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002637 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002638 HandleCodeCompleteResults(this, CodeCompleter,
2639 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2640 BaseType),
2641 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002642}
2643
Douglas Gregor374929f2009-09-18 15:37:17 +00002644void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2645 if (!CodeCompleter)
2646 return;
2647
John McCall0a2c5e22010-08-25 06:19:51 +00002648 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002649 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002650 enum CodeCompletionContext::Kind ContextKind
2651 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002652 switch ((DeclSpec::TST)TagSpec) {
2653 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002654 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002655 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002656 break;
2657
2658 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002659 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002660 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002661 break;
2662
2663 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002664 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002665 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002666 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002667 break;
2668
2669 default:
2670 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2671 return;
2672 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002673
John McCall0d6b1642010-04-23 18:46:30 +00002674 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002675 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002676
2677 // First pass: look for tags.
2678 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002679 LookupVisibleDecls(S, LookupTagName, Consumer,
2680 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002681
Douglas Gregor8071e422010-08-15 06:18:01 +00002682 if (CodeCompleter->includeGlobals()) {
2683 // Second pass: look for nested name specifiers.
2684 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2685 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2686 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002687
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002688 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2689 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002690}
2691
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002692void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002693 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002694 return;
2695
John McCall781472f2010-08-25 08:40:02 +00002696 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002697 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002698 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2699 Data.IntegralConstantExpression = true;
2700 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002701 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002702 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002703
2704 // Code-complete the cases of a switch statement over an enumeration type
2705 // by providing the list of
2706 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2707
2708 // Determine which enumerators we have already seen in the switch statement.
2709 // FIXME: Ideally, we would also be able to look *past* the code-completion
2710 // token, in case we are code-completing in the middle of the switch and not
2711 // at the end. However, we aren't able to do so at the moment.
2712 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002713 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002714 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2715 SC = SC->getNextSwitchCase()) {
2716 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2717 if (!Case)
2718 continue;
2719
2720 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2721 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2722 if (EnumConstantDecl *Enumerator
2723 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2724 // We look into the AST of the case statement to determine which
2725 // enumerator was named. Alternatively, we could compute the value of
2726 // the integral constant expression, then compare it against the
2727 // values of each enumerator. However, value-based approach would not
2728 // work as well with C++ templates where enumerators declared within a
2729 // template are type- and value-dependent.
2730 EnumeratorsSeen.insert(Enumerator);
2731
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002732 // If this is a qualified-id, keep track of the nested-name-specifier
2733 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002734 //
2735 // switch (TagD.getKind()) {
2736 // case TagDecl::TK_enum:
2737 // break;
2738 // case XXX
2739 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002740 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002741 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2742 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002743 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002744 }
2745 }
2746
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002747 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2748 // If there are no prior enumerators in C++, check whether we have to
2749 // qualify the names of the enumerators that we suggest, because they
2750 // may not be visible in this scope.
2751 Qualifier = getRequiredQualification(Context, CurContext,
2752 Enum->getDeclContext());
2753
2754 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2755 }
2756
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002757 // Add any enumerators that have not yet been mentioned.
2758 ResultBuilder Results(*this);
2759 Results.EnterNewScope();
2760 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2761 EEnd = Enum->enumerator_end();
2762 E != EEnd; ++E) {
2763 if (EnumeratorsSeen.count(*E))
2764 continue;
2765
John McCall0a2c5e22010-08-25 06:19:51 +00002766 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00002767 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002768 }
2769 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002770
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002771 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002772 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002773 HandleCodeCompleteResults(this, CodeCompleter,
2774 CodeCompletionContext::CCC_Expression,
2775 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002776}
2777
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002778namespace {
2779 struct IsBetterOverloadCandidate {
2780 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002781 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002782
2783 public:
John McCall5769d612010-02-08 23:07:23 +00002784 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2785 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002786
2787 bool
2788 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00002789 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002790 }
2791 };
2792}
2793
Douglas Gregord28dcd72010-05-30 06:10:08 +00002794static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2795 if (NumArgs && !Args)
2796 return true;
2797
2798 for (unsigned I = 0; I != NumArgs; ++I)
2799 if (!Args[I])
2800 return true;
2801
2802 return false;
2803}
2804
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002805void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2806 ExprTy **ArgsIn, unsigned NumArgs) {
2807 if (!CodeCompleter)
2808 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002809
2810 // When we're code-completing for a call, we fall back to ordinary
2811 // name code-completion whenever we can't produce specific
2812 // results. We may want to revisit this strategy in the future,
2813 // e.g., by merging the two kinds of results.
2814
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002815 Expr *Fn = (Expr *)FnIn;
2816 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002817
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002818 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00002819 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002820 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002821 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002822 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002823 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002824
John McCall3b4294e2009-12-16 12:17:52 +00002825 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002826 SourceLocation Loc = Fn->getExprLoc();
2827 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002828
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002829 // FIXME: What if we're calling something that isn't a function declaration?
2830 // FIXME: What if we're calling a pseudo-destructor?
2831 // FIXME: What if we're calling a member function?
2832
Douglas Gregorc0265402010-01-21 15:46:19 +00002833 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2834 llvm::SmallVector<ResultCandidate, 8> Results;
2835
John McCall3b4294e2009-12-16 12:17:52 +00002836 Expr *NakedFn = Fn->IgnoreParenCasts();
2837 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2838 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2839 /*PartialOverloading=*/ true);
2840 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2841 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002842 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00002843 if (!getLangOptions().CPlusPlus ||
2844 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00002845 Results.push_back(ResultCandidate(FDecl));
2846 else
John McCall86820f52010-01-26 01:37:31 +00002847 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002848 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2849 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002850 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002851 }
John McCall3b4294e2009-12-16 12:17:52 +00002852 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002853
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002854 QualType ParamType;
2855
Douglas Gregorc0265402010-01-21 15:46:19 +00002856 if (!CandidateSet.empty()) {
2857 // Sort the overload candidate set by placing the best overloads first.
2858 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002859 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002860
Douglas Gregorc0265402010-01-21 15:46:19 +00002861 // Add the remaining viable overload candidates as code-completion reslults.
2862 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2863 CandEnd = CandidateSet.end();
2864 Cand != CandEnd; ++Cand) {
2865 if (Cand->Viable)
2866 Results.push_back(ResultCandidate(Cand->Function));
2867 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002868
2869 // From the viable candidates, try to determine the type of this parameter.
2870 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2871 if (const FunctionType *FType = Results[I].getFunctionType())
2872 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2873 if (NumArgs < Proto->getNumArgs()) {
2874 if (ParamType.isNull())
2875 ParamType = Proto->getArgType(NumArgs);
2876 else if (!Context.hasSameUnqualifiedType(
2877 ParamType.getNonReferenceType(),
2878 Proto->getArgType(NumArgs).getNonReferenceType())) {
2879 ParamType = QualType();
2880 break;
2881 }
2882 }
2883 }
2884 } else {
2885 // Try to determine the parameter type from the type of the expression
2886 // being called.
2887 QualType FunctionType = Fn->getType();
2888 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2889 FunctionType = Ptr->getPointeeType();
2890 else if (const BlockPointerType *BlockPtr
2891 = FunctionType->getAs<BlockPointerType>())
2892 FunctionType = BlockPtr->getPointeeType();
2893 else if (const MemberPointerType *MemPtr
2894 = FunctionType->getAs<MemberPointerType>())
2895 FunctionType = MemPtr->getPointeeType();
2896
2897 if (const FunctionProtoType *Proto
2898 = FunctionType->getAs<FunctionProtoType>()) {
2899 if (NumArgs < Proto->getNumArgs())
2900 ParamType = Proto->getArgType(NumArgs);
2901 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002902 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002903
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002904 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002905 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002906 else
2907 CodeCompleteExpression(S, ParamType);
2908
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002909 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002910 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2911 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002912}
2913
John McCalld226f652010-08-21 09:40:31 +00002914void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2915 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002916 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002917 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002918 return;
2919 }
2920
2921 CodeCompleteExpression(S, VD->getType());
2922}
2923
2924void Sema::CodeCompleteReturn(Scope *S) {
2925 QualType ResultType;
2926 if (isa<BlockDecl>(CurContext)) {
2927 if (BlockScopeInfo *BSI = getCurBlock())
2928 ResultType = BSI->ReturnType;
2929 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2930 ResultType = Function->getResultType();
2931 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2932 ResultType = Method->getResultType();
2933
2934 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002935 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002936 else
2937 CodeCompleteExpression(S, ResultType);
2938}
2939
2940void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2941 if (LHS)
2942 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2943 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002944 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002945}
2946
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002947void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002948 bool EnteringContext) {
2949 if (!SS.getScopeRep() || !CodeCompleter)
2950 return;
2951
Douglas Gregor86d9a522009-09-21 16:56:56 +00002952 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2953 if (!Ctx)
2954 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002955
2956 // Try to instantiate any non-dependent declaration contexts before
2957 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00002958 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002959 return;
2960
Douglas Gregor86d9a522009-09-21 16:56:56 +00002961 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002962 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2963 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002964
2965 // The "template" keyword can follow "::" in the grammar, but only
2966 // put it into the grammar if the nested-name-specifier is dependent.
2967 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2968 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002969 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002970
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002971 HandleCodeCompleteResults(this, CodeCompleter,
2972 CodeCompletionContext::CCC_Other,
2973 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002974}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002975
2976void Sema::CodeCompleteUsing(Scope *S) {
2977 if (!CodeCompleter)
2978 return;
2979
Douglas Gregor86d9a522009-09-21 16:56:56 +00002980 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002981 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002982
2983 // If we aren't in class scope, we could see the "namespace" keyword.
2984 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00002985 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002986
2987 // After "using", we can see anything that would start a
2988 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002989 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002990 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2991 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002992 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002993
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002994 HandleCodeCompleteResults(this, CodeCompleter,
2995 CodeCompletionContext::CCC_Other,
2996 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002997}
2998
2999void Sema::CodeCompleteUsingDirective(Scope *S) {
3000 if (!CodeCompleter)
3001 return;
3002
Douglas Gregor86d9a522009-09-21 16:56:56 +00003003 // After "using namespace", we expect to see a namespace name or namespace
3004 // alias.
3005 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003006 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003007 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003008 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3009 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003010 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003011 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003012 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003013 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003014}
3015
3016void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3017 if (!CodeCompleter)
3018 return;
3019
Douglas Gregor86d9a522009-09-21 16:56:56 +00003020 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3021 DeclContext *Ctx = (DeclContext *)S->getEntity();
3022 if (!S->getParent())
3023 Ctx = Context.getTranslationUnitDecl();
3024
3025 if (Ctx && Ctx->isFileContext()) {
3026 // We only want to see those namespaces that have already been defined
3027 // within this scope, because its likely that the user is creating an
3028 // extended namespace declaration. Keep track of the most recent
3029 // definition of each namespace.
3030 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3031 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3032 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3033 NS != NSEnd; ++NS)
3034 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3035
3036 // Add the most recent definition (or extended definition) of each
3037 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003038 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003039 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3040 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3041 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003042 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003043 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003044 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003045 }
3046
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003047 HandleCodeCompleteResults(this, CodeCompleter,
3048 CodeCompletionContext::CCC_Other,
3049 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003050}
3051
3052void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3053 if (!CodeCompleter)
3054 return;
3055
Douglas Gregor86d9a522009-09-21 16:56:56 +00003056 // After "namespace", we expect to see a namespace or alias.
3057 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003058 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003059 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3060 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003061 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003062 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003063 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003064}
3065
Douglas Gregored8d3222009-09-18 20:05:18 +00003066void Sema::CodeCompleteOperatorName(Scope *S) {
3067 if (!CodeCompleter)
3068 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003069
John McCall0a2c5e22010-08-25 06:19:51 +00003070 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003071 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003072 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003073
Douglas Gregor86d9a522009-09-21 16:56:56 +00003074 // Add the names of overloadable operators.
3075#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3076 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003077 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003078#include "clang/Basic/OperatorKinds.def"
3079
3080 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003081 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003082 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003083 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3084 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003085
3086 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003087 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003088 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003089
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003090 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003091 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003092 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003093}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003094
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003095// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3096// true or false.
3097#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003098static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003099 ResultBuilder &Results,
3100 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003101 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003102 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003103 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003104
3105 CodeCompletionString *Pattern = 0;
3106 if (LangOpts.ObjC2) {
3107 // @dynamic
3108 Pattern = new CodeCompletionString;
3109 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3110 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3111 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003112 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003113
3114 // @synthesize
3115 Pattern = new CodeCompletionString;
3116 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3117 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3118 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003119 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003120 }
3121}
3122
Douglas Gregorbca403c2010-01-13 23:51:12 +00003123static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003124 ResultBuilder &Results,
3125 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003126 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003127
3128 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003129 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003130
3131 if (LangOpts.ObjC2) {
3132 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003133 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003134
3135 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003136 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003137
3138 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003139 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003140 }
3141}
3142
Douglas Gregorbca403c2010-01-13 23:51:12 +00003143static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003144 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003145 CodeCompletionString *Pattern = 0;
3146
3147 // @class name ;
3148 Pattern = new CodeCompletionString;
3149 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3150 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003151 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003152 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003153
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003154 if (Results.includeCodePatterns()) {
3155 // @interface name
3156 // FIXME: Could introduce the whole pattern, including superclasses and
3157 // such.
3158 Pattern = new CodeCompletionString;
3159 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3160 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3161 Pattern->AddPlaceholderChunk("class");
3162 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003163
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003164 // @protocol name
3165 Pattern = new CodeCompletionString;
3166 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3167 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3168 Pattern->AddPlaceholderChunk("protocol");
3169 Results.AddResult(Result(Pattern));
3170
3171 // @implementation name
3172 Pattern = new CodeCompletionString;
3173 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3174 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3175 Pattern->AddPlaceholderChunk("class");
3176 Results.AddResult(Result(Pattern));
3177 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003178
3179 // @compatibility_alias name
3180 Pattern = new CodeCompletionString;
3181 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3182 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3183 Pattern->AddPlaceholderChunk("alias");
3184 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3185 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003186 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003187}
3188
John McCalld226f652010-08-21 09:40:31 +00003189void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003190 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003191 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003192 ResultBuilder Results(*this);
3193 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003194 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003195 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003196 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003197 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003198 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003199 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003200 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003201 HandleCodeCompleteResults(this, CodeCompleter,
3202 CodeCompletionContext::CCC_Other,
3203 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003204}
3205
Douglas Gregorbca403c2010-01-13 23:51:12 +00003206static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003207 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003208 CodeCompletionString *Pattern = 0;
3209
3210 // @encode ( type-name )
3211 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003212 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003213 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3214 Pattern->AddPlaceholderChunk("type-name");
3215 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003216 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003217
3218 // @protocol ( protocol-name )
3219 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003220 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003221 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3222 Pattern->AddPlaceholderChunk("protocol-name");
3223 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003224 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003225
3226 // @selector ( selector )
3227 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003228 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003229 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3230 Pattern->AddPlaceholderChunk("selector");
3231 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003232 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003233}
3234
Douglas Gregorbca403c2010-01-13 23:51:12 +00003235static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003236 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003237 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003238
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003239 if (Results.includeCodePatterns()) {
3240 // @try { statements } @catch ( declaration ) { statements } @finally
3241 // { statements }
3242 Pattern = new CodeCompletionString;
3243 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3244 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3245 Pattern->AddPlaceholderChunk("statements");
3246 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3247 Pattern->AddTextChunk("@catch");
3248 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3249 Pattern->AddPlaceholderChunk("parameter");
3250 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3251 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3252 Pattern->AddPlaceholderChunk("statements");
3253 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3254 Pattern->AddTextChunk("@finally");
3255 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3256 Pattern->AddPlaceholderChunk("statements");
3257 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3258 Results.AddResult(Result(Pattern));
3259 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003260
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003261 // @throw
3262 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003263 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003264 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003265 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003266 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003267
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003268 if (Results.includeCodePatterns()) {
3269 // @synchronized ( expression ) { statements }
3270 Pattern = new CodeCompletionString;
3271 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3272 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3273 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3274 Pattern->AddPlaceholderChunk("expression");
3275 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3276 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3277 Pattern->AddPlaceholderChunk("statements");
3278 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3279 Results.AddResult(Result(Pattern));
3280 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003281}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003282
Douglas Gregorbca403c2010-01-13 23:51:12 +00003283static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003284 ResultBuilder &Results,
3285 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003286 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003287 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3288 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3289 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003290 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003291 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003292}
3293
3294void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3295 ResultBuilder Results(*this);
3296 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003297 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003298 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003299 HandleCodeCompleteResults(this, CodeCompleter,
3300 CodeCompletionContext::CCC_Other,
3301 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003302}
3303
3304void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003305 ResultBuilder Results(*this);
3306 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003307 AddObjCStatementResults(Results, false);
3308 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003309 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003310 HandleCodeCompleteResults(this, CodeCompleter,
3311 CodeCompletionContext::CCC_Other,
3312 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003313}
3314
3315void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3316 ResultBuilder Results(*this);
3317 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003318 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003319 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003320 HandleCodeCompleteResults(this, CodeCompleter,
3321 CodeCompletionContext::CCC_Other,
3322 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003323}
3324
Douglas Gregor988358f2009-11-19 00:14:45 +00003325/// \brief Determine whether the addition of the given flag to an Objective-C
3326/// property's attributes will cause a conflict.
3327static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3328 // Check if we've already added this flag.
3329 if (Attributes & NewFlag)
3330 return true;
3331
3332 Attributes |= NewFlag;
3333
3334 // Check for collisions with "readonly".
3335 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3336 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3337 ObjCDeclSpec::DQ_PR_assign |
3338 ObjCDeclSpec::DQ_PR_copy |
3339 ObjCDeclSpec::DQ_PR_retain)))
3340 return true;
3341
3342 // Check for more than one of { assign, copy, retain }.
3343 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3344 ObjCDeclSpec::DQ_PR_copy |
3345 ObjCDeclSpec::DQ_PR_retain);
3346 if (AssignCopyRetMask &&
3347 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3348 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3349 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3350 return true;
3351
3352 return false;
3353}
3354
Douglas Gregora93b1082009-11-18 23:08:07 +00003355void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003356 if (!CodeCompleter)
3357 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003358
Steve Naroffece8e712009-10-08 21:55:05 +00003359 unsigned Attributes = ODS.getPropertyAttributes();
3360
John McCall0a2c5e22010-08-25 06:19:51 +00003361 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003362 ResultBuilder Results(*this);
3363 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003364 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003365 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003366 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003367 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003368 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003369 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003370 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003371 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003372 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003373 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003374 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003375 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003376 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003377 CodeCompletionString *Setter = new CodeCompletionString;
3378 Setter->AddTypedTextChunk("setter");
3379 Setter->AddTextChunk(" = ");
3380 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003381 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003382 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003383 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003384 CodeCompletionString *Getter = new CodeCompletionString;
3385 Getter->AddTypedTextChunk("getter");
3386 Getter->AddTextChunk(" = ");
3387 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003388 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003389 }
Steve Naroffece8e712009-10-08 21:55:05 +00003390 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003391 HandleCodeCompleteResults(this, CodeCompleter,
3392 CodeCompletionContext::CCC_Other,
3393 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003394}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003395
Douglas Gregor4ad96852009-11-19 07:41:15 +00003396/// \brief Descripts the kind of Objective-C method that we want to find
3397/// via code completion.
3398enum ObjCMethodKind {
3399 MK_Any, //< Any kind of method, provided it means other specified criteria.
3400 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3401 MK_OneArgSelector //< One-argument selector.
3402};
3403
3404static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3405 ObjCMethodKind WantKind,
3406 IdentifierInfo **SelIdents,
3407 unsigned NumSelIdents) {
3408 Selector Sel = Method->getSelector();
3409 if (NumSelIdents > Sel.getNumArgs())
3410 return false;
3411
3412 switch (WantKind) {
3413 case MK_Any: break;
3414 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3415 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3416 }
3417
3418 for (unsigned I = 0; I != NumSelIdents; ++I)
3419 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3420 return false;
3421
3422 return true;
3423}
3424
Douglas Gregor36ecb042009-11-17 23:22:23 +00003425/// \brief Add all of the Objective-C methods in the given Objective-C
3426/// container to the set of results.
3427///
3428/// The container will be a class, protocol, category, or implementation of
3429/// any of the above. This mether will recurse to include methods from
3430/// the superclasses of classes along with their categories, protocols, and
3431/// implementations.
3432///
3433/// \param Container the container in which we'll look to find methods.
3434///
3435/// \param WantInstance whether to add instance methods (only); if false, this
3436/// routine will add factory methods (only).
3437///
3438/// \param CurContext the context in which we're performing the lookup that
3439/// finds methods.
3440///
3441/// \param Results the structure into which we'll add results.
3442static void AddObjCMethods(ObjCContainerDecl *Container,
3443 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003444 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003445 IdentifierInfo **SelIdents,
3446 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003447 DeclContext *CurContext,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003448 ResultBuilder &Results,
3449 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003450 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003451 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3452 MEnd = Container->meth_end();
3453 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003454 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3455 // Check whether the selector identifiers we've been given are a
3456 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003457 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003458 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003459
Douglas Gregord3c68542009-11-19 01:08:35 +00003460 Result R = Result(*M, 0);
3461 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003462 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003463 if (!InOriginalClass)
3464 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003465 Results.MaybeAddResult(R, CurContext);
3466 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003467 }
3468
3469 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3470 if (!IFace)
3471 return;
3472
3473 // Add methods in protocols.
3474 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3475 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3476 E = Protocols.end();
3477 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003478 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003479 CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003480
3481 // Add methods in categories.
3482 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3483 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003484 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003485 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003486
3487 // Add a categories protocol methods.
3488 const ObjCList<ObjCProtocolDecl> &Protocols
3489 = CatDecl->getReferencedProtocols();
3490 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3491 E = Protocols.end();
3492 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003493 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003494 NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003495
3496 // Add methods in category implementations.
3497 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003498 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003499 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003500 }
3501
3502 // Add methods in superclass.
3503 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003504 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003505 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003506
3507 // Add methods in our implementation, if any.
3508 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003509 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003510 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003511}
3512
3513
John McCalld226f652010-08-21 09:40:31 +00003514void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3515 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003516 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003517 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003518
3519 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003520 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003521 if (!Class) {
3522 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003523 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003524 Class = Category->getClassInterface();
3525
3526 if (!Class)
3527 return;
3528 }
3529
3530 // Find all of the potential getters.
3531 ResultBuilder Results(*this);
3532 Results.EnterNewScope();
3533
3534 // FIXME: We need to do this because Objective-C methods don't get
3535 // pushed into DeclContexts early enough. Argh!
3536 for (unsigned I = 0; I != NumMethods; ++I) {
3537 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003538 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003539 if (Method->isInstanceMethod() &&
3540 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3541 Result R = Result(Method, 0);
3542 R.AllParametersAreInformative = true;
3543 Results.MaybeAddResult(R, CurContext);
3544 }
3545 }
3546
3547 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3548 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003549 HandleCodeCompleteResults(this, CodeCompleter,
3550 CodeCompletionContext::CCC_Other,
3551 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003552}
3553
John McCalld226f652010-08-21 09:40:31 +00003554void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3555 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003556 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003557 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003558
3559 // Try to find the interface where setters might live.
3560 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003561 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003562 if (!Class) {
3563 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003564 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003565 Class = Category->getClassInterface();
3566
3567 if (!Class)
3568 return;
3569 }
3570
3571 // Find all of the potential getters.
3572 ResultBuilder Results(*this);
3573 Results.EnterNewScope();
3574
3575 // FIXME: We need to do this because Objective-C methods don't get
3576 // pushed into DeclContexts early enough. Argh!
3577 for (unsigned I = 0; I != NumMethods; ++I) {
3578 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003579 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003580 if (Method->isInstanceMethod() &&
3581 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3582 Result R = Result(Method, 0);
3583 R.AllParametersAreInformative = true;
3584 Results.MaybeAddResult(R, CurContext);
3585 }
3586 }
3587
3588 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3589
3590 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003591 HandleCodeCompleteResults(this, CodeCompleter,
3592 CodeCompletionContext::CCC_Other,
3593 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003594}
3595
Douglas Gregord32b0222010-08-24 01:06:58 +00003596void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00003597 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00003598 ResultBuilder Results(*this);
3599 Results.EnterNewScope();
3600
3601 // Add context-sensitive, Objective-C parameter-passing keywords.
3602 bool AddedInOut = false;
3603 if ((DS.getObjCDeclQualifier() &
3604 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3605 Results.AddResult("in");
3606 Results.AddResult("inout");
3607 AddedInOut = true;
3608 }
3609 if ((DS.getObjCDeclQualifier() &
3610 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3611 Results.AddResult("out");
3612 if (!AddedInOut)
3613 Results.AddResult("inout");
3614 }
3615 if ((DS.getObjCDeclQualifier() &
3616 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3617 ObjCDeclSpec::DQ_Oneway)) == 0) {
3618 Results.AddResult("bycopy");
3619 Results.AddResult("byref");
3620 Results.AddResult("oneway");
3621 }
3622
3623 // Add various builtin type names and specifiers.
3624 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3625 Results.ExitScope();
3626
3627 // Add the various type names
3628 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3629 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3630 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3631 CodeCompleter->includeGlobals());
3632
3633 if (CodeCompleter->includeMacros())
3634 AddMacroResults(PP, Results);
3635
3636 HandleCodeCompleteResults(this, CodeCompleter,
3637 CodeCompletionContext::CCC_Type,
3638 Results.data(), Results.size());
3639}
3640
Douglas Gregor22f56992010-04-06 19:22:33 +00003641/// \brief When we have an expression with type "id", we may assume
3642/// that it has some more-specific class type based on knowledge of
3643/// common uses of Objective-C. This routine returns that class type,
3644/// or NULL if no better result could be determined.
3645static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3646 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3647 if (!Msg)
3648 return 0;
3649
3650 Selector Sel = Msg->getSelector();
3651 if (Sel.isNull())
3652 return 0;
3653
3654 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3655 if (!Id)
3656 return 0;
3657
3658 ObjCMethodDecl *Method = Msg->getMethodDecl();
3659 if (!Method)
3660 return 0;
3661
3662 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003663 ObjCInterfaceDecl *IFace = 0;
3664 switch (Msg->getReceiverKind()) {
3665 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003666 if (const ObjCObjectType *ObjType
3667 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3668 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003669 break;
3670
3671 case ObjCMessageExpr::Instance: {
3672 QualType T = Msg->getInstanceReceiver()->getType();
3673 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3674 IFace = Ptr->getInterfaceDecl();
3675 break;
3676 }
3677
3678 case ObjCMessageExpr::SuperInstance:
3679 case ObjCMessageExpr::SuperClass:
3680 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003681 }
3682
3683 if (!IFace)
3684 return 0;
3685
3686 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3687 if (Method->isInstanceMethod())
3688 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3689 .Case("retain", IFace)
3690 .Case("autorelease", IFace)
3691 .Case("copy", IFace)
3692 .Case("copyWithZone", IFace)
3693 .Case("mutableCopy", IFace)
3694 .Case("mutableCopyWithZone", IFace)
3695 .Case("awakeFromCoder", IFace)
3696 .Case("replacementObjectFromCoder", IFace)
3697 .Case("class", IFace)
3698 .Case("classForCoder", IFace)
3699 .Case("superclass", Super)
3700 .Default(0);
3701
3702 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3703 .Case("new", IFace)
3704 .Case("alloc", IFace)
3705 .Case("allocWithZone", IFace)
3706 .Case("class", IFace)
3707 .Case("superclass", Super)
3708 .Default(0);
3709}
3710
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003711void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00003712 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003713 ResultBuilder Results(*this);
3714
3715 // Find anything that looks like it could be a message receiver.
3716 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3717 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3718 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00003719 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3720 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003721
3722 // If we are in an Objective-C method inside a class that has a superclass,
3723 // add "super" as an option.
3724 if (ObjCMethodDecl *Method = getCurMethodDecl())
3725 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3726 if (Iface->getSuperClass())
3727 Results.AddResult(Result("super"));
3728
3729 Results.ExitScope();
3730
3731 if (CodeCompleter->includeMacros())
3732 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003733 HandleCodeCompleteResults(this, CodeCompleter,
3734 CodeCompletionContext::CCC_ObjCMessageReceiver,
3735 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003736
3737}
3738
Douglas Gregor2725ca82010-04-21 19:57:20 +00003739void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3740 IdentifierInfo **SelIdents,
3741 unsigned NumSelIdents) {
3742 ObjCInterfaceDecl *CDecl = 0;
3743 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3744 // Figure out which interface we're in.
3745 CDecl = CurMethod->getClassInterface();
3746 if (!CDecl)
3747 return;
3748
3749 // Find the superclass of this class.
3750 CDecl = CDecl->getSuperClass();
3751 if (!CDecl)
3752 return;
3753
3754 if (CurMethod->isInstanceMethod()) {
3755 // We are inside an instance method, which means that the message
3756 // send [super ...] is actually calling an instance method on the
3757 // current object. Build the super expression and handle this like
3758 // an instance method.
3759 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3760 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00003761 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00003762 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3763 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3764 SelIdents, NumSelIdents);
3765 }
3766
3767 // Fall through to send to the superclass in CDecl.
3768 } else {
3769 // "super" may be the name of a type or variable. Figure out which
3770 // it is.
3771 IdentifierInfo *Super = &Context.Idents.get("super");
3772 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3773 LookupOrdinaryName);
3774 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3775 // "super" names an interface. Use it.
3776 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003777 if (const ObjCObjectType *Iface
3778 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3779 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003780 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3781 // "super" names an unresolved type; we can't be more specific.
3782 } else {
3783 // Assume that "super" names some kind of value and parse that way.
3784 CXXScopeSpec SS;
3785 UnqualifiedId id;
3786 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00003787 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003788 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3789 SelIdents, NumSelIdents);
3790 }
3791
3792 // Fall through
3793 }
3794
John McCallb3d87482010-08-24 05:47:05 +00003795 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00003796 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00003797 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00003798 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3799 NumSelIdents);
3800}
3801
John McCallb3d87482010-08-24 05:47:05 +00003802void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003803 IdentifierInfo **SelIdents,
3804 unsigned NumSelIdents) {
John McCall0a2c5e22010-08-25 06:19:51 +00003805 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003806 ObjCInterfaceDecl *CDecl = 0;
3807
Douglas Gregor24a069f2009-11-17 17:59:40 +00003808 // If the given name refers to an interface type, retrieve the
3809 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003810 if (Receiver) {
3811 QualType T = GetTypeFromParser(Receiver, 0);
3812 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003813 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3814 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003815 }
3816
Douglas Gregor36ecb042009-11-17 23:22:23 +00003817 // Add all of the factory methods in this Objective-C class, its protocols,
3818 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003819 ResultBuilder Results(*this);
3820 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003821
3822 if (CDecl)
3823 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3824 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003825 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003826 // We're messaging "id" as a type; provide all class/factory methods.
3827
Douglas Gregor719770d2010-04-06 17:30:22 +00003828 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003829 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003830 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003831 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3832 I != N; ++I) {
3833 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003834 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003835 continue;
3836
Sebastian Redldb9d2142010-08-02 23:18:59 +00003837 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003838 }
3839 }
3840
Sebastian Redldb9d2142010-08-02 23:18:59 +00003841 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3842 MEnd = MethodPool.end();
3843 M != MEnd; ++M) {
3844 for (ObjCMethodList *MethList = &M->second.second;
3845 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003846 MethList = MethList->Next) {
3847 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3848 NumSelIdents))
3849 continue;
3850
3851 Result R(MethList->Method, 0);
3852 R.StartParameter = NumSelIdents;
3853 R.AllParametersAreInformative = false;
3854 Results.MaybeAddResult(R, CurContext);
3855 }
3856 }
3857 }
3858
Steve Naroffc4df6d22009-11-07 02:08:14 +00003859 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003860 HandleCodeCompleteResults(this, CodeCompleter,
3861 CodeCompletionContext::CCC_Other,
3862 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003863}
3864
Douglas Gregord3c68542009-11-19 01:08:35 +00003865void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3866 IdentifierInfo **SelIdents,
3867 unsigned NumSelIdents) {
John McCall0a2c5e22010-08-25 06:19:51 +00003868 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003869
3870 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003871
Douglas Gregor36ecb042009-11-17 23:22:23 +00003872 // If necessary, apply function/array conversion to the receiver.
3873 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003874 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003875 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003876
Douglas Gregor36ecb042009-11-17 23:22:23 +00003877 // Build the set of methods we can see.
3878 ResultBuilder Results(*this);
3879 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003880
3881 // If we're messaging an expression with type "id" or "Class", check
3882 // whether we know something special about the receiver that allows
3883 // us to assume a more-specific receiver type.
3884 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3885 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3886 ReceiverType = Context.getObjCObjectPointerType(
3887 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003888
Douglas Gregorf74a4192009-11-18 00:06:18 +00003889 // Handle messages to Class. This really isn't a message to an instance
3890 // method, so we treat it the same way we would treat a message send to a
3891 // class method.
3892 if (ReceiverType->isObjCClassType() ||
3893 ReceiverType->isObjCQualifiedClassType()) {
3894 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3895 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003896 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3897 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003898 }
3899 }
3900 // Handle messages to a qualified ID ("id<foo>").
3901 else if (const ObjCObjectPointerType *QualID
3902 = ReceiverType->getAsObjCQualifiedIdType()) {
3903 // Search protocols for instance methods.
3904 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3905 E = QualID->qual_end();
3906 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003907 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3908 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003909 }
3910 // Handle messages to a pointer to interface type.
3911 else if (const ObjCObjectPointerType *IFacePtr
3912 = ReceiverType->getAsObjCInterfacePointerType()) {
3913 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003914 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3915 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003916
3917 // Search protocols for instance methods.
3918 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3919 E = IFacePtr->qual_end();
3920 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003921 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3922 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003923 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003924 // Handle messages to "id".
3925 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003926 // We're messaging "id", so provide all instance methods we know
3927 // about as code-completion results.
3928
3929 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003930 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003931 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003932 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3933 I != N; ++I) {
3934 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003935 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003936 continue;
3937
Sebastian Redldb9d2142010-08-02 23:18:59 +00003938 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003939 }
3940 }
3941
Sebastian Redldb9d2142010-08-02 23:18:59 +00003942 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3943 MEnd = MethodPool.end();
3944 M != MEnd; ++M) {
3945 for (ObjCMethodList *MethList = &M->second.first;
3946 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003947 MethList = MethList->Next) {
3948 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3949 NumSelIdents))
3950 continue;
3951
3952 Result R(MethList->Method, 0);
3953 R.StartParameter = NumSelIdents;
3954 R.AllParametersAreInformative = false;
3955 Results.MaybeAddResult(R, CurContext);
3956 }
3957 }
3958 }
3959
Steve Naroffc4df6d22009-11-07 02:08:14 +00003960 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003961 HandleCodeCompleteResults(this, CodeCompleter,
3962 CodeCompletionContext::CCC_Other,
3963 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003964}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003965
Douglas Gregorfb629412010-08-23 21:17:50 +00003966void Sema::CodeCompleteObjCForCollection(Scope *S,
3967 DeclGroupPtrTy IterationVar) {
3968 CodeCompleteExpressionData Data;
3969 Data.ObjCCollection = true;
3970
3971 if (IterationVar.getAsOpaquePtr()) {
3972 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
3973 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
3974 if (*I)
3975 Data.IgnoreDecls.push_back(*I);
3976 }
3977 }
3978
3979 CodeCompleteExpression(S, Data);
3980}
3981
Douglas Gregor55385fe2009-11-18 04:19:12 +00003982/// \brief Add all of the protocol declarations that we find in the given
3983/// (translation unit) context.
3984static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003985 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003986 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00003987 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00003988
3989 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3990 DEnd = Ctx->decls_end();
3991 D != DEnd; ++D) {
3992 // Record any protocols we find.
3993 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003994 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003995 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003996
3997 // Record any forward-declared protocols we find.
3998 if (ObjCForwardProtocolDecl *Forward
3999 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4000 for (ObjCForwardProtocolDecl::protocol_iterator
4001 P = Forward->protocol_begin(),
4002 PEnd = Forward->protocol_end();
4003 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004004 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004005 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004006 }
4007 }
4008}
4009
4010void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4011 unsigned NumProtocols) {
4012 ResultBuilder Results(*this);
4013 Results.EnterNewScope();
4014
4015 // Tell the result set to ignore all of the protocols we have
4016 // already seen.
4017 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004018 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4019 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004020 Results.Ignore(Protocol);
4021
4022 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004023 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4024 Results);
4025
4026 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004027 HandleCodeCompleteResults(this, CodeCompleter,
4028 CodeCompletionContext::CCC_ObjCProtocolName,
4029 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004030}
4031
4032void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4033 ResultBuilder Results(*this);
4034 Results.EnterNewScope();
4035
4036 // Add all protocols.
4037 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4038 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004039
4040 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004041 HandleCodeCompleteResults(this, CodeCompleter,
4042 CodeCompletionContext::CCC_ObjCProtocolName,
4043 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004044}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004045
4046/// \brief Add all of the Objective-C interface declarations that we find in
4047/// the given (translation unit) context.
4048static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4049 bool OnlyForwardDeclarations,
4050 bool OnlyUnimplemented,
4051 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004052 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004053
4054 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4055 DEnd = Ctx->decls_end();
4056 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004057 // Record any interfaces we find.
4058 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4059 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4060 (!OnlyUnimplemented || !Class->getImplementation()))
4061 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004062
4063 // Record any forward-declared interfaces we find.
4064 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4065 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004066 C != CEnd; ++C)
4067 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4068 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4069 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004070 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004071 }
4072 }
4073}
4074
4075void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4076 ResultBuilder Results(*this);
4077 Results.EnterNewScope();
4078
4079 // Add all classes.
4080 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4081 false, Results);
4082
4083 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004084 HandleCodeCompleteResults(this, CodeCompleter,
4085 CodeCompletionContext::CCC_Other,
4086 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004087}
4088
Douglas Gregorc83c6872010-04-15 22:33:43 +00004089void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4090 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004091 ResultBuilder Results(*this);
4092 Results.EnterNewScope();
4093
4094 // Make sure that we ignore the class we're currently defining.
4095 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004096 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004097 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004098 Results.Ignore(CurClass);
4099
4100 // Add all classes.
4101 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4102 false, Results);
4103
4104 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004105 HandleCodeCompleteResults(this, CodeCompleter,
4106 CodeCompletionContext::CCC_Other,
4107 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004108}
4109
4110void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4111 ResultBuilder Results(*this);
4112 Results.EnterNewScope();
4113
4114 // Add all unimplemented classes.
4115 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4116 true, Results);
4117
4118 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004119 HandleCodeCompleteResults(this, CodeCompleter,
4120 CodeCompletionContext::CCC_Other,
4121 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004122}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004123
4124void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004125 IdentifierInfo *ClassName,
4126 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004127 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004128
4129 ResultBuilder Results(*this);
4130
4131 // Ignore any categories we find that have already been implemented by this
4132 // interface.
4133 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4134 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004135 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004136 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4137 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4138 Category = Category->getNextClassCategory())
4139 CategoryNames.insert(Category->getIdentifier());
4140
4141 // Add all of the categories we know about.
4142 Results.EnterNewScope();
4143 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4144 for (DeclContext::decl_iterator D = TU->decls_begin(),
4145 DEnd = TU->decls_end();
4146 D != DEnd; ++D)
4147 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4148 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004149 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004150 Results.ExitScope();
4151
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004152 HandleCodeCompleteResults(this, CodeCompleter,
4153 CodeCompletionContext::CCC_Other,
4154 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004155}
4156
4157void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004158 IdentifierInfo *ClassName,
4159 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004160 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004161
4162 // Find the corresponding interface. If we couldn't find the interface, the
4163 // program itself is ill-formed. However, we'll try to be helpful still by
4164 // providing the list of all of the categories we know about.
4165 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004166 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004167 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4168 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004169 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004170
4171 ResultBuilder Results(*this);
4172
4173 // Add all of the categories that have have corresponding interface
4174 // declarations in this class and any of its superclasses, except for
4175 // already-implemented categories in the class itself.
4176 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4177 Results.EnterNewScope();
4178 bool IgnoreImplemented = true;
4179 while (Class) {
4180 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4181 Category = Category->getNextClassCategory())
4182 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4183 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004184 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004185
4186 Class = Class->getSuperClass();
4187 IgnoreImplemented = false;
4188 }
4189 Results.ExitScope();
4190
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004191 HandleCodeCompleteResults(this, CodeCompleter,
4192 CodeCompletionContext::CCC_Other,
4193 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004194}
Douglas Gregor322328b2009-11-18 22:32:06 +00004195
John McCalld226f652010-08-21 09:40:31 +00004196void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004197 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004198 ResultBuilder Results(*this);
4199
4200 // Figure out where this @synthesize lives.
4201 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004202 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004203 if (!Container ||
4204 (!isa<ObjCImplementationDecl>(Container) &&
4205 !isa<ObjCCategoryImplDecl>(Container)))
4206 return;
4207
4208 // Ignore any properties that have already been implemented.
4209 for (DeclContext::decl_iterator D = Container->decls_begin(),
4210 DEnd = Container->decls_end();
4211 D != DEnd; ++D)
4212 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4213 Results.Ignore(PropertyImpl->getPropertyDecl());
4214
4215 // Add any properties that we find.
4216 Results.EnterNewScope();
4217 if (ObjCImplementationDecl *ClassImpl
4218 = dyn_cast<ObjCImplementationDecl>(Container))
4219 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4220 Results);
4221 else
4222 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4223 false, CurContext, Results);
4224 Results.ExitScope();
4225
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004226 HandleCodeCompleteResults(this, CodeCompleter,
4227 CodeCompletionContext::CCC_Other,
4228 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004229}
4230
4231void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4232 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004233 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004234 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004235 ResultBuilder Results(*this);
4236
4237 // Figure out where this @synthesize lives.
4238 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004239 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004240 if (!Container ||
4241 (!isa<ObjCImplementationDecl>(Container) &&
4242 !isa<ObjCCategoryImplDecl>(Container)))
4243 return;
4244
4245 // Figure out which interface we're looking into.
4246 ObjCInterfaceDecl *Class = 0;
4247 if (ObjCImplementationDecl *ClassImpl
4248 = dyn_cast<ObjCImplementationDecl>(Container))
4249 Class = ClassImpl->getClassInterface();
4250 else
4251 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4252 ->getClassInterface();
4253
4254 // Add all of the instance variables in this class and its superclasses.
4255 Results.EnterNewScope();
4256 for(; Class; Class = Class->getSuperClass()) {
4257 // FIXME: We could screen the type of each ivar for compatibility with
4258 // the property, but is that being too paternal?
4259 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4260 IVarEnd = Class->ivar_end();
4261 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004262 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004263 }
4264 Results.ExitScope();
4265
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004266 HandleCodeCompleteResults(this, CodeCompleter,
4267 CodeCompletionContext::CCC_Other,
4268 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004269}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004270
Douglas Gregor408be5a2010-08-25 01:08:01 +00004271// Mapping from selectors to the methods that implement that selector, along
4272// with the "in original class" flag.
4273typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4274 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004275
4276/// \brief Find all of the methods that reside in the given container
4277/// (and its superclasses, protocols, etc.) that meet the given
4278/// criteria. Insert those methods into the map of known methods,
4279/// indexed by selector so they can be easily found.
4280static void FindImplementableMethods(ASTContext &Context,
4281 ObjCContainerDecl *Container,
4282 bool WantInstanceMethods,
4283 QualType ReturnType,
4284 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004285 KnownMethodsMap &KnownMethods,
4286 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004287 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4288 // Recurse into protocols.
4289 const ObjCList<ObjCProtocolDecl> &Protocols
4290 = IFace->getReferencedProtocols();
4291 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4292 E = Protocols.end();
4293 I != E; ++I)
4294 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004295 IsInImplementation, KnownMethods,
4296 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004297
4298 // If we're not in the implementation of a class, also visit the
4299 // superclass.
4300 if (!IsInImplementation && IFace->getSuperClass())
4301 FindImplementableMethods(Context, IFace->getSuperClass(),
4302 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004303 IsInImplementation, KnownMethods,
4304 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004305
4306 // Add methods from any class extensions (but not from categories;
4307 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004308 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4309 Cat = Cat->getNextClassExtension())
4310 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4311 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004312 IsInImplementation, KnownMethods,
4313 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004314 }
4315
4316 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4317 // Recurse into protocols.
4318 const ObjCList<ObjCProtocolDecl> &Protocols
4319 = Category->getReferencedProtocols();
4320 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4321 E = Protocols.end();
4322 I != E; ++I)
4323 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004324 IsInImplementation, KnownMethods,
4325 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004326 }
4327
4328 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4329 // Recurse into protocols.
4330 const ObjCList<ObjCProtocolDecl> &Protocols
4331 = Protocol->getReferencedProtocols();
4332 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4333 E = Protocols.end();
4334 I != E; ++I)
4335 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004336 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004337 }
4338
4339 // Add methods in this container. This operation occurs last because
4340 // we want the methods from this container to override any methods
4341 // we've previously seen with the same selector.
4342 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4343 MEnd = Container->meth_end();
4344 M != MEnd; ++M) {
4345 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4346 if (!ReturnType.isNull() &&
4347 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4348 continue;
4349
Douglas Gregor408be5a2010-08-25 01:08:01 +00004350 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004351 }
4352 }
4353}
4354
4355void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4356 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004357 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004358 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004359 // Determine the return type of the method we're declaring, if
4360 // provided.
4361 QualType ReturnType = GetTypeFromParser(ReturnTy);
4362
4363 // Determine where we should start searching for methods, and where we
4364 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4365 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004366 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004367 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4368 SearchDecl = Impl->getClassInterface();
4369 CurrentDecl = Impl;
4370 IsInImplementation = true;
4371 } else if (ObjCCategoryImplDecl *CatImpl
4372 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4373 SearchDecl = CatImpl->getCategoryDecl();
4374 CurrentDecl = CatImpl;
4375 IsInImplementation = true;
4376 } else {
4377 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4378 CurrentDecl = SearchDecl;
4379 }
4380 }
4381
4382 if (!SearchDecl && S) {
4383 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4384 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4385 CurrentDecl = SearchDecl;
4386 }
4387 }
4388
4389 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004390 HandleCodeCompleteResults(this, CodeCompleter,
4391 CodeCompletionContext::CCC_Other,
4392 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004393 return;
4394 }
4395
4396 // Find all of the methods that we could declare/implement here.
4397 KnownMethodsMap KnownMethods;
4398 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4399 ReturnType, IsInImplementation, KnownMethods);
4400
4401 // Erase any methods that have already been declared or
4402 // implemented here.
4403 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4404 MEnd = CurrentDecl->meth_end();
4405 M != MEnd; ++M) {
4406 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4407 continue;
4408
4409 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4410 if (Pos != KnownMethods.end())
4411 KnownMethods.erase(Pos);
4412 }
4413
4414 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00004415 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004416 ResultBuilder Results(*this);
4417 Results.EnterNewScope();
4418 PrintingPolicy Policy(Context.PrintingPolicy);
4419 Policy.AnonymousTagLocations = false;
4420 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4421 MEnd = KnownMethods.end();
4422 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00004423 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004424 CodeCompletionString *Pattern = new CodeCompletionString;
4425
4426 // If the result type was not already provided, add it to the
4427 // pattern as (type).
4428 if (ReturnType.isNull()) {
4429 std::string TypeStr;
4430 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4431 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4432 Pattern->AddTextChunk(TypeStr);
4433 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4434 }
4435
4436 Selector Sel = Method->getSelector();
4437
4438 // Add the first part of the selector to the pattern.
4439 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4440
4441 // Add parameters to the pattern.
4442 unsigned I = 0;
4443 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4444 PEnd = Method->param_end();
4445 P != PEnd; (void)++P, ++I) {
4446 // Add the part of the selector name.
4447 if (I == 0)
4448 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4449 else if (I < Sel.getNumArgs()) {
4450 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00004451 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004452 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4453 } else
4454 break;
4455
4456 // Add the parameter type.
4457 std::string TypeStr;
4458 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4459 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4460 Pattern->AddTextChunk(TypeStr);
4461 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4462
4463 if (IdentifierInfo *Id = (*P)->getIdentifier())
4464 Pattern->AddTextChunk(Id->getName());
4465 }
4466
4467 if (Method->isVariadic()) {
4468 if (Method->param_size() > 0)
4469 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4470 Pattern->AddTextChunk("...");
4471 }
4472
Douglas Gregor447107d2010-05-28 00:57:46 +00004473 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004474 // We will be defining the method here, so add a compound statement.
4475 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4476 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4477 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4478 if (!Method->getResultType()->isVoidType()) {
4479 // If the result type is not void, add a return clause.
4480 Pattern->AddTextChunk("return");
4481 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4482 Pattern->AddPlaceholderChunk("expression");
4483 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4484 } else
4485 Pattern->AddPlaceholderChunk("statements");
4486
4487 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4488 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4489 }
4490
Douglas Gregor408be5a2010-08-25 01:08:01 +00004491 unsigned Priority = CCP_CodePattern;
4492 if (!M->second.second)
4493 Priority += CCD_InBaseClass;
4494
4495 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00004496 Method->isInstanceMethod()
4497 ? CXCursor_ObjCInstanceMethodDecl
4498 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00004499 }
4500
4501 Results.ExitScope();
4502
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004503 HandleCodeCompleteResults(this, CodeCompleter,
4504 CodeCompletionContext::CCC_Other,
4505 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004506}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004507
4508void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4509 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004510 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00004511 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004512 IdentifierInfo **SelIdents,
4513 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004514 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004515 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004516 if (ExternalSource) {
4517 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4518 I != N; ++I) {
4519 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004520 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004521 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00004522
4523 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004524 }
4525 }
4526
4527 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00004528 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004529 ResultBuilder Results(*this);
4530
4531 if (ReturnTy)
4532 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00004533
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004534 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004535 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4536 MEnd = MethodPool.end();
4537 M != MEnd; ++M) {
4538 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4539 &M->second.second;
4540 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004541 MethList = MethList->Next) {
4542 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4543 NumSelIdents))
4544 continue;
4545
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004546 if (AtParameterName) {
4547 // Suggest parameter names we've seen before.
4548 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4549 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4550 if (Param->getIdentifier()) {
4551 CodeCompletionString *Pattern = new CodeCompletionString;
4552 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4553 Results.AddResult(Pattern);
4554 }
4555 }
4556
4557 continue;
4558 }
4559
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004560 Result R(MethList->Method, 0);
4561 R.StartParameter = NumSelIdents;
4562 R.AllParametersAreInformative = false;
4563 R.DeclaringEntity = true;
4564 Results.MaybeAddResult(R, CurContext);
4565 }
4566 }
4567
4568 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004569 HandleCodeCompleteResults(this, CodeCompleter,
4570 CodeCompletionContext::CCC_Other,
4571 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004572}
Douglas Gregor87c08a52010-08-13 22:48:40 +00004573
Douglas Gregorf29c5232010-08-24 22:20:20 +00004574void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00004575 ResultBuilder Results(*this);
4576 Results.EnterNewScope();
4577
4578 // #if <condition>
4579 CodeCompletionString *Pattern = new CodeCompletionString;
4580 Pattern->AddTypedTextChunk("if");
4581 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4582 Pattern->AddPlaceholderChunk("condition");
4583 Results.AddResult(Pattern);
4584
4585 // #ifdef <macro>
4586 Pattern = new CodeCompletionString;
4587 Pattern->AddTypedTextChunk("ifdef");
4588 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4589 Pattern->AddPlaceholderChunk("macro");
4590 Results.AddResult(Pattern);
4591
4592 // #ifndef <macro>
4593 Pattern = new CodeCompletionString;
4594 Pattern->AddTypedTextChunk("ifndef");
4595 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4596 Pattern->AddPlaceholderChunk("macro");
4597 Results.AddResult(Pattern);
4598
4599 if (InConditional) {
4600 // #elif <condition>
4601 Pattern = new CodeCompletionString;
4602 Pattern->AddTypedTextChunk("elif");
4603 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4604 Pattern->AddPlaceholderChunk("condition");
4605 Results.AddResult(Pattern);
4606
4607 // #else
4608 Pattern = new CodeCompletionString;
4609 Pattern->AddTypedTextChunk("else");
4610 Results.AddResult(Pattern);
4611
4612 // #endif
4613 Pattern = new CodeCompletionString;
4614 Pattern->AddTypedTextChunk("endif");
4615 Results.AddResult(Pattern);
4616 }
4617
4618 // #include "header"
4619 Pattern = new CodeCompletionString;
4620 Pattern->AddTypedTextChunk("include");
4621 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4622 Pattern->AddTextChunk("\"");
4623 Pattern->AddPlaceholderChunk("header");
4624 Pattern->AddTextChunk("\"");
4625 Results.AddResult(Pattern);
4626
4627 // #include <header>
4628 Pattern = new CodeCompletionString;
4629 Pattern->AddTypedTextChunk("include");
4630 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4631 Pattern->AddTextChunk("<");
4632 Pattern->AddPlaceholderChunk("header");
4633 Pattern->AddTextChunk(">");
4634 Results.AddResult(Pattern);
4635
4636 // #define <macro>
4637 Pattern = new CodeCompletionString;
4638 Pattern->AddTypedTextChunk("define");
4639 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4640 Pattern->AddPlaceholderChunk("macro");
4641 Results.AddResult(Pattern);
4642
4643 // #define <macro>(<args>)
4644 Pattern = new CodeCompletionString;
4645 Pattern->AddTypedTextChunk("define");
4646 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4647 Pattern->AddPlaceholderChunk("macro");
4648 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4649 Pattern->AddPlaceholderChunk("args");
4650 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4651 Results.AddResult(Pattern);
4652
4653 // #undef <macro>
4654 Pattern = new CodeCompletionString;
4655 Pattern->AddTypedTextChunk("undef");
4656 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4657 Pattern->AddPlaceholderChunk("macro");
4658 Results.AddResult(Pattern);
4659
4660 // #line <number>
4661 Pattern = new CodeCompletionString;
4662 Pattern->AddTypedTextChunk("line");
4663 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4664 Pattern->AddPlaceholderChunk("number");
4665 Results.AddResult(Pattern);
4666
4667 // #line <number> "filename"
4668 Pattern = new CodeCompletionString;
4669 Pattern->AddTypedTextChunk("line");
4670 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4671 Pattern->AddPlaceholderChunk("number");
4672 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4673 Pattern->AddTextChunk("\"");
4674 Pattern->AddPlaceholderChunk("filename");
4675 Pattern->AddTextChunk("\"");
4676 Results.AddResult(Pattern);
4677
4678 // #error <message>
4679 Pattern = new CodeCompletionString;
4680 Pattern->AddTypedTextChunk("error");
4681 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4682 Pattern->AddPlaceholderChunk("message");
4683 Results.AddResult(Pattern);
4684
4685 // #pragma <arguments>
4686 Pattern = new CodeCompletionString;
4687 Pattern->AddTypedTextChunk("pragma");
4688 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4689 Pattern->AddPlaceholderChunk("arguments");
4690 Results.AddResult(Pattern);
4691
4692 if (getLangOptions().ObjC1) {
4693 // #import "header"
4694 Pattern = new CodeCompletionString;
4695 Pattern->AddTypedTextChunk("import");
4696 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4697 Pattern->AddTextChunk("\"");
4698 Pattern->AddPlaceholderChunk("header");
4699 Pattern->AddTextChunk("\"");
4700 Results.AddResult(Pattern);
4701
4702 // #import <header>
4703 Pattern = new CodeCompletionString;
4704 Pattern->AddTypedTextChunk("import");
4705 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4706 Pattern->AddTextChunk("<");
4707 Pattern->AddPlaceholderChunk("header");
4708 Pattern->AddTextChunk(">");
4709 Results.AddResult(Pattern);
4710 }
4711
4712 // #include_next "header"
4713 Pattern = new CodeCompletionString;
4714 Pattern->AddTypedTextChunk("include_next");
4715 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4716 Pattern->AddTextChunk("\"");
4717 Pattern->AddPlaceholderChunk("header");
4718 Pattern->AddTextChunk("\"");
4719 Results.AddResult(Pattern);
4720
4721 // #include_next <header>
4722 Pattern = new CodeCompletionString;
4723 Pattern->AddTypedTextChunk("include_next");
4724 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4725 Pattern->AddTextChunk("<");
4726 Pattern->AddPlaceholderChunk("header");
4727 Pattern->AddTextChunk(">");
4728 Results.AddResult(Pattern);
4729
4730 // #warning <message>
4731 Pattern = new CodeCompletionString;
4732 Pattern->AddTypedTextChunk("warning");
4733 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4734 Pattern->AddPlaceholderChunk("message");
4735 Results.AddResult(Pattern);
4736
4737 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
4738 // completions for them. And __include_macros is a Clang-internal extension
4739 // that we don't want to encourage anyone to use.
4740
4741 // FIXME: we don't support #assert or #unassert, so don't suggest them.
4742 Results.ExitScope();
4743
Douglas Gregorf44e8542010-08-24 19:08:16 +00004744 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00004745 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00004746 Results.data(), Results.size());
4747}
4748
4749void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00004750 CodeCompleteOrdinaryName(S,
4751 S->getFnParent()? Action::PCC_RecoveryInFunction
4752 : Action::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00004753}
4754
Douglas Gregorf29c5232010-08-24 22:20:20 +00004755void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00004756 ResultBuilder Results(*this);
4757 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
4758 // Add just the names of macros, not their arguments.
4759 Results.EnterNewScope();
4760 for (Preprocessor::macro_iterator M = PP.macro_begin(),
4761 MEnd = PP.macro_end();
4762 M != MEnd; ++M) {
4763 CodeCompletionString *Pattern = new CodeCompletionString;
4764 Pattern->AddTypedTextChunk(M->first->getName());
4765 Results.AddResult(Pattern);
4766 }
4767 Results.ExitScope();
4768 } else if (IsDefinition) {
4769 // FIXME: Can we detect when the user just wrote an include guard above?
4770 }
4771
4772 HandleCodeCompleteResults(this, CodeCompleter,
4773 IsDefinition? CodeCompletionContext::CCC_MacroName
4774 : CodeCompletionContext::CCC_MacroNameUse,
4775 Results.data(), Results.size());
4776}
4777
Douglas Gregorf29c5232010-08-24 22:20:20 +00004778void Sema::CodeCompletePreprocessorExpression() {
4779 ResultBuilder Results(*this);
4780
4781 if (!CodeCompleter || CodeCompleter->includeMacros())
4782 AddMacroResults(PP, Results);
4783
4784 // defined (<macro>)
4785 Results.EnterNewScope();
4786 CodeCompletionString *Pattern = new CodeCompletionString;
4787 Pattern->AddTypedTextChunk("defined");
4788 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4789 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4790 Pattern->AddPlaceholderChunk("macro");
4791 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4792 Results.AddResult(Pattern);
4793 Results.ExitScope();
4794
4795 HandleCodeCompleteResults(this, CodeCompleter,
4796 CodeCompletionContext::CCC_PreprocessorExpression,
4797 Results.data(), Results.size());
4798}
4799
4800void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
4801 IdentifierInfo *Macro,
4802 MacroInfo *MacroInfo,
4803 unsigned Argument) {
4804 // FIXME: In the future, we could provide "overload" results, much like we
4805 // do for function calls.
4806
4807 CodeCompleteOrdinaryName(S,
4808 S->getFnParent()? Action::PCC_RecoveryInFunction
4809 : Action::PCC_Namespace);
4810}
4811
Douglas Gregor55817af2010-08-25 17:04:25 +00004812void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00004813 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00004814 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00004815 0, 0);
4816}
4817
Douglas Gregor87c08a52010-08-13 22:48:40 +00004818void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00004819 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00004820 ResultBuilder Builder(*this);
4821
Douglas Gregor8071e422010-08-15 06:18:01 +00004822 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4823 CodeCompletionDeclConsumer Consumer(Builder,
4824 Context.getTranslationUnitDecl());
4825 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4826 Consumer);
4827 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00004828
4829 if (!CodeCompleter || CodeCompleter->includeMacros())
4830 AddMacroResults(PP, Builder);
4831
4832 Results.clear();
4833 Results.insert(Results.end(),
4834 Builder.data(), Builder.data() + Builder.size());
4835}