1198092Srdivacky//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2198092Srdivacky//
3198092Srdivacky//                     The LLVM Compiler Infrastructure
4198092Srdivacky//
5198092Srdivacky// This file is distributed under the University of Illinois Open Source
6198092Srdivacky// License. See LICENSE.TXT for details.
7198092Srdivacky//
8198092Srdivacky//===----------------------------------------------------------------------===//
9198092Srdivacky//
10198092Srdivacky//  This file defines the code-completion semantic actions.
11198092Srdivacky//
12198092Srdivacky//===----------------------------------------------------------------------===//
13212904Sdim#include "clang/Sema/SemaInternal.h"
14212904Sdim#include "clang/AST/DeclObjC.h"
15198092Srdivacky#include "clang/AST/ExprCXX.h"
16199482Srdivacky#include "clang/AST/ExprObjC.h"
17249423Sdim#include "clang/Basic/CharInfo.h"
18234353Sdim#include "clang/Lex/HeaderSearch.h"
19198893Srdivacky#include "clang/Lex/MacroInfo.h"
20198893Srdivacky#include "clang/Lex/Preprocessor.h"
21249423Sdim#include "clang/Sema/CodeCompleteConsumer.h"
22249423Sdim#include "clang/Sema/ExternalSemaSource.h"
23249423Sdim#include "clang/Sema/Lookup.h"
24249423Sdim#include "clang/Sema/Overload.h"
25249423Sdim#include "clang/Sema/Scope.h"
26249423Sdim#include "clang/Sema/ScopeInfo.h"
27218893Sdim#include "llvm/ADT/DenseSet.h"
28234353Sdim#include "llvm/ADT/SmallBitVector.h"
29198092Srdivacky#include "llvm/ADT/SmallPtrSet.h"
30234353Sdim#include "llvm/ADT/SmallString.h"
31198092Srdivacky#include "llvm/ADT/StringExtras.h"
32207619Srdivacky#include "llvm/ADT/StringSwitch.h"
33212904Sdim#include "llvm/ADT/Twine.h"
34198092Srdivacky#include <list>
35198092Srdivacky#include <map>
36198092Srdivacky#include <vector>
37198092Srdivacky
38198092Srdivackyusing namespace clang;
39212904Sdimusing namespace sema;
40198092Srdivacky
41198092Srdivackynamespace {
42198092Srdivacky  /// \brief A container of code-completion results.
43198092Srdivacky  class ResultBuilder {
44198092Srdivacky  public:
45198092Srdivacky    /// \brief The type of a name-lookup filter, which can be provided to the
46198092Srdivacky    /// name-lookup routines to specify which declarations should be included in
47198092Srdivacky    /// the result set (when it returns true) and which declarations should be
48198092Srdivacky    /// filtered out (returns false).
49249423Sdim    typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const;
50198092Srdivacky
51212904Sdim    typedef CodeCompletionResult Result;
52198092Srdivacky
53198092Srdivacky  private:
54198092Srdivacky    /// \brief The actual results we have found.
55198092Srdivacky    std::vector<Result> Results;
56198092Srdivacky
57198092Srdivacky    /// \brief A record of all of the declarations we have found and placed
58198092Srdivacky    /// into the result set, used to ensure that no declaration ever gets into
59198092Srdivacky    /// the result set twice.
60249423Sdim    llvm::SmallPtrSet<const Decl*, 16> AllDeclsFound;
61198092Srdivacky
62249423Sdim    typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair;
63200583Srdivacky
64200583Srdivacky    /// \brief An entry in the shadow map, which is optimized to store
65200583Srdivacky    /// a single (declaration, index) mapping (the common case) but
66200583Srdivacky    /// can also store a list of (declaration, index) mappings.
67200583Srdivacky    class ShadowMapEntry {
68226633Sdim      typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
69200583Srdivacky
70200583Srdivacky      /// \brief Contains either the solitary NamedDecl * or a vector
71200583Srdivacky      /// of (declaration, index) pairs.
72249423Sdim      llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector*> DeclOrVector;
73200583Srdivacky
74200583Srdivacky      /// \brief When the entry contains a single declaration, this is
75200583Srdivacky      /// the index associated with that entry.
76200583Srdivacky      unsigned SingleDeclIndex;
77200583Srdivacky
78200583Srdivacky    public:
79200583Srdivacky      ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
80200583Srdivacky
81249423Sdim      void Add(const NamedDecl *ND, unsigned Index) {
82200583Srdivacky        if (DeclOrVector.isNull()) {
83200583Srdivacky          // 0 - > 1 elements: just set the single element information.
84200583Srdivacky          DeclOrVector = ND;
85200583Srdivacky          SingleDeclIndex = Index;
86200583Srdivacky          return;
87200583Srdivacky        }
88200583Srdivacky
89249423Sdim        if (const NamedDecl *PrevND =
90249423Sdim                DeclOrVector.dyn_cast<const NamedDecl *>()) {
91200583Srdivacky          // 1 -> 2 elements: create the vector of results and push in the
92200583Srdivacky          // existing declaration.
93200583Srdivacky          DeclIndexPairVector *Vec = new DeclIndexPairVector;
94200583Srdivacky          Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
95200583Srdivacky          DeclOrVector = Vec;
96200583Srdivacky        }
97200583Srdivacky
98200583Srdivacky        // Add the new element to the end of the vector.
99200583Srdivacky        DeclOrVector.get<DeclIndexPairVector*>()->push_back(
100200583Srdivacky                                                    DeclIndexPair(ND, Index));
101200583Srdivacky      }
102200583Srdivacky
103200583Srdivacky      void Destroy() {
104200583Srdivacky        if (DeclIndexPairVector *Vec
105200583Srdivacky              = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
106200583Srdivacky          delete Vec;
107200583Srdivacky          DeclOrVector = ((NamedDecl *)0);
108200583Srdivacky        }
109200583Srdivacky      }
110200583Srdivacky
111200583Srdivacky      // Iteration.
112200583Srdivacky      class iterator;
113200583Srdivacky      iterator begin() const;
114200583Srdivacky      iterator end() const;
115200583Srdivacky    };
116200583Srdivacky
117198092Srdivacky    /// \brief A mapping from declaration names to the declarations that have
118198092Srdivacky    /// this name within a particular scope and their index within the list of
119198092Srdivacky    /// results.
120200583Srdivacky    typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
121198092Srdivacky
122198092Srdivacky    /// \brief The semantic analysis object for which results are being
123198092Srdivacky    /// produced.
124198092Srdivacky    Sema &SemaRef;
125218893Sdim
126218893Sdim    /// \brief The allocator used to allocate new code-completion strings.
127218893Sdim    CodeCompletionAllocator &Allocator;
128234353Sdim
129234353Sdim    CodeCompletionTUInfo &CCTUInfo;
130198092Srdivacky
131198092Srdivacky    /// \brief If non-NULL, a filter function used to remove any code-completion
132198092Srdivacky    /// results that are not desirable.
133198092Srdivacky    LookupFilter Filter;
134202379Srdivacky
135202379Srdivacky    /// \brief Whether we should allow declarations as
136202379Srdivacky    /// nested-name-specifiers that would otherwise be filtered out.
137202379Srdivacky    bool AllowNestedNameSpecifiers;
138202379Srdivacky
139210299Sed    /// \brief If set, the type that we would prefer our resulting value
140210299Sed    /// declarations to have.
141210299Sed    ///
142210299Sed    /// Closely matching the preferred type gives a boost to a result's
143210299Sed    /// priority.
144210299Sed    CanQualType PreferredType;
145210299Sed
146198092Srdivacky    /// \brief A list of shadow maps, which is used to model name hiding at
147198092Srdivacky    /// different levels of, e.g., the inheritance hierarchy.
148198092Srdivacky    std::list<ShadowMap> ShadowMaps;
149198092Srdivacky
150212904Sdim    /// \brief If we're potentially referring to a C++ member function, the set
151212904Sdim    /// of qualifiers applied to the object type.
152212904Sdim    Qualifiers ObjectTypeQualifiers;
153212904Sdim
154212904Sdim    /// \brief Whether the \p ObjectTypeQualifiers field is active.
155212904Sdim    bool HasObjectTypeQualifiers;
156212904Sdim
157212904Sdim    /// \brief The selector that we prefer.
158212904Sdim    Selector PreferredSelector;
159212904Sdim
160218893Sdim    /// \brief The completion context in which we are gathering results.
161218893Sdim    CodeCompletionContext CompletionContext;
162218893Sdim
163239462Sdim    /// \brief If we are in an instance method definition, the \@implementation
164218893Sdim    /// object.
165218893Sdim    ObjCImplementationDecl *ObjCImplementation;
166249423Sdim
167218893Sdim    void AdjustResultPriorityForDecl(Result &R);
168210299Sed
169218893Sdim    void MaybeAddConstructorResults(Result R);
170218893Sdim
171198092Srdivacky  public:
172218893Sdim    explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
173234353Sdim                           CodeCompletionTUInfo &CCTUInfo,
174218893Sdim                           const CodeCompletionContext &CompletionContext,
175218893Sdim                           LookupFilter Filter = 0)
176234353Sdim      : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo),
177234353Sdim        Filter(Filter),
178218893Sdim        AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false),
179218893Sdim        CompletionContext(CompletionContext),
180218893Sdim        ObjCImplementation(0)
181218893Sdim    {
182218893Sdim      // If this is an Objective-C instance method definition, dig out the
183218893Sdim      // corresponding implementation.
184218893Sdim      switch (CompletionContext.getKind()) {
185218893Sdim      case CodeCompletionContext::CCC_Expression:
186218893Sdim      case CodeCompletionContext::CCC_ObjCMessageReceiver:
187218893Sdim      case CodeCompletionContext::CCC_ParenthesizedExpression:
188218893Sdim      case CodeCompletionContext::CCC_Statement:
189218893Sdim      case CodeCompletionContext::CCC_Recovery:
190218893Sdim        if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
191218893Sdim          if (Method->isInstanceMethod())
192218893Sdim            if (ObjCInterfaceDecl *Interface = Method->getClassInterface())
193218893Sdim              ObjCImplementation = Interface->getImplementation();
194218893Sdim        break;
195218893Sdim
196218893Sdim      default:
197218893Sdim        break;
198218893Sdim      }
199218893Sdim    }
200249423Sdim
201249423Sdim    /// \brief Determine the priority for a reference to the given declaration.
202249423Sdim    unsigned getBasePriority(const NamedDecl *D);
203249423Sdim
204208600Srdivacky    /// \brief Whether we should include code patterns in the completion
205208600Srdivacky    /// results.
206208600Srdivacky    bool includeCodePatterns() const {
207208600Srdivacky      return SemaRef.CodeCompleter &&
208212904Sdim             SemaRef.CodeCompleter->includeCodePatterns();
209208600Srdivacky    }
210208600Srdivacky
211198092Srdivacky    /// \brief Set the filter used for code-completion results.
212198092Srdivacky    void setFilter(LookupFilter Filter) {
213198092Srdivacky      this->Filter = Filter;
214198092Srdivacky    }
215198092Srdivacky
216198092Srdivacky    Result *data() { return Results.empty()? 0 : &Results.front(); }
217198092Srdivacky    unsigned size() const { return Results.size(); }
218198092Srdivacky    bool empty() const { return Results.empty(); }
219198092Srdivacky
220210299Sed    /// \brief Specify the preferred type.
221210299Sed    void setPreferredType(QualType T) {
222210299Sed      PreferredType = SemaRef.Context.getCanonicalType(T);
223210299Sed    }
224210299Sed
225212904Sdim    /// \brief Set the cv-qualifiers on the object type, for us in filtering
226212904Sdim    /// calls to member functions.
227212904Sdim    ///
228212904Sdim    /// When there are qualifiers in this set, they will be used to filter
229212904Sdim    /// out member functions that aren't available (because there will be a
230212904Sdim    /// cv-qualifier mismatch) or prefer functions with an exact qualifier
231212904Sdim    /// match.
232212904Sdim    void setObjectTypeQualifiers(Qualifiers Quals) {
233212904Sdim      ObjectTypeQualifiers = Quals;
234212904Sdim      HasObjectTypeQualifiers = true;
235212904Sdim    }
236212904Sdim
237212904Sdim    /// \brief Set the preferred selector.
238212904Sdim    ///
239212904Sdim    /// When an Objective-C method declaration result is added, and that
240212904Sdim    /// method's selector matches this preferred selector, we give that method
241212904Sdim    /// a slight priority boost.
242212904Sdim    void setPreferredSelector(Selector Sel) {
243212904Sdim      PreferredSelector = Sel;
244212904Sdim    }
245218893Sdim
246218893Sdim    /// \brief Retrieve the code-completion context for which results are
247218893Sdim    /// being collected.
248218893Sdim    const CodeCompletionContext &getCompletionContext() const {
249218893Sdim      return CompletionContext;
250218893Sdim    }
251212904Sdim
252202379Srdivacky    /// \brief Specify whether nested-name-specifiers are allowed.
253202379Srdivacky    void allowNestedNameSpecifiers(bool Allow = true) {
254202379Srdivacky      AllowNestedNameSpecifiers = Allow;
255202379Srdivacky    }
256202379Srdivacky
257218893Sdim    /// \brief Return the semantic analysis object for which we are collecting
258218893Sdim    /// code completion results.
259218893Sdim    Sema &getSema() const { return SemaRef; }
260218893Sdim
261218893Sdim    /// \brief Retrieve the allocator used to allocate code completion strings.
262218893Sdim    CodeCompletionAllocator &getAllocator() const { return Allocator; }
263234353Sdim
264234353Sdim    CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
265218893Sdim
266202379Srdivacky    /// \brief Determine whether the given declaration is at all interesting
267202379Srdivacky    /// as a code-completion result.
268202379Srdivacky    ///
269202379Srdivacky    /// \param ND the declaration that we are inspecting.
270202379Srdivacky    ///
271202379Srdivacky    /// \param AsNestedNameSpecifier will be set true if this declaration is
272202379Srdivacky    /// only interesting when it is a nested-name-specifier.
273249423Sdim    bool isInterestingDecl(const NamedDecl *ND,
274249423Sdim                           bool &AsNestedNameSpecifier) const;
275202379Srdivacky
276202379Srdivacky    /// \brief Check whether the result is hidden by the Hiding declaration.
277202379Srdivacky    ///
278202379Srdivacky    /// \returns true if the result is hidden and cannot be found, false if
279202379Srdivacky    /// the hidden result could still be found. When false, \p R may be
280202379Srdivacky    /// modified to describe how the result can be found (e.g., via extra
281202379Srdivacky    /// qualification).
282202379Srdivacky    bool CheckHiddenResult(Result &R, DeclContext *CurContext,
283249423Sdim                           const NamedDecl *Hiding);
284202379Srdivacky
285198092Srdivacky    /// \brief Add a new result to this result set (if it isn't already in one
286198092Srdivacky    /// of the shadow maps), or replace an existing result (for, e.g., a
287198092Srdivacky    /// redeclaration).
288198092Srdivacky    ///
289234353Sdim    /// \param R the result to add (if it is unique).
290198092Srdivacky    ///
291234353Sdim    /// \param CurContext the context in which this result will be named.
292198092Srdivacky    void MaybeAddResult(Result R, DeclContext *CurContext = 0);
293198092Srdivacky
294202379Srdivacky    /// \brief Add a new result to this result set, where we already know
295202379Srdivacky    /// the hiding declation (if any).
296202379Srdivacky    ///
297202379Srdivacky    /// \param R the result to add (if it is unique).
298202379Srdivacky    ///
299202379Srdivacky    /// \param CurContext the context in which this result will be named.
300202379Srdivacky    ///
301202379Srdivacky    /// \param Hiding the declaration that hides the result.
302202379Srdivacky    ///
303202379Srdivacky    /// \param InBaseClass whether the result was found in a base
304202379Srdivacky    /// class of the searched context.
305202379Srdivacky    void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
306202379Srdivacky                   bool InBaseClass);
307202379Srdivacky
308202379Srdivacky    /// \brief Add a new non-declaration result to this result set.
309202379Srdivacky    void AddResult(Result R);
310202379Srdivacky
311198092Srdivacky    /// \brief Enter into a new scope.
312198092Srdivacky    void EnterNewScope();
313198092Srdivacky
314198092Srdivacky    /// \brief Exit from the current scope.
315198092Srdivacky    void ExitScope();
316198092Srdivacky
317199482Srdivacky    /// \brief Ignore this declaration, if it is seen again.
318249423Sdim    void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
319199482Srdivacky
320198092Srdivacky    /// \name Name lookup predicates
321198092Srdivacky    ///
322198092Srdivacky    /// These predicates can be passed to the name lookup functions to filter the
323198092Srdivacky    /// results of name lookup. All of the predicates have the same type, so that
324198092Srdivacky    ///
325198092Srdivacky    //@{
326249423Sdim    bool IsOrdinaryName(const NamedDecl *ND) const;
327249423Sdim    bool IsOrdinaryNonTypeName(const NamedDecl *ND) const;
328249423Sdim    bool IsIntegralConstantValue(const NamedDecl *ND) const;
329249423Sdim    bool IsOrdinaryNonValueName(const NamedDecl *ND) const;
330249423Sdim    bool IsNestedNameSpecifier(const NamedDecl *ND) const;
331249423Sdim    bool IsEnum(const NamedDecl *ND) const;
332249423Sdim    bool IsClassOrStruct(const NamedDecl *ND) const;
333249423Sdim    bool IsUnion(const NamedDecl *ND) const;
334249423Sdim    bool IsNamespace(const NamedDecl *ND) const;
335249423Sdim    bool IsNamespaceOrAlias(const NamedDecl *ND) const;
336249423Sdim    bool IsType(const NamedDecl *ND) const;
337249423Sdim    bool IsMember(const NamedDecl *ND) const;
338249423Sdim    bool IsObjCIvar(const NamedDecl *ND) const;
339249423Sdim    bool IsObjCMessageReceiver(const NamedDecl *ND) const;
340249423Sdim    bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const;
341249423Sdim    bool IsObjCCollection(const NamedDecl *ND) const;
342249423Sdim    bool IsImpossibleToSatisfy(const NamedDecl *ND) const;
343198092Srdivacky    //@}
344198092Srdivacky  };
345198092Srdivacky}
346198092Srdivacky
347200583Srdivackyclass ResultBuilder::ShadowMapEntry::iterator {
348249423Sdim  llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator;
349200583Srdivacky  unsigned SingleDeclIndex;
350200583Srdivacky
351200583Srdivackypublic:
352200583Srdivacky  typedef DeclIndexPair value_type;
353200583Srdivacky  typedef value_type reference;
354200583Srdivacky  typedef std::ptrdiff_t difference_type;
355200583Srdivacky  typedef std::input_iterator_tag iterator_category;
356200583Srdivacky
357200583Srdivacky  class pointer {
358200583Srdivacky    DeclIndexPair Value;
359200583Srdivacky
360200583Srdivacky  public:
361200583Srdivacky    pointer(const DeclIndexPair &Value) : Value(Value) { }
362200583Srdivacky
363200583Srdivacky    const DeclIndexPair *operator->() const {
364200583Srdivacky      return &Value;
365200583Srdivacky    }
366200583Srdivacky  };
367200583Srdivacky
368200583Srdivacky  iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
369200583Srdivacky
370249423Sdim  iterator(const NamedDecl *SingleDecl, unsigned Index)
371200583Srdivacky    : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
372200583Srdivacky
373200583Srdivacky  iterator(const DeclIndexPair *Iterator)
374200583Srdivacky    : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
375200583Srdivacky
376200583Srdivacky  iterator &operator++() {
377249423Sdim    if (DeclOrIterator.is<const NamedDecl *>()) {
378200583Srdivacky      DeclOrIterator = (NamedDecl *)0;
379200583Srdivacky      SingleDeclIndex = 0;
380200583Srdivacky      return *this;
381200583Srdivacky    }
382200583Srdivacky
383200583Srdivacky    const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
384200583Srdivacky    ++I;
385200583Srdivacky    DeclOrIterator = I;
386200583Srdivacky    return *this;
387200583Srdivacky  }
388200583Srdivacky
389218893Sdim  /*iterator operator++(int) {
390200583Srdivacky    iterator tmp(*this);
391200583Srdivacky    ++(*this);
392200583Srdivacky    return tmp;
393218893Sdim  }*/
394200583Srdivacky
395200583Srdivacky  reference operator*() const {
396249423Sdim    if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>())
397200583Srdivacky      return reference(ND, SingleDeclIndex);
398200583Srdivacky
399200583Srdivacky    return *DeclOrIterator.get<const DeclIndexPair*>();
400200583Srdivacky  }
401200583Srdivacky
402200583Srdivacky  pointer operator->() const {
403200583Srdivacky    return pointer(**this);
404200583Srdivacky  }
405200583Srdivacky
406200583Srdivacky  friend bool operator==(const iterator &X, const iterator &Y) {
407200583Srdivacky    return X.DeclOrIterator.getOpaqueValue()
408200583Srdivacky                                  == Y.DeclOrIterator.getOpaqueValue() &&
409200583Srdivacky      X.SingleDeclIndex == Y.SingleDeclIndex;
410200583Srdivacky  }
411200583Srdivacky
412200583Srdivacky  friend bool operator!=(const iterator &X, const iterator &Y) {
413200583Srdivacky    return !(X == Y);
414200583Srdivacky  }
415200583Srdivacky};
416200583Srdivacky
417200583SrdivackyResultBuilder::ShadowMapEntry::iterator
418200583SrdivackyResultBuilder::ShadowMapEntry::begin() const {
419200583Srdivacky  if (DeclOrVector.isNull())
420200583Srdivacky    return iterator();
421200583Srdivacky
422249423Sdim  if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>())
423200583Srdivacky    return iterator(ND, SingleDeclIndex);
424200583Srdivacky
425200583Srdivacky  return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
426200583Srdivacky}
427200583Srdivacky
428200583SrdivackyResultBuilder::ShadowMapEntry::iterator
429200583SrdivackyResultBuilder::ShadowMapEntry::end() const {
430249423Sdim  if (DeclOrVector.is<const NamedDecl *>() || DeclOrVector.isNull())
431200583Srdivacky    return iterator();
432200583Srdivacky
433200583Srdivacky  return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
434200583Srdivacky}
435200583Srdivacky
436198092Srdivacky/// \brief Compute the qualification required to get from the current context
437198092Srdivacky/// (\p CurContext) to the target context (\p TargetContext).
438198092Srdivacky///
439198092Srdivacky/// \param Context the AST context in which the qualification will be used.
440198092Srdivacky///
441198092Srdivacky/// \param CurContext the context where an entity is being named, which is
442198092Srdivacky/// typically based on the current scope.
443198092Srdivacky///
444198092Srdivacky/// \param TargetContext the context in which the named entity actually
445198092Srdivacky/// resides.
446198092Srdivacky///
447198092Srdivacky/// \returns a nested name specifier that refers into the target context, or
448198092Srdivacky/// NULL if no qualification is needed.
449198092Srdivackystatic NestedNameSpecifier *
450198092SrdivackygetRequiredQualification(ASTContext &Context,
451249423Sdim                         const DeclContext *CurContext,
452249423Sdim                         const DeclContext *TargetContext) {
453249423Sdim  SmallVector<const DeclContext *, 4> TargetParents;
454198092Srdivacky
455249423Sdim  for (const DeclContext *CommonAncestor = TargetContext;
456198092Srdivacky       CommonAncestor && !CommonAncestor->Encloses(CurContext);
457198092Srdivacky       CommonAncestor = CommonAncestor->getLookupParent()) {
458198092Srdivacky    if (CommonAncestor->isTransparentContext() ||
459198092Srdivacky        CommonAncestor->isFunctionOrMethod())
460198092Srdivacky      continue;
461198092Srdivacky
462198092Srdivacky    TargetParents.push_back(CommonAncestor);
463198092Srdivacky  }
464198092Srdivacky
465198092Srdivacky  NestedNameSpecifier *Result = 0;
466198092Srdivacky  while (!TargetParents.empty()) {
467249423Sdim    const DeclContext *Parent = TargetParents.back();
468198092Srdivacky    TargetParents.pop_back();
469198092Srdivacky
470249423Sdim    if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
471212904Sdim      if (!Namespace->getIdentifier())
472212904Sdim        continue;
473212904Sdim
474198092Srdivacky      Result = NestedNameSpecifier::Create(Context, Result, Namespace);
475212904Sdim    }
476249423Sdim    else if (const TagDecl *TD = dyn_cast<TagDecl>(Parent))
477198092Srdivacky      Result = NestedNameSpecifier::Create(Context, Result,
478198092Srdivacky                                           false,
479198092Srdivacky                                     Context.getTypeDeclType(TD).getTypePtr());
480199482Srdivacky  }
481198092Srdivacky  return Result;
482198092Srdivacky}
483198092Srdivacky
484249423Sdimbool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
485202379Srdivacky                                      bool &AsNestedNameSpecifier) const {
486202379Srdivacky  AsNestedNameSpecifier = false;
487198092Srdivacky
488202379Srdivacky  ND = ND->getUnderlyingDecl();
489202379Srdivacky  unsigned IDNS = ND->getIdentifierNamespace();
490202379Srdivacky
491198092Srdivacky  // Skip unnamed entities.
492202379Srdivacky  if (!ND->getDeclName())
493202379Srdivacky    return false;
494198092Srdivacky
495198092Srdivacky  // Friend declarations and declarations introduced due to friends are never
496198092Srdivacky  // added as results.
497205219Srdivacky  if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
498202379Srdivacky    return false;
499202379Srdivacky
500200583Srdivacky  // Class template (partial) specializations are never added as results.
501202379Srdivacky  if (isa<ClassTemplateSpecializationDecl>(ND) ||
502202379Srdivacky      isa<ClassTemplatePartialSpecializationDecl>(ND))
503202379Srdivacky    return false;
504198092Srdivacky
505200583Srdivacky  // Using declarations themselves are never added as results.
506202379Srdivacky  if (isa<UsingDecl>(ND))
507202379Srdivacky    return false;
508202379Srdivacky
509202379Srdivacky  // Some declarations have reserved names that we don't want to ever show.
510202379Srdivacky  if (const IdentifierInfo *Id = ND->getIdentifier()) {
511198092Srdivacky    // __va_list_tag is a freak of nature. Find it and skip it.
512198092Srdivacky    if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
513202379Srdivacky      return false;
514198092Srdivacky
515198092Srdivacky    // Filter out names reserved for the implementation (C99 7.1.3,
516210299Sed    // C++ [lib.global.names]) if they come from a system header.
517198398Srdivacky    //
518198398Srdivacky    // FIXME: Add predicate for this.
519198092Srdivacky    if (Id->getLength() >= 2) {
520198398Srdivacky      const char *Name = Id->getNameStart();
521198092Srdivacky      if (Name[0] == '_' &&
522210299Sed          (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
523210299Sed          (ND->getLocation().isInvalid() ||
524210299Sed           SemaRef.SourceMgr.isInSystemHeader(
525210299Sed                          SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
526202379Srdivacky        return false;
527198092Srdivacky    }
528198092Srdivacky  }
529218893Sdim
530212904Sdim  if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
531212904Sdim      ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
532212904Sdim       Filter != &ResultBuilder::IsNamespace &&
533218893Sdim       Filter != &ResultBuilder::IsNamespaceOrAlias &&
534218893Sdim       Filter != 0))
535212904Sdim    AsNestedNameSpecifier = true;
536212904Sdim
537198092Srdivacky  // Filter out any unwanted results.
538202379Srdivacky  if (Filter && !(this->*Filter)(ND)) {
539202379Srdivacky    // Check whether it is interesting as a nested-name-specifier.
540234353Sdim    if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus &&
541202379Srdivacky        IsNestedNameSpecifier(ND) &&
542202379Srdivacky        (Filter != &ResultBuilder::IsMember ||
543202379Srdivacky         (isa<CXXRecordDecl>(ND) &&
544202379Srdivacky          cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
545202379Srdivacky      AsNestedNameSpecifier = true;
546202379Srdivacky      return true;
547202379Srdivacky    }
548202379Srdivacky
549202379Srdivacky    return false;
550212904Sdim  }
551202379Srdivacky  // ... then it must be interesting!
552202379Srdivacky  return true;
553202379Srdivacky}
554202379Srdivacky
555202379Srdivackybool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
556249423Sdim                                      const NamedDecl *Hiding) {
557202379Srdivacky  // In C, there is no way to refer to a hidden name.
558202379Srdivacky  // FIXME: This isn't true; we can find a tag name hidden by an ordinary
559202379Srdivacky  // name if we introduce the tag type.
560234353Sdim  if (!SemaRef.getLangOpts().CPlusPlus)
561202379Srdivacky    return true;
562202379Srdivacky
563249423Sdim  const DeclContext *HiddenCtx =
564249423Sdim      R.Declaration->getDeclContext()->getRedeclContext();
565202379Srdivacky
566202379Srdivacky  // There is no way to qualify a name declared in a function or method.
567202379Srdivacky  if (HiddenCtx->isFunctionOrMethod())
568202379Srdivacky    return true;
569202379Srdivacky
570212904Sdim  if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
571202379Srdivacky    return true;
572202379Srdivacky
573202379Srdivacky  // We can refer to the result with the appropriate qualification. Do it.
574202379Srdivacky  R.Hidden = true;
575202379Srdivacky  R.QualifierIsInformative = false;
576202379Srdivacky
577202379Srdivacky  if (!R.Qualifier)
578202379Srdivacky    R.Qualifier = getRequiredQualification(SemaRef.Context,
579202379Srdivacky                                           CurContext,
580202379Srdivacky                                           R.Declaration->getDeclContext());
581202379Srdivacky  return false;
582202379Srdivacky}
583202379Srdivacky
584210299Sed/// \brief A simplified classification of types used to determine whether two
585210299Sed/// types are "similar enough" when adjusting priorities.
586212904SdimSimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
587210299Sed  switch (T->getTypeClass()) {
588210299Sed  case Type::Builtin:
589210299Sed    switch (cast<BuiltinType>(T)->getKind()) {
590210299Sed      case BuiltinType::Void:
591210299Sed        return STC_Void;
592210299Sed
593210299Sed      case BuiltinType::NullPtr:
594210299Sed        return STC_Pointer;
595210299Sed
596210299Sed      case BuiltinType::Overload:
597210299Sed      case BuiltinType::Dependent:
598210299Sed        return STC_Other;
599210299Sed
600210299Sed      case BuiltinType::ObjCId:
601210299Sed      case BuiltinType::ObjCClass:
602210299Sed      case BuiltinType::ObjCSel:
603210299Sed        return STC_ObjectiveC;
604210299Sed
605210299Sed      default:
606210299Sed        return STC_Arithmetic;
607210299Sed    }
608234353Sdim
609210299Sed  case Type::Complex:
610210299Sed    return STC_Arithmetic;
611210299Sed
612210299Sed  case Type::Pointer:
613210299Sed    return STC_Pointer;
614210299Sed
615210299Sed  case Type::BlockPointer:
616210299Sed    return STC_Block;
617210299Sed
618210299Sed  case Type::LValueReference:
619210299Sed  case Type::RValueReference:
620210299Sed    return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
621210299Sed
622210299Sed  case Type::ConstantArray:
623210299Sed  case Type::IncompleteArray:
624210299Sed  case Type::VariableArray:
625210299Sed  case Type::DependentSizedArray:
626210299Sed    return STC_Array;
627210299Sed
628210299Sed  case Type::DependentSizedExtVector:
629210299Sed  case Type::Vector:
630210299Sed  case Type::ExtVector:
631210299Sed    return STC_Arithmetic;
632210299Sed
633210299Sed  case Type::FunctionProto:
634210299Sed  case Type::FunctionNoProto:
635210299Sed    return STC_Function;
636210299Sed
637210299Sed  case Type::Record:
638210299Sed    return STC_Record;
639210299Sed
640210299Sed  case Type::Enum:
641210299Sed    return STC_Arithmetic;
642210299Sed
643210299Sed  case Type::ObjCObject:
644210299Sed  case Type::ObjCInterface:
645210299Sed  case Type::ObjCObjectPointer:
646210299Sed    return STC_ObjectiveC;
647210299Sed
648210299Sed  default:
649210299Sed    return STC_Other;
650210299Sed  }
651210299Sed}
652210299Sed
653210299Sed/// \brief Get the type that a given expression will have if this declaration
654210299Sed/// is used as an expression in its "typical" code-completion form.
655249423SdimQualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
656210299Sed  ND = cast<NamedDecl>(ND->getUnderlyingDecl());
657210299Sed
658249423Sdim  if (const TypeDecl *Type = dyn_cast<TypeDecl>(ND))
659210299Sed    return C.getTypeDeclType(Type);
660249423Sdim  if (const ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
661210299Sed    return C.getObjCInterfaceType(Iface);
662210299Sed
663210299Sed  QualType T;
664249423Sdim  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
665210299Sed    T = Function->getCallResultType();
666249423Sdim  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
667210299Sed    T = Method->getSendResultType();
668249423Sdim  else if (const FunctionTemplateDecl *FunTmpl =
669249423Sdim               dyn_cast<FunctionTemplateDecl>(ND))
670210299Sed    T = FunTmpl->getTemplatedDecl()->getCallResultType();
671249423Sdim  else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
672210299Sed    T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
673249423Sdim  else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
674210299Sed    T = Property->getType();
675249423Sdim  else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND))
676210299Sed    T = Value->getType();
677210299Sed  else
678210299Sed    return QualType();
679221345Sdim
680221345Sdim  // Dig through references, function pointers, and block pointers to
681221345Sdim  // get down to the likely type of an expression when the entity is
682221345Sdim  // used.
683221345Sdim  do {
684221345Sdim    if (const ReferenceType *Ref = T->getAs<ReferenceType>()) {
685221345Sdim      T = Ref->getPointeeType();
686221345Sdim      continue;
687221345Sdim    }
688221345Sdim
689221345Sdim    if (const PointerType *Pointer = T->getAs<PointerType>()) {
690221345Sdim      if (Pointer->getPointeeType()->isFunctionType()) {
691221345Sdim        T = Pointer->getPointeeType();
692221345Sdim        continue;
693221345Sdim      }
694221345Sdim
695221345Sdim      break;
696221345Sdim    }
697221345Sdim
698221345Sdim    if (const BlockPointerType *Block = T->getAs<BlockPointerType>()) {
699221345Sdim      T = Block->getPointeeType();
700221345Sdim      continue;
701221345Sdim    }
702221345Sdim
703221345Sdim    if (const FunctionType *Function = T->getAs<FunctionType>()) {
704221345Sdim      T = Function->getResultType();
705221345Sdim      continue;
706221345Sdim    }
707221345Sdim
708221345Sdim    break;
709221345Sdim  } while (true);
710221345Sdim
711221345Sdim  return T;
712210299Sed}
713210299Sed
714249423Sdimunsigned ResultBuilder::getBasePriority(const NamedDecl *ND) {
715249423Sdim  if (!ND)
716249423Sdim    return CCP_Unlikely;
717249423Sdim
718249423Sdim  // Context-based decisions.
719249423Sdim  const DeclContext *DC = ND->getDeclContext()->getRedeclContext();
720249423Sdim  if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC)) {
721249423Sdim    // _cmd is relatively rare
722249423Sdim    if (const ImplicitParamDecl *ImplicitParam =
723249423Sdim        dyn_cast<ImplicitParamDecl>(ND))
724249423Sdim      if (ImplicitParam->getIdentifier() &&
725249423Sdim          ImplicitParam->getIdentifier()->isStr("_cmd"))
726249423Sdim        return CCP_ObjC_cmd;
727249423Sdim
728249423Sdim    return CCP_LocalDeclaration;
729249423Sdim  }
730249423Sdim  if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
731249423Sdim    return CCP_MemberDeclaration;
732249423Sdim
733249423Sdim  // Content-based decisions.
734249423Sdim  if (isa<EnumConstantDecl>(ND))
735249423Sdim    return CCP_Constant;
736249423Sdim
737249423Sdim  // Use CCP_Type for type declarations unless we're in a statement, Objective-C
738249423Sdim  // message receiver, or parenthesized expression context. There, it's as
739249423Sdim  // likely that the user will want to write a type as other declarations.
740249423Sdim  if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
741249423Sdim      !(CompletionContext.getKind() == CodeCompletionContext::CCC_Statement ||
742249423Sdim        CompletionContext.getKind()
743249423Sdim          == CodeCompletionContext::CCC_ObjCMessageReceiver ||
744249423Sdim        CompletionContext.getKind()
745249423Sdim          == CodeCompletionContext::CCC_ParenthesizedExpression))
746249423Sdim    return CCP_Type;
747249423Sdim
748249423Sdim  return CCP_Declaration;
749249423Sdim}
750249423Sdim
751218893Sdimvoid ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
752218893Sdim  // If this is an Objective-C method declaration whose selector matches our
753218893Sdim  // preferred selector, give it a priority boost.
754218893Sdim  if (!PreferredSelector.isNull())
755249423Sdim    if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
756218893Sdim      if (PreferredSelector == Method->getSelector())
757218893Sdim        R.Priority += CCD_SelectorMatch;
758210299Sed
759218893Sdim  // If we have a preferred type, adjust the priority for results with exactly-
760218893Sdim  // matching or nearly-matching types.
761218893Sdim  if (!PreferredType.isNull()) {
762218893Sdim    QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
763218893Sdim    if (!T.isNull()) {
764218893Sdim      CanQualType TC = SemaRef.Context.getCanonicalType(T);
765218893Sdim      // Check for exactly-matching types (modulo qualifiers).
766218893Sdim      if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
767218893Sdim        R.Priority /= CCF_ExactTypeMatch;
768218893Sdim      // Check for nearly-matching types, based on classification of each.
769218893Sdim      else if ((getSimplifiedTypeClass(PreferredType)
770210299Sed                                               == getSimplifiedTypeClass(TC)) &&
771218893Sdim               !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
772218893Sdim        R.Priority /= CCF_SimilarTypeMatch;
773218893Sdim    }
774218893Sdim  }
775210299Sed}
776210299Sed
777218893Sdimvoid ResultBuilder::MaybeAddConstructorResults(Result R) {
778234353Sdim  if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration ||
779218893Sdim      !CompletionContext.wantConstructorResults())
780218893Sdim    return;
781218893Sdim
782218893Sdim  ASTContext &Context = SemaRef.Context;
783249423Sdim  const NamedDecl *D = R.Declaration;
784249423Sdim  const CXXRecordDecl *Record = 0;
785249423Sdim  if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
786218893Sdim    Record = ClassTemplate->getTemplatedDecl();
787218893Sdim  else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
788218893Sdim    // Skip specializations and partial specializations.
789218893Sdim    if (isa<ClassTemplateSpecializationDecl>(Record))
790218893Sdim      return;
791218893Sdim  } else {
792218893Sdim    // There are no constructors here.
793218893Sdim    return;
794218893Sdim  }
795218893Sdim
796218893Sdim  Record = Record->getDefinition();
797218893Sdim  if (!Record)
798218893Sdim    return;
799218893Sdim
800218893Sdim
801218893Sdim  QualType RecordTy = Context.getTypeDeclType(Record);
802218893Sdim  DeclarationName ConstructorName
803218893Sdim    = Context.DeclarationNames.getCXXConstructorName(
804218893Sdim                                           Context.getCanonicalType(RecordTy));
805249423Sdim  DeclContext::lookup_const_result Ctors = Record->lookup(ConstructorName);
806249423Sdim  for (DeclContext::lookup_const_iterator I = Ctors.begin(),
807249423Sdim                                          E = Ctors.end();
808249423Sdim       I != E; ++I) {
809249423Sdim    R.Declaration = *I;
810218893Sdim    R.CursorKind = getCursorKindForDecl(R.Declaration);
811218893Sdim    Results.push_back(R);
812218893Sdim  }
813218893Sdim}
814218893Sdim
815202379Srdivackyvoid ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
816202379Srdivacky  assert(!ShadowMaps.empty() && "Must enter into a results scope");
817202379Srdivacky
818202379Srdivacky  if (R.Kind != Result::RK_Declaration) {
819202379Srdivacky    // For non-declaration results, just add the result.
820202379Srdivacky    Results.push_back(R);
821198092Srdivacky    return;
822202379Srdivacky  }
823202379Srdivacky
824202379Srdivacky  // Look through using declarations.
825249423Sdim  if (const UsingShadowDecl *Using =
826249423Sdim          dyn_cast<UsingShadowDecl>(R.Declaration)) {
827249423Sdim    MaybeAddResult(Result(Using->getTargetDecl(),
828249423Sdim                          getBasePriority(Using->getTargetDecl()),
829249423Sdim                          R.Qualifier),
830249423Sdim                   CurContext);
831202379Srdivacky    return;
832202379Srdivacky  }
833198092Srdivacky
834249423Sdim  const Decl *CanonDecl = R.Declaration->getCanonicalDecl();
835202379Srdivacky  unsigned IDNS = CanonDecl->getIdentifierNamespace();
836202379Srdivacky
837202379Srdivacky  bool AsNestedNameSpecifier = false;
838202379Srdivacky  if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
839202379Srdivacky    return;
840202379Srdivacky
841218893Sdim  // C++ constructors are never found by name lookup.
842218893Sdim  if (isa<CXXConstructorDecl>(R.Declaration))
843218893Sdim    return;
844218893Sdim
845198092Srdivacky  ShadowMap &SMap = ShadowMaps.back();
846200583Srdivacky  ShadowMapEntry::iterator I, IEnd;
847200583Srdivacky  ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
848200583Srdivacky  if (NamePos != SMap.end()) {
849200583Srdivacky    I = NamePos->second.begin();
850200583Srdivacky    IEnd = NamePos->second.end();
851200583Srdivacky  }
852200583Srdivacky
853200583Srdivacky  for (; I != IEnd; ++I) {
854249423Sdim    const NamedDecl *ND = I->first;
855200583Srdivacky    unsigned Index = I->second;
856198092Srdivacky    if (ND->getCanonicalDecl() == CanonDecl) {
857198092Srdivacky      // This is a redeclaration. Always pick the newer declaration.
858198092Srdivacky      Results[Index].Declaration = R.Declaration;
859198092Srdivacky
860198092Srdivacky      // We're done.
861198092Srdivacky      return;
862198092Srdivacky    }
863198092Srdivacky  }
864198092Srdivacky
865198092Srdivacky  // This is a new declaration in this scope. However, check whether this
866198092Srdivacky  // declaration name is hidden by a similarly-named declaration in an outer
867198092Srdivacky  // scope.
868198092Srdivacky  std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
869198092Srdivacky  --SMEnd;
870198092Srdivacky  for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
871200583Srdivacky    ShadowMapEntry::iterator I, IEnd;
872200583Srdivacky    ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
873200583Srdivacky    if (NamePos != SM->end()) {
874200583Srdivacky      I = NamePos->second.begin();
875200583Srdivacky      IEnd = NamePos->second.end();
876200583Srdivacky    }
877200583Srdivacky    for (; I != IEnd; ++I) {
878198092Srdivacky      // A tag declaration does not hide a non-tag declaration.
879207619Srdivacky      if (I->first->hasTagIdentifierNamespace() &&
880198092Srdivacky          (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
881198092Srdivacky                   Decl::IDNS_ObjCProtocol)))
882198092Srdivacky        continue;
883198092Srdivacky
884198092Srdivacky      // Protocols are in distinct namespaces from everything else.
885200583Srdivacky      if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
886198092Srdivacky           || (IDNS & Decl::IDNS_ObjCProtocol)) &&
887200583Srdivacky          I->first->getIdentifierNamespace() != IDNS)
888198092Srdivacky        continue;
889198092Srdivacky
890198092Srdivacky      // The newly-added result is hidden by an entry in the shadow map.
891202379Srdivacky      if (CheckHiddenResult(R, CurContext, I->first))
892198092Srdivacky        return;
893198092Srdivacky
894198092Srdivacky      break;
895198092Srdivacky    }
896198092Srdivacky  }
897198092Srdivacky
898198092Srdivacky  // Make sure that any given declaration only shows up in the result set once.
899198092Srdivacky  if (!AllDeclsFound.insert(CanonDecl))
900198092Srdivacky    return;
901212904Sdim
902198092Srdivacky  // If the filter is for nested-name-specifiers, then this result starts a
903198092Srdivacky  // nested-name-specifier.
904208600Srdivacky  if (AsNestedNameSpecifier) {
905198092Srdivacky    R.StartsNestedNameSpecifier = true;
906208600Srdivacky    R.Priority = CCP_NestedNameSpecifier;
907218893Sdim  } else
908218893Sdim      AdjustResultPriorityForDecl(R);
909212904Sdim
910198092Srdivacky  // If this result is supposed to have an informative qualifier, add one.
911198092Srdivacky  if (R.QualifierIsInformative && !R.Qualifier &&
912198092Srdivacky      !R.StartsNestedNameSpecifier) {
913249423Sdim    const DeclContext *Ctx = R.Declaration->getDeclContext();
914249423Sdim    if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
915198092Srdivacky      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
916249423Sdim    else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
917198092Srdivacky      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
918198092Srdivacky                             SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
919198092Srdivacky    else
920198092Srdivacky      R.QualifierIsInformative = false;
921198092Srdivacky  }
922198092Srdivacky
923198092Srdivacky  // Insert this result into the set of results and into the current shadow
924198092Srdivacky  // map.
925200583Srdivacky  SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
926198092Srdivacky  Results.push_back(R);
927218893Sdim
928218893Sdim  if (!AsNestedNameSpecifier)
929218893Sdim    MaybeAddConstructorResults(R);
930198092Srdivacky}
931198092Srdivacky
932202379Srdivackyvoid ResultBuilder::AddResult(Result R, DeclContext *CurContext,
933202379Srdivacky                              NamedDecl *Hiding, bool InBaseClass = false) {
934202379Srdivacky  if (R.Kind != Result::RK_Declaration) {
935202379Srdivacky    // For non-declaration results, just add the result.
936202379Srdivacky    Results.push_back(R);
937202379Srdivacky    return;
938202379Srdivacky  }
939202379Srdivacky
940202379Srdivacky  // Look through using declarations.
941249423Sdim  if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
942249423Sdim    AddResult(Result(Using->getTargetDecl(),
943249423Sdim                     getBasePriority(Using->getTargetDecl()),
944249423Sdim                     R.Qualifier),
945249423Sdim              CurContext, Hiding);
946202379Srdivacky    return;
947202379Srdivacky  }
948202379Srdivacky
949202379Srdivacky  bool AsNestedNameSpecifier = false;
950202379Srdivacky  if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
951202379Srdivacky    return;
952202379Srdivacky
953218893Sdim  // C++ constructors are never found by name lookup.
954218893Sdim  if (isa<CXXConstructorDecl>(R.Declaration))
955218893Sdim    return;
956218893Sdim
957202379Srdivacky  if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
958202379Srdivacky    return;
959234353Sdim
960202379Srdivacky  // Make sure that any given declaration only shows up in the result set once.
961202379Srdivacky  if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
962202379Srdivacky    return;
963202379Srdivacky
964202379Srdivacky  // If the filter is for nested-name-specifiers, then this result starts a
965202379Srdivacky  // nested-name-specifier.
966208600Srdivacky  if (AsNestedNameSpecifier) {
967202379Srdivacky    R.StartsNestedNameSpecifier = true;
968208600Srdivacky    R.Priority = CCP_NestedNameSpecifier;
969208600Srdivacky  }
970202379Srdivacky  else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
971202379Srdivacky           isa<CXXRecordDecl>(R.Declaration->getDeclContext()
972212904Sdim                                                  ->getRedeclContext()))
973202379Srdivacky    R.QualifierIsInformative = true;
974202379Srdivacky
975202379Srdivacky  // If this result is supposed to have an informative qualifier, add one.
976202379Srdivacky  if (R.QualifierIsInformative && !R.Qualifier &&
977202379Srdivacky      !R.StartsNestedNameSpecifier) {
978249423Sdim    const DeclContext *Ctx = R.Declaration->getDeclContext();
979249423Sdim    if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
980202379Srdivacky      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
981249423Sdim    else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
982202379Srdivacky      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
983202379Srdivacky                            SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
984202379Srdivacky    else
985202379Srdivacky      R.QualifierIsInformative = false;
986202379Srdivacky  }
987202379Srdivacky
988208600Srdivacky  // Adjust the priority if this result comes from a base class.
989208600Srdivacky  if (InBaseClass)
990208600Srdivacky    R.Priority += CCD_InBaseClass;
991208600Srdivacky
992218893Sdim  AdjustResultPriorityForDecl(R);
993210299Sed
994212904Sdim  if (HasObjectTypeQualifiers)
995249423Sdim    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
996212904Sdim      if (Method->isInstance()) {
997212904Sdim        Qualifiers MethodQuals
998212904Sdim                        = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
999212904Sdim        if (ObjectTypeQualifiers == MethodQuals)
1000212904Sdim          R.Priority += CCD_ObjectQualifierMatch;
1001212904Sdim        else if (ObjectTypeQualifiers - MethodQuals) {
1002212904Sdim          // The method cannot be invoked, because doing so would drop
1003212904Sdim          // qualifiers.
1004212904Sdim          return;
1005212904Sdim        }
1006212904Sdim      }
1007212904Sdim
1008202379Srdivacky  // Insert this result into the set of results.
1009202379Srdivacky  Results.push_back(R);
1010218893Sdim
1011218893Sdim  if (!AsNestedNameSpecifier)
1012218893Sdim    MaybeAddConstructorResults(R);
1013202379Srdivacky}
1014202379Srdivacky
1015202379Srdivackyvoid ResultBuilder::AddResult(Result R) {
1016202379Srdivacky  assert(R.Kind != Result::RK_Declaration &&
1017202379Srdivacky          "Declaration results need more context");
1018202379Srdivacky  Results.push_back(R);
1019202379Srdivacky}
1020202379Srdivacky
1021198092Srdivacky/// \brief Enter into a new scope.
1022198092Srdivackyvoid ResultBuilder::EnterNewScope() {
1023198092Srdivacky  ShadowMaps.push_back(ShadowMap());
1024198092Srdivacky}
1025198092Srdivacky
1026198092Srdivacky/// \brief Exit from the current scope.
1027198092Srdivackyvoid ResultBuilder::ExitScope() {
1028200583Srdivacky  for (ShadowMap::iterator E = ShadowMaps.back().begin(),
1029200583Srdivacky                        EEnd = ShadowMaps.back().end();
1030200583Srdivacky       E != EEnd;
1031200583Srdivacky       ++E)
1032200583Srdivacky    E->second.Destroy();
1033200583Srdivacky
1034198092Srdivacky  ShadowMaps.pop_back();
1035198092Srdivacky}
1036198092Srdivacky
1037198092Srdivacky/// \brief Determines whether this given declaration will be found by
1038198092Srdivacky/// ordinary name lookup.
1039249423Sdimbool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {
1040210299Sed  ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1041210299Sed
1042198092Srdivacky  unsigned IDNS = Decl::IDNS_Ordinary;
1043234353Sdim  if (SemaRef.getLangOpts().CPlusPlus)
1044210299Sed    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1045234353Sdim  else if (SemaRef.getLangOpts().ObjC1) {
1046218893Sdim    if (isa<ObjCIvarDecl>(ND))
1047218893Sdim      return true;
1048218893Sdim  }
1049218893Sdim
1050198092Srdivacky  return ND->getIdentifierNamespace() & IDNS;
1051198092Srdivacky}
1052198092Srdivacky
1053202379Srdivacky/// \brief Determines whether this given declaration will be found by
1054210299Sed/// ordinary name lookup but is not a type name.
1055249423Sdimbool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
1056210299Sed  ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1057210299Sed  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
1058210299Sed    return false;
1059210299Sed
1060210299Sed  unsigned IDNS = Decl::IDNS_Ordinary;
1061234353Sdim  if (SemaRef.getLangOpts().CPlusPlus)
1062210299Sed    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1063234353Sdim  else if (SemaRef.getLangOpts().ObjC1) {
1064218893Sdim    if (isa<ObjCIvarDecl>(ND))
1065218893Sdim      return true;
1066218893Sdim  }
1067218893Sdim
1068210299Sed  return ND->getIdentifierNamespace() & IDNS;
1069210299Sed}
1070210299Sed
1071249423Sdimbool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const {
1072212904Sdim  if (!IsOrdinaryNonTypeName(ND))
1073212904Sdim    return 0;
1074212904Sdim
1075249423Sdim  if (const ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
1076212904Sdim    if (VD->getType()->isIntegralOrEnumerationType())
1077212904Sdim      return true;
1078212904Sdim
1079212904Sdim  return false;
1080212904Sdim}
1081212904Sdim
1082210299Sed/// \brief Determines whether this given declaration will be found by
1083202379Srdivacky/// ordinary name lookup.
1084249423Sdimbool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {
1085210299Sed  ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1086210299Sed
1087202379Srdivacky  unsigned IDNS = Decl::IDNS_Ordinary;
1088234353Sdim  if (SemaRef.getLangOpts().CPlusPlus)
1089207619Srdivacky    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
1090202379Srdivacky
1091202379Srdivacky  return (ND->getIdentifierNamespace() & IDNS) &&
1092210299Sed    !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
1093210299Sed    !isa<ObjCPropertyDecl>(ND);
1094202379Srdivacky}
1095202379Srdivacky
1096198092Srdivacky/// \brief Determines whether the given declaration is suitable as the
1097198092Srdivacky/// start of a C++ nested-name-specifier, e.g., a class or namespace.
1098249423Sdimbool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const {
1099198092Srdivacky  // Allow us to find class templates, too.
1100249423Sdim  if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1101198092Srdivacky    ND = ClassTemplate->getTemplatedDecl();
1102198092Srdivacky
1103198092Srdivacky  return SemaRef.isAcceptableNestedNameSpecifier(ND);
1104198092Srdivacky}
1105198092Srdivacky
1106198092Srdivacky/// \brief Determines whether the given declaration is an enumeration.
1107249423Sdimbool ResultBuilder::IsEnum(const NamedDecl *ND) const {
1108198092Srdivacky  return isa<EnumDecl>(ND);
1109198092Srdivacky}
1110198092Srdivacky
1111198092Srdivacky/// \brief Determines whether the given declaration is a class or struct.
1112249423Sdimbool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const {
1113198092Srdivacky  // Allow us to find class templates, too.
1114249423Sdim  if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1115198092Srdivacky    ND = ClassTemplate->getTemplatedDecl();
1116243830Sdim
1117243830Sdim  // For purposes of this check, interfaces match too.
1118249423Sdim  if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
1119208600Srdivacky    return RD->getTagKind() == TTK_Class ||
1120243830Sdim    RD->getTagKind() == TTK_Struct ||
1121243830Sdim    RD->getTagKind() == TTK_Interface;
1122198092Srdivacky
1123198092Srdivacky  return false;
1124198092Srdivacky}
1125198092Srdivacky
1126198092Srdivacky/// \brief Determines whether the given declaration is a union.
1127249423Sdimbool ResultBuilder::IsUnion(const NamedDecl *ND) const {
1128198092Srdivacky  // Allow us to find class templates, too.
1129249423Sdim  if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1130198092Srdivacky    ND = ClassTemplate->getTemplatedDecl();
1131198092Srdivacky
1132249423Sdim  if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
1133208600Srdivacky    return RD->getTagKind() == TTK_Union;
1134198092Srdivacky
1135198092Srdivacky  return false;
1136198092Srdivacky}
1137198092Srdivacky
1138198092Srdivacky/// \brief Determines whether the given declaration is a namespace.
1139249423Sdimbool ResultBuilder::IsNamespace(const NamedDecl *ND) const {
1140198092Srdivacky  return isa<NamespaceDecl>(ND);
1141198092Srdivacky}
1142198092Srdivacky
1143198092Srdivacky/// \brief Determines whether the given declaration is a namespace or
1144198092Srdivacky/// namespace alias.
1145249423Sdimbool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const {
1146198092Srdivacky  return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
1147198092Srdivacky}
1148198092Srdivacky
1149200583Srdivacky/// \brief Determines whether the given declaration is a type.
1150249423Sdimbool ResultBuilder::IsType(const NamedDecl *ND) const {
1151249423Sdim  if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1152212904Sdim    ND = Using->getTargetDecl();
1153212904Sdim
1154212904Sdim  return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
1155198092Srdivacky}
1156198092Srdivacky
1157200583Srdivacky/// \brief Determines which members of a class should be visible via
1158200583Srdivacky/// "." or "->".  Only value declarations, nested name specifiers, and
1159200583Srdivacky/// using declarations thereof should show up.
1160249423Sdimbool ResultBuilder::IsMember(const NamedDecl *ND) const {
1161249423Sdim  if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
1162200583Srdivacky    ND = Using->getTargetDecl();
1163200583Srdivacky
1164200583Srdivacky  return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1165200583Srdivacky    isa<ObjCPropertyDecl>(ND);
1166198092Srdivacky}
1167198092Srdivacky
1168210299Sedstatic bool isObjCReceiverType(ASTContext &C, QualType T) {
1169210299Sed  T = C.getCanonicalType(T);
1170210299Sed  switch (T->getTypeClass()) {
1171210299Sed  case Type::ObjCObject:
1172210299Sed  case Type::ObjCInterface:
1173210299Sed  case Type::ObjCObjectPointer:
1174210299Sed    return true;
1175210299Sed
1176210299Sed  case Type::Builtin:
1177210299Sed    switch (cast<BuiltinType>(T)->getKind()) {
1178210299Sed    case BuiltinType::ObjCId:
1179210299Sed    case BuiltinType::ObjCClass:
1180210299Sed    case BuiltinType::ObjCSel:
1181210299Sed      return true;
1182210299Sed
1183210299Sed    default:
1184210299Sed      break;
1185210299Sed    }
1186210299Sed    return false;
1187210299Sed
1188210299Sed  default:
1189210299Sed    break;
1190210299Sed  }
1191210299Sed
1192234353Sdim  if (!C.getLangOpts().CPlusPlus)
1193210299Sed    return false;
1194210299Sed
1195210299Sed  // FIXME: We could perform more analysis here to determine whether a
1196210299Sed  // particular class type has any conversions to Objective-C types. For now,
1197210299Sed  // just accept all class types.
1198210299Sed  return T->isDependentType() || T->isRecordType();
1199210299Sed}
1200210299Sed
1201249423Sdimbool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {
1202210299Sed  QualType T = getDeclUsageType(SemaRef.Context, ND);
1203210299Sed  if (T.isNull())
1204210299Sed    return false;
1205210299Sed
1206210299Sed  T = SemaRef.Context.getBaseElementType(T);
1207210299Sed  return isObjCReceiverType(SemaRef.Context, T);
1208210299Sed}
1209210299Sed
1210249423Sdimbool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const {
1211234353Sdim  if (IsObjCMessageReceiver(ND))
1212234353Sdim    return true;
1213234353Sdim
1214249423Sdim  const VarDecl *Var = dyn_cast<VarDecl>(ND);
1215234353Sdim  if (!Var)
1216234353Sdim    return false;
1217234353Sdim
1218234353Sdim  return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>();
1219234353Sdim}
1220234353Sdim
1221249423Sdimbool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {
1222234353Sdim  if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) ||
1223234353Sdim      (!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1224212904Sdim    return false;
1225212904Sdim
1226212904Sdim  QualType T = getDeclUsageType(SemaRef.Context, ND);
1227212904Sdim  if (T.isNull())
1228212904Sdim    return false;
1229212904Sdim
1230212904Sdim  T = SemaRef.Context.getBaseElementType(T);
1231212904Sdim  return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1232212904Sdim         T->isObjCIdType() ||
1233234353Sdim         (SemaRef.getLangOpts().CPlusPlus && T->isRecordType());
1234212904Sdim}
1235210299Sed
1236249423Sdimbool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const {
1237218893Sdim  return false;
1238218893Sdim}
1239218893Sdim
1240239462Sdim/// \brief Determines whether the given declaration is an Objective-C
1241202379Srdivacky/// instance variable.
1242249423Sdimbool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const {
1243202379Srdivacky  return isa<ObjCIvarDecl>(ND);
1244198092Srdivacky}
1245198092Srdivacky
1246202379Srdivackynamespace {
1247202379Srdivacky  /// \brief Visible declaration consumer that adds a code-completion result
1248202379Srdivacky  /// for each visible declaration.
1249202379Srdivacky  class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1250202379Srdivacky    ResultBuilder &Results;
1251202379Srdivacky    DeclContext *CurContext;
1252198092Srdivacky
1253202379Srdivacky  public:
1254202379Srdivacky    CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1255202379Srdivacky      : Results(Results), CurContext(CurContext) { }
1256202379Srdivacky
1257226633Sdim    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
1258226633Sdim                           bool InBaseClass) {
1259226633Sdim      bool Accessible = true;
1260234353Sdim      if (Ctx)
1261234353Sdim        Accessible = Results.getSema().IsSimplyAccessible(ND, Ctx);
1262234353Sdim
1263249423Sdim      ResultBuilder::Result Result(ND, Results.getBasePriority(ND), 0, false,
1264249423Sdim                                   Accessible);
1265226633Sdim      Results.AddResult(Result, CurContext, Hiding, InBaseClass);
1266198092Srdivacky    }
1267202379Srdivacky  };
1268198092Srdivacky}
1269198092Srdivacky
1270198092Srdivacky/// \brief Add type specifiers for the current language as keyword results.
1271202379Srdivackystatic void AddTypeSpecifierResults(const LangOptions &LangOpts,
1272198092Srdivacky                                    ResultBuilder &Results) {
1273212904Sdim  typedef CodeCompletionResult Result;
1274208600Srdivacky  Results.AddResult(Result("short", CCP_Type));
1275208600Srdivacky  Results.AddResult(Result("long", CCP_Type));
1276208600Srdivacky  Results.AddResult(Result("signed", CCP_Type));
1277208600Srdivacky  Results.AddResult(Result("unsigned", CCP_Type));
1278208600Srdivacky  Results.AddResult(Result("void", CCP_Type));
1279208600Srdivacky  Results.AddResult(Result("char", CCP_Type));
1280208600Srdivacky  Results.AddResult(Result("int", CCP_Type));
1281208600Srdivacky  Results.AddResult(Result("float", CCP_Type));
1282208600Srdivacky  Results.AddResult(Result("double", CCP_Type));
1283208600Srdivacky  Results.AddResult(Result("enum", CCP_Type));
1284208600Srdivacky  Results.AddResult(Result("struct", CCP_Type));
1285208600Srdivacky  Results.AddResult(Result("union", CCP_Type));
1286208600Srdivacky  Results.AddResult(Result("const", CCP_Type));
1287208600Srdivacky  Results.AddResult(Result("volatile", CCP_Type));
1288202379Srdivacky
1289198092Srdivacky  if (LangOpts.C99) {
1290198092Srdivacky    // C99-specific
1291208600Srdivacky    Results.AddResult(Result("_Complex", CCP_Type));
1292208600Srdivacky    Results.AddResult(Result("_Imaginary", CCP_Type));
1293208600Srdivacky    Results.AddResult(Result("_Bool", CCP_Type));
1294208600Srdivacky    Results.AddResult(Result("restrict", CCP_Type));
1295198092Srdivacky  }
1296198092Srdivacky
1297234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
1298234353Sdim                                Results.getCodeCompletionTUInfo());
1299198092Srdivacky  if (LangOpts.CPlusPlus) {
1300198092Srdivacky    // C++-specific
1301218893Sdim    Results.AddResult(Result("bool", CCP_Type +
1302218893Sdim                             (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
1303208600Srdivacky    Results.AddResult(Result("class", CCP_Type));
1304208600Srdivacky    Results.AddResult(Result("wchar_t", CCP_Type));
1305198092Srdivacky
1306210299Sed    // typename qualified-id
1307218893Sdim    Builder.AddTypedTextChunk("typename");
1308218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1309218893Sdim    Builder.AddPlaceholderChunk("qualifier");
1310218893Sdim    Builder.AddTextChunk("::");
1311218893Sdim    Builder.AddPlaceholderChunk("name");
1312218893Sdim    Results.AddResult(Result(Builder.TakeString()));
1313208600Srdivacky
1314249423Sdim    if (LangOpts.CPlusPlus11) {
1315208600Srdivacky      Results.AddResult(Result("auto", CCP_Type));
1316208600Srdivacky      Results.AddResult(Result("char16_t", CCP_Type));
1317208600Srdivacky      Results.AddResult(Result("char32_t", CCP_Type));
1318210299Sed
1319218893Sdim      Builder.AddTypedTextChunk("decltype");
1320218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1321218893Sdim      Builder.AddPlaceholderChunk("expression");
1322218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1323218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1324198092Srdivacky    }
1325198092Srdivacky  }
1326198092Srdivacky
1327198092Srdivacky  // GNU extensions
1328198092Srdivacky  if (LangOpts.GNUMode) {
1329198092Srdivacky    // FIXME: Enable when we actually support decimal floating point.
1330202379Srdivacky    //    Results.AddResult(Result("_Decimal32"));
1331202379Srdivacky    //    Results.AddResult(Result("_Decimal64"));
1332202379Srdivacky    //    Results.AddResult(Result("_Decimal128"));
1333202379Srdivacky
1334218893Sdim    Builder.AddTypedTextChunk("typeof");
1335218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1336218893Sdim    Builder.AddPlaceholderChunk("expression");
1337218893Sdim    Results.AddResult(Result(Builder.TakeString()));
1338210299Sed
1339218893Sdim    Builder.AddTypedTextChunk("typeof");
1340218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1341218893Sdim    Builder.AddPlaceholderChunk("type");
1342218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
1343218893Sdim    Results.AddResult(Result(Builder.TakeString()));
1344198092Srdivacky  }
1345198092Srdivacky}
1346198092Srdivacky
1347212904Sdimstatic void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
1348202379Srdivacky                                 const LangOptions &LangOpts,
1349202379Srdivacky                                 ResultBuilder &Results) {
1350212904Sdim  typedef CodeCompletionResult Result;
1351202379Srdivacky  // Note: we don't suggest either "auto" or "register", because both
1352202379Srdivacky  // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1353202379Srdivacky  // in C++0x as a type specifier.
1354202379Srdivacky  Results.AddResult(Result("extern"));
1355202379Srdivacky  Results.AddResult(Result("static"));
1356202379Srdivacky}
1357202379Srdivacky
1358212904Sdimstatic void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
1359202379Srdivacky                                  const LangOptions &LangOpts,
1360202379Srdivacky                                  ResultBuilder &Results) {
1361212904Sdim  typedef CodeCompletionResult Result;
1362202379Srdivacky  switch (CCC) {
1363212904Sdim  case Sema::PCC_Class:
1364212904Sdim  case Sema::PCC_MemberTemplate:
1365202379Srdivacky    if (LangOpts.CPlusPlus) {
1366202379Srdivacky      Results.AddResult(Result("explicit"));
1367202379Srdivacky      Results.AddResult(Result("friend"));
1368202379Srdivacky      Results.AddResult(Result("mutable"));
1369202379Srdivacky      Results.AddResult(Result("virtual"));
1370202379Srdivacky    }
1371202379Srdivacky    // Fall through
1372202379Srdivacky
1373212904Sdim  case Sema::PCC_ObjCInterface:
1374212904Sdim  case Sema::PCC_ObjCImplementation:
1375212904Sdim  case Sema::PCC_Namespace:
1376212904Sdim  case Sema::PCC_Template:
1377202379Srdivacky    if (LangOpts.CPlusPlus || LangOpts.C99)
1378202379Srdivacky      Results.AddResult(Result("inline"));
1379202379Srdivacky    break;
1380202379Srdivacky
1381212904Sdim  case Sema::PCC_ObjCInstanceVariableList:
1382212904Sdim  case Sema::PCC_Expression:
1383212904Sdim  case Sema::PCC_Statement:
1384212904Sdim  case Sema::PCC_ForInit:
1385212904Sdim  case Sema::PCC_Condition:
1386212904Sdim  case Sema::PCC_RecoveryInFunction:
1387212904Sdim  case Sema::PCC_Type:
1388218893Sdim  case Sema::PCC_ParenthesizedExpression:
1389218893Sdim  case Sema::PCC_LocalDeclarationSpecifiers:
1390202379Srdivacky    break;
1391202379Srdivacky  }
1392202379Srdivacky}
1393202379Srdivacky
1394202379Srdivackystatic void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1395202379Srdivackystatic void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1396202379Srdivackystatic void AddObjCVisibilityResults(const LangOptions &LangOpts,
1397202379Srdivacky                                     ResultBuilder &Results,
1398202379Srdivacky                                     bool NeedAt);
1399202379Srdivackystatic void AddObjCImplementationResults(const LangOptions &LangOpts,
1400202379Srdivacky                                         ResultBuilder &Results,
1401202379Srdivacky                                         bool NeedAt);
1402202379Srdivackystatic void AddObjCInterfaceResults(const LangOptions &LangOpts,
1403202379Srdivacky                                    ResultBuilder &Results,
1404202379Srdivacky                                    bool NeedAt);
1405202379Srdivackystatic void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
1406202379Srdivacky
1407210299Sedstatic void AddTypedefResult(ResultBuilder &Results) {
1408234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
1409234353Sdim                                Results.getCodeCompletionTUInfo());
1410218893Sdim  Builder.AddTypedTextChunk("typedef");
1411218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1412218893Sdim  Builder.AddPlaceholderChunk("type");
1413218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1414218893Sdim  Builder.AddPlaceholderChunk("name");
1415218893Sdim  Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1416210299Sed}
1417210299Sed
1418212904Sdimstatic bool WantTypesInContext(Sema::ParserCompletionContext CCC,
1419210299Sed                               const LangOptions &LangOpts) {
1420210299Sed  switch (CCC) {
1421212904Sdim  case Sema::PCC_Namespace:
1422212904Sdim  case Sema::PCC_Class:
1423212904Sdim  case Sema::PCC_ObjCInstanceVariableList:
1424212904Sdim  case Sema::PCC_Template:
1425212904Sdim  case Sema::PCC_MemberTemplate:
1426212904Sdim  case Sema::PCC_Statement:
1427212904Sdim  case Sema::PCC_RecoveryInFunction:
1428212904Sdim  case Sema::PCC_Type:
1429218893Sdim  case Sema::PCC_ParenthesizedExpression:
1430218893Sdim  case Sema::PCC_LocalDeclarationSpecifiers:
1431210299Sed    return true;
1432210299Sed
1433218893Sdim  case Sema::PCC_Expression:
1434218893Sdim  case Sema::PCC_Condition:
1435218893Sdim    return LangOpts.CPlusPlus;
1436218893Sdim
1437212904Sdim  case Sema::PCC_ObjCInterface:
1438212904Sdim  case Sema::PCC_ObjCImplementation:
1439210299Sed    return false;
1440210299Sed
1441212904Sdim  case Sema::PCC_ForInit:
1442218893Sdim    return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
1443210299Sed  }
1444234353Sdim
1445234353Sdim  llvm_unreachable("Invalid ParserCompletionContext!");
1446234353Sdim}
1447234353Sdim
1448234353Sdimstatic PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
1449234353Sdim                                                  const Preprocessor &PP) {
1450234353Sdim  PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP);
1451234353Sdim  Policy.AnonymousTagLocations = false;
1452234353Sdim  Policy.SuppressStrongLifetime = true;
1453234353Sdim  Policy.SuppressUnwrittenScope = true;
1454234353Sdim  return Policy;
1455234353Sdim}
1456234353Sdim
1457234353Sdim/// \brief Retrieve a printing policy suitable for code completion.
1458234353Sdimstatic PrintingPolicy getCompletionPrintingPolicy(Sema &S) {
1459234353Sdim  return getCompletionPrintingPolicy(S.Context, S.PP);
1460234353Sdim}
1461234353Sdim
1462234353Sdim/// \brief Retrieve the string representation of the given type as a string
1463234353Sdim/// that has the appropriate lifetime for code completion.
1464234353Sdim///
1465234353Sdim/// This routine provides a fast path where we provide constant strings for
1466234353Sdim/// common type names.
1467234353Sdimstatic const char *GetCompletionTypeString(QualType T,
1468234353Sdim                                           ASTContext &Context,
1469234353Sdim                                           const PrintingPolicy &Policy,
1470234353Sdim                                           CodeCompletionAllocator &Allocator) {
1471234353Sdim  if (!T.getLocalQualifiers()) {
1472234353Sdim    // Built-in type names are constant strings.
1473234353Sdim    if (const BuiltinType *BT = dyn_cast<BuiltinType>(T))
1474239462Sdim      return BT->getNameAsCString(Policy);
1475234353Sdim
1476234353Sdim    // Anonymous tag types are constant strings.
1477234353Sdim    if (const TagType *TagT = dyn_cast<TagType>(T))
1478234353Sdim      if (TagDecl *Tag = TagT->getDecl())
1479249423Sdim        if (!Tag->hasNameForLinkage()) {
1480234353Sdim          switch (Tag->getTagKind()) {
1481234353Sdim          case TTK_Struct: return "struct <anonymous>";
1482243830Sdim          case TTK_Interface: return "__interface <anonymous>";
1483243830Sdim          case TTK_Class:  return "class <anonymous>";
1484234353Sdim          case TTK_Union:  return "union <anonymous>";
1485234353Sdim          case TTK_Enum:   return "enum <anonymous>";
1486234353Sdim          }
1487234353Sdim        }
1488234353Sdim  }
1489210299Sed
1490234353Sdim  // Slow path: format the type as a string.
1491234353Sdim  std::string Result;
1492234353Sdim  T.getAsStringInternal(Result, Policy);
1493234353Sdim  return Allocator.CopyString(Result);
1494210299Sed}
1495210299Sed
1496234353Sdim/// \brief Add a completion for "this", if we're in a member function.
1497234353Sdimstatic void addThisCompletion(Sema &S, ResultBuilder &Results) {
1498234353Sdim  QualType ThisTy = S.getCurrentThisType();
1499234353Sdim  if (ThisTy.isNull())
1500234353Sdim    return;
1501234353Sdim
1502234353Sdim  CodeCompletionAllocator &Allocator = Results.getAllocator();
1503234353Sdim  CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1504234353Sdim  PrintingPolicy Policy = getCompletionPrintingPolicy(S);
1505234353Sdim  Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy,
1506234353Sdim                                                     S.Context,
1507234353Sdim                                                     Policy,
1508234353Sdim                                                     Allocator));
1509234353Sdim  Builder.AddTypedTextChunk("this");
1510243830Sdim  Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1511234353Sdim}
1512234353Sdim
1513202379Srdivacky/// \brief Add language constructs that show up for "ordinary" names.
1514212904Sdimstatic void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
1515202379Srdivacky                                   Scope *S,
1516202379Srdivacky                                   Sema &SemaRef,
1517202379Srdivacky                                   ResultBuilder &Results) {
1518234353Sdim  CodeCompletionAllocator &Allocator = Results.getAllocator();
1519234353Sdim  CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1520234353Sdim  PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef);
1521218893Sdim
1522212904Sdim  typedef CodeCompletionResult Result;
1523202379Srdivacky  switch (CCC) {
1524212904Sdim  case Sema::PCC_Namespace:
1525234353Sdim    if (SemaRef.getLangOpts().CPlusPlus) {
1526210299Sed      if (Results.includeCodePatterns()) {
1527210299Sed        // namespace <identifier> { declarations }
1528218893Sdim        Builder.AddTypedTextChunk("namespace");
1529218893Sdim        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1530218893Sdim        Builder.AddPlaceholderChunk("identifier");
1531218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1532218893Sdim        Builder.AddPlaceholderChunk("declarations");
1533218893Sdim        Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1534218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1535218893Sdim        Results.AddResult(Result(Builder.TakeString()));
1536210299Sed      }
1537210299Sed
1538202379Srdivacky      // namespace identifier = identifier ;
1539218893Sdim      Builder.AddTypedTextChunk("namespace");
1540218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1541218893Sdim      Builder.AddPlaceholderChunk("name");
1542218893Sdim      Builder.AddChunk(CodeCompletionString::CK_Equal);
1543218893Sdim      Builder.AddPlaceholderChunk("namespace");
1544218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1545202379Srdivacky
1546202379Srdivacky      // Using directives
1547218893Sdim      Builder.AddTypedTextChunk("using");
1548218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1549218893Sdim      Builder.AddTextChunk("namespace");
1550218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1551218893Sdim      Builder.AddPlaceholderChunk("identifier");
1552218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1553202379Srdivacky
1554202379Srdivacky      // asm(string-literal)
1555218893Sdim      Builder.AddTypedTextChunk("asm");
1556218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1557218893Sdim      Builder.AddPlaceholderChunk("string-literal");
1558218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1559218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1560202379Srdivacky
1561210299Sed      if (Results.includeCodePatterns()) {
1562210299Sed        // Explicit template instantiation
1563218893Sdim        Builder.AddTypedTextChunk("template");
1564218893Sdim        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1565218893Sdim        Builder.AddPlaceholderChunk("declaration");
1566218893Sdim        Results.AddResult(Result(Builder.TakeString()));
1567210299Sed      }
1568202379Srdivacky    }
1569202379Srdivacky
1570234353Sdim    if (SemaRef.getLangOpts().ObjC1)
1571202379Srdivacky      AddObjCTopLevelResults(Results, true);
1572202379Srdivacky
1573210299Sed    AddTypedefResult(Results);
1574202379Srdivacky    // Fall through
1575202379Srdivacky
1576212904Sdim  case Sema::PCC_Class:
1577234353Sdim    if (SemaRef.getLangOpts().CPlusPlus) {
1578202379Srdivacky      // Using declaration
1579218893Sdim      Builder.AddTypedTextChunk("using");
1580218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1581218893Sdim      Builder.AddPlaceholderChunk("qualifier");
1582218893Sdim      Builder.AddTextChunk("::");
1583218893Sdim      Builder.AddPlaceholderChunk("name");
1584218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1585202379Srdivacky
1586210299Sed      // using typename qualifier::name (only in a dependent context)
1587202379Srdivacky      if (SemaRef.CurContext->isDependentContext()) {
1588218893Sdim        Builder.AddTypedTextChunk("using");
1589218893Sdim        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1590218893Sdim        Builder.AddTextChunk("typename");
1591218893Sdim        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1592218893Sdim        Builder.AddPlaceholderChunk("qualifier");
1593218893Sdim        Builder.AddTextChunk("::");
1594218893Sdim        Builder.AddPlaceholderChunk("name");
1595218893Sdim        Results.AddResult(Result(Builder.TakeString()));
1596202379Srdivacky      }
1597202379Srdivacky
1598212904Sdim      if (CCC == Sema::PCC_Class) {
1599210299Sed        AddTypedefResult(Results);
1600210299Sed
1601202379Srdivacky        // public:
1602218893Sdim        Builder.AddTypedTextChunk("public");
1603234353Sdim        if (Results.includeCodePatterns())
1604234353Sdim          Builder.AddChunk(CodeCompletionString::CK_Colon);
1605218893Sdim        Results.AddResult(Result(Builder.TakeString()));
1606202379Srdivacky
1607202379Srdivacky        // protected:
1608218893Sdim        Builder.AddTypedTextChunk("protected");
1609234353Sdim        if (Results.includeCodePatterns())
1610234353Sdim          Builder.AddChunk(CodeCompletionString::CK_Colon);
1611218893Sdim        Results.AddResult(Result(Builder.TakeString()));
1612202379Srdivacky
1613202379Srdivacky        // private:
1614218893Sdim        Builder.AddTypedTextChunk("private");
1615234353Sdim        if (Results.includeCodePatterns())
1616234353Sdim          Builder.AddChunk(CodeCompletionString::CK_Colon);
1617218893Sdim        Results.AddResult(Result(Builder.TakeString()));
1618202379Srdivacky      }
1619202379Srdivacky    }
1620202379Srdivacky    // Fall through
1621202379Srdivacky
1622212904Sdim  case Sema::PCC_Template:
1623212904Sdim  case Sema::PCC_MemberTemplate:
1624234353Sdim    if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) {
1625202379Srdivacky      // template < parameters >
1626218893Sdim      Builder.AddTypedTextChunk("template");
1627218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1628218893Sdim      Builder.AddPlaceholderChunk("parameters");
1629218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1630218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1631202379Srdivacky    }
1632202379Srdivacky
1633234353Sdim    AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1634234353Sdim    AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1635202379Srdivacky    break;
1636202379Srdivacky
1637212904Sdim  case Sema::PCC_ObjCInterface:
1638234353Sdim    AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true);
1639234353Sdim    AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1640234353Sdim    AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1641202379Srdivacky    break;
1642202379Srdivacky
1643212904Sdim  case Sema::PCC_ObjCImplementation:
1644234353Sdim    AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true);
1645234353Sdim    AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1646234353Sdim    AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1647202379Srdivacky    break;
1648202379Srdivacky
1649212904Sdim  case Sema::PCC_ObjCInstanceVariableList:
1650234353Sdim    AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true);
1651202379Srdivacky    break;
1652202379Srdivacky
1653212904Sdim  case Sema::PCC_RecoveryInFunction:
1654212904Sdim  case Sema::PCC_Statement: {
1655210299Sed    AddTypedefResult(Results);
1656202379Srdivacky
1657234353Sdim    if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() &&
1658234353Sdim        SemaRef.getLangOpts().CXXExceptions) {
1659218893Sdim      Builder.AddTypedTextChunk("try");
1660218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1661218893Sdim      Builder.AddPlaceholderChunk("statements");
1662218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1663218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1664218893Sdim      Builder.AddTextChunk("catch");
1665218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1666218893Sdim      Builder.AddPlaceholderChunk("declaration");
1667218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1668218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1669218893Sdim      Builder.AddPlaceholderChunk("statements");
1670218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1671218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1672218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1673202379Srdivacky    }
1674234353Sdim    if (SemaRef.getLangOpts().ObjC1)
1675202379Srdivacky      AddObjCStatementResults(Results, true);
1676202379Srdivacky
1677208600Srdivacky    if (Results.includeCodePatterns()) {
1678208600Srdivacky      // if (condition) { statements }
1679218893Sdim      Builder.AddTypedTextChunk("if");
1680218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1681234353Sdim      if (SemaRef.getLangOpts().CPlusPlus)
1682218893Sdim        Builder.AddPlaceholderChunk("condition");
1683208600Srdivacky      else
1684218893Sdim        Builder.AddPlaceholderChunk("expression");
1685218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1686218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1687218893Sdim      Builder.AddPlaceholderChunk("statements");
1688218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1689218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1690218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1691202379Srdivacky
1692208600Srdivacky      // switch (condition) { }
1693218893Sdim      Builder.AddTypedTextChunk("switch");
1694218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1695234353Sdim      if (SemaRef.getLangOpts().CPlusPlus)
1696218893Sdim        Builder.AddPlaceholderChunk("condition");
1697208600Srdivacky      else
1698218893Sdim        Builder.AddPlaceholderChunk("expression");
1699218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1700218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1701218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1702218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1703218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1704208600Srdivacky    }
1705208600Srdivacky
1706202379Srdivacky    // Switch-specific statements.
1707212904Sdim    if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
1708202379Srdivacky      // case expression:
1709218893Sdim      Builder.AddTypedTextChunk("case");
1710218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1711218893Sdim      Builder.AddPlaceholderChunk("expression");
1712218893Sdim      Builder.AddChunk(CodeCompletionString::CK_Colon);
1713218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1714202379Srdivacky
1715202379Srdivacky      // default:
1716218893Sdim      Builder.AddTypedTextChunk("default");
1717218893Sdim      Builder.AddChunk(CodeCompletionString::CK_Colon);
1718218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1719202379Srdivacky    }
1720202379Srdivacky
1721208600Srdivacky    if (Results.includeCodePatterns()) {
1722208600Srdivacky      /// while (condition) { statements }
1723218893Sdim      Builder.AddTypedTextChunk("while");
1724218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1725234353Sdim      if (SemaRef.getLangOpts().CPlusPlus)
1726218893Sdim        Builder.AddPlaceholderChunk("condition");
1727208600Srdivacky      else
1728218893Sdim        Builder.AddPlaceholderChunk("expression");
1729218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1730218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1731218893Sdim      Builder.AddPlaceholderChunk("statements");
1732218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1733218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1734218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1735208600Srdivacky
1736208600Srdivacky      // do { statements } while ( expression );
1737218893Sdim      Builder.AddTypedTextChunk("do");
1738218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1739218893Sdim      Builder.AddPlaceholderChunk("statements");
1740218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1741218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1742218893Sdim      Builder.AddTextChunk("while");
1743218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1744218893Sdim      Builder.AddPlaceholderChunk("expression");
1745218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1746218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1747202379Srdivacky
1748208600Srdivacky      // for ( for-init-statement ; condition ; expression ) { statements }
1749218893Sdim      Builder.AddTypedTextChunk("for");
1750218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1751234353Sdim      if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99)
1752218893Sdim        Builder.AddPlaceholderChunk("init-statement");
1753208600Srdivacky      else
1754218893Sdim        Builder.AddPlaceholderChunk("init-expression");
1755218893Sdim      Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1756218893Sdim      Builder.AddPlaceholderChunk("condition");
1757218893Sdim      Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1758218893Sdim      Builder.AddPlaceholderChunk("inc-expression");
1759218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1760218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1761218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1762218893Sdim      Builder.AddPlaceholderChunk("statements");
1763218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1764218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1765218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1766208600Srdivacky    }
1767202379Srdivacky
1768202379Srdivacky    if (S->getContinueParent()) {
1769202379Srdivacky      // continue ;
1770218893Sdim      Builder.AddTypedTextChunk("continue");
1771218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1772202379Srdivacky    }
1773202379Srdivacky
1774202379Srdivacky    if (S->getBreakParent()) {
1775202379Srdivacky      // break ;
1776218893Sdim      Builder.AddTypedTextChunk("break");
1777218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1778202379Srdivacky    }
1779202379Srdivacky
1780202379Srdivacky    // "return expression ;" or "return ;", depending on whether we
1781202379Srdivacky    // know the function is void or not.
1782202379Srdivacky    bool isVoid = false;
1783202379Srdivacky    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1784202379Srdivacky      isVoid = Function->getResultType()->isVoidType();
1785202379Srdivacky    else if (ObjCMethodDecl *Method
1786202379Srdivacky                                 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1787202379Srdivacky      isVoid = Method->getResultType()->isVoidType();
1788204643Srdivacky    else if (SemaRef.getCurBlock() &&
1789204643Srdivacky             !SemaRef.getCurBlock()->ReturnType.isNull())
1790204643Srdivacky      isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
1791218893Sdim    Builder.AddTypedTextChunk("return");
1792204643Srdivacky    if (!isVoid) {
1793218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1794218893Sdim      Builder.AddPlaceholderChunk("expression");
1795204643Srdivacky    }
1796218893Sdim    Results.AddResult(Result(Builder.TakeString()));
1797202379Srdivacky
1798210299Sed    // goto identifier ;
1799218893Sdim    Builder.AddTypedTextChunk("goto");
1800218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1801218893Sdim    Builder.AddPlaceholderChunk("label");
1802218893Sdim    Results.AddResult(Result(Builder.TakeString()));
1803202379Srdivacky
1804210299Sed    // Using directives
1805218893Sdim    Builder.AddTypedTextChunk("using");
1806218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1807218893Sdim    Builder.AddTextChunk("namespace");
1808218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1809218893Sdim    Builder.AddPlaceholderChunk("identifier");
1810218893Sdim    Results.AddResult(Result(Builder.TakeString()));
1811202379Srdivacky  }
1812202379Srdivacky
1813202379Srdivacky  // Fall through (for statement expressions).
1814212904Sdim  case Sema::PCC_ForInit:
1815212904Sdim  case Sema::PCC_Condition:
1816234353Sdim    AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1817202379Srdivacky    // Fall through: conditions and statements can have expressions.
1818202379Srdivacky
1819218893Sdim  case Sema::PCC_ParenthesizedExpression:
1820234353Sdim    if (SemaRef.getLangOpts().ObjCAutoRefCount &&
1821224145Sdim        CCC == Sema::PCC_ParenthesizedExpression) {
1822224145Sdim      // (__bridge <type>)<expression>
1823224145Sdim      Builder.AddTypedTextChunk("__bridge");
1824224145Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1825224145Sdim      Builder.AddPlaceholderChunk("type");
1826224145Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1827224145Sdim      Builder.AddPlaceholderChunk("expression");
1828224145Sdim      Results.AddResult(Result(Builder.TakeString()));
1829224145Sdim
1830224145Sdim      // (__bridge_transfer <Objective-C type>)<expression>
1831224145Sdim      Builder.AddTypedTextChunk("__bridge_transfer");
1832224145Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1833224145Sdim      Builder.AddPlaceholderChunk("Objective-C type");
1834224145Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1835224145Sdim      Builder.AddPlaceholderChunk("expression");
1836224145Sdim      Results.AddResult(Result(Builder.TakeString()));
1837224145Sdim
1838224145Sdim      // (__bridge_retained <CF type>)<expression>
1839224145Sdim      Builder.AddTypedTextChunk("__bridge_retained");
1840224145Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1841224145Sdim      Builder.AddPlaceholderChunk("CF type");
1842224145Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1843224145Sdim      Builder.AddPlaceholderChunk("expression");
1844224145Sdim      Results.AddResult(Result(Builder.TakeString()));
1845224145Sdim    }
1846224145Sdim    // Fall through
1847224145Sdim
1848212904Sdim  case Sema::PCC_Expression: {
1849234353Sdim    if (SemaRef.getLangOpts().CPlusPlus) {
1850202379Srdivacky      // 'this', if we're in a non-static member function.
1851234353Sdim      addThisCompletion(SemaRef, Results);
1852202379Srdivacky
1853234353Sdim      // true
1854234353Sdim      Builder.AddResultTypeChunk("bool");
1855234353Sdim      Builder.AddTypedTextChunk("true");
1856234353Sdim      Results.AddResult(Result(Builder.TakeString()));
1857234353Sdim
1858234353Sdim      // false
1859234353Sdim      Builder.AddResultTypeChunk("bool");
1860234353Sdim      Builder.AddTypedTextChunk("false");
1861234353Sdim      Results.AddResult(Result(Builder.TakeString()));
1862202379Srdivacky
1863234353Sdim      if (SemaRef.getLangOpts().RTTI) {
1864221345Sdim        // dynamic_cast < type-id > ( expression )
1865221345Sdim        Builder.AddTypedTextChunk("dynamic_cast");
1866221345Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1867221345Sdim        Builder.AddPlaceholderChunk("type");
1868221345Sdim        Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1869221345Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1870221345Sdim        Builder.AddPlaceholderChunk("expression");
1871221345Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
1872221345Sdim        Results.AddResult(Result(Builder.TakeString()));
1873221345Sdim      }
1874210299Sed
1875210299Sed      // static_cast < type-id > ( expression )
1876218893Sdim      Builder.AddTypedTextChunk("static_cast");
1877218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1878218893Sdim      Builder.AddPlaceholderChunk("type");
1879218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1880218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1881218893Sdim      Builder.AddPlaceholderChunk("expression");
1882218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1883218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1884202379Srdivacky
1885210299Sed      // reinterpret_cast < type-id > ( expression )
1886218893Sdim      Builder.AddTypedTextChunk("reinterpret_cast");
1887218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1888218893Sdim      Builder.AddPlaceholderChunk("type");
1889218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1890218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1891218893Sdim      Builder.AddPlaceholderChunk("expression");
1892218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1893218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1894202379Srdivacky
1895210299Sed      // const_cast < type-id > ( expression )
1896218893Sdim      Builder.AddTypedTextChunk("const_cast");
1897218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1898218893Sdim      Builder.AddPlaceholderChunk("type");
1899218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1900218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1901218893Sdim      Builder.AddPlaceholderChunk("expression");
1902218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1903218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1904202379Srdivacky
1905234353Sdim      if (SemaRef.getLangOpts().RTTI) {
1906221345Sdim        // typeid ( expression-or-type )
1907234353Sdim        Builder.AddResultTypeChunk("std::type_info");
1908221345Sdim        Builder.AddTypedTextChunk("typeid");
1909221345Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1910221345Sdim        Builder.AddPlaceholderChunk("expression-or-type");
1911221345Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
1912221345Sdim        Results.AddResult(Result(Builder.TakeString()));
1913221345Sdim      }
1914221345Sdim
1915210299Sed      // new T ( ... )
1916218893Sdim      Builder.AddTypedTextChunk("new");
1917218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1918218893Sdim      Builder.AddPlaceholderChunk("type");
1919218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1920218893Sdim      Builder.AddPlaceholderChunk("expressions");
1921218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1922218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1923202379Srdivacky
1924210299Sed      // new T [ ] ( ... )
1925218893Sdim      Builder.AddTypedTextChunk("new");
1926218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1927218893Sdim      Builder.AddPlaceholderChunk("type");
1928218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
1929218893Sdim      Builder.AddPlaceholderChunk("size");
1930218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBracket);
1931218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1932218893Sdim      Builder.AddPlaceholderChunk("expressions");
1933218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
1934218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1935202379Srdivacky
1936210299Sed      // delete expression
1937234353Sdim      Builder.AddResultTypeChunk("void");
1938218893Sdim      Builder.AddTypedTextChunk("delete");
1939218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1940218893Sdim      Builder.AddPlaceholderChunk("expression");
1941218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1942202379Srdivacky
1943210299Sed      // delete [] expression
1944234353Sdim      Builder.AddResultTypeChunk("void");
1945218893Sdim      Builder.AddTypedTextChunk("delete");
1946218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1947218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
1948218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBracket);
1949218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1950218893Sdim      Builder.AddPlaceholderChunk("expression");
1951218893Sdim      Results.AddResult(Result(Builder.TakeString()));
1952202379Srdivacky
1953234353Sdim      if (SemaRef.getLangOpts().CXXExceptions) {
1954221345Sdim        // throw expression
1955234353Sdim        Builder.AddResultTypeChunk("void");
1956221345Sdim        Builder.AddTypedTextChunk("throw");
1957221345Sdim        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1958221345Sdim        Builder.AddPlaceholderChunk("expression");
1959221345Sdim        Results.AddResult(Result(Builder.TakeString()));
1960221345Sdim      }
1961234353Sdim
1962208600Srdivacky      // FIXME: Rethrow?
1963234353Sdim
1964249423Sdim      if (SemaRef.getLangOpts().CPlusPlus11) {
1965234353Sdim        // nullptr
1966234353Sdim        Builder.AddResultTypeChunk("std::nullptr_t");
1967234353Sdim        Builder.AddTypedTextChunk("nullptr");
1968234353Sdim        Results.AddResult(Result(Builder.TakeString()));
1969234353Sdim
1970234353Sdim        // alignof
1971234353Sdim        Builder.AddResultTypeChunk("size_t");
1972234353Sdim        Builder.AddTypedTextChunk("alignof");
1973234353Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1974234353Sdim        Builder.AddPlaceholderChunk("type");
1975234353Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
1976234353Sdim        Results.AddResult(Result(Builder.TakeString()));
1977234353Sdim
1978234353Sdim        // noexcept
1979234353Sdim        Builder.AddResultTypeChunk("bool");
1980234353Sdim        Builder.AddTypedTextChunk("noexcept");
1981234353Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1982234353Sdim        Builder.AddPlaceholderChunk("expression");
1983234353Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
1984234353Sdim        Results.AddResult(Result(Builder.TakeString()));
1985234353Sdim
1986234353Sdim        // sizeof... expression
1987234353Sdim        Builder.AddResultTypeChunk("size_t");
1988234353Sdim        Builder.AddTypedTextChunk("sizeof...");
1989234353Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1990234353Sdim        Builder.AddPlaceholderChunk("parameter-pack");
1991234353Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
1992234353Sdim        Results.AddResult(Result(Builder.TakeString()));
1993234353Sdim      }
1994202379Srdivacky    }
1995202379Srdivacky
1996234353Sdim    if (SemaRef.getLangOpts().ObjC1) {
1997202379Srdivacky      // Add "super", if we're in an Objective-C class with a superclass.
1998210299Sed      if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
1999210299Sed        // The interface can be NULL.
2000210299Sed        if (ObjCInterfaceDecl *ID = Method->getClassInterface())
2001234353Sdim          if (ID->getSuperClass()) {
2002234353Sdim            std::string SuperType;
2003234353Sdim            SuperType = ID->getSuperClass()->getNameAsString();
2004234353Sdim            if (Method->isInstanceMethod())
2005234353Sdim              SuperType += " *";
2006234353Sdim
2007234353Sdim            Builder.AddResultTypeChunk(Allocator.CopyString(SuperType));
2008234353Sdim            Builder.AddTypedTextChunk("super");
2009234353Sdim            Results.AddResult(Result(Builder.TakeString()));
2010234353Sdim          }
2011210299Sed      }
2012210299Sed
2013202379Srdivacky      AddObjCExpressionResults(Results, true);
2014202379Srdivacky    }
2015202379Srdivacky
2016239462Sdim    if (SemaRef.getLangOpts().C11) {
2017239462Sdim      // _Alignof
2018239462Sdim      Builder.AddResultTypeChunk("size_t");
2019239462Sdim      if (SemaRef.getASTContext().Idents.get("alignof").hasMacroDefinition())
2020239462Sdim        Builder.AddTypedTextChunk("alignof");
2021239462Sdim      else
2022239462Sdim        Builder.AddTypedTextChunk("_Alignof");
2023239462Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2024239462Sdim      Builder.AddPlaceholderChunk("type");
2025239462Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
2026239462Sdim      Results.AddResult(Result(Builder.TakeString()));
2027239462Sdim    }
2028239462Sdim
2029210299Sed    // sizeof expression
2030234353Sdim    Builder.AddResultTypeChunk("size_t");
2031218893Sdim    Builder.AddTypedTextChunk("sizeof");
2032218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2033218893Sdim    Builder.AddPlaceholderChunk("expression-or-type");
2034218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
2035218893Sdim    Results.AddResult(Result(Builder.TakeString()));
2036202379Srdivacky    break;
2037202379Srdivacky  }
2038212904Sdim
2039212904Sdim  case Sema::PCC_Type:
2040218893Sdim  case Sema::PCC_LocalDeclarationSpecifiers:
2041212904Sdim    break;
2042202379Srdivacky  }
2043202379Srdivacky
2044234353Sdim  if (WantTypesInContext(CCC, SemaRef.getLangOpts()))
2045234353Sdim    AddTypeSpecifierResults(SemaRef.getLangOpts(), Results);
2046202379Srdivacky
2047234353Sdim  if (SemaRef.getLangOpts().CPlusPlus && CCC != Sema::PCC_Type)
2048202379Srdivacky    Results.AddResult(Result("operator"));
2049202379Srdivacky}
2050202379Srdivacky
2051201361Srdivacky/// \brief If the given declaration has an associated type, add it as a result
2052201361Srdivacky/// type chunk.
2053201361Srdivackystatic void AddResultTypeChunk(ASTContext &Context,
2054226633Sdim                               const PrintingPolicy &Policy,
2055249423Sdim                               const NamedDecl *ND,
2056218893Sdim                               CodeCompletionBuilder &Result) {
2057201361Srdivacky  if (!ND)
2058201361Srdivacky    return;
2059218893Sdim
2060218893Sdim  // Skip constructors and conversion functions, which have their return types
2061218893Sdim  // built into their names.
2062218893Sdim  if (isa<CXXConstructorDecl>(ND) || isa<CXXConversionDecl>(ND))
2063218893Sdim    return;
2064218893Sdim
2065201361Srdivacky  // Determine the type of the declaration (if it has a type).
2066218893Sdim  QualType T;
2067249423Sdim  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
2068201361Srdivacky    T = Function->getResultType();
2069249423Sdim  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
2070201361Srdivacky    T = Method->getResultType();
2071249423Sdim  else if (const FunctionTemplateDecl *FunTmpl =
2072249423Sdim               dyn_cast<FunctionTemplateDecl>(ND))
2073201361Srdivacky    T = FunTmpl->getTemplatedDecl()->getResultType();
2074249423Sdim  else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
2075201361Srdivacky    T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
2076201361Srdivacky  else if (isa<UnresolvedUsingValueDecl>(ND)) {
2077201361Srdivacky    /* Do nothing: ignore unresolved using declarations*/
2078249423Sdim  } else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) {
2079201361Srdivacky    T = Value->getType();
2080249423Sdim  } else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
2081201361Srdivacky    T = Property->getType();
2082201361Srdivacky
2083201361Srdivacky  if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
2084201361Srdivacky    return;
2085201361Srdivacky
2086226633Sdim  Result.AddResultTypeChunk(GetCompletionTypeString(T, Context, Policy,
2087218893Sdim                                                    Result.getAllocator()));
2088201361Srdivacky}
2089201361Srdivacky
2090249423Sdimstatic void MaybeAddSentinel(ASTContext &Context,
2091249423Sdim                             const NamedDecl *FunctionOrMethod,
2092218893Sdim                             CodeCompletionBuilder &Result) {
2093212904Sdim  if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
2094212904Sdim    if (Sentinel->getSentinel() == 0) {
2095234353Sdim      if (Context.getLangOpts().ObjC1 &&
2096212904Sdim          Context.Idents.get("nil").hasMacroDefinition())
2097218893Sdim        Result.AddTextChunk(", nil");
2098212904Sdim      else if (Context.Idents.get("NULL").hasMacroDefinition())
2099218893Sdim        Result.AddTextChunk(", NULL");
2100212904Sdim      else
2101218893Sdim        Result.AddTextChunk(", (void*)0");
2102212904Sdim    }
2103212904Sdim}
2104212904Sdim
2105226633Sdimstatic std::string formatObjCParamQualifiers(unsigned ObjCQuals) {
2106226633Sdim  std::string Result;
2107226633Sdim  if (ObjCQuals & Decl::OBJC_TQ_In)
2108234353Sdim    Result += "in ";
2109226633Sdim  else if (ObjCQuals & Decl::OBJC_TQ_Inout)
2110234353Sdim    Result += "inout ";
2111226633Sdim  else if (ObjCQuals & Decl::OBJC_TQ_Out)
2112234353Sdim    Result += "out ";
2113226633Sdim  if (ObjCQuals & Decl::OBJC_TQ_Bycopy)
2114234353Sdim    Result += "bycopy ";
2115226633Sdim  else if (ObjCQuals & Decl::OBJC_TQ_Byref)
2116234353Sdim    Result += "byref ";
2117226633Sdim  if (ObjCQuals & Decl::OBJC_TQ_Oneway)
2118234353Sdim    Result += "oneway ";
2119226633Sdim  return Result;
2120226633Sdim}
2121226633Sdim
2122212904Sdimstatic std::string FormatFunctionParameter(ASTContext &Context,
2123226633Sdim                                           const PrintingPolicy &Policy,
2124249423Sdim                                           const ParmVarDecl *Param,
2125234353Sdim                                           bool SuppressName = false,
2126234353Sdim                                           bool SuppressBlock = false) {
2127212904Sdim  bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
2128212904Sdim  if (Param->getType()->isDependentType() ||
2129212904Sdim      !Param->getType()->isBlockPointerType()) {
2130212904Sdim    // The argument for a dependent or non-block parameter is a placeholder
2131212904Sdim    // containing that parameter's type.
2132212904Sdim    std::string Result;
2133212904Sdim
2134212904Sdim    if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
2135212904Sdim      Result = Param->getIdentifier()->getName();
2136212904Sdim
2137224145Sdim    Param->getType().getAsStringInternal(Result, Policy);
2138212904Sdim
2139212904Sdim    if (ObjCMethodParam) {
2140226633Sdim      Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier())
2141226633Sdim             + Result + ")";
2142212904Sdim      if (Param->getIdentifier() && !SuppressName)
2143212904Sdim        Result += Param->getIdentifier()->getName();
2144212904Sdim    }
2145212904Sdim    return Result;
2146212904Sdim  }
2147212904Sdim
2148212904Sdim  // The argument for a block pointer parameter is a block literal with
2149212904Sdim  // the appropriate type.
2150249423Sdim  FunctionTypeLoc Block;
2151249423Sdim  FunctionProtoTypeLoc BlockProto;
2152212904Sdim  TypeLoc TL;
2153212904Sdim  if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
2154212904Sdim    TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
2155212904Sdim    while (true) {
2156212904Sdim      // Look through typedefs.
2157234353Sdim      if (!SuppressBlock) {
2158249423Sdim        if (TypedefTypeLoc TypedefTL = TL.getAs<TypedefTypeLoc>()) {
2159249423Sdim          if (TypeSourceInfo *InnerTSInfo =
2160249423Sdim                  TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) {
2161234353Sdim            TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
2162234353Sdim            continue;
2163234353Sdim          }
2164234353Sdim        }
2165234353Sdim
2166234353Sdim        // Look through qualified types
2167249423Sdim        if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) {
2168249423Sdim          TL = QualifiedTL.getUnqualifiedLoc();
2169212904Sdim          continue;
2170212904Sdim        }
2171212904Sdim      }
2172212904Sdim
2173212904Sdim      // Try to get the function prototype behind the block pointer type,
2174212904Sdim      // then we're done.
2175249423Sdim      if (BlockPointerTypeLoc BlockPtr = TL.getAs<BlockPointerTypeLoc>()) {
2176249423Sdim        TL = BlockPtr.getPointeeLoc().IgnoreParens();
2177249423Sdim        Block = TL.getAs<FunctionTypeLoc>();
2178249423Sdim        BlockProto = TL.getAs<FunctionProtoTypeLoc>();
2179212904Sdim      }
2180212904Sdim      break;
2181212904Sdim    }
2182212904Sdim  }
2183212904Sdim
2184212904Sdim  if (!Block) {
2185212904Sdim    // We were unable to find a FunctionProtoTypeLoc with parameter names
2186212904Sdim    // for the block; just use the parameter type as a placeholder.
2187212904Sdim    std::string Result;
2188234353Sdim    if (!ObjCMethodParam && Param->getIdentifier())
2189234353Sdim      Result = Param->getIdentifier()->getName();
2190234353Sdim
2191224145Sdim    Param->getType().getUnqualifiedType().getAsStringInternal(Result, Policy);
2192212904Sdim
2193212904Sdim    if (ObjCMethodParam) {
2194226633Sdim      Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier())
2195226633Sdim             + Result + ")";
2196212904Sdim      if (Param->getIdentifier())
2197212904Sdim        Result += Param->getIdentifier()->getName();
2198212904Sdim    }
2199212904Sdim
2200212904Sdim    return Result;
2201212904Sdim  }
2202234353Sdim
2203212904Sdim  // We have the function prototype behind the block pointer type, as it was
2204212904Sdim  // written in the source.
2205218893Sdim  std::string Result;
2206249423Sdim  QualType ResultType = Block.getTypePtr()->getResultType();
2207234353Sdim  if (!ResultType->isVoidType() || SuppressBlock)
2208224145Sdim    ResultType.getAsStringInternal(Result, Policy);
2209234353Sdim
2210234353Sdim  // Format the parameter list.
2211234353Sdim  std::string Params;
2212249423Sdim  if (!BlockProto || Block.getNumArgs() == 0) {
2213249423Sdim    if (BlockProto && BlockProto.getTypePtr()->isVariadic())
2214234353Sdim      Params = "(...)";
2215218893Sdim    else
2216234353Sdim      Params = "(void)";
2217218893Sdim  } else {
2218234353Sdim    Params += "(";
2219249423Sdim    for (unsigned I = 0, N = Block.getNumArgs(); I != N; ++I) {
2220218893Sdim      if (I)
2221234353Sdim        Params += ", ";
2222249423Sdim      Params += FormatFunctionParameter(Context, Policy, Block.getArg(I),
2223234353Sdim                                        /*SuppressName=*/false,
2224234353Sdim                                        /*SuppressBlock=*/true);
2225218893Sdim
2226249423Sdim      if (I == N - 1 && BlockProto.getTypePtr()->isVariadic())
2227234353Sdim        Params += ", ...";
2228218893Sdim    }
2229234353Sdim    Params += ")";
2230234353Sdim  }
2231234353Sdim
2232234353Sdim  if (SuppressBlock) {
2233234353Sdim    // Format as a parameter.
2234234353Sdim    Result = Result + " (^";
2235234353Sdim    if (Param->getIdentifier())
2236234353Sdim      Result += Param->getIdentifier()->getName();
2237218893Sdim    Result += ")";
2238234353Sdim    Result += Params;
2239234353Sdim  } else {
2240234353Sdim    // Format as a block literal argument.
2241234353Sdim    Result = '^' + Result;
2242234353Sdim    Result += Params;
2243234353Sdim
2244234353Sdim    if (Param->getIdentifier())
2245234353Sdim      Result += Param->getIdentifier()->getName();
2246212904Sdim  }
2247218893Sdim
2248212904Sdim  return Result;
2249212904Sdim}
2250212904Sdim
2251198092Srdivacky/// \brief Add function parameter chunks to the given code completion string.
2252198092Srdivackystatic void AddFunctionParameterChunks(ASTContext &Context,
2253226633Sdim                                       const PrintingPolicy &Policy,
2254249423Sdim                                       const FunctionDecl *Function,
2255218893Sdim                                       CodeCompletionBuilder &Result,
2256218893Sdim                                       unsigned Start = 0,
2257218893Sdim                                       bool InOptional = false) {
2258218893Sdim  bool FirstParameter = true;
2259199482Srdivacky
2260218893Sdim  for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) {
2261249423Sdim    const ParmVarDecl *Param = Function->getParamDecl(P);
2262198092Srdivacky
2263218893Sdim    if (Param->hasDefaultArg() && !InOptional) {
2264198092Srdivacky      // When we see an optional default argument, put that argument and
2265198092Srdivacky      // the remaining default arguments into a new, optional string.
2266234353Sdim      CodeCompletionBuilder Opt(Result.getAllocator(),
2267234353Sdim                                Result.getCodeCompletionTUInfo());
2268218893Sdim      if (!FirstParameter)
2269234353Sdim        Opt.AddChunk(CodeCompletionString::CK_Comma);
2270226633Sdim      AddFunctionParameterChunks(Context, Policy, Function, Opt, P, true);
2271218893Sdim      Result.AddOptionalChunk(Opt.TakeString());
2272218893Sdim      break;
2273198092Srdivacky    }
2274198092Srdivacky
2275218893Sdim    if (FirstParameter)
2276218893Sdim      FirstParameter = false;
2277218893Sdim    else
2278234353Sdim      Result.AddChunk(CodeCompletionString::CK_Comma);
2279198092Srdivacky
2280218893Sdim    InOptional = false;
2281218893Sdim
2282198092Srdivacky    // Format the placeholder string.
2283226633Sdim    std::string PlaceholderStr = FormatFunctionParameter(Context, Policy,
2284226633Sdim                                                         Param);
2285212904Sdim
2286212904Sdim    if (Function->isVariadic() && P == N - 1)
2287212904Sdim      PlaceholderStr += ", ...";
2288212904Sdim
2289198092Srdivacky    // Add the placeholder string.
2290218893Sdim    Result.AddPlaceholderChunk(
2291218893Sdim                             Result.getAllocator().CopyString(PlaceholderStr));
2292198092Srdivacky  }
2293198092Srdivacky
2294198092Srdivacky  if (const FunctionProtoType *Proto
2295198092Srdivacky        = Function->getType()->getAs<FunctionProtoType>())
2296212904Sdim    if (Proto->isVariadic()) {
2297212904Sdim      if (Proto->getNumArgs() == 0)
2298218893Sdim        Result.AddPlaceholderChunk("...");
2299212904Sdim
2300218893Sdim      MaybeAddSentinel(Context, Function, Result);
2301212904Sdim    }
2302198092Srdivacky}
2303198092Srdivacky
2304198092Srdivacky/// \brief Add template parameter chunks to the given code completion string.
2305198092Srdivackystatic void AddTemplateParameterChunks(ASTContext &Context,
2306226633Sdim                                       const PrintingPolicy &Policy,
2307249423Sdim                                       const TemplateDecl *Template,
2308218893Sdim                                       CodeCompletionBuilder &Result,
2309218893Sdim                                       unsigned MaxParameters = 0,
2310218893Sdim                                       unsigned Start = 0,
2311218893Sdim                                       bool InDefaultArg = false) {
2312198092Srdivacky  bool FirstParameter = true;
2313198092Srdivacky
2314198092Srdivacky  TemplateParameterList *Params = Template->getTemplateParameters();
2315198092Srdivacky  TemplateParameterList::iterator PEnd = Params->end();
2316198092Srdivacky  if (MaxParameters)
2317198092Srdivacky    PEnd = Params->begin() + MaxParameters;
2318218893Sdim  for (TemplateParameterList::iterator P = Params->begin() + Start;
2319218893Sdim       P != PEnd; ++P) {
2320198092Srdivacky    bool HasDefaultArg = false;
2321198092Srdivacky    std::string PlaceholderStr;
2322198092Srdivacky    if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
2323198092Srdivacky      if (TTP->wasDeclaredWithTypename())
2324198092Srdivacky        PlaceholderStr = "typename";
2325198092Srdivacky      else
2326198092Srdivacky        PlaceholderStr = "class";
2327198092Srdivacky
2328198092Srdivacky      if (TTP->getIdentifier()) {
2329198092Srdivacky        PlaceholderStr += ' ';
2330198092Srdivacky        PlaceholderStr += TTP->getIdentifier()->getName();
2331198092Srdivacky      }
2332198092Srdivacky
2333198092Srdivacky      HasDefaultArg = TTP->hasDefaultArgument();
2334198092Srdivacky    } else if (NonTypeTemplateParmDecl *NTTP
2335218893Sdim                                    = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
2336198092Srdivacky      if (NTTP->getIdentifier())
2337198092Srdivacky        PlaceholderStr = NTTP->getIdentifier()->getName();
2338224145Sdim      NTTP->getType().getAsStringInternal(PlaceholderStr, Policy);
2339198092Srdivacky      HasDefaultArg = NTTP->hasDefaultArgument();
2340198092Srdivacky    } else {
2341198092Srdivacky      assert(isa<TemplateTemplateParmDecl>(*P));
2342198092Srdivacky      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
2343198092Srdivacky
2344198092Srdivacky      // Since putting the template argument list into the placeholder would
2345198092Srdivacky      // be very, very long, we just use an abbreviation.
2346198092Srdivacky      PlaceholderStr = "template<...> class";
2347198092Srdivacky      if (TTP->getIdentifier()) {
2348198092Srdivacky        PlaceholderStr += ' ';
2349198092Srdivacky        PlaceholderStr += TTP->getIdentifier()->getName();
2350198092Srdivacky      }
2351198092Srdivacky
2352198092Srdivacky      HasDefaultArg = TTP->hasDefaultArgument();
2353198092Srdivacky    }
2354198092Srdivacky
2355218893Sdim    if (HasDefaultArg && !InDefaultArg) {
2356198092Srdivacky      // When we see an optional default argument, put that argument and
2357198092Srdivacky      // the remaining default arguments into a new, optional string.
2358234353Sdim      CodeCompletionBuilder Opt(Result.getAllocator(),
2359234353Sdim                                Result.getCodeCompletionTUInfo());
2360218893Sdim      if (!FirstParameter)
2361234353Sdim        Opt.AddChunk(CodeCompletionString::CK_Comma);
2362226633Sdim      AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters,
2363218893Sdim                                 P - Params->begin(), true);
2364218893Sdim      Result.AddOptionalChunk(Opt.TakeString());
2365218893Sdim      break;
2366198092Srdivacky    }
2367198092Srdivacky
2368218893Sdim    InDefaultArg = false;
2369218893Sdim
2370198092Srdivacky    if (FirstParameter)
2371198092Srdivacky      FirstParameter = false;
2372198092Srdivacky    else
2373234353Sdim      Result.AddChunk(CodeCompletionString::CK_Comma);
2374198092Srdivacky
2375198092Srdivacky    // Add the placeholder string.
2376218893Sdim    Result.AddPlaceholderChunk(
2377218893Sdim                              Result.getAllocator().CopyString(PlaceholderStr));
2378198092Srdivacky  }
2379198092Srdivacky}
2380198092Srdivacky
2381198092Srdivacky/// \brief Add a qualifier to the given code-completion string, if the
2382198092Srdivacky/// provided nested-name-specifier is non-NULL.
2383200583Srdivackystatic void
2384218893SdimAddQualifierToCompletionString(CodeCompletionBuilder &Result,
2385200583Srdivacky                               NestedNameSpecifier *Qualifier,
2386200583Srdivacky                               bool QualifierIsInformative,
2387226633Sdim                               ASTContext &Context,
2388226633Sdim                               const PrintingPolicy &Policy) {
2389198092Srdivacky  if (!Qualifier)
2390198092Srdivacky    return;
2391198092Srdivacky
2392198092Srdivacky  std::string PrintedNNS;
2393198092Srdivacky  {
2394198092Srdivacky    llvm::raw_string_ostream OS(PrintedNNS);
2395226633Sdim    Qualifier->print(OS, Policy);
2396198092Srdivacky  }
2397198092Srdivacky  if (QualifierIsInformative)
2398218893Sdim    Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS));
2399198092Srdivacky  else
2400218893Sdim    Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS));
2401198092Srdivacky}
2402198092Srdivacky
2403218893Sdimstatic void
2404218893SdimAddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
2405249423Sdim                                       const FunctionDecl *Function) {
2406200583Srdivacky  const FunctionProtoType *Proto
2407200583Srdivacky    = Function->getType()->getAs<FunctionProtoType>();
2408200583Srdivacky  if (!Proto || !Proto->getTypeQuals())
2409200583Srdivacky    return;
2410200583Srdivacky
2411218893Sdim  // FIXME: Add ref-qualifier!
2412218893Sdim
2413218893Sdim  // Handle single qualifiers without copying
2414218893Sdim  if (Proto->getTypeQuals() == Qualifiers::Const) {
2415218893Sdim    Result.AddInformativeChunk(" const");
2416218893Sdim    return;
2417218893Sdim  }
2418218893Sdim
2419218893Sdim  if (Proto->getTypeQuals() == Qualifiers::Volatile) {
2420218893Sdim    Result.AddInformativeChunk(" volatile");
2421218893Sdim    return;
2422218893Sdim  }
2423218893Sdim
2424218893Sdim  if (Proto->getTypeQuals() == Qualifiers::Restrict) {
2425218893Sdim    Result.AddInformativeChunk(" restrict");
2426218893Sdim    return;
2427218893Sdim  }
2428218893Sdim
2429218893Sdim  // Handle multiple qualifiers.
2430200583Srdivacky  std::string QualsStr;
2431239462Sdim  if (Proto->isConst())
2432200583Srdivacky    QualsStr += " const";
2433239462Sdim  if (Proto->isVolatile())
2434200583Srdivacky    QualsStr += " volatile";
2435239462Sdim  if (Proto->isRestrict())
2436200583Srdivacky    QualsStr += " restrict";
2437218893Sdim  Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr));
2438200583Srdivacky}
2439200583Srdivacky
2440218893Sdim/// \brief Add the name of the given declaration
2441226633Sdimstatic void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
2442249423Sdim                              const NamedDecl *ND,
2443249423Sdim                              CodeCompletionBuilder &Result) {
2444218893Sdim  DeclarationName Name = ND->getDeclName();
2445218893Sdim  if (!Name)
2446218893Sdim    return;
2447218893Sdim
2448218893Sdim  switch (Name.getNameKind()) {
2449218893Sdim    case DeclarationName::CXXOperatorName: {
2450218893Sdim      const char *OperatorName = 0;
2451218893Sdim      switch (Name.getCXXOverloadedOperator()) {
2452218893Sdim      case OO_None:
2453218893Sdim      case OO_Conditional:
2454218893Sdim      case NUM_OVERLOADED_OPERATORS:
2455218893Sdim        OperatorName = "operator";
2456218893Sdim        break;
2457218893Sdim
2458218893Sdim#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2459218893Sdim      case OO_##Name: OperatorName = "operator" Spelling; break;
2460218893Sdim#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
2461218893Sdim#include "clang/Basic/OperatorKinds.def"
2462218893Sdim
2463218893Sdim      case OO_New:          OperatorName = "operator new"; break;
2464218893Sdim      case OO_Delete:       OperatorName = "operator delete"; break;
2465218893Sdim      case OO_Array_New:    OperatorName = "operator new[]"; break;
2466218893Sdim      case OO_Array_Delete: OperatorName = "operator delete[]"; break;
2467218893Sdim      case OO_Call:         OperatorName = "operator()"; break;
2468218893Sdim      case OO_Subscript:    OperatorName = "operator[]"; break;
2469218893Sdim      }
2470218893Sdim      Result.AddTypedTextChunk(OperatorName);
2471218893Sdim      break;
2472218893Sdim    }
2473218893Sdim
2474218893Sdim  case DeclarationName::Identifier:
2475218893Sdim  case DeclarationName::CXXConversionFunctionName:
2476218893Sdim  case DeclarationName::CXXDestructorName:
2477218893Sdim  case DeclarationName::CXXLiteralOperatorName:
2478218893Sdim    Result.AddTypedTextChunk(
2479218893Sdim                      Result.getAllocator().CopyString(ND->getNameAsString()));
2480218893Sdim    break;
2481218893Sdim
2482218893Sdim  case DeclarationName::CXXUsingDirective:
2483218893Sdim  case DeclarationName::ObjCZeroArgSelector:
2484218893Sdim  case DeclarationName::ObjCOneArgSelector:
2485218893Sdim  case DeclarationName::ObjCMultiArgSelector:
2486218893Sdim    break;
2487218893Sdim
2488218893Sdim  case DeclarationName::CXXConstructorName: {
2489218893Sdim    CXXRecordDecl *Record = 0;
2490218893Sdim    QualType Ty = Name.getCXXNameType();
2491218893Sdim    if (const RecordType *RecordTy = Ty->getAs<RecordType>())
2492218893Sdim      Record = cast<CXXRecordDecl>(RecordTy->getDecl());
2493218893Sdim    else if (const InjectedClassNameType *InjectedTy
2494218893Sdim                                        = Ty->getAs<InjectedClassNameType>())
2495218893Sdim      Record = InjectedTy->getDecl();
2496218893Sdim    else {
2497218893Sdim      Result.AddTypedTextChunk(
2498218893Sdim                      Result.getAllocator().CopyString(ND->getNameAsString()));
2499218893Sdim      break;
2500218893Sdim    }
2501218893Sdim
2502218893Sdim    Result.AddTypedTextChunk(
2503218893Sdim                  Result.getAllocator().CopyString(Record->getNameAsString()));
2504218893Sdim    if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
2505234353Sdim      Result.AddChunk(CodeCompletionString::CK_LeftAngle);
2506226633Sdim      AddTemplateParameterChunks(Context, Policy, Template, Result);
2507234353Sdim      Result.AddChunk(CodeCompletionString::CK_RightAngle);
2508218893Sdim    }
2509218893Sdim    break;
2510218893Sdim  }
2511218893Sdim  }
2512218893Sdim}
2513218893Sdim
2514234353SdimCodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S,
2515234353Sdim                                         CodeCompletionAllocator &Allocator,
2516239462Sdim                                         CodeCompletionTUInfo &CCTUInfo,
2517239462Sdim                                         bool IncludeBriefComments) {
2518239462Sdim  return CreateCodeCompletionString(S.Context, S.PP, Allocator, CCTUInfo,
2519239462Sdim                                    IncludeBriefComments);
2520234353Sdim}
2521234353Sdim
2522198092Srdivacky/// \brief If possible, create a new code completion string for the given
2523198092Srdivacky/// result.
2524198092Srdivacky///
2525198092Srdivacky/// \returns Either a new, heap-allocated code completion string describing
2526198092Srdivacky/// how to use this result, or NULL to indicate that the string or name of the
2527198092Srdivacky/// result is all that is needed.
2528198092SrdivackyCodeCompletionString *
2529234353SdimCodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
2530234353Sdim                                                 Preprocessor &PP,
2531234353Sdim                                           CodeCompletionAllocator &Allocator,
2532239462Sdim                                           CodeCompletionTUInfo &CCTUInfo,
2533239462Sdim                                           bool IncludeBriefComments) {
2534234353Sdim  CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
2535199482Srdivacky
2536234353Sdim  PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
2537218893Sdim  if (Kind == RK_Pattern) {
2538218893Sdim    Pattern->Priority = Priority;
2539218893Sdim    Pattern->Availability = Availability;
2540234353Sdim
2541234353Sdim    if (Declaration) {
2542234353Sdim      Result.addParentContext(Declaration->getDeclContext());
2543234353Sdim      Pattern->ParentName = Result.getParentName();
2544249423Sdim      // Provide code completion comment for self.GetterName where
2545249423Sdim      // GetterName is the getter method for a property with name
2546249423Sdim      // different from the property name (declared via a property
2547249423Sdim      // getter attribute.
2548249423Sdim      const NamedDecl *ND = Declaration;
2549249423Sdim      if (const ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(ND))
2550249423Sdim        if (M->isPropertyAccessor())
2551249423Sdim          if (const ObjCPropertyDecl *PDecl = M->findPropertyDecl())
2552249423Sdim            if (PDecl->getGetterName() == M->getSelector() &&
2553249423Sdim                PDecl->getIdentifier() != M->getIdentifier()) {
2554249423Sdim              if (const RawComment *RC =
2555249423Sdim                    Ctx.getRawCommentForAnyRedecl(M)) {
2556249423Sdim                Result.addBriefComment(RC->getBriefText(Ctx));
2557249423Sdim                Pattern->BriefComment = Result.getBriefComment();
2558249423Sdim              }
2559249423Sdim              else if (const RawComment *RC =
2560249423Sdim                         Ctx.getRawCommentForAnyRedecl(PDecl)) {
2561249423Sdim                Result.addBriefComment(RC->getBriefText(Ctx));
2562249423Sdim                Pattern->BriefComment = Result.getBriefComment();
2563249423Sdim              }
2564249423Sdim            }
2565234353Sdim    }
2566234353Sdim
2567218893Sdim    return Pattern;
2568218893Sdim  }
2569198092Srdivacky
2570199990Srdivacky  if (Kind == RK_Keyword) {
2571218893Sdim    Result.AddTypedTextChunk(Keyword);
2572218893Sdim    return Result.TakeString();
2573199990Srdivacky  }
2574199990Srdivacky
2575198893Srdivacky  if (Kind == RK_Macro) {
2576249423Sdim    const MacroDirective *MD = PP.getMacroDirectiveHistory(Macro);
2577249423Sdim    assert(MD && "Not a macro?");
2578249423Sdim    const MacroInfo *MI = MD->getMacroInfo();
2579199990Srdivacky
2580218893Sdim    Result.AddTypedTextChunk(
2581218893Sdim                            Result.getAllocator().CopyString(Macro->getName()));
2582199990Srdivacky
2583199990Srdivacky    if (!MI->isFunctionLike())
2584218893Sdim      return Result.TakeString();
2585198893Srdivacky
2586198893Srdivacky    // Format a function-like macro with placeholders for the arguments.
2587234353Sdim    Result.AddChunk(CodeCompletionString::CK_LeftParen);
2588226633Sdim    MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2589234353Sdim
2590234353Sdim    // C99 variadic macros add __VA_ARGS__ at the end. Skip it.
2591234353Sdim    if (MI->isC99Varargs()) {
2592234353Sdim      --AEnd;
2593234353Sdim
2594234353Sdim      if (A == AEnd) {
2595234353Sdim        Result.AddPlaceholderChunk("...");
2596234353Sdim      }
2597226633Sdim    }
2598234353Sdim
2599226633Sdim    for (MacroInfo::arg_iterator A = MI->arg_begin(); A != AEnd; ++A) {
2600198893Srdivacky      if (A != MI->arg_begin())
2601234353Sdim        Result.AddChunk(CodeCompletionString::CK_Comma);
2602234353Sdim
2603234353Sdim      if (MI->isVariadic() && (A+1) == AEnd) {
2604234353Sdim        SmallString<32> Arg = (*A)->getName();
2605234353Sdim        if (MI->isC99Varargs())
2606234353Sdim          Arg += ", ...";
2607234353Sdim        else
2608234353Sdim          Arg += "...";
2609218893Sdim        Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
2610234353Sdim        break;
2611198893Srdivacky      }
2612234353Sdim
2613234353Sdim      // Non-variadic macros are simple.
2614234353Sdim      Result.AddPlaceholderChunk(
2615234353Sdim                          Result.getAllocator().CopyString((*A)->getName()));
2616198893Srdivacky    }
2617234353Sdim    Result.AddChunk(CodeCompletionString::CK_RightParen);
2618218893Sdim    return Result.TakeString();
2619198893Srdivacky  }
2620198893Srdivacky
2621208600Srdivacky  assert(Kind == RK_Declaration && "Missed a result kind?");
2622249423Sdim  const NamedDecl *ND = Declaration;
2623234353Sdim  Result.addParentContext(ND->getDeclContext());
2624239462Sdim
2625239462Sdim  if (IncludeBriefComments) {
2626239462Sdim    // Add documentation comment, if it exists.
2627239462Sdim    if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(ND)) {
2628239462Sdim      Result.addBriefComment(RC->getBriefText(Ctx));
2629249423Sdim    }
2630249423Sdim    else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
2631249423Sdim      if (OMD->isPropertyAccessor())
2632249423Sdim        if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl())
2633249423Sdim          if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(PDecl))
2634249423Sdim            Result.addBriefComment(RC->getBriefText(Ctx));
2635239462Sdim  }
2636239462Sdim
2637199482Srdivacky  if (StartsNestedNameSpecifier) {
2638218893Sdim    Result.AddTypedTextChunk(
2639218893Sdim                      Result.getAllocator().CopyString(ND->getNameAsString()));
2640218893Sdim    Result.AddTextChunk("::");
2641218893Sdim    return Result.TakeString();
2642199482Srdivacky  }
2643226633Sdim
2644226633Sdim  for (Decl::attr_iterator i = ND->attr_begin(); i != ND->attr_end(); ++i) {
2645226633Sdim    if (AnnotateAttr *Attr = dyn_cast_or_null<AnnotateAttr>(*i)) {
2646226633Sdim      Result.AddAnnotation(Result.getAllocator().CopyString(Attr->getAnnotation()));
2647226633Sdim    }
2648226633Sdim  }
2649199482Srdivacky
2650234353Sdim  AddResultTypeChunk(Ctx, Policy, ND, Result);
2651201361Srdivacky
2652249423Sdim  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
2653198092Srdivacky    AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2654234353Sdim                                   Ctx, Policy);
2655234353Sdim    AddTypedNameChunk(Ctx, Policy, ND, Result);
2656234353Sdim    Result.AddChunk(CodeCompletionString::CK_LeftParen);
2657234353Sdim    AddFunctionParameterChunks(Ctx, Policy, Function, Result);
2658234353Sdim    Result.AddChunk(CodeCompletionString::CK_RightParen);
2659200583Srdivacky    AddFunctionTypeQualsToCompletionString(Result, Function);
2660218893Sdim    return Result.TakeString();
2661198092Srdivacky  }
2662198092Srdivacky
2663249423Sdim  if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
2664198092Srdivacky    AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2665234353Sdim                                   Ctx, Policy);
2666198092Srdivacky    FunctionDecl *Function = FunTmpl->getTemplatedDecl();
2667234353Sdim    AddTypedNameChunk(Ctx, Policy, Function, Result);
2668218893Sdim
2669198092Srdivacky    // Figure out which template parameters are deduced (or have default
2670198092Srdivacky    // arguments).
2671234353Sdim    llvm::SmallBitVector Deduced;
2672234353Sdim    Sema::MarkDeducedTemplateParameters(Ctx, FunTmpl, Deduced);
2673198092Srdivacky    unsigned LastDeducibleArgument;
2674198092Srdivacky    for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2675198092Srdivacky         --LastDeducibleArgument) {
2676198092Srdivacky      if (!Deduced[LastDeducibleArgument - 1]) {
2677198092Srdivacky        // C++0x: Figure out if the template argument has a default. If so,
2678198092Srdivacky        // the user doesn't need to type this argument.
2679198092Srdivacky        // FIXME: We need to abstract template parameters better!
2680198092Srdivacky        bool HasDefaultArg = false;
2681198092Srdivacky        NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2682218893Sdim                                                    LastDeducibleArgument - 1);
2683198092Srdivacky        if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2684198092Srdivacky          HasDefaultArg = TTP->hasDefaultArgument();
2685198092Srdivacky        else if (NonTypeTemplateParmDecl *NTTP
2686198092Srdivacky                 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2687198092Srdivacky          HasDefaultArg = NTTP->hasDefaultArgument();
2688198092Srdivacky        else {
2689198092Srdivacky          assert(isa<TemplateTemplateParmDecl>(Param));
2690198092Srdivacky          HasDefaultArg
2691199482Srdivacky            = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
2692198092Srdivacky        }
2693198092Srdivacky
2694198092Srdivacky        if (!HasDefaultArg)
2695198092Srdivacky          break;
2696198092Srdivacky      }
2697198092Srdivacky    }
2698198092Srdivacky
2699198092Srdivacky    if (LastDeducibleArgument) {
2700198092Srdivacky      // Some of the function template arguments cannot be deduced from a
2701198092Srdivacky      // function call, so we introduce an explicit template argument list
2702198092Srdivacky      // containing all of the arguments up to the first deducible argument.
2703234353Sdim      Result.AddChunk(CodeCompletionString::CK_LeftAngle);
2704234353Sdim      AddTemplateParameterChunks(Ctx, Policy, FunTmpl, Result,
2705198092Srdivacky                                 LastDeducibleArgument);
2706234353Sdim      Result.AddChunk(CodeCompletionString::CK_RightAngle);
2707198092Srdivacky    }
2708198092Srdivacky
2709198092Srdivacky    // Add the function parameters
2710234353Sdim    Result.AddChunk(CodeCompletionString::CK_LeftParen);
2711234353Sdim    AddFunctionParameterChunks(Ctx, Policy, Function, Result);
2712234353Sdim    Result.AddChunk(CodeCompletionString::CK_RightParen);
2713200583Srdivacky    AddFunctionTypeQualsToCompletionString(Result, Function);
2714218893Sdim    return Result.TakeString();
2715198092Srdivacky  }
2716198092Srdivacky
2717249423Sdim  if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
2718198092Srdivacky    AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2719234353Sdim                                   Ctx, Policy);
2720218893Sdim    Result.AddTypedTextChunk(
2721218893Sdim                Result.getAllocator().CopyString(Template->getNameAsString()));
2722234353Sdim    Result.AddChunk(CodeCompletionString::CK_LeftAngle);
2723234353Sdim    AddTemplateParameterChunks(Ctx, Policy, Template, Result);
2724234353Sdim    Result.AddChunk(CodeCompletionString::CK_RightAngle);
2725218893Sdim    return Result.TakeString();
2726198092Srdivacky  }
2727198092Srdivacky
2728249423Sdim  if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
2729199482Srdivacky    Selector Sel = Method->getSelector();
2730199482Srdivacky    if (Sel.isUnarySelector()) {
2731218893Sdim      Result.AddTypedTextChunk(Result.getAllocator().CopyString(
2732218893Sdim                                  Sel.getNameForSlot(0)));
2733218893Sdim      return Result.TakeString();
2734199482Srdivacky    }
2735199482Srdivacky
2736218893Sdim    std::string SelName = Sel.getNameForSlot(0).str();
2737199512Srdivacky    SelName += ':';
2738199512Srdivacky    if (StartParameter == 0)
2739218893Sdim      Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName));
2740199512Srdivacky    else {
2741218893Sdim      Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName));
2742199512Srdivacky
2743199512Srdivacky      // If there is only one parameter, and we're past it, add an empty
2744199512Srdivacky      // typed-text chunk since there is nothing to type.
2745199512Srdivacky      if (Method->param_size() == 1)
2746218893Sdim        Result.AddTypedTextChunk("");
2747199512Srdivacky    }
2748199482Srdivacky    unsigned Idx = 0;
2749249423Sdim    for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
2750249423Sdim                                           PEnd = Method->param_end();
2751199482Srdivacky         P != PEnd; (void)++P, ++Idx) {
2752199482Srdivacky      if (Idx > 0) {
2753199512Srdivacky        std::string Keyword;
2754199512Srdivacky        if (Idx > StartParameter)
2755218893Sdim          Result.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2756199482Srdivacky        if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2757226633Sdim          Keyword += II->getName();
2758199482Srdivacky        Keyword += ":";
2759210299Sed        if (Idx < StartParameter || AllParametersAreInformative)
2760218893Sdim          Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword));
2761218893Sdim        else
2762218893Sdim          Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword));
2763199482Srdivacky      }
2764199512Srdivacky
2765199512Srdivacky      // If we're before the starting parameter, skip the placeholder.
2766199512Srdivacky      if (Idx < StartParameter)
2767199512Srdivacky        continue;
2768199482Srdivacky
2769199482Srdivacky      std::string Arg;
2770212904Sdim
2771212904Sdim      if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
2772234353Sdim        Arg = FormatFunctionParameter(Ctx, Policy, *P, true);
2773212904Sdim      else {
2774224145Sdim        (*P)->getType().getAsStringInternal(Arg, Policy);
2775226633Sdim        Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier())
2776226633Sdim            + Arg + ")";
2777212904Sdim        if (IdentifierInfo *II = (*P)->getIdentifier())
2778212904Sdim          if (DeclaringEntity || AllParametersAreInformative)
2779226633Sdim            Arg += II->getName();
2780212904Sdim      }
2781212904Sdim
2782212904Sdim      if (Method->isVariadic() && (P + 1) == PEnd)
2783212904Sdim        Arg += ", ...";
2784212904Sdim
2785210299Sed      if (DeclaringEntity)
2786218893Sdim        Result.AddTextChunk(Result.getAllocator().CopyString(Arg));
2787210299Sed      else if (AllParametersAreInformative)
2788218893Sdim        Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg));
2789199512Srdivacky      else
2790218893Sdim        Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
2791199482Srdivacky    }
2792199482Srdivacky
2793201361Srdivacky    if (Method->isVariadic()) {
2794212904Sdim      if (Method->param_size() == 0) {
2795212904Sdim        if (DeclaringEntity)
2796218893Sdim          Result.AddTextChunk(", ...");
2797212904Sdim        else if (AllParametersAreInformative)
2798218893Sdim          Result.AddInformativeChunk(", ...");
2799212904Sdim        else
2800218893Sdim          Result.AddPlaceholderChunk(", ...");
2801212904Sdim      }
2802212904Sdim
2803234353Sdim      MaybeAddSentinel(Ctx, Method, Result);
2804201361Srdivacky    }
2805201361Srdivacky
2806218893Sdim    return Result.TakeString();
2807199482Srdivacky  }
2808199482Srdivacky
2809199990Srdivacky  if (Qualifier)
2810198092Srdivacky    AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2811234353Sdim                                   Ctx, Policy);
2812199990Srdivacky
2813218893Sdim  Result.AddTypedTextChunk(
2814218893Sdim                       Result.getAllocator().CopyString(ND->getNameAsString()));
2815218893Sdim  return Result.TakeString();
2816198092Srdivacky}
2817198092Srdivacky
2818198092SrdivackyCodeCompletionString *
2819198092SrdivackyCodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2820198092Srdivacky                                                          unsigned CurrentArg,
2821218893Sdim                                                               Sema &S,
2822234353Sdim                                     CodeCompletionAllocator &Allocator,
2823234353Sdim                                     CodeCompletionTUInfo &CCTUInfo) const {
2824226633Sdim  PrintingPolicy Policy = getCompletionPrintingPolicy(S);
2825224145Sdim
2826218893Sdim  // FIXME: Set priority, availability appropriately.
2827234353Sdim  CodeCompletionBuilder Result(Allocator,CCTUInfo, 1, CXAvailability_Available);
2828198092Srdivacky  FunctionDecl *FDecl = getFunction();
2829226633Sdim  AddResultTypeChunk(S.Context, Policy, FDecl, Result);
2830198092Srdivacky  const FunctionProtoType *Proto
2831198092Srdivacky    = dyn_cast<FunctionProtoType>(getFunctionType());
2832198092Srdivacky  if (!FDecl && !Proto) {
2833198092Srdivacky    // Function without a prototype. Just give the return type and a
2834198092Srdivacky    // highlighted ellipsis.
2835198092Srdivacky    const FunctionType *FT = getFunctionType();
2836218893Sdim    Result.AddTextChunk(GetCompletionTypeString(FT->getResultType(),
2837226633Sdim                                                S.Context, Policy,
2838218893Sdim                                                Result.getAllocator()));
2839234353Sdim    Result.AddChunk(CodeCompletionString::CK_LeftParen);
2840234353Sdim    Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
2841234353Sdim    Result.AddChunk(CodeCompletionString::CK_RightParen);
2842218893Sdim    return Result.TakeString();
2843198092Srdivacky  }
2844198092Srdivacky
2845198092Srdivacky  if (FDecl)
2846218893Sdim    Result.AddTextChunk(
2847218893Sdim                    Result.getAllocator().CopyString(FDecl->getNameAsString()));
2848198092Srdivacky  else
2849218893Sdim    Result.AddTextChunk(
2850218893Sdim         Result.getAllocator().CopyString(
2851224145Sdim                                  Proto->getResultType().getAsString(Policy)));
2852198092Srdivacky
2853234353Sdim  Result.AddChunk(CodeCompletionString::CK_LeftParen);
2854198092Srdivacky  unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
2855198092Srdivacky  for (unsigned I = 0; I != NumParams; ++I) {
2856198092Srdivacky    if (I)
2857234353Sdim      Result.AddChunk(CodeCompletionString::CK_Comma);
2858198092Srdivacky
2859198092Srdivacky    std::string ArgString;
2860198092Srdivacky    QualType ArgType;
2861198092Srdivacky
2862198092Srdivacky    if (FDecl) {
2863198092Srdivacky      ArgString = FDecl->getParamDecl(I)->getNameAsString();
2864198092Srdivacky      ArgType = FDecl->getParamDecl(I)->getOriginalType();
2865198092Srdivacky    } else {
2866198092Srdivacky      ArgType = Proto->getArgType(I);
2867198092Srdivacky    }
2868198092Srdivacky
2869224145Sdim    ArgType.getAsStringInternal(ArgString, Policy);
2870198092Srdivacky
2871198092Srdivacky    if (I == CurrentArg)
2872234353Sdim      Result.AddChunk(CodeCompletionString::CK_CurrentParameter,
2873234353Sdim                      Result.getAllocator().CopyString(ArgString));
2874198092Srdivacky    else
2875218893Sdim      Result.AddTextChunk(Result.getAllocator().CopyString(ArgString));
2876198092Srdivacky  }
2877198092Srdivacky
2878198092Srdivacky  if (Proto && Proto->isVariadic()) {
2879234353Sdim    Result.AddChunk(CodeCompletionString::CK_Comma);
2880198092Srdivacky    if (CurrentArg < NumParams)
2881218893Sdim      Result.AddTextChunk("...");
2882198092Srdivacky    else
2883234353Sdim      Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
2884198092Srdivacky  }
2885234353Sdim  Result.AddChunk(CodeCompletionString::CK_RightParen);
2886198092Srdivacky
2887218893Sdim  return Result.TakeString();
2888198092Srdivacky}
2889198092Srdivacky
2890226633Sdimunsigned clang::getMacroUsagePriority(StringRef MacroName,
2891218893Sdim                                      const LangOptions &LangOpts,
2892212904Sdim                                      bool PreferredTypeIsPointer) {
2893212904Sdim  unsigned Priority = CCP_Macro;
2894212904Sdim
2895218893Sdim  // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
2896218893Sdim  if (MacroName.equals("nil") || MacroName.equals("NULL") ||
2897218893Sdim      MacroName.equals("Nil")) {
2898212904Sdim    Priority = CCP_Constant;
2899212904Sdim    if (PreferredTypeIsPointer)
2900212904Sdim      Priority = Priority / CCF_SimilarTypeMatch;
2901218893Sdim  }
2902218893Sdim  // Treat "YES", "NO", "true", and "false" as constants.
2903218893Sdim  else if (MacroName.equals("YES") || MacroName.equals("NO") ||
2904218893Sdim           MacroName.equals("true") || MacroName.equals("false"))
2905218893Sdim    Priority = CCP_Constant;
2906218893Sdim  // Treat "bool" as a type.
2907218893Sdim  else if (MacroName.equals("bool"))
2908218893Sdim    Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
2909218893Sdim
2910212904Sdim
2911212904Sdim  return Priority;
2912212904Sdim}
2913200583Srdivacky
2914249423SdimCXCursorKind clang::getCursorKindForDecl(const Decl *D) {
2915212904Sdim  if (!D)
2916212904Sdim    return CXCursor_UnexposedDecl;
2917212904Sdim
2918212904Sdim  switch (D->getKind()) {
2919212904Sdim    case Decl::Enum:               return CXCursor_EnumDecl;
2920212904Sdim    case Decl::EnumConstant:       return CXCursor_EnumConstantDecl;
2921212904Sdim    case Decl::Field:              return CXCursor_FieldDecl;
2922212904Sdim    case Decl::Function:
2923212904Sdim      return CXCursor_FunctionDecl;
2924212904Sdim    case Decl::ObjCCategory:       return CXCursor_ObjCCategoryDecl;
2925212904Sdim    case Decl::ObjCCategoryImpl:   return CXCursor_ObjCCategoryImplDecl;
2926212904Sdim    case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
2927234353Sdim
2928212904Sdim    case Decl::ObjCInterface:      return CXCursor_ObjCInterfaceDecl;
2929212904Sdim    case Decl::ObjCIvar:           return CXCursor_ObjCIvarDecl;
2930212904Sdim    case Decl::ObjCMethod:
2931212904Sdim      return cast<ObjCMethodDecl>(D)->isInstanceMethod()
2932212904Sdim      ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
2933212904Sdim    case Decl::CXXMethod:          return CXCursor_CXXMethod;
2934212904Sdim    case Decl::CXXConstructor:     return CXCursor_Constructor;
2935212904Sdim    case Decl::CXXDestructor:      return CXCursor_Destructor;
2936212904Sdim    case Decl::CXXConversion:      return CXCursor_ConversionFunction;
2937212904Sdim    case Decl::ObjCProperty:       return CXCursor_ObjCPropertyDecl;
2938212904Sdim    case Decl::ObjCProtocol:       return CXCursor_ObjCProtocolDecl;
2939212904Sdim    case Decl::ParmVar:            return CXCursor_ParmDecl;
2940212904Sdim    case Decl::Typedef:            return CXCursor_TypedefDecl;
2941221345Sdim    case Decl::TypeAlias:          return CXCursor_TypeAliasDecl;
2942212904Sdim    case Decl::Var:                return CXCursor_VarDecl;
2943212904Sdim    case Decl::Namespace:          return CXCursor_Namespace;
2944212904Sdim    case Decl::NamespaceAlias:     return CXCursor_NamespaceAlias;
2945212904Sdim    case Decl::TemplateTypeParm:   return CXCursor_TemplateTypeParameter;
2946212904Sdim    case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
2947212904Sdim    case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
2948212904Sdim    case Decl::FunctionTemplate:   return CXCursor_FunctionTemplate;
2949212904Sdim    case Decl::ClassTemplate:      return CXCursor_ClassTemplate;
2950226633Sdim    case Decl::AccessSpec:         return CXCursor_CXXAccessSpecifier;
2951212904Sdim    case Decl::ClassTemplatePartialSpecialization:
2952212904Sdim      return CXCursor_ClassTemplatePartialSpecialization;
2953212904Sdim    case Decl::UsingDirective:     return CXCursor_UsingDirective;
2954239462Sdim    case Decl::TranslationUnit:    return CXCursor_TranslationUnit;
2955198092Srdivacky
2956212904Sdim    case Decl::Using:
2957212904Sdim    case Decl::UnresolvedUsingValue:
2958212904Sdim    case Decl::UnresolvedUsingTypename:
2959212904Sdim      return CXCursor_UsingDeclaration;
2960212904Sdim
2961223017Sdim    case Decl::ObjCPropertyImpl:
2962223017Sdim      switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) {
2963223017Sdim      case ObjCPropertyImplDecl::Dynamic:
2964223017Sdim        return CXCursor_ObjCDynamicDecl;
2965223017Sdim
2966223017Sdim      case ObjCPropertyImplDecl::Synthesize:
2967223017Sdim        return CXCursor_ObjCSynthesizeDecl;
2968223017Sdim      }
2969243830Sdim
2970243830Sdim      case Decl::Import:
2971243830Sdim        return CXCursor_ModuleImportDecl;
2972223017Sdim
2973212904Sdim    default:
2974249423Sdim      if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
2975212904Sdim        switch (TD->getTagKind()) {
2976243830Sdim          case TTK_Interface:  // fall through
2977212904Sdim          case TTK_Struct: return CXCursor_StructDecl;
2978212904Sdim          case TTK_Class:  return CXCursor_ClassDecl;
2979212904Sdim          case TTK_Union:  return CXCursor_UnionDecl;
2980212904Sdim          case TTK_Enum:   return CXCursor_EnumDecl;
2981212904Sdim        }
2982199512Srdivacky      }
2983212904Sdim  }
2984212904Sdim
2985212904Sdim  return CXCursor_UnexposedDecl;
2986198092Srdivacky}
2987198092Srdivacky
2988210299Sedstatic void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
2989243830Sdim                            bool IncludeUndefined,
2990210299Sed                            bool TargetTypeIsPointer = false) {
2991212904Sdim  typedef CodeCompletionResult Result;
2992210299Sed
2993198893Srdivacky  Results.EnterNewScope();
2994218893Sdim
2995199482Srdivacky  for (Preprocessor::macro_iterator M = PP.macro_begin(),
2996199482Srdivacky                                 MEnd = PP.macro_end();
2997210299Sed       M != MEnd; ++M) {
2998243830Sdim    if (IncludeUndefined || M->first->hasMacroDefinition())
2999243830Sdim      Results.AddResult(Result(M->first,
3000212904Sdim                             getMacroUsagePriority(M->first->getName(),
3001234353Sdim                                                   PP.getLangOpts(),
3002212904Sdim                                                   TargetTypeIsPointer)));
3003210299Sed  }
3004218893Sdim
3005198893Srdivacky  Results.ExitScope();
3006218893Sdim
3007198893Srdivacky}
3008198893Srdivacky
3009212904Sdimstatic void AddPrettyFunctionResults(const LangOptions &LangOpts,
3010212904Sdim                                     ResultBuilder &Results) {
3011212904Sdim  typedef CodeCompletionResult Result;
3012212904Sdim
3013212904Sdim  Results.EnterNewScope();
3014218893Sdim
3015212904Sdim  Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
3016212904Sdim  Results.AddResult(Result("__FUNCTION__", CCP_Constant));
3017249423Sdim  if (LangOpts.C99 || LangOpts.CPlusPlus11)
3018212904Sdim    Results.AddResult(Result("__func__", CCP_Constant));
3019212904Sdim  Results.ExitScope();
3020212904Sdim}
3021212904Sdim
3022199482Srdivackystatic void HandleCodeCompleteResults(Sema *S,
3023199482Srdivacky                                      CodeCompleteConsumer *CodeCompleter,
3024212904Sdim                                      CodeCompletionContext Context,
3025212904Sdim                                      CodeCompletionResult *Results,
3026212904Sdim                                      unsigned NumResults) {
3027198092Srdivacky  if (CodeCompleter)
3028212904Sdim    CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
3029198092Srdivacky}
3030198092Srdivacky
3031212904Sdimstatic enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
3032212904Sdim                                            Sema::ParserCompletionContext PCC) {
3033212904Sdim  switch (PCC) {
3034212904Sdim  case Sema::PCC_Namespace:
3035212904Sdim    return CodeCompletionContext::CCC_TopLevel;
3036212904Sdim
3037212904Sdim  case Sema::PCC_Class:
3038212904Sdim    return CodeCompletionContext::CCC_ClassStructUnion;
3039212904Sdim
3040212904Sdim  case Sema::PCC_ObjCInterface:
3041212904Sdim    return CodeCompletionContext::CCC_ObjCInterface;
3042212904Sdim
3043212904Sdim  case Sema::PCC_ObjCImplementation:
3044212904Sdim    return CodeCompletionContext::CCC_ObjCImplementation;
3045212904Sdim
3046212904Sdim  case Sema::PCC_ObjCInstanceVariableList:
3047212904Sdim    return CodeCompletionContext::CCC_ObjCIvarList;
3048212904Sdim
3049212904Sdim  case Sema::PCC_Template:
3050212904Sdim  case Sema::PCC_MemberTemplate:
3051218893Sdim    if (S.CurContext->isFileContext())
3052218893Sdim      return CodeCompletionContext::CCC_TopLevel;
3053234353Sdim    if (S.CurContext->isRecord())
3054218893Sdim      return CodeCompletionContext::CCC_ClassStructUnion;
3055234353Sdim    return CodeCompletionContext::CCC_Other;
3056218893Sdim
3057212904Sdim  case Sema::PCC_RecoveryInFunction:
3058218893Sdim    return CodeCompletionContext::CCC_Recovery;
3059218893Sdim
3060218893Sdim  case Sema::PCC_ForInit:
3061234353Sdim    if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 ||
3062234353Sdim        S.getLangOpts().ObjC1)
3063218893Sdim      return CodeCompletionContext::CCC_ParenthesizedExpression;
3064218893Sdim    else
3065218893Sdim      return CodeCompletionContext::CCC_Expression;
3066218893Sdim
3067212904Sdim  case Sema::PCC_Expression:
3068212904Sdim  case Sema::PCC_Condition:
3069212904Sdim    return CodeCompletionContext::CCC_Expression;
3070212904Sdim
3071212904Sdim  case Sema::PCC_Statement:
3072212904Sdim    return CodeCompletionContext::CCC_Statement;
3073212904Sdim
3074212904Sdim  case Sema::PCC_Type:
3075212904Sdim    return CodeCompletionContext::CCC_Type;
3076218893Sdim
3077218893Sdim  case Sema::PCC_ParenthesizedExpression:
3078218893Sdim    return CodeCompletionContext::CCC_ParenthesizedExpression;
3079218893Sdim
3080218893Sdim  case Sema::PCC_LocalDeclarationSpecifiers:
3081218893Sdim    return CodeCompletionContext::CCC_Type;
3082212904Sdim  }
3083234353Sdim
3084234353Sdim  llvm_unreachable("Invalid ParserCompletionContext!");
3085212904Sdim}
3086212904Sdim
3087212904Sdim/// \brief If we're in a C++ virtual member function, add completion results
3088212904Sdim/// that invoke the functions we override, since it's common to invoke the
3089212904Sdim/// overridden function as well as adding new functionality.
3090212904Sdim///
3091212904Sdim/// \param S The semantic analysis object for which we are generating results.
3092212904Sdim///
3093212904Sdim/// \param InContext This context in which the nested-name-specifier preceding
3094212904Sdim/// the code-completion point
3095212904Sdimstatic void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
3096212904Sdim                                  ResultBuilder &Results) {
3097212904Sdim  // Look through blocks.
3098212904Sdim  DeclContext *CurContext = S.CurContext;
3099212904Sdim  while (isa<BlockDecl>(CurContext))
3100212904Sdim    CurContext = CurContext->getParent();
3101212904Sdim
3102212904Sdim
3103212904Sdim  CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
3104212904Sdim  if (!Method || !Method->isVirtual())
3105212904Sdim    return;
3106212904Sdim
3107212904Sdim  // We need to have names for all of the parameters, if we're going to
3108212904Sdim  // generate a forwarding call.
3109212904Sdim  for (CXXMethodDecl::param_iterator P = Method->param_begin(),
3110212904Sdim                                  PEnd = Method->param_end();
3111212904Sdim       P != PEnd;
3112212904Sdim       ++P) {
3113212904Sdim    if (!(*P)->getDeclName())
3114212904Sdim      return;
3115212904Sdim  }
3116212904Sdim
3117226633Sdim  PrintingPolicy Policy = getCompletionPrintingPolicy(S);
3118212904Sdim  for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
3119212904Sdim                                   MEnd = Method->end_overridden_methods();
3120212904Sdim       M != MEnd; ++M) {
3121234353Sdim    CodeCompletionBuilder Builder(Results.getAllocator(),
3122234353Sdim                                  Results.getCodeCompletionTUInfo());
3123249423Sdim    const CXXMethodDecl *Overridden = *M;
3124212904Sdim    if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
3125212904Sdim      continue;
3126212904Sdim
3127212904Sdim    // If we need a nested-name-specifier, add one now.
3128212904Sdim    if (!InContext) {
3129212904Sdim      NestedNameSpecifier *NNS
3130212904Sdim        = getRequiredQualification(S.Context, CurContext,
3131212904Sdim                                   Overridden->getDeclContext());
3132212904Sdim      if (NNS) {
3133212904Sdim        std::string Str;
3134212904Sdim        llvm::raw_string_ostream OS(Str);
3135226633Sdim        NNS->print(OS, Policy);
3136218893Sdim        Builder.AddTextChunk(Results.getAllocator().CopyString(OS.str()));
3137212904Sdim      }
3138212904Sdim    } else if (!InContext->Equals(Overridden->getDeclContext()))
3139212904Sdim      continue;
3140212904Sdim
3141218893Sdim    Builder.AddTypedTextChunk(Results.getAllocator().CopyString(
3142218893Sdim                                         Overridden->getNameAsString()));
3143218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
3144212904Sdim    bool FirstParam = true;
3145212904Sdim    for (CXXMethodDecl::param_iterator P = Method->param_begin(),
3146212904Sdim                                    PEnd = Method->param_end();
3147212904Sdim         P != PEnd; ++P) {
3148212904Sdim      if (FirstParam)
3149212904Sdim        FirstParam = false;
3150212904Sdim      else
3151218893Sdim        Builder.AddChunk(CodeCompletionString::CK_Comma);
3152212904Sdim
3153218893Sdim      Builder.AddPlaceholderChunk(Results.getAllocator().CopyString(
3154218893Sdim                                        (*P)->getIdentifier()->getName()));
3155212904Sdim    }
3156218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
3157218893Sdim    Results.AddResult(CodeCompletionResult(Builder.TakeString(),
3158212904Sdim                                           CCP_SuperCompletion,
3159234353Sdim                                           CXCursor_CXXMethod,
3160234353Sdim                                           CXAvailability_Available,
3161234353Sdim                                           Overridden));
3162212904Sdim    Results.Ignore(Overridden);
3163212904Sdim  }
3164212904Sdim}
3165212904Sdim
3166234353Sdimvoid Sema::CodeCompleteModuleImport(SourceLocation ImportLoc,
3167234353Sdim                                    ModuleIdPath Path) {
3168234353Sdim  typedef CodeCompletionResult Result;
3169234353Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3170234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
3171234353Sdim                        CodeCompletionContext::CCC_Other);
3172234353Sdim  Results.EnterNewScope();
3173234353Sdim
3174234353Sdim  CodeCompletionAllocator &Allocator = Results.getAllocator();
3175234353Sdim  CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
3176234353Sdim  typedef CodeCompletionResult Result;
3177234353Sdim  if (Path.empty()) {
3178234353Sdim    // Enumerate all top-level modules.
3179249423Sdim    SmallVector<Module *, 8> Modules;
3180234353Sdim    PP.getHeaderSearchInfo().collectAllModules(Modules);
3181234353Sdim    for (unsigned I = 0, N = Modules.size(); I != N; ++I) {
3182234353Sdim      Builder.AddTypedTextChunk(
3183234353Sdim        Builder.getAllocator().CopyString(Modules[I]->Name));
3184234353Sdim      Results.AddResult(Result(Builder.TakeString(),
3185234353Sdim                               CCP_Declaration,
3186234353Sdim                               CXCursor_NotImplemented,
3187234353Sdim                               Modules[I]->isAvailable()
3188234353Sdim                                 ? CXAvailability_Available
3189234353Sdim                                  : CXAvailability_NotAvailable));
3190234353Sdim    }
3191234353Sdim  } else {
3192234353Sdim    // Load the named module.
3193234353Sdim    Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path,
3194234353Sdim                                                  Module::AllVisible,
3195234353Sdim                                                /*IsInclusionDirective=*/false);
3196234353Sdim    // Enumerate submodules.
3197234353Sdim    if (Mod) {
3198234353Sdim      for (Module::submodule_iterator Sub = Mod->submodule_begin(),
3199234353Sdim                                   SubEnd = Mod->submodule_end();
3200234353Sdim           Sub != SubEnd; ++Sub) {
3201234353Sdim
3202234353Sdim        Builder.AddTypedTextChunk(
3203234353Sdim          Builder.getAllocator().CopyString((*Sub)->Name));
3204234353Sdim        Results.AddResult(Result(Builder.TakeString(),
3205234353Sdim                                 CCP_Declaration,
3206234353Sdim                                 CXCursor_NotImplemented,
3207234353Sdim                                 (*Sub)->isAvailable()
3208234353Sdim                                   ? CXAvailability_Available
3209234353Sdim                                   : CXAvailability_NotAvailable));
3210234353Sdim      }
3211234353Sdim    }
3212234353Sdim  }
3213234353Sdim  Results.ExitScope();
3214234353Sdim  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3215234353Sdim                            Results.data(),Results.size());
3216234353Sdim}
3217234353Sdim
3218202379Srdivackyvoid Sema::CodeCompleteOrdinaryName(Scope *S,
3219212904Sdim                                    ParserCompletionContext CompletionContext) {
3220218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3221234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
3222218893Sdim                        mapCodeCompletionContext(*this, CompletionContext));
3223212904Sdim  Results.EnterNewScope();
3224218893Sdim
3225202379Srdivacky  // Determine how to filter results, e.g., so that the names of
3226202379Srdivacky  // values (functions, enumerators, function templates, etc.) are
3227202379Srdivacky  // only allowed where we can have an expression.
3228202379Srdivacky  switch (CompletionContext) {
3229212904Sdim  case PCC_Namespace:
3230212904Sdim  case PCC_Class:
3231212904Sdim  case PCC_ObjCInterface:
3232212904Sdim  case PCC_ObjCImplementation:
3233212904Sdim  case PCC_ObjCInstanceVariableList:
3234212904Sdim  case PCC_Template:
3235212904Sdim  case PCC_MemberTemplate:
3236212904Sdim  case PCC_Type:
3237218893Sdim  case PCC_LocalDeclarationSpecifiers:
3238202379Srdivacky    Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3239202379Srdivacky    break;
3240202379Srdivacky
3241212904Sdim  case PCC_Statement:
3242218893Sdim  case PCC_ParenthesizedExpression:
3243212904Sdim  case PCC_Expression:
3244212904Sdim  case PCC_ForInit:
3245212904Sdim  case PCC_Condition:
3246234353Sdim    if (WantTypesInContext(CompletionContext, getLangOpts()))
3247210299Sed      Results.setFilter(&ResultBuilder::IsOrdinaryName);
3248210299Sed    else
3249210299Sed      Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
3250212904Sdim
3251234353Sdim    if (getLangOpts().CPlusPlus)
3252212904Sdim      MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
3253202379Srdivacky    break;
3254208600Srdivacky
3255212904Sdim  case PCC_RecoveryInFunction:
3256208600Srdivacky    // Unfiltered
3257208600Srdivacky    break;
3258200583Srdivacky  }
3259200583Srdivacky
3260212904Sdim  // If we are in a C++ non-static member function, check the qualifiers on
3261212904Sdim  // the member function to filter/prioritize the results list.
3262212904Sdim  if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
3263212904Sdim    if (CurMethod->isInstance())
3264212904Sdim      Results.setObjectTypeQualifiers(
3265212904Sdim                      Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
3266212904Sdim
3267202379Srdivacky  CodeCompletionDeclConsumer Consumer(Results, CurContext);
3268212904Sdim  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3269212904Sdim                     CodeCompleter->includeGlobals());
3270202379Srdivacky
3271202379Srdivacky  AddOrdinaryNameResults(CompletionContext, S, *this, Results);
3272200583Srdivacky  Results.ExitScope();
3273200583Srdivacky
3274212904Sdim  switch (CompletionContext) {
3275218893Sdim  case PCC_ParenthesizedExpression:
3276212904Sdim  case PCC_Expression:
3277212904Sdim  case PCC_Statement:
3278212904Sdim  case PCC_RecoveryInFunction:
3279212904Sdim    if (S->getFnParent())
3280234353Sdim      AddPrettyFunctionResults(PP.getLangOpts(), Results);
3281212904Sdim    break;
3282212904Sdim
3283212904Sdim  case PCC_Namespace:
3284212904Sdim  case PCC_Class:
3285212904Sdim  case PCC_ObjCInterface:
3286212904Sdim  case PCC_ObjCImplementation:
3287212904Sdim  case PCC_ObjCInstanceVariableList:
3288212904Sdim  case PCC_Template:
3289212904Sdim  case PCC_MemberTemplate:
3290212904Sdim  case PCC_ForInit:
3291212904Sdim  case PCC_Condition:
3292212904Sdim  case PCC_Type:
3293218893Sdim  case PCC_LocalDeclarationSpecifiers:
3294212904Sdim    break;
3295212904Sdim  }
3296212904Sdim
3297199482Srdivacky  if (CodeCompleter->includeMacros())
3298243830Sdim    AddMacroResults(PP, Results, false);
3299212904Sdim
3300218893Sdim  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3301212904Sdim                            Results.data(),Results.size());
3302198092Srdivacky}
3303198092Srdivacky
3304218893Sdimstatic void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
3305218893Sdim                                       ParsedType Receiver,
3306218893Sdim                                       IdentifierInfo **SelIdents,
3307218893Sdim                                       unsigned NumSelIdents,
3308218893Sdim                                       bool AtArgumentExpression,
3309218893Sdim                                       bool IsSuper,
3310218893Sdim                                       ResultBuilder &Results);
3311218893Sdim
3312218893Sdimvoid Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
3313218893Sdim                                bool AllowNonIdentifiers,
3314218893Sdim                                bool AllowNestedNameSpecifiers) {
3315212904Sdim  typedef CodeCompletionResult Result;
3316218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3317234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
3318218893Sdim                        AllowNestedNameSpecifiers
3319218893Sdim                          ? CodeCompletionContext::CCC_PotentiallyQualifiedName
3320218893Sdim                          : CodeCompletionContext::CCC_Name);
3321212904Sdim  Results.EnterNewScope();
3322212904Sdim
3323212904Sdim  // Type qualifiers can come after names.
3324212904Sdim  Results.AddResult(Result("const"));
3325212904Sdim  Results.AddResult(Result("volatile"));
3326234353Sdim  if (getLangOpts().C99)
3327212904Sdim    Results.AddResult(Result("restrict"));
3328212904Sdim
3329234353Sdim  if (getLangOpts().CPlusPlus) {
3330212904Sdim    if (AllowNonIdentifiers) {
3331212904Sdim      Results.AddResult(Result("operator"));
3332212904Sdim    }
3333212904Sdim
3334212904Sdim    // Add nested-name-specifiers.
3335212904Sdim    if (AllowNestedNameSpecifiers) {
3336212904Sdim      Results.allowNestedNameSpecifiers();
3337218893Sdim      Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
3338212904Sdim      CodeCompletionDeclConsumer Consumer(Results, CurContext);
3339212904Sdim      LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
3340212904Sdim                         CodeCompleter->includeGlobals());
3341218893Sdim      Results.setFilter(0);
3342212904Sdim    }
3343212904Sdim  }
3344212904Sdim  Results.ExitScope();
3345212904Sdim
3346218893Sdim  // If we're in a context where we might have an expression (rather than a
3347218893Sdim  // declaration), and what we've seen so far is an Objective-C type that could
3348218893Sdim  // be a receiver of a class message, this may be a class message send with
3349218893Sdim  // the initial opening bracket '[' missing. Add appropriate completions.
3350218893Sdim  if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
3351251662Sdim      DS.getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier &&
3352218893Sdim      DS.getTypeSpecType() == DeclSpec::TST_typename &&
3353218893Sdim      DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
3354218893Sdim      DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
3355251662Sdim      !DS.isTypeAltiVecVector() &&
3356251662Sdim      S &&
3357218893Sdim      (S->getFlags() & Scope::DeclScope) != 0 &&
3358218893Sdim      (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
3359218893Sdim                        Scope::FunctionPrototypeScope |
3360218893Sdim                        Scope::AtCatchScope)) == 0) {
3361218893Sdim    ParsedType T = DS.getRepAsType();
3362218893Sdim    if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
3363218893Sdim      AddClassMessageCompletions(*this, S, T, 0, 0, false, false, Results);
3364218893Sdim  }
3365218893Sdim
3366212904Sdim  // Note that we intentionally suppress macro results here, since we do not
3367212904Sdim  // encourage using macros to produce the names of entities.
3368212904Sdim
3369218893Sdim  HandleCodeCompleteResults(this, CodeCompleter,
3370218893Sdim                            Results.getCompletionContext(),
3371212904Sdim                            Results.data(), Results.size());
3372212904Sdim}
3373212904Sdim
3374212904Sdimstruct Sema::CodeCompleteExpressionData {
3375212904Sdim  CodeCompleteExpressionData(QualType PreferredType = QualType())
3376212904Sdim    : PreferredType(PreferredType), IntegralConstantExpression(false),
3377212904Sdim      ObjCCollection(false) { }
3378212904Sdim
3379212904Sdim  QualType PreferredType;
3380212904Sdim  bool IntegralConstantExpression;
3381212904Sdim  bool ObjCCollection;
3382226633Sdim  SmallVector<Decl *, 4> IgnoreDecls;
3383212904Sdim};
3384212904Sdim
3385210299Sed/// \brief Perform code-completion in an expression context when we know what
3386210299Sed/// type we're looking for.
3387212904Sdimvoid Sema::CodeCompleteExpression(Scope *S,
3388212904Sdim                                  const CodeCompleteExpressionData &Data) {
3389218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3390234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
3391218893Sdim                        CodeCompletionContext::CCC_Expression);
3392212904Sdim  if (Data.ObjCCollection)
3393212904Sdim    Results.setFilter(&ResultBuilder::IsObjCCollection);
3394212904Sdim  else if (Data.IntegralConstantExpression)
3395212904Sdim    Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
3396234353Sdim  else if (WantTypesInContext(PCC_Expression, getLangOpts()))
3397210299Sed    Results.setFilter(&ResultBuilder::IsOrdinaryName);
3398210299Sed  else
3399210299Sed    Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
3400212904Sdim
3401212904Sdim  if (!Data.PreferredType.isNull())
3402212904Sdim    Results.setPreferredType(Data.PreferredType.getNonReferenceType());
3403210299Sed
3404212904Sdim  // Ignore any declarations that we were told that we don't care about.
3405212904Sdim  for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
3406212904Sdim    Results.Ignore(Data.IgnoreDecls[I]);
3407212904Sdim
3408210299Sed  CodeCompletionDeclConsumer Consumer(Results, CurContext);
3409212904Sdim  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3410212904Sdim                     CodeCompleter->includeGlobals());
3411210299Sed
3412210299Sed  Results.EnterNewScope();
3413212904Sdim  AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
3414210299Sed  Results.ExitScope();
3415210299Sed
3416210299Sed  bool PreferredTypeIsPointer = false;
3417212904Sdim  if (!Data.PreferredType.isNull())
3418212904Sdim    PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
3419212904Sdim      || Data.PreferredType->isMemberPointerType()
3420212904Sdim      || Data.PreferredType->isBlockPointerType();
3421210299Sed
3422212904Sdim  if (S->getFnParent() &&
3423212904Sdim      !Data.ObjCCollection &&
3424212904Sdim      !Data.IntegralConstantExpression)
3425234353Sdim    AddPrettyFunctionResults(PP.getLangOpts(), Results);
3426212904Sdim
3427210299Sed  if (CodeCompleter->includeMacros())
3428243830Sdim    AddMacroResults(PP, Results, false, PreferredTypeIsPointer);
3429212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
3430212904Sdim                CodeCompletionContext(CodeCompletionContext::CCC_Expression,
3431212904Sdim                                      Data.PreferredType),
3432212904Sdim                            Results.data(),Results.size());
3433210299Sed}
3434210299Sed
3435218893Sdimvoid Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
3436218893Sdim  if (E.isInvalid())
3437218893Sdim    CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
3438234353Sdim  else if (getLangOpts().ObjC1)
3439218893Sdim    CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
3440218893Sdim}
3441210299Sed
3442218893Sdim/// \brief The set of properties that have already been added, referenced by
3443218893Sdim/// property name.
3444218893Sdimtypedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
3445218893Sdim
3446239462Sdim/// \brief Retrieve the container definition, if any?
3447239462Sdimstatic ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) {
3448239462Sdim  if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
3449239462Sdim    if (Interface->hasDefinition())
3450239462Sdim      return Interface->getDefinition();
3451239462Sdim
3452239462Sdim    return Interface;
3453239462Sdim  }
3454239462Sdim
3455239462Sdim  if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3456239462Sdim    if (Protocol->hasDefinition())
3457239462Sdim      return Protocol->getDefinition();
3458239462Sdim
3459239462Sdim    return Protocol;
3460239462Sdim  }
3461239462Sdim  return Container;
3462239462Sdim}
3463239462Sdim
3464239462Sdimstatic void AddObjCProperties(ObjCContainerDecl *Container,
3465199512Srdivacky                              bool AllowCategories,
3466223017Sdim                              bool AllowNullaryMethods,
3467199482Srdivacky                              DeclContext *CurContext,
3468218893Sdim                              AddedPropertiesSet &AddedProperties,
3469199482Srdivacky                              ResultBuilder &Results) {
3470212904Sdim  typedef CodeCompletionResult Result;
3471199482Srdivacky
3472239462Sdim  // Retrieve the definition.
3473239462Sdim  Container = getContainerDef(Container);
3474239462Sdim
3475199482Srdivacky  // Add properties in this container.
3476199482Srdivacky  for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
3477199482Srdivacky                                     PEnd = Container->prop_end();
3478199482Srdivacky       P != PEnd;
3479218893Sdim       ++P) {
3480218893Sdim    if (AddedProperties.insert(P->getIdentifier()))
3481249423Sdim      Results.MaybeAddResult(Result(*P, Results.getBasePriority(*P), 0),
3482249423Sdim                             CurContext);
3483218893Sdim  }
3484199482Srdivacky
3485223017Sdim  // Add nullary methods
3486223017Sdim  if (AllowNullaryMethods) {
3487223017Sdim    ASTContext &Context = Container->getASTContext();
3488226633Sdim    PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
3489223017Sdim    for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3490223017Sdim                                         MEnd = Container->meth_end();
3491223017Sdim         M != MEnd; ++M) {
3492223017Sdim      if (M->getSelector().isUnarySelector())
3493223017Sdim        if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0))
3494223017Sdim          if (AddedProperties.insert(Name)) {
3495234353Sdim            CodeCompletionBuilder Builder(Results.getAllocator(),
3496234353Sdim                                          Results.getCodeCompletionTUInfo());
3497226633Sdim            AddResultTypeChunk(Context, Policy, *M, Builder);
3498223017Sdim            Builder.AddTypedTextChunk(
3499223017Sdim                            Results.getAllocator().CopyString(Name->getName()));
3500223017Sdim
3501234353Sdim            Results.MaybeAddResult(Result(Builder.TakeString(), *M,
3502234353Sdim                                  CCP_MemberDeclaration + CCD_MethodAsProperty),
3503223017Sdim                                          CurContext);
3504223017Sdim          }
3505223017Sdim    }
3506223017Sdim  }
3507223017Sdim
3508223017Sdim
3509199482Srdivacky  // Add properties in referenced protocols.
3510199482Srdivacky  if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3511199482Srdivacky    for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
3512199482Srdivacky                                          PEnd = Protocol->protocol_end();
3513199482Srdivacky         P != PEnd; ++P)
3514223017Sdim      AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
3515223017Sdim                        AddedProperties, Results);
3516199482Srdivacky  } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
3517199512Srdivacky    if (AllowCategories) {
3518199512Srdivacky      // Look through categories.
3519249423Sdim      for (ObjCInterfaceDecl::known_categories_iterator
3520249423Sdim             Cat = IFace->known_categories_begin(),
3521249423Sdim             CatEnd = IFace->known_categories_end();
3522249423Sdim           Cat != CatEnd; ++Cat)
3523249423Sdim        AddObjCProperties(*Cat, AllowCategories, AllowNullaryMethods,
3524223017Sdim                          CurContext, AddedProperties, Results);
3525199512Srdivacky    }
3526199482Srdivacky
3527199482Srdivacky    // Look through protocols.
3528212904Sdim    for (ObjCInterfaceDecl::all_protocol_iterator
3529212904Sdim         I = IFace->all_referenced_protocol_begin(),
3530212904Sdim         E = IFace->all_referenced_protocol_end(); I != E; ++I)
3531223017Sdim      AddObjCProperties(*I, AllowCategories, AllowNullaryMethods, CurContext,
3532223017Sdim                        AddedProperties, Results);
3533199482Srdivacky
3534199482Srdivacky    // Look in the superclass.
3535199482Srdivacky    if (IFace->getSuperClass())
3536223017Sdim      AddObjCProperties(IFace->getSuperClass(), AllowCategories,
3537223017Sdim                        AllowNullaryMethods, CurContext,
3538218893Sdim                        AddedProperties, Results);
3539199482Srdivacky  } else if (const ObjCCategoryDecl *Category
3540199482Srdivacky                                    = dyn_cast<ObjCCategoryDecl>(Container)) {
3541199482Srdivacky    // Look through protocols.
3542212904Sdim    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
3543212904Sdim                                          PEnd = Category->protocol_end();
3544199482Srdivacky         P != PEnd; ++P)
3545223017Sdim      AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
3546223017Sdim                        AddedProperties, Results);
3547199482Srdivacky  }
3548199482Srdivacky}
3549199482Srdivacky
3550234353Sdimvoid Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
3551198092Srdivacky                                           SourceLocation OpLoc,
3552198092Srdivacky                                           bool IsArrow) {
3553234353Sdim  if (!Base || !CodeCompleter)
3554198092Srdivacky    return;
3555198092Srdivacky
3556234353Sdim  ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
3557234353Sdim  if (ConvertedBase.isInvalid())
3558234353Sdim    return;
3559234353Sdim  Base = ConvertedBase.get();
3560234353Sdim
3561212904Sdim  typedef CodeCompletionResult Result;
3562198092Srdivacky
3563198092Srdivacky  QualType BaseType = Base->getType();
3564198092Srdivacky
3565198092Srdivacky  if (IsArrow) {
3566198092Srdivacky    if (const PointerType *Ptr = BaseType->getAs<PointerType>())
3567198092Srdivacky      BaseType = Ptr->getPointeeType();
3568198092Srdivacky    else if (BaseType->isObjCObjectPointerType())
3569212904Sdim      /*Do nothing*/ ;
3570198092Srdivacky    else
3571198092Srdivacky      return;
3572198092Srdivacky  }
3573198092Srdivacky
3574224145Sdim  enum CodeCompletionContext::Kind contextKind;
3575224145Sdim
3576224145Sdim  if (IsArrow) {
3577224145Sdim    contextKind = CodeCompletionContext::CCC_ArrowMemberAccess;
3578224145Sdim  }
3579224145Sdim  else {
3580224145Sdim    if (BaseType->isObjCObjectPointerType() ||
3581224145Sdim        BaseType->isObjCObjectOrInterfaceType()) {
3582224145Sdim      contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess;
3583224145Sdim    }
3584224145Sdim    else {
3585224145Sdim      contextKind = CodeCompletionContext::CCC_DotMemberAccess;
3586224145Sdim    }
3587224145Sdim  }
3588224145Sdim
3589218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3590234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
3591224145Sdim                  CodeCompletionContext(contextKind,
3592218893Sdim                                        BaseType),
3593218893Sdim                        &ResultBuilder::IsMember);
3594199482Srdivacky  Results.EnterNewScope();
3595198092Srdivacky  if (const RecordType *Record = BaseType->getAs<RecordType>()) {
3596212904Sdim    // Indicate that we are performing a member access, and the cv-qualifiers
3597212904Sdim    // for the base object type.
3598212904Sdim    Results.setObjectTypeQualifiers(BaseType.getQualifiers());
3599212904Sdim
3600199482Srdivacky    // Access to a C/C++ class, struct, or union.
3601202379Srdivacky    Results.allowNestedNameSpecifiers();
3602202379Srdivacky    CodeCompletionDeclConsumer Consumer(Results, CurContext);
3603212904Sdim    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
3604212904Sdim                       CodeCompleter->includeGlobals());
3605199482Srdivacky
3606234353Sdim    if (getLangOpts().CPlusPlus) {
3607198092Srdivacky      if (!Results.empty()) {
3608198092Srdivacky        // The "template" keyword can follow "->" or "." in the grammar.
3609198092Srdivacky        // However, we only want to suggest the template keyword if something
3610198092Srdivacky        // is dependent.
3611198092Srdivacky        bool IsDependent = BaseType->isDependentType();
3612198092Srdivacky        if (!IsDependent) {
3613198092Srdivacky          for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
3614198092Srdivacky            if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
3615198092Srdivacky              IsDependent = Ctx->isDependentContext();
3616198092Srdivacky              break;
3617198092Srdivacky            }
3618198092Srdivacky        }
3619199482Srdivacky
3620198092Srdivacky        if (IsDependent)
3621202379Srdivacky          Results.AddResult(Result("template"));
3622198092Srdivacky      }
3623198092Srdivacky    }
3624199482Srdivacky  } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
3625199482Srdivacky    // Objective-C property reference.
3626218893Sdim    AddedPropertiesSet AddedProperties;
3627198092Srdivacky
3628199482Srdivacky    // Add property results based on our interface.
3629199482Srdivacky    const ObjCObjectPointerType *ObjCPtr
3630199482Srdivacky      = BaseType->getAsObjCInterfacePointerType();
3631199482Srdivacky    assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
3632223017Sdim    AddObjCProperties(ObjCPtr->getInterfaceDecl(), true,
3633223017Sdim                      /*AllowNullaryMethods=*/true, CurContext,
3634218893Sdim                      AddedProperties, Results);
3635198893Srdivacky
3636199482Srdivacky    // Add properties from the protocols in a qualified interface.
3637199482Srdivacky    for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
3638199482Srdivacky                                              E = ObjCPtr->qual_end();
3639199482Srdivacky         I != E; ++I)
3640223017Sdim      AddObjCProperties(*I, true, /*AllowNullaryMethods=*/true, CurContext,
3641223017Sdim                        AddedProperties, Results);
3642199482Srdivacky  } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
3643208600Srdivacky             (!IsArrow && BaseType->isObjCObjectType())) {
3644199482Srdivacky    // Objective-C instance variable access.
3645199482Srdivacky    ObjCInterfaceDecl *Class = 0;
3646199482Srdivacky    if (const ObjCObjectPointerType *ObjCPtr
3647199482Srdivacky                                    = BaseType->getAs<ObjCObjectPointerType>())
3648199482Srdivacky      Class = ObjCPtr->getInterfaceDecl();
3649199482Srdivacky    else
3650208600Srdivacky      Class = BaseType->getAs<ObjCObjectType>()->getInterface();
3651199482Srdivacky
3652199482Srdivacky    // Add all ivars from this class and its superclasses.
3653202379Srdivacky    if (Class) {
3654202379Srdivacky      CodeCompletionDeclConsumer Consumer(Results, CurContext);
3655202379Srdivacky      Results.setFilter(&ResultBuilder::IsObjCIvar);
3656212904Sdim      LookupVisibleDecls(Class, LookupMemberName, Consumer,
3657212904Sdim                         CodeCompleter->includeGlobals());
3658199482Srdivacky    }
3659198092Srdivacky  }
3660199482Srdivacky
3661199482Srdivacky  // FIXME: How do we cope with isa?
3662199482Srdivacky
3663199482Srdivacky  Results.ExitScope();
3664199482Srdivacky
3665199482Srdivacky  // Hand off the results found for code completion.
3666212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
3667218893Sdim                            Results.getCompletionContext(),
3668212904Sdim                            Results.data(),Results.size());
3669198092Srdivacky}
3670198092Srdivacky
3671198092Srdivackyvoid Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
3672198092Srdivacky  if (!CodeCompleter)
3673198092Srdivacky    return;
3674198092Srdivacky
3675198092Srdivacky  ResultBuilder::LookupFilter Filter = 0;
3676212904Sdim  enum CodeCompletionContext::Kind ContextKind
3677212904Sdim    = CodeCompletionContext::CCC_Other;
3678198092Srdivacky  switch ((DeclSpec::TST)TagSpec) {
3679198092Srdivacky  case DeclSpec::TST_enum:
3680198092Srdivacky    Filter = &ResultBuilder::IsEnum;
3681212904Sdim    ContextKind = CodeCompletionContext::CCC_EnumTag;
3682198092Srdivacky    break;
3683198092Srdivacky
3684198092Srdivacky  case DeclSpec::TST_union:
3685198092Srdivacky    Filter = &ResultBuilder::IsUnion;
3686212904Sdim    ContextKind = CodeCompletionContext::CCC_UnionTag;
3687198092Srdivacky    break;
3688198092Srdivacky
3689198092Srdivacky  case DeclSpec::TST_struct:
3690198092Srdivacky  case DeclSpec::TST_class:
3691243830Sdim  case DeclSpec::TST_interface:
3692198092Srdivacky    Filter = &ResultBuilder::IsClassOrStruct;
3693212904Sdim    ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
3694198092Srdivacky    break;
3695198092Srdivacky
3696198092Srdivacky  default:
3697226633Sdim    llvm_unreachable("Unknown type specifier kind in CodeCompleteTag");
3698198092Srdivacky  }
3699198092Srdivacky
3700234353Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3701234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(), ContextKind);
3702202379Srdivacky  CodeCompletionDeclConsumer Consumer(Results, CurContext);
3703207619Srdivacky
3704207619Srdivacky  // First pass: look for tags.
3705207619Srdivacky  Results.setFilter(Filter);
3706212904Sdim  LookupVisibleDecls(S, LookupTagName, Consumer,
3707212904Sdim                     CodeCompleter->includeGlobals());
3708207619Srdivacky
3709212904Sdim  if (CodeCompleter->includeGlobals()) {
3710212904Sdim    // Second pass: look for nested name specifiers.
3711212904Sdim    Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
3712212904Sdim    LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
3713212904Sdim  }
3714198092Srdivacky
3715218893Sdim  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3716212904Sdim                            Results.data(),Results.size());
3717198092Srdivacky}
3718198092Srdivacky
3719212904Sdimvoid Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
3720218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3721234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
3722218893Sdim                        CodeCompletionContext::CCC_TypeQualifiers);
3723212904Sdim  Results.EnterNewScope();
3724212904Sdim  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
3725212904Sdim    Results.AddResult("const");
3726212904Sdim  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
3727212904Sdim    Results.AddResult("volatile");
3728234353Sdim  if (getLangOpts().C99 &&
3729212904Sdim      !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
3730212904Sdim    Results.AddResult("restrict");
3731249423Sdim  if (getLangOpts().C11 &&
3732249423Sdim      !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
3733249423Sdim    Results.AddResult("_Atomic");
3734212904Sdim  Results.ExitScope();
3735212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
3736218893Sdim                            Results.getCompletionContext(),
3737212904Sdim                            Results.data(), Results.size());
3738212904Sdim}
3739212904Sdim
3740198092Srdivackyvoid Sema::CodeCompleteCase(Scope *S) {
3741212904Sdim  if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
3742198092Srdivacky    return;
3743226633Sdim
3744212904Sdim  SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
3745226633Sdim  QualType type = Switch->getCond()->IgnoreImplicit()->getType();
3746226633Sdim  if (!type->isEnumeralType()) {
3747226633Sdim    CodeCompleteExpressionData Data(type);
3748212904Sdim    Data.IntegralConstantExpression = true;
3749212904Sdim    CodeCompleteExpression(S, Data);
3750198092Srdivacky    return;
3751212904Sdim  }
3752198092Srdivacky
3753198092Srdivacky  // Code-complete the cases of a switch statement over an enumeration type
3754198092Srdivacky  // by providing the list of
3755226633Sdim  EnumDecl *Enum = type->castAs<EnumType>()->getDecl();
3756239462Sdim  if (EnumDecl *Def = Enum->getDefinition())
3757239462Sdim    Enum = Def;
3758198092Srdivacky
3759198092Srdivacky  // Determine which enumerators we have already seen in the switch statement.
3760198092Srdivacky  // FIXME: Ideally, we would also be able to look *past* the code-completion
3761198092Srdivacky  // token, in case we are code-completing in the middle of the switch and not
3762198092Srdivacky  // at the end. However, we aren't able to do so at the moment.
3763198092Srdivacky  llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
3764198092Srdivacky  NestedNameSpecifier *Qualifier = 0;
3765198092Srdivacky  for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3766198092Srdivacky       SC = SC->getNextSwitchCase()) {
3767198092Srdivacky    CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3768198092Srdivacky    if (!Case)
3769198092Srdivacky      continue;
3770198092Srdivacky
3771198092Srdivacky    Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3772198092Srdivacky    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3773198092Srdivacky      if (EnumConstantDecl *Enumerator
3774198092Srdivacky            = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3775198092Srdivacky        // We look into the AST of the case statement to determine which
3776198092Srdivacky        // enumerator was named. Alternatively, we could compute the value of
3777198092Srdivacky        // the integral constant expression, then compare it against the
3778198092Srdivacky        // values of each enumerator. However, value-based approach would not
3779198092Srdivacky        // work as well with C++ templates where enumerators declared within a
3780198092Srdivacky        // template are type- and value-dependent.
3781198092Srdivacky        EnumeratorsSeen.insert(Enumerator);
3782198092Srdivacky
3783198092Srdivacky        // If this is a qualified-id, keep track of the nested-name-specifier
3784198092Srdivacky        // so that we can reproduce it as part of code completion, e.g.,
3785198092Srdivacky        //
3786198092Srdivacky        //   switch (TagD.getKind()) {
3787198092Srdivacky        //     case TagDecl::TK_enum:
3788198092Srdivacky        //       break;
3789198092Srdivacky        //     case XXX
3790198092Srdivacky        //
3791198092Srdivacky        // At the XXX, our completions are TagDecl::TK_union,
3792198092Srdivacky        // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3793198092Srdivacky        // TK_struct, and TK_class.
3794198893Srdivacky        Qualifier = DRE->getQualifier();
3795198092Srdivacky      }
3796198092Srdivacky  }
3797198092Srdivacky
3798234353Sdim  if (getLangOpts().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3799198092Srdivacky    // If there are no prior enumerators in C++, check whether we have to
3800198092Srdivacky    // qualify the names of the enumerators that we suggest, because they
3801198092Srdivacky    // may not be visible in this scope.
3802234353Sdim    Qualifier = getRequiredQualification(Context, CurContext, Enum);
3803198092Srdivacky  }
3804198092Srdivacky
3805198092Srdivacky  // Add any enumerators that have not yet been mentioned.
3806218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3807234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
3808218893Sdim                        CodeCompletionContext::CCC_Expression);
3809198092Srdivacky  Results.EnterNewScope();
3810198092Srdivacky  for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
3811198092Srdivacky                                  EEnd = Enum->enumerator_end();
3812198092Srdivacky       E != EEnd; ++E) {
3813198092Srdivacky    if (EnumeratorsSeen.count(*E))
3814198092Srdivacky      continue;
3815198092Srdivacky
3816249423Sdim    CodeCompletionResult R(*E, CCP_EnumInCase, Qualifier);
3817218893Sdim    Results.AddResult(R, CurContext, 0, false);
3818198092Srdivacky  }
3819198092Srdivacky  Results.ExitScope();
3820207619Srdivacky
3821224145Sdim  //We need to make sure we're setting the right context,
3822224145Sdim  //so only say we include macros if the code completer says we do
3823224145Sdim  enum CodeCompletionContext::Kind kind = CodeCompletionContext::CCC_Other;
3824224145Sdim  if (CodeCompleter->includeMacros()) {
3825243830Sdim    AddMacroResults(PP, Results, false);
3826224145Sdim    kind = CodeCompletionContext::CCC_OtherWithMacros;
3827224145Sdim  }
3828224145Sdim
3829212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
3830224145Sdim                            kind,
3831212904Sdim                            Results.data(),Results.size());
3832198092Srdivacky}
3833198092Srdivacky
3834198092Srdivackynamespace {
3835198092Srdivacky  struct IsBetterOverloadCandidate {
3836198092Srdivacky    Sema &S;
3837203955Srdivacky    SourceLocation Loc;
3838198092Srdivacky
3839198092Srdivacky  public:
3840203955Srdivacky    explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
3841203955Srdivacky      : S(S), Loc(Loc) { }
3842198092Srdivacky
3843198092Srdivacky    bool
3844198092Srdivacky    operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
3845212904Sdim      return isBetterOverloadCandidate(S, X, Y, Loc);
3846198092Srdivacky    }
3847198092Srdivacky  };
3848198092Srdivacky}
3849198092Srdivacky
3850234353Sdimstatic bool anyNullArguments(llvm::ArrayRef<Expr*> Args) {
3851234353Sdim  if (Args.size() && !Args.data())
3852210299Sed    return true;
3853234353Sdim
3854234353Sdim  for (unsigned I = 0; I != Args.size(); ++I)
3855210299Sed    if (!Args[I])
3856210299Sed      return true;
3857234353Sdim
3858210299Sed  return false;
3859210299Sed}
3860210299Sed
3861226633Sdimvoid Sema::CodeCompleteCall(Scope *S, Expr *FnIn,
3862234353Sdim                            llvm::ArrayRef<Expr *> Args) {
3863198092Srdivacky  if (!CodeCompleter)
3864198092Srdivacky    return;
3865200583Srdivacky
3866200583Srdivacky  // When we're code-completing for a call, we fall back to ordinary
3867200583Srdivacky  // name code-completion whenever we can't produce specific
3868200583Srdivacky  // results. We may want to revisit this strategy in the future,
3869200583Srdivacky  // e.g., by merging the two kinds of results.
3870200583Srdivacky
3871198092Srdivacky  Expr *Fn = (Expr *)FnIn;
3872200583Srdivacky
3873198092Srdivacky  // Ignore type-dependent call expressions entirely.
3874234353Sdim  if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||
3875234353Sdim      Expr::hasAnyTypeDependentArguments(Args)) {
3876212904Sdim    CodeCompleteOrdinaryName(S, PCC_Expression);
3877198092Srdivacky    return;
3878200583Srdivacky  }
3879198092Srdivacky
3880201361Srdivacky  // Build an overload candidate set based on the functions we find.
3881203955Srdivacky  SourceLocation Loc = Fn->getExprLoc();
3882203955Srdivacky  OverloadCandidateSet CandidateSet(Loc);
3883201361Srdivacky
3884198092Srdivacky  // FIXME: What if we're calling something that isn't a function declaration?
3885198092Srdivacky  // FIXME: What if we're calling a pseudo-destructor?
3886198092Srdivacky  // FIXME: What if we're calling a member function?
3887198092Srdivacky
3888202879Srdivacky  typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3889226633Sdim  SmallVector<ResultCandidate, 8> Results;
3890202879Srdivacky
3891201361Srdivacky  Expr *NakedFn = Fn->IgnoreParenCasts();
3892201361Srdivacky  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
3893234353Sdim    AddOverloadedCallCandidates(ULE, Args, CandidateSet,
3894201361Srdivacky                                /*PartialOverloading=*/ true);
3895201361Srdivacky  else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
3896201361Srdivacky    FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
3897202879Srdivacky    if (FDecl) {
3898234353Sdim      if (!getLangOpts().CPlusPlus ||
3899210299Sed          !FDecl->getType()->getAs<FunctionProtoType>())
3900202879Srdivacky        Results.push_back(ResultCandidate(FDecl));
3901202879Srdivacky      else
3902203955Srdivacky        // FIXME: access?
3903234353Sdim        AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none), Args,
3904234353Sdim                             CandidateSet, false, /*PartialOverloading*/true);
3905202879Srdivacky    }
3906201361Srdivacky  }
3907198092Srdivacky
3908210299Sed  QualType ParamType;
3909210299Sed
3910202879Srdivacky  if (!CandidateSet.empty()) {
3911202879Srdivacky    // Sort the overload candidate set by placing the best overloads first.
3912202879Srdivacky    std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
3913203955Srdivacky                     IsBetterOverloadCandidate(*this, Loc));
3914198092Srdivacky
3915202879Srdivacky    // Add the remaining viable overload candidates as code-completion reslults.
3916202879Srdivacky    for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
3917202879Srdivacky                                     CandEnd = CandidateSet.end();
3918202879Srdivacky         Cand != CandEnd; ++Cand) {
3919202879Srdivacky      if (Cand->Viable)
3920202879Srdivacky        Results.push_back(ResultCandidate(Cand->Function));
3921202879Srdivacky    }
3922210299Sed
3923210299Sed    // From the viable candidates, try to determine the type of this parameter.
3924210299Sed    for (unsigned I = 0, N = Results.size(); I != N; ++I) {
3925210299Sed      if (const FunctionType *FType = Results[I].getFunctionType())
3926210299Sed        if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
3927234353Sdim          if (Args.size() < Proto->getNumArgs()) {
3928210299Sed            if (ParamType.isNull())
3929234353Sdim              ParamType = Proto->getArgType(Args.size());
3930210299Sed            else if (!Context.hasSameUnqualifiedType(
3931210299Sed                                            ParamType.getNonReferenceType(),
3932234353Sdim                       Proto->getArgType(Args.size()).getNonReferenceType())) {
3933210299Sed              ParamType = QualType();
3934210299Sed              break;
3935210299Sed            }
3936210299Sed          }
3937210299Sed    }
3938210299Sed  } else {
3939210299Sed    // Try to determine the parameter type from the type of the expression
3940210299Sed    // being called.
3941210299Sed    QualType FunctionType = Fn->getType();
3942210299Sed    if (const PointerType *Ptr = FunctionType->getAs<PointerType>())
3943210299Sed      FunctionType = Ptr->getPointeeType();
3944210299Sed    else if (const BlockPointerType *BlockPtr
3945210299Sed                                    = FunctionType->getAs<BlockPointerType>())
3946210299Sed      FunctionType = BlockPtr->getPointeeType();
3947210299Sed    else if (const MemberPointerType *MemPtr
3948210299Sed                                    = FunctionType->getAs<MemberPointerType>())
3949210299Sed      FunctionType = MemPtr->getPointeeType();
3950210299Sed
3951210299Sed    if (const FunctionProtoType *Proto
3952210299Sed                                  = FunctionType->getAs<FunctionProtoType>()) {
3953234353Sdim      if (Args.size() < Proto->getNumArgs())
3954234353Sdim        ParamType = Proto->getArgType(Args.size());
3955210299Sed    }
3956198092Srdivacky  }
3957200583Srdivacky
3958210299Sed  if (ParamType.isNull())
3959212904Sdim    CodeCompleteOrdinaryName(S, PCC_Expression);
3960210299Sed  else
3961210299Sed    CodeCompleteExpression(S, ParamType);
3962210299Sed
3963207619Srdivacky  if (!Results.empty())
3964234353Sdim    CodeCompleter->ProcessOverloadCandidates(*this, Args.size(), Results.data(),
3965200583Srdivacky                                             Results.size());
3966198092Srdivacky}
3967198092Srdivacky
3968212904Sdimvoid Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
3969212904Sdim  ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
3970210299Sed  if (!VD) {
3971212904Sdim    CodeCompleteOrdinaryName(S, PCC_Expression);
3972210299Sed    return;
3973210299Sed  }
3974210299Sed
3975210299Sed  CodeCompleteExpression(S, VD->getType());
3976210299Sed}
3977210299Sed
3978210299Sedvoid Sema::CodeCompleteReturn(Scope *S) {
3979210299Sed  QualType ResultType;
3980210299Sed  if (isa<BlockDecl>(CurContext)) {
3981210299Sed    if (BlockScopeInfo *BSI = getCurBlock())
3982210299Sed      ResultType = BSI->ReturnType;
3983210299Sed  } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
3984210299Sed    ResultType = Function->getResultType();
3985210299Sed  else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
3986210299Sed    ResultType = Method->getResultType();
3987210299Sed
3988210299Sed  if (ResultType.isNull())
3989212904Sdim    CodeCompleteOrdinaryName(S, PCC_Expression);
3990210299Sed  else
3991210299Sed    CodeCompleteExpression(S, ResultType);
3992210299Sed}
3993210299Sed
3994226633Sdimvoid Sema::CodeCompleteAfterIf(Scope *S) {
3995226633Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3996234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
3997226633Sdim                        mapCodeCompletionContext(*this, PCC_Statement));
3998226633Sdim  Results.setFilter(&ResultBuilder::IsOrdinaryName);
3999226633Sdim  Results.EnterNewScope();
4000226633Sdim
4001226633Sdim  CodeCompletionDeclConsumer Consumer(Results, CurContext);
4002226633Sdim  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4003226633Sdim                     CodeCompleter->includeGlobals());
4004226633Sdim
4005226633Sdim  AddOrdinaryNameResults(PCC_Statement, S, *this, Results);
4006226633Sdim
4007226633Sdim  // "else" block
4008234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
4009234353Sdim                                Results.getCodeCompletionTUInfo());
4010226633Sdim  Builder.AddTypedTextChunk("else");
4011234353Sdim  if (Results.includeCodePatterns()) {
4012234353Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4013234353Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4014234353Sdim    Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4015234353Sdim    Builder.AddPlaceholderChunk("statements");
4016234353Sdim    Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4017234353Sdim    Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4018234353Sdim  }
4019226633Sdim  Results.AddResult(Builder.TakeString());
4020226633Sdim
4021226633Sdim  // "else if" block
4022226633Sdim  Builder.AddTypedTextChunk("else");
4023226633Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4024226633Sdim  Builder.AddTextChunk("if");
4025226633Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4026226633Sdim  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4027234353Sdim  if (getLangOpts().CPlusPlus)
4028226633Sdim    Builder.AddPlaceholderChunk("condition");
4029226633Sdim  else
4030226633Sdim    Builder.AddPlaceholderChunk("expression");
4031226633Sdim  Builder.AddChunk(CodeCompletionString::CK_RightParen);
4032234353Sdim  if (Results.includeCodePatterns()) {
4033234353Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4034234353Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4035234353Sdim    Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4036234353Sdim    Builder.AddPlaceholderChunk("statements");
4037234353Sdim    Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4038234353Sdim    Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4039234353Sdim  }
4040226633Sdim  Results.AddResult(Builder.TakeString());
4041226633Sdim
4042226633Sdim  Results.ExitScope();
4043226633Sdim
4044226633Sdim  if (S->getFnParent())
4045234353Sdim    AddPrettyFunctionResults(PP.getLangOpts(), Results);
4046226633Sdim
4047226633Sdim  if (CodeCompleter->includeMacros())
4048243830Sdim    AddMacroResults(PP, Results, false);
4049226633Sdim
4050226633Sdim  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4051226633Sdim                            Results.data(),Results.size());
4052226633Sdim}
4053226633Sdim
4054226633Sdimvoid Sema::CodeCompleteAssignmentRHS(Scope *S, Expr *LHS) {
4055210299Sed  if (LHS)
4056210299Sed    CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
4057210299Sed  else
4058212904Sdim    CodeCompleteOrdinaryName(S, PCC_Expression);
4059210299Sed}
4060210299Sed
4061207619Srdivackyvoid Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
4062198092Srdivacky                                   bool EnteringContext) {
4063198092Srdivacky  if (!SS.getScopeRep() || !CodeCompleter)
4064198092Srdivacky    return;
4065198092Srdivacky
4066198092Srdivacky  DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
4067198092Srdivacky  if (!Ctx)
4068198092Srdivacky    return;
4069200583Srdivacky
4070200583Srdivacky  // Try to instantiate any non-dependent declaration contexts before
4071200583Srdivacky  // we look in them.
4072207619Srdivacky  if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
4073200583Srdivacky    return;
4074200583Srdivacky
4075218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4076234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4077218893Sdim                        CodeCompletionContext::CCC_Name);
4078218893Sdim  Results.EnterNewScope();
4079198092Srdivacky
4080198092Srdivacky  // The "template" keyword can follow "::" in the grammar, but only
4081198092Srdivacky  // put it into the grammar if the nested-name-specifier is dependent.
4082198092Srdivacky  NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
4083198092Srdivacky  if (!Results.empty() && NNS->isDependent())
4084202379Srdivacky    Results.AddResult("template");
4085212904Sdim
4086212904Sdim  // Add calls to overridden virtual functions, if there are any.
4087212904Sdim  //
4088212904Sdim  // FIXME: This isn't wonderful, because we don't know whether we're actually
4089212904Sdim  // in a context that permits expressions. This is a general issue with
4090212904Sdim  // qualified-id completions.
4091212904Sdim  if (!EnteringContext)
4092212904Sdim    MaybeAddOverrideCalls(*this, Ctx, Results);
4093212904Sdim  Results.ExitScope();
4094198092Srdivacky
4095212904Sdim  CodeCompletionDeclConsumer Consumer(Results, CurContext);
4096212904Sdim  LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
4097212904Sdim
4098212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4099226633Sdim                            Results.getCompletionContext(),
4100212904Sdim                            Results.data(),Results.size());
4101198092Srdivacky}
4102198092Srdivacky
4103198092Srdivackyvoid Sema::CodeCompleteUsing(Scope *S) {
4104198092Srdivacky  if (!CodeCompleter)
4105198092Srdivacky    return;
4106198092Srdivacky
4107218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4108234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4109218893Sdim                        CodeCompletionContext::CCC_PotentiallyQualifiedName,
4110218893Sdim                        &ResultBuilder::IsNestedNameSpecifier);
4111198092Srdivacky  Results.EnterNewScope();
4112198092Srdivacky
4113198092Srdivacky  // If we aren't in class scope, we could see the "namespace" keyword.
4114198092Srdivacky  if (!S->isClassScope())
4115212904Sdim    Results.AddResult(CodeCompletionResult("namespace"));
4116198092Srdivacky
4117198092Srdivacky  // After "using", we can see anything that would start a
4118198092Srdivacky  // nested-name-specifier.
4119202379Srdivacky  CodeCompletionDeclConsumer Consumer(Results, CurContext);
4120212904Sdim  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4121212904Sdim                     CodeCompleter->includeGlobals());
4122198092Srdivacky  Results.ExitScope();
4123198092Srdivacky
4124212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4125218893Sdim                            CodeCompletionContext::CCC_PotentiallyQualifiedName,
4126212904Sdim                            Results.data(),Results.size());
4127198092Srdivacky}
4128198092Srdivacky
4129198092Srdivackyvoid Sema::CodeCompleteUsingDirective(Scope *S) {
4130198092Srdivacky  if (!CodeCompleter)
4131198092Srdivacky    return;
4132198092Srdivacky
4133198092Srdivacky  // After "using namespace", we expect to see a namespace name or namespace
4134198092Srdivacky  // alias.
4135218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4136234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4137218893Sdim                        CodeCompletionContext::CCC_Namespace,
4138218893Sdim                        &ResultBuilder::IsNamespaceOrAlias);
4139198092Srdivacky  Results.EnterNewScope();
4140202379Srdivacky  CodeCompletionDeclConsumer Consumer(Results, CurContext);
4141212904Sdim  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4142212904Sdim                     CodeCompleter->includeGlobals());
4143198092Srdivacky  Results.ExitScope();
4144212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4145212904Sdim                            CodeCompletionContext::CCC_Namespace,
4146212904Sdim                            Results.data(),Results.size());
4147198092Srdivacky}
4148198092Srdivacky
4149198092Srdivackyvoid Sema::CodeCompleteNamespaceDecl(Scope *S)  {
4150198092Srdivacky  if (!CodeCompleter)
4151198092Srdivacky    return;
4152198092Srdivacky
4153198092Srdivacky  DeclContext *Ctx = (DeclContext *)S->getEntity();
4154198092Srdivacky  if (!S->getParent())
4155198092Srdivacky    Ctx = Context.getTranslationUnitDecl();
4156198092Srdivacky
4157218893Sdim  bool SuppressedGlobalResults
4158218893Sdim    = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
4159218893Sdim
4160218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4161234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4162218893Sdim                        SuppressedGlobalResults
4163218893Sdim                          ? CodeCompletionContext::CCC_Namespace
4164218893Sdim                          : CodeCompletionContext::CCC_Other,
4165218893Sdim                        &ResultBuilder::IsNamespace);
4166218893Sdim
4167218893Sdim  if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
4168198092Srdivacky    // We only want to see those namespaces that have already been defined
4169198092Srdivacky    // within this scope, because its likely that the user is creating an
4170198092Srdivacky    // extended namespace declaration. Keep track of the most recent
4171198092Srdivacky    // definition of each namespace.
4172198092Srdivacky    std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
4173198092Srdivacky    for (DeclContext::specific_decl_iterator<NamespaceDecl>
4174198092Srdivacky         NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
4175198092Srdivacky         NS != NSEnd; ++NS)
4176198092Srdivacky      OrigToLatest[NS->getOriginalNamespace()] = *NS;
4177198092Srdivacky
4178198092Srdivacky    // Add the most recent definition (or extended definition) of each
4179198092Srdivacky    // namespace to the list of results.
4180198092Srdivacky    Results.EnterNewScope();
4181198092Srdivacky    for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
4182234353Sdim              NS = OrigToLatest.begin(),
4183234353Sdim           NSEnd = OrigToLatest.end();
4184198092Srdivacky         NS != NSEnd; ++NS)
4185249423Sdim      Results.AddResult(CodeCompletionResult(
4186249423Sdim                          NS->second, Results.getBasePriority(NS->second), 0),
4187202379Srdivacky                        CurContext, 0, false);
4188198092Srdivacky    Results.ExitScope();
4189198092Srdivacky  }
4190198092Srdivacky
4191212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4192218893Sdim                            Results.getCompletionContext(),
4193212904Sdim                            Results.data(),Results.size());
4194198092Srdivacky}
4195198092Srdivacky
4196198092Srdivackyvoid Sema::CodeCompleteNamespaceAliasDecl(Scope *S)  {
4197198092Srdivacky  if (!CodeCompleter)
4198198092Srdivacky    return;
4199198092Srdivacky
4200198092Srdivacky  // After "namespace", we expect to see a namespace or alias.
4201218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4202234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4203218893Sdim                        CodeCompletionContext::CCC_Namespace,
4204218893Sdim                        &ResultBuilder::IsNamespaceOrAlias);
4205202379Srdivacky  CodeCompletionDeclConsumer Consumer(Results, CurContext);
4206212904Sdim  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4207212904Sdim                     CodeCompleter->includeGlobals());
4208212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4209218893Sdim                            Results.getCompletionContext(),
4210212904Sdim                            Results.data(),Results.size());
4211198092Srdivacky}
4212198092Srdivacky
4213198092Srdivackyvoid Sema::CodeCompleteOperatorName(Scope *S) {
4214198092Srdivacky  if (!CodeCompleter)
4215198092Srdivacky    return;
4216198092Srdivacky
4217212904Sdim  typedef CodeCompletionResult Result;
4218218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4219234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4220218893Sdim                        CodeCompletionContext::CCC_Type,
4221218893Sdim                        &ResultBuilder::IsType);
4222198092Srdivacky  Results.EnterNewScope();
4223198092Srdivacky
4224198092Srdivacky  // Add the names of overloadable operators.
4225198092Srdivacky#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)      \
4226198092Srdivacky  if (std::strcmp(Spelling, "?"))                                                  \
4227202379Srdivacky    Results.AddResult(Result(Spelling));
4228198092Srdivacky#include "clang/Basic/OperatorKinds.def"
4229198092Srdivacky
4230198092Srdivacky  // Add any type names visible from the current scope
4231202379Srdivacky  Results.allowNestedNameSpecifiers();
4232202379Srdivacky  CodeCompletionDeclConsumer Consumer(Results, CurContext);
4233212904Sdim  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4234212904Sdim                     CodeCompleter->includeGlobals());
4235198092Srdivacky
4236198092Srdivacky  // Add any type specifiers
4237234353Sdim  AddTypeSpecifierResults(getLangOpts(), Results);
4238198092Srdivacky  Results.ExitScope();
4239198092Srdivacky
4240212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4241212904Sdim                            CodeCompletionContext::CCC_Type,
4242212904Sdim                            Results.data(),Results.size());
4243198092Srdivacky}
4244198092Srdivacky
4245212904Sdimvoid Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
4246218893Sdim                                              CXXCtorInitializer** Initializers,
4247212904Sdim                                              unsigned NumInitializers) {
4248226633Sdim  PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
4249212904Sdim  CXXConstructorDecl *Constructor
4250212904Sdim    = static_cast<CXXConstructorDecl *>(ConstructorD);
4251212904Sdim  if (!Constructor)
4252212904Sdim    return;
4253212904Sdim
4254218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4255234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4256218893Sdim                        CodeCompletionContext::CCC_PotentiallyQualifiedName);
4257212904Sdim  Results.EnterNewScope();
4258212904Sdim
4259212904Sdim  // Fill in any already-initialized fields or base classes.
4260212904Sdim  llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
4261212904Sdim  llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
4262212904Sdim  for (unsigned I = 0; I != NumInitializers; ++I) {
4263212904Sdim    if (Initializers[I]->isBaseInitializer())
4264212904Sdim      InitializedBases.insert(
4265212904Sdim        Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
4266212904Sdim    else
4267218893Sdim      InitializedFields.insert(cast<FieldDecl>(
4268218893Sdim                               Initializers[I]->getAnyMember()));
4269212904Sdim  }
4270212904Sdim
4271212904Sdim  // Add completions for base classes.
4272234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
4273234353Sdim                                Results.getCodeCompletionTUInfo());
4274212904Sdim  bool SawLastInitializer = (NumInitializers == 0);
4275212904Sdim  CXXRecordDecl *ClassDecl = Constructor->getParent();
4276212904Sdim  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
4277212904Sdim                                       BaseEnd = ClassDecl->bases_end();
4278212904Sdim       Base != BaseEnd; ++Base) {
4279212904Sdim    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
4280212904Sdim      SawLastInitializer
4281212904Sdim        = NumInitializers > 0 &&
4282212904Sdim          Initializers[NumInitializers - 1]->isBaseInitializer() &&
4283212904Sdim          Context.hasSameUnqualifiedType(Base->getType(),
4284212904Sdim               QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
4285212904Sdim      continue;
4286212904Sdim    }
4287212904Sdim
4288218893Sdim    Builder.AddTypedTextChunk(
4289218893Sdim               Results.getAllocator().CopyString(
4290224145Sdim                          Base->getType().getAsString(Policy)));
4291218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4292218893Sdim    Builder.AddPlaceholderChunk("args");
4293218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
4294218893Sdim    Results.AddResult(CodeCompletionResult(Builder.TakeString(),
4295212904Sdim                                   SawLastInitializer? CCP_NextInitializer
4296212904Sdim                                                     : CCP_MemberDeclaration));
4297212904Sdim    SawLastInitializer = false;
4298212904Sdim  }
4299212904Sdim
4300212904Sdim  // Add completions for virtual base classes.
4301212904Sdim  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
4302212904Sdim                                       BaseEnd = ClassDecl->vbases_end();
4303212904Sdim       Base != BaseEnd; ++Base) {
4304212904Sdim    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
4305212904Sdim      SawLastInitializer
4306212904Sdim        = NumInitializers > 0 &&
4307212904Sdim          Initializers[NumInitializers - 1]->isBaseInitializer() &&
4308212904Sdim          Context.hasSameUnqualifiedType(Base->getType(),
4309212904Sdim               QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
4310212904Sdim      continue;
4311212904Sdim    }
4312212904Sdim
4313218893Sdim    Builder.AddTypedTextChunk(
4314218893Sdim               Builder.getAllocator().CopyString(
4315224145Sdim                          Base->getType().getAsString(Policy)));
4316218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4317218893Sdim    Builder.AddPlaceholderChunk("args");
4318218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
4319218893Sdim    Results.AddResult(CodeCompletionResult(Builder.TakeString(),
4320212904Sdim                                   SawLastInitializer? CCP_NextInitializer
4321212904Sdim                                                     : CCP_MemberDeclaration));
4322212904Sdim    SawLastInitializer = false;
4323212904Sdim  }
4324212904Sdim
4325212904Sdim  // Add completions for members.
4326212904Sdim  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
4327212904Sdim                                  FieldEnd = ClassDecl->field_end();
4328212904Sdim       Field != FieldEnd; ++Field) {
4329212904Sdim    if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
4330212904Sdim      SawLastInitializer
4331212904Sdim        = NumInitializers > 0 &&
4332218893Sdim          Initializers[NumInitializers - 1]->isAnyMemberInitializer() &&
4333218893Sdim          Initializers[NumInitializers - 1]->getAnyMember() == *Field;
4334212904Sdim      continue;
4335212904Sdim    }
4336212904Sdim
4337212904Sdim    if (!Field->getDeclName())
4338212904Sdim      continue;
4339212904Sdim
4340218893Sdim    Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
4341218893Sdim                                         Field->getIdentifier()->getName()));
4342218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4343218893Sdim    Builder.AddPlaceholderChunk("args");
4344218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
4345218893Sdim    Results.AddResult(CodeCompletionResult(Builder.TakeString(),
4346212904Sdim                                   SawLastInitializer? CCP_NextInitializer
4347218893Sdim                                                     : CCP_MemberDeclaration,
4348234353Sdim                                           CXCursor_MemberRef,
4349234353Sdim                                           CXAvailability_Available,
4350234353Sdim                                           *Field));
4351212904Sdim    SawLastInitializer = false;
4352212904Sdim  }
4353212904Sdim  Results.ExitScope();
4354212904Sdim
4355218893Sdim  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4356212904Sdim                            Results.data(), Results.size());
4357212904Sdim}
4358212904Sdim
4359234353Sdim/// \brief Determine whether this scope denotes a namespace.
4360234353Sdimstatic bool isNamespaceScope(Scope *S) {
4361234353Sdim  DeclContext *DC = static_cast<DeclContext *>(S->getEntity());
4362234353Sdim  if (!DC)
4363234353Sdim    return false;
4364234353Sdim
4365234353Sdim  return DC->isFileContext();
4366234353Sdim}
4367234353Sdim
4368234353Sdimvoid Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
4369234353Sdim                                        bool AfterAmpersand) {
4370234353Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4371234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4372234353Sdim                        CodeCompletionContext::CCC_Other);
4373234353Sdim  Results.EnterNewScope();
4374234353Sdim
4375234353Sdim  // Note what has already been captured.
4376234353Sdim  llvm::SmallPtrSet<IdentifierInfo *, 4> Known;
4377234353Sdim  bool IncludedThis = false;
4378234353Sdim  for (SmallVectorImpl<LambdaCapture>::iterator C = Intro.Captures.begin(),
4379234353Sdim                                             CEnd = Intro.Captures.end();
4380234353Sdim       C != CEnd; ++C) {
4381234353Sdim    if (C->Kind == LCK_This) {
4382234353Sdim      IncludedThis = true;
4383234353Sdim      continue;
4384234353Sdim    }
4385234353Sdim
4386234353Sdim    Known.insert(C->Id);
4387234353Sdim  }
4388234353Sdim
4389234353Sdim  // Look for other capturable variables.
4390234353Sdim  for (; S && !isNamespaceScope(S); S = S->getParent()) {
4391234353Sdim    for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
4392234353Sdim         D != DEnd; ++D) {
4393234353Sdim      VarDecl *Var = dyn_cast<VarDecl>(*D);
4394234353Sdim      if (!Var ||
4395234353Sdim          !Var->hasLocalStorage() ||
4396234353Sdim          Var->hasAttr<BlocksAttr>())
4397234353Sdim        continue;
4398234353Sdim
4399234353Sdim      if (Known.insert(Var->getIdentifier()))
4400249423Sdim        Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration),
4401249423Sdim                          CurContext, 0, false);
4402234353Sdim    }
4403234353Sdim  }
4404234353Sdim
4405234353Sdim  // Add 'this', if it would be valid.
4406234353Sdim  if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy)
4407234353Sdim    addThisCompletion(*this, Results);
4408234353Sdim
4409234353Sdim  Results.ExitScope();
4410234353Sdim
4411234353Sdim  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4412234353Sdim                            Results.data(), Results.size());
4413234353Sdim}
4414234353Sdim
4415239462Sdim/// Macro that optionally prepends an "@" to the string literal passed in via
4416239462Sdim/// Keyword, depending on whether NeedAt is true or false.
4417239462Sdim#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) ((NeedAt)? "@" Keyword : Keyword)
4418239462Sdim
4419202379Srdivackystatic void AddObjCImplementationResults(const LangOptions &LangOpts,
4420202379Srdivacky                                         ResultBuilder &Results,
4421202379Srdivacky                                         bool NeedAt) {
4422212904Sdim  typedef CodeCompletionResult Result;
4423202379Srdivacky  // Since we have an implementation, we can end it.
4424239462Sdim  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end")));
4425202379Srdivacky
4426234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
4427234353Sdim                                Results.getCodeCompletionTUInfo());
4428202379Srdivacky  if (LangOpts.ObjC2) {
4429202379Srdivacky    // @dynamic
4430239462Sdim    Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"dynamic"));
4431218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4432218893Sdim    Builder.AddPlaceholderChunk("property");
4433218893Sdim    Results.AddResult(Result(Builder.TakeString()));
4434202379Srdivacky
4435202379Srdivacky    // @synthesize
4436239462Sdim    Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synthesize"));
4437218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4438218893Sdim    Builder.AddPlaceholderChunk("property");
4439218893Sdim    Results.AddResult(Result(Builder.TakeString()));
4440202379Srdivacky  }
4441202379Srdivacky}
4442200583Srdivacky
4443202379Srdivackystatic void AddObjCInterfaceResults(const LangOptions &LangOpts,
4444202379Srdivacky                                    ResultBuilder &Results,
4445202379Srdivacky                                    bool NeedAt) {
4446212904Sdim  typedef CodeCompletionResult Result;
4447202379Srdivacky
4448202379Srdivacky  // Since we have an interface or protocol, we can end it.
4449239462Sdim  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end")));
4450202379Srdivacky
4451202379Srdivacky  if (LangOpts.ObjC2) {
4452202379Srdivacky    // @property
4453239462Sdim    Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"property")));
4454202379Srdivacky
4455200583Srdivacky    // @required
4456239462Sdim    Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"required")));
4457202379Srdivacky
4458200583Srdivacky    // @optional
4459239462Sdim    Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"optional")));
4460202379Srdivacky  }
4461202379Srdivacky}
4462200583Srdivacky
4463202379Srdivackystatic void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
4464212904Sdim  typedef CodeCompletionResult Result;
4465234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
4466234353Sdim                                Results.getCodeCompletionTUInfo());
4467202379Srdivacky
4468202379Srdivacky  // @class name ;
4469239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"class"));
4470218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4471218893Sdim  Builder.AddPlaceholderChunk("name");
4472218893Sdim  Results.AddResult(Result(Builder.TakeString()));
4473202379Srdivacky
4474210299Sed  if (Results.includeCodePatterns()) {
4475210299Sed    // @interface name
4476210299Sed    // FIXME: Could introduce the whole pattern, including superclasses and
4477210299Sed    // such.
4478239462Sdim    Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"interface"));
4479218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4480218893Sdim    Builder.AddPlaceholderChunk("class");
4481218893Sdim    Results.AddResult(Result(Builder.TakeString()));
4482202379Srdivacky
4483210299Sed    // @protocol name
4484239462Sdim    Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol"));
4485218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4486218893Sdim    Builder.AddPlaceholderChunk("protocol");
4487218893Sdim    Results.AddResult(Result(Builder.TakeString()));
4488210299Sed
4489210299Sed    // @implementation name
4490239462Sdim    Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"implementation"));
4491218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4492218893Sdim    Builder.AddPlaceholderChunk("class");
4493218893Sdim    Results.AddResult(Result(Builder.TakeString()));
4494210299Sed  }
4495202379Srdivacky
4496202379Srdivacky  // @compatibility_alias name
4497239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"compatibility_alias"));
4498218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4499218893Sdim  Builder.AddPlaceholderChunk("alias");
4500218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4501218893Sdim  Builder.AddPlaceholderChunk("class");
4502218893Sdim  Results.AddResult(Result(Builder.TakeString()));
4503249423Sdim
4504249423Sdim  if (Results.getSema().getLangOpts().Modules) {
4505249423Sdim    // @import name
4506249423Sdim    Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "import"));
4507249423Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4508249423Sdim    Builder.AddPlaceholderChunk("module");
4509249423Sdim    Results.AddResult(Result(Builder.TakeString()));
4510249423Sdim  }
4511202379Srdivacky}
4512200583Srdivacky
4513226633Sdimvoid Sema::CodeCompleteObjCAtDirective(Scope *S) {
4514218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4515234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4516218893Sdim                        CodeCompletionContext::CCC_Other);
4517202379Srdivacky  Results.EnterNewScope();
4518226633Sdim  if (isa<ObjCImplDecl>(CurContext))
4519234353Sdim    AddObjCImplementationResults(getLangOpts(), Results, false);
4520226633Sdim  else if (CurContext->isObjCContainer())
4521234353Sdim    AddObjCInterfaceResults(getLangOpts(), Results, false);
4522202379Srdivacky  else
4523202379Srdivacky    AddObjCTopLevelResults(Results, false);
4524200583Srdivacky  Results.ExitScope();
4525212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4526212904Sdim                            CodeCompletionContext::CCC_Other,
4527212904Sdim                            Results.data(),Results.size());
4528200583Srdivacky}
4529200583Srdivacky
4530202379Srdivackystatic void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
4531212904Sdim  typedef CodeCompletionResult Result;
4532234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
4533234353Sdim                                Results.getCodeCompletionTUInfo());
4534200583Srdivacky
4535200583Srdivacky  // @encode ( type-name )
4536234353Sdim  const char *EncodeType = "char[]";
4537234353Sdim  if (Results.getSema().getLangOpts().CPlusPlus ||
4538234353Sdim      Results.getSema().getLangOpts().ConstStrings)
4539239462Sdim    EncodeType = "const char[]";
4540234353Sdim  Builder.AddResultTypeChunk(EncodeType);
4541239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"encode"));
4542218893Sdim  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4543218893Sdim  Builder.AddPlaceholderChunk("type-name");
4544218893Sdim  Builder.AddChunk(CodeCompletionString::CK_RightParen);
4545218893Sdim  Results.AddResult(Result(Builder.TakeString()));
4546200583Srdivacky
4547200583Srdivacky  // @protocol ( protocol-name )
4548234353Sdim  Builder.AddResultTypeChunk("Protocol *");
4549239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol"));
4550218893Sdim  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4551218893Sdim  Builder.AddPlaceholderChunk("protocol-name");
4552218893Sdim  Builder.AddChunk(CodeCompletionString::CK_RightParen);
4553218893Sdim  Results.AddResult(Result(Builder.TakeString()));
4554200583Srdivacky
4555200583Srdivacky  // @selector ( selector )
4556234353Sdim  Builder.AddResultTypeChunk("SEL");
4557239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"selector"));
4558218893Sdim  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4559218893Sdim  Builder.AddPlaceholderChunk("selector");
4560218893Sdim  Builder.AddChunk(CodeCompletionString::CK_RightParen);
4561218893Sdim  Results.AddResult(Result(Builder.TakeString()));
4562239462Sdim
4563239462Sdim  // @"string"
4564239462Sdim  Builder.AddResultTypeChunk("NSString *");
4565239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"\""));
4566239462Sdim  Builder.AddPlaceholderChunk("string");
4567239462Sdim  Builder.AddTextChunk("\"");
4568239462Sdim  Results.AddResult(Result(Builder.TakeString()));
4569239462Sdim
4570239462Sdim  // @[objects, ...]
4571239462Sdim  Builder.AddResultTypeChunk("NSArray *");
4572239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"["));
4573234353Sdim  Builder.AddPlaceholderChunk("objects, ...");
4574234353Sdim  Builder.AddChunk(CodeCompletionString::CK_RightBracket);
4575234353Sdim  Results.AddResult(Result(Builder.TakeString()));
4576234353Sdim
4577239462Sdim  // @{key : object, ...}
4578239462Sdim  Builder.AddResultTypeChunk("NSDictionary *");
4579239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"{"));
4580234353Sdim  Builder.AddPlaceholderChunk("key");
4581234353Sdim  Builder.AddChunk(CodeCompletionString::CK_Colon);
4582234353Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4583234353Sdim  Builder.AddPlaceholderChunk("object, ...");
4584234353Sdim  Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4585234353Sdim  Results.AddResult(Result(Builder.TakeString()));
4586239462Sdim
4587239462Sdim  // @(expression)
4588239462Sdim  Builder.AddResultTypeChunk("id");
4589239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "("));
4590239462Sdim  Builder.AddPlaceholderChunk("expression");
4591239462Sdim  Builder.AddChunk(CodeCompletionString::CK_RightParen);
4592239462Sdim  Results.AddResult(Result(Builder.TakeString()));
4593200583Srdivacky}
4594200583Srdivacky
4595202379Srdivackystatic void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
4596212904Sdim  typedef CodeCompletionResult Result;
4597234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
4598234353Sdim                                Results.getCodeCompletionTUInfo());
4599202379Srdivacky
4600210299Sed  if (Results.includeCodePatterns()) {
4601210299Sed    // @try { statements } @catch ( declaration ) { statements } @finally
4602210299Sed    //   { statements }
4603239462Sdim    Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"try"));
4604218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4605218893Sdim    Builder.AddPlaceholderChunk("statements");
4606218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4607218893Sdim    Builder.AddTextChunk("@catch");
4608218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4609218893Sdim    Builder.AddPlaceholderChunk("parameter");
4610218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
4611218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4612218893Sdim    Builder.AddPlaceholderChunk("statements");
4613218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4614218893Sdim    Builder.AddTextChunk("@finally");
4615218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4616218893Sdim    Builder.AddPlaceholderChunk("statements");
4617218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4618218893Sdim    Results.AddResult(Result(Builder.TakeString()));
4619210299Sed  }
4620202379Srdivacky
4621200583Srdivacky  // @throw
4622239462Sdim  Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"throw"));
4623218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4624218893Sdim  Builder.AddPlaceholderChunk("expression");
4625218893Sdim  Results.AddResult(Result(Builder.TakeString()));
4626202379Srdivacky
4627210299Sed  if (Results.includeCodePatterns()) {
4628210299Sed    // @synchronized ( expression ) { statements }
4629239462Sdim    Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synchronized"));
4630218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4631218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4632218893Sdim    Builder.AddPlaceholderChunk("expression");
4633218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
4634218893Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4635218893Sdim    Builder.AddPlaceholderChunk("statements");
4636218893Sdim    Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4637218893Sdim    Results.AddResult(Result(Builder.TakeString()));
4638210299Sed  }
4639202379Srdivacky}
4640200583Srdivacky
4641202379Srdivackystatic void AddObjCVisibilityResults(const LangOptions &LangOpts,
4642202379Srdivacky                                     ResultBuilder &Results,
4643202379Srdivacky                                     bool NeedAt) {
4644212904Sdim  typedef CodeCompletionResult Result;
4645239462Sdim  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"private")));
4646239462Sdim  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"protected")));
4647239462Sdim  Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"public")));
4648202379Srdivacky  if (LangOpts.ObjC2)
4649239462Sdim    Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"package")));
4650202379Srdivacky}
4651202379Srdivacky
4652202379Srdivackyvoid Sema::CodeCompleteObjCAtVisibility(Scope *S) {
4653218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4654234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4655218893Sdim                        CodeCompletionContext::CCC_Other);
4656202379Srdivacky  Results.EnterNewScope();
4657234353Sdim  AddObjCVisibilityResults(getLangOpts(), Results, false);
4658200583Srdivacky  Results.ExitScope();
4659212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4660212904Sdim                            CodeCompletionContext::CCC_Other,
4661212904Sdim                            Results.data(),Results.size());
4662200583Srdivacky}
4663200583Srdivacky
4664202379Srdivackyvoid Sema::CodeCompleteObjCAtStatement(Scope *S) {
4665218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4666234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4667218893Sdim                        CodeCompletionContext::CCC_Other);
4668202379Srdivacky  Results.EnterNewScope();
4669202379Srdivacky  AddObjCStatementResults(Results, false);
4670202379Srdivacky  AddObjCExpressionResults(Results, false);
4671202379Srdivacky  Results.ExitScope();
4672212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4673212904Sdim                            CodeCompletionContext::CCC_Other,
4674212904Sdim                            Results.data(),Results.size());
4675202379Srdivacky}
4676202379Srdivacky
4677200583Srdivackyvoid Sema::CodeCompleteObjCAtExpression(Scope *S) {
4678218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4679234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4680218893Sdim                        CodeCompletionContext::CCC_Other);
4681200583Srdivacky  Results.EnterNewScope();
4682202379Srdivacky  AddObjCExpressionResults(Results, false);
4683200583Srdivacky  Results.ExitScope();
4684212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4685212904Sdim                            CodeCompletionContext::CCC_Other,
4686212904Sdim                            Results.data(),Results.size());
4687200583Srdivacky}
4688200583Srdivacky
4689199512Srdivacky/// \brief Determine whether the addition of the given flag to an Objective-C
4690199512Srdivacky/// property's attributes will cause a conflict.
4691199512Srdivackystatic bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
4692199512Srdivacky  // Check if we've already added this flag.
4693199512Srdivacky  if (Attributes & NewFlag)
4694199512Srdivacky    return true;
4695199512Srdivacky
4696199512Srdivacky  Attributes |= NewFlag;
4697199512Srdivacky
4698199512Srdivacky  // Check for collisions with "readonly".
4699199512Srdivacky  if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
4700243830Sdim      (Attributes & ObjCDeclSpec::DQ_PR_readwrite))
4701199512Srdivacky    return true;
4702199512Srdivacky
4703243830Sdim  // Check for more than one of { assign, copy, retain, strong, weak }.
4704199512Srdivacky  unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
4705224145Sdim                                         ObjCDeclSpec::DQ_PR_unsafe_unretained |
4706199512Srdivacky                                             ObjCDeclSpec::DQ_PR_copy |
4707243830Sdim                                             ObjCDeclSpec::DQ_PR_retain |
4708243830Sdim                                             ObjCDeclSpec::DQ_PR_strong |
4709243830Sdim                                             ObjCDeclSpec::DQ_PR_weak);
4710199512Srdivacky  if (AssignCopyRetMask &&
4711199512Srdivacky      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
4712224145Sdim      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained &&
4713199512Srdivacky      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
4714224145Sdim      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain &&
4715243830Sdim      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong &&
4716243830Sdim      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_weak)
4717199512Srdivacky    return true;
4718199512Srdivacky
4719199512Srdivacky  return false;
4720199512Srdivacky}
4721199512Srdivacky
4722199512Srdivackyvoid Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
4723198092Srdivacky  if (!CodeCompleter)
4724198092Srdivacky    return;
4725199512Srdivacky
4726198092Srdivacky  unsigned Attributes = ODS.getPropertyAttributes();
4727198092Srdivacky
4728218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4729234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4730218893Sdim                        CodeCompletionContext::CCC_Other);
4731198092Srdivacky  Results.EnterNewScope();
4732199512Srdivacky  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
4733212904Sdim    Results.AddResult(CodeCompletionResult("readonly"));
4734199512Srdivacky  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
4735212904Sdim    Results.AddResult(CodeCompletionResult("assign"));
4736224145Sdim  if (!ObjCPropertyFlagConflicts(Attributes,
4737224145Sdim                                 ObjCDeclSpec::DQ_PR_unsafe_unretained))
4738224145Sdim    Results.AddResult(CodeCompletionResult("unsafe_unretained"));
4739199512Srdivacky  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
4740212904Sdim    Results.AddResult(CodeCompletionResult("readwrite"));
4741199512Srdivacky  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
4742212904Sdim    Results.AddResult(CodeCompletionResult("retain"));
4743224145Sdim  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_strong))
4744224145Sdim    Results.AddResult(CodeCompletionResult("strong"));
4745199512Srdivacky  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
4746212904Sdim    Results.AddResult(CodeCompletionResult("copy"));
4747199512Srdivacky  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
4748212904Sdim    Results.AddResult(CodeCompletionResult("nonatomic"));
4749223017Sdim  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic))
4750223017Sdim    Results.AddResult(CodeCompletionResult("atomic"));
4751243830Sdim
4752243830Sdim  // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
4753243830Sdim  if (getLangOpts().ObjCARCWeak || getLangOpts().getGC() != LangOptions::NonGC)
4754243830Sdim    if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak))
4755243830Sdim      Results.AddResult(CodeCompletionResult("weak"));
4756243830Sdim
4757199512Srdivacky  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
4758234353Sdim    CodeCompletionBuilder Setter(Results.getAllocator(),
4759234353Sdim                                 Results.getCodeCompletionTUInfo());
4760218893Sdim    Setter.AddTypedTextChunk("setter");
4761218893Sdim    Setter.AddTextChunk(" = ");
4762218893Sdim    Setter.AddPlaceholderChunk("method");
4763218893Sdim    Results.AddResult(CodeCompletionResult(Setter.TakeString()));
4764199512Srdivacky  }
4765199512Srdivacky  if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
4766234353Sdim    CodeCompletionBuilder Getter(Results.getAllocator(),
4767234353Sdim                                 Results.getCodeCompletionTUInfo());
4768218893Sdim    Getter.AddTypedTextChunk("getter");
4769218893Sdim    Getter.AddTextChunk(" = ");
4770218893Sdim    Getter.AddPlaceholderChunk("method");
4771218893Sdim    Results.AddResult(CodeCompletionResult(Getter.TakeString()));
4772199512Srdivacky  }
4773198092Srdivacky  Results.ExitScope();
4774212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4775212904Sdim                            CodeCompletionContext::CCC_Other,
4776212904Sdim                            Results.data(),Results.size());
4777198092Srdivacky}
4778199482Srdivacky
4779239462Sdim/// \brief Describes the kind of Objective-C method that we want to find
4780199512Srdivacky/// via code completion.
4781199512Srdivackyenum ObjCMethodKind {
4782239462Sdim  MK_Any, ///< Any kind of method, provided it means other specified criteria.
4783239462Sdim  MK_ZeroArgSelector, ///< Zero-argument (unary) selector.
4784239462Sdim  MK_OneArgSelector ///< One-argument selector.
4785199512Srdivacky};
4786199512Srdivacky
4787212904Sdimstatic bool isAcceptableObjCSelector(Selector Sel,
4788212904Sdim                                     ObjCMethodKind WantKind,
4789212904Sdim                                     IdentifierInfo **SelIdents,
4790218893Sdim                                     unsigned NumSelIdents,
4791218893Sdim                                     bool AllowSameLength = true) {
4792199512Srdivacky  if (NumSelIdents > Sel.getNumArgs())
4793199512Srdivacky    return false;
4794212904Sdim
4795199512Srdivacky  switch (WantKind) {
4796212904Sdim    case MK_Any:             break;
4797212904Sdim    case MK_ZeroArgSelector: return Sel.isUnarySelector();
4798212904Sdim    case MK_OneArgSelector:  return Sel.getNumArgs() == 1;
4799199512Srdivacky  }
4800212904Sdim
4801218893Sdim  if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
4802218893Sdim    return false;
4803218893Sdim
4804199512Srdivacky  for (unsigned I = 0; I != NumSelIdents; ++I)
4805199512Srdivacky    if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
4806199512Srdivacky      return false;
4807212904Sdim
4808199512Srdivacky  return true;
4809199512Srdivacky}
4810212904Sdim
4811212904Sdimstatic bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
4812212904Sdim                                   ObjCMethodKind WantKind,
4813212904Sdim                                   IdentifierInfo **SelIdents,
4814218893Sdim                                   unsigned NumSelIdents,
4815218893Sdim                                   bool AllowSameLength = true) {
4816212904Sdim  return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
4817218893Sdim                                  NumSelIdents, AllowSameLength);
4818212904Sdim}
4819218893Sdim
4820218893Sdimnamespace {
4821218893Sdim  /// \brief A set of selectors, which is used to avoid introducing multiple
4822218893Sdim  /// completions with the same selector into the result set.
4823218893Sdim  typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
4824218893Sdim}
4825218893Sdim
4826199482Srdivacky/// \brief Add all of the Objective-C methods in the given Objective-C
4827199482Srdivacky/// container to the set of results.
4828199482Srdivacky///
4829199482Srdivacky/// The container will be a class, protocol, category, or implementation of
4830199482Srdivacky/// any of the above. This mether will recurse to include methods from
4831199482Srdivacky/// the superclasses of classes along with their categories, protocols, and
4832199482Srdivacky/// implementations.
4833199482Srdivacky///
4834199482Srdivacky/// \param Container the container in which we'll look to find methods.
4835199482Srdivacky///
4836239462Sdim/// \param WantInstanceMethods Whether to add instance methods (only); if
4837239462Sdim/// false, this routine will add factory methods (only).
4838199482Srdivacky///
4839199482Srdivacky/// \param CurContext the context in which we're performing the lookup that
4840199482Srdivacky/// finds methods.
4841199482Srdivacky///
4842218893Sdim/// \param AllowSameLength Whether we allow a method to be added to the list
4843218893Sdim/// when it has the same number of parameters as we have selector identifiers.
4844218893Sdim///
4845199482Srdivacky/// \param Results the structure into which we'll add results.
4846199482Srdivackystatic void AddObjCMethods(ObjCContainerDecl *Container,
4847199482Srdivacky                           bool WantInstanceMethods,
4848199512Srdivacky                           ObjCMethodKind WantKind,
4849199512Srdivacky                           IdentifierInfo **SelIdents,
4850199512Srdivacky                           unsigned NumSelIdents,
4851199482Srdivacky                           DeclContext *CurContext,
4852218893Sdim                           VisitedSelectorSet &Selectors,
4853218893Sdim                           bool AllowSameLength,
4854212904Sdim                           ResultBuilder &Results,
4855212904Sdim                           bool InOriginalClass = true) {
4856212904Sdim  typedef CodeCompletionResult Result;
4857239462Sdim  Container = getContainerDef(Container);
4858249423Sdim  ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
4859249423Sdim  bool isRootClass = IFace && !IFace->getSuperClass();
4860199482Srdivacky  for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
4861199482Srdivacky                                       MEnd = Container->meth_end();
4862199482Srdivacky       M != MEnd; ++M) {
4863249423Sdim    // The instance methods on the root class can be messaged via the
4864249423Sdim    // metaclass.
4865249423Sdim    if (M->isInstanceMethod() == WantInstanceMethods ||
4866249423Sdim        (isRootClass && !WantInstanceMethods)) {
4867199512Srdivacky      // Check whether the selector identifiers we've been given are a
4868199512Srdivacky      // subset of the identifiers for this particular method.
4869218893Sdim      if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents,
4870218893Sdim                                  AllowSameLength))
4871199512Srdivacky        continue;
4872199512Srdivacky
4873239462Sdim      if (!Selectors.insert(M->getSelector()))
4874218893Sdim        continue;
4875218893Sdim
4876249423Sdim      Result R = Result(*M, Results.getBasePriority(*M), 0);
4877199512Srdivacky      R.StartParameter = NumSelIdents;
4878199512Srdivacky      R.AllParametersAreInformative = (WantKind != MK_Any);
4879212904Sdim      if (!InOriginalClass)
4880212904Sdim        R.Priority += CCD_InBaseClass;
4881199512Srdivacky      Results.MaybeAddResult(R, CurContext);
4882199512Srdivacky    }
4883199482Srdivacky  }
4884199482Srdivacky
4885218893Sdim  // Visit the protocols of protocols.
4886218893Sdim  if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4887234353Sdim    if (Protocol->hasDefinition()) {
4888234353Sdim      const ObjCList<ObjCProtocolDecl> &Protocols
4889234353Sdim        = Protocol->getReferencedProtocols();
4890234353Sdim      for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4891234353Sdim                                                E = Protocols.end();
4892234353Sdim           I != E; ++I)
4893234353Sdim        AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
4894234353Sdim                       NumSelIdents, CurContext, Selectors, AllowSameLength,
4895234353Sdim                       Results, false);
4896234353Sdim    }
4897218893Sdim  }
4898218893Sdim
4899234353Sdim  if (!IFace || !IFace->hasDefinition())
4900199482Srdivacky    return;
4901199482Srdivacky
4902199482Srdivacky  // Add methods in protocols.
4903234353Sdim  for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
4904234353Sdim                                            E = IFace->protocol_end();
4905199482Srdivacky       I != E; ++I)
4906199512Srdivacky    AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
4907218893Sdim                   CurContext, Selectors, AllowSameLength, Results, false);
4908199482Srdivacky
4909199482Srdivacky  // Add methods in categories.
4910249423Sdim  for (ObjCInterfaceDecl::known_categories_iterator
4911249423Sdim         Cat = IFace->known_categories_begin(),
4912249423Sdim         CatEnd = IFace->known_categories_end();
4913249423Sdim       Cat != CatEnd; ++Cat) {
4914249423Sdim    ObjCCategoryDecl *CatDecl = *Cat;
4915249423Sdim
4916249423Sdim    AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
4917218893Sdim                   NumSelIdents, CurContext, Selectors, AllowSameLength,
4918218893Sdim                   Results, InOriginalClass);
4919199482Srdivacky
4920199482Srdivacky    // Add a categories protocol methods.
4921199482Srdivacky    const ObjCList<ObjCProtocolDecl> &Protocols
4922199482Srdivacky      = CatDecl->getReferencedProtocols();
4923199482Srdivacky    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
4924199482Srdivacky                                              E = Protocols.end();
4925199482Srdivacky         I != E; ++I)
4926199512Srdivacky      AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
4927218893Sdim                     NumSelIdents, CurContext, Selectors, AllowSameLength,
4928218893Sdim                     Results, false);
4929199482Srdivacky
4930199482Srdivacky    // Add methods in category implementations.
4931199482Srdivacky    if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
4932199512Srdivacky      AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
4933218893Sdim                     NumSelIdents, CurContext, Selectors, AllowSameLength,
4934218893Sdim                     Results, InOriginalClass);
4935199482Srdivacky  }
4936199482Srdivacky
4937199482Srdivacky  // Add methods in superclass.
4938199482Srdivacky  if (IFace->getSuperClass())
4939199512Srdivacky    AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
4940218893Sdim                   SelIdents, NumSelIdents, CurContext, Selectors,
4941218893Sdim                   AllowSameLength, Results, false);
4942199482Srdivacky
4943199482Srdivacky  // Add methods in our implementation, if any.
4944199482Srdivacky  if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4945199512Srdivacky    AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
4946218893Sdim                   NumSelIdents, CurContext, Selectors, AllowSameLength,
4947218893Sdim                   Results, InOriginalClass);
4948199482Srdivacky}
4949199482Srdivacky
4950199512Srdivacky
4951226633Sdimvoid Sema::CodeCompleteObjCPropertyGetter(Scope *S) {
4952199512Srdivacky  // Try to find the interface where getters might live.
4953226633Sdim  ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
4954199512Srdivacky  if (!Class) {
4955199512Srdivacky    if (ObjCCategoryDecl *Category
4956226633Sdim          = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
4957199512Srdivacky      Class = Category->getClassInterface();
4958199512Srdivacky
4959199512Srdivacky    if (!Class)
4960199512Srdivacky      return;
4961199512Srdivacky  }
4962199512Srdivacky
4963199512Srdivacky  // Find all of the potential getters.
4964218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4965234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4966218893Sdim                        CodeCompletionContext::CCC_Other);
4967199512Srdivacky  Results.EnterNewScope();
4968199512Srdivacky
4969218893Sdim  VisitedSelectorSet Selectors;
4970218893Sdim  AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors,
4971218893Sdim                 /*AllowSameLength=*/true, Results);
4972199512Srdivacky  Results.ExitScope();
4973212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
4974212904Sdim                            CodeCompletionContext::CCC_Other,
4975212904Sdim                            Results.data(),Results.size());
4976199512Srdivacky}
4977199512Srdivacky
4978226633Sdimvoid Sema::CodeCompleteObjCPropertySetter(Scope *S) {
4979199512Srdivacky  // Try to find the interface where setters might live.
4980199512Srdivacky  ObjCInterfaceDecl *Class
4981226633Sdim    = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
4982199512Srdivacky  if (!Class) {
4983199512Srdivacky    if (ObjCCategoryDecl *Category
4984226633Sdim          = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
4985199512Srdivacky      Class = Category->getClassInterface();
4986199512Srdivacky
4987199512Srdivacky    if (!Class)
4988199512Srdivacky      return;
4989199512Srdivacky  }
4990199512Srdivacky
4991199512Srdivacky  // Find all of the potential getters.
4992218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4993234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
4994218893Sdim                        CodeCompletionContext::CCC_Other);
4995199512Srdivacky  Results.EnterNewScope();
4996199512Srdivacky
4997218893Sdim  VisitedSelectorSet Selectors;
4998218893Sdim  AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext,
4999218893Sdim                 Selectors, /*AllowSameLength=*/true, Results);
5000199512Srdivacky
5001199512Srdivacky  Results.ExitScope();
5002212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5003212904Sdim                            CodeCompletionContext::CCC_Other,
5004212904Sdim                            Results.data(),Results.size());
5005199512Srdivacky}
5006199512Srdivacky
5007218893Sdimvoid Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
5008218893Sdim                                       bool IsParameter) {
5009218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5010234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5011218893Sdim                        CodeCompletionContext::CCC_Type);
5012212904Sdim  Results.EnterNewScope();
5013212904Sdim
5014212904Sdim  // Add context-sensitive, Objective-C parameter-passing keywords.
5015212904Sdim  bool AddedInOut = false;
5016212904Sdim  if ((DS.getObjCDeclQualifier() &
5017212904Sdim       (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
5018212904Sdim    Results.AddResult("in");
5019212904Sdim    Results.AddResult("inout");
5020212904Sdim    AddedInOut = true;
5021212904Sdim  }
5022212904Sdim  if ((DS.getObjCDeclQualifier() &
5023212904Sdim       (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
5024212904Sdim    Results.AddResult("out");
5025212904Sdim    if (!AddedInOut)
5026212904Sdim      Results.AddResult("inout");
5027212904Sdim  }
5028212904Sdim  if ((DS.getObjCDeclQualifier() &
5029212904Sdim       (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
5030212904Sdim        ObjCDeclSpec::DQ_Oneway)) == 0) {
5031212904Sdim     Results.AddResult("bycopy");
5032212904Sdim     Results.AddResult("byref");
5033212904Sdim     Results.AddResult("oneway");
5034212904Sdim  }
5035212904Sdim
5036218893Sdim  // If we're completing the return type of an Objective-C method and the
5037218893Sdim  // identifier IBAction refers to a macro, provide a completion item for
5038218893Sdim  // an action, e.g.,
5039218893Sdim  //   IBAction)<#selector#>:(id)sender
5040218893Sdim  if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
5041218893Sdim      Context.Idents.get("IBAction").hasMacroDefinition()) {
5042234353Sdim    CodeCompletionBuilder Builder(Results.getAllocator(),
5043234353Sdim                                  Results.getCodeCompletionTUInfo(),
5044234353Sdim                                  CCP_CodePattern, CXAvailability_Available);
5045218893Sdim    Builder.AddTypedTextChunk("IBAction");
5046234353Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
5047218893Sdim    Builder.AddPlaceholderChunk("selector");
5048234353Sdim    Builder.AddChunk(CodeCompletionString::CK_Colon);
5049234353Sdim    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5050218893Sdim    Builder.AddTextChunk("id");
5051234353Sdim    Builder.AddChunk(CodeCompletionString::CK_RightParen);
5052218893Sdim    Builder.AddTextChunk("sender");
5053218893Sdim    Results.AddResult(CodeCompletionResult(Builder.TakeString()));
5054218893Sdim  }
5055249423Sdim
5056249423Sdim  // If we're completing the return type, provide 'instancetype'.
5057249423Sdim  if (!IsParameter) {
5058249423Sdim    Results.AddResult(CodeCompletionResult("instancetype"));
5059249423Sdim  }
5060218893Sdim
5061212904Sdim  // Add various builtin type names and specifiers.
5062212904Sdim  AddOrdinaryNameResults(PCC_Type, S, *this, Results);
5063212904Sdim  Results.ExitScope();
5064212904Sdim
5065212904Sdim  // Add the various type names
5066212904Sdim  Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
5067212904Sdim  CodeCompletionDeclConsumer Consumer(Results, CurContext);
5068212904Sdim  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5069212904Sdim                     CodeCompleter->includeGlobals());
5070212904Sdim
5071212904Sdim  if (CodeCompleter->includeMacros())
5072243830Sdim    AddMacroResults(PP, Results, false);
5073212904Sdim
5074212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5075212904Sdim                            CodeCompletionContext::CCC_Type,
5076212904Sdim                            Results.data(), Results.size());
5077212904Sdim}
5078212904Sdim
5079207619Srdivacky/// \brief When we have an expression with type "id", we may assume
5080207619Srdivacky/// that it has some more-specific class type based on knowledge of
5081207619Srdivacky/// common uses of Objective-C. This routine returns that class type,
5082207619Srdivacky/// or NULL if no better result could be determined.
5083207619Srdivackystatic ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
5084218893Sdim  ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
5085207619Srdivacky  if (!Msg)
5086207619Srdivacky    return 0;
5087207619Srdivacky
5088207619Srdivacky  Selector Sel = Msg->getSelector();
5089207619Srdivacky  if (Sel.isNull())
5090207619Srdivacky    return 0;
5091207619Srdivacky
5092207619Srdivacky  IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
5093207619Srdivacky  if (!Id)
5094207619Srdivacky    return 0;
5095207619Srdivacky
5096207619Srdivacky  ObjCMethodDecl *Method = Msg->getMethodDecl();
5097207619Srdivacky  if (!Method)
5098207619Srdivacky    return 0;
5099207619Srdivacky
5100207619Srdivacky  // Determine the class that we're sending the message to.
5101207619Srdivacky  ObjCInterfaceDecl *IFace = 0;
5102207619Srdivacky  switch (Msg->getReceiverKind()) {
5103207619Srdivacky  case ObjCMessageExpr::Class:
5104208600Srdivacky    if (const ObjCObjectType *ObjType
5105208600Srdivacky                           = Msg->getClassReceiver()->getAs<ObjCObjectType>())
5106208600Srdivacky      IFace = ObjType->getInterface();
5107207619Srdivacky    break;
5108207619Srdivacky
5109207619Srdivacky  case ObjCMessageExpr::Instance: {
5110207619Srdivacky    QualType T = Msg->getInstanceReceiver()->getType();
5111207619Srdivacky    if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
5112207619Srdivacky      IFace = Ptr->getInterfaceDecl();
5113207619Srdivacky    break;
5114207619Srdivacky  }
5115207619Srdivacky
5116207619Srdivacky  case ObjCMessageExpr::SuperInstance:
5117207619Srdivacky  case ObjCMessageExpr::SuperClass:
5118207619Srdivacky    break;
5119207619Srdivacky  }
5120207619Srdivacky
5121207619Srdivacky  if (!IFace)
5122207619Srdivacky    return 0;
5123207619Srdivacky
5124207619Srdivacky  ObjCInterfaceDecl *Super = IFace->getSuperClass();
5125207619Srdivacky  if (Method->isInstanceMethod())
5126207619Srdivacky    return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
5127207619Srdivacky      .Case("retain", IFace)
5128224145Sdim      .Case("strong", IFace)
5129207619Srdivacky      .Case("autorelease", IFace)
5130207619Srdivacky      .Case("copy", IFace)
5131207619Srdivacky      .Case("copyWithZone", IFace)
5132207619Srdivacky      .Case("mutableCopy", IFace)
5133207619Srdivacky      .Case("mutableCopyWithZone", IFace)
5134207619Srdivacky      .Case("awakeFromCoder", IFace)
5135207619Srdivacky      .Case("replacementObjectFromCoder", IFace)
5136207619Srdivacky      .Case("class", IFace)
5137207619Srdivacky      .Case("classForCoder", IFace)
5138207619Srdivacky      .Case("superclass", Super)
5139207619Srdivacky      .Default(0);
5140207619Srdivacky
5141207619Srdivacky  return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
5142207619Srdivacky    .Case("new", IFace)
5143207619Srdivacky    .Case("alloc", IFace)
5144207619Srdivacky    .Case("allocWithZone", IFace)
5145207619Srdivacky    .Case("class", IFace)
5146207619Srdivacky    .Case("superclass", Super)
5147207619Srdivacky    .Default(0);
5148207619Srdivacky}
5149207619Srdivacky
5150212904Sdim// Add a special completion for a message send to "super", which fills in the
5151212904Sdim// most likely case of forwarding all of our arguments to the superclass
5152212904Sdim// function.
5153212904Sdim///
5154212904Sdim/// \param S The semantic analysis object.
5155212904Sdim///
5156243830Sdim/// \param NeedSuperKeyword Whether we need to prefix this completion with
5157212904Sdim/// the "super" keyword. Otherwise, we just need to provide the arguments.
5158212904Sdim///
5159212904Sdim/// \param SelIdents The identifiers in the selector that have already been
5160212904Sdim/// provided as arguments for a send to "super".
5161212904Sdim///
5162212904Sdim/// \param NumSelIdents The number of identifiers in \p SelIdents.
5163212904Sdim///
5164212904Sdim/// \param Results The set of results to augment.
5165212904Sdim///
5166212904Sdim/// \returns the Objective-C method declaration that would be invoked by
5167212904Sdim/// this "super" completion. If NULL, no completion was added.
5168212904Sdimstatic ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
5169212904Sdim                                              IdentifierInfo **SelIdents,
5170212904Sdim                                              unsigned NumSelIdents,
5171212904Sdim                                              ResultBuilder &Results) {
5172212904Sdim  ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
5173212904Sdim  if (!CurMethod)
5174212904Sdim    return 0;
5175212904Sdim
5176212904Sdim  ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
5177212904Sdim  if (!Class)
5178212904Sdim    return 0;
5179212904Sdim
5180212904Sdim  // Try to find a superclass method with the same selector.
5181212904Sdim  ObjCMethodDecl *SuperMethod = 0;
5182218893Sdim  while ((Class = Class->getSuperClass()) && !SuperMethod) {
5183218893Sdim    // Check in the class
5184212904Sdim    SuperMethod = Class->getMethod(CurMethod->getSelector(),
5185212904Sdim                                   CurMethod->isInstanceMethod());
5186212904Sdim
5187218893Sdim    // Check in categories or class extensions.
5188218893Sdim    if (!SuperMethod) {
5189249423Sdim      for (ObjCInterfaceDecl::known_categories_iterator
5190249423Sdim             Cat = Class->known_categories_begin(),
5191249423Sdim             CatEnd = Class->known_categories_end();
5192249423Sdim           Cat != CatEnd; ++Cat) {
5193249423Sdim        if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(),
5194218893Sdim                                               CurMethod->isInstanceMethod())))
5195218893Sdim          break;
5196249423Sdim      }
5197218893Sdim    }
5198218893Sdim  }
5199218893Sdim
5200212904Sdim  if (!SuperMethod)
5201212904Sdim    return 0;
5202212904Sdim
5203212904Sdim  // Check whether the superclass method has the same signature.
5204212904Sdim  if (CurMethod->param_size() != SuperMethod->param_size() ||
5205212904Sdim      CurMethod->isVariadic() != SuperMethod->isVariadic())
5206212904Sdim    return 0;
5207212904Sdim
5208212904Sdim  for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
5209212904Sdim                                   CurPEnd = CurMethod->param_end(),
5210212904Sdim                                    SuperP = SuperMethod->param_begin();
5211212904Sdim       CurP != CurPEnd; ++CurP, ++SuperP) {
5212212904Sdim    // Make sure the parameter types are compatible.
5213212904Sdim    if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
5214212904Sdim                                          (*SuperP)->getType()))
5215212904Sdim      return 0;
5216212904Sdim
5217212904Sdim    // Make sure we have a parameter name to forward!
5218212904Sdim    if (!(*CurP)->getIdentifier())
5219212904Sdim      return 0;
5220212904Sdim  }
5221212904Sdim
5222212904Sdim  // We have a superclass method. Now, form the send-to-super completion.
5223234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
5224234353Sdim                                Results.getCodeCompletionTUInfo());
5225212904Sdim
5226212904Sdim  // Give this completion a return type.
5227226633Sdim  AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod,
5228226633Sdim                     Builder);
5229212904Sdim
5230212904Sdim  // If we need the "super" keyword, add it (plus some spacing).
5231212904Sdim  if (NeedSuperKeyword) {
5232218893Sdim    Builder.AddTypedTextChunk("super");
5233218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5234212904Sdim  }
5235212904Sdim
5236212904Sdim  Selector Sel = CurMethod->getSelector();
5237212904Sdim  if (Sel.isUnarySelector()) {
5238212904Sdim    if (NeedSuperKeyword)
5239218893Sdim      Builder.AddTextChunk(Builder.getAllocator().CopyString(
5240218893Sdim                                  Sel.getNameForSlot(0)));
5241212904Sdim    else
5242218893Sdim      Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
5243218893Sdim                                   Sel.getNameForSlot(0)));
5244212904Sdim  } else {
5245212904Sdim    ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
5246212904Sdim    for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
5247212904Sdim      if (I > NumSelIdents)
5248218893Sdim        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5249212904Sdim
5250212904Sdim      if (I < NumSelIdents)
5251218893Sdim        Builder.AddInformativeChunk(
5252218893Sdim                   Builder.getAllocator().CopyString(
5253218893Sdim                                                 Sel.getNameForSlot(I) + ":"));
5254212904Sdim      else if (NeedSuperKeyword || I > NumSelIdents) {
5255218893Sdim        Builder.AddTextChunk(
5256218893Sdim                 Builder.getAllocator().CopyString(
5257218893Sdim                                                  Sel.getNameForSlot(I) + ":"));
5258218893Sdim        Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
5259218893Sdim                                         (*CurP)->getIdentifier()->getName()));
5260212904Sdim      } else {
5261218893Sdim        Builder.AddTypedTextChunk(
5262218893Sdim                  Builder.getAllocator().CopyString(
5263218893Sdim                                                  Sel.getNameForSlot(I) + ":"));
5264218893Sdim        Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
5265218893Sdim                                         (*CurP)->getIdentifier()->getName()));
5266212904Sdim      }
5267212904Sdim    }
5268212904Sdim  }
5269212904Sdim
5270234353Sdim  Results.AddResult(CodeCompletionResult(Builder.TakeString(), SuperMethod,
5271234353Sdim                                         CCP_SuperCompletion));
5272212904Sdim  return SuperMethod;
5273212904Sdim}
5274212904Sdim
5275210299Sedvoid Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
5276212904Sdim  typedef CodeCompletionResult Result;
5277218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5278234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5279218893Sdim                        CodeCompletionContext::CCC_ObjCMessageReceiver,
5280249423Sdim                        getLangOpts().CPlusPlus11
5281234353Sdim                          ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
5282234353Sdim                          : &ResultBuilder::IsObjCMessageReceiver);
5283210299Sed
5284210299Sed  CodeCompletionDeclConsumer Consumer(Results, CurContext);
5285210299Sed  Results.EnterNewScope();
5286212904Sdim  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5287212904Sdim                     CodeCompleter->includeGlobals());
5288210299Sed
5289210299Sed  // If we are in an Objective-C method inside a class that has a superclass,
5290210299Sed  // add "super" as an option.
5291210299Sed  if (ObjCMethodDecl *Method = getCurMethodDecl())
5292210299Sed    if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
5293212904Sdim      if (Iface->getSuperClass()) {
5294210299Sed        Results.AddResult(Result("super"));
5295212904Sdim
5296212904Sdim        AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
5297212904Sdim      }
5298210299Sed
5299249423Sdim  if (getLangOpts().CPlusPlus11)
5300234353Sdim    addThisCompletion(*this, Results);
5301234353Sdim
5302210299Sed  Results.ExitScope();
5303210299Sed
5304210299Sed  if (CodeCompleter->includeMacros())
5305243830Sdim    AddMacroResults(PP, Results, false);
5306218893Sdim  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5307212904Sdim                            Results.data(), Results.size());
5308210299Sed
5309210299Sed}
5310210299Sed
5311207619Srdivackyvoid Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
5312199512Srdivacky                                        IdentifierInfo **SelIdents,
5313218893Sdim                                        unsigned NumSelIdents,
5314218893Sdim                                        bool AtArgumentExpression) {
5315199482Srdivacky  ObjCInterfaceDecl *CDecl = 0;
5316207619Srdivacky  if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
5317207619Srdivacky    // Figure out which interface we're in.
5318207619Srdivacky    CDecl = CurMethod->getClassInterface();
5319207619Srdivacky    if (!CDecl)
5320207619Srdivacky      return;
5321207619Srdivacky
5322207619Srdivacky    // Find the superclass of this class.
5323207619Srdivacky    CDecl = CDecl->getSuperClass();
5324207619Srdivacky    if (!CDecl)
5325207619Srdivacky      return;
5326199482Srdivacky
5327207619Srdivacky    if (CurMethod->isInstanceMethod()) {
5328207619Srdivacky      // We are inside an instance method, which means that the message
5329207619Srdivacky      // send [super ...] is actually calling an instance method on the
5330218893Sdim      // current object.
5331218893Sdim      return CodeCompleteObjCInstanceMessage(S, 0,
5332212904Sdim                                             SelIdents, NumSelIdents,
5333218893Sdim                                             AtArgumentExpression,
5334218893Sdim                                             CDecl);
5335207619Srdivacky    }
5336199482Srdivacky
5337207619Srdivacky    // Fall through to send to the superclass in CDecl.
5338207619Srdivacky  } else {
5339207619Srdivacky    // "super" may be the name of a type or variable. Figure out which
5340207619Srdivacky    // it is.
5341249423Sdim    IdentifierInfo *Super = getSuperIdentifier();
5342207619Srdivacky    NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
5343207619Srdivacky                                     LookupOrdinaryName);
5344207619Srdivacky    if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
5345207619Srdivacky      // "super" names an interface. Use it.
5346207619Srdivacky    } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
5347208600Srdivacky      if (const ObjCObjectType *Iface
5348208600Srdivacky            = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
5349208600Srdivacky        CDecl = Iface->getInterface();
5350207619Srdivacky    } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
5351207619Srdivacky      // "super" names an unresolved type; we can't be more specific.
5352207619Srdivacky    } else {
5353207619Srdivacky      // Assume that "super" names some kind of value and parse that way.
5354207619Srdivacky      CXXScopeSpec SS;
5355234353Sdim      SourceLocation TemplateKWLoc;
5356207619Srdivacky      UnqualifiedId id;
5357207619Srdivacky      id.setIdentifier(Super, SuperLoc);
5358234353Sdim      ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id,
5359234353Sdim                                               false, false);
5360207619Srdivacky      return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
5361218893Sdim                                             SelIdents, NumSelIdents,
5362218893Sdim                                             AtArgumentExpression);
5363207619Srdivacky    }
5364199482Srdivacky
5365207619Srdivacky    // Fall through
5366199482Srdivacky  }
5367199482Srdivacky
5368212904Sdim  ParsedType Receiver;
5369207619Srdivacky  if (CDecl)
5370212904Sdim    Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
5371207619Srdivacky  return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
5372218893Sdim                                      NumSelIdents, AtArgumentExpression,
5373218893Sdim                                      /*IsSuper=*/true);
5374207619Srdivacky}
5375207619Srdivacky
5376218893Sdim/// \brief Given a set of code-completion results for the argument of a message
5377218893Sdim/// send, determine the preferred type (if any) for that argument expression.
5378218893Sdimstatic QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
5379218893Sdim                                                       unsigned NumSelIdents) {
5380218893Sdim  typedef CodeCompletionResult Result;
5381218893Sdim  ASTContext &Context = Results.getSema().Context;
5382218893Sdim
5383218893Sdim  QualType PreferredType;
5384218893Sdim  unsigned BestPriority = CCP_Unlikely * 2;
5385218893Sdim  Result *ResultsData = Results.data();
5386218893Sdim  for (unsigned I = 0, N = Results.size(); I != N; ++I) {
5387218893Sdim    Result &R = ResultsData[I];
5388218893Sdim    if (R.Kind == Result::RK_Declaration &&
5389218893Sdim        isa<ObjCMethodDecl>(R.Declaration)) {
5390218893Sdim      if (R.Priority <= BestPriority) {
5391249423Sdim        const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
5392218893Sdim        if (NumSelIdents <= Method->param_size()) {
5393218893Sdim          QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
5394218893Sdim                                       ->getType();
5395218893Sdim          if (R.Priority < BestPriority || PreferredType.isNull()) {
5396218893Sdim            BestPriority = R.Priority;
5397218893Sdim            PreferredType = MyPreferredType;
5398218893Sdim          } else if (!Context.hasSameUnqualifiedType(PreferredType,
5399218893Sdim                                                     MyPreferredType)) {
5400218893Sdim            PreferredType = QualType();
5401218893Sdim          }
5402218893Sdim        }
5403218893Sdim      }
5404218893Sdim    }
5405218893Sdim  }
5406218893Sdim
5407218893Sdim  return PreferredType;
5408212904Sdim}
5409212904Sdim
5410218893Sdimstatic void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
5411218893Sdim                                       ParsedType Receiver,
5412218893Sdim                                       IdentifierInfo **SelIdents,
5413218893Sdim                                       unsigned NumSelIdents,
5414218893Sdim                                       bool AtArgumentExpression,
5415218893Sdim                                       bool IsSuper,
5416218893Sdim                                       ResultBuilder &Results) {
5417212904Sdim  typedef CodeCompletionResult Result;
5418207619Srdivacky  ObjCInterfaceDecl *CDecl = 0;
5419218893Sdim
5420199482Srdivacky  // If the given name refers to an interface type, retrieve the
5421199482Srdivacky  // corresponding declaration.
5422207619Srdivacky  if (Receiver) {
5423218893Sdim    QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
5424207619Srdivacky    if (!T.isNull())
5425208600Srdivacky      if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
5426208600Srdivacky        CDecl = Interface->getInterface();
5427199482Srdivacky  }
5428218893Sdim
5429199482Srdivacky  // Add all of the factory methods in this Objective-C class, its protocols,
5430199482Srdivacky  // superclasses, categories, implementation, etc.
5431199482Srdivacky  Results.EnterNewScope();
5432218893Sdim
5433212904Sdim  // If this is a send-to-super, try to add the special "super" send
5434212904Sdim  // completion.
5435212904Sdim  if (IsSuper) {
5436212904Sdim    if (ObjCMethodDecl *SuperMethod
5437218893Sdim        = AddSuperSendCompletion(SemaRef, false, SelIdents, NumSelIdents,
5438218893Sdim                                 Results))
5439212904Sdim      Results.Ignore(SuperMethod);
5440212904Sdim  }
5441218893Sdim
5442212904Sdim  // If we're inside an Objective-C method definition, prefer its selector to
5443212904Sdim  // others.
5444218893Sdim  if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
5445212904Sdim    Results.setPreferredSelector(CurMethod->getSelector());
5446218893Sdim
5447218893Sdim  VisitedSelectorSet Selectors;
5448207619Srdivacky  if (CDecl)
5449218893Sdim    AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents,
5450218893Sdim                   SemaRef.CurContext, Selectors, AtArgumentExpression,
5451207619Srdivacky                   Results);
5452207619Srdivacky  else {
5453207619Srdivacky    // We're messaging "id" as a type; provide all class/factory methods.
5454218893Sdim
5455207619Srdivacky    // If we have an external source, load the entire class method
5456212904Sdim    // pool from the AST file.
5457243830Sdim    if (SemaRef.getExternalSource()) {
5458218893Sdim      for (uint32_t I = 0,
5459243830Sdim                    N = SemaRef.getExternalSource()->GetNumExternalSelectors();
5460210299Sed           I != N; ++I) {
5461243830Sdim        Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I);
5462218893Sdim        if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
5463207619Srdivacky          continue;
5464218893Sdim
5465218893Sdim        SemaRef.ReadMethodPool(Sel);
5466207619Srdivacky      }
5467207619Srdivacky    }
5468218893Sdim
5469218893Sdim    for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
5470218893Sdim                                       MEnd = SemaRef.MethodPool.end();
5471212904Sdim         M != MEnd; ++M) {
5472212904Sdim      for (ObjCMethodList *MethList = &M->second.second;
5473212904Sdim           MethList && MethList->Method;
5474251662Sdim           MethList = MethList->getNext()) {
5475207619Srdivacky        if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5476207619Srdivacky                                    NumSelIdents))
5477207619Srdivacky          continue;
5478218893Sdim
5479249423Sdim        Result R(MethList->Method, Results.getBasePriority(MethList->Method),0);
5480207619Srdivacky        R.StartParameter = NumSelIdents;
5481207619Srdivacky        R.AllParametersAreInformative = false;
5482218893Sdim        Results.MaybeAddResult(R, SemaRef.CurContext);
5483207619Srdivacky      }
5484207619Srdivacky    }
5485207619Srdivacky  }
5486218893Sdim
5487218893Sdim  Results.ExitScope();
5488218893Sdim}
5489207619Srdivacky
5490218893Sdimvoid Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
5491218893Sdim                                        IdentifierInfo **SelIdents,
5492218893Sdim                                        unsigned NumSelIdents,
5493218893Sdim                                        bool AtArgumentExpression,
5494218893Sdim                                        bool IsSuper) {
5495226633Sdim
5496226633Sdim  QualType T = this->GetTypeFromParser(Receiver);
5497226633Sdim
5498218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5499234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5500226633Sdim              CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage,
5501226633Sdim                                    T, SelIdents, NumSelIdents));
5502226633Sdim
5503218893Sdim  AddClassMessageCompletions(*this, S, Receiver, SelIdents, NumSelIdents,
5504218893Sdim                             AtArgumentExpression, IsSuper, Results);
5505218893Sdim
5506218893Sdim  // If we're actually at the argument expression (rather than prior to the
5507218893Sdim  // selector), we're actually performing code completion for an expression.
5508218893Sdim  // Determine whether we have a single, best method. If so, we can
5509218893Sdim  // code-complete the expression using the corresponding parameter type as
5510218893Sdim  // our preferred type, improving completion results.
5511218893Sdim  if (AtArgumentExpression) {
5512218893Sdim    QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
5513226633Sdim                                                                  NumSelIdents);
5514218893Sdim    if (PreferredType.isNull())
5515218893Sdim      CodeCompleteOrdinaryName(S, PCC_Expression);
5516218893Sdim    else
5517218893Sdim      CodeCompleteExpression(S, PreferredType);
5518218893Sdim    return;
5519218893Sdim  }
5520218893Sdim
5521212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5522226633Sdim                            Results.getCompletionContext(),
5523212904Sdim                            Results.data(), Results.size());
5524199482Srdivacky}
5525199482Srdivacky
5526226633Sdimvoid Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
5527199512Srdivacky                                           IdentifierInfo **SelIdents,
5528212904Sdim                                           unsigned NumSelIdents,
5529218893Sdim                                           bool AtArgumentExpression,
5530218893Sdim                                           ObjCInterfaceDecl *Super) {
5531212904Sdim  typedef CodeCompletionResult Result;
5532199482Srdivacky
5533199482Srdivacky  Expr *RecExpr = static_cast<Expr *>(Receiver);
5534199482Srdivacky
5535199482Srdivacky  // If necessary, apply function/array conversion to the receiver.
5536199482Srdivacky  // C99 6.7.5.3p[7,8].
5537221345Sdim  if (RecExpr) {
5538221345Sdim    ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr);
5539221345Sdim    if (Conv.isInvalid()) // conversion failed. bail.
5540221345Sdim      return;
5541221345Sdim    RecExpr = Conv.take();
5542221345Sdim  }
5543218893Sdim  QualType ReceiverType = RecExpr? RecExpr->getType()
5544218893Sdim                          : Super? Context.getObjCObjectPointerType(
5545218893Sdim                                            Context.getObjCInterfaceType(Super))
5546218893Sdim                                 : Context.getObjCIdType();
5547199482Srdivacky
5548218893Sdim  // If we're messaging an expression with type "id" or "Class", check
5549218893Sdim  // whether we know something special about the receiver that allows
5550218893Sdim  // us to assume a more-specific receiver type.
5551218893Sdim  if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
5552218893Sdim    if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
5553218893Sdim      if (ReceiverType->isObjCClassType())
5554218893Sdim        return CodeCompleteObjCClassMessage(S,
5555218893Sdim                       ParsedType::make(Context.getObjCInterfaceType(IFace)),
5556218893Sdim                                            SelIdents, NumSelIdents,
5557218893Sdim                                            AtArgumentExpression, Super);
5558218893Sdim
5559218893Sdim      ReceiverType = Context.getObjCObjectPointerType(
5560218893Sdim                                          Context.getObjCInterfaceType(IFace));
5561218893Sdim    }
5562218893Sdim
5563199482Srdivacky  // Build the set of methods we can see.
5564218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5565234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5566226633Sdim           CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
5567226633Sdim                                 ReceiverType, SelIdents, NumSelIdents));
5568226633Sdim
5569199482Srdivacky  Results.EnterNewScope();
5570207619Srdivacky
5571212904Sdim  // If this is a send-to-super, try to add the special "super" send
5572212904Sdim  // completion.
5573218893Sdim  if (Super) {
5574212904Sdim    if (ObjCMethodDecl *SuperMethod
5575212904Sdim          = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
5576212904Sdim                                   Results))
5577212904Sdim      Results.Ignore(SuperMethod);
5578212904Sdim  }
5579212904Sdim
5580212904Sdim  // If we're inside an Objective-C method definition, prefer its selector to
5581212904Sdim  // others.
5582212904Sdim  if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
5583212904Sdim    Results.setPreferredSelector(CurMethod->getSelector());
5584199482Srdivacky
5585218893Sdim  // Keep track of the selectors we've already added.
5586218893Sdim  VisitedSelectorSet Selectors;
5587218893Sdim
5588199482Srdivacky  // Handle messages to Class. This really isn't a message to an instance
5589199482Srdivacky  // method, so we treat it the same way we would treat a message send to a
5590199482Srdivacky  // class method.
5591199482Srdivacky  if (ReceiverType->isObjCClassType() ||
5592199482Srdivacky      ReceiverType->isObjCQualifiedClassType()) {
5593199482Srdivacky    if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
5594199482Srdivacky      if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
5595199512Srdivacky        AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
5596218893Sdim                       CurContext, Selectors, AtArgumentExpression, Results);
5597199482Srdivacky    }
5598199482Srdivacky  }
5599199482Srdivacky  // Handle messages to a qualified ID ("id<foo>").
5600199482Srdivacky  else if (const ObjCObjectPointerType *QualID
5601199482Srdivacky             = ReceiverType->getAsObjCQualifiedIdType()) {
5602199482Srdivacky    // Search protocols for instance methods.
5603199482Srdivacky    for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
5604199482Srdivacky                                              E = QualID->qual_end();
5605199482Srdivacky         I != E; ++I)
5606199512Srdivacky      AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
5607218893Sdim                     Selectors, AtArgumentExpression, Results);
5608199482Srdivacky  }
5609199482Srdivacky  // Handle messages to a pointer to interface type.
5610199482Srdivacky  else if (const ObjCObjectPointerType *IFacePtr
5611199482Srdivacky                              = ReceiverType->getAsObjCInterfacePointerType()) {
5612199482Srdivacky    // Search the class, its superclasses, etc., for instance methods.
5613199512Srdivacky    AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
5614218893Sdim                   NumSelIdents, CurContext, Selectors, AtArgumentExpression,
5615218893Sdim                   Results);
5616199482Srdivacky
5617199482Srdivacky    // Search protocols for instance methods.
5618199482Srdivacky    for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
5619199482Srdivacky         E = IFacePtr->qual_end();
5620199482Srdivacky         I != E; ++I)
5621199512Srdivacky      AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
5622218893Sdim                     Selectors, AtArgumentExpression, Results);
5623199482Srdivacky  }
5624207619Srdivacky  // Handle messages to "id".
5625207619Srdivacky  else if (ReceiverType->isObjCIdType()) {
5626207619Srdivacky    // We're messaging "id", so provide all instance methods we know
5627207619Srdivacky    // about as code-completion results.
5628207619Srdivacky
5629207619Srdivacky    // If we have an external source, load the entire class method
5630212904Sdim    // pool from the AST file.
5631207619Srdivacky    if (ExternalSource) {
5632210299Sed      for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5633210299Sed           I != N; ++I) {
5634210299Sed        Selector Sel = ExternalSource->GetExternalSelector(I);
5635212904Sdim        if (Sel.isNull() || MethodPool.count(Sel))
5636207619Srdivacky          continue;
5637207619Srdivacky
5638212904Sdim        ReadMethodPool(Sel);
5639207619Srdivacky      }
5640207619Srdivacky    }
5641207619Srdivacky
5642212904Sdim    for (GlobalMethodPool::iterator M = MethodPool.begin(),
5643212904Sdim                                    MEnd = MethodPool.end();
5644212904Sdim         M != MEnd; ++M) {
5645212904Sdim      for (ObjCMethodList *MethList = &M->second.first;
5646212904Sdim           MethList && MethList->Method;
5647251662Sdim           MethList = MethList->getNext()) {
5648207619Srdivacky        if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
5649207619Srdivacky                                    NumSelIdents))
5650207619Srdivacky          continue;
5651218893Sdim
5652218893Sdim        if (!Selectors.insert(MethList->Method->getSelector()))
5653218893Sdim          continue;
5654218893Sdim
5655249423Sdim        Result R(MethList->Method, Results.getBasePriority(MethList->Method),0);
5656207619Srdivacky        R.StartParameter = NumSelIdents;
5657207619Srdivacky        R.AllParametersAreInformative = false;
5658207619Srdivacky        Results.MaybeAddResult(R, CurContext);
5659207619Srdivacky      }
5660207619Srdivacky    }
5661207619Srdivacky  }
5662199482Srdivacky  Results.ExitScope();
5663218893Sdim
5664218893Sdim
5665218893Sdim  // If we're actually at the argument expression (rather than prior to the
5666218893Sdim  // selector), we're actually performing code completion for an expression.
5667218893Sdim  // Determine whether we have a single, best method. If so, we can
5668218893Sdim  // code-complete the expression using the corresponding parameter type as
5669218893Sdim  // our preferred type, improving completion results.
5670218893Sdim  if (AtArgumentExpression) {
5671218893Sdim    QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
5672218893Sdim                                                                  NumSelIdents);
5673218893Sdim    if (PreferredType.isNull())
5674218893Sdim      CodeCompleteOrdinaryName(S, PCC_Expression);
5675218893Sdim    else
5676218893Sdim      CodeCompleteExpression(S, PreferredType);
5677218893Sdim    return;
5678218893Sdim  }
5679218893Sdim
5680212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5681226633Sdim                            Results.getCompletionContext(),
5682212904Sdim                            Results.data(),Results.size());
5683199482Srdivacky}
5684199482Srdivacky
5685212904Sdimvoid Sema::CodeCompleteObjCForCollection(Scope *S,
5686212904Sdim                                         DeclGroupPtrTy IterationVar) {
5687212904Sdim  CodeCompleteExpressionData Data;
5688212904Sdim  Data.ObjCCollection = true;
5689212904Sdim
5690212904Sdim  if (IterationVar.getAsOpaquePtr()) {
5691212904Sdim    DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
5692212904Sdim    for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
5693212904Sdim      if (*I)
5694212904Sdim        Data.IgnoreDecls.push_back(*I);
5695212904Sdim    }
5696212904Sdim  }
5697212904Sdim
5698212904Sdim  CodeCompleteExpression(S, Data);
5699212904Sdim}
5700212904Sdim
5701212904Sdimvoid Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
5702212904Sdim                                    unsigned NumSelIdents) {
5703212904Sdim  // If we have an external source, load the entire class method
5704212904Sdim  // pool from the AST file.
5705212904Sdim  if (ExternalSource) {
5706212904Sdim    for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5707212904Sdim         I != N; ++I) {
5708212904Sdim      Selector Sel = ExternalSource->GetExternalSelector(I);
5709212904Sdim      if (Sel.isNull() || MethodPool.count(Sel))
5710212904Sdim        continue;
5711212904Sdim
5712212904Sdim      ReadMethodPool(Sel);
5713212904Sdim    }
5714212904Sdim  }
5715212904Sdim
5716218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5717234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5718218893Sdim                        CodeCompletionContext::CCC_SelectorName);
5719212904Sdim  Results.EnterNewScope();
5720212904Sdim  for (GlobalMethodPool::iterator M = MethodPool.begin(),
5721212904Sdim                               MEnd = MethodPool.end();
5722212904Sdim       M != MEnd; ++M) {
5723212904Sdim
5724212904Sdim    Selector Sel = M->first;
5725212904Sdim    if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
5726212904Sdim      continue;
5727212904Sdim
5728234353Sdim    CodeCompletionBuilder Builder(Results.getAllocator(),
5729234353Sdim                                  Results.getCodeCompletionTUInfo());
5730212904Sdim    if (Sel.isUnarySelector()) {
5731218893Sdim      Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
5732218893Sdim                                                       Sel.getNameForSlot(0)));
5733218893Sdim      Results.AddResult(Builder.TakeString());
5734212904Sdim      continue;
5735212904Sdim    }
5736212904Sdim
5737212904Sdim    std::string Accumulator;
5738212904Sdim    for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
5739212904Sdim      if (I == NumSelIdents) {
5740212904Sdim        if (!Accumulator.empty()) {
5741218893Sdim          Builder.AddInformativeChunk(Builder.getAllocator().CopyString(
5742218893Sdim                                                 Accumulator));
5743212904Sdim          Accumulator.clear();
5744212904Sdim        }
5745212904Sdim      }
5746212904Sdim
5747226633Sdim      Accumulator += Sel.getNameForSlot(I);
5748212904Sdim      Accumulator += ':';
5749212904Sdim    }
5750218893Sdim    Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( Accumulator));
5751218893Sdim    Results.AddResult(Builder.TakeString());
5752212904Sdim  }
5753212904Sdim  Results.ExitScope();
5754212904Sdim
5755212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5756212904Sdim                            CodeCompletionContext::CCC_SelectorName,
5757212904Sdim                            Results.data(), Results.size());
5758212904Sdim}
5759212904Sdim
5760199482Srdivacky/// \brief Add all of the protocol declarations that we find in the given
5761199482Srdivacky/// (translation unit) context.
5762199482Srdivackystatic void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
5763199482Srdivacky                               bool OnlyForwardDeclarations,
5764199482Srdivacky                               ResultBuilder &Results) {
5765212904Sdim  typedef CodeCompletionResult Result;
5766199482Srdivacky
5767199482Srdivacky  for (DeclContext::decl_iterator D = Ctx->decls_begin(),
5768199482Srdivacky                               DEnd = Ctx->decls_end();
5769199482Srdivacky       D != DEnd; ++D) {
5770199482Srdivacky    // Record any protocols we find.
5771199482Srdivacky    if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
5772234353Sdim      if (!OnlyForwardDeclarations || !Proto->hasDefinition())
5773249423Sdim        Results.AddResult(Result(Proto, Results.getBasePriority(Proto), 0),
5774249423Sdim                          CurContext, 0, false);
5775199482Srdivacky  }
5776199482Srdivacky}
5777199482Srdivacky
5778199482Srdivackyvoid Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
5779199482Srdivacky                                              unsigned NumProtocols) {
5780218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5781234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5782218893Sdim                        CodeCompletionContext::CCC_ObjCProtocolName);
5783199482Srdivacky
5784218893Sdim  if (CodeCompleter && CodeCompleter->includeGlobals()) {
5785218893Sdim    Results.EnterNewScope();
5786218893Sdim
5787218893Sdim    // Tell the result set to ignore all of the protocols we have
5788218893Sdim    // already seen.
5789218893Sdim    // FIXME: This doesn't work when caching code-completion results.
5790218893Sdim    for (unsigned I = 0; I != NumProtocols; ++I)
5791218893Sdim      if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
5792218893Sdim                                                      Protocols[I].second))
5793218893Sdim        Results.Ignore(Protocol);
5794199482Srdivacky
5795218893Sdim    // Add all protocols.
5796218893Sdim    AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
5797218893Sdim                       Results);
5798199482Srdivacky
5799218893Sdim    Results.ExitScope();
5800218893Sdim  }
5801218893Sdim
5802212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5803212904Sdim                            CodeCompletionContext::CCC_ObjCProtocolName,
5804212904Sdim                            Results.data(),Results.size());
5805199482Srdivacky}
5806199482Srdivacky
5807199482Srdivackyvoid Sema::CodeCompleteObjCProtocolDecl(Scope *) {
5808218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5809234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5810218893Sdim                        CodeCompletionContext::CCC_ObjCProtocolName);
5811199482Srdivacky
5812218893Sdim  if (CodeCompleter && CodeCompleter->includeGlobals()) {
5813218893Sdim    Results.EnterNewScope();
5814218893Sdim
5815218893Sdim    // Add all protocols.
5816218893Sdim    AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
5817218893Sdim                       Results);
5818199482Srdivacky
5819218893Sdim    Results.ExitScope();
5820218893Sdim  }
5821218893Sdim
5822212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5823212904Sdim                            CodeCompletionContext::CCC_ObjCProtocolName,
5824212904Sdim                            Results.data(),Results.size());
5825199482Srdivacky}
5826199512Srdivacky
5827199512Srdivacky/// \brief Add all of the Objective-C interface declarations that we find in
5828199512Srdivacky/// the given (translation unit) context.
5829199512Srdivackystatic void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
5830199512Srdivacky                                bool OnlyForwardDeclarations,
5831199512Srdivacky                                bool OnlyUnimplemented,
5832199512Srdivacky                                ResultBuilder &Results) {
5833212904Sdim  typedef CodeCompletionResult Result;
5834199512Srdivacky
5835199512Srdivacky  for (DeclContext::decl_iterator D = Ctx->decls_begin(),
5836199512Srdivacky                               DEnd = Ctx->decls_end();
5837199512Srdivacky       D != DEnd; ++D) {
5838199512Srdivacky    // Record any interfaces we find.
5839199512Srdivacky    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
5840234353Sdim      if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
5841199512Srdivacky          (!OnlyUnimplemented || !Class->getImplementation()))
5842249423Sdim        Results.AddResult(Result(Class, Results.getBasePriority(Class), 0),
5843249423Sdim                          CurContext, 0, false);
5844199512Srdivacky  }
5845199512Srdivacky}
5846199512Srdivacky
5847199512Srdivackyvoid Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
5848218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5849234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5850218893Sdim                        CodeCompletionContext::CCC_Other);
5851199512Srdivacky  Results.EnterNewScope();
5852199512Srdivacky
5853226633Sdim  if (CodeCompleter->includeGlobals()) {
5854226633Sdim    // Add all classes.
5855226633Sdim    AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5856226633Sdim                        false, Results);
5857226633Sdim  }
5858226633Sdim
5859226633Sdim  Results.ExitScope();
5860199512Srdivacky
5861212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5862226633Sdim                            CodeCompletionContext::CCC_ObjCInterfaceName,
5863212904Sdim                            Results.data(),Results.size());
5864199512Srdivacky}
5865199512Srdivacky
5866207619Srdivackyvoid Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
5867207619Srdivacky                                      SourceLocation ClassNameLoc) {
5868218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5869234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5870226633Sdim                        CodeCompletionContext::CCC_ObjCInterfaceName);
5871199512Srdivacky  Results.EnterNewScope();
5872199512Srdivacky
5873199512Srdivacky  // Make sure that we ignore the class we're currently defining.
5874199512Srdivacky  NamedDecl *CurClass
5875207619Srdivacky    = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
5876199512Srdivacky  if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
5877199512Srdivacky    Results.Ignore(CurClass);
5878199512Srdivacky
5879226633Sdim  if (CodeCompleter->includeGlobals()) {
5880226633Sdim    // Add all classes.
5881226633Sdim    AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5882226633Sdim                        false, Results);
5883226633Sdim  }
5884226633Sdim
5885226633Sdim  Results.ExitScope();
5886199512Srdivacky
5887212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5888226633Sdim                            CodeCompletionContext::CCC_ObjCInterfaceName,
5889212904Sdim                            Results.data(),Results.size());
5890199512Srdivacky}
5891199512Srdivacky
5892199512Srdivackyvoid Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
5893218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5894234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5895218893Sdim                        CodeCompletionContext::CCC_Other);
5896199512Srdivacky  Results.EnterNewScope();
5897199512Srdivacky
5898226633Sdim  if (CodeCompleter->includeGlobals()) {
5899226633Sdim    // Add all unimplemented classes.
5900226633Sdim    AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
5901226633Sdim                        true, Results);
5902226633Sdim  }
5903226633Sdim
5904226633Sdim  Results.ExitScope();
5905199512Srdivacky
5906212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5907226633Sdim                            CodeCompletionContext::CCC_ObjCInterfaceName,
5908212904Sdim                            Results.data(),Results.size());
5909199512Srdivacky}
5910199512Srdivacky
5911199512Srdivackyvoid Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
5912207619Srdivacky                                             IdentifierInfo *ClassName,
5913207619Srdivacky                                             SourceLocation ClassNameLoc) {
5914212904Sdim  typedef CodeCompletionResult Result;
5915199512Srdivacky
5916218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5917234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5918224145Sdim                        CodeCompletionContext::CCC_ObjCCategoryName);
5919199512Srdivacky
5920199512Srdivacky  // Ignore any categories we find that have already been implemented by this
5921199512Srdivacky  // interface.
5922199512Srdivacky  llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5923199512Srdivacky  NamedDecl *CurClass
5924207619Srdivacky    = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
5925249423Sdim  if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)){
5926249423Sdim    for (ObjCInterfaceDecl::visible_categories_iterator
5927249423Sdim           Cat = Class->visible_categories_begin(),
5928249423Sdim           CatEnd = Class->visible_categories_end();
5929249423Sdim         Cat != CatEnd; ++Cat) {
5930249423Sdim      CategoryNames.insert(Cat->getIdentifier());
5931249423Sdim    }
5932249423Sdim  }
5933249423Sdim
5934199512Srdivacky  // Add all of the categories we know about.
5935199512Srdivacky  Results.EnterNewScope();
5936199512Srdivacky  TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
5937199512Srdivacky  for (DeclContext::decl_iterator D = TU->decls_begin(),
5938199512Srdivacky                               DEnd = TU->decls_end();
5939199512Srdivacky       D != DEnd; ++D)
5940199512Srdivacky    if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
5941199512Srdivacky      if (CategoryNames.insert(Category->getIdentifier()))
5942249423Sdim        Results.AddResult(Result(Category, Results.getBasePriority(Category),0),
5943249423Sdim                          CurContext, 0, false);
5944199512Srdivacky  Results.ExitScope();
5945199512Srdivacky
5946212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5947224145Sdim                            CodeCompletionContext::CCC_ObjCCategoryName,
5948212904Sdim                            Results.data(),Results.size());
5949199512Srdivacky}
5950199512Srdivacky
5951199512Srdivackyvoid Sema::CodeCompleteObjCImplementationCategory(Scope *S,
5952207619Srdivacky                                                  IdentifierInfo *ClassName,
5953207619Srdivacky                                                  SourceLocation ClassNameLoc) {
5954212904Sdim  typedef CodeCompletionResult Result;
5955199512Srdivacky
5956199512Srdivacky  // Find the corresponding interface. If we couldn't find the interface, the
5957199512Srdivacky  // program itself is ill-formed. However, we'll try to be helpful still by
5958199512Srdivacky  // providing the list of all of the categories we know about.
5959199512Srdivacky  NamedDecl *CurClass
5960207619Srdivacky    = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
5961199512Srdivacky  ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
5962199512Srdivacky  if (!Class)
5963207619Srdivacky    return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
5964199512Srdivacky
5965218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5966234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5967224145Sdim                        CodeCompletionContext::CCC_ObjCCategoryName);
5968199512Srdivacky
5969199512Srdivacky  // Add all of the categories that have have corresponding interface
5970199512Srdivacky  // declarations in this class and any of its superclasses, except for
5971199512Srdivacky  // already-implemented categories in the class itself.
5972199512Srdivacky  llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
5973199512Srdivacky  Results.EnterNewScope();
5974199512Srdivacky  bool IgnoreImplemented = true;
5975199512Srdivacky  while (Class) {
5976249423Sdim    for (ObjCInterfaceDecl::visible_categories_iterator
5977249423Sdim           Cat = Class->visible_categories_begin(),
5978249423Sdim           CatEnd = Class->visible_categories_end();
5979249423Sdim         Cat != CatEnd; ++Cat) {
5980249423Sdim      if ((!IgnoreImplemented || !Cat->getImplementation()) &&
5981249423Sdim          CategoryNames.insert(Cat->getIdentifier()))
5982249423Sdim        Results.AddResult(Result(*Cat, Results.getBasePriority(*Cat), 0),
5983249423Sdim                          CurContext, 0, false);
5984249423Sdim    }
5985199512Srdivacky
5986199512Srdivacky    Class = Class->getSuperClass();
5987199512Srdivacky    IgnoreImplemented = false;
5988199512Srdivacky  }
5989199512Srdivacky  Results.ExitScope();
5990199512Srdivacky
5991212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
5992224145Sdim                            CodeCompletionContext::CCC_ObjCCategoryName,
5993212904Sdim                            Results.data(),Results.size());
5994199512Srdivacky}
5995199512Srdivacky
5996226633Sdimvoid Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
5997218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5998234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
5999218893Sdim                        CodeCompletionContext::CCC_Other);
6000199512Srdivacky
6001199512Srdivacky  // Figure out where this @synthesize lives.
6002199512Srdivacky  ObjCContainerDecl *Container
6003226633Sdim    = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
6004199512Srdivacky  if (!Container ||
6005199512Srdivacky      (!isa<ObjCImplementationDecl>(Container) &&
6006199512Srdivacky       !isa<ObjCCategoryImplDecl>(Container)))
6007199512Srdivacky    return;
6008199512Srdivacky
6009199512Srdivacky  // Ignore any properties that have already been implemented.
6010239462Sdim  Container = getContainerDef(Container);
6011239462Sdim  for (DeclContext::decl_iterator D = Container->decls_begin(),
6012199512Srdivacky                               DEnd = Container->decls_end();
6013199512Srdivacky       D != DEnd; ++D)
6014199512Srdivacky    if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
6015199512Srdivacky      Results.Ignore(PropertyImpl->getPropertyDecl());
6016199512Srdivacky
6017199512Srdivacky  // Add any properties that we find.
6018218893Sdim  AddedPropertiesSet AddedProperties;
6019199512Srdivacky  Results.EnterNewScope();
6020199512Srdivacky  if (ObjCImplementationDecl *ClassImpl
6021199512Srdivacky        = dyn_cast<ObjCImplementationDecl>(Container))
6022223017Sdim    AddObjCProperties(ClassImpl->getClassInterface(), false,
6023223017Sdim                      /*AllowNullaryMethods=*/false, CurContext,
6024218893Sdim                      AddedProperties, Results);
6025199512Srdivacky  else
6026199512Srdivacky    AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
6027223017Sdim                      false, /*AllowNullaryMethods=*/false, CurContext,
6028223017Sdim                      AddedProperties, Results);
6029199512Srdivacky  Results.ExitScope();
6030199512Srdivacky
6031212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
6032212904Sdim                            CodeCompletionContext::CCC_Other,
6033212904Sdim                            Results.data(),Results.size());
6034199512Srdivacky}
6035199512Srdivacky
6036199512Srdivackyvoid Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
6037226633Sdim                                                  IdentifierInfo *PropertyName) {
6038212904Sdim  typedef CodeCompletionResult Result;
6039218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6040234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
6041218893Sdim                        CodeCompletionContext::CCC_Other);
6042199512Srdivacky
6043199512Srdivacky  // Figure out where this @synthesize lives.
6044199512Srdivacky  ObjCContainerDecl *Container
6045226633Sdim    = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
6046199512Srdivacky  if (!Container ||
6047199512Srdivacky      (!isa<ObjCImplementationDecl>(Container) &&
6048199512Srdivacky       !isa<ObjCCategoryImplDecl>(Container)))
6049199512Srdivacky    return;
6050199512Srdivacky
6051199512Srdivacky  // Figure out which interface we're looking into.
6052199512Srdivacky  ObjCInterfaceDecl *Class = 0;
6053199512Srdivacky  if (ObjCImplementationDecl *ClassImpl
6054199512Srdivacky                                 = dyn_cast<ObjCImplementationDecl>(Container))
6055199512Srdivacky    Class = ClassImpl->getClassInterface();
6056199512Srdivacky  else
6057199512Srdivacky    Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
6058199512Srdivacky                                                          ->getClassInterface();
6059199512Srdivacky
6060221345Sdim  // Determine the type of the property we're synthesizing.
6061221345Sdim  QualType PropertyType = Context.getObjCIdType();
6062221345Sdim  if (Class) {
6063221345Sdim    if (ObjCPropertyDecl *Property
6064221345Sdim                              = Class->FindPropertyDeclaration(PropertyName)) {
6065221345Sdim      PropertyType
6066221345Sdim        = Property->getType().getNonReferenceType().getUnqualifiedType();
6067221345Sdim
6068221345Sdim      // Give preference to ivars
6069221345Sdim      Results.setPreferredType(PropertyType);
6070221345Sdim    }
6071221345Sdim  }
6072221345Sdim
6073199512Srdivacky  // Add all of the instance variables in this class and its superclasses.
6074199512Srdivacky  Results.EnterNewScope();
6075221345Sdim  bool SawSimilarlyNamedIvar = false;
6076221345Sdim  std::string NameWithPrefix;
6077221345Sdim  NameWithPrefix += '_';
6078226633Sdim  NameWithPrefix += PropertyName->getName();
6079221345Sdim  std::string NameWithSuffix = PropertyName->getName().str();
6080221345Sdim  NameWithSuffix += '_';
6081199512Srdivacky  for(; Class; Class = Class->getSuperClass()) {
6082221345Sdim    for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar;
6083221345Sdim         Ivar = Ivar->getNextIvar()) {
6084249423Sdim      Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), 0),
6085249423Sdim                        CurContext, 0, false);
6086221345Sdim
6087221345Sdim      // Determine whether we've seen an ivar with a name similar to the
6088221345Sdim      // property.
6089221345Sdim      if ((PropertyName == Ivar->getIdentifier() ||
6090221345Sdim           NameWithPrefix == Ivar->getName() ||
6091221345Sdim           NameWithSuffix == Ivar->getName())) {
6092221345Sdim        SawSimilarlyNamedIvar = true;
6093221345Sdim
6094221345Sdim        // Reduce the priority of this result by one, to give it a slight
6095221345Sdim        // advantage over other results whose names don't match so closely.
6096221345Sdim        if (Results.size() &&
6097221345Sdim            Results.data()[Results.size() - 1].Kind
6098221345Sdim                                      == CodeCompletionResult::RK_Declaration &&
6099221345Sdim            Results.data()[Results.size() - 1].Declaration == Ivar)
6100221345Sdim          Results.data()[Results.size() - 1].Priority--;
6101221345Sdim      }
6102221345Sdim    }
6103199512Srdivacky  }
6104221345Sdim
6105221345Sdim  if (!SawSimilarlyNamedIvar) {
6106221345Sdim    // Create ivar result _propName, that the user can use to synthesize
6107221345Sdim    // an ivar of the appropriate type.
6108221345Sdim    unsigned Priority = CCP_MemberDeclaration + 1;
6109221345Sdim    typedef CodeCompletionResult Result;
6110221345Sdim    CodeCompletionAllocator &Allocator = Results.getAllocator();
6111234353Sdim    CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(),
6112234353Sdim                                  Priority,CXAvailability_Available);
6113221345Sdim
6114226633Sdim    PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
6115221345Sdim    Builder.AddResultTypeChunk(GetCompletionTypeString(PropertyType, Context,
6116226633Sdim                                                       Policy, Allocator));
6117221345Sdim    Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix));
6118221345Sdim    Results.AddResult(Result(Builder.TakeString(), Priority,
6119221345Sdim                             CXCursor_ObjCIvarDecl));
6120221345Sdim  }
6121221345Sdim
6122199512Srdivacky  Results.ExitScope();
6123199512Srdivacky
6124212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
6125212904Sdim                            CodeCompletionContext::CCC_Other,
6126212904Sdim                            Results.data(),Results.size());
6127199512Srdivacky}
6128207619Srdivacky
6129212904Sdim// Mapping from selectors to the methods that implement that selector, along
6130212904Sdim// with the "in original class" flag.
6131212904Sdimtypedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
6132212904Sdim  KnownMethodsMap;
6133207619Srdivacky
6134207619Srdivacky/// \brief Find all of the methods that reside in the given container
6135207619Srdivacky/// (and its superclasses, protocols, etc.) that meet the given
6136207619Srdivacky/// criteria. Insert those methods into the map of known methods,
6137207619Srdivacky/// indexed by selector so they can be easily found.
6138207619Srdivackystatic void FindImplementableMethods(ASTContext &Context,
6139207619Srdivacky                                     ObjCContainerDecl *Container,
6140207619Srdivacky                                     bool WantInstanceMethods,
6141207619Srdivacky                                     QualType ReturnType,
6142212904Sdim                                     KnownMethodsMap &KnownMethods,
6143212904Sdim                                     bool InOriginalClass = true) {
6144207619Srdivacky  if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
6145239462Sdim    // Make sure we have a definition; that's what we'll walk.
6146234353Sdim    if (!IFace->hasDefinition())
6147234353Sdim      return;
6148239462Sdim
6149239462Sdim    IFace = IFace->getDefinition();
6150239462Sdim    Container = IFace;
6151234353Sdim
6152207619Srdivacky    const ObjCList<ObjCProtocolDecl> &Protocols
6153207619Srdivacky      = IFace->getReferencedProtocols();
6154207619Srdivacky    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6155218893Sdim                                              E = Protocols.end();
6156207619Srdivacky         I != E; ++I)
6157207619Srdivacky      FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6158218893Sdim                               KnownMethods, InOriginalClass);
6159207619Srdivacky
6160218893Sdim    // Add methods from any class extensions and categories.
6161249423Sdim    for (ObjCInterfaceDecl::visible_categories_iterator
6162249423Sdim           Cat = IFace->visible_categories_begin(),
6163249423Sdim           CatEnd = IFace->visible_categories_end();
6164249423Sdim         Cat != CatEnd; ++Cat) {
6165249423Sdim      FindImplementableMethods(Context, *Cat, WantInstanceMethods, ReturnType,
6166218893Sdim                               KnownMethods, false);
6167249423Sdim    }
6168249423Sdim
6169218893Sdim    // Visit the superclass.
6170218893Sdim    if (IFace->getSuperClass())
6171207619Srdivacky      FindImplementableMethods(Context, IFace->getSuperClass(),
6172207619Srdivacky                               WantInstanceMethods, ReturnType,
6173218893Sdim                               KnownMethods, false);
6174207619Srdivacky  }
6175207619Srdivacky
6176207619Srdivacky  if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
6177207619Srdivacky    // Recurse into protocols.
6178207619Srdivacky    const ObjCList<ObjCProtocolDecl> &Protocols
6179207619Srdivacky      = Category->getReferencedProtocols();
6180207619Srdivacky    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6181218893Sdim                                              E = Protocols.end();
6182207619Srdivacky         I != E; ++I)
6183207619Srdivacky      FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6184218893Sdim                               KnownMethods, InOriginalClass);
6185218893Sdim
6186218893Sdim    // If this category is the original class, jump to the interface.
6187218893Sdim    if (InOriginalClass && Category->getClassInterface())
6188218893Sdim      FindImplementableMethods(Context, Category->getClassInterface(),
6189218893Sdim                               WantInstanceMethods, ReturnType, KnownMethods,
6190218893Sdim                               false);
6191207619Srdivacky  }
6192207619Srdivacky
6193207619Srdivacky  if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
6194239462Sdim    // Make sure we have a definition; that's what we'll walk.
6195239462Sdim    if (!Protocol->hasDefinition())
6196239462Sdim      return;
6197239462Sdim    Protocol = Protocol->getDefinition();
6198239462Sdim    Container = Protocol;
6199239462Sdim
6200239462Sdim    // Recurse into protocols.
6201239462Sdim    const ObjCList<ObjCProtocolDecl> &Protocols
6202239462Sdim      = Protocol->getReferencedProtocols();
6203239462Sdim    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6204239462Sdim           E = Protocols.end();
6205239462Sdim         I != E; ++I)
6206239462Sdim      FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6207239462Sdim                               KnownMethods, false);
6208207619Srdivacky  }
6209207619Srdivacky
6210207619Srdivacky  // Add methods in this container. This operation occurs last because
6211207619Srdivacky  // we want the methods from this container to override any methods
6212207619Srdivacky  // we've previously seen with the same selector.
6213207619Srdivacky  for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
6214207619Srdivacky                                       MEnd = Container->meth_end();
6215207619Srdivacky       M != MEnd; ++M) {
6216239462Sdim    if (M->isInstanceMethod() == WantInstanceMethods) {
6217207619Srdivacky      if (!ReturnType.isNull() &&
6218239462Sdim          !Context.hasSameUnqualifiedType(ReturnType, M->getResultType()))
6219207619Srdivacky        continue;
6220207619Srdivacky
6221239462Sdim      KnownMethods[M->getSelector()] = std::make_pair(*M, InOriginalClass);
6222207619Srdivacky    }
6223207619Srdivacky  }
6224207619Srdivacky}
6225207619Srdivacky
6226218893Sdim/// \brief Add the parenthesized return or parameter type chunk to a code
6227218893Sdim/// completion string.
6228218893Sdimstatic void AddObjCPassingTypeChunk(QualType Type,
6229234353Sdim                                    unsigned ObjCDeclQuals,
6230218893Sdim                                    ASTContext &Context,
6231226633Sdim                                    const PrintingPolicy &Policy,
6232218893Sdim                                    CodeCompletionBuilder &Builder) {
6233218893Sdim  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6234234353Sdim  std::string Quals = formatObjCParamQualifiers(ObjCDeclQuals);
6235234353Sdim  if (!Quals.empty())
6236234353Sdim    Builder.AddTextChunk(Builder.getAllocator().CopyString(Quals));
6237226633Sdim  Builder.AddTextChunk(GetCompletionTypeString(Type, Context, Policy,
6238218893Sdim                                               Builder.getAllocator()));
6239218893Sdim  Builder.AddChunk(CodeCompletionString::CK_RightParen);
6240218893Sdim}
6241218893Sdim
6242218893Sdim/// \brief Determine whether the given class is or inherits from a class by
6243218893Sdim/// the given name.
6244218893Sdimstatic bool InheritsFromClassNamed(ObjCInterfaceDecl *Class,
6245226633Sdim                                   StringRef Name) {
6246218893Sdim  if (!Class)
6247218893Sdim    return false;
6248218893Sdim
6249218893Sdim  if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name)
6250218893Sdim    return true;
6251218893Sdim
6252218893Sdim  return InheritsFromClassNamed(Class->getSuperClass(), Name);
6253218893Sdim}
6254218893Sdim
6255218893Sdim/// \brief Add code completions for Objective-C Key-Value Coding (KVC) and
6256218893Sdim/// Key-Value Observing (KVO).
6257218893Sdimstatic void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
6258218893Sdim                                       bool IsInstanceMethod,
6259218893Sdim                                       QualType ReturnType,
6260218893Sdim                                       ASTContext &Context,
6261223017Sdim                                       VisitedSelectorSet &KnownSelectors,
6262218893Sdim                                       ResultBuilder &Results) {
6263218893Sdim  IdentifierInfo *PropName = Property->getIdentifier();
6264218893Sdim  if (!PropName || PropName->getLength() == 0)
6265218893Sdim    return;
6266218893Sdim
6267226633Sdim  PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
6268226633Sdim
6269218893Sdim  // Builder that will create each code completion.
6270218893Sdim  typedef CodeCompletionResult Result;
6271218893Sdim  CodeCompletionAllocator &Allocator = Results.getAllocator();
6272234353Sdim  CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
6273218893Sdim
6274218893Sdim  // The selector table.
6275218893Sdim  SelectorTable &Selectors = Context.Selectors;
6276218893Sdim
6277218893Sdim  // The property name, copied into the code completion allocation region
6278218893Sdim  // on demand.
6279218893Sdim  struct KeyHolder {
6280218893Sdim    CodeCompletionAllocator &Allocator;
6281226633Sdim    StringRef Key;
6282218893Sdim    const char *CopiedKey;
6283218893Sdim
6284226633Sdim    KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key)
6285218893Sdim    : Allocator(Allocator), Key(Key), CopiedKey(0) { }
6286218893Sdim
6287218893Sdim    operator const char *() {
6288218893Sdim      if (CopiedKey)
6289218893Sdim        return CopiedKey;
6290218893Sdim
6291218893Sdim      return CopiedKey = Allocator.CopyString(Key);
6292218893Sdim    }
6293218893Sdim  } Key(Allocator, PropName->getName());
6294218893Sdim
6295218893Sdim  // The uppercased name of the property name.
6296218893Sdim  std::string UpperKey = PropName->getName();
6297218893Sdim  if (!UpperKey.empty())
6298249423Sdim    UpperKey[0] = toUppercase(UpperKey[0]);
6299218893Sdim
6300218893Sdim  bool ReturnTypeMatchesProperty = ReturnType.isNull() ||
6301218893Sdim    Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(),
6302218893Sdim                                   Property->getType());
6303218893Sdim  bool ReturnTypeMatchesVoid
6304218893Sdim    = ReturnType.isNull() || ReturnType->isVoidType();
6305218893Sdim
6306218893Sdim  // Add the normal accessor -(type)key.
6307218893Sdim  if (IsInstanceMethod &&
6308223017Sdim      KnownSelectors.insert(Selectors.getNullarySelector(PropName)) &&
6309218893Sdim      ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) {
6310218893Sdim    if (ReturnType.isNull())
6311234353Sdim      AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0,
6312234353Sdim                              Context, Policy, Builder);
6313218893Sdim
6314218893Sdim    Builder.AddTypedTextChunk(Key);
6315218893Sdim    Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6316218893Sdim                             CXCursor_ObjCInstanceMethodDecl));
6317218893Sdim  }
6318218893Sdim
6319218893Sdim  // If we have an integral or boolean property (or the user has provided
6320218893Sdim  // an integral or boolean return type), add the accessor -(type)isKey.
6321218893Sdim  if (IsInstanceMethod &&
6322218893Sdim      ((!ReturnType.isNull() &&
6323218893Sdim        (ReturnType->isIntegerType() || ReturnType->isBooleanType())) ||
6324218893Sdim       (ReturnType.isNull() &&
6325218893Sdim        (Property->getType()->isIntegerType() ||
6326218893Sdim         Property->getType()->isBooleanType())))) {
6327226633Sdim    std::string SelectorName = (Twine("is") + UpperKey).str();
6328218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6329223017Sdim    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6330218893Sdim      if (ReturnType.isNull()) {
6331218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6332218893Sdim        Builder.AddTextChunk("BOOL");
6333218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6334218893Sdim      }
6335218893Sdim
6336218893Sdim      Builder.AddTypedTextChunk(
6337218893Sdim                                Allocator.CopyString(SelectorId->getName()));
6338218893Sdim      Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6339218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6340218893Sdim    }
6341218893Sdim  }
6342218893Sdim
6343218893Sdim  // Add the normal mutator.
6344218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid &&
6345218893Sdim      !Property->getSetterMethodDecl()) {
6346226633Sdim    std::string SelectorName = (Twine("set") + UpperKey).str();
6347218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6348223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6349218893Sdim      if (ReturnType.isNull()) {
6350218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6351218893Sdim        Builder.AddTextChunk("void");
6352218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6353218893Sdim      }
6354218893Sdim
6355218893Sdim      Builder.AddTypedTextChunk(
6356218893Sdim                                Allocator.CopyString(SelectorId->getName()));
6357218893Sdim      Builder.AddTypedTextChunk(":");
6358234353Sdim      AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0,
6359234353Sdim                              Context, Policy, Builder);
6360218893Sdim      Builder.AddTextChunk(Key);
6361218893Sdim      Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6362218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6363218893Sdim    }
6364218893Sdim  }
6365218893Sdim
6366218893Sdim  // Indexed and unordered accessors
6367218893Sdim  unsigned IndexedGetterPriority = CCP_CodePattern;
6368218893Sdim  unsigned IndexedSetterPriority = CCP_CodePattern;
6369218893Sdim  unsigned UnorderedGetterPriority = CCP_CodePattern;
6370218893Sdim  unsigned UnorderedSetterPriority = CCP_CodePattern;
6371218893Sdim  if (const ObjCObjectPointerType *ObjCPointer
6372218893Sdim                    = Property->getType()->getAs<ObjCObjectPointerType>()) {
6373218893Sdim    if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) {
6374218893Sdim      // If this interface type is not provably derived from a known
6375218893Sdim      // collection, penalize the corresponding completions.
6376218893Sdim      if (!InheritsFromClassNamed(IFace, "NSMutableArray")) {
6377218893Sdim        IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
6378218893Sdim        if (!InheritsFromClassNamed(IFace, "NSArray"))
6379218893Sdim          IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
6380218893Sdim      }
6381218893Sdim
6382218893Sdim      if (!InheritsFromClassNamed(IFace, "NSMutableSet")) {
6383218893Sdim        UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
6384218893Sdim        if (!InheritsFromClassNamed(IFace, "NSSet"))
6385218893Sdim          UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
6386218893Sdim      }
6387218893Sdim    }
6388218893Sdim  } else {
6389218893Sdim    IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
6390218893Sdim    IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
6391218893Sdim    UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
6392218893Sdim    UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
6393218893Sdim  }
6394218893Sdim
6395218893Sdim  // Add -(NSUInteger)countOf<key>
6396218893Sdim  if (IsInstanceMethod &&
6397218893Sdim      (ReturnType.isNull() || ReturnType->isIntegerType())) {
6398226633Sdim    std::string SelectorName = (Twine("countOf") + UpperKey).str();
6399218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6400223017Sdim    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6401218893Sdim      if (ReturnType.isNull()) {
6402218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6403218893Sdim        Builder.AddTextChunk("NSUInteger");
6404218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6405218893Sdim      }
6406218893Sdim
6407218893Sdim      Builder.AddTypedTextChunk(
6408218893Sdim                                Allocator.CopyString(SelectorId->getName()));
6409218893Sdim      Results.AddResult(Result(Builder.TakeString(),
6410218893Sdim                               std::min(IndexedGetterPriority,
6411218893Sdim                                        UnorderedGetterPriority),
6412218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6413218893Sdim    }
6414218893Sdim  }
6415218893Sdim
6416218893Sdim  // Indexed getters
6417218893Sdim  // Add -(id)objectInKeyAtIndex:(NSUInteger)index
6418218893Sdim  if (IsInstanceMethod &&
6419218893Sdim      (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
6420218893Sdim    std::string SelectorName
6421226633Sdim      = (Twine("objectIn") + UpperKey + "AtIndex").str();
6422218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6423223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6424218893Sdim      if (ReturnType.isNull()) {
6425218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6426218893Sdim        Builder.AddTextChunk("id");
6427218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6428218893Sdim      }
6429218893Sdim
6430218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6431218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6432218893Sdim      Builder.AddTextChunk("NSUInteger");
6433218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6434218893Sdim      Builder.AddTextChunk("index");
6435218893Sdim      Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6436218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6437218893Sdim    }
6438218893Sdim  }
6439218893Sdim
6440218893Sdim  // Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes
6441218893Sdim  if (IsInstanceMethod &&
6442218893Sdim      (ReturnType.isNull() ||
6443218893Sdim       (ReturnType->isObjCObjectPointerType() &&
6444218893Sdim        ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6445218893Sdim        ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6446218893Sdim                                                ->getName() == "NSArray"))) {
6447218893Sdim    std::string SelectorName
6448226633Sdim      = (Twine(Property->getName()) + "AtIndexes").str();
6449218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6450223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6451218893Sdim      if (ReturnType.isNull()) {
6452218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6453218893Sdim        Builder.AddTextChunk("NSArray *");
6454218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6455218893Sdim      }
6456218893Sdim
6457218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6458218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6459218893Sdim      Builder.AddTextChunk("NSIndexSet *");
6460218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6461218893Sdim      Builder.AddTextChunk("indexes");
6462218893Sdim      Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6463218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6464218893Sdim    }
6465218893Sdim  }
6466218893Sdim
6467218893Sdim  // Add -(void)getKey:(type **)buffer range:(NSRange)inRange
6468218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6469226633Sdim    std::string SelectorName = (Twine("get") + UpperKey).str();
6470218893Sdim    IdentifierInfo *SelectorIds[2] = {
6471218893Sdim      &Context.Idents.get(SelectorName),
6472218893Sdim      &Context.Idents.get("range")
6473218893Sdim    };
6474218893Sdim
6475223017Sdim    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6476218893Sdim      if (ReturnType.isNull()) {
6477218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6478218893Sdim        Builder.AddTextChunk("void");
6479218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6480218893Sdim      }
6481218893Sdim
6482218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6483218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6484218893Sdim      Builder.AddPlaceholderChunk("object-type");
6485218893Sdim      Builder.AddTextChunk(" **");
6486218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6487218893Sdim      Builder.AddTextChunk("buffer");
6488218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6489218893Sdim      Builder.AddTypedTextChunk("range:");
6490218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6491218893Sdim      Builder.AddTextChunk("NSRange");
6492218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6493218893Sdim      Builder.AddTextChunk("inRange");
6494218893Sdim      Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6495218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6496218893Sdim    }
6497218893Sdim  }
6498218893Sdim
6499218893Sdim  // Mutable indexed accessors
6500218893Sdim
6501218893Sdim  // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index
6502218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6503226633Sdim    std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str();
6504218893Sdim    IdentifierInfo *SelectorIds[2] = {
6505218893Sdim      &Context.Idents.get("insertObject"),
6506218893Sdim      &Context.Idents.get(SelectorName)
6507218893Sdim    };
6508218893Sdim
6509223017Sdim    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6510218893Sdim      if (ReturnType.isNull()) {
6511218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6512218893Sdim        Builder.AddTextChunk("void");
6513218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6514218893Sdim      }
6515218893Sdim
6516218893Sdim      Builder.AddTypedTextChunk("insertObject:");
6517218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6518218893Sdim      Builder.AddPlaceholderChunk("object-type");
6519218893Sdim      Builder.AddTextChunk(" *");
6520218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6521218893Sdim      Builder.AddTextChunk("object");
6522218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6523218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6524218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6525218893Sdim      Builder.AddPlaceholderChunk("NSUInteger");
6526218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6527218893Sdim      Builder.AddTextChunk("index");
6528218893Sdim      Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6529218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6530218893Sdim    }
6531218893Sdim  }
6532218893Sdim
6533218893Sdim  // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes
6534218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6535226633Sdim    std::string SelectorName = (Twine("insert") + UpperKey).str();
6536218893Sdim    IdentifierInfo *SelectorIds[2] = {
6537218893Sdim      &Context.Idents.get(SelectorName),
6538218893Sdim      &Context.Idents.get("atIndexes")
6539218893Sdim    };
6540218893Sdim
6541223017Sdim    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6542218893Sdim      if (ReturnType.isNull()) {
6543218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6544218893Sdim        Builder.AddTextChunk("void");
6545218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6546218893Sdim      }
6547218893Sdim
6548218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6549218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6550218893Sdim      Builder.AddTextChunk("NSArray *");
6551218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6552218893Sdim      Builder.AddTextChunk("array");
6553218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6554218893Sdim      Builder.AddTypedTextChunk("atIndexes:");
6555218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6556218893Sdim      Builder.AddPlaceholderChunk("NSIndexSet *");
6557218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6558218893Sdim      Builder.AddTextChunk("indexes");
6559218893Sdim      Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6560218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6561218893Sdim    }
6562218893Sdim  }
6563218893Sdim
6564218893Sdim  // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index
6565218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6566218893Sdim    std::string SelectorName
6567226633Sdim      = (Twine("removeObjectFrom") + UpperKey + "AtIndex").str();
6568218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6569223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6570218893Sdim      if (ReturnType.isNull()) {
6571218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6572218893Sdim        Builder.AddTextChunk("void");
6573218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6574218893Sdim      }
6575218893Sdim
6576218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6577218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6578218893Sdim      Builder.AddTextChunk("NSUInteger");
6579218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6580218893Sdim      Builder.AddTextChunk("index");
6581218893Sdim      Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6582218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6583218893Sdim    }
6584218893Sdim  }
6585218893Sdim
6586218893Sdim  // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes
6587218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6588218893Sdim    std::string SelectorName
6589226633Sdim      = (Twine("remove") + UpperKey + "AtIndexes").str();
6590218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6591223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6592218893Sdim      if (ReturnType.isNull()) {
6593218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6594218893Sdim        Builder.AddTextChunk("void");
6595218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6596218893Sdim      }
6597218893Sdim
6598218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6599218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6600218893Sdim      Builder.AddTextChunk("NSIndexSet *");
6601218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6602218893Sdim      Builder.AddTextChunk("indexes");
6603218893Sdim      Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6604218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6605218893Sdim    }
6606218893Sdim  }
6607218893Sdim
6608218893Sdim  // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object
6609218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6610218893Sdim    std::string SelectorName
6611226633Sdim      = (Twine("replaceObjectIn") + UpperKey + "AtIndex").str();
6612218893Sdim    IdentifierInfo *SelectorIds[2] = {
6613218893Sdim      &Context.Idents.get(SelectorName),
6614218893Sdim      &Context.Idents.get("withObject")
6615218893Sdim    };
6616218893Sdim
6617223017Sdim    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6618218893Sdim      if (ReturnType.isNull()) {
6619218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6620218893Sdim        Builder.AddTextChunk("void");
6621218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6622218893Sdim      }
6623218893Sdim
6624218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6625218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6626218893Sdim      Builder.AddPlaceholderChunk("NSUInteger");
6627218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6628218893Sdim      Builder.AddTextChunk("index");
6629218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6630218893Sdim      Builder.AddTypedTextChunk("withObject:");
6631218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6632218893Sdim      Builder.AddTextChunk("id");
6633218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6634218893Sdim      Builder.AddTextChunk("object");
6635218893Sdim      Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6636218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6637218893Sdim    }
6638218893Sdim  }
6639218893Sdim
6640218893Sdim  // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array
6641218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6642218893Sdim    std::string SelectorName1
6643226633Sdim      = (Twine("replace") + UpperKey + "AtIndexes").str();
6644226633Sdim    std::string SelectorName2 = (Twine("with") + UpperKey).str();
6645218893Sdim    IdentifierInfo *SelectorIds[2] = {
6646218893Sdim      &Context.Idents.get(SelectorName1),
6647218893Sdim      &Context.Idents.get(SelectorName2)
6648218893Sdim    };
6649218893Sdim
6650223017Sdim    if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds))) {
6651218893Sdim      if (ReturnType.isNull()) {
6652218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6653218893Sdim        Builder.AddTextChunk("void");
6654218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6655218893Sdim      }
6656218893Sdim
6657218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName1 + ":"));
6658218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6659218893Sdim      Builder.AddPlaceholderChunk("NSIndexSet *");
6660218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6661218893Sdim      Builder.AddTextChunk("indexes");
6662218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6663218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName2 + ":"));
6664218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6665218893Sdim      Builder.AddTextChunk("NSArray *");
6666218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6667218893Sdim      Builder.AddTextChunk("array");
6668218893Sdim      Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6669218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6670218893Sdim    }
6671218893Sdim  }
6672218893Sdim
6673218893Sdim  // Unordered getters
6674218893Sdim  // - (NSEnumerator *)enumeratorOfKey
6675218893Sdim  if (IsInstanceMethod &&
6676218893Sdim      (ReturnType.isNull() ||
6677218893Sdim       (ReturnType->isObjCObjectPointerType() &&
6678218893Sdim        ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6679218893Sdim        ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6680218893Sdim          ->getName() == "NSEnumerator"))) {
6681226633Sdim    std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str();
6682218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6683223017Sdim    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6684218893Sdim      if (ReturnType.isNull()) {
6685218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6686218893Sdim        Builder.AddTextChunk("NSEnumerator *");
6687218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6688218893Sdim      }
6689218893Sdim
6690218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6691218893Sdim      Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
6692218893Sdim                              CXCursor_ObjCInstanceMethodDecl));
6693218893Sdim    }
6694218893Sdim  }
6695218893Sdim
6696218893Sdim  // - (type *)memberOfKey:(type *)object
6697218893Sdim  if (IsInstanceMethod &&
6698218893Sdim      (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
6699226633Sdim    std::string SelectorName = (Twine("memberOf") + UpperKey).str();
6700218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6701223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6702218893Sdim      if (ReturnType.isNull()) {
6703218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6704218893Sdim        Builder.AddPlaceholderChunk("object-type");
6705218893Sdim        Builder.AddTextChunk(" *");
6706218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6707218893Sdim      }
6708218893Sdim
6709218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6710218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6711218893Sdim      if (ReturnType.isNull()) {
6712218893Sdim        Builder.AddPlaceholderChunk("object-type");
6713218893Sdim        Builder.AddTextChunk(" *");
6714218893Sdim      } else {
6715218893Sdim        Builder.AddTextChunk(GetCompletionTypeString(ReturnType, Context,
6716226633Sdim                                                     Policy,
6717218893Sdim                                                     Builder.getAllocator()));
6718218893Sdim      }
6719218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6720218893Sdim      Builder.AddTextChunk("object");
6721218893Sdim      Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
6722218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6723218893Sdim    }
6724218893Sdim  }
6725218893Sdim
6726218893Sdim  // Mutable unordered accessors
6727218893Sdim  // - (void)addKeyObject:(type *)object
6728218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6729218893Sdim    std::string SelectorName
6730226633Sdim      = (Twine("add") + UpperKey + Twine("Object")).str();
6731218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6732223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6733218893Sdim      if (ReturnType.isNull()) {
6734218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6735218893Sdim        Builder.AddTextChunk("void");
6736218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6737218893Sdim      }
6738218893Sdim
6739218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6740218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6741218893Sdim      Builder.AddPlaceholderChunk("object-type");
6742218893Sdim      Builder.AddTextChunk(" *");
6743218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6744218893Sdim      Builder.AddTextChunk("object");
6745218893Sdim      Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6746218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6747218893Sdim    }
6748218893Sdim  }
6749218893Sdim
6750218893Sdim  // - (void)addKey:(NSSet *)objects
6751218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6752226633Sdim    std::string SelectorName = (Twine("add") + UpperKey).str();
6753218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6754223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6755218893Sdim      if (ReturnType.isNull()) {
6756218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6757218893Sdim        Builder.AddTextChunk("void");
6758218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6759218893Sdim      }
6760218893Sdim
6761218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6762218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6763218893Sdim      Builder.AddTextChunk("NSSet *");
6764218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6765218893Sdim      Builder.AddTextChunk("objects");
6766218893Sdim      Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6767218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6768218893Sdim    }
6769218893Sdim  }
6770218893Sdim
6771218893Sdim  // - (void)removeKeyObject:(type *)object
6772218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6773218893Sdim    std::string SelectorName
6774226633Sdim      = (Twine("remove") + UpperKey + Twine("Object")).str();
6775218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6776223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6777218893Sdim      if (ReturnType.isNull()) {
6778218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6779218893Sdim        Builder.AddTextChunk("void");
6780218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6781218893Sdim      }
6782218893Sdim
6783218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6784218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6785218893Sdim      Builder.AddPlaceholderChunk("object-type");
6786218893Sdim      Builder.AddTextChunk(" *");
6787218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6788218893Sdim      Builder.AddTextChunk("object");
6789218893Sdim      Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6790218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6791218893Sdim    }
6792218893Sdim  }
6793218893Sdim
6794218893Sdim  // - (void)removeKey:(NSSet *)objects
6795218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6796226633Sdim    std::string SelectorName = (Twine("remove") + UpperKey).str();
6797218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6798223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6799218893Sdim      if (ReturnType.isNull()) {
6800218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6801218893Sdim        Builder.AddTextChunk("void");
6802218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6803218893Sdim      }
6804218893Sdim
6805218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6806218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6807218893Sdim      Builder.AddTextChunk("NSSet *");
6808218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6809218893Sdim      Builder.AddTextChunk("objects");
6810218893Sdim      Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6811218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6812218893Sdim    }
6813218893Sdim  }
6814218893Sdim
6815218893Sdim  // - (void)intersectKey:(NSSet *)objects
6816218893Sdim  if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6817226633Sdim    std::string SelectorName = (Twine("intersect") + UpperKey).str();
6818218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6819223017Sdim    if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId))) {
6820218893Sdim      if (ReturnType.isNull()) {
6821218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6822218893Sdim        Builder.AddTextChunk("void");
6823218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6824218893Sdim      }
6825218893Sdim
6826218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6827218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6828218893Sdim      Builder.AddTextChunk("NSSet *");
6829218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightParen);
6830218893Sdim      Builder.AddTextChunk("objects");
6831218893Sdim      Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6832218893Sdim                               CXCursor_ObjCInstanceMethodDecl));
6833218893Sdim    }
6834218893Sdim  }
6835218893Sdim
6836218893Sdim  // Key-Value Observing
6837218893Sdim  // + (NSSet *)keyPathsForValuesAffectingKey
6838218893Sdim  if (!IsInstanceMethod &&
6839218893Sdim      (ReturnType.isNull() ||
6840218893Sdim       (ReturnType->isObjCObjectPointerType() &&
6841218893Sdim        ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6842218893Sdim        ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6843218893Sdim                                                    ->getName() == "NSSet"))) {
6844218893Sdim    std::string SelectorName
6845226633Sdim      = (Twine("keyPathsForValuesAffecting") + UpperKey).str();
6846218893Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6847223017Sdim    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6848218893Sdim      if (ReturnType.isNull()) {
6849218893Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6850218893Sdim        Builder.AddTextChunk("NSSet *");
6851218893Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6852218893Sdim      }
6853218893Sdim
6854218893Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6855218893Sdim      Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6856223017Sdim                              CXCursor_ObjCClassMethodDecl));
6857218893Sdim    }
6858218893Sdim  }
6859223017Sdim
6860223017Sdim  // + (BOOL)automaticallyNotifiesObserversForKey
6861223017Sdim  if (!IsInstanceMethod &&
6862223017Sdim      (ReturnType.isNull() ||
6863223017Sdim       ReturnType->isIntegerType() ||
6864223017Sdim       ReturnType->isBooleanType())) {
6865223017Sdim    std::string SelectorName
6866226633Sdim      = (Twine("automaticallyNotifiesObserversOf") + UpperKey).str();
6867223017Sdim    IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6868223017Sdim    if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))) {
6869223017Sdim      if (ReturnType.isNull()) {
6870223017Sdim        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6871223017Sdim        Builder.AddTextChunk("BOOL");
6872223017Sdim        Builder.AddChunk(CodeCompletionString::CK_RightParen);
6873223017Sdim      }
6874223017Sdim
6875223017Sdim      Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6876223017Sdim      Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6877223017Sdim                              CXCursor_ObjCClassMethodDecl));
6878223017Sdim    }
6879223017Sdim  }
6880218893Sdim}
6881218893Sdim
6882207619Srdivackyvoid Sema::CodeCompleteObjCMethodDecl(Scope *S,
6883207619Srdivacky                                      bool IsInstanceMethod,
6884226633Sdim                                      ParsedType ReturnTy) {
6885207619Srdivacky  // Determine the return type of the method we're declaring, if
6886207619Srdivacky  // provided.
6887207619Srdivacky  QualType ReturnType = GetTypeFromParser(ReturnTy);
6888226633Sdim  Decl *IDecl = 0;
6889226633Sdim  if (CurContext->isObjCContainer()) {
6890226633Sdim      ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
6891226633Sdim      IDecl = cast<Decl>(OCD);
6892226633Sdim  }
6893218893Sdim  // Determine where we should start searching for methods.
6894218893Sdim  ObjCContainerDecl *SearchDecl = 0;
6895207619Srdivacky  bool IsInImplementation = false;
6896212904Sdim  if (Decl *D = IDecl) {
6897207619Srdivacky    if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
6898207619Srdivacky      SearchDecl = Impl->getClassInterface();
6899207619Srdivacky      IsInImplementation = true;
6900207619Srdivacky    } else if (ObjCCategoryImplDecl *CatImpl
6901218893Sdim                                         = dyn_cast<ObjCCategoryImplDecl>(D)) {
6902207619Srdivacky      SearchDecl = CatImpl->getCategoryDecl();
6903207619Srdivacky      IsInImplementation = true;
6904218893Sdim    } else
6905207619Srdivacky      SearchDecl = dyn_cast<ObjCContainerDecl>(D);
6906207619Srdivacky  }
6907207619Srdivacky
6908207619Srdivacky  if (!SearchDecl && S) {
6909218893Sdim    if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity()))
6910207619Srdivacky      SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
6911207619Srdivacky  }
6912207619Srdivacky
6913218893Sdim  if (!SearchDecl) {
6914212904Sdim    HandleCodeCompleteResults(this, CodeCompleter,
6915212904Sdim                              CodeCompletionContext::CCC_Other,
6916212904Sdim                              0, 0);
6917207619Srdivacky    return;
6918207619Srdivacky  }
6919207619Srdivacky
6920207619Srdivacky  // Find all of the methods that we could declare/implement here.
6921207619Srdivacky  KnownMethodsMap KnownMethods;
6922207619Srdivacky  FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
6923218893Sdim                           ReturnType, KnownMethods);
6924207619Srdivacky
6925207619Srdivacky  // Add declarations or definitions for each of the known methods.
6926212904Sdim  typedef CodeCompletionResult Result;
6927218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6928234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
6929218893Sdim                        CodeCompletionContext::CCC_Other);
6930207619Srdivacky  Results.EnterNewScope();
6931226633Sdim  PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
6932207619Srdivacky  for (KnownMethodsMap::iterator M = KnownMethods.begin(),
6933207619Srdivacky                              MEnd = KnownMethods.end();
6934207619Srdivacky       M != MEnd; ++M) {
6935212904Sdim    ObjCMethodDecl *Method = M->second.first;
6936234353Sdim    CodeCompletionBuilder Builder(Results.getAllocator(),
6937234353Sdim                                  Results.getCodeCompletionTUInfo());
6938207619Srdivacky
6939207619Srdivacky    // If the result type was not already provided, add it to the
6940207619Srdivacky    // pattern as (type).
6941218893Sdim    if (ReturnType.isNull())
6942234353Sdim      AddObjCPassingTypeChunk(Method->getResultType(),
6943234353Sdim                              Method->getObjCDeclQualifier(),
6944234353Sdim                              Context, Policy,
6945234353Sdim                              Builder);
6946207619Srdivacky
6947207619Srdivacky    Selector Sel = Method->getSelector();
6948207619Srdivacky
6949207619Srdivacky    // Add the first part of the selector to the pattern.
6950218893Sdim    Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
6951218893Sdim                                                       Sel.getNameForSlot(0)));
6952207619Srdivacky
6953207619Srdivacky    // Add parameters to the pattern.
6954207619Srdivacky    unsigned I = 0;
6955207619Srdivacky    for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
6956207619Srdivacky                                     PEnd = Method->param_end();
6957207619Srdivacky         P != PEnd; (void)++P, ++I) {
6958207619Srdivacky      // Add the part of the selector name.
6959207619Srdivacky      if (I == 0)
6960218893Sdim        Builder.AddTypedTextChunk(":");
6961207619Srdivacky      else if (I < Sel.getNumArgs()) {
6962218893Sdim        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6963218893Sdim        Builder.AddTypedTextChunk(
6964218893Sdim                Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
6965207619Srdivacky      } else
6966207619Srdivacky        break;
6967207619Srdivacky
6968207619Srdivacky      // Add the parameter type.
6969234353Sdim      AddObjCPassingTypeChunk((*P)->getOriginalType(),
6970234353Sdim                              (*P)->getObjCDeclQualifier(),
6971234353Sdim                              Context, Policy,
6972226633Sdim                              Builder);
6973207619Srdivacky
6974207619Srdivacky      if (IdentifierInfo *Id = (*P)->getIdentifier())
6975218893Sdim        Builder.AddTextChunk(Builder.getAllocator().CopyString( Id->getName()));
6976207619Srdivacky    }
6977207619Srdivacky
6978207619Srdivacky    if (Method->isVariadic()) {
6979207619Srdivacky      if (Method->param_size() > 0)
6980218893Sdim        Builder.AddChunk(CodeCompletionString::CK_Comma);
6981218893Sdim      Builder.AddTextChunk("...");
6982212904Sdim    }
6983207619Srdivacky
6984210299Sed    if (IsInImplementation && Results.includeCodePatterns()) {
6985207619Srdivacky      // We will be defining the method here, so add a compound statement.
6986218893Sdim      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6987218893Sdim      Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
6988218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6989207619Srdivacky      if (!Method->getResultType()->isVoidType()) {
6990207619Srdivacky        // If the result type is not void, add a return clause.
6991218893Sdim        Builder.AddTextChunk("return");
6992218893Sdim        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6993218893Sdim        Builder.AddPlaceholderChunk("expression");
6994218893Sdim        Builder.AddChunk(CodeCompletionString::CK_SemiColon);
6995207619Srdivacky      } else
6996218893Sdim        Builder.AddPlaceholderChunk("statements");
6997207619Srdivacky
6998218893Sdim      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6999218893Sdim      Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7000207619Srdivacky    }
7001207619Srdivacky
7002212904Sdim    unsigned Priority = CCP_CodePattern;
7003212904Sdim    if (!M->second.second)
7004212904Sdim      Priority += CCD_InBaseClass;
7005212904Sdim
7006234353Sdim    Results.AddResult(Result(Builder.TakeString(), Method, Priority));
7007207619Srdivacky  }
7008207619Srdivacky
7009218893Sdim  // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of
7010218893Sdim  // the properties in this class and its categories.
7011234353Sdim  if (Context.getLangOpts().ObjC2) {
7012226633Sdim    SmallVector<ObjCContainerDecl *, 4> Containers;
7013218893Sdim    Containers.push_back(SearchDecl);
7014218893Sdim
7015223017Sdim    VisitedSelectorSet KnownSelectors;
7016223017Sdim    for (KnownMethodsMap::iterator M = KnownMethods.begin(),
7017223017Sdim                                MEnd = KnownMethods.end();
7018223017Sdim         M != MEnd; ++M)
7019223017Sdim      KnownSelectors.insert(M->first);
7020223017Sdim
7021223017Sdim
7022218893Sdim    ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl);
7023218893Sdim    if (!IFace)
7024218893Sdim      if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl))
7025218893Sdim        IFace = Category->getClassInterface();
7026218893Sdim
7027218893Sdim    if (IFace) {
7028249423Sdim      for (ObjCInterfaceDecl::visible_categories_iterator
7029249423Sdim             Cat = IFace->visible_categories_begin(),
7030249423Sdim             CatEnd = IFace->visible_categories_end();
7031249423Sdim           Cat != CatEnd; ++Cat) {
7032249423Sdim        Containers.push_back(*Cat);
7033249423Sdim      }
7034218893Sdim    }
7035218893Sdim
7036218893Sdim    for (unsigned I = 0, N = Containers.size(); I != N; ++I) {
7037218893Sdim      for (ObjCContainerDecl::prop_iterator P = Containers[I]->prop_begin(),
7038218893Sdim                                         PEnd = Containers[I]->prop_end();
7039218893Sdim           P != PEnd; ++P) {
7040218893Sdim        AddObjCKeyValueCompletions(*P, IsInstanceMethod, ReturnType, Context,
7041223017Sdim                                   KnownSelectors, Results);
7042218893Sdim      }
7043218893Sdim    }
7044218893Sdim  }
7045218893Sdim
7046207619Srdivacky  Results.ExitScope();
7047207619Srdivacky
7048212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
7049212904Sdim                            CodeCompletionContext::CCC_Other,
7050212904Sdim                            Results.data(),Results.size());
7051207619Srdivacky}
7052210299Sed
7053210299Sedvoid Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
7054210299Sed                                              bool IsInstanceMethod,
7055210299Sed                                              bool AtParameterName,
7056212904Sdim                                              ParsedType ReturnTy,
7057210299Sed                                              IdentifierInfo **SelIdents,
7058210299Sed                                              unsigned NumSelIdents) {
7059210299Sed  // If we have an external source, load the entire class method
7060212904Sdim  // pool from the AST file.
7061210299Sed  if (ExternalSource) {
7062210299Sed    for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
7063210299Sed         I != N; ++I) {
7064210299Sed      Selector Sel = ExternalSource->GetExternalSelector(I);
7065212904Sdim      if (Sel.isNull() || MethodPool.count(Sel))
7066210299Sed        continue;
7067212904Sdim
7068212904Sdim      ReadMethodPool(Sel);
7069210299Sed    }
7070210299Sed  }
7071210299Sed
7072210299Sed  // Build the set of methods we can see.
7073212904Sdim  typedef CodeCompletionResult Result;
7074218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7075234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
7076218893Sdim                        CodeCompletionContext::CCC_Other);
7077210299Sed
7078210299Sed  if (ReturnTy)
7079210299Sed    Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
7080212904Sdim
7081210299Sed  Results.EnterNewScope();
7082212904Sdim  for (GlobalMethodPool::iterator M = MethodPool.begin(),
7083212904Sdim                                  MEnd = MethodPool.end();
7084212904Sdim       M != MEnd; ++M) {
7085212904Sdim    for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
7086212904Sdim                                                       &M->second.second;
7087212904Sdim         MethList && MethList->Method;
7088251662Sdim         MethList = MethList->getNext()) {
7089210299Sed      if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
7090210299Sed                                  NumSelIdents))
7091210299Sed        continue;
7092210299Sed
7093210299Sed      if (AtParameterName) {
7094210299Sed        // Suggest parameter names we've seen before.
7095210299Sed        if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
7096210299Sed          ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
7097210299Sed          if (Param->getIdentifier()) {
7098234353Sdim            CodeCompletionBuilder Builder(Results.getAllocator(),
7099234353Sdim                                          Results.getCodeCompletionTUInfo());
7100218893Sdim            Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
7101218893Sdim                                           Param->getIdentifier()->getName()));
7102218893Sdim            Results.AddResult(Builder.TakeString());
7103210299Sed          }
7104210299Sed        }
7105210299Sed
7106210299Sed        continue;
7107210299Sed      }
7108210299Sed
7109249423Sdim      Result R(MethList->Method, Results.getBasePriority(MethList->Method), 0);
7110210299Sed      R.StartParameter = NumSelIdents;
7111210299Sed      R.AllParametersAreInformative = false;
7112210299Sed      R.DeclaringEntity = true;
7113210299Sed      Results.MaybeAddResult(R, CurContext);
7114210299Sed    }
7115210299Sed  }
7116210299Sed
7117210299Sed  Results.ExitScope();
7118212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
7119212904Sdim                            CodeCompletionContext::CCC_Other,
7120212904Sdim                            Results.data(),Results.size());
7121210299Sed}
7122212904Sdim
7123212904Sdimvoid Sema::CodeCompletePreprocessorDirective(bool InConditional) {
7124218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7125234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
7126218893Sdim                        CodeCompletionContext::CCC_PreprocessorDirective);
7127212904Sdim  Results.EnterNewScope();
7128212904Sdim
7129212904Sdim  // #if <condition>
7130234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
7131234353Sdim                                Results.getCodeCompletionTUInfo());
7132218893Sdim  Builder.AddTypedTextChunk("if");
7133218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7134218893Sdim  Builder.AddPlaceholderChunk("condition");
7135218893Sdim  Results.AddResult(Builder.TakeString());
7136212904Sdim
7137212904Sdim  // #ifdef <macro>
7138218893Sdim  Builder.AddTypedTextChunk("ifdef");
7139218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7140218893Sdim  Builder.AddPlaceholderChunk("macro");
7141218893Sdim  Results.AddResult(Builder.TakeString());
7142218893Sdim
7143212904Sdim  // #ifndef <macro>
7144218893Sdim  Builder.AddTypedTextChunk("ifndef");
7145218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7146218893Sdim  Builder.AddPlaceholderChunk("macro");
7147218893Sdim  Results.AddResult(Builder.TakeString());
7148212904Sdim
7149212904Sdim  if (InConditional) {
7150212904Sdim    // #elif <condition>
7151218893Sdim    Builder.AddTypedTextChunk("elif");
7152218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7153218893Sdim    Builder.AddPlaceholderChunk("condition");
7154218893Sdim    Results.AddResult(Builder.TakeString());
7155212904Sdim
7156212904Sdim    // #else
7157218893Sdim    Builder.AddTypedTextChunk("else");
7158218893Sdim    Results.AddResult(Builder.TakeString());
7159212904Sdim
7160212904Sdim    // #endif
7161218893Sdim    Builder.AddTypedTextChunk("endif");
7162218893Sdim    Results.AddResult(Builder.TakeString());
7163212904Sdim  }
7164212904Sdim
7165212904Sdim  // #include "header"
7166218893Sdim  Builder.AddTypedTextChunk("include");
7167218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7168218893Sdim  Builder.AddTextChunk("\"");
7169218893Sdim  Builder.AddPlaceholderChunk("header");
7170218893Sdim  Builder.AddTextChunk("\"");
7171218893Sdim  Results.AddResult(Builder.TakeString());
7172212904Sdim
7173212904Sdim  // #include <header>
7174218893Sdim  Builder.AddTypedTextChunk("include");
7175218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7176218893Sdim  Builder.AddTextChunk("<");
7177218893Sdim  Builder.AddPlaceholderChunk("header");
7178218893Sdim  Builder.AddTextChunk(">");
7179218893Sdim  Results.AddResult(Builder.TakeString());
7180212904Sdim
7181212904Sdim  // #define <macro>
7182218893Sdim  Builder.AddTypedTextChunk("define");
7183218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7184218893Sdim  Builder.AddPlaceholderChunk("macro");
7185218893Sdim  Results.AddResult(Builder.TakeString());
7186212904Sdim
7187212904Sdim  // #define <macro>(<args>)
7188218893Sdim  Builder.AddTypedTextChunk("define");
7189218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7190218893Sdim  Builder.AddPlaceholderChunk("macro");
7191218893Sdim  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7192218893Sdim  Builder.AddPlaceholderChunk("args");
7193218893Sdim  Builder.AddChunk(CodeCompletionString::CK_RightParen);
7194218893Sdim  Results.AddResult(Builder.TakeString());
7195212904Sdim
7196212904Sdim  // #undef <macro>
7197218893Sdim  Builder.AddTypedTextChunk("undef");
7198218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7199218893Sdim  Builder.AddPlaceholderChunk("macro");
7200218893Sdim  Results.AddResult(Builder.TakeString());
7201212904Sdim
7202212904Sdim  // #line <number>
7203218893Sdim  Builder.AddTypedTextChunk("line");
7204218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7205218893Sdim  Builder.AddPlaceholderChunk("number");
7206218893Sdim  Results.AddResult(Builder.TakeString());
7207212904Sdim
7208212904Sdim  // #line <number> "filename"
7209218893Sdim  Builder.AddTypedTextChunk("line");
7210218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7211218893Sdim  Builder.AddPlaceholderChunk("number");
7212218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7213218893Sdim  Builder.AddTextChunk("\"");
7214218893Sdim  Builder.AddPlaceholderChunk("filename");
7215218893Sdim  Builder.AddTextChunk("\"");
7216218893Sdim  Results.AddResult(Builder.TakeString());
7217212904Sdim
7218212904Sdim  // #error <message>
7219218893Sdim  Builder.AddTypedTextChunk("error");
7220218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7221218893Sdim  Builder.AddPlaceholderChunk("message");
7222218893Sdim  Results.AddResult(Builder.TakeString());
7223212904Sdim
7224212904Sdim  // #pragma <arguments>
7225218893Sdim  Builder.AddTypedTextChunk("pragma");
7226218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7227218893Sdim  Builder.AddPlaceholderChunk("arguments");
7228218893Sdim  Results.AddResult(Builder.TakeString());
7229212904Sdim
7230234353Sdim  if (getLangOpts().ObjC1) {
7231212904Sdim    // #import "header"
7232218893Sdim    Builder.AddTypedTextChunk("import");
7233218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7234218893Sdim    Builder.AddTextChunk("\"");
7235218893Sdim    Builder.AddPlaceholderChunk("header");
7236218893Sdim    Builder.AddTextChunk("\"");
7237218893Sdim    Results.AddResult(Builder.TakeString());
7238212904Sdim
7239212904Sdim    // #import <header>
7240218893Sdim    Builder.AddTypedTextChunk("import");
7241218893Sdim    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7242218893Sdim    Builder.AddTextChunk("<");
7243218893Sdim    Builder.AddPlaceholderChunk("header");
7244218893Sdim    Builder.AddTextChunk(">");
7245218893Sdim    Results.AddResult(Builder.TakeString());
7246212904Sdim  }
7247212904Sdim
7248212904Sdim  // #include_next "header"
7249218893Sdim  Builder.AddTypedTextChunk("include_next");
7250218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7251218893Sdim  Builder.AddTextChunk("\"");
7252218893Sdim  Builder.AddPlaceholderChunk("header");
7253218893Sdim  Builder.AddTextChunk("\"");
7254218893Sdim  Results.AddResult(Builder.TakeString());
7255212904Sdim
7256212904Sdim  // #include_next <header>
7257218893Sdim  Builder.AddTypedTextChunk("include_next");
7258218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7259218893Sdim  Builder.AddTextChunk("<");
7260218893Sdim  Builder.AddPlaceholderChunk("header");
7261218893Sdim  Builder.AddTextChunk(">");
7262218893Sdim  Results.AddResult(Builder.TakeString());
7263212904Sdim
7264212904Sdim  // #warning <message>
7265218893Sdim  Builder.AddTypedTextChunk("warning");
7266218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7267218893Sdim  Builder.AddPlaceholderChunk("message");
7268218893Sdim  Results.AddResult(Builder.TakeString());
7269212904Sdim
7270212904Sdim  // Note: #ident and #sccs are such crazy anachronisms that we don't provide
7271212904Sdim  // completions for them. And __include_macros is a Clang-internal extension
7272212904Sdim  // that we don't want to encourage anyone to use.
7273212904Sdim
7274212904Sdim  // FIXME: we don't support #assert or #unassert, so don't suggest them.
7275212904Sdim  Results.ExitScope();
7276212904Sdim
7277212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
7278212904Sdim                            CodeCompletionContext::CCC_PreprocessorDirective,
7279212904Sdim                            Results.data(), Results.size());
7280212904Sdim}
7281212904Sdim
7282212904Sdimvoid Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
7283212904Sdim  CodeCompleteOrdinaryName(S,
7284212904Sdim                           S->getFnParent()? Sema::PCC_RecoveryInFunction
7285212904Sdim                                           : Sema::PCC_Namespace);
7286212904Sdim}
7287212904Sdim
7288212904Sdimvoid Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
7289218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7290234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
7291218893Sdim                        IsDefinition? CodeCompletionContext::CCC_MacroName
7292218893Sdim                                    : CodeCompletionContext::CCC_MacroNameUse);
7293212904Sdim  if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
7294212904Sdim    // Add just the names of macros, not their arguments.
7295234353Sdim    CodeCompletionBuilder Builder(Results.getAllocator(),
7296234353Sdim                                  Results.getCodeCompletionTUInfo());
7297212904Sdim    Results.EnterNewScope();
7298212904Sdim    for (Preprocessor::macro_iterator M = PP.macro_begin(),
7299212904Sdim                                   MEnd = PP.macro_end();
7300212904Sdim         M != MEnd; ++M) {
7301218893Sdim      Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
7302218893Sdim                                           M->first->getName()));
7303243830Sdim      Results.AddResult(CodeCompletionResult(Builder.TakeString(),
7304243830Sdim                                             CCP_CodePattern,
7305243830Sdim                                             CXCursor_MacroDefinition));
7306212904Sdim    }
7307212904Sdim    Results.ExitScope();
7308212904Sdim  } else if (IsDefinition) {
7309212904Sdim    // FIXME: Can we detect when the user just wrote an include guard above?
7310212904Sdim  }
7311212904Sdim
7312218893Sdim  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7313212904Sdim                            Results.data(), Results.size());
7314212904Sdim}
7315212904Sdim
7316212904Sdimvoid Sema::CodeCompletePreprocessorExpression() {
7317218893Sdim  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7318234353Sdim                        CodeCompleter->getCodeCompletionTUInfo(),
7319218893Sdim                        CodeCompletionContext::CCC_PreprocessorExpression);
7320212904Sdim
7321212904Sdim  if (!CodeCompleter || CodeCompleter->includeMacros())
7322243830Sdim    AddMacroResults(PP, Results, true);
7323212904Sdim
7324212904Sdim    // defined (<macro>)
7325212904Sdim  Results.EnterNewScope();
7326234353Sdim  CodeCompletionBuilder Builder(Results.getAllocator(),
7327234353Sdim                                Results.getCodeCompletionTUInfo());
7328218893Sdim  Builder.AddTypedTextChunk("defined");
7329218893Sdim  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7330218893Sdim  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7331218893Sdim  Builder.AddPlaceholderChunk("macro");
7332218893Sdim  Builder.AddChunk(CodeCompletionString::CK_RightParen);
7333218893Sdim  Results.AddResult(Builder.TakeString());
7334212904Sdim  Results.ExitScope();
7335212904Sdim
7336212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
7337212904Sdim                            CodeCompletionContext::CCC_PreprocessorExpression,
7338212904Sdim                            Results.data(), Results.size());
7339212904Sdim}
7340212904Sdim
7341212904Sdimvoid Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
7342212904Sdim                                                 IdentifierInfo *Macro,
7343212904Sdim                                                 MacroInfo *MacroInfo,
7344212904Sdim                                                 unsigned Argument) {
7345212904Sdim  // FIXME: In the future, we could provide "overload" results, much like we
7346212904Sdim  // do for function calls.
7347212904Sdim
7348226633Sdim  // Now just ignore this. There will be another code-completion callback
7349226633Sdim  // for the expanded tokens.
7350212904Sdim}
7351212904Sdim
7352212904Sdimvoid Sema::CodeCompleteNaturalLanguage() {
7353212904Sdim  HandleCodeCompleteResults(this, CodeCompleter,
7354212904Sdim                            CodeCompletionContext::CCC_NaturalLanguage,
7355212904Sdim                            0, 0);
7356212904Sdim}
7357212904Sdim
7358218893Sdimvoid Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
7359234353Sdim                                       CodeCompletionTUInfo &CCTUInfo,
7360226633Sdim                 SmallVectorImpl<CodeCompletionResult> &Results) {
7361234353Sdim  ResultBuilder Builder(*this, Allocator, CCTUInfo,
7362234353Sdim                        CodeCompletionContext::CCC_Recovery);
7363212904Sdim  if (!CodeCompleter || CodeCompleter->includeGlobals()) {
7364212904Sdim    CodeCompletionDeclConsumer Consumer(Builder,
7365212904Sdim                                        Context.getTranslationUnitDecl());
7366212904Sdim    LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
7367212904Sdim                       Consumer);
7368212904Sdim  }
7369212904Sdim
7370212904Sdim  if (!CodeCompleter || CodeCompleter->includeMacros())
7371243830Sdim    AddMacroResults(PP, Builder, true);
7372212904Sdim
7373212904Sdim  Results.clear();
7374212904Sdim  Results.insert(Results.end(),
7375212904Sdim                 Builder.data(), Builder.data() + Builder.size());
7376212904Sdim}
7377