blob: fed65365706c82030f8b48123f6d48ba60a74afd [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 Gregor721f3592010-08-25 18:41:16 +00002280 std::stable_sort(Results, Results + NumResults);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002281
2282 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002283 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002284
2285 for (unsigned I = 0; I != NumResults; ++I)
2286 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002287}
2288
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002289static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2290 Sema::ParserCompletionContext PCC) {
2291 switch (PCC) {
2292 case Action::PCC_Namespace:
2293 return CodeCompletionContext::CCC_TopLevel;
2294
2295 case Action::PCC_Class:
2296 return CodeCompletionContext::CCC_ClassStructUnion;
2297
2298 case Action::PCC_ObjCInterface:
2299 return CodeCompletionContext::CCC_ObjCInterface;
2300
2301 case Action::PCC_ObjCImplementation:
2302 return CodeCompletionContext::CCC_ObjCImplementation;
2303
2304 case Action::PCC_ObjCInstanceVariableList:
2305 return CodeCompletionContext::CCC_ObjCIvarList;
2306
2307 case Action::PCC_Template:
2308 case Action::PCC_MemberTemplate:
2309 case Action::PCC_RecoveryInFunction:
2310 return CodeCompletionContext::CCC_Other;
2311
2312 case Action::PCC_Expression:
2313 case Action::PCC_ForInit:
2314 case Action::PCC_Condition:
2315 return CodeCompletionContext::CCC_Expression;
2316
2317 case Action::PCC_Statement:
2318 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002319
2320 case Action::PCC_Type:
2321 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002322 }
2323
2324 return CodeCompletionContext::CCC_Other;
2325}
2326
Douglas Gregor01dfea02010-01-10 23:08:15 +00002327void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002328 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002329 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002330 ResultBuilder Results(*this);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002331
2332 // Determine how to filter results, e.g., so that the names of
2333 // values (functions, enumerators, function templates, etc.) are
2334 // only allowed where we can have an expression.
2335 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002336 case PCC_Namespace:
2337 case PCC_Class:
2338 case PCC_ObjCInterface:
2339 case PCC_ObjCImplementation:
2340 case PCC_ObjCInstanceVariableList:
2341 case PCC_Template:
2342 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002343 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002344 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2345 break;
2346
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002347 case PCC_Statement:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002348 // For statements that are expressions, we prefer to call 'void' functions
2349 // rather than functions that return a result, since then the result would
2350 // be ignored.
2351 Results.setPreferredType(Context.VoidTy);
2352 // Fall through
2353
2354 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002355 case PCC_ForInit:
2356 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002357 if (WantTypesInContext(CompletionContext, getLangOptions()))
2358 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2359 else
2360 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002361 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002362
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002363 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002364 // Unfiltered
2365 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002366 }
2367
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002368 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002369 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2370 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002371
2372 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002373 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002374 Results.ExitScope();
2375
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002376 switch (CompletionContext) {
Douglas Gregor72db1082010-08-24 01:11:00 +00002377 case PCC_Expression:
2378 case PCC_Statement:
2379 case PCC_RecoveryInFunction:
2380 if (S->getFnParent())
2381 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2382 break;
2383
2384 case PCC_Namespace:
2385 case PCC_Class:
2386 case PCC_ObjCInterface:
2387 case PCC_ObjCImplementation:
2388 case PCC_ObjCInstanceVariableList:
2389 case PCC_Template:
2390 case PCC_MemberTemplate:
2391 case PCC_ForInit:
2392 case PCC_Condition:
2393 case PCC_Type:
2394 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002395 }
2396
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002397 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002398 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002399
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002400 HandleCodeCompleteResults(this, CodeCompleter,
2401 mapCodeCompletionContext(*this, CompletionContext),
2402 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002403}
2404
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002405void Sema::CodeCompleteDeclarator(Scope *S,
2406 bool AllowNonIdentifiers,
2407 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002408 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002409 ResultBuilder Results(*this);
2410 Results.EnterNewScope();
2411
2412 // Type qualifiers can come after names.
2413 Results.AddResult(Result("const"));
2414 Results.AddResult(Result("volatile"));
2415 if (getLangOptions().C99)
2416 Results.AddResult(Result("restrict"));
2417
2418 if (getLangOptions().CPlusPlus) {
2419 if (AllowNonIdentifiers) {
2420 Results.AddResult(Result("operator"));
2421 }
2422
2423 // Add nested-name-specifiers.
2424 if (AllowNestedNameSpecifiers) {
2425 Results.allowNestedNameSpecifiers();
2426 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2427 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2428 CodeCompleter->includeGlobals());
2429 }
2430 }
2431 Results.ExitScope();
2432
Douglas Gregor4497dd42010-08-24 04:59:56 +00002433 // Note that we intentionally suppress macro results here, since we do not
2434 // encourage using macros to produce the names of entities.
2435
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002436 HandleCodeCompleteResults(this, CodeCompleter,
2437 AllowNestedNameSpecifiers
2438 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2439 : CodeCompletionContext::CCC_Name,
2440 Results.data(), Results.size());
2441}
2442
Douglas Gregorfb629412010-08-23 21:17:50 +00002443struct Sema::CodeCompleteExpressionData {
2444 CodeCompleteExpressionData(QualType PreferredType = QualType())
2445 : PreferredType(PreferredType), IntegralConstantExpression(false),
2446 ObjCCollection(false) { }
2447
2448 QualType PreferredType;
2449 bool IntegralConstantExpression;
2450 bool ObjCCollection;
2451 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2452};
2453
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002454/// \brief Perform code-completion in an expression context when we know what
2455/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002456///
2457/// \param IntegralConstantExpression Only permit integral constant
2458/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002459void Sema::CodeCompleteExpression(Scope *S,
2460 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002461 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002462 ResultBuilder Results(*this);
2463
Douglas Gregorfb629412010-08-23 21:17:50 +00002464 if (Data.ObjCCollection)
2465 Results.setFilter(&ResultBuilder::IsObjCCollection);
2466 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002467 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002468 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002469 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2470 else
2471 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002472
2473 if (!Data.PreferredType.isNull())
2474 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2475
2476 // Ignore any declarations that we were told that we don't care about.
2477 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2478 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002479
2480 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002481 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2482 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002483
2484 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002485 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002486 Results.ExitScope();
2487
Douglas Gregor590c7d52010-07-08 20:55:51 +00002488 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002489 if (!Data.PreferredType.isNull())
2490 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2491 || Data.PreferredType->isMemberPointerType()
2492 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002493
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002494 if (S->getFnParent() &&
2495 !Data.ObjCCollection &&
2496 !Data.IntegralConstantExpression)
2497 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2498
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002499 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002500 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002501 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002502 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2503 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002504 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002505}
2506
2507
Douglas Gregor95ac6552009-11-18 01:29:26 +00002508static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002509 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002510 DeclContext *CurContext,
2511 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002512 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002513
2514 // Add properties in this container.
2515 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2516 PEnd = Container->prop_end();
2517 P != PEnd;
2518 ++P)
2519 Results.MaybeAddResult(Result(*P, 0), CurContext);
2520
2521 // Add properties in referenced protocols.
2522 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2523 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2524 PEnd = Protocol->protocol_end();
2525 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002526 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002527 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002528 if (AllowCategories) {
2529 // Look through categories.
2530 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2531 Category; Category = Category->getNextClassCategory())
2532 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2533 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002534
2535 // Look through protocols.
2536 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2537 E = IFace->protocol_end();
2538 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002539 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002540
2541 // Look in the superclass.
2542 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002543 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2544 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002545 } else if (const ObjCCategoryDecl *Category
2546 = dyn_cast<ObjCCategoryDecl>(Container)) {
2547 // Look through protocols.
2548 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2549 PEnd = Category->protocol_end();
2550 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002551 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002552 }
2553}
2554
Douglas Gregor81b747b2009-09-17 21:32:03 +00002555void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2556 SourceLocation OpLoc,
2557 bool IsArrow) {
2558 if (!BaseE || !CodeCompleter)
2559 return;
2560
John McCall0a2c5e22010-08-25 06:19:51 +00002561 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002562
Douglas Gregor81b747b2009-09-17 21:32:03 +00002563 Expr *Base = static_cast<Expr *>(BaseE);
2564 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002565
2566 if (IsArrow) {
2567 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2568 BaseType = Ptr->getPointeeType();
2569 else if (BaseType->isObjCObjectPointerType())
2570 /*Do nothing*/ ;
2571 else
2572 return;
2573 }
2574
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002575 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002576 Results.EnterNewScope();
2577 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2578 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002579 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002580 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002581 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2582 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002583
Douglas Gregor95ac6552009-11-18 01:29:26 +00002584 if (getLangOptions().CPlusPlus) {
2585 if (!Results.empty()) {
2586 // The "template" keyword can follow "->" or "." in the grammar.
2587 // However, we only want to suggest the template keyword if something
2588 // is dependent.
2589 bool IsDependent = BaseType->isDependentType();
2590 if (!IsDependent) {
2591 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2592 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2593 IsDependent = Ctx->isDependentContext();
2594 break;
2595 }
2596 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002597
Douglas Gregor95ac6552009-11-18 01:29:26 +00002598 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002599 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002600 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002601 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002602 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2603 // Objective-C property reference.
2604
2605 // Add property results based on our interface.
2606 const ObjCObjectPointerType *ObjCPtr
2607 = BaseType->getAsObjCInterfacePointerType();
2608 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002609 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002610
2611 // Add properties from the protocols in a qualified interface.
2612 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2613 E = ObjCPtr->qual_end();
2614 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002615 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002616 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002617 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002618 // Objective-C instance variable access.
2619 ObjCInterfaceDecl *Class = 0;
2620 if (const ObjCObjectPointerType *ObjCPtr
2621 = BaseType->getAs<ObjCObjectPointerType>())
2622 Class = ObjCPtr->getInterfaceDecl();
2623 else
John McCallc12c5bb2010-05-15 11:32:37 +00002624 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002625
2626 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002627 if (Class) {
2628 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2629 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002630 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2631 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002632 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002633 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002634
2635 // FIXME: How do we cope with isa?
2636
2637 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002638
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002639 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002640 HandleCodeCompleteResults(this, CodeCompleter,
2641 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2642 BaseType),
2643 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002644}
2645
Douglas Gregor374929f2009-09-18 15:37:17 +00002646void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2647 if (!CodeCompleter)
2648 return;
2649
John McCall0a2c5e22010-08-25 06:19:51 +00002650 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002651 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002652 enum CodeCompletionContext::Kind ContextKind
2653 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002654 switch ((DeclSpec::TST)TagSpec) {
2655 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002656 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002657 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002658 break;
2659
2660 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002661 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002662 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002663 break;
2664
2665 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002666 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002667 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002668 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002669 break;
2670
2671 default:
2672 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2673 return;
2674 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002675
John McCall0d6b1642010-04-23 18:46:30 +00002676 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002677 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002678
2679 // First pass: look for tags.
2680 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002681 LookupVisibleDecls(S, LookupTagName, Consumer,
2682 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002683
Douglas Gregor8071e422010-08-15 06:18:01 +00002684 if (CodeCompleter->includeGlobals()) {
2685 // Second pass: look for nested name specifiers.
2686 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2687 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2688 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002689
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002690 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2691 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002692}
2693
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002694void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002695 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002696 return;
2697
John McCall781472f2010-08-25 08:40:02 +00002698 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002699 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002700 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2701 Data.IntegralConstantExpression = true;
2702 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002703 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002704 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002705
2706 // Code-complete the cases of a switch statement over an enumeration type
2707 // by providing the list of
2708 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2709
2710 // Determine which enumerators we have already seen in the switch statement.
2711 // FIXME: Ideally, we would also be able to look *past* the code-completion
2712 // token, in case we are code-completing in the middle of the switch and not
2713 // at the end. However, we aren't able to do so at the moment.
2714 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002715 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002716 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2717 SC = SC->getNextSwitchCase()) {
2718 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2719 if (!Case)
2720 continue;
2721
2722 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2723 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2724 if (EnumConstantDecl *Enumerator
2725 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2726 // We look into the AST of the case statement to determine which
2727 // enumerator was named. Alternatively, we could compute the value of
2728 // the integral constant expression, then compare it against the
2729 // values of each enumerator. However, value-based approach would not
2730 // work as well with C++ templates where enumerators declared within a
2731 // template are type- and value-dependent.
2732 EnumeratorsSeen.insert(Enumerator);
2733
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002734 // If this is a qualified-id, keep track of the nested-name-specifier
2735 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002736 //
2737 // switch (TagD.getKind()) {
2738 // case TagDecl::TK_enum:
2739 // break;
2740 // case XXX
2741 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002742 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002743 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2744 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002745 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002746 }
2747 }
2748
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002749 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2750 // If there are no prior enumerators in C++, check whether we have to
2751 // qualify the names of the enumerators that we suggest, because they
2752 // may not be visible in this scope.
2753 Qualifier = getRequiredQualification(Context, CurContext,
2754 Enum->getDeclContext());
2755
2756 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2757 }
2758
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002759 // Add any enumerators that have not yet been mentioned.
2760 ResultBuilder Results(*this);
2761 Results.EnterNewScope();
2762 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2763 EEnd = Enum->enumerator_end();
2764 E != EEnd; ++E) {
2765 if (EnumeratorsSeen.count(*E))
2766 continue;
2767
John McCall0a2c5e22010-08-25 06:19:51 +00002768 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00002769 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002770 }
2771 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002772
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002773 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002774 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002775 HandleCodeCompleteResults(this, CodeCompleter,
2776 CodeCompletionContext::CCC_Expression,
2777 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002778}
2779
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002780namespace {
2781 struct IsBetterOverloadCandidate {
2782 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002783 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002784
2785 public:
John McCall5769d612010-02-08 23:07:23 +00002786 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2787 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002788
2789 bool
2790 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00002791 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002792 }
2793 };
2794}
2795
Douglas Gregord28dcd72010-05-30 06:10:08 +00002796static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2797 if (NumArgs && !Args)
2798 return true;
2799
2800 for (unsigned I = 0; I != NumArgs; ++I)
2801 if (!Args[I])
2802 return true;
2803
2804 return false;
2805}
2806
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002807void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2808 ExprTy **ArgsIn, unsigned NumArgs) {
2809 if (!CodeCompleter)
2810 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002811
2812 // When we're code-completing for a call, we fall back to ordinary
2813 // name code-completion whenever we can't produce specific
2814 // results. We may want to revisit this strategy in the future,
2815 // e.g., by merging the two kinds of results.
2816
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002817 Expr *Fn = (Expr *)FnIn;
2818 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002819
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002820 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00002821 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002822 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002823 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002824 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002825 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002826
John McCall3b4294e2009-12-16 12:17:52 +00002827 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002828 SourceLocation Loc = Fn->getExprLoc();
2829 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002830
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002831 // FIXME: What if we're calling something that isn't a function declaration?
2832 // FIXME: What if we're calling a pseudo-destructor?
2833 // FIXME: What if we're calling a member function?
2834
Douglas Gregorc0265402010-01-21 15:46:19 +00002835 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2836 llvm::SmallVector<ResultCandidate, 8> Results;
2837
John McCall3b4294e2009-12-16 12:17:52 +00002838 Expr *NakedFn = Fn->IgnoreParenCasts();
2839 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2840 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2841 /*PartialOverloading=*/ true);
2842 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2843 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002844 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00002845 if (!getLangOptions().CPlusPlus ||
2846 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00002847 Results.push_back(ResultCandidate(FDecl));
2848 else
John McCall86820f52010-01-26 01:37:31 +00002849 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002850 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2851 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002852 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002853 }
John McCall3b4294e2009-12-16 12:17:52 +00002854 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002855
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002856 QualType ParamType;
2857
Douglas Gregorc0265402010-01-21 15:46:19 +00002858 if (!CandidateSet.empty()) {
2859 // Sort the overload candidate set by placing the best overloads first.
2860 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002861 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002862
Douglas Gregorc0265402010-01-21 15:46:19 +00002863 // Add the remaining viable overload candidates as code-completion reslults.
2864 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2865 CandEnd = CandidateSet.end();
2866 Cand != CandEnd; ++Cand) {
2867 if (Cand->Viable)
2868 Results.push_back(ResultCandidate(Cand->Function));
2869 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002870
2871 // From the viable candidates, try to determine the type of this parameter.
2872 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2873 if (const FunctionType *FType = Results[I].getFunctionType())
2874 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2875 if (NumArgs < Proto->getNumArgs()) {
2876 if (ParamType.isNull())
2877 ParamType = Proto->getArgType(NumArgs);
2878 else if (!Context.hasSameUnqualifiedType(
2879 ParamType.getNonReferenceType(),
2880 Proto->getArgType(NumArgs).getNonReferenceType())) {
2881 ParamType = QualType();
2882 break;
2883 }
2884 }
2885 }
2886 } else {
2887 // Try to determine the parameter type from the type of the expression
2888 // being called.
2889 QualType FunctionType = Fn->getType();
2890 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2891 FunctionType = Ptr->getPointeeType();
2892 else if (const BlockPointerType *BlockPtr
2893 = FunctionType->getAs<BlockPointerType>())
2894 FunctionType = BlockPtr->getPointeeType();
2895 else if (const MemberPointerType *MemPtr
2896 = FunctionType->getAs<MemberPointerType>())
2897 FunctionType = MemPtr->getPointeeType();
2898
2899 if (const FunctionProtoType *Proto
2900 = FunctionType->getAs<FunctionProtoType>()) {
2901 if (NumArgs < Proto->getNumArgs())
2902 ParamType = Proto->getArgType(NumArgs);
2903 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002904 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002905
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002906 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002907 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002908 else
2909 CodeCompleteExpression(S, ParamType);
2910
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002911 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002912 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2913 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002914}
2915
John McCalld226f652010-08-21 09:40:31 +00002916void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2917 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002918 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002919 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002920 return;
2921 }
2922
2923 CodeCompleteExpression(S, VD->getType());
2924}
2925
2926void Sema::CodeCompleteReturn(Scope *S) {
2927 QualType ResultType;
2928 if (isa<BlockDecl>(CurContext)) {
2929 if (BlockScopeInfo *BSI = getCurBlock())
2930 ResultType = BSI->ReturnType;
2931 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2932 ResultType = Function->getResultType();
2933 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2934 ResultType = Method->getResultType();
2935
2936 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002937 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002938 else
2939 CodeCompleteExpression(S, ResultType);
2940}
2941
2942void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
2943 if (LHS)
2944 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
2945 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002946 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002947}
2948
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002949void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002950 bool EnteringContext) {
2951 if (!SS.getScopeRep() || !CodeCompleter)
2952 return;
2953
Douglas Gregor86d9a522009-09-21 16:56:56 +00002954 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2955 if (!Ctx)
2956 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002957
2958 // Try to instantiate any non-dependent declaration contexts before
2959 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00002960 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002961 return;
2962
Douglas Gregor86d9a522009-09-21 16:56:56 +00002963 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002964 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2965 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002966
2967 // The "template" keyword can follow "::" in the grammar, but only
2968 // put it into the grammar if the nested-name-specifier is dependent.
2969 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2970 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002971 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002972
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002973 HandleCodeCompleteResults(this, CodeCompleter,
2974 CodeCompletionContext::CCC_Other,
2975 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002976}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002977
2978void Sema::CodeCompleteUsing(Scope *S) {
2979 if (!CodeCompleter)
2980 return;
2981
Douglas Gregor86d9a522009-09-21 16:56:56 +00002982 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002983 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002984
2985 // If we aren't in class scope, we could see the "namespace" keyword.
2986 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00002987 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002988
2989 // After "using", we can see anything that would start a
2990 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002991 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002992 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2993 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002994 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002995
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002996 HandleCodeCompleteResults(this, CodeCompleter,
2997 CodeCompletionContext::CCC_Other,
2998 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002999}
3000
3001void Sema::CodeCompleteUsingDirective(Scope *S) {
3002 if (!CodeCompleter)
3003 return;
3004
Douglas Gregor86d9a522009-09-21 16:56:56 +00003005 // After "using namespace", we expect to see a namespace name or namespace
3006 // alias.
3007 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003008 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003009 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003010 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3011 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003012 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003013 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003014 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003015 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003016}
3017
3018void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3019 if (!CodeCompleter)
3020 return;
3021
Douglas Gregor86d9a522009-09-21 16:56:56 +00003022 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3023 DeclContext *Ctx = (DeclContext *)S->getEntity();
3024 if (!S->getParent())
3025 Ctx = Context.getTranslationUnitDecl();
3026
3027 if (Ctx && Ctx->isFileContext()) {
3028 // We only want to see those namespaces that have already been defined
3029 // within this scope, because its likely that the user is creating an
3030 // extended namespace declaration. Keep track of the most recent
3031 // definition of each namespace.
3032 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3033 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3034 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3035 NS != NSEnd; ++NS)
3036 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3037
3038 // Add the most recent definition (or extended definition) of each
3039 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003040 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003041 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3042 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3043 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003044 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003045 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003046 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003047 }
3048
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003049 HandleCodeCompleteResults(this, CodeCompleter,
3050 CodeCompletionContext::CCC_Other,
3051 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003052}
3053
3054void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3055 if (!CodeCompleter)
3056 return;
3057
Douglas Gregor86d9a522009-09-21 16:56:56 +00003058 // After "namespace", we expect to see a namespace or alias.
3059 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003060 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003061 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3062 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003063 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003064 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003065 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003066}
3067
Douglas Gregored8d3222009-09-18 20:05:18 +00003068void Sema::CodeCompleteOperatorName(Scope *S) {
3069 if (!CodeCompleter)
3070 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003071
John McCall0a2c5e22010-08-25 06:19:51 +00003072 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003073 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003074 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003075
Douglas Gregor86d9a522009-09-21 16:56:56 +00003076 // Add the names of overloadable operators.
3077#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3078 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003079 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003080#include "clang/Basic/OperatorKinds.def"
3081
3082 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003083 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003084 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003085 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3086 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003087
3088 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003089 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003090 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003091
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003092 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003093 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003094 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003095}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003096
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003097// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3098// true or false.
3099#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003100static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003101 ResultBuilder &Results,
3102 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003103 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003104 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003105 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003106
3107 CodeCompletionString *Pattern = 0;
3108 if (LangOpts.ObjC2) {
3109 // @dynamic
3110 Pattern = new CodeCompletionString;
3111 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3112 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3113 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003114 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003115
3116 // @synthesize
3117 Pattern = new CodeCompletionString;
3118 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3119 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3120 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003121 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003122 }
3123}
3124
Douglas Gregorbca403c2010-01-13 23:51:12 +00003125static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003126 ResultBuilder &Results,
3127 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003128 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003129
3130 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003131 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003132
3133 if (LangOpts.ObjC2) {
3134 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003135 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003136
3137 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003138 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003139
3140 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003141 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003142 }
3143}
3144
Douglas Gregorbca403c2010-01-13 23:51:12 +00003145static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003146 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003147 CodeCompletionString *Pattern = 0;
3148
3149 // @class name ;
3150 Pattern = new CodeCompletionString;
3151 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3152 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003153 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003154 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003155
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003156 if (Results.includeCodePatterns()) {
3157 // @interface name
3158 // FIXME: Could introduce the whole pattern, including superclasses and
3159 // such.
3160 Pattern = new CodeCompletionString;
3161 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3162 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3163 Pattern->AddPlaceholderChunk("class");
3164 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003165
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003166 // @protocol name
3167 Pattern = new CodeCompletionString;
3168 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3169 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3170 Pattern->AddPlaceholderChunk("protocol");
3171 Results.AddResult(Result(Pattern));
3172
3173 // @implementation name
3174 Pattern = new CodeCompletionString;
3175 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3176 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3177 Pattern->AddPlaceholderChunk("class");
3178 Results.AddResult(Result(Pattern));
3179 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003180
3181 // @compatibility_alias name
3182 Pattern = new CodeCompletionString;
3183 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3184 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3185 Pattern->AddPlaceholderChunk("alias");
3186 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3187 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003188 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003189}
3190
John McCalld226f652010-08-21 09:40:31 +00003191void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003192 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003193 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003194 ResultBuilder Results(*this);
3195 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003196 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003197 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003198 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003199 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003200 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003201 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003202 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003203 HandleCodeCompleteResults(this, CodeCompleter,
3204 CodeCompletionContext::CCC_Other,
3205 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003206}
3207
Douglas Gregorbca403c2010-01-13 23:51:12 +00003208static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003209 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003210 CodeCompletionString *Pattern = 0;
3211
3212 // @encode ( type-name )
3213 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003214 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003215 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3216 Pattern->AddPlaceholderChunk("type-name");
3217 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003218 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003219
3220 // @protocol ( protocol-name )
3221 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003222 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003223 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3224 Pattern->AddPlaceholderChunk("protocol-name");
3225 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003226 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003227
3228 // @selector ( selector )
3229 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003230 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003231 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3232 Pattern->AddPlaceholderChunk("selector");
3233 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003234 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003235}
3236
Douglas Gregorbca403c2010-01-13 23:51:12 +00003237static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003238 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003239 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003240
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003241 if (Results.includeCodePatterns()) {
3242 // @try { statements } @catch ( declaration ) { statements } @finally
3243 // { statements }
3244 Pattern = new CodeCompletionString;
3245 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3246 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3247 Pattern->AddPlaceholderChunk("statements");
3248 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3249 Pattern->AddTextChunk("@catch");
3250 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3251 Pattern->AddPlaceholderChunk("parameter");
3252 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3253 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3254 Pattern->AddPlaceholderChunk("statements");
3255 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3256 Pattern->AddTextChunk("@finally");
3257 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3258 Pattern->AddPlaceholderChunk("statements");
3259 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3260 Results.AddResult(Result(Pattern));
3261 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003262
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003263 // @throw
3264 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003265 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003266 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003267 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003268 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003269
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003270 if (Results.includeCodePatterns()) {
3271 // @synchronized ( expression ) { statements }
3272 Pattern = new CodeCompletionString;
3273 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3274 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3275 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3276 Pattern->AddPlaceholderChunk("expression");
3277 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3278 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3279 Pattern->AddPlaceholderChunk("statements");
3280 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3281 Results.AddResult(Result(Pattern));
3282 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003283}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003284
Douglas Gregorbca403c2010-01-13 23:51:12 +00003285static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003286 ResultBuilder &Results,
3287 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003288 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003289 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3290 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3291 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003292 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003293 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003294}
3295
3296void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3297 ResultBuilder Results(*this);
3298 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003299 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003300 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003301 HandleCodeCompleteResults(this, CodeCompleter,
3302 CodeCompletionContext::CCC_Other,
3303 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003304}
3305
3306void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003307 ResultBuilder Results(*this);
3308 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003309 AddObjCStatementResults(Results, false);
3310 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003311 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003312 HandleCodeCompleteResults(this, CodeCompleter,
3313 CodeCompletionContext::CCC_Other,
3314 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003315}
3316
3317void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3318 ResultBuilder Results(*this);
3319 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003320 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003321 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003322 HandleCodeCompleteResults(this, CodeCompleter,
3323 CodeCompletionContext::CCC_Other,
3324 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003325}
3326
Douglas Gregor988358f2009-11-19 00:14:45 +00003327/// \brief Determine whether the addition of the given flag to an Objective-C
3328/// property's attributes will cause a conflict.
3329static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3330 // Check if we've already added this flag.
3331 if (Attributes & NewFlag)
3332 return true;
3333
3334 Attributes |= NewFlag;
3335
3336 // Check for collisions with "readonly".
3337 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3338 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3339 ObjCDeclSpec::DQ_PR_assign |
3340 ObjCDeclSpec::DQ_PR_copy |
3341 ObjCDeclSpec::DQ_PR_retain)))
3342 return true;
3343
3344 // Check for more than one of { assign, copy, retain }.
3345 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3346 ObjCDeclSpec::DQ_PR_copy |
3347 ObjCDeclSpec::DQ_PR_retain);
3348 if (AssignCopyRetMask &&
3349 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3350 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3351 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3352 return true;
3353
3354 return false;
3355}
3356
Douglas Gregora93b1082009-11-18 23:08:07 +00003357void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003358 if (!CodeCompleter)
3359 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003360
Steve Naroffece8e712009-10-08 21:55:05 +00003361 unsigned Attributes = ODS.getPropertyAttributes();
3362
John McCall0a2c5e22010-08-25 06:19:51 +00003363 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003364 ResultBuilder Results(*this);
3365 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003366 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003367 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003368 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003369 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003370 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003371 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003372 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003373 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003374 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003375 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003376 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003377 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003378 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003379 CodeCompletionString *Setter = new CodeCompletionString;
3380 Setter->AddTypedTextChunk("setter");
3381 Setter->AddTextChunk(" = ");
3382 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003383 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003384 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003385 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003386 CodeCompletionString *Getter = new CodeCompletionString;
3387 Getter->AddTypedTextChunk("getter");
3388 Getter->AddTextChunk(" = ");
3389 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003390 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003391 }
Steve Naroffece8e712009-10-08 21:55:05 +00003392 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003393 HandleCodeCompleteResults(this, CodeCompleter,
3394 CodeCompletionContext::CCC_Other,
3395 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003396}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003397
Douglas Gregor4ad96852009-11-19 07:41:15 +00003398/// \brief Descripts the kind of Objective-C method that we want to find
3399/// via code completion.
3400enum ObjCMethodKind {
3401 MK_Any, //< Any kind of method, provided it means other specified criteria.
3402 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3403 MK_OneArgSelector //< One-argument selector.
3404};
3405
3406static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3407 ObjCMethodKind WantKind,
3408 IdentifierInfo **SelIdents,
3409 unsigned NumSelIdents) {
3410 Selector Sel = Method->getSelector();
3411 if (NumSelIdents > Sel.getNumArgs())
3412 return false;
3413
3414 switch (WantKind) {
3415 case MK_Any: break;
3416 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3417 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3418 }
3419
3420 for (unsigned I = 0; I != NumSelIdents; ++I)
3421 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3422 return false;
3423
3424 return true;
3425}
3426
Douglas Gregor36ecb042009-11-17 23:22:23 +00003427/// \brief Add all of the Objective-C methods in the given Objective-C
3428/// container to the set of results.
3429///
3430/// The container will be a class, protocol, category, or implementation of
3431/// any of the above. This mether will recurse to include methods from
3432/// the superclasses of classes along with their categories, protocols, and
3433/// implementations.
3434///
3435/// \param Container the container in which we'll look to find methods.
3436///
3437/// \param WantInstance whether to add instance methods (only); if false, this
3438/// routine will add factory methods (only).
3439///
3440/// \param CurContext the context in which we're performing the lookup that
3441/// finds methods.
3442///
3443/// \param Results the structure into which we'll add results.
3444static void AddObjCMethods(ObjCContainerDecl *Container,
3445 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003446 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003447 IdentifierInfo **SelIdents,
3448 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003449 DeclContext *CurContext,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003450 ResultBuilder &Results,
3451 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003452 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003453 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3454 MEnd = Container->meth_end();
3455 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003456 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3457 // Check whether the selector identifiers we've been given are a
3458 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003459 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003460 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003461
Douglas Gregord3c68542009-11-19 01:08:35 +00003462 Result R = Result(*M, 0);
3463 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003464 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003465 if (!InOriginalClass)
3466 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003467 Results.MaybeAddResult(R, CurContext);
3468 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003469 }
3470
3471 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3472 if (!IFace)
3473 return;
3474
3475 // Add methods in protocols.
3476 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3477 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3478 E = Protocols.end();
3479 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003480 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003481 CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003482
3483 // Add methods in categories.
3484 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3485 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003486 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003487 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003488
3489 // Add a categories protocol methods.
3490 const ObjCList<ObjCProtocolDecl> &Protocols
3491 = CatDecl->getReferencedProtocols();
3492 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3493 E = Protocols.end();
3494 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003495 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003496 NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003497
3498 // Add methods in category implementations.
3499 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003500 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003501 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003502 }
3503
3504 // Add methods in superclass.
3505 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003506 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003507 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003508
3509 // Add methods in our implementation, if any.
3510 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003511 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003512 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003513}
3514
3515
John McCalld226f652010-08-21 09:40:31 +00003516void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3517 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003518 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003519 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003520
3521 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003522 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003523 if (!Class) {
3524 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003525 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003526 Class = Category->getClassInterface();
3527
3528 if (!Class)
3529 return;
3530 }
3531
3532 // Find all of the potential getters.
3533 ResultBuilder Results(*this);
3534 Results.EnterNewScope();
3535
3536 // FIXME: We need to do this because Objective-C methods don't get
3537 // pushed into DeclContexts early enough. Argh!
3538 for (unsigned I = 0; I != NumMethods; ++I) {
3539 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003540 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003541 if (Method->isInstanceMethod() &&
3542 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3543 Result R = Result(Method, 0);
3544 R.AllParametersAreInformative = true;
3545 Results.MaybeAddResult(R, CurContext);
3546 }
3547 }
3548
3549 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3550 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003551 HandleCodeCompleteResults(this, CodeCompleter,
3552 CodeCompletionContext::CCC_Other,
3553 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003554}
3555
John McCalld226f652010-08-21 09:40:31 +00003556void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3557 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003558 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003559 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003560
3561 // Try to find the interface where setters might live.
3562 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003563 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003564 if (!Class) {
3565 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003566 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003567 Class = Category->getClassInterface();
3568
3569 if (!Class)
3570 return;
3571 }
3572
3573 // Find all of the potential getters.
3574 ResultBuilder Results(*this);
3575 Results.EnterNewScope();
3576
3577 // FIXME: We need to do this because Objective-C methods don't get
3578 // pushed into DeclContexts early enough. Argh!
3579 for (unsigned I = 0; I != NumMethods; ++I) {
3580 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003581 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003582 if (Method->isInstanceMethod() &&
3583 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3584 Result R = Result(Method, 0);
3585 R.AllParametersAreInformative = true;
3586 Results.MaybeAddResult(R, CurContext);
3587 }
3588 }
3589
3590 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3591
3592 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003593 HandleCodeCompleteResults(this, CodeCompleter,
3594 CodeCompletionContext::CCC_Other,
3595 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003596}
3597
Douglas Gregord32b0222010-08-24 01:06:58 +00003598void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00003599 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00003600 ResultBuilder Results(*this);
3601 Results.EnterNewScope();
3602
3603 // Add context-sensitive, Objective-C parameter-passing keywords.
3604 bool AddedInOut = false;
3605 if ((DS.getObjCDeclQualifier() &
3606 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3607 Results.AddResult("in");
3608 Results.AddResult("inout");
3609 AddedInOut = true;
3610 }
3611 if ((DS.getObjCDeclQualifier() &
3612 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3613 Results.AddResult("out");
3614 if (!AddedInOut)
3615 Results.AddResult("inout");
3616 }
3617 if ((DS.getObjCDeclQualifier() &
3618 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3619 ObjCDeclSpec::DQ_Oneway)) == 0) {
3620 Results.AddResult("bycopy");
3621 Results.AddResult("byref");
3622 Results.AddResult("oneway");
3623 }
3624
3625 // Add various builtin type names and specifiers.
3626 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3627 Results.ExitScope();
3628
3629 // Add the various type names
3630 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3631 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3632 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3633 CodeCompleter->includeGlobals());
3634
3635 if (CodeCompleter->includeMacros())
3636 AddMacroResults(PP, Results);
3637
3638 HandleCodeCompleteResults(this, CodeCompleter,
3639 CodeCompletionContext::CCC_Type,
3640 Results.data(), Results.size());
3641}
3642
Douglas Gregor22f56992010-04-06 19:22:33 +00003643/// \brief When we have an expression with type "id", we may assume
3644/// that it has some more-specific class type based on knowledge of
3645/// common uses of Objective-C. This routine returns that class type,
3646/// or NULL if no better result could be determined.
3647static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3648 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3649 if (!Msg)
3650 return 0;
3651
3652 Selector Sel = Msg->getSelector();
3653 if (Sel.isNull())
3654 return 0;
3655
3656 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3657 if (!Id)
3658 return 0;
3659
3660 ObjCMethodDecl *Method = Msg->getMethodDecl();
3661 if (!Method)
3662 return 0;
3663
3664 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003665 ObjCInterfaceDecl *IFace = 0;
3666 switch (Msg->getReceiverKind()) {
3667 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003668 if (const ObjCObjectType *ObjType
3669 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3670 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003671 break;
3672
3673 case ObjCMessageExpr::Instance: {
3674 QualType T = Msg->getInstanceReceiver()->getType();
3675 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3676 IFace = Ptr->getInterfaceDecl();
3677 break;
3678 }
3679
3680 case ObjCMessageExpr::SuperInstance:
3681 case ObjCMessageExpr::SuperClass:
3682 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003683 }
3684
3685 if (!IFace)
3686 return 0;
3687
3688 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3689 if (Method->isInstanceMethod())
3690 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3691 .Case("retain", IFace)
3692 .Case("autorelease", IFace)
3693 .Case("copy", IFace)
3694 .Case("copyWithZone", IFace)
3695 .Case("mutableCopy", IFace)
3696 .Case("mutableCopyWithZone", IFace)
3697 .Case("awakeFromCoder", IFace)
3698 .Case("replacementObjectFromCoder", IFace)
3699 .Case("class", IFace)
3700 .Case("classForCoder", IFace)
3701 .Case("superclass", Super)
3702 .Default(0);
3703
3704 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3705 .Case("new", IFace)
3706 .Case("alloc", IFace)
3707 .Case("allocWithZone", IFace)
3708 .Case("class", IFace)
3709 .Case("superclass", Super)
3710 .Default(0);
3711}
3712
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003713void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00003714 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003715 ResultBuilder Results(*this);
3716
3717 // Find anything that looks like it could be a message receiver.
3718 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3719 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3720 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00003721 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3722 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003723
3724 // If we are in an Objective-C method inside a class that has a superclass,
3725 // add "super" as an option.
3726 if (ObjCMethodDecl *Method = getCurMethodDecl())
3727 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3728 if (Iface->getSuperClass())
3729 Results.AddResult(Result("super"));
3730
3731 Results.ExitScope();
3732
3733 if (CodeCompleter->includeMacros())
3734 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003735 HandleCodeCompleteResults(this, CodeCompleter,
3736 CodeCompletionContext::CCC_ObjCMessageReceiver,
3737 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003738
3739}
3740
Douglas Gregor2725ca82010-04-21 19:57:20 +00003741void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3742 IdentifierInfo **SelIdents,
3743 unsigned NumSelIdents) {
3744 ObjCInterfaceDecl *CDecl = 0;
3745 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3746 // Figure out which interface we're in.
3747 CDecl = CurMethod->getClassInterface();
3748 if (!CDecl)
3749 return;
3750
3751 // Find the superclass of this class.
3752 CDecl = CDecl->getSuperClass();
3753 if (!CDecl)
3754 return;
3755
3756 if (CurMethod->isInstanceMethod()) {
3757 // We are inside an instance method, which means that the message
3758 // send [super ...] is actually calling an instance method on the
3759 // current object. Build the super expression and handle this like
3760 // an instance method.
3761 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3762 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00003763 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00003764 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3765 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3766 SelIdents, NumSelIdents);
3767 }
3768
3769 // Fall through to send to the superclass in CDecl.
3770 } else {
3771 // "super" may be the name of a type or variable. Figure out which
3772 // it is.
3773 IdentifierInfo *Super = &Context.Idents.get("super");
3774 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3775 LookupOrdinaryName);
3776 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3777 // "super" names an interface. Use it.
3778 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003779 if (const ObjCObjectType *Iface
3780 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3781 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003782 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3783 // "super" names an unresolved type; we can't be more specific.
3784 } else {
3785 // Assume that "super" names some kind of value and parse that way.
3786 CXXScopeSpec SS;
3787 UnqualifiedId id;
3788 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00003789 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003790 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3791 SelIdents, NumSelIdents);
3792 }
3793
3794 // Fall through
3795 }
3796
John McCallb3d87482010-08-24 05:47:05 +00003797 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00003798 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00003799 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00003800 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3801 NumSelIdents);
3802}
3803
John McCallb3d87482010-08-24 05:47:05 +00003804void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003805 IdentifierInfo **SelIdents,
3806 unsigned NumSelIdents) {
John McCall0a2c5e22010-08-25 06:19:51 +00003807 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003808 ObjCInterfaceDecl *CDecl = 0;
3809
Douglas Gregor24a069f2009-11-17 17:59:40 +00003810 // If the given name refers to an interface type, retrieve the
3811 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003812 if (Receiver) {
3813 QualType T = GetTypeFromParser(Receiver, 0);
3814 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003815 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3816 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003817 }
3818
Douglas Gregor36ecb042009-11-17 23:22:23 +00003819 // Add all of the factory methods in this Objective-C class, its protocols,
3820 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003821 ResultBuilder Results(*this);
3822 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003823
3824 if (CDecl)
3825 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3826 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003827 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003828 // We're messaging "id" as a type; provide all class/factory methods.
3829
Douglas Gregor719770d2010-04-06 17:30:22 +00003830 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003831 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003832 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003833 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3834 I != N; ++I) {
3835 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003836 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003837 continue;
3838
Sebastian Redldb9d2142010-08-02 23:18:59 +00003839 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003840 }
3841 }
3842
Sebastian Redldb9d2142010-08-02 23:18:59 +00003843 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3844 MEnd = MethodPool.end();
3845 M != MEnd; ++M) {
3846 for (ObjCMethodList *MethList = &M->second.second;
3847 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003848 MethList = MethList->Next) {
3849 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3850 NumSelIdents))
3851 continue;
3852
3853 Result R(MethList->Method, 0);
3854 R.StartParameter = NumSelIdents;
3855 R.AllParametersAreInformative = false;
3856 Results.MaybeAddResult(R, CurContext);
3857 }
3858 }
3859 }
3860
Steve Naroffc4df6d22009-11-07 02:08:14 +00003861 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003862 HandleCodeCompleteResults(this, CodeCompleter,
3863 CodeCompletionContext::CCC_Other,
3864 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003865}
3866
Douglas Gregord3c68542009-11-19 01:08:35 +00003867void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3868 IdentifierInfo **SelIdents,
3869 unsigned NumSelIdents) {
John McCall0a2c5e22010-08-25 06:19:51 +00003870 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003871
3872 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003873
Douglas Gregor36ecb042009-11-17 23:22:23 +00003874 // If necessary, apply function/array conversion to the receiver.
3875 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003876 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003877 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003878
Douglas Gregor36ecb042009-11-17 23:22:23 +00003879 // Build the set of methods we can see.
3880 ResultBuilder Results(*this);
3881 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003882
3883 // If we're messaging an expression with type "id" or "Class", check
3884 // whether we know something special about the receiver that allows
3885 // us to assume a more-specific receiver type.
3886 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3887 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3888 ReceiverType = Context.getObjCObjectPointerType(
3889 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003890
Douglas Gregorf74a4192009-11-18 00:06:18 +00003891 // Handle messages to Class. This really isn't a message to an instance
3892 // method, so we treat it the same way we would treat a message send to a
3893 // class method.
3894 if (ReceiverType->isObjCClassType() ||
3895 ReceiverType->isObjCQualifiedClassType()) {
3896 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3897 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003898 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3899 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003900 }
3901 }
3902 // Handle messages to a qualified ID ("id<foo>").
3903 else if (const ObjCObjectPointerType *QualID
3904 = ReceiverType->getAsObjCQualifiedIdType()) {
3905 // Search protocols for instance methods.
3906 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3907 E = QualID->qual_end();
3908 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003909 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3910 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003911 }
3912 // Handle messages to a pointer to interface type.
3913 else if (const ObjCObjectPointerType *IFacePtr
3914 = ReceiverType->getAsObjCInterfacePointerType()) {
3915 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003916 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3917 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003918
3919 // Search protocols for instance methods.
3920 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3921 E = IFacePtr->qual_end();
3922 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003923 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3924 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003925 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003926 // Handle messages to "id".
3927 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003928 // We're messaging "id", so provide all instance methods we know
3929 // about as code-completion results.
3930
3931 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003932 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003933 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003934 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3935 I != N; ++I) {
3936 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003937 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003938 continue;
3939
Sebastian Redldb9d2142010-08-02 23:18:59 +00003940 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003941 }
3942 }
3943
Sebastian Redldb9d2142010-08-02 23:18:59 +00003944 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3945 MEnd = MethodPool.end();
3946 M != MEnd; ++M) {
3947 for (ObjCMethodList *MethList = &M->second.first;
3948 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003949 MethList = MethList->Next) {
3950 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3951 NumSelIdents))
3952 continue;
3953
3954 Result R(MethList->Method, 0);
3955 R.StartParameter = NumSelIdents;
3956 R.AllParametersAreInformative = false;
3957 Results.MaybeAddResult(R, CurContext);
3958 }
3959 }
3960 }
3961
Steve Naroffc4df6d22009-11-07 02:08:14 +00003962 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003963 HandleCodeCompleteResults(this, CodeCompleter,
3964 CodeCompletionContext::CCC_Other,
3965 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003966}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003967
Douglas Gregorfb629412010-08-23 21:17:50 +00003968void Sema::CodeCompleteObjCForCollection(Scope *S,
3969 DeclGroupPtrTy IterationVar) {
3970 CodeCompleteExpressionData Data;
3971 Data.ObjCCollection = true;
3972
3973 if (IterationVar.getAsOpaquePtr()) {
3974 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
3975 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
3976 if (*I)
3977 Data.IgnoreDecls.push_back(*I);
3978 }
3979 }
3980
3981 CodeCompleteExpression(S, Data);
3982}
3983
Douglas Gregor55385fe2009-11-18 04:19:12 +00003984/// \brief Add all of the protocol declarations that we find in the given
3985/// (translation unit) context.
3986static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003987 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003988 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00003989 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00003990
3991 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3992 DEnd = Ctx->decls_end();
3993 D != DEnd; ++D) {
3994 // Record any protocols we find.
3995 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003996 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003997 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003998
3999 // Record any forward-declared protocols we find.
4000 if (ObjCForwardProtocolDecl *Forward
4001 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4002 for (ObjCForwardProtocolDecl::protocol_iterator
4003 P = Forward->protocol_begin(),
4004 PEnd = Forward->protocol_end();
4005 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004006 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004007 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004008 }
4009 }
4010}
4011
4012void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4013 unsigned NumProtocols) {
4014 ResultBuilder Results(*this);
4015 Results.EnterNewScope();
4016
4017 // Tell the result set to ignore all of the protocols we have
4018 // already seen.
4019 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004020 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4021 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004022 Results.Ignore(Protocol);
4023
4024 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004025 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4026 Results);
4027
4028 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004029 HandleCodeCompleteResults(this, CodeCompleter,
4030 CodeCompletionContext::CCC_ObjCProtocolName,
4031 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004032}
4033
4034void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4035 ResultBuilder Results(*this);
4036 Results.EnterNewScope();
4037
4038 // Add all protocols.
4039 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4040 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004041
4042 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004043 HandleCodeCompleteResults(this, CodeCompleter,
4044 CodeCompletionContext::CCC_ObjCProtocolName,
4045 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004046}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004047
4048/// \brief Add all of the Objective-C interface declarations that we find in
4049/// the given (translation unit) context.
4050static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4051 bool OnlyForwardDeclarations,
4052 bool OnlyUnimplemented,
4053 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004054 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004055
4056 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4057 DEnd = Ctx->decls_end();
4058 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004059 // Record any interfaces we find.
4060 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4061 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4062 (!OnlyUnimplemented || !Class->getImplementation()))
4063 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004064
4065 // Record any forward-declared interfaces we find.
4066 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4067 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004068 C != CEnd; ++C)
4069 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4070 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4071 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004072 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004073 }
4074 }
4075}
4076
4077void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4078 ResultBuilder Results(*this);
4079 Results.EnterNewScope();
4080
4081 // Add all classes.
4082 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4083 false, Results);
4084
4085 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004086 HandleCodeCompleteResults(this, CodeCompleter,
4087 CodeCompletionContext::CCC_Other,
4088 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004089}
4090
Douglas Gregorc83c6872010-04-15 22:33:43 +00004091void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4092 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004093 ResultBuilder Results(*this);
4094 Results.EnterNewScope();
4095
4096 // Make sure that we ignore the class we're currently defining.
4097 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004098 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004099 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004100 Results.Ignore(CurClass);
4101
4102 // Add all classes.
4103 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4104 false, Results);
4105
4106 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004107 HandleCodeCompleteResults(this, CodeCompleter,
4108 CodeCompletionContext::CCC_Other,
4109 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004110}
4111
4112void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4113 ResultBuilder Results(*this);
4114 Results.EnterNewScope();
4115
4116 // Add all unimplemented classes.
4117 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4118 true, Results);
4119
4120 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004121 HandleCodeCompleteResults(this, CodeCompleter,
4122 CodeCompletionContext::CCC_Other,
4123 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004124}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004125
4126void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004127 IdentifierInfo *ClassName,
4128 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004129 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004130
4131 ResultBuilder Results(*this);
4132
4133 // Ignore any categories we find that have already been implemented by this
4134 // interface.
4135 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4136 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004137 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004138 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4139 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4140 Category = Category->getNextClassCategory())
4141 CategoryNames.insert(Category->getIdentifier());
4142
4143 // Add all of the categories we know about.
4144 Results.EnterNewScope();
4145 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4146 for (DeclContext::decl_iterator D = TU->decls_begin(),
4147 DEnd = TU->decls_end();
4148 D != DEnd; ++D)
4149 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4150 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004151 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004152 Results.ExitScope();
4153
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004154 HandleCodeCompleteResults(this, CodeCompleter,
4155 CodeCompletionContext::CCC_Other,
4156 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004157}
4158
4159void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004160 IdentifierInfo *ClassName,
4161 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004162 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004163
4164 // Find the corresponding interface. If we couldn't find the interface, the
4165 // program itself is ill-formed. However, we'll try to be helpful still by
4166 // providing the list of all of the categories we know about.
4167 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004168 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004169 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4170 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004171 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004172
4173 ResultBuilder Results(*this);
4174
4175 // Add all of the categories that have have corresponding interface
4176 // declarations in this class and any of its superclasses, except for
4177 // already-implemented categories in the class itself.
4178 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4179 Results.EnterNewScope();
4180 bool IgnoreImplemented = true;
4181 while (Class) {
4182 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4183 Category = Category->getNextClassCategory())
4184 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4185 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004186 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004187
4188 Class = Class->getSuperClass();
4189 IgnoreImplemented = false;
4190 }
4191 Results.ExitScope();
4192
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004193 HandleCodeCompleteResults(this, CodeCompleter,
4194 CodeCompletionContext::CCC_Other,
4195 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004196}
Douglas Gregor322328b2009-11-18 22:32:06 +00004197
John McCalld226f652010-08-21 09:40:31 +00004198void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004199 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004200 ResultBuilder Results(*this);
4201
4202 // Figure out where this @synthesize lives.
4203 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004204 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004205 if (!Container ||
4206 (!isa<ObjCImplementationDecl>(Container) &&
4207 !isa<ObjCCategoryImplDecl>(Container)))
4208 return;
4209
4210 // Ignore any properties that have already been implemented.
4211 for (DeclContext::decl_iterator D = Container->decls_begin(),
4212 DEnd = Container->decls_end();
4213 D != DEnd; ++D)
4214 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4215 Results.Ignore(PropertyImpl->getPropertyDecl());
4216
4217 // Add any properties that we find.
4218 Results.EnterNewScope();
4219 if (ObjCImplementationDecl *ClassImpl
4220 = dyn_cast<ObjCImplementationDecl>(Container))
4221 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4222 Results);
4223 else
4224 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4225 false, CurContext, Results);
4226 Results.ExitScope();
4227
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004228 HandleCodeCompleteResults(this, CodeCompleter,
4229 CodeCompletionContext::CCC_Other,
4230 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004231}
4232
4233void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4234 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004235 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004236 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004237 ResultBuilder Results(*this);
4238
4239 // Figure out where this @synthesize lives.
4240 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004241 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004242 if (!Container ||
4243 (!isa<ObjCImplementationDecl>(Container) &&
4244 !isa<ObjCCategoryImplDecl>(Container)))
4245 return;
4246
4247 // Figure out which interface we're looking into.
4248 ObjCInterfaceDecl *Class = 0;
4249 if (ObjCImplementationDecl *ClassImpl
4250 = dyn_cast<ObjCImplementationDecl>(Container))
4251 Class = ClassImpl->getClassInterface();
4252 else
4253 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4254 ->getClassInterface();
4255
4256 // Add all of the instance variables in this class and its superclasses.
4257 Results.EnterNewScope();
4258 for(; Class; Class = Class->getSuperClass()) {
4259 // FIXME: We could screen the type of each ivar for compatibility with
4260 // the property, but is that being too paternal?
4261 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4262 IVarEnd = Class->ivar_end();
4263 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004264 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004265 }
4266 Results.ExitScope();
4267
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004268 HandleCodeCompleteResults(this, CodeCompleter,
4269 CodeCompletionContext::CCC_Other,
4270 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004271}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004272
Douglas Gregor408be5a2010-08-25 01:08:01 +00004273// Mapping from selectors to the methods that implement that selector, along
4274// with the "in original class" flag.
4275typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4276 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004277
4278/// \brief Find all of the methods that reside in the given container
4279/// (and its superclasses, protocols, etc.) that meet the given
4280/// criteria. Insert those methods into the map of known methods,
4281/// indexed by selector so they can be easily found.
4282static void FindImplementableMethods(ASTContext &Context,
4283 ObjCContainerDecl *Container,
4284 bool WantInstanceMethods,
4285 QualType ReturnType,
4286 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004287 KnownMethodsMap &KnownMethods,
4288 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004289 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4290 // Recurse into protocols.
4291 const ObjCList<ObjCProtocolDecl> &Protocols
4292 = IFace->getReferencedProtocols();
4293 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4294 E = Protocols.end();
4295 I != E; ++I)
4296 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004297 IsInImplementation, KnownMethods,
4298 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004299
4300 // If we're not in the implementation of a class, also visit the
4301 // superclass.
4302 if (!IsInImplementation && IFace->getSuperClass())
4303 FindImplementableMethods(Context, IFace->getSuperClass(),
4304 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004305 IsInImplementation, KnownMethods,
4306 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004307
4308 // Add methods from any class extensions (but not from categories;
4309 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004310 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4311 Cat = Cat->getNextClassExtension())
4312 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4313 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004314 IsInImplementation, KnownMethods,
4315 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004316 }
4317
4318 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4319 // Recurse into protocols.
4320 const ObjCList<ObjCProtocolDecl> &Protocols
4321 = Category->getReferencedProtocols();
4322 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4323 E = Protocols.end();
4324 I != E; ++I)
4325 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004326 IsInImplementation, KnownMethods,
4327 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004328 }
4329
4330 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4331 // Recurse into protocols.
4332 const ObjCList<ObjCProtocolDecl> &Protocols
4333 = Protocol->getReferencedProtocols();
4334 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4335 E = Protocols.end();
4336 I != E; ++I)
4337 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004338 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004339 }
4340
4341 // Add methods in this container. This operation occurs last because
4342 // we want the methods from this container to override any methods
4343 // we've previously seen with the same selector.
4344 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4345 MEnd = Container->meth_end();
4346 M != MEnd; ++M) {
4347 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4348 if (!ReturnType.isNull() &&
4349 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4350 continue;
4351
Douglas Gregor408be5a2010-08-25 01:08:01 +00004352 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004353 }
4354 }
4355}
4356
4357void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4358 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004359 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004360 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004361 // Determine the return type of the method we're declaring, if
4362 // provided.
4363 QualType ReturnType = GetTypeFromParser(ReturnTy);
4364
4365 // Determine where we should start searching for methods, and where we
4366 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4367 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004368 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004369 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4370 SearchDecl = Impl->getClassInterface();
4371 CurrentDecl = Impl;
4372 IsInImplementation = true;
4373 } else if (ObjCCategoryImplDecl *CatImpl
4374 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4375 SearchDecl = CatImpl->getCategoryDecl();
4376 CurrentDecl = CatImpl;
4377 IsInImplementation = true;
4378 } else {
4379 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4380 CurrentDecl = SearchDecl;
4381 }
4382 }
4383
4384 if (!SearchDecl && S) {
4385 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4386 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4387 CurrentDecl = SearchDecl;
4388 }
4389 }
4390
4391 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004392 HandleCodeCompleteResults(this, CodeCompleter,
4393 CodeCompletionContext::CCC_Other,
4394 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004395 return;
4396 }
4397
4398 // Find all of the methods that we could declare/implement here.
4399 KnownMethodsMap KnownMethods;
4400 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4401 ReturnType, IsInImplementation, KnownMethods);
4402
4403 // Erase any methods that have already been declared or
4404 // implemented here.
4405 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4406 MEnd = CurrentDecl->meth_end();
4407 M != MEnd; ++M) {
4408 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4409 continue;
4410
4411 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4412 if (Pos != KnownMethods.end())
4413 KnownMethods.erase(Pos);
4414 }
4415
4416 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00004417 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004418 ResultBuilder Results(*this);
4419 Results.EnterNewScope();
4420 PrintingPolicy Policy(Context.PrintingPolicy);
4421 Policy.AnonymousTagLocations = false;
4422 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4423 MEnd = KnownMethods.end();
4424 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00004425 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004426 CodeCompletionString *Pattern = new CodeCompletionString;
4427
4428 // If the result type was not already provided, add it to the
4429 // pattern as (type).
4430 if (ReturnType.isNull()) {
4431 std::string TypeStr;
4432 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4433 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4434 Pattern->AddTextChunk(TypeStr);
4435 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4436 }
4437
4438 Selector Sel = Method->getSelector();
4439
4440 // Add the first part of the selector to the pattern.
4441 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4442
4443 // Add parameters to the pattern.
4444 unsigned I = 0;
4445 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4446 PEnd = Method->param_end();
4447 P != PEnd; (void)++P, ++I) {
4448 // Add the part of the selector name.
4449 if (I == 0)
4450 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4451 else if (I < Sel.getNumArgs()) {
4452 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00004453 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004454 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4455 } else
4456 break;
4457
4458 // Add the parameter type.
4459 std::string TypeStr;
4460 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4461 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4462 Pattern->AddTextChunk(TypeStr);
4463 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4464
4465 if (IdentifierInfo *Id = (*P)->getIdentifier())
4466 Pattern->AddTextChunk(Id->getName());
4467 }
4468
4469 if (Method->isVariadic()) {
4470 if (Method->param_size() > 0)
4471 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4472 Pattern->AddTextChunk("...");
4473 }
4474
Douglas Gregor447107d2010-05-28 00:57:46 +00004475 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004476 // We will be defining the method here, so add a compound statement.
4477 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4478 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4479 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4480 if (!Method->getResultType()->isVoidType()) {
4481 // If the result type is not void, add a return clause.
4482 Pattern->AddTextChunk("return");
4483 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4484 Pattern->AddPlaceholderChunk("expression");
4485 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4486 } else
4487 Pattern->AddPlaceholderChunk("statements");
4488
4489 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4490 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4491 }
4492
Douglas Gregor408be5a2010-08-25 01:08:01 +00004493 unsigned Priority = CCP_CodePattern;
4494 if (!M->second.second)
4495 Priority += CCD_InBaseClass;
4496
4497 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00004498 Method->isInstanceMethod()
4499 ? CXCursor_ObjCInstanceMethodDecl
4500 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00004501 }
4502
4503 Results.ExitScope();
4504
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004505 HandleCodeCompleteResults(this, CodeCompleter,
4506 CodeCompletionContext::CCC_Other,
4507 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004508}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004509
4510void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4511 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004512 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00004513 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004514 IdentifierInfo **SelIdents,
4515 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004516 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004517 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004518 if (ExternalSource) {
4519 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4520 I != N; ++I) {
4521 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004522 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004523 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00004524
4525 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004526 }
4527 }
4528
4529 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00004530 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004531 ResultBuilder Results(*this);
4532
4533 if (ReturnTy)
4534 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00004535
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004536 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004537 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4538 MEnd = MethodPool.end();
4539 M != MEnd; ++M) {
4540 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4541 &M->second.second;
4542 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004543 MethList = MethList->Next) {
4544 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4545 NumSelIdents))
4546 continue;
4547
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004548 if (AtParameterName) {
4549 // Suggest parameter names we've seen before.
4550 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4551 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4552 if (Param->getIdentifier()) {
4553 CodeCompletionString *Pattern = new CodeCompletionString;
4554 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4555 Results.AddResult(Pattern);
4556 }
4557 }
4558
4559 continue;
4560 }
4561
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004562 Result R(MethList->Method, 0);
4563 R.StartParameter = NumSelIdents;
4564 R.AllParametersAreInformative = false;
4565 R.DeclaringEntity = true;
4566 Results.MaybeAddResult(R, CurContext);
4567 }
4568 }
4569
4570 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004571 HandleCodeCompleteResults(this, CodeCompleter,
4572 CodeCompletionContext::CCC_Other,
4573 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004574}
Douglas Gregor87c08a52010-08-13 22:48:40 +00004575
Douglas Gregorf29c5232010-08-24 22:20:20 +00004576void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00004577 ResultBuilder Results(*this);
4578 Results.EnterNewScope();
4579
4580 // #if <condition>
4581 CodeCompletionString *Pattern = new CodeCompletionString;
4582 Pattern->AddTypedTextChunk("if");
4583 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4584 Pattern->AddPlaceholderChunk("condition");
4585 Results.AddResult(Pattern);
4586
4587 // #ifdef <macro>
4588 Pattern = new CodeCompletionString;
4589 Pattern->AddTypedTextChunk("ifdef");
4590 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4591 Pattern->AddPlaceholderChunk("macro");
4592 Results.AddResult(Pattern);
4593
4594 // #ifndef <macro>
4595 Pattern = new CodeCompletionString;
4596 Pattern->AddTypedTextChunk("ifndef");
4597 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4598 Pattern->AddPlaceholderChunk("macro");
4599 Results.AddResult(Pattern);
4600
4601 if (InConditional) {
4602 // #elif <condition>
4603 Pattern = new CodeCompletionString;
4604 Pattern->AddTypedTextChunk("elif");
4605 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4606 Pattern->AddPlaceholderChunk("condition");
4607 Results.AddResult(Pattern);
4608
4609 // #else
4610 Pattern = new CodeCompletionString;
4611 Pattern->AddTypedTextChunk("else");
4612 Results.AddResult(Pattern);
4613
4614 // #endif
4615 Pattern = new CodeCompletionString;
4616 Pattern->AddTypedTextChunk("endif");
4617 Results.AddResult(Pattern);
4618 }
4619
4620 // #include "header"
4621 Pattern = new CodeCompletionString;
4622 Pattern->AddTypedTextChunk("include");
4623 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4624 Pattern->AddTextChunk("\"");
4625 Pattern->AddPlaceholderChunk("header");
4626 Pattern->AddTextChunk("\"");
4627 Results.AddResult(Pattern);
4628
4629 // #include <header>
4630 Pattern = new CodeCompletionString;
4631 Pattern->AddTypedTextChunk("include");
4632 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4633 Pattern->AddTextChunk("<");
4634 Pattern->AddPlaceholderChunk("header");
4635 Pattern->AddTextChunk(">");
4636 Results.AddResult(Pattern);
4637
4638 // #define <macro>
4639 Pattern = new CodeCompletionString;
4640 Pattern->AddTypedTextChunk("define");
4641 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4642 Pattern->AddPlaceholderChunk("macro");
4643 Results.AddResult(Pattern);
4644
4645 // #define <macro>(<args>)
4646 Pattern = new CodeCompletionString;
4647 Pattern->AddTypedTextChunk("define");
4648 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4649 Pattern->AddPlaceholderChunk("macro");
4650 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4651 Pattern->AddPlaceholderChunk("args");
4652 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4653 Results.AddResult(Pattern);
4654
4655 // #undef <macro>
4656 Pattern = new CodeCompletionString;
4657 Pattern->AddTypedTextChunk("undef");
4658 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4659 Pattern->AddPlaceholderChunk("macro");
4660 Results.AddResult(Pattern);
4661
4662 // #line <number>
4663 Pattern = new CodeCompletionString;
4664 Pattern->AddTypedTextChunk("line");
4665 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4666 Pattern->AddPlaceholderChunk("number");
4667 Results.AddResult(Pattern);
4668
4669 // #line <number> "filename"
4670 Pattern = new CodeCompletionString;
4671 Pattern->AddTypedTextChunk("line");
4672 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4673 Pattern->AddPlaceholderChunk("number");
4674 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4675 Pattern->AddTextChunk("\"");
4676 Pattern->AddPlaceholderChunk("filename");
4677 Pattern->AddTextChunk("\"");
4678 Results.AddResult(Pattern);
4679
4680 // #error <message>
4681 Pattern = new CodeCompletionString;
4682 Pattern->AddTypedTextChunk("error");
4683 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4684 Pattern->AddPlaceholderChunk("message");
4685 Results.AddResult(Pattern);
4686
4687 // #pragma <arguments>
4688 Pattern = new CodeCompletionString;
4689 Pattern->AddTypedTextChunk("pragma");
4690 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4691 Pattern->AddPlaceholderChunk("arguments");
4692 Results.AddResult(Pattern);
4693
4694 if (getLangOptions().ObjC1) {
4695 // #import "header"
4696 Pattern = new CodeCompletionString;
4697 Pattern->AddTypedTextChunk("import");
4698 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4699 Pattern->AddTextChunk("\"");
4700 Pattern->AddPlaceholderChunk("header");
4701 Pattern->AddTextChunk("\"");
4702 Results.AddResult(Pattern);
4703
4704 // #import <header>
4705 Pattern = new CodeCompletionString;
4706 Pattern->AddTypedTextChunk("import");
4707 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4708 Pattern->AddTextChunk("<");
4709 Pattern->AddPlaceholderChunk("header");
4710 Pattern->AddTextChunk(">");
4711 Results.AddResult(Pattern);
4712 }
4713
4714 // #include_next "header"
4715 Pattern = new CodeCompletionString;
4716 Pattern->AddTypedTextChunk("include_next");
4717 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4718 Pattern->AddTextChunk("\"");
4719 Pattern->AddPlaceholderChunk("header");
4720 Pattern->AddTextChunk("\"");
4721 Results.AddResult(Pattern);
4722
4723 // #include_next <header>
4724 Pattern = new CodeCompletionString;
4725 Pattern->AddTypedTextChunk("include_next");
4726 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4727 Pattern->AddTextChunk("<");
4728 Pattern->AddPlaceholderChunk("header");
4729 Pattern->AddTextChunk(">");
4730 Results.AddResult(Pattern);
4731
4732 // #warning <message>
4733 Pattern = new CodeCompletionString;
4734 Pattern->AddTypedTextChunk("warning");
4735 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4736 Pattern->AddPlaceholderChunk("message");
4737 Results.AddResult(Pattern);
4738
4739 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
4740 // completions for them. And __include_macros is a Clang-internal extension
4741 // that we don't want to encourage anyone to use.
4742
4743 // FIXME: we don't support #assert or #unassert, so don't suggest them.
4744 Results.ExitScope();
4745
Douglas Gregorf44e8542010-08-24 19:08:16 +00004746 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor721f3592010-08-25 18:41:16 +00004747 CodeCompletionContext::CCC_PreprocessorDirective,
Douglas Gregorf44e8542010-08-24 19:08:16 +00004748 Results.data(), Results.size());
4749}
4750
4751void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00004752 CodeCompleteOrdinaryName(S,
4753 S->getFnParent()? Action::PCC_RecoveryInFunction
4754 : Action::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00004755}
4756
Douglas Gregorf29c5232010-08-24 22:20:20 +00004757void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00004758 ResultBuilder Results(*this);
4759 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
4760 // Add just the names of macros, not their arguments.
4761 Results.EnterNewScope();
4762 for (Preprocessor::macro_iterator M = PP.macro_begin(),
4763 MEnd = PP.macro_end();
4764 M != MEnd; ++M) {
4765 CodeCompletionString *Pattern = new CodeCompletionString;
4766 Pattern->AddTypedTextChunk(M->first->getName());
4767 Results.AddResult(Pattern);
4768 }
4769 Results.ExitScope();
4770 } else if (IsDefinition) {
4771 // FIXME: Can we detect when the user just wrote an include guard above?
4772 }
4773
4774 HandleCodeCompleteResults(this, CodeCompleter,
4775 IsDefinition? CodeCompletionContext::CCC_MacroName
4776 : CodeCompletionContext::CCC_MacroNameUse,
4777 Results.data(), Results.size());
4778}
4779
Douglas Gregorf29c5232010-08-24 22:20:20 +00004780void Sema::CodeCompletePreprocessorExpression() {
4781 ResultBuilder Results(*this);
4782
4783 if (!CodeCompleter || CodeCompleter->includeMacros())
4784 AddMacroResults(PP, Results);
4785
4786 // defined (<macro>)
4787 Results.EnterNewScope();
4788 CodeCompletionString *Pattern = new CodeCompletionString;
4789 Pattern->AddTypedTextChunk("defined");
4790 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4791 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4792 Pattern->AddPlaceholderChunk("macro");
4793 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4794 Results.AddResult(Pattern);
4795 Results.ExitScope();
4796
4797 HandleCodeCompleteResults(this, CodeCompleter,
4798 CodeCompletionContext::CCC_PreprocessorExpression,
4799 Results.data(), Results.size());
4800}
4801
4802void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
4803 IdentifierInfo *Macro,
4804 MacroInfo *MacroInfo,
4805 unsigned Argument) {
4806 // FIXME: In the future, we could provide "overload" results, much like we
4807 // do for function calls.
4808
4809 CodeCompleteOrdinaryName(S,
4810 S->getFnParent()? Action::PCC_RecoveryInFunction
4811 : Action::PCC_Namespace);
4812}
4813
Douglas Gregor55817af2010-08-25 17:04:25 +00004814void Sema::CodeCompleteNaturalLanguage() {
Douglas Gregor55817af2010-08-25 17:04:25 +00004815 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregoraf1c6b52010-08-25 17:10:00 +00004816 CodeCompletionContext::CCC_NaturalLanguage,
Douglas Gregor55817af2010-08-25 17:04:25 +00004817 0, 0);
4818}
4819
Douglas Gregor87c08a52010-08-13 22:48:40 +00004820void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00004821 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00004822 ResultBuilder Builder(*this);
4823
Douglas Gregor8071e422010-08-15 06:18:01 +00004824 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4825 CodeCompletionDeclConsumer Consumer(Builder,
4826 Context.getTranslationUnitDecl());
4827 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4828 Consumer);
4829 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00004830
4831 if (!CodeCompleter || CodeCompleter->includeMacros())
4832 AddMacroResults(PP, Builder);
4833
4834 Results.clear();
4835 Results.insert(Results.end(),
4836 Builder.data(), Builder.data() + Builder.size());
4837}