blob: ad4382e09b384a2498e9e2e1cae896894d931c48 [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//===----------------------------------------------------------------------===//
Douglas Gregore737f502010-08-12 20:07:10 +000013#include "clang/Sema/Sema.h"
14#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 Gregor86d9a522009-09-21 16:56:56 +00002234namespace {
2235 struct SortCodeCompleteResult {
John McCall0a2c5e22010-08-25 06:19:51 +00002236 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002237
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002238 /// \brief Retrieve the name that should be used to order a result.
2239 ///
2240 /// If the name needs to be constructed as a string, that string will be
2241 /// saved into Saved and the returned StringRef will refer to it.
2242 static llvm::StringRef getOrderedName(const Result &R,
2243 std::string &Saved) {
2244 switch (R.Kind) {
2245 case Result::RK_Keyword:
2246 return R.Keyword;
2247
2248 case Result::RK_Pattern:
2249 return R.Pattern->getTypedText();
2250
2251 case Result::RK_Macro:
2252 return R.Macro->getName();
2253
2254 case Result::RK_Declaration:
2255 // Handle declarations below.
2256 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00002257 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002258
2259 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00002260
Douglas Gregorab0b4f12010-01-13 23:24:38 +00002261 // If the name is a simple identifier (by far the common case), or a
2262 // zero-argument selector, just return a reference to that identifier.
2263 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
2264 return Id->getName();
2265 if (Name.isObjCZeroArgSelector())
2266 if (IdentifierInfo *Id
2267 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
2268 return Id->getName();
2269
2270 Saved = Name.getAsString();
2271 return Saved;
2272 }
2273
2274 bool operator()(const Result &X, const Result &Y) const {
2275 std::string XSaved, YSaved;
2276 llvm::StringRef XStr = getOrderedName(X, XSaved);
2277 llvm::StringRef YStr = getOrderedName(Y, YSaved);
2278 int cmp = XStr.compare_lower(YStr);
2279 if (cmp)
2280 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002281
2282 // Non-hidden names precede hidden names.
2283 if (X.Hidden != Y.Hidden)
2284 return !X.Hidden;
2285
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002286 // Non-nested-name-specifiers precede nested-name-specifiers.
2287 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
2288 return !X.StartsNestedNameSpecifier;
2289
Douglas Gregor86d9a522009-09-21 16:56:56 +00002290 return false;
2291 }
2292 };
2293}
2294
Douglas Gregor1827e102010-08-16 16:18:59 +00002295unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
2296 bool PreferredTypeIsPointer) {
2297 unsigned Priority = CCP_Macro;
2298
2299 // Treat the "nil" and "NULL" macros as null pointer constants.
2300 if (MacroName.equals("nil") || MacroName.equals("NULL")) {
2301 Priority = CCP_Constant;
2302 if (PreferredTypeIsPointer)
2303 Priority = Priority / CCF_SimilarTypeMatch;
2304 }
2305
2306 return Priority;
2307}
2308
Douglas Gregor590c7d52010-07-08 20:55:51 +00002309static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2310 bool TargetTypeIsPointer = false) {
John McCall0a2c5e22010-08-25 06:19:51 +00002311 typedef CodeCompletionResult Result;
Douglas Gregor590c7d52010-07-08 20:55:51 +00002312
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002313 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002314 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2315 MEnd = PP.macro_end();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002316 M != MEnd; ++M) {
Douglas Gregor1827e102010-08-16 16:18:59 +00002317 Results.AddResult(Result(M->first,
2318 getMacroUsagePriority(M->first->getName(),
2319 TargetTypeIsPointer)));
Douglas Gregor590c7d52010-07-08 20:55:51 +00002320 }
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002321 Results.ExitScope();
2322}
2323
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002324static void AddPrettyFunctionResults(const LangOptions &LangOpts,
2325 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002326 typedef CodeCompletionResult Result;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002327
2328 Results.EnterNewScope();
2329 Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
2330 Results.AddResult(Result("__FUNCTION__", CCP_Constant));
2331 if (LangOpts.C99 || LangOpts.CPlusPlus0x)
2332 Results.AddResult(Result("__func__", CCP_Constant));
2333 Results.ExitScope();
2334}
2335
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002336static void HandleCodeCompleteResults(Sema *S,
2337 CodeCompleteConsumer *CodeCompleter,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002338 CodeCompletionContext Context,
John McCall0a2c5e22010-08-25 06:19:51 +00002339 CodeCompletionResult *Results,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002340 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002341 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2342
2343 if (CodeCompleter)
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002344 CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002345
2346 for (unsigned I = 0; I != NumResults; ++I)
2347 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002348}
2349
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002350static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
2351 Sema::ParserCompletionContext PCC) {
2352 switch (PCC) {
2353 case Action::PCC_Namespace:
2354 return CodeCompletionContext::CCC_TopLevel;
2355
2356 case Action::PCC_Class:
2357 return CodeCompletionContext::CCC_ClassStructUnion;
2358
2359 case Action::PCC_ObjCInterface:
2360 return CodeCompletionContext::CCC_ObjCInterface;
2361
2362 case Action::PCC_ObjCImplementation:
2363 return CodeCompletionContext::CCC_ObjCImplementation;
2364
2365 case Action::PCC_ObjCInstanceVariableList:
2366 return CodeCompletionContext::CCC_ObjCIvarList;
2367
2368 case Action::PCC_Template:
2369 case Action::PCC_MemberTemplate:
2370 case Action::PCC_RecoveryInFunction:
2371 return CodeCompletionContext::CCC_Other;
2372
2373 case Action::PCC_Expression:
2374 case Action::PCC_ForInit:
2375 case Action::PCC_Condition:
2376 return CodeCompletionContext::CCC_Expression;
2377
2378 case Action::PCC_Statement:
2379 return CodeCompletionContext::CCC_Statement;
Douglas Gregor72db1082010-08-24 01:11:00 +00002380
2381 case Action::PCC_Type:
2382 return CodeCompletionContext::CCC_Type;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002383 }
2384
2385 return CodeCompletionContext::CCC_Other;
2386}
2387
Douglas Gregor01dfea02010-01-10 23:08:15 +00002388void Sema::CodeCompleteOrdinaryName(Scope *S,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002389 ParserCompletionContext CompletionContext) {
John McCall0a2c5e22010-08-25 06:19:51 +00002390 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002391 ResultBuilder Results(*this);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002392
2393 // Determine how to filter results, e.g., so that the names of
2394 // values (functions, enumerators, function templates, etc.) are
2395 // only allowed where we can have an expression.
2396 switch (CompletionContext) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002397 case PCC_Namespace:
2398 case PCC_Class:
2399 case PCC_ObjCInterface:
2400 case PCC_ObjCImplementation:
2401 case PCC_ObjCInstanceVariableList:
2402 case PCC_Template:
2403 case PCC_MemberTemplate:
Douglas Gregor72db1082010-08-24 01:11:00 +00002404 case PCC_Type:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002405 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2406 break;
2407
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002408 case PCC_Statement:
Douglas Gregoreb0d0142010-08-24 23:58:17 +00002409 // For statements that are expressions, we prefer to call 'void' functions
2410 // rather than functions that return a result, since then the result would
2411 // be ignored.
2412 Results.setPreferredType(Context.VoidTy);
2413 // Fall through
2414
2415 case PCC_Expression:
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002416 case PCC_ForInit:
2417 case PCC_Condition:
Douglas Gregor4710e5b2010-05-28 00:49:12 +00002418 if (WantTypesInContext(CompletionContext, getLangOptions()))
2419 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2420 else
2421 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregor01dfea02010-01-10 23:08:15 +00002422 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002423
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002424 case PCC_RecoveryInFunction:
Douglas Gregordc845342010-05-25 05:58:43 +00002425 // Unfiltered
2426 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002427 }
2428
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002429 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002430 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2431 CodeCompleter->includeGlobals());
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002432
2433 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002434 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002435 Results.ExitScope();
2436
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002437 switch (CompletionContext) {
Douglas Gregor72db1082010-08-24 01:11:00 +00002438 case PCC_Expression:
2439 case PCC_Statement:
2440 case PCC_RecoveryInFunction:
2441 if (S->getFnParent())
2442 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2443 break;
2444
2445 case PCC_Namespace:
2446 case PCC_Class:
2447 case PCC_ObjCInterface:
2448 case PCC_ObjCImplementation:
2449 case PCC_ObjCInstanceVariableList:
2450 case PCC_Template:
2451 case PCC_MemberTemplate:
2452 case PCC_ForInit:
2453 case PCC_Condition:
2454 case PCC_Type:
2455 break;
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002456 }
2457
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002458 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002459 AddMacroResults(PP, Results);
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002460
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002461 HandleCodeCompleteResults(this, CodeCompleter,
2462 mapCodeCompletionContext(*this, CompletionContext),
2463 Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002464}
2465
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002466void Sema::CodeCompleteDeclarator(Scope *S,
2467 bool AllowNonIdentifiers,
2468 bool AllowNestedNameSpecifiers) {
John McCall0a2c5e22010-08-25 06:19:51 +00002469 typedef CodeCompletionResult Result;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002470 ResultBuilder Results(*this);
2471 Results.EnterNewScope();
2472
2473 // Type qualifiers can come after names.
2474 Results.AddResult(Result("const"));
2475 Results.AddResult(Result("volatile"));
2476 if (getLangOptions().C99)
2477 Results.AddResult(Result("restrict"));
2478
2479 if (getLangOptions().CPlusPlus) {
2480 if (AllowNonIdentifiers) {
2481 Results.AddResult(Result("operator"));
2482 }
2483
2484 // Add nested-name-specifiers.
2485 if (AllowNestedNameSpecifiers) {
2486 Results.allowNestedNameSpecifiers();
2487 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2488 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
2489 CodeCompleter->includeGlobals());
2490 }
2491 }
2492 Results.ExitScope();
2493
Douglas Gregor4497dd42010-08-24 04:59:56 +00002494 // Note that we intentionally suppress macro results here, since we do not
2495 // encourage using macros to produce the names of entities.
2496
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002497 HandleCodeCompleteResults(this, CodeCompleter,
2498 AllowNestedNameSpecifiers
2499 ? CodeCompletionContext::CCC_PotentiallyQualifiedName
2500 : CodeCompletionContext::CCC_Name,
2501 Results.data(), Results.size());
2502}
2503
Douglas Gregorfb629412010-08-23 21:17:50 +00002504struct Sema::CodeCompleteExpressionData {
2505 CodeCompleteExpressionData(QualType PreferredType = QualType())
2506 : PreferredType(PreferredType), IntegralConstantExpression(false),
2507 ObjCCollection(false) { }
2508
2509 QualType PreferredType;
2510 bool IntegralConstantExpression;
2511 bool ObjCCollection;
2512 llvm::SmallVector<Decl *, 4> IgnoreDecls;
2513};
2514
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002515/// \brief Perform code-completion in an expression context when we know what
2516/// type we're looking for.
Douglas Gregorf9578432010-07-28 21:50:18 +00002517///
2518/// \param IntegralConstantExpression Only permit integral constant
2519/// expressions.
Douglas Gregorfb629412010-08-23 21:17:50 +00002520void Sema::CodeCompleteExpression(Scope *S,
2521 const CodeCompleteExpressionData &Data) {
John McCall0a2c5e22010-08-25 06:19:51 +00002522 typedef CodeCompletionResult Result;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002523 ResultBuilder Results(*this);
2524
Douglas Gregorfb629412010-08-23 21:17:50 +00002525 if (Data.ObjCCollection)
2526 Results.setFilter(&ResultBuilder::IsObjCCollection);
2527 else if (Data.IntegralConstantExpression)
Douglas Gregorf9578432010-07-28 21:50:18 +00002528 Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002529 else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002530 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2531 else
2532 Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
Douglas Gregorfb629412010-08-23 21:17:50 +00002533
2534 if (!Data.PreferredType.isNull())
2535 Results.setPreferredType(Data.PreferredType.getNonReferenceType());
2536
2537 // Ignore any declarations that we were told that we don't care about.
2538 for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
2539 Results.Ignore(Data.IgnoreDecls[I]);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002540
2541 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002542 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
2543 CodeCompleter->includeGlobals());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002544
2545 Results.EnterNewScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002546 AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002547 Results.ExitScope();
2548
Douglas Gregor590c7d52010-07-08 20:55:51 +00002549 bool PreferredTypeIsPointer = false;
Douglas Gregorfb629412010-08-23 21:17:50 +00002550 if (!Data.PreferredType.isNull())
2551 PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
2552 || Data.PreferredType->isMemberPointerType()
2553 || Data.PreferredType->isBlockPointerType();
Douglas Gregor590c7d52010-07-08 20:55:51 +00002554
Douglas Gregoraa5f77b2010-08-23 21:54:33 +00002555 if (S->getFnParent() &&
2556 !Data.ObjCCollection &&
2557 !Data.IntegralConstantExpression)
2558 AddPrettyFunctionResults(PP.getLangOptions(), Results);
2559
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002560 if (CodeCompleter->includeMacros())
Douglas Gregor590c7d52010-07-08 20:55:51 +00002561 AddMacroResults(PP, Results, PreferredTypeIsPointer);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002562 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregorfb629412010-08-23 21:17:50 +00002563 CodeCompletionContext(CodeCompletionContext::CCC_Expression,
2564 Data.PreferredType),
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002565 Results.data(),Results.size());
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002566}
2567
2568
Douglas Gregor95ac6552009-11-18 01:29:26 +00002569static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002570 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002571 DeclContext *CurContext,
2572 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00002573 typedef CodeCompletionResult Result;
Douglas Gregor95ac6552009-11-18 01:29:26 +00002574
2575 // Add properties in this container.
2576 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2577 PEnd = Container->prop_end();
2578 P != PEnd;
2579 ++P)
2580 Results.MaybeAddResult(Result(*P, 0), CurContext);
2581
2582 // Add properties in referenced protocols.
2583 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2584 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2585 PEnd = Protocol->protocol_end();
2586 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002587 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002588 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002589 if (AllowCategories) {
2590 // Look through categories.
2591 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2592 Category; Category = Category->getNextClassCategory())
2593 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2594 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002595
2596 // Look through protocols.
2597 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2598 E = IFace->protocol_end();
2599 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002600 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002601
2602 // Look in the superclass.
2603 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002604 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2605 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002606 } else if (const ObjCCategoryDecl *Category
2607 = dyn_cast<ObjCCategoryDecl>(Container)) {
2608 // Look through protocols.
2609 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2610 PEnd = Category->protocol_end();
2611 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002612 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002613 }
2614}
2615
Douglas Gregor81b747b2009-09-17 21:32:03 +00002616void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2617 SourceLocation OpLoc,
2618 bool IsArrow) {
2619 if (!BaseE || !CodeCompleter)
2620 return;
2621
John McCall0a2c5e22010-08-25 06:19:51 +00002622 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002623
Douglas Gregor81b747b2009-09-17 21:32:03 +00002624 Expr *Base = static_cast<Expr *>(BaseE);
2625 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002626
2627 if (IsArrow) {
2628 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2629 BaseType = Ptr->getPointeeType();
2630 else if (BaseType->isObjCObjectPointerType())
2631 /*Do nothing*/ ;
2632 else
2633 return;
2634 }
2635
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002636 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002637 Results.EnterNewScope();
2638 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2639 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002640 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002641 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00002642 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
2643 CodeCompleter->includeGlobals());
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002644
Douglas Gregor95ac6552009-11-18 01:29:26 +00002645 if (getLangOptions().CPlusPlus) {
2646 if (!Results.empty()) {
2647 // The "template" keyword can follow "->" or "." in the grammar.
2648 // However, we only want to suggest the template keyword if something
2649 // is dependent.
2650 bool IsDependent = BaseType->isDependentType();
2651 if (!IsDependent) {
2652 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2653 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2654 IsDependent = Ctx->isDependentContext();
2655 break;
2656 }
2657 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002658
Douglas Gregor95ac6552009-11-18 01:29:26 +00002659 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002660 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002661 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002662 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002663 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2664 // Objective-C property reference.
2665
2666 // Add property results based on our interface.
2667 const ObjCObjectPointerType *ObjCPtr
2668 = BaseType->getAsObjCInterfacePointerType();
2669 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002670 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002671
2672 // Add properties from the protocols in a qualified interface.
2673 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2674 E = ObjCPtr->qual_end();
2675 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002676 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002677 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002678 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002679 // Objective-C instance variable access.
2680 ObjCInterfaceDecl *Class = 0;
2681 if (const ObjCObjectPointerType *ObjCPtr
2682 = BaseType->getAs<ObjCObjectPointerType>())
2683 Class = ObjCPtr->getInterfaceDecl();
2684 else
John McCallc12c5bb2010-05-15 11:32:37 +00002685 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002686
2687 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002688 if (Class) {
2689 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2690 Results.setFilter(&ResultBuilder::IsObjCIvar);
Douglas Gregor8071e422010-08-15 06:18:01 +00002691 LookupVisibleDecls(Class, LookupMemberName, Consumer,
2692 CodeCompleter->includeGlobals());
Douglas Gregor95ac6552009-11-18 01:29:26 +00002693 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002694 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002695
2696 // FIXME: How do we cope with isa?
2697
2698 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002699
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002700 // Hand off the results found for code completion.
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002701 HandleCodeCompleteResults(this, CodeCompleter,
2702 CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
2703 BaseType),
2704 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002705}
2706
Douglas Gregor374929f2009-09-18 15:37:17 +00002707void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2708 if (!CodeCompleter)
2709 return;
2710
John McCall0a2c5e22010-08-25 06:19:51 +00002711 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002712 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002713 enum CodeCompletionContext::Kind ContextKind
2714 = CodeCompletionContext::CCC_Other;
Douglas Gregor374929f2009-09-18 15:37:17 +00002715 switch ((DeclSpec::TST)TagSpec) {
2716 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002717 Filter = &ResultBuilder::IsEnum;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002718 ContextKind = CodeCompletionContext::CCC_EnumTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002719 break;
2720
2721 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002722 Filter = &ResultBuilder::IsUnion;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002723 ContextKind = CodeCompletionContext::CCC_UnionTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002724 break;
2725
2726 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002727 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002728 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002729 ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
Douglas Gregor374929f2009-09-18 15:37:17 +00002730 break;
2731
2732 default:
2733 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2734 return;
2735 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002736
John McCall0d6b1642010-04-23 18:46:30 +00002737 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002738 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002739
2740 // First pass: look for tags.
2741 Results.setFilter(Filter);
Douglas Gregor8071e422010-08-15 06:18:01 +00002742 LookupVisibleDecls(S, LookupTagName, Consumer,
2743 CodeCompleter->includeGlobals());
John McCall0d6b1642010-04-23 18:46:30 +00002744
Douglas Gregor8071e422010-08-15 06:18:01 +00002745 if (CodeCompleter->includeGlobals()) {
2746 // Second pass: look for nested name specifiers.
2747 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2748 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
2749 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002750
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002751 HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
2752 Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002753}
2754
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002755void Sema::CodeCompleteCase(Scope *S) {
John McCall781472f2010-08-25 08:40:02 +00002756 if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002757 return;
2758
John McCall781472f2010-08-25 08:40:02 +00002759 SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
Douglas Gregorf9578432010-07-28 21:50:18 +00002760 if (!Switch->getCond()->getType()->isEnumeralType()) {
Douglas Gregorfb629412010-08-23 21:17:50 +00002761 CodeCompleteExpressionData Data(Switch->getCond()->getType());
2762 Data.IntegralConstantExpression = true;
2763 CodeCompleteExpression(S, Data);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002764 return;
Douglas Gregorf9578432010-07-28 21:50:18 +00002765 }
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002766
2767 // Code-complete the cases of a switch statement over an enumeration type
2768 // by providing the list of
2769 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2770
2771 // Determine which enumerators we have already seen in the switch statement.
2772 // FIXME: Ideally, we would also be able to look *past* the code-completion
2773 // token, in case we are code-completing in the middle of the switch and not
2774 // at the end. However, we aren't able to do so at the moment.
2775 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002776 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002777 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2778 SC = SC->getNextSwitchCase()) {
2779 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2780 if (!Case)
2781 continue;
2782
2783 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2784 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2785 if (EnumConstantDecl *Enumerator
2786 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2787 // We look into the AST of the case statement to determine which
2788 // enumerator was named. Alternatively, we could compute the value of
2789 // the integral constant expression, then compare it against the
2790 // values of each enumerator. However, value-based approach would not
2791 // work as well with C++ templates where enumerators declared within a
2792 // template are type- and value-dependent.
2793 EnumeratorsSeen.insert(Enumerator);
2794
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002795 // If this is a qualified-id, keep track of the nested-name-specifier
2796 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002797 //
2798 // switch (TagD.getKind()) {
2799 // case TagDecl::TK_enum:
2800 // break;
2801 // case XXX
2802 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002803 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002804 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2805 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002806 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002807 }
2808 }
2809
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002810 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2811 // If there are no prior enumerators in C++, check whether we have to
2812 // qualify the names of the enumerators that we suggest, because they
2813 // may not be visible in this scope.
2814 Qualifier = getRequiredQualification(Context, CurContext,
2815 Enum->getDeclContext());
2816
2817 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2818 }
2819
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002820 // Add any enumerators that have not yet been mentioned.
2821 ResultBuilder Results(*this);
2822 Results.EnterNewScope();
2823 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2824 EEnd = Enum->enumerator_end();
2825 E != EEnd; ++E) {
2826 if (EnumeratorsSeen.count(*E))
2827 continue;
2828
John McCall0a2c5e22010-08-25 06:19:51 +00002829 Results.AddResult(CodeCompletionResult(*E, Qualifier),
Douglas Gregor608300b2010-01-14 16:14:35 +00002830 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002831 }
2832 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002833
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002834 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002835 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002836 HandleCodeCompleteResults(this, CodeCompleter,
2837 CodeCompletionContext::CCC_Expression,
2838 Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002839}
2840
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002841namespace {
2842 struct IsBetterOverloadCandidate {
2843 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002844 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002845
2846 public:
John McCall5769d612010-02-08 23:07:23 +00002847 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2848 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002849
2850 bool
2851 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall120d63c2010-08-24 20:38:10 +00002852 return isBetterOverloadCandidate(S, X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002853 }
2854 };
2855}
2856
Douglas Gregord28dcd72010-05-30 06:10:08 +00002857static bool anyNullArguments(Expr **Args, unsigned NumArgs) {
2858 if (NumArgs && !Args)
2859 return true;
2860
2861 for (unsigned I = 0; I != NumArgs; ++I)
2862 if (!Args[I])
2863 return true;
2864
2865 return false;
2866}
2867
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002868void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2869 ExprTy **ArgsIn, unsigned NumArgs) {
2870 if (!CodeCompleter)
2871 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002872
2873 // When we're code-completing for a call, we fall back to ordinary
2874 // name code-completion whenever we can't produce specific
2875 // results. We may want to revisit this strategy in the future,
2876 // e.g., by merging the two kinds of results.
2877
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002878 Expr *Fn = (Expr *)FnIn;
2879 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002880
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002881 // Ignore type-dependent call expressions entirely.
Douglas Gregord28dcd72010-05-30 06:10:08 +00002882 if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002883 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002884 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002885 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002886 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002887
John McCall3b4294e2009-12-16 12:17:52 +00002888 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002889 SourceLocation Loc = Fn->getExprLoc();
2890 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002891
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002892 // FIXME: What if we're calling something that isn't a function declaration?
2893 // FIXME: What if we're calling a pseudo-destructor?
2894 // FIXME: What if we're calling a member function?
2895
Douglas Gregorc0265402010-01-21 15:46:19 +00002896 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2897 llvm::SmallVector<ResultCandidate, 8> Results;
2898
John McCall3b4294e2009-12-16 12:17:52 +00002899 Expr *NakedFn = Fn->IgnoreParenCasts();
2900 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2901 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2902 /*PartialOverloading=*/ true);
2903 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2904 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002905 if (FDecl) {
Douglas Gregord28dcd72010-05-30 06:10:08 +00002906 if (!getLangOptions().CPlusPlus ||
2907 !FDecl->getType()->getAs<FunctionProtoType>())
Douglas Gregorc0265402010-01-21 15:46:19 +00002908 Results.push_back(ResultCandidate(FDecl));
2909 else
John McCall86820f52010-01-26 01:37:31 +00002910 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002911 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2912 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002913 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002914 }
John McCall3b4294e2009-12-16 12:17:52 +00002915 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002916
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002917 QualType ParamType;
2918
Douglas Gregorc0265402010-01-21 15:46:19 +00002919 if (!CandidateSet.empty()) {
2920 // Sort the overload candidate set by placing the best overloads first.
2921 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002922 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002923
Douglas Gregorc0265402010-01-21 15:46:19 +00002924 // Add the remaining viable overload candidates as code-completion reslults.
2925 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2926 CandEnd = CandidateSet.end();
2927 Cand != CandEnd; ++Cand) {
2928 if (Cand->Viable)
2929 Results.push_back(ResultCandidate(Cand->Function));
2930 }
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002931
2932 // From the viable candidates, try to determine the type of this parameter.
2933 for (unsigned I = 0, N = Results.size(); I != N; ++I) {
2934 if (const FunctionType *FType = Results[I].getFunctionType())
2935 if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
2936 if (NumArgs < Proto->getNumArgs()) {
2937 if (ParamType.isNull())
2938 ParamType = Proto->getArgType(NumArgs);
2939 else if (!Context.hasSameUnqualifiedType(
2940 ParamType.getNonReferenceType(),
2941 Proto->getArgType(NumArgs).getNonReferenceType())) {
2942 ParamType = QualType();
2943 break;
2944 }
2945 }
2946 }
2947 } else {
2948 // Try to determine the parameter type from the type of the expression
2949 // being called.
2950 QualType FunctionType = Fn->getType();
2951 if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
2952 FunctionType = Ptr->getPointeeType();
2953 else if (const BlockPointerType *BlockPtr
2954 = FunctionType->getAs<BlockPointerType>())
2955 FunctionType = BlockPtr->getPointeeType();
2956 else if (const MemberPointerType *MemPtr
2957 = FunctionType->getAs<MemberPointerType>())
2958 FunctionType = MemPtr->getPointeeType();
2959
2960 if (const FunctionProtoType *Proto
2961 = FunctionType->getAs<FunctionProtoType>()) {
2962 if (NumArgs < Proto->getNumArgs())
2963 ParamType = Proto->getArgType(NumArgs);
2964 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002965 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002966
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002967 if (ParamType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002968 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002969 else
2970 CodeCompleteExpression(S, ParamType);
2971
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002972 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002973 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2974 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002975}
2976
John McCalld226f652010-08-21 09:40:31 +00002977void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
2978 ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002979 if (!VD) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002980 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002981 return;
2982 }
2983
2984 CodeCompleteExpression(S, VD->getType());
2985}
2986
2987void Sema::CodeCompleteReturn(Scope *S) {
2988 QualType ResultType;
2989 if (isa<BlockDecl>(CurContext)) {
2990 if (BlockScopeInfo *BSI = getCurBlock())
2991 ResultType = BSI->ReturnType;
2992 } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
2993 ResultType = Function->getResultType();
2994 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
2995 ResultType = Method->getResultType();
2996
2997 if (ResultType.isNull())
Douglas Gregore6b1bb62010-08-11 21:23:17 +00002998 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00002999 else
3000 CodeCompleteExpression(S, ResultType);
3001}
3002
3003void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
3004 if (LHS)
3005 CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
3006 else
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003007 CodeCompleteOrdinaryName(S, PCC_Expression);
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00003008}
3009
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00003010void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00003011 bool EnteringContext) {
3012 if (!SS.getScopeRep() || !CodeCompleter)
3013 return;
3014
Douglas Gregor86d9a522009-09-21 16:56:56 +00003015 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
3016 if (!Ctx)
3017 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003018
3019 // Try to instantiate any non-dependent declaration contexts before
3020 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00003021 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00003022 return;
3023
Douglas Gregor86d9a522009-09-21 16:56:56 +00003024 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00003025 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3026 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00003027
3028 // The "template" keyword can follow "::" in the grammar, but only
3029 // put it into the grammar if the nested-name-specifier is dependent.
3030 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
3031 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00003032 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00003033
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003034 HandleCodeCompleteResults(this, CodeCompleter,
3035 CodeCompletionContext::CCC_Other,
3036 Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00003037}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003038
3039void Sema::CodeCompleteUsing(Scope *S) {
3040 if (!CodeCompleter)
3041 return;
3042
Douglas Gregor86d9a522009-09-21 16:56:56 +00003043 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003044 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003045
3046 // If we aren't in class scope, we could see the "namespace" keyword.
3047 if (!S->isClassScope())
John McCall0a2c5e22010-08-25 06:19:51 +00003048 Results.AddResult(CodeCompletionResult("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003049
3050 // After "using", we can see anything that would start a
3051 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003052 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003053 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3054 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003055 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003056
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003057 HandleCodeCompleteResults(this, CodeCompleter,
3058 CodeCompletionContext::CCC_Other,
3059 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003060}
3061
3062void Sema::CodeCompleteUsingDirective(Scope *S) {
3063 if (!CodeCompleter)
3064 return;
3065
Douglas Gregor86d9a522009-09-21 16:56:56 +00003066 // After "using namespace", we expect to see a namespace name or namespace
3067 // alias.
3068 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003069 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003070 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003071 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3072 CodeCompleter->includeGlobals());
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003073 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003074 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003075 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003076 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003077}
3078
3079void Sema::CodeCompleteNamespaceDecl(Scope *S) {
3080 if (!CodeCompleter)
3081 return;
3082
Douglas Gregor86d9a522009-09-21 16:56:56 +00003083 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
3084 DeclContext *Ctx = (DeclContext *)S->getEntity();
3085 if (!S->getParent())
3086 Ctx = Context.getTranslationUnitDecl();
3087
3088 if (Ctx && Ctx->isFileContext()) {
3089 // We only want to see those namespaces that have already been defined
3090 // within this scope, because its likely that the user is creating an
3091 // extended namespace declaration. Keep track of the most recent
3092 // definition of each namespace.
3093 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
3094 for (DeclContext::specific_decl_iterator<NamespaceDecl>
3095 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
3096 NS != NSEnd; ++NS)
3097 OrigToLatest[NS->getOriginalNamespace()] = *NS;
3098
3099 // Add the most recent definition (or extended definition) of each
3100 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003101 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003102 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
3103 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
3104 NS != NSEnd; ++NS)
John McCall0a2c5e22010-08-25 06:19:51 +00003105 Results.AddResult(CodeCompletionResult(NS->second, 0),
Douglas Gregor608300b2010-01-14 16:14:35 +00003106 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003107 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003108 }
3109
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003110 HandleCodeCompleteResults(this, CodeCompleter,
3111 CodeCompletionContext::CCC_Other,
3112 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003113}
3114
3115void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
3116 if (!CodeCompleter)
3117 return;
3118
Douglas Gregor86d9a522009-09-21 16:56:56 +00003119 // After "namespace", we expect to see a namespace or alias.
3120 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003121 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003122 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3123 CodeCompleter->includeGlobals());
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003124 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003125 CodeCompletionContext::CCC_Namespace,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003126 Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003127}
3128
Douglas Gregored8d3222009-09-18 20:05:18 +00003129void Sema::CodeCompleteOperatorName(Scope *S) {
3130 if (!CodeCompleter)
3131 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003132
John McCall0a2c5e22010-08-25 06:19:51 +00003133 typedef CodeCompletionResult Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00003134 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003135 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00003136
Douglas Gregor86d9a522009-09-21 16:56:56 +00003137 // Add the names of overloadable operators.
3138#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
3139 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00003140 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00003141#include "clang/Basic/OperatorKinds.def"
3142
3143 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00003144 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00003145 CodeCompletionDeclConsumer Consumer(Results, CurContext);
Douglas Gregor8071e422010-08-15 06:18:01 +00003146 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3147 CodeCompleter->includeGlobals());
Douglas Gregor86d9a522009-09-21 16:56:56 +00003148
3149 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00003150 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00003151 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00003152
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003153 HandleCodeCompleteResults(this, CodeCompleter,
Douglas Gregor8071e422010-08-15 06:18:01 +00003154 CodeCompletionContext::CCC_Type,
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003155 Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00003156}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00003157
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003158// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
3159// true or false.
3160#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00003161static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003162 ResultBuilder &Results,
3163 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003164 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003165 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003166 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003167
3168 CodeCompletionString *Pattern = 0;
3169 if (LangOpts.ObjC2) {
3170 // @dynamic
3171 Pattern = new CodeCompletionString;
3172 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
3173 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3174 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003175 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003176
3177 // @synthesize
3178 Pattern = new CodeCompletionString;
3179 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
3180 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3181 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00003182 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003183 }
3184}
3185
Douglas Gregorbca403c2010-01-13 23:51:12 +00003186static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003187 ResultBuilder &Results,
3188 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003189 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003190
3191 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00003192 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003193
3194 if (LangOpts.ObjC2) {
3195 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00003196 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003197
3198 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00003199 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003200
3201 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00003202 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003203 }
3204}
3205
Douglas Gregorbca403c2010-01-13 23:51:12 +00003206static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003207 typedef CodeCompletionResult Result;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003208 CodeCompletionString *Pattern = 0;
3209
3210 // @class name ;
3211 Pattern = new CodeCompletionString;
3212 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
3213 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003214 Pattern->AddPlaceholderChunk("name");
Douglas Gregora4477812010-01-14 16:01:26 +00003215 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003216
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003217 if (Results.includeCodePatterns()) {
3218 // @interface name
3219 // FIXME: Could introduce the whole pattern, including superclasses and
3220 // such.
3221 Pattern = new CodeCompletionString;
3222 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
3223 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3224 Pattern->AddPlaceholderChunk("class");
3225 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003226
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003227 // @protocol name
3228 Pattern = new CodeCompletionString;
3229 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
3230 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3231 Pattern->AddPlaceholderChunk("protocol");
3232 Results.AddResult(Result(Pattern));
3233
3234 // @implementation name
3235 Pattern = new CodeCompletionString;
3236 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
3237 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3238 Pattern->AddPlaceholderChunk("class");
3239 Results.AddResult(Result(Pattern));
3240 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003241
3242 // @compatibility_alias name
3243 Pattern = new CodeCompletionString;
3244 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
3245 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3246 Pattern->AddPlaceholderChunk("alias");
3247 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3248 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00003249 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003250}
3251
John McCalld226f652010-08-21 09:40:31 +00003252void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
Douglas Gregorc464ae82009-12-07 09:27:33 +00003253 bool InInterface) {
John McCall0a2c5e22010-08-25 06:19:51 +00003254 typedef CodeCompletionResult Result;
Douglas Gregorc464ae82009-12-07 09:27:33 +00003255 ResultBuilder Results(*this);
3256 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003257 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003258 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003259 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00003260 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003261 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00003262 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00003263 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003264 HandleCodeCompleteResults(this, CodeCompleter,
3265 CodeCompletionContext::CCC_Other,
3266 Results.data(),Results.size());
Douglas Gregorc464ae82009-12-07 09:27:33 +00003267}
3268
Douglas Gregorbca403c2010-01-13 23:51:12 +00003269static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003270 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003271 CodeCompletionString *Pattern = 0;
3272
3273 // @encode ( type-name )
3274 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003275 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003276 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3277 Pattern->AddPlaceholderChunk("type-name");
3278 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003279 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003280
3281 // @protocol ( protocol-name )
3282 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003283 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003284 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3285 Pattern->AddPlaceholderChunk("protocol-name");
3286 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003287 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003288
3289 // @selector ( selector )
3290 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003291 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003292 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3293 Pattern->AddPlaceholderChunk("selector");
3294 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00003295 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003296}
3297
Douglas Gregorbca403c2010-01-13 23:51:12 +00003298static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003299 typedef CodeCompletionResult Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003300 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003301
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003302 if (Results.includeCodePatterns()) {
3303 // @try { statements } @catch ( declaration ) { statements } @finally
3304 // { statements }
3305 Pattern = new CodeCompletionString;
3306 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
3307 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3308 Pattern->AddPlaceholderChunk("statements");
3309 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3310 Pattern->AddTextChunk("@catch");
3311 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3312 Pattern->AddPlaceholderChunk("parameter");
3313 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3314 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3315 Pattern->AddPlaceholderChunk("statements");
3316 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3317 Pattern->AddTextChunk("@finally");
3318 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3319 Pattern->AddPlaceholderChunk("statements");
3320 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3321 Results.AddResult(Result(Pattern));
3322 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003323
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003324 // @throw
3325 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003326 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00003327 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003328 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00003329 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003330
Douglas Gregorc8bddde2010-05-28 00:22:41 +00003331 if (Results.includeCodePatterns()) {
3332 // @synchronized ( expression ) { statements }
3333 Pattern = new CodeCompletionString;
3334 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
3335 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3336 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3337 Pattern->AddPlaceholderChunk("expression");
3338 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3339 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3340 Pattern->AddPlaceholderChunk("statements");
3341 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3342 Results.AddResult(Result(Pattern));
3343 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003344}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003345
Douglas Gregorbca403c2010-01-13 23:51:12 +00003346static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003347 ResultBuilder &Results,
3348 bool NeedAt) {
John McCall0a2c5e22010-08-25 06:19:51 +00003349 typedef CodeCompletionResult Result;
Douglas Gregora4477812010-01-14 16:01:26 +00003350 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
3351 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
3352 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003353 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00003354 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003355}
3356
3357void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
3358 ResultBuilder Results(*this);
3359 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003360 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003361 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003362 HandleCodeCompleteResults(this, CodeCompleter,
3363 CodeCompletionContext::CCC_Other,
3364 Results.data(),Results.size());
Douglas Gregorc38c3e12010-01-13 21:54:15 +00003365}
3366
3367void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00003368 ResultBuilder Results(*this);
3369 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003370 AddObjCStatementResults(Results, false);
3371 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003372 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003373 HandleCodeCompleteResults(this, CodeCompleter,
3374 CodeCompletionContext::CCC_Other,
3375 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003376}
3377
3378void Sema::CodeCompleteObjCAtExpression(Scope *S) {
3379 ResultBuilder Results(*this);
3380 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00003381 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003382 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003383 HandleCodeCompleteResults(this, CodeCompleter,
3384 CodeCompletionContext::CCC_Other,
3385 Results.data(),Results.size());
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00003386}
3387
Douglas Gregor988358f2009-11-19 00:14:45 +00003388/// \brief Determine whether the addition of the given flag to an Objective-C
3389/// property's attributes will cause a conflict.
3390static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
3391 // Check if we've already added this flag.
3392 if (Attributes & NewFlag)
3393 return true;
3394
3395 Attributes |= NewFlag;
3396
3397 // Check for collisions with "readonly".
3398 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
3399 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
3400 ObjCDeclSpec::DQ_PR_assign |
3401 ObjCDeclSpec::DQ_PR_copy |
3402 ObjCDeclSpec::DQ_PR_retain)))
3403 return true;
3404
3405 // Check for more than one of { assign, copy, retain }.
3406 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
3407 ObjCDeclSpec::DQ_PR_copy |
3408 ObjCDeclSpec::DQ_PR_retain);
3409 if (AssignCopyRetMask &&
3410 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
3411 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
3412 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
3413 return true;
3414
3415 return false;
3416}
3417
Douglas Gregora93b1082009-11-18 23:08:07 +00003418void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00003419 if (!CodeCompleter)
3420 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00003421
Steve Naroffece8e712009-10-08 21:55:05 +00003422 unsigned Attributes = ODS.getPropertyAttributes();
3423
John McCall0a2c5e22010-08-25 06:19:51 +00003424 typedef CodeCompletionResult Result;
Steve Naroffece8e712009-10-08 21:55:05 +00003425 ResultBuilder Results(*this);
3426 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00003427 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
John McCall0a2c5e22010-08-25 06:19:51 +00003428 Results.AddResult(CodeCompletionResult("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003429 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
John McCall0a2c5e22010-08-25 06:19:51 +00003430 Results.AddResult(CodeCompletionResult("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003431 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
John McCall0a2c5e22010-08-25 06:19:51 +00003432 Results.AddResult(CodeCompletionResult("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003433 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
John McCall0a2c5e22010-08-25 06:19:51 +00003434 Results.AddResult(CodeCompletionResult("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003435 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
John McCall0a2c5e22010-08-25 06:19:51 +00003436 Results.AddResult(CodeCompletionResult("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003437 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
John McCall0a2c5e22010-08-25 06:19:51 +00003438 Results.AddResult(CodeCompletionResult("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00003439 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003440 CodeCompletionString *Setter = new CodeCompletionString;
3441 Setter->AddTypedTextChunk("setter");
3442 Setter->AddTextChunk(" = ");
3443 Setter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003444 Results.AddResult(CodeCompletionResult(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003445 }
Douglas Gregor988358f2009-11-19 00:14:45 +00003446 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00003447 CodeCompletionString *Getter = new CodeCompletionString;
3448 Getter->AddTypedTextChunk("getter");
3449 Getter->AddTextChunk(" = ");
3450 Getter->AddPlaceholderChunk("method");
John McCall0a2c5e22010-08-25 06:19:51 +00003451 Results.AddResult(CodeCompletionResult(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00003452 }
Steve Naroffece8e712009-10-08 21:55:05 +00003453 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003454 HandleCodeCompleteResults(this, CodeCompleter,
3455 CodeCompletionContext::CCC_Other,
3456 Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00003457}
Steve Naroffc4df6d22009-11-07 02:08:14 +00003458
Douglas Gregor4ad96852009-11-19 07:41:15 +00003459/// \brief Descripts the kind of Objective-C method that we want to find
3460/// via code completion.
3461enum ObjCMethodKind {
3462 MK_Any, //< Any kind of method, provided it means other specified criteria.
3463 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
3464 MK_OneArgSelector //< One-argument selector.
3465};
3466
3467static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
3468 ObjCMethodKind WantKind,
3469 IdentifierInfo **SelIdents,
3470 unsigned NumSelIdents) {
3471 Selector Sel = Method->getSelector();
3472 if (NumSelIdents > Sel.getNumArgs())
3473 return false;
3474
3475 switch (WantKind) {
3476 case MK_Any: break;
3477 case MK_ZeroArgSelector: return Sel.isUnarySelector();
3478 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
3479 }
3480
3481 for (unsigned I = 0; I != NumSelIdents; ++I)
3482 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
3483 return false;
3484
3485 return true;
3486}
3487
Douglas Gregor36ecb042009-11-17 23:22:23 +00003488/// \brief Add all of the Objective-C methods in the given Objective-C
3489/// container to the set of results.
3490///
3491/// The container will be a class, protocol, category, or implementation of
3492/// any of the above. This mether will recurse to include methods from
3493/// the superclasses of classes along with their categories, protocols, and
3494/// implementations.
3495///
3496/// \param Container the container in which we'll look to find methods.
3497///
3498/// \param WantInstance whether to add instance methods (only); if false, this
3499/// routine will add factory methods (only).
3500///
3501/// \param CurContext the context in which we're performing the lookup that
3502/// finds methods.
3503///
3504/// \param Results the structure into which we'll add results.
3505static void AddObjCMethods(ObjCContainerDecl *Container,
3506 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003507 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00003508 IdentifierInfo **SelIdents,
3509 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00003510 DeclContext *CurContext,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003511 ResultBuilder &Results,
3512 bool InOriginalClass = true) {
John McCall0a2c5e22010-08-25 06:19:51 +00003513 typedef CodeCompletionResult Result;
Douglas Gregor36ecb042009-11-17 23:22:23 +00003514 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3515 MEnd = Container->meth_end();
3516 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00003517 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3518 // Check whether the selector identifiers we've been given are a
3519 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003520 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00003521 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003522
Douglas Gregord3c68542009-11-19 01:08:35 +00003523 Result R = Result(*M, 0);
3524 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003525 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor408be5a2010-08-25 01:08:01 +00003526 if (!InOriginalClass)
3527 R.Priority += CCD_InBaseClass;
Douglas Gregord3c68542009-11-19 01:08:35 +00003528 Results.MaybeAddResult(R, CurContext);
3529 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00003530 }
3531
3532 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
3533 if (!IFace)
3534 return;
3535
3536 // Add methods in protocols.
3537 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
3538 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3539 E = Protocols.end();
3540 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003541 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003542 CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003543
3544 // Add methods in categories.
3545 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
3546 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00003547 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003548 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003549
3550 // Add a categories protocol methods.
3551 const ObjCList<ObjCProtocolDecl> &Protocols
3552 = CatDecl->getReferencedProtocols();
3553 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3554 E = Protocols.end();
3555 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003556 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003557 NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003558
3559 // Add methods in category implementations.
3560 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003561 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003562 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003563 }
3564
3565 // Add methods in superclass.
3566 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003567 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003568 SelIdents, NumSelIdents, CurContext, Results, false);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003569
3570 // Add methods in our implementation, if any.
3571 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003572 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
Douglas Gregor408be5a2010-08-25 01:08:01 +00003573 NumSelIdents, CurContext, Results, InOriginalClass);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003574}
3575
3576
John McCalld226f652010-08-21 09:40:31 +00003577void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
3578 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003579 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003580 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003581
3582 // Try to find the interface where getters might live.
John McCalld226f652010-08-21 09:40:31 +00003583 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003584 if (!Class) {
3585 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003586 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003587 Class = Category->getClassInterface();
3588
3589 if (!Class)
3590 return;
3591 }
3592
3593 // Find all of the potential getters.
3594 ResultBuilder Results(*this);
3595 Results.EnterNewScope();
3596
3597 // FIXME: We need to do this because Objective-C methods don't get
3598 // pushed into DeclContexts early enough. Argh!
3599 for (unsigned I = 0; I != NumMethods; ++I) {
3600 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003601 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003602 if (Method->isInstanceMethod() &&
3603 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
3604 Result R = Result(Method, 0);
3605 R.AllParametersAreInformative = true;
3606 Results.MaybeAddResult(R, CurContext);
3607 }
3608 }
3609
3610 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
3611 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003612 HandleCodeCompleteResults(this, CodeCompleter,
3613 CodeCompletionContext::CCC_Other,
3614 Results.data(),Results.size());
Douglas Gregor4ad96852009-11-19 07:41:15 +00003615}
3616
John McCalld226f652010-08-21 09:40:31 +00003617void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
3618 Decl **Methods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00003619 unsigned NumMethods) {
John McCall0a2c5e22010-08-25 06:19:51 +00003620 typedef CodeCompletionResult Result;
Douglas Gregor4ad96852009-11-19 07:41:15 +00003621
3622 // Try to find the interface where setters might live.
3623 ObjCInterfaceDecl *Class
John McCalld226f652010-08-21 09:40:31 +00003624 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
Douglas Gregor4ad96852009-11-19 07:41:15 +00003625 if (!Class) {
3626 if (ObjCCategoryDecl *Category
John McCalld226f652010-08-21 09:40:31 +00003627 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003628 Class = Category->getClassInterface();
3629
3630 if (!Class)
3631 return;
3632 }
3633
3634 // Find all of the potential getters.
3635 ResultBuilder Results(*this);
3636 Results.EnterNewScope();
3637
3638 // FIXME: We need to do this because Objective-C methods don't get
3639 // pushed into DeclContexts early enough. Argh!
3640 for (unsigned I = 0; I != NumMethods; ++I) {
3641 if (ObjCMethodDecl *Method
John McCalld226f652010-08-21 09:40:31 +00003642 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
Douglas Gregor4ad96852009-11-19 07:41:15 +00003643 if (Method->isInstanceMethod() &&
3644 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3645 Result R = Result(Method, 0);
3646 R.AllParametersAreInformative = true;
3647 Results.MaybeAddResult(R, CurContext);
3648 }
3649 }
3650
3651 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3652
3653 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003654 HandleCodeCompleteResults(this, CodeCompleter,
3655 CodeCompletionContext::CCC_Other,
3656 Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003657}
3658
Douglas Gregord32b0222010-08-24 01:06:58 +00003659void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
John McCall0a2c5e22010-08-25 06:19:51 +00003660 typedef CodeCompletionResult Result;
Douglas Gregord32b0222010-08-24 01:06:58 +00003661 ResultBuilder Results(*this);
3662 Results.EnterNewScope();
3663
3664 // Add context-sensitive, Objective-C parameter-passing keywords.
3665 bool AddedInOut = false;
3666 if ((DS.getObjCDeclQualifier() &
3667 (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
3668 Results.AddResult("in");
3669 Results.AddResult("inout");
3670 AddedInOut = true;
3671 }
3672 if ((DS.getObjCDeclQualifier() &
3673 (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
3674 Results.AddResult("out");
3675 if (!AddedInOut)
3676 Results.AddResult("inout");
3677 }
3678 if ((DS.getObjCDeclQualifier() &
3679 (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
3680 ObjCDeclSpec::DQ_Oneway)) == 0) {
3681 Results.AddResult("bycopy");
3682 Results.AddResult("byref");
3683 Results.AddResult("oneway");
3684 }
3685
3686 // Add various builtin type names and specifiers.
3687 AddOrdinaryNameResults(PCC_Type, S, *this, Results);
3688 Results.ExitScope();
3689
3690 // Add the various type names
3691 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3692 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3693 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3694 CodeCompleter->includeGlobals());
3695
3696 if (CodeCompleter->includeMacros())
3697 AddMacroResults(PP, Results);
3698
3699 HandleCodeCompleteResults(this, CodeCompleter,
3700 CodeCompletionContext::CCC_Type,
3701 Results.data(), Results.size());
3702}
3703
Douglas Gregor22f56992010-04-06 19:22:33 +00003704/// \brief When we have an expression with type "id", we may assume
3705/// that it has some more-specific class type based on knowledge of
3706/// common uses of Objective-C. This routine returns that class type,
3707/// or NULL if no better result could be determined.
3708static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3709 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3710 if (!Msg)
3711 return 0;
3712
3713 Selector Sel = Msg->getSelector();
3714 if (Sel.isNull())
3715 return 0;
3716
3717 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3718 if (!Id)
3719 return 0;
3720
3721 ObjCMethodDecl *Method = Msg->getMethodDecl();
3722 if (!Method)
3723 return 0;
3724
3725 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003726 ObjCInterfaceDecl *IFace = 0;
3727 switch (Msg->getReceiverKind()) {
3728 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003729 if (const ObjCObjectType *ObjType
3730 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3731 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003732 break;
3733
3734 case ObjCMessageExpr::Instance: {
3735 QualType T = Msg->getInstanceReceiver()->getType();
3736 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3737 IFace = Ptr->getInterfaceDecl();
3738 break;
3739 }
3740
3741 case ObjCMessageExpr::SuperInstance:
3742 case ObjCMessageExpr::SuperClass:
3743 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003744 }
3745
3746 if (!IFace)
3747 return 0;
3748
3749 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3750 if (Method->isInstanceMethod())
3751 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3752 .Case("retain", IFace)
3753 .Case("autorelease", IFace)
3754 .Case("copy", IFace)
3755 .Case("copyWithZone", IFace)
3756 .Case("mutableCopy", IFace)
3757 .Case("mutableCopyWithZone", IFace)
3758 .Case("awakeFromCoder", IFace)
3759 .Case("replacementObjectFromCoder", IFace)
3760 .Case("class", IFace)
3761 .Case("classForCoder", IFace)
3762 .Case("superclass", Super)
3763 .Default(0);
3764
3765 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3766 .Case("new", IFace)
3767 .Case("alloc", IFace)
3768 .Case("allocWithZone", IFace)
3769 .Case("class", IFace)
3770 .Case("superclass", Super)
3771 .Default(0);
3772}
3773
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003774void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
John McCall0a2c5e22010-08-25 06:19:51 +00003775 typedef CodeCompletionResult Result;
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003776 ResultBuilder Results(*this);
3777
3778 // Find anything that looks like it could be a message receiver.
3779 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3780 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3781 Results.EnterNewScope();
Douglas Gregor8071e422010-08-15 06:18:01 +00003782 LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3783 CodeCompleter->includeGlobals());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003784
3785 // If we are in an Objective-C method inside a class that has a superclass,
3786 // add "super" as an option.
3787 if (ObjCMethodDecl *Method = getCurMethodDecl())
3788 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3789 if (Iface->getSuperClass())
3790 Results.AddResult(Result("super"));
3791
3792 Results.ExitScope();
3793
3794 if (CodeCompleter->includeMacros())
3795 AddMacroResults(PP, Results);
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003796 HandleCodeCompleteResults(this, CodeCompleter,
3797 CodeCompletionContext::CCC_ObjCMessageReceiver,
3798 Results.data(), Results.size());
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003799
3800}
3801
Douglas Gregor2725ca82010-04-21 19:57:20 +00003802void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3803 IdentifierInfo **SelIdents,
3804 unsigned NumSelIdents) {
3805 ObjCInterfaceDecl *CDecl = 0;
3806 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3807 // Figure out which interface we're in.
3808 CDecl = CurMethod->getClassInterface();
3809 if (!CDecl)
3810 return;
3811
3812 // Find the superclass of this class.
3813 CDecl = CDecl->getSuperClass();
3814 if (!CDecl)
3815 return;
3816
3817 if (CurMethod->isInstanceMethod()) {
3818 // We are inside an instance method, which means that the message
3819 // send [super ...] is actually calling an instance method on the
3820 // current object. Build the super expression and handle this like
3821 // an instance method.
3822 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3823 SuperTy = Context.getObjCObjectPointerType(SuperTy);
John McCall60d7b3a2010-08-24 06:29:42 +00003824 ExprResult Super
Douglas Gregor2725ca82010-04-21 19:57:20 +00003825 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3826 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3827 SelIdents, NumSelIdents);
3828 }
3829
3830 // Fall through to send to the superclass in CDecl.
3831 } else {
3832 // "super" may be the name of a type or variable. Figure out which
3833 // it is.
3834 IdentifierInfo *Super = &Context.Idents.get("super");
3835 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3836 LookupOrdinaryName);
3837 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3838 // "super" names an interface. Use it.
3839 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003840 if (const ObjCObjectType *Iface
3841 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3842 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003843 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3844 // "super" names an unresolved type; we can't be more specific.
3845 } else {
3846 // Assume that "super" names some kind of value and parse that way.
3847 CXXScopeSpec SS;
3848 UnqualifiedId id;
3849 id.setIdentifier(Super, SuperLoc);
John McCall60d7b3a2010-08-24 06:29:42 +00003850 ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003851 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3852 SelIdents, NumSelIdents);
3853 }
3854
3855 // Fall through
3856 }
3857
John McCallb3d87482010-08-24 05:47:05 +00003858 ParsedType Receiver;
Douglas Gregor2725ca82010-04-21 19:57:20 +00003859 if (CDecl)
John McCallb3d87482010-08-24 05:47:05 +00003860 Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
Douglas Gregor2725ca82010-04-21 19:57:20 +00003861 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3862 NumSelIdents);
3863}
3864
John McCallb3d87482010-08-24 05:47:05 +00003865void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003866 IdentifierInfo **SelIdents,
3867 unsigned NumSelIdents) {
John McCall0a2c5e22010-08-25 06:19:51 +00003868 typedef CodeCompletionResult Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003869 ObjCInterfaceDecl *CDecl = 0;
3870
Douglas Gregor24a069f2009-11-17 17:59:40 +00003871 // If the given name refers to an interface type, retrieve the
3872 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003873 if (Receiver) {
3874 QualType T = GetTypeFromParser(Receiver, 0);
3875 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003876 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3877 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003878 }
3879
Douglas Gregor36ecb042009-11-17 23:22:23 +00003880 // Add all of the factory methods in this Objective-C class, its protocols,
3881 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003882 ResultBuilder Results(*this);
3883 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003884
3885 if (CDecl)
3886 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3887 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003888 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003889 // We're messaging "id" as a type; provide all class/factory methods.
3890
Douglas Gregor719770d2010-04-06 17:30:22 +00003891 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003892 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003893 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003894 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3895 I != N; ++I) {
3896 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003897 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003898 continue;
3899
Sebastian Redldb9d2142010-08-02 23:18:59 +00003900 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00003901 }
3902 }
3903
Sebastian Redldb9d2142010-08-02 23:18:59 +00003904 for (GlobalMethodPool::iterator M = MethodPool.begin(),
3905 MEnd = MethodPool.end();
3906 M != MEnd; ++M) {
3907 for (ObjCMethodList *MethList = &M->second.second;
3908 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003909 MethList = MethList->Next) {
3910 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3911 NumSelIdents))
3912 continue;
3913
3914 Result R(MethList->Method, 0);
3915 R.StartParameter = NumSelIdents;
3916 R.AllParametersAreInformative = false;
3917 Results.MaybeAddResult(R, CurContext);
3918 }
3919 }
3920 }
3921
Steve Naroffc4df6d22009-11-07 02:08:14 +00003922 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00003923 HandleCodeCompleteResults(this, CodeCompleter,
3924 CodeCompletionContext::CCC_Other,
3925 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003926}
3927
Douglas Gregord3c68542009-11-19 01:08:35 +00003928void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3929 IdentifierInfo **SelIdents,
3930 unsigned NumSelIdents) {
John McCall0a2c5e22010-08-25 06:19:51 +00003931 typedef CodeCompletionResult Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003932
3933 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003934
Douglas Gregor36ecb042009-11-17 23:22:23 +00003935 // If necessary, apply function/array conversion to the receiver.
3936 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003937 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003938 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003939
Douglas Gregor36ecb042009-11-17 23:22:23 +00003940 // Build the set of methods we can see.
3941 ResultBuilder Results(*this);
3942 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003943
3944 // If we're messaging an expression with type "id" or "Class", check
3945 // whether we know something special about the receiver that allows
3946 // us to assume a more-specific receiver type.
3947 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3948 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3949 ReceiverType = Context.getObjCObjectPointerType(
3950 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003951
Douglas Gregorf74a4192009-11-18 00:06:18 +00003952 // Handle messages to Class. This really isn't a message to an instance
3953 // method, so we treat it the same way we would treat a message send to a
3954 // class method.
3955 if (ReceiverType->isObjCClassType() ||
3956 ReceiverType->isObjCQualifiedClassType()) {
3957 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3958 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003959 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3960 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003961 }
3962 }
3963 // Handle messages to a qualified ID ("id<foo>").
3964 else if (const ObjCObjectPointerType *QualID
3965 = ReceiverType->getAsObjCQualifiedIdType()) {
3966 // Search protocols for instance methods.
3967 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3968 E = QualID->qual_end();
3969 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003970 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3971 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003972 }
3973 // Handle messages to a pointer to interface type.
3974 else if (const ObjCObjectPointerType *IFacePtr
3975 = ReceiverType->getAsObjCInterfacePointerType()) {
3976 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003977 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3978 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003979
3980 // Search protocols for instance methods.
3981 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3982 E = IFacePtr->qual_end();
3983 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003984 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3985 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003986 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003987 // Handle messages to "id".
3988 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003989 // We're messaging "id", so provide all instance methods we know
3990 // about as code-completion results.
3991
3992 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00003993 // pool from the AST file.
Douglas Gregor719770d2010-04-06 17:30:22 +00003994 if (ExternalSource) {
John McCall76bd1f32010-06-01 09:23:16 +00003995 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
3996 I != N; ++I) {
3997 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00003998 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor719770d2010-04-06 17:30:22 +00003999 continue;
4000
Sebastian Redldb9d2142010-08-02 23:18:59 +00004001 ReadMethodPool(Sel);
Douglas Gregor719770d2010-04-06 17:30:22 +00004002 }
4003 }
4004
Sebastian Redldb9d2142010-08-02 23:18:59 +00004005 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4006 MEnd = MethodPool.end();
4007 M != MEnd; ++M) {
4008 for (ObjCMethodList *MethList = &M->second.first;
4009 MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00004010 MethList = MethList->Next) {
4011 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4012 NumSelIdents))
4013 continue;
4014
4015 Result R(MethList->Method, 0);
4016 R.StartParameter = NumSelIdents;
4017 R.AllParametersAreInformative = false;
4018 Results.MaybeAddResult(R, CurContext);
4019 }
4020 }
4021 }
4022
Steve Naroffc4df6d22009-11-07 02:08:14 +00004023 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004024 HandleCodeCompleteResults(this, CodeCompleter,
4025 CodeCompletionContext::CCC_Other,
4026 Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00004027}
Douglas Gregor55385fe2009-11-18 04:19:12 +00004028
Douglas Gregorfb629412010-08-23 21:17:50 +00004029void Sema::CodeCompleteObjCForCollection(Scope *S,
4030 DeclGroupPtrTy IterationVar) {
4031 CodeCompleteExpressionData Data;
4032 Data.ObjCCollection = true;
4033
4034 if (IterationVar.getAsOpaquePtr()) {
4035 DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
4036 for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
4037 if (*I)
4038 Data.IgnoreDecls.push_back(*I);
4039 }
4040 }
4041
4042 CodeCompleteExpression(S, Data);
4043}
4044
Douglas Gregor55385fe2009-11-18 04:19:12 +00004045/// \brief Add all of the protocol declarations that we find in the given
4046/// (translation unit) context.
4047static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00004048 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00004049 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004050 typedef CodeCompletionResult Result;
Douglas Gregor55385fe2009-11-18 04:19:12 +00004051
4052 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4053 DEnd = Ctx->decls_end();
4054 D != DEnd; ++D) {
4055 // Record any protocols we find.
4056 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00004057 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004058 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004059
4060 // Record any forward-declared protocols we find.
4061 if (ObjCForwardProtocolDecl *Forward
4062 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
4063 for (ObjCForwardProtocolDecl::protocol_iterator
4064 P = Forward->protocol_begin(),
4065 PEnd = Forward->protocol_end();
4066 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00004067 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00004068 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004069 }
4070 }
4071}
4072
4073void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
4074 unsigned NumProtocols) {
4075 ResultBuilder Results(*this);
4076 Results.EnterNewScope();
4077
4078 // Tell the result set to ignore all of the protocols we have
4079 // already seen.
4080 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004081 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
4082 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00004083 Results.Ignore(Protocol);
4084
4085 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00004086 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
4087 Results);
4088
4089 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004090 HandleCodeCompleteResults(this, CodeCompleter,
4091 CodeCompletionContext::CCC_ObjCProtocolName,
4092 Results.data(),Results.size());
Douglas Gregor083128f2009-11-18 04:49:41 +00004093}
4094
4095void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
4096 ResultBuilder Results(*this);
4097 Results.EnterNewScope();
4098
4099 // Add all protocols.
4100 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
4101 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00004102
4103 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004104 HandleCodeCompleteResults(this, CodeCompleter,
4105 CodeCompletionContext::CCC_ObjCProtocolName,
4106 Results.data(),Results.size());
Douglas Gregor55385fe2009-11-18 04:19:12 +00004107}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004108
4109/// \brief Add all of the Objective-C interface declarations that we find in
4110/// the given (translation unit) context.
4111static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
4112 bool OnlyForwardDeclarations,
4113 bool OnlyUnimplemented,
4114 ResultBuilder &Results) {
John McCall0a2c5e22010-08-25 06:19:51 +00004115 typedef CodeCompletionResult Result;
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004116
4117 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
4118 DEnd = Ctx->decls_end();
4119 D != DEnd; ++D) {
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004120 // Record any interfaces we find.
4121 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
4122 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
4123 (!OnlyUnimplemented || !Class->getImplementation()))
4124 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004125
4126 // Record any forward-declared interfaces we find.
4127 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
4128 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
Douglas Gregordeacbdc2010-08-11 12:19:30 +00004129 C != CEnd; ++C)
4130 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
4131 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
4132 Results.AddResult(Result(C->getInterface(), 0), CurContext,
Douglas Gregor608300b2010-01-14 16:14:35 +00004133 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004134 }
4135 }
4136}
4137
4138void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
4139 ResultBuilder Results(*this);
4140 Results.EnterNewScope();
4141
4142 // Add all classes.
4143 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
4144 false, Results);
4145
4146 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004147 HandleCodeCompleteResults(this, CodeCompleter,
4148 CodeCompletionContext::CCC_Other,
4149 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004150}
4151
Douglas Gregorc83c6872010-04-15 22:33:43 +00004152void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
4153 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004154 ResultBuilder Results(*this);
4155 Results.EnterNewScope();
4156
4157 // Make sure that we ignore the class we're currently defining.
4158 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004159 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004160 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004161 Results.Ignore(CurClass);
4162
4163 // Add all classes.
4164 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4165 false, Results);
4166
4167 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004168 HandleCodeCompleteResults(this, CodeCompleter,
4169 CodeCompletionContext::CCC_Other,
4170 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004171}
4172
4173void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
4174 ResultBuilder Results(*this);
4175 Results.EnterNewScope();
4176
4177 // Add all unimplemented classes.
4178 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
4179 true, Results);
4180
4181 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004182 HandleCodeCompleteResults(this, CodeCompleter,
4183 CodeCompletionContext::CCC_Other,
4184 Results.data(),Results.size());
Douglas Gregor3b49aca2009-11-18 16:26:39 +00004185}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004186
4187void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004188 IdentifierInfo *ClassName,
4189 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004190 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004191
4192 ResultBuilder Results(*this);
4193
4194 // Ignore any categories we find that have already been implemented by this
4195 // interface.
4196 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4197 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004198 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004199 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
4200 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4201 Category = Category->getNextClassCategory())
4202 CategoryNames.insert(Category->getIdentifier());
4203
4204 // Add all of the categories we know about.
4205 Results.EnterNewScope();
4206 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
4207 for (DeclContext::decl_iterator D = TU->decls_begin(),
4208 DEnd = TU->decls_end();
4209 D != DEnd; ++D)
4210 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
4211 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004212 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004213 Results.ExitScope();
4214
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004215 HandleCodeCompleteResults(this, CodeCompleter,
4216 CodeCompletionContext::CCC_Other,
4217 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004218}
4219
4220void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00004221 IdentifierInfo *ClassName,
4222 SourceLocation ClassNameLoc) {
John McCall0a2c5e22010-08-25 06:19:51 +00004223 typedef CodeCompletionResult Result;
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004224
4225 // Find the corresponding interface. If we couldn't find the interface, the
4226 // program itself is ill-formed. However, we'll try to be helpful still by
4227 // providing the list of all of the categories we know about.
4228 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00004229 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004230 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
4231 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00004232 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004233
4234 ResultBuilder Results(*this);
4235
4236 // Add all of the categories that have have corresponding interface
4237 // declarations in this class and any of its superclasses, except for
4238 // already-implemented categories in the class itself.
4239 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
4240 Results.EnterNewScope();
4241 bool IgnoreImplemented = true;
4242 while (Class) {
4243 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
4244 Category = Category->getNextClassCategory())
4245 if ((!IgnoreImplemented || !Category->getImplementation()) &&
4246 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00004247 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004248
4249 Class = Class->getSuperClass();
4250 IgnoreImplemented = false;
4251 }
4252 Results.ExitScope();
4253
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004254 HandleCodeCompleteResults(this, CodeCompleter,
4255 CodeCompletionContext::CCC_Other,
4256 Results.data(),Results.size());
Douglas Gregor33ced0b2009-11-18 19:08:43 +00004257}
Douglas Gregor322328b2009-11-18 22:32:06 +00004258
John McCalld226f652010-08-21 09:40:31 +00004259void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004260 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004261 ResultBuilder Results(*this);
4262
4263 // Figure out where this @synthesize lives.
4264 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004265 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004266 if (!Container ||
4267 (!isa<ObjCImplementationDecl>(Container) &&
4268 !isa<ObjCCategoryImplDecl>(Container)))
4269 return;
4270
4271 // Ignore any properties that have already been implemented.
4272 for (DeclContext::decl_iterator D = Container->decls_begin(),
4273 DEnd = Container->decls_end();
4274 D != DEnd; ++D)
4275 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
4276 Results.Ignore(PropertyImpl->getPropertyDecl());
4277
4278 // Add any properties that we find.
4279 Results.EnterNewScope();
4280 if (ObjCImplementationDecl *ClassImpl
4281 = dyn_cast<ObjCImplementationDecl>(Container))
4282 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
4283 Results);
4284 else
4285 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
4286 false, CurContext, Results);
4287 Results.ExitScope();
4288
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004289 HandleCodeCompleteResults(this, CodeCompleter,
4290 CodeCompletionContext::CCC_Other,
4291 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004292}
4293
4294void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
4295 IdentifierInfo *PropertyName,
John McCalld226f652010-08-21 09:40:31 +00004296 Decl *ObjCImpDecl) {
John McCall0a2c5e22010-08-25 06:19:51 +00004297 typedef CodeCompletionResult Result;
Douglas Gregor322328b2009-11-18 22:32:06 +00004298 ResultBuilder Results(*this);
4299
4300 // Figure out where this @synthesize lives.
4301 ObjCContainerDecl *Container
John McCalld226f652010-08-21 09:40:31 +00004302 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
Douglas Gregor322328b2009-11-18 22:32:06 +00004303 if (!Container ||
4304 (!isa<ObjCImplementationDecl>(Container) &&
4305 !isa<ObjCCategoryImplDecl>(Container)))
4306 return;
4307
4308 // Figure out which interface we're looking into.
4309 ObjCInterfaceDecl *Class = 0;
4310 if (ObjCImplementationDecl *ClassImpl
4311 = dyn_cast<ObjCImplementationDecl>(Container))
4312 Class = ClassImpl->getClassInterface();
4313 else
4314 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
4315 ->getClassInterface();
4316
4317 // Add all of the instance variables in this class and its superclasses.
4318 Results.EnterNewScope();
4319 for(; Class; Class = Class->getSuperClass()) {
4320 // FIXME: We could screen the type of each ivar for compatibility with
4321 // the property, but is that being too paternal?
4322 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
4323 IVarEnd = Class->ivar_end();
4324 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00004325 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00004326 }
4327 Results.ExitScope();
4328
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004329 HandleCodeCompleteResults(this, CodeCompleter,
4330 CodeCompletionContext::CCC_Other,
4331 Results.data(),Results.size());
Douglas Gregor322328b2009-11-18 22:32:06 +00004332}
Douglas Gregore8f5a172010-04-07 00:21:17 +00004333
Douglas Gregor408be5a2010-08-25 01:08:01 +00004334// Mapping from selectors to the methods that implement that selector, along
4335// with the "in original class" flag.
4336typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
4337 KnownMethodsMap;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004338
4339/// \brief Find all of the methods that reside in the given container
4340/// (and its superclasses, protocols, etc.) that meet the given
4341/// criteria. Insert those methods into the map of known methods,
4342/// indexed by selector so they can be easily found.
4343static void FindImplementableMethods(ASTContext &Context,
4344 ObjCContainerDecl *Container,
4345 bool WantInstanceMethods,
4346 QualType ReturnType,
4347 bool IsInImplementation,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004348 KnownMethodsMap &KnownMethods,
4349 bool InOriginalClass = true) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004350 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
4351 // Recurse into protocols.
4352 const ObjCList<ObjCProtocolDecl> &Protocols
4353 = IFace->getReferencedProtocols();
4354 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4355 E = Protocols.end();
4356 I != E; ++I)
4357 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004358 IsInImplementation, KnownMethods,
4359 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004360
4361 // If we're not in the implementation of a class, also visit the
4362 // superclass.
4363 if (!IsInImplementation && IFace->getSuperClass())
4364 FindImplementableMethods(Context, IFace->getSuperClass(),
4365 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004366 IsInImplementation, KnownMethods,
4367 false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004368
4369 // Add methods from any class extensions (but not from categories;
4370 // those should go into category implementations).
Fariborz Jahanian80aa1cd2010-06-22 23:20:40 +00004371 for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
4372 Cat = Cat->getNextClassExtension())
4373 FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
4374 WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004375 IsInImplementation, KnownMethods,
4376 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004377 }
4378
4379 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4380 // Recurse into protocols.
4381 const ObjCList<ObjCProtocolDecl> &Protocols
4382 = Category->getReferencedProtocols();
4383 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4384 E = Protocols.end();
4385 I != E; ++I)
4386 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004387 IsInImplementation, KnownMethods,
4388 InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004389 }
4390
4391 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4392 // Recurse into protocols.
4393 const ObjCList<ObjCProtocolDecl> &Protocols
4394 = Protocol->getReferencedProtocols();
4395 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4396 E = Protocols.end();
4397 I != E; ++I)
4398 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
Douglas Gregor408be5a2010-08-25 01:08:01 +00004399 IsInImplementation, KnownMethods, false);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004400 }
4401
4402 // Add methods in this container. This operation occurs last because
4403 // we want the methods from this container to override any methods
4404 // we've previously seen with the same selector.
4405 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4406 MEnd = Container->meth_end();
4407 M != MEnd; ++M) {
4408 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
4409 if (!ReturnType.isNull() &&
4410 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
4411 continue;
4412
Douglas Gregor408be5a2010-08-25 01:08:01 +00004413 KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004414 }
4415 }
4416}
4417
4418void Sema::CodeCompleteObjCMethodDecl(Scope *S,
4419 bool IsInstanceMethod,
John McCallb3d87482010-08-24 05:47:05 +00004420 ParsedType ReturnTy,
John McCalld226f652010-08-21 09:40:31 +00004421 Decl *IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004422 // Determine the return type of the method we're declaring, if
4423 // provided.
4424 QualType ReturnType = GetTypeFromParser(ReturnTy);
4425
4426 // Determine where we should start searching for methods, and where we
4427 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
4428 bool IsInImplementation = false;
John McCalld226f652010-08-21 09:40:31 +00004429 if (Decl *D = IDecl) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004430 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
4431 SearchDecl = Impl->getClassInterface();
4432 CurrentDecl = Impl;
4433 IsInImplementation = true;
4434 } else if (ObjCCategoryImplDecl *CatImpl
4435 = dyn_cast<ObjCCategoryImplDecl>(D)) {
4436 SearchDecl = CatImpl->getCategoryDecl();
4437 CurrentDecl = CatImpl;
4438 IsInImplementation = true;
4439 } else {
4440 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
4441 CurrentDecl = SearchDecl;
4442 }
4443 }
4444
4445 if (!SearchDecl && S) {
4446 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
4447 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
4448 CurrentDecl = SearchDecl;
4449 }
4450 }
4451
4452 if (!SearchDecl || !CurrentDecl) {
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004453 HandleCodeCompleteResults(this, CodeCompleter,
4454 CodeCompletionContext::CCC_Other,
4455 0, 0);
Douglas Gregore8f5a172010-04-07 00:21:17 +00004456 return;
4457 }
4458
4459 // Find all of the methods that we could declare/implement here.
4460 KnownMethodsMap KnownMethods;
4461 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
4462 ReturnType, IsInImplementation, KnownMethods);
4463
4464 // Erase any methods that have already been declared or
4465 // implemented here.
4466 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
4467 MEnd = CurrentDecl->meth_end();
4468 M != MEnd; ++M) {
4469 if ((*M)->isInstanceMethod() != IsInstanceMethod)
4470 continue;
4471
4472 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
4473 if (Pos != KnownMethods.end())
4474 KnownMethods.erase(Pos);
4475 }
4476
4477 // Add declarations or definitions for each of the known methods.
John McCall0a2c5e22010-08-25 06:19:51 +00004478 typedef CodeCompletionResult Result;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004479 ResultBuilder Results(*this);
4480 Results.EnterNewScope();
4481 PrintingPolicy Policy(Context.PrintingPolicy);
4482 Policy.AnonymousTagLocations = false;
4483 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
4484 MEnd = KnownMethods.end();
4485 M != MEnd; ++M) {
Douglas Gregor408be5a2010-08-25 01:08:01 +00004486 ObjCMethodDecl *Method = M->second.first;
Douglas Gregore8f5a172010-04-07 00:21:17 +00004487 CodeCompletionString *Pattern = new CodeCompletionString;
4488
4489 // If the result type was not already provided, add it to the
4490 // pattern as (type).
4491 if (ReturnType.isNull()) {
4492 std::string TypeStr;
4493 Method->getResultType().getAsStringInternal(TypeStr, Policy);
4494 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4495 Pattern->AddTextChunk(TypeStr);
4496 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4497 }
4498
4499 Selector Sel = Method->getSelector();
4500
4501 // Add the first part of the selector to the pattern.
4502 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
4503
4504 // Add parameters to the pattern.
4505 unsigned I = 0;
4506 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4507 PEnd = Method->param_end();
4508 P != PEnd; (void)++P, ++I) {
4509 // Add the part of the selector name.
4510 if (I == 0)
4511 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4512 else if (I < Sel.getNumArgs()) {
4513 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor47c03a72010-08-17 15:53:35 +00004514 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004515 Pattern->AddChunk(CodeCompletionString::CK_Colon);
4516 } else
4517 break;
4518
4519 // Add the parameter type.
4520 std::string TypeStr;
4521 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
4522 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4523 Pattern->AddTextChunk(TypeStr);
4524 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4525
4526 if (IdentifierInfo *Id = (*P)->getIdentifier())
4527 Pattern->AddTextChunk(Id->getName());
4528 }
4529
4530 if (Method->isVariadic()) {
4531 if (Method->param_size() > 0)
4532 Pattern->AddChunk(CodeCompletionString::CK_Comma);
4533 Pattern->AddTextChunk("...");
4534 }
4535
Douglas Gregor447107d2010-05-28 00:57:46 +00004536 if (IsInImplementation && Results.includeCodePatterns()) {
Douglas Gregore8f5a172010-04-07 00:21:17 +00004537 // We will be defining the method here, so add a compound statement.
4538 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4539 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
4540 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4541 if (!Method->getResultType()->isVoidType()) {
4542 // If the result type is not void, add a return clause.
4543 Pattern->AddTextChunk("return");
4544 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4545 Pattern->AddPlaceholderChunk("expression");
4546 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
4547 } else
4548 Pattern->AddPlaceholderChunk("statements");
4549
4550 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
4551 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
4552 }
4553
Douglas Gregor408be5a2010-08-25 01:08:01 +00004554 unsigned Priority = CCP_CodePattern;
4555 if (!M->second.second)
4556 Priority += CCD_InBaseClass;
4557
4558 Results.AddResult(Result(Pattern, Priority,
Douglas Gregor16ed9ad2010-08-17 16:06:07 +00004559 Method->isInstanceMethod()
4560 ? CXCursor_ObjCInstanceMethodDecl
4561 : CXCursor_ObjCClassMethodDecl));
Douglas Gregore8f5a172010-04-07 00:21:17 +00004562 }
4563
4564 Results.ExitScope();
4565
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004566 HandleCodeCompleteResults(this, CodeCompleter,
4567 CodeCompletionContext::CCC_Other,
4568 Results.data(),Results.size());
Douglas Gregore8f5a172010-04-07 00:21:17 +00004569}
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004570
4571void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
4572 bool IsInstanceMethod,
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004573 bool AtParameterName,
John McCallb3d87482010-08-24 05:47:05 +00004574 ParsedType ReturnTy,
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004575 IdentifierInfo **SelIdents,
4576 unsigned NumSelIdents) {
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004577 // If we have an external source, load the entire class method
Sebastian Redl3c7f4132010-08-18 23:57:06 +00004578 // pool from the AST file.
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004579 if (ExternalSource) {
4580 for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
4581 I != N; ++I) {
4582 Selector Sel = ExternalSource->GetExternalSelector(I);
Sebastian Redldb9d2142010-08-02 23:18:59 +00004583 if (Sel.isNull() || MethodPool.count(Sel))
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004584 continue;
Sebastian Redldb9d2142010-08-02 23:18:59 +00004585
4586 ReadMethodPool(Sel);
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004587 }
4588 }
4589
4590 // Build the set of methods we can see.
John McCall0a2c5e22010-08-25 06:19:51 +00004591 typedef CodeCompletionResult Result;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004592 ResultBuilder Results(*this);
4593
4594 if (ReturnTy)
4595 Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
Sebastian Redldb9d2142010-08-02 23:18:59 +00004596
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004597 Results.EnterNewScope();
Sebastian Redldb9d2142010-08-02 23:18:59 +00004598 for (GlobalMethodPool::iterator M = MethodPool.begin(),
4599 MEnd = MethodPool.end();
4600 M != MEnd; ++M) {
4601 for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
4602 &M->second.second;
4603 MethList && MethList->Method;
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004604 MethList = MethList->Next) {
4605 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
4606 NumSelIdents))
4607 continue;
4608
Douglas Gregor40ed9a12010-07-08 23:37:41 +00004609 if (AtParameterName) {
4610 // Suggest parameter names we've seen before.
4611 if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
4612 ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
4613 if (Param->getIdentifier()) {
4614 CodeCompletionString *Pattern = new CodeCompletionString;
4615 Pattern->AddTypedTextChunk(Param->getIdentifier()->getName());
4616 Results.AddResult(Pattern);
4617 }
4618 }
4619
4620 continue;
4621 }
4622
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004623 Result R(MethList->Method, 0);
4624 R.StartParameter = NumSelIdents;
4625 R.AllParametersAreInformative = false;
4626 R.DeclaringEntity = true;
4627 Results.MaybeAddResult(R, CurContext);
4628 }
4629 }
4630
4631 Results.ExitScope();
Douglas Gregore6b1bb62010-08-11 21:23:17 +00004632 HandleCodeCompleteResults(this, CodeCompleter,
4633 CodeCompletionContext::CCC_Other,
4634 Results.data(),Results.size());
Douglas Gregor1f5537a2010-07-08 23:20:03 +00004635}
Douglas Gregor87c08a52010-08-13 22:48:40 +00004636
Douglas Gregorf29c5232010-08-24 22:20:20 +00004637void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
Douglas Gregorf44e8542010-08-24 19:08:16 +00004638 ResultBuilder Results(*this);
4639 Results.EnterNewScope();
4640
4641 // #if <condition>
4642 CodeCompletionString *Pattern = new CodeCompletionString;
4643 Pattern->AddTypedTextChunk("if");
4644 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4645 Pattern->AddPlaceholderChunk("condition");
4646 Results.AddResult(Pattern);
4647
4648 // #ifdef <macro>
4649 Pattern = new CodeCompletionString;
4650 Pattern->AddTypedTextChunk("ifdef");
4651 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4652 Pattern->AddPlaceholderChunk("macro");
4653 Results.AddResult(Pattern);
4654
4655 // #ifndef <macro>
4656 Pattern = new CodeCompletionString;
4657 Pattern->AddTypedTextChunk("ifndef");
4658 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4659 Pattern->AddPlaceholderChunk("macro");
4660 Results.AddResult(Pattern);
4661
4662 if (InConditional) {
4663 // #elif <condition>
4664 Pattern = new CodeCompletionString;
4665 Pattern->AddTypedTextChunk("elif");
4666 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4667 Pattern->AddPlaceholderChunk("condition");
4668 Results.AddResult(Pattern);
4669
4670 // #else
4671 Pattern = new CodeCompletionString;
4672 Pattern->AddTypedTextChunk("else");
4673 Results.AddResult(Pattern);
4674
4675 // #endif
4676 Pattern = new CodeCompletionString;
4677 Pattern->AddTypedTextChunk("endif");
4678 Results.AddResult(Pattern);
4679 }
4680
4681 // #include "header"
4682 Pattern = new CodeCompletionString;
4683 Pattern->AddTypedTextChunk("include");
4684 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4685 Pattern->AddTextChunk("\"");
4686 Pattern->AddPlaceholderChunk("header");
4687 Pattern->AddTextChunk("\"");
4688 Results.AddResult(Pattern);
4689
4690 // #include <header>
4691 Pattern = new CodeCompletionString;
4692 Pattern->AddTypedTextChunk("include");
4693 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4694 Pattern->AddTextChunk("<");
4695 Pattern->AddPlaceholderChunk("header");
4696 Pattern->AddTextChunk(">");
4697 Results.AddResult(Pattern);
4698
4699 // #define <macro>
4700 Pattern = new CodeCompletionString;
4701 Pattern->AddTypedTextChunk("define");
4702 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4703 Pattern->AddPlaceholderChunk("macro");
4704 Results.AddResult(Pattern);
4705
4706 // #define <macro>(<args>)
4707 Pattern = new CodeCompletionString;
4708 Pattern->AddTypedTextChunk("define");
4709 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4710 Pattern->AddPlaceholderChunk("macro");
4711 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4712 Pattern->AddPlaceholderChunk("args");
4713 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4714 Results.AddResult(Pattern);
4715
4716 // #undef <macro>
4717 Pattern = new CodeCompletionString;
4718 Pattern->AddTypedTextChunk("undef");
4719 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4720 Pattern->AddPlaceholderChunk("macro");
4721 Results.AddResult(Pattern);
4722
4723 // #line <number>
4724 Pattern = new CodeCompletionString;
4725 Pattern->AddTypedTextChunk("line");
4726 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4727 Pattern->AddPlaceholderChunk("number");
4728 Results.AddResult(Pattern);
4729
4730 // #line <number> "filename"
4731 Pattern = new CodeCompletionString;
4732 Pattern->AddTypedTextChunk("line");
4733 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4734 Pattern->AddPlaceholderChunk("number");
4735 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4736 Pattern->AddTextChunk("\"");
4737 Pattern->AddPlaceholderChunk("filename");
4738 Pattern->AddTextChunk("\"");
4739 Results.AddResult(Pattern);
4740
4741 // #error <message>
4742 Pattern = new CodeCompletionString;
4743 Pattern->AddTypedTextChunk("error");
4744 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4745 Pattern->AddPlaceholderChunk("message");
4746 Results.AddResult(Pattern);
4747
4748 // #pragma <arguments>
4749 Pattern = new CodeCompletionString;
4750 Pattern->AddTypedTextChunk("pragma");
4751 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4752 Pattern->AddPlaceholderChunk("arguments");
4753 Results.AddResult(Pattern);
4754
4755 if (getLangOptions().ObjC1) {
4756 // #import "header"
4757 Pattern = new CodeCompletionString;
4758 Pattern->AddTypedTextChunk("import");
4759 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4760 Pattern->AddTextChunk("\"");
4761 Pattern->AddPlaceholderChunk("header");
4762 Pattern->AddTextChunk("\"");
4763 Results.AddResult(Pattern);
4764
4765 // #import <header>
4766 Pattern = new CodeCompletionString;
4767 Pattern->AddTypedTextChunk("import");
4768 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4769 Pattern->AddTextChunk("<");
4770 Pattern->AddPlaceholderChunk("header");
4771 Pattern->AddTextChunk(">");
4772 Results.AddResult(Pattern);
4773 }
4774
4775 // #include_next "header"
4776 Pattern = new CodeCompletionString;
4777 Pattern->AddTypedTextChunk("include_next");
4778 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4779 Pattern->AddTextChunk("\"");
4780 Pattern->AddPlaceholderChunk("header");
4781 Pattern->AddTextChunk("\"");
4782 Results.AddResult(Pattern);
4783
4784 // #include_next <header>
4785 Pattern = new CodeCompletionString;
4786 Pattern->AddTypedTextChunk("include_next");
4787 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4788 Pattern->AddTextChunk("<");
4789 Pattern->AddPlaceholderChunk("header");
4790 Pattern->AddTextChunk(">");
4791 Results.AddResult(Pattern);
4792
4793 // #warning <message>
4794 Pattern = new CodeCompletionString;
4795 Pattern->AddTypedTextChunk("warning");
4796 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4797 Pattern->AddPlaceholderChunk("message");
4798 Results.AddResult(Pattern);
4799
4800 // Note: #ident and #sccs are such crazy anachronisms that we don't provide
4801 // completions for them. And __include_macros is a Clang-internal extension
4802 // that we don't want to encourage anyone to use.
4803
4804 // FIXME: we don't support #assert or #unassert, so don't suggest them.
4805 Results.ExitScope();
4806
4807 // FIXME: Create a new code-completion context for this?
4808 HandleCodeCompleteResults(this, CodeCompleter,
4809 CodeCompletionContext::CCC_Other,
4810 Results.data(), Results.size());
4811}
4812
4813void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
Douglas Gregorf29c5232010-08-24 22:20:20 +00004814 CodeCompleteOrdinaryName(S,
4815 S->getFnParent()? Action::PCC_RecoveryInFunction
4816 : Action::PCC_Namespace);
Douglas Gregorf44e8542010-08-24 19:08:16 +00004817}
4818
Douglas Gregorf29c5232010-08-24 22:20:20 +00004819void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
Douglas Gregor1fbb4472010-08-24 20:21:13 +00004820 ResultBuilder Results(*this);
4821 if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
4822 // Add just the names of macros, not their arguments.
4823 Results.EnterNewScope();
4824 for (Preprocessor::macro_iterator M = PP.macro_begin(),
4825 MEnd = PP.macro_end();
4826 M != MEnd; ++M) {
4827 CodeCompletionString *Pattern = new CodeCompletionString;
4828 Pattern->AddTypedTextChunk(M->first->getName());
4829 Results.AddResult(Pattern);
4830 }
4831 Results.ExitScope();
4832 } else if (IsDefinition) {
4833 // FIXME: Can we detect when the user just wrote an include guard above?
4834 }
4835
4836 HandleCodeCompleteResults(this, CodeCompleter,
4837 IsDefinition? CodeCompletionContext::CCC_MacroName
4838 : CodeCompletionContext::CCC_MacroNameUse,
4839 Results.data(), Results.size());
4840}
4841
Douglas Gregorf29c5232010-08-24 22:20:20 +00004842void Sema::CodeCompletePreprocessorExpression() {
4843 ResultBuilder Results(*this);
4844
4845 if (!CodeCompleter || CodeCompleter->includeMacros())
4846 AddMacroResults(PP, Results);
4847
4848 // defined (<macro>)
4849 Results.EnterNewScope();
4850 CodeCompletionString *Pattern = new CodeCompletionString;
4851 Pattern->AddTypedTextChunk("defined");
4852 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
4853 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
4854 Pattern->AddPlaceholderChunk("macro");
4855 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
4856 Results.AddResult(Pattern);
4857 Results.ExitScope();
4858
4859 HandleCodeCompleteResults(this, CodeCompleter,
4860 CodeCompletionContext::CCC_PreprocessorExpression,
4861 Results.data(), Results.size());
4862}
4863
4864void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
4865 IdentifierInfo *Macro,
4866 MacroInfo *MacroInfo,
4867 unsigned Argument) {
4868 // FIXME: In the future, we could provide "overload" results, much like we
4869 // do for function calls.
4870
4871 CodeCompleteOrdinaryName(S,
4872 S->getFnParent()? Action::PCC_RecoveryInFunction
4873 : Action::PCC_Namespace);
4874}
4875
Douglas Gregor87c08a52010-08-13 22:48:40 +00004876void Sema::GatherGlobalCodeCompletions(
John McCall0a2c5e22010-08-25 06:19:51 +00004877 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
Douglas Gregor87c08a52010-08-13 22:48:40 +00004878 ResultBuilder Builder(*this);
4879
Douglas Gregor8071e422010-08-15 06:18:01 +00004880 if (!CodeCompleter || CodeCompleter->includeGlobals()) {
4881 CodeCompletionDeclConsumer Consumer(Builder,
4882 Context.getTranslationUnitDecl());
4883 LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
4884 Consumer);
4885 }
Douglas Gregor87c08a52010-08-13 22:48:40 +00004886
4887 if (!CodeCompleter || CodeCompleter->includeMacros())
4888 AddMacroResults(PP, Builder);
4889
4890 Results.clear();
4891 Results.insert(Results.end(),
4892 Builder.data(), Builder.data() + Builder.size());
4893}