1*67e74705SXin Li //===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file defines the code-completion semantic actions.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li #include "clang/Sema/SemaInternal.h"
14*67e74705SXin Li #include "clang/AST/DeclObjC.h"
15*67e74705SXin Li #include "clang/AST/ExprCXX.h"
16*67e74705SXin Li #include "clang/AST/ExprObjC.h"
17*67e74705SXin Li #include "clang/Basic/CharInfo.h"
18*67e74705SXin Li #include "clang/Lex/HeaderSearch.h"
19*67e74705SXin Li #include "clang/Lex/MacroInfo.h"
20*67e74705SXin Li #include "clang/Lex/Preprocessor.h"
21*67e74705SXin Li #include "clang/Sema/CodeCompleteConsumer.h"
22*67e74705SXin Li #include "clang/Sema/Lookup.h"
23*67e74705SXin Li #include "clang/Sema/Overload.h"
24*67e74705SXin Li #include "clang/Sema/Scope.h"
25*67e74705SXin Li #include "clang/Sema/ScopeInfo.h"
26*67e74705SXin Li #include "llvm/ADT/DenseSet.h"
27*67e74705SXin Li #include "llvm/ADT/SmallBitVector.h"
28*67e74705SXin Li #include "llvm/ADT/SmallPtrSet.h"
29*67e74705SXin Li #include "llvm/ADT/SmallString.h"
30*67e74705SXin Li #include "llvm/ADT/StringExtras.h"
31*67e74705SXin Li #include "llvm/ADT/StringSwitch.h"
32*67e74705SXin Li #include "llvm/ADT/Twine.h"
33*67e74705SXin Li #include <list>
34*67e74705SXin Li #include <map>
35*67e74705SXin Li #include <vector>
36*67e74705SXin Li
37*67e74705SXin Li using namespace clang;
38*67e74705SXin Li using namespace sema;
39*67e74705SXin Li
40*67e74705SXin Li namespace {
41*67e74705SXin Li /// \brief A container of code-completion results.
42*67e74705SXin Li class ResultBuilder {
43*67e74705SXin Li public:
44*67e74705SXin Li /// \brief The type of a name-lookup filter, which can be provided to the
45*67e74705SXin Li /// name-lookup routines to specify which declarations should be included in
46*67e74705SXin Li /// the result set (when it returns true) and which declarations should be
47*67e74705SXin Li /// filtered out (returns false).
48*67e74705SXin Li typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const;
49*67e74705SXin Li
50*67e74705SXin Li typedef CodeCompletionResult Result;
51*67e74705SXin Li
52*67e74705SXin Li private:
53*67e74705SXin Li /// \brief The actual results we have found.
54*67e74705SXin Li std::vector<Result> Results;
55*67e74705SXin Li
56*67e74705SXin Li /// \brief A record of all of the declarations we have found and placed
57*67e74705SXin Li /// into the result set, used to ensure that no declaration ever gets into
58*67e74705SXin Li /// the result set twice.
59*67e74705SXin Li llvm::SmallPtrSet<const Decl*, 16> AllDeclsFound;
60*67e74705SXin Li
61*67e74705SXin Li typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair;
62*67e74705SXin Li
63*67e74705SXin Li /// \brief An entry in the shadow map, which is optimized to store
64*67e74705SXin Li /// a single (declaration, index) mapping (the common case) but
65*67e74705SXin Li /// can also store a list of (declaration, index) mappings.
66*67e74705SXin Li class ShadowMapEntry {
67*67e74705SXin Li typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
68*67e74705SXin Li
69*67e74705SXin Li /// \brief Contains either the solitary NamedDecl * or a vector
70*67e74705SXin Li /// of (declaration, index) pairs.
71*67e74705SXin Li llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector*> DeclOrVector;
72*67e74705SXin Li
73*67e74705SXin Li /// \brief When the entry contains a single declaration, this is
74*67e74705SXin Li /// the index associated with that entry.
75*67e74705SXin Li unsigned SingleDeclIndex;
76*67e74705SXin Li
77*67e74705SXin Li public:
ShadowMapEntry()78*67e74705SXin Li ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
79*67e74705SXin Li
Add(const NamedDecl * ND,unsigned Index)80*67e74705SXin Li void Add(const NamedDecl *ND, unsigned Index) {
81*67e74705SXin Li if (DeclOrVector.isNull()) {
82*67e74705SXin Li // 0 - > 1 elements: just set the single element information.
83*67e74705SXin Li DeclOrVector = ND;
84*67e74705SXin Li SingleDeclIndex = Index;
85*67e74705SXin Li return;
86*67e74705SXin Li }
87*67e74705SXin Li
88*67e74705SXin Li if (const NamedDecl *PrevND =
89*67e74705SXin Li DeclOrVector.dyn_cast<const NamedDecl *>()) {
90*67e74705SXin Li // 1 -> 2 elements: create the vector of results and push in the
91*67e74705SXin Li // existing declaration.
92*67e74705SXin Li DeclIndexPairVector *Vec = new DeclIndexPairVector;
93*67e74705SXin Li Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
94*67e74705SXin Li DeclOrVector = Vec;
95*67e74705SXin Li }
96*67e74705SXin Li
97*67e74705SXin Li // Add the new element to the end of the vector.
98*67e74705SXin Li DeclOrVector.get<DeclIndexPairVector*>()->push_back(
99*67e74705SXin Li DeclIndexPair(ND, Index));
100*67e74705SXin Li }
101*67e74705SXin Li
Destroy()102*67e74705SXin Li void Destroy() {
103*67e74705SXin Li if (DeclIndexPairVector *Vec
104*67e74705SXin Li = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
105*67e74705SXin Li delete Vec;
106*67e74705SXin Li DeclOrVector = ((NamedDecl *)nullptr);
107*67e74705SXin Li }
108*67e74705SXin Li }
109*67e74705SXin Li
110*67e74705SXin Li // Iteration.
111*67e74705SXin Li class iterator;
112*67e74705SXin Li iterator begin() const;
113*67e74705SXin Li iterator end() const;
114*67e74705SXin Li };
115*67e74705SXin Li
116*67e74705SXin Li /// \brief A mapping from declaration names to the declarations that have
117*67e74705SXin Li /// this name within a particular scope and their index within the list of
118*67e74705SXin Li /// results.
119*67e74705SXin Li typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
120*67e74705SXin Li
121*67e74705SXin Li /// \brief The semantic analysis object for which results are being
122*67e74705SXin Li /// produced.
123*67e74705SXin Li Sema &SemaRef;
124*67e74705SXin Li
125*67e74705SXin Li /// \brief The allocator used to allocate new code-completion strings.
126*67e74705SXin Li CodeCompletionAllocator &Allocator;
127*67e74705SXin Li
128*67e74705SXin Li CodeCompletionTUInfo &CCTUInfo;
129*67e74705SXin Li
130*67e74705SXin Li /// \brief If non-NULL, a filter function used to remove any code-completion
131*67e74705SXin Li /// results that are not desirable.
132*67e74705SXin Li LookupFilter Filter;
133*67e74705SXin Li
134*67e74705SXin Li /// \brief Whether we should allow declarations as
135*67e74705SXin Li /// nested-name-specifiers that would otherwise be filtered out.
136*67e74705SXin Li bool AllowNestedNameSpecifiers;
137*67e74705SXin Li
138*67e74705SXin Li /// \brief If set, the type that we would prefer our resulting value
139*67e74705SXin Li /// declarations to have.
140*67e74705SXin Li ///
141*67e74705SXin Li /// Closely matching the preferred type gives a boost to a result's
142*67e74705SXin Li /// priority.
143*67e74705SXin Li CanQualType PreferredType;
144*67e74705SXin Li
145*67e74705SXin Li /// \brief A list of shadow maps, which is used to model name hiding at
146*67e74705SXin Li /// different levels of, e.g., the inheritance hierarchy.
147*67e74705SXin Li std::list<ShadowMap> ShadowMaps;
148*67e74705SXin Li
149*67e74705SXin Li /// \brief If we're potentially referring to a C++ member function, the set
150*67e74705SXin Li /// of qualifiers applied to the object type.
151*67e74705SXin Li Qualifiers ObjectTypeQualifiers;
152*67e74705SXin Li
153*67e74705SXin Li /// \brief Whether the \p ObjectTypeQualifiers field is active.
154*67e74705SXin Li bool HasObjectTypeQualifiers;
155*67e74705SXin Li
156*67e74705SXin Li /// \brief The selector that we prefer.
157*67e74705SXin Li Selector PreferredSelector;
158*67e74705SXin Li
159*67e74705SXin Li /// \brief The completion context in which we are gathering results.
160*67e74705SXin Li CodeCompletionContext CompletionContext;
161*67e74705SXin Li
162*67e74705SXin Li /// \brief If we are in an instance method definition, the \@implementation
163*67e74705SXin Li /// object.
164*67e74705SXin Li ObjCImplementationDecl *ObjCImplementation;
165*67e74705SXin Li
166*67e74705SXin Li void AdjustResultPriorityForDecl(Result &R);
167*67e74705SXin Li
168*67e74705SXin Li void MaybeAddConstructorResults(Result R);
169*67e74705SXin Li
170*67e74705SXin Li public:
ResultBuilder(Sema & SemaRef,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,const CodeCompletionContext & CompletionContext,LookupFilter Filter=nullptr)171*67e74705SXin Li explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
172*67e74705SXin Li CodeCompletionTUInfo &CCTUInfo,
173*67e74705SXin Li const CodeCompletionContext &CompletionContext,
174*67e74705SXin Li LookupFilter Filter = nullptr)
175*67e74705SXin Li : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo),
176*67e74705SXin Li Filter(Filter),
177*67e74705SXin Li AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false),
178*67e74705SXin Li CompletionContext(CompletionContext),
179*67e74705SXin Li ObjCImplementation(nullptr)
180*67e74705SXin Li {
181*67e74705SXin Li // If this is an Objective-C instance method definition, dig out the
182*67e74705SXin Li // corresponding implementation.
183*67e74705SXin Li switch (CompletionContext.getKind()) {
184*67e74705SXin Li case CodeCompletionContext::CCC_Expression:
185*67e74705SXin Li case CodeCompletionContext::CCC_ObjCMessageReceiver:
186*67e74705SXin Li case CodeCompletionContext::CCC_ParenthesizedExpression:
187*67e74705SXin Li case CodeCompletionContext::CCC_Statement:
188*67e74705SXin Li case CodeCompletionContext::CCC_Recovery:
189*67e74705SXin Li if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
190*67e74705SXin Li if (Method->isInstanceMethod())
191*67e74705SXin Li if (ObjCInterfaceDecl *Interface = Method->getClassInterface())
192*67e74705SXin Li ObjCImplementation = Interface->getImplementation();
193*67e74705SXin Li break;
194*67e74705SXin Li
195*67e74705SXin Li default:
196*67e74705SXin Li break;
197*67e74705SXin Li }
198*67e74705SXin Li }
199*67e74705SXin Li
200*67e74705SXin Li /// \brief Determine the priority for a reference to the given declaration.
201*67e74705SXin Li unsigned getBasePriority(const NamedDecl *D);
202*67e74705SXin Li
203*67e74705SXin Li /// \brief Whether we should include code patterns in the completion
204*67e74705SXin Li /// results.
includeCodePatterns() const205*67e74705SXin Li bool includeCodePatterns() const {
206*67e74705SXin Li return SemaRef.CodeCompleter &&
207*67e74705SXin Li SemaRef.CodeCompleter->includeCodePatterns();
208*67e74705SXin Li }
209*67e74705SXin Li
210*67e74705SXin Li /// \brief Set the filter used for code-completion results.
setFilter(LookupFilter Filter)211*67e74705SXin Li void setFilter(LookupFilter Filter) {
212*67e74705SXin Li this->Filter = Filter;
213*67e74705SXin Li }
214*67e74705SXin Li
data()215*67e74705SXin Li Result *data() { return Results.empty()? nullptr : &Results.front(); }
size() const216*67e74705SXin Li unsigned size() const { return Results.size(); }
empty() const217*67e74705SXin Li bool empty() const { return Results.empty(); }
218*67e74705SXin Li
219*67e74705SXin Li /// \brief Specify the preferred type.
setPreferredType(QualType T)220*67e74705SXin Li void setPreferredType(QualType T) {
221*67e74705SXin Li PreferredType = SemaRef.Context.getCanonicalType(T);
222*67e74705SXin Li }
223*67e74705SXin Li
224*67e74705SXin Li /// \brief Set the cv-qualifiers on the object type, for us in filtering
225*67e74705SXin Li /// calls to member functions.
226*67e74705SXin Li ///
227*67e74705SXin Li /// When there are qualifiers in this set, they will be used to filter
228*67e74705SXin Li /// out member functions that aren't available (because there will be a
229*67e74705SXin Li /// cv-qualifier mismatch) or prefer functions with an exact qualifier
230*67e74705SXin Li /// match.
setObjectTypeQualifiers(Qualifiers Quals)231*67e74705SXin Li void setObjectTypeQualifiers(Qualifiers Quals) {
232*67e74705SXin Li ObjectTypeQualifiers = Quals;
233*67e74705SXin Li HasObjectTypeQualifiers = true;
234*67e74705SXin Li }
235*67e74705SXin Li
236*67e74705SXin Li /// \brief Set the preferred selector.
237*67e74705SXin Li ///
238*67e74705SXin Li /// When an Objective-C method declaration result is added, and that
239*67e74705SXin Li /// method's selector matches this preferred selector, we give that method
240*67e74705SXin Li /// a slight priority boost.
setPreferredSelector(Selector Sel)241*67e74705SXin Li void setPreferredSelector(Selector Sel) {
242*67e74705SXin Li PreferredSelector = Sel;
243*67e74705SXin Li }
244*67e74705SXin Li
245*67e74705SXin Li /// \brief Retrieve the code-completion context for which results are
246*67e74705SXin Li /// being collected.
getCompletionContext() const247*67e74705SXin Li const CodeCompletionContext &getCompletionContext() const {
248*67e74705SXin Li return CompletionContext;
249*67e74705SXin Li }
250*67e74705SXin Li
251*67e74705SXin Li /// \brief Specify whether nested-name-specifiers are allowed.
allowNestedNameSpecifiers(bool Allow=true)252*67e74705SXin Li void allowNestedNameSpecifiers(bool Allow = true) {
253*67e74705SXin Li AllowNestedNameSpecifiers = Allow;
254*67e74705SXin Li }
255*67e74705SXin Li
256*67e74705SXin Li /// \brief Return the semantic analysis object for which we are collecting
257*67e74705SXin Li /// code completion results.
getSema() const258*67e74705SXin Li Sema &getSema() const { return SemaRef; }
259*67e74705SXin Li
260*67e74705SXin Li /// \brief Retrieve the allocator used to allocate code completion strings.
getAllocator() const261*67e74705SXin Li CodeCompletionAllocator &getAllocator() const { return Allocator; }
262*67e74705SXin Li
getCodeCompletionTUInfo() const263*67e74705SXin Li CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
264*67e74705SXin Li
265*67e74705SXin Li /// \brief Determine whether the given declaration is at all interesting
266*67e74705SXin Li /// as a code-completion result.
267*67e74705SXin Li ///
268*67e74705SXin Li /// \param ND the declaration that we are inspecting.
269*67e74705SXin Li ///
270*67e74705SXin Li /// \param AsNestedNameSpecifier will be set true if this declaration is
271*67e74705SXin Li /// only interesting when it is a nested-name-specifier.
272*67e74705SXin Li bool isInterestingDecl(const NamedDecl *ND,
273*67e74705SXin Li bool &AsNestedNameSpecifier) const;
274*67e74705SXin Li
275*67e74705SXin Li /// \brief Check whether the result is hidden by the Hiding declaration.
276*67e74705SXin Li ///
277*67e74705SXin Li /// \returns true if the result is hidden and cannot be found, false if
278*67e74705SXin Li /// the hidden result could still be found. When false, \p R may be
279*67e74705SXin Li /// modified to describe how the result can be found (e.g., via extra
280*67e74705SXin Li /// qualification).
281*67e74705SXin Li bool CheckHiddenResult(Result &R, DeclContext *CurContext,
282*67e74705SXin Li const NamedDecl *Hiding);
283*67e74705SXin Li
284*67e74705SXin Li /// \brief Add a new result to this result set (if it isn't already in one
285*67e74705SXin Li /// of the shadow maps), or replace an existing result (for, e.g., a
286*67e74705SXin Li /// redeclaration).
287*67e74705SXin Li ///
288*67e74705SXin Li /// \param R the result to add (if it is unique).
289*67e74705SXin Li ///
290*67e74705SXin Li /// \param CurContext the context in which this result will be named.
291*67e74705SXin Li void MaybeAddResult(Result R, DeclContext *CurContext = nullptr);
292*67e74705SXin Li
293*67e74705SXin Li /// \brief Add a new result to this result set, where we already know
294*67e74705SXin Li /// the hiding declaration (if any).
295*67e74705SXin Li ///
296*67e74705SXin Li /// \param R the result to add (if it is unique).
297*67e74705SXin Li ///
298*67e74705SXin Li /// \param CurContext the context in which this result will be named.
299*67e74705SXin Li ///
300*67e74705SXin Li /// \param Hiding the declaration that hides the result.
301*67e74705SXin Li ///
302*67e74705SXin Li /// \param InBaseClass whether the result was found in a base
303*67e74705SXin Li /// class of the searched context.
304*67e74705SXin Li void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
305*67e74705SXin Li bool InBaseClass);
306*67e74705SXin Li
307*67e74705SXin Li /// \brief Add a new non-declaration result to this result set.
308*67e74705SXin Li void AddResult(Result R);
309*67e74705SXin Li
310*67e74705SXin Li /// \brief Enter into a new scope.
311*67e74705SXin Li void EnterNewScope();
312*67e74705SXin Li
313*67e74705SXin Li /// \brief Exit from the current scope.
314*67e74705SXin Li void ExitScope();
315*67e74705SXin Li
316*67e74705SXin Li /// \brief Ignore this declaration, if it is seen again.
Ignore(const Decl * D)317*67e74705SXin Li void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
318*67e74705SXin Li
319*67e74705SXin Li /// \name Name lookup predicates
320*67e74705SXin Li ///
321*67e74705SXin Li /// These predicates can be passed to the name lookup functions to filter the
322*67e74705SXin Li /// results of name lookup. All of the predicates have the same type, so that
323*67e74705SXin Li ///
324*67e74705SXin Li //@{
325*67e74705SXin Li bool IsOrdinaryName(const NamedDecl *ND) const;
326*67e74705SXin Li bool IsOrdinaryNonTypeName(const NamedDecl *ND) const;
327*67e74705SXin Li bool IsIntegralConstantValue(const NamedDecl *ND) const;
328*67e74705SXin Li bool IsOrdinaryNonValueName(const NamedDecl *ND) const;
329*67e74705SXin Li bool IsNestedNameSpecifier(const NamedDecl *ND) const;
330*67e74705SXin Li bool IsEnum(const NamedDecl *ND) const;
331*67e74705SXin Li bool IsClassOrStruct(const NamedDecl *ND) const;
332*67e74705SXin Li bool IsUnion(const NamedDecl *ND) const;
333*67e74705SXin Li bool IsNamespace(const NamedDecl *ND) const;
334*67e74705SXin Li bool IsNamespaceOrAlias(const NamedDecl *ND) const;
335*67e74705SXin Li bool IsType(const NamedDecl *ND) const;
336*67e74705SXin Li bool IsMember(const NamedDecl *ND) const;
337*67e74705SXin Li bool IsObjCIvar(const NamedDecl *ND) const;
338*67e74705SXin Li bool IsObjCMessageReceiver(const NamedDecl *ND) const;
339*67e74705SXin Li bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const;
340*67e74705SXin Li bool IsObjCCollection(const NamedDecl *ND) const;
341*67e74705SXin Li bool IsImpossibleToSatisfy(const NamedDecl *ND) const;
342*67e74705SXin Li //@}
343*67e74705SXin Li };
344*67e74705SXin Li }
345*67e74705SXin Li
346*67e74705SXin Li class ResultBuilder::ShadowMapEntry::iterator {
347*67e74705SXin Li llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator;
348*67e74705SXin Li unsigned SingleDeclIndex;
349*67e74705SXin Li
350*67e74705SXin Li public:
351*67e74705SXin Li typedef DeclIndexPair value_type;
352*67e74705SXin Li typedef value_type reference;
353*67e74705SXin Li typedef std::ptrdiff_t difference_type;
354*67e74705SXin Li typedef std::input_iterator_tag iterator_category;
355*67e74705SXin Li
356*67e74705SXin Li class pointer {
357*67e74705SXin Li DeclIndexPair Value;
358*67e74705SXin Li
359*67e74705SXin Li public:
pointer(const DeclIndexPair & Value)360*67e74705SXin Li pointer(const DeclIndexPair &Value) : Value(Value) { }
361*67e74705SXin Li
operator ->() const362*67e74705SXin Li const DeclIndexPair *operator->() const {
363*67e74705SXin Li return &Value;
364*67e74705SXin Li }
365*67e74705SXin Li };
366*67e74705SXin Li
iterator()367*67e74705SXin Li iterator() : DeclOrIterator((NamedDecl *)nullptr), SingleDeclIndex(0) {}
368*67e74705SXin Li
iterator(const NamedDecl * SingleDecl,unsigned Index)369*67e74705SXin Li iterator(const NamedDecl *SingleDecl, unsigned Index)
370*67e74705SXin Li : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
371*67e74705SXin Li
iterator(const DeclIndexPair * Iterator)372*67e74705SXin Li iterator(const DeclIndexPair *Iterator)
373*67e74705SXin Li : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
374*67e74705SXin Li
operator ++()375*67e74705SXin Li iterator &operator++() {
376*67e74705SXin Li if (DeclOrIterator.is<const NamedDecl *>()) {
377*67e74705SXin Li DeclOrIterator = (NamedDecl *)nullptr;
378*67e74705SXin Li SingleDeclIndex = 0;
379*67e74705SXin Li return *this;
380*67e74705SXin Li }
381*67e74705SXin Li
382*67e74705SXin Li const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
383*67e74705SXin Li ++I;
384*67e74705SXin Li DeclOrIterator = I;
385*67e74705SXin Li return *this;
386*67e74705SXin Li }
387*67e74705SXin Li
388*67e74705SXin Li /*iterator operator++(int) {
389*67e74705SXin Li iterator tmp(*this);
390*67e74705SXin Li ++(*this);
391*67e74705SXin Li return tmp;
392*67e74705SXin Li }*/
393*67e74705SXin Li
operator *() const394*67e74705SXin Li reference operator*() const {
395*67e74705SXin Li if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>())
396*67e74705SXin Li return reference(ND, SingleDeclIndex);
397*67e74705SXin Li
398*67e74705SXin Li return *DeclOrIterator.get<const DeclIndexPair*>();
399*67e74705SXin Li }
400*67e74705SXin Li
operator ->() const401*67e74705SXin Li pointer operator->() const {
402*67e74705SXin Li return pointer(**this);
403*67e74705SXin Li }
404*67e74705SXin Li
operator ==(const iterator & X,const iterator & Y)405*67e74705SXin Li friend bool operator==(const iterator &X, const iterator &Y) {
406*67e74705SXin Li return X.DeclOrIterator.getOpaqueValue()
407*67e74705SXin Li == Y.DeclOrIterator.getOpaqueValue() &&
408*67e74705SXin Li X.SingleDeclIndex == Y.SingleDeclIndex;
409*67e74705SXin Li }
410*67e74705SXin Li
operator !=(const iterator & X,const iterator & Y)411*67e74705SXin Li friend bool operator!=(const iterator &X, const iterator &Y) {
412*67e74705SXin Li return !(X == Y);
413*67e74705SXin Li }
414*67e74705SXin Li };
415*67e74705SXin Li
416*67e74705SXin Li ResultBuilder::ShadowMapEntry::iterator
begin() const417*67e74705SXin Li ResultBuilder::ShadowMapEntry::begin() const {
418*67e74705SXin Li if (DeclOrVector.isNull())
419*67e74705SXin Li return iterator();
420*67e74705SXin Li
421*67e74705SXin Li if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>())
422*67e74705SXin Li return iterator(ND, SingleDeclIndex);
423*67e74705SXin Li
424*67e74705SXin Li return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
425*67e74705SXin Li }
426*67e74705SXin Li
427*67e74705SXin Li ResultBuilder::ShadowMapEntry::iterator
end() const428*67e74705SXin Li ResultBuilder::ShadowMapEntry::end() const {
429*67e74705SXin Li if (DeclOrVector.is<const NamedDecl *>() || DeclOrVector.isNull())
430*67e74705SXin Li return iterator();
431*67e74705SXin Li
432*67e74705SXin Li return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
433*67e74705SXin Li }
434*67e74705SXin Li
435*67e74705SXin Li /// \brief Compute the qualification required to get from the current context
436*67e74705SXin Li /// (\p CurContext) to the target context (\p TargetContext).
437*67e74705SXin Li ///
438*67e74705SXin Li /// \param Context the AST context in which the qualification will be used.
439*67e74705SXin Li ///
440*67e74705SXin Li /// \param CurContext the context where an entity is being named, which is
441*67e74705SXin Li /// typically based on the current scope.
442*67e74705SXin Li ///
443*67e74705SXin Li /// \param TargetContext the context in which the named entity actually
444*67e74705SXin Li /// resides.
445*67e74705SXin Li ///
446*67e74705SXin Li /// \returns a nested name specifier that refers into the target context, or
447*67e74705SXin Li /// NULL if no qualification is needed.
448*67e74705SXin Li static NestedNameSpecifier *
getRequiredQualification(ASTContext & Context,const DeclContext * CurContext,const DeclContext * TargetContext)449*67e74705SXin Li getRequiredQualification(ASTContext &Context,
450*67e74705SXin Li const DeclContext *CurContext,
451*67e74705SXin Li const DeclContext *TargetContext) {
452*67e74705SXin Li SmallVector<const DeclContext *, 4> TargetParents;
453*67e74705SXin Li
454*67e74705SXin Li for (const DeclContext *CommonAncestor = TargetContext;
455*67e74705SXin Li CommonAncestor && !CommonAncestor->Encloses(CurContext);
456*67e74705SXin Li CommonAncestor = CommonAncestor->getLookupParent()) {
457*67e74705SXin Li if (CommonAncestor->isTransparentContext() ||
458*67e74705SXin Li CommonAncestor->isFunctionOrMethod())
459*67e74705SXin Li continue;
460*67e74705SXin Li
461*67e74705SXin Li TargetParents.push_back(CommonAncestor);
462*67e74705SXin Li }
463*67e74705SXin Li
464*67e74705SXin Li NestedNameSpecifier *Result = nullptr;
465*67e74705SXin Li while (!TargetParents.empty()) {
466*67e74705SXin Li const DeclContext *Parent = TargetParents.pop_back_val();
467*67e74705SXin Li
468*67e74705SXin Li if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
469*67e74705SXin Li if (!Namespace->getIdentifier())
470*67e74705SXin Li continue;
471*67e74705SXin Li
472*67e74705SXin Li Result = NestedNameSpecifier::Create(Context, Result, Namespace);
473*67e74705SXin Li }
474*67e74705SXin Li else if (const TagDecl *TD = dyn_cast<TagDecl>(Parent))
475*67e74705SXin Li Result = NestedNameSpecifier::Create(Context, Result,
476*67e74705SXin Li false,
477*67e74705SXin Li Context.getTypeDeclType(TD).getTypePtr());
478*67e74705SXin Li }
479*67e74705SXin Li return Result;
480*67e74705SXin Li }
481*67e74705SXin Li
482*67e74705SXin Li /// Determine whether \p Id is a name reserved for the implementation (C99
483*67e74705SXin Li /// 7.1.3, C++ [lib.global.names]).
isReservedName(const IdentifierInfo * Id,bool doubleUnderscoreOnly=false)484*67e74705SXin Li static bool isReservedName(const IdentifierInfo *Id,
485*67e74705SXin Li bool doubleUnderscoreOnly = false) {
486*67e74705SXin Li if (Id->getLength() < 2)
487*67e74705SXin Li return false;
488*67e74705SXin Li const char *Name = Id->getNameStart();
489*67e74705SXin Li return Name[0] == '_' &&
490*67e74705SXin Li (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z' &&
491*67e74705SXin Li !doubleUnderscoreOnly));
492*67e74705SXin Li }
493*67e74705SXin Li
494*67e74705SXin Li // Some declarations have reserved names that we don't want to ever show.
495*67e74705SXin Li // Filter out names reserved for the implementation if they come from a
496*67e74705SXin Li // system header.
shouldIgnoreDueToReservedName(const NamedDecl * ND,Sema & SemaRef)497*67e74705SXin Li static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) {
498*67e74705SXin Li const IdentifierInfo *Id = ND->getIdentifier();
499*67e74705SXin Li if (!Id)
500*67e74705SXin Li return false;
501*67e74705SXin Li
502*67e74705SXin Li // Ignore reserved names for compiler provided decls.
503*67e74705SXin Li if (isReservedName(Id) && ND->getLocation().isInvalid())
504*67e74705SXin Li return true;
505*67e74705SXin Li
506*67e74705SXin Li // For system headers ignore only double-underscore names.
507*67e74705SXin Li // This allows for system headers providing private symbols with a single
508*67e74705SXin Li // underscore.
509*67e74705SXin Li if (isReservedName(Id, /*doubleUnderscoreOnly=*/true) &&
510*67e74705SXin Li SemaRef.SourceMgr.isInSystemHeader(
511*67e74705SXin Li SemaRef.SourceMgr.getSpellingLoc(ND->getLocation())))
512*67e74705SXin Li return true;
513*67e74705SXin Li
514*67e74705SXin Li return false;
515*67e74705SXin Li }
516*67e74705SXin Li
isInterestingDecl(const NamedDecl * ND,bool & AsNestedNameSpecifier) const517*67e74705SXin Li bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
518*67e74705SXin Li bool &AsNestedNameSpecifier) const {
519*67e74705SXin Li AsNestedNameSpecifier = false;
520*67e74705SXin Li
521*67e74705SXin Li auto *Named = ND;
522*67e74705SXin Li ND = ND->getUnderlyingDecl();
523*67e74705SXin Li
524*67e74705SXin Li // Skip unnamed entities.
525*67e74705SXin Li if (!ND->getDeclName())
526*67e74705SXin Li return false;
527*67e74705SXin Li
528*67e74705SXin Li // Friend declarations and declarations introduced due to friends are never
529*67e74705SXin Li // added as results.
530*67e74705SXin Li if (ND->getFriendObjectKind() == Decl::FOK_Undeclared)
531*67e74705SXin Li return false;
532*67e74705SXin Li
533*67e74705SXin Li // Class template (partial) specializations are never added as results.
534*67e74705SXin Li if (isa<ClassTemplateSpecializationDecl>(ND) ||
535*67e74705SXin Li isa<ClassTemplatePartialSpecializationDecl>(ND))
536*67e74705SXin Li return false;
537*67e74705SXin Li
538*67e74705SXin Li // Using declarations themselves are never added as results.
539*67e74705SXin Li if (isa<UsingDecl>(ND))
540*67e74705SXin Li return false;
541*67e74705SXin Li
542*67e74705SXin Li if (shouldIgnoreDueToReservedName(ND, SemaRef))
543*67e74705SXin Li return false;
544*67e74705SXin Li
545*67e74705SXin Li if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
546*67e74705SXin Li (isa<NamespaceDecl>(ND) &&
547*67e74705SXin Li Filter != &ResultBuilder::IsNamespace &&
548*67e74705SXin Li Filter != &ResultBuilder::IsNamespaceOrAlias &&
549*67e74705SXin Li Filter != nullptr))
550*67e74705SXin Li AsNestedNameSpecifier = true;
551*67e74705SXin Li
552*67e74705SXin Li // Filter out any unwanted results.
553*67e74705SXin Li if (Filter && !(this->*Filter)(Named)) {
554*67e74705SXin Li // Check whether it is interesting as a nested-name-specifier.
555*67e74705SXin Li if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus &&
556*67e74705SXin Li IsNestedNameSpecifier(ND) &&
557*67e74705SXin Li (Filter != &ResultBuilder::IsMember ||
558*67e74705SXin Li (isa<CXXRecordDecl>(ND) &&
559*67e74705SXin Li cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
560*67e74705SXin Li AsNestedNameSpecifier = true;
561*67e74705SXin Li return true;
562*67e74705SXin Li }
563*67e74705SXin Li
564*67e74705SXin Li return false;
565*67e74705SXin Li }
566*67e74705SXin Li // ... then it must be interesting!
567*67e74705SXin Li return true;
568*67e74705SXin Li }
569*67e74705SXin Li
CheckHiddenResult(Result & R,DeclContext * CurContext,const NamedDecl * Hiding)570*67e74705SXin Li bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
571*67e74705SXin Li const NamedDecl *Hiding) {
572*67e74705SXin Li // In C, there is no way to refer to a hidden name.
573*67e74705SXin Li // FIXME: This isn't true; we can find a tag name hidden by an ordinary
574*67e74705SXin Li // name if we introduce the tag type.
575*67e74705SXin Li if (!SemaRef.getLangOpts().CPlusPlus)
576*67e74705SXin Li return true;
577*67e74705SXin Li
578*67e74705SXin Li const DeclContext *HiddenCtx =
579*67e74705SXin Li R.Declaration->getDeclContext()->getRedeclContext();
580*67e74705SXin Li
581*67e74705SXin Li // There is no way to qualify a name declared in a function or method.
582*67e74705SXin Li if (HiddenCtx->isFunctionOrMethod())
583*67e74705SXin Li return true;
584*67e74705SXin Li
585*67e74705SXin Li if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
586*67e74705SXin Li return true;
587*67e74705SXin Li
588*67e74705SXin Li // We can refer to the result with the appropriate qualification. Do it.
589*67e74705SXin Li R.Hidden = true;
590*67e74705SXin Li R.QualifierIsInformative = false;
591*67e74705SXin Li
592*67e74705SXin Li if (!R.Qualifier)
593*67e74705SXin Li R.Qualifier = getRequiredQualification(SemaRef.Context,
594*67e74705SXin Li CurContext,
595*67e74705SXin Li R.Declaration->getDeclContext());
596*67e74705SXin Li return false;
597*67e74705SXin Li }
598*67e74705SXin Li
599*67e74705SXin Li /// \brief A simplified classification of types used to determine whether two
600*67e74705SXin Li /// types are "similar enough" when adjusting priorities.
getSimplifiedTypeClass(CanQualType T)601*67e74705SXin Li SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
602*67e74705SXin Li switch (T->getTypeClass()) {
603*67e74705SXin Li case Type::Builtin:
604*67e74705SXin Li switch (cast<BuiltinType>(T)->getKind()) {
605*67e74705SXin Li case BuiltinType::Void:
606*67e74705SXin Li return STC_Void;
607*67e74705SXin Li
608*67e74705SXin Li case BuiltinType::NullPtr:
609*67e74705SXin Li return STC_Pointer;
610*67e74705SXin Li
611*67e74705SXin Li case BuiltinType::Overload:
612*67e74705SXin Li case BuiltinType::Dependent:
613*67e74705SXin Li return STC_Other;
614*67e74705SXin Li
615*67e74705SXin Li case BuiltinType::ObjCId:
616*67e74705SXin Li case BuiltinType::ObjCClass:
617*67e74705SXin Li case BuiltinType::ObjCSel:
618*67e74705SXin Li return STC_ObjectiveC;
619*67e74705SXin Li
620*67e74705SXin Li default:
621*67e74705SXin Li return STC_Arithmetic;
622*67e74705SXin Li }
623*67e74705SXin Li
624*67e74705SXin Li case Type::Complex:
625*67e74705SXin Li return STC_Arithmetic;
626*67e74705SXin Li
627*67e74705SXin Li case Type::Pointer:
628*67e74705SXin Li return STC_Pointer;
629*67e74705SXin Li
630*67e74705SXin Li case Type::BlockPointer:
631*67e74705SXin Li return STC_Block;
632*67e74705SXin Li
633*67e74705SXin Li case Type::LValueReference:
634*67e74705SXin Li case Type::RValueReference:
635*67e74705SXin Li return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
636*67e74705SXin Li
637*67e74705SXin Li case Type::ConstantArray:
638*67e74705SXin Li case Type::IncompleteArray:
639*67e74705SXin Li case Type::VariableArray:
640*67e74705SXin Li case Type::DependentSizedArray:
641*67e74705SXin Li return STC_Array;
642*67e74705SXin Li
643*67e74705SXin Li case Type::DependentSizedExtVector:
644*67e74705SXin Li case Type::Vector:
645*67e74705SXin Li case Type::ExtVector:
646*67e74705SXin Li return STC_Arithmetic;
647*67e74705SXin Li
648*67e74705SXin Li case Type::FunctionProto:
649*67e74705SXin Li case Type::FunctionNoProto:
650*67e74705SXin Li return STC_Function;
651*67e74705SXin Li
652*67e74705SXin Li case Type::Record:
653*67e74705SXin Li return STC_Record;
654*67e74705SXin Li
655*67e74705SXin Li case Type::Enum:
656*67e74705SXin Li return STC_Arithmetic;
657*67e74705SXin Li
658*67e74705SXin Li case Type::ObjCObject:
659*67e74705SXin Li case Type::ObjCInterface:
660*67e74705SXin Li case Type::ObjCObjectPointer:
661*67e74705SXin Li return STC_ObjectiveC;
662*67e74705SXin Li
663*67e74705SXin Li default:
664*67e74705SXin Li return STC_Other;
665*67e74705SXin Li }
666*67e74705SXin Li }
667*67e74705SXin Li
668*67e74705SXin Li /// \brief Get the type that a given expression will have if this declaration
669*67e74705SXin Li /// is used as an expression in its "typical" code-completion form.
getDeclUsageType(ASTContext & C,const NamedDecl * ND)670*67e74705SXin Li QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
671*67e74705SXin Li ND = cast<NamedDecl>(ND->getUnderlyingDecl());
672*67e74705SXin Li
673*67e74705SXin Li if (const TypeDecl *Type = dyn_cast<TypeDecl>(ND))
674*67e74705SXin Li return C.getTypeDeclType(Type);
675*67e74705SXin Li if (const ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
676*67e74705SXin Li return C.getObjCInterfaceType(Iface);
677*67e74705SXin Li
678*67e74705SXin Li QualType T;
679*67e74705SXin Li if (const FunctionDecl *Function = ND->getAsFunction())
680*67e74705SXin Li T = Function->getCallResultType();
681*67e74705SXin Li else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
682*67e74705SXin Li T = Method->getSendResultType();
683*67e74705SXin Li else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
684*67e74705SXin Li T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
685*67e74705SXin Li else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
686*67e74705SXin Li T = Property->getType();
687*67e74705SXin Li else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND))
688*67e74705SXin Li T = Value->getType();
689*67e74705SXin Li else
690*67e74705SXin Li return QualType();
691*67e74705SXin Li
692*67e74705SXin Li // Dig through references, function pointers, and block pointers to
693*67e74705SXin Li // get down to the likely type of an expression when the entity is
694*67e74705SXin Li // used.
695*67e74705SXin Li do {
696*67e74705SXin Li if (const ReferenceType *Ref = T->getAs<ReferenceType>()) {
697*67e74705SXin Li T = Ref->getPointeeType();
698*67e74705SXin Li continue;
699*67e74705SXin Li }
700*67e74705SXin Li
701*67e74705SXin Li if (const PointerType *Pointer = T->getAs<PointerType>()) {
702*67e74705SXin Li if (Pointer->getPointeeType()->isFunctionType()) {
703*67e74705SXin Li T = Pointer->getPointeeType();
704*67e74705SXin Li continue;
705*67e74705SXin Li }
706*67e74705SXin Li
707*67e74705SXin Li break;
708*67e74705SXin Li }
709*67e74705SXin Li
710*67e74705SXin Li if (const BlockPointerType *Block = T->getAs<BlockPointerType>()) {
711*67e74705SXin Li T = Block->getPointeeType();
712*67e74705SXin Li continue;
713*67e74705SXin Li }
714*67e74705SXin Li
715*67e74705SXin Li if (const FunctionType *Function = T->getAs<FunctionType>()) {
716*67e74705SXin Li T = Function->getReturnType();
717*67e74705SXin Li continue;
718*67e74705SXin Li }
719*67e74705SXin Li
720*67e74705SXin Li break;
721*67e74705SXin Li } while (true);
722*67e74705SXin Li
723*67e74705SXin Li return T;
724*67e74705SXin Li }
725*67e74705SXin Li
getBasePriority(const NamedDecl * ND)726*67e74705SXin Li unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) {
727*67e74705SXin Li if (!ND)
728*67e74705SXin Li return CCP_Unlikely;
729*67e74705SXin Li
730*67e74705SXin Li // Context-based decisions.
731*67e74705SXin Li const DeclContext *LexicalDC = ND->getLexicalDeclContext();
732*67e74705SXin Li if (LexicalDC->isFunctionOrMethod()) {
733*67e74705SXin Li // _cmd is relatively rare
734*67e74705SXin Li if (const ImplicitParamDecl *ImplicitParam =
735*67e74705SXin Li dyn_cast<ImplicitParamDecl>(ND))
736*67e74705SXin Li if (ImplicitParam->getIdentifier() &&
737*67e74705SXin Li ImplicitParam->getIdentifier()->isStr("_cmd"))
738*67e74705SXin Li return CCP_ObjC_cmd;
739*67e74705SXin Li
740*67e74705SXin Li return CCP_LocalDeclaration;
741*67e74705SXin Li }
742*67e74705SXin Li
743*67e74705SXin Li const DeclContext *DC = ND->getDeclContext()->getRedeclContext();
744*67e74705SXin Li if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
745*67e74705SXin Li return CCP_MemberDeclaration;
746*67e74705SXin Li
747*67e74705SXin Li // Content-based decisions.
748*67e74705SXin Li if (isa<EnumConstantDecl>(ND))
749*67e74705SXin Li return CCP_Constant;
750*67e74705SXin Li
751*67e74705SXin Li // Use CCP_Type for type declarations unless we're in a statement, Objective-C
752*67e74705SXin Li // message receiver, or parenthesized expression context. There, it's as
753*67e74705SXin Li // likely that the user will want to write a type as other declarations.
754*67e74705SXin Li if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
755*67e74705SXin Li !(CompletionContext.getKind() == CodeCompletionContext::CCC_Statement ||
756*67e74705SXin Li CompletionContext.getKind()
757*67e74705SXin Li == CodeCompletionContext::CCC_ObjCMessageReceiver ||
758*67e74705SXin Li CompletionContext.getKind()
759*67e74705SXin Li == CodeCompletionContext::CCC_ParenthesizedExpression))
760*67e74705SXin Li return CCP_Type;
761*67e74705SXin Li
762*67e74705SXin Li return CCP_Declaration;
763*67e74705SXin Li }
764*67e74705SXin Li
AdjustResultPriorityForDecl(Result & R)765*67e74705SXin Li void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
766*67e74705SXin Li // If this is an Objective-C method declaration whose selector matches our
767*67e74705SXin Li // preferred selector, give it a priority boost.
768*67e74705SXin Li if (!PreferredSelector.isNull())
769*67e74705SXin Li if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
770*67e74705SXin Li if (PreferredSelector == Method->getSelector())
771*67e74705SXin Li R.Priority += CCD_SelectorMatch;
772*67e74705SXin Li
773*67e74705SXin Li // If we have a preferred type, adjust the priority for results with exactly-
774*67e74705SXin Li // matching or nearly-matching types.
775*67e74705SXin Li if (!PreferredType.isNull()) {
776*67e74705SXin Li QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
777*67e74705SXin Li if (!T.isNull()) {
778*67e74705SXin Li CanQualType TC = SemaRef.Context.getCanonicalType(T);
779*67e74705SXin Li // Check for exactly-matching types (modulo qualifiers).
780*67e74705SXin Li if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
781*67e74705SXin Li R.Priority /= CCF_ExactTypeMatch;
782*67e74705SXin Li // Check for nearly-matching types, based on classification of each.
783*67e74705SXin Li else if ((getSimplifiedTypeClass(PreferredType)
784*67e74705SXin Li == getSimplifiedTypeClass(TC)) &&
785*67e74705SXin Li !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
786*67e74705SXin Li R.Priority /= CCF_SimilarTypeMatch;
787*67e74705SXin Li }
788*67e74705SXin Li }
789*67e74705SXin Li }
790*67e74705SXin Li
MaybeAddConstructorResults(Result R)791*67e74705SXin Li void ResultBuilder::MaybeAddConstructorResults(Result R) {
792*67e74705SXin Li if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration ||
793*67e74705SXin Li !CompletionContext.wantConstructorResults())
794*67e74705SXin Li return;
795*67e74705SXin Li
796*67e74705SXin Li ASTContext &Context = SemaRef.Context;
797*67e74705SXin Li const NamedDecl *D = R.Declaration;
798*67e74705SXin Li const CXXRecordDecl *Record = nullptr;
799*67e74705SXin Li if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
800*67e74705SXin Li Record = ClassTemplate->getTemplatedDecl();
801*67e74705SXin Li else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
802*67e74705SXin Li // Skip specializations and partial specializations.
803*67e74705SXin Li if (isa<ClassTemplateSpecializationDecl>(Record))
804*67e74705SXin Li return;
805*67e74705SXin Li } else {
806*67e74705SXin Li // There are no constructors here.
807*67e74705SXin Li return;
808*67e74705SXin Li }
809*67e74705SXin Li
810*67e74705SXin Li Record = Record->getDefinition();
811*67e74705SXin Li if (!Record)
812*67e74705SXin Li return;
813*67e74705SXin Li
814*67e74705SXin Li
815*67e74705SXin Li QualType RecordTy = Context.getTypeDeclType(Record);
816*67e74705SXin Li DeclarationName ConstructorName
817*67e74705SXin Li = Context.DeclarationNames.getCXXConstructorName(
818*67e74705SXin Li Context.getCanonicalType(RecordTy));
819*67e74705SXin Li DeclContext::lookup_result Ctors = Record->lookup(ConstructorName);
820*67e74705SXin Li for (DeclContext::lookup_iterator I = Ctors.begin(),
821*67e74705SXin Li E = Ctors.end();
822*67e74705SXin Li I != E; ++I) {
823*67e74705SXin Li R.Declaration = *I;
824*67e74705SXin Li R.CursorKind = getCursorKindForDecl(R.Declaration);
825*67e74705SXin Li Results.push_back(R);
826*67e74705SXin Li }
827*67e74705SXin Li }
828*67e74705SXin Li
MaybeAddResult(Result R,DeclContext * CurContext)829*67e74705SXin Li void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
830*67e74705SXin Li assert(!ShadowMaps.empty() && "Must enter into a results scope");
831*67e74705SXin Li
832*67e74705SXin Li if (R.Kind != Result::RK_Declaration) {
833*67e74705SXin Li // For non-declaration results, just add the result.
834*67e74705SXin Li Results.push_back(R);
835*67e74705SXin Li return;
836*67e74705SXin Li }
837*67e74705SXin Li
838*67e74705SXin Li // Look through using declarations.
839*67e74705SXin Li if (const UsingShadowDecl *Using =
840*67e74705SXin Li dyn_cast<UsingShadowDecl>(R.Declaration)) {
841*67e74705SXin Li MaybeAddResult(Result(Using->getTargetDecl(),
842*67e74705SXin Li getBasePriority(Using->getTargetDecl()),
843*67e74705SXin Li R.Qualifier),
844*67e74705SXin Li CurContext);
845*67e74705SXin Li return;
846*67e74705SXin Li }
847*67e74705SXin Li
848*67e74705SXin Li const Decl *CanonDecl = R.Declaration->getCanonicalDecl();
849*67e74705SXin Li unsigned IDNS = CanonDecl->getIdentifierNamespace();
850*67e74705SXin Li
851*67e74705SXin Li bool AsNestedNameSpecifier = false;
852*67e74705SXin Li if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
853*67e74705SXin Li return;
854*67e74705SXin Li
855*67e74705SXin Li // C++ constructors are never found by name lookup.
856*67e74705SXin Li if (isa<CXXConstructorDecl>(R.Declaration))
857*67e74705SXin Li return;
858*67e74705SXin Li
859*67e74705SXin Li ShadowMap &SMap = ShadowMaps.back();
860*67e74705SXin Li ShadowMapEntry::iterator I, IEnd;
861*67e74705SXin Li ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
862*67e74705SXin Li if (NamePos != SMap.end()) {
863*67e74705SXin Li I = NamePos->second.begin();
864*67e74705SXin Li IEnd = NamePos->second.end();
865*67e74705SXin Li }
866*67e74705SXin Li
867*67e74705SXin Li for (; I != IEnd; ++I) {
868*67e74705SXin Li const NamedDecl *ND = I->first;
869*67e74705SXin Li unsigned Index = I->second;
870*67e74705SXin Li if (ND->getCanonicalDecl() == CanonDecl) {
871*67e74705SXin Li // This is a redeclaration. Always pick the newer declaration.
872*67e74705SXin Li Results[Index].Declaration = R.Declaration;
873*67e74705SXin Li
874*67e74705SXin Li // We're done.
875*67e74705SXin Li return;
876*67e74705SXin Li }
877*67e74705SXin Li }
878*67e74705SXin Li
879*67e74705SXin Li // This is a new declaration in this scope. However, check whether this
880*67e74705SXin Li // declaration name is hidden by a similarly-named declaration in an outer
881*67e74705SXin Li // scope.
882*67e74705SXin Li std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
883*67e74705SXin Li --SMEnd;
884*67e74705SXin Li for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
885*67e74705SXin Li ShadowMapEntry::iterator I, IEnd;
886*67e74705SXin Li ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
887*67e74705SXin Li if (NamePos != SM->end()) {
888*67e74705SXin Li I = NamePos->second.begin();
889*67e74705SXin Li IEnd = NamePos->second.end();
890*67e74705SXin Li }
891*67e74705SXin Li for (; I != IEnd; ++I) {
892*67e74705SXin Li // A tag declaration does not hide a non-tag declaration.
893*67e74705SXin Li if (I->first->hasTagIdentifierNamespace() &&
894*67e74705SXin Li (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
895*67e74705SXin Li Decl::IDNS_LocalExtern | Decl::IDNS_ObjCProtocol)))
896*67e74705SXin Li continue;
897*67e74705SXin Li
898*67e74705SXin Li // Protocols are in distinct namespaces from everything else.
899*67e74705SXin Li if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
900*67e74705SXin Li || (IDNS & Decl::IDNS_ObjCProtocol)) &&
901*67e74705SXin Li I->first->getIdentifierNamespace() != IDNS)
902*67e74705SXin Li continue;
903*67e74705SXin Li
904*67e74705SXin Li // The newly-added result is hidden by an entry in the shadow map.
905*67e74705SXin Li if (CheckHiddenResult(R, CurContext, I->first))
906*67e74705SXin Li return;
907*67e74705SXin Li
908*67e74705SXin Li break;
909*67e74705SXin Li }
910*67e74705SXin Li }
911*67e74705SXin Li
912*67e74705SXin Li // Make sure that any given declaration only shows up in the result set once.
913*67e74705SXin Li if (!AllDeclsFound.insert(CanonDecl).second)
914*67e74705SXin Li return;
915*67e74705SXin Li
916*67e74705SXin Li // If the filter is for nested-name-specifiers, then this result starts a
917*67e74705SXin Li // nested-name-specifier.
918*67e74705SXin Li if (AsNestedNameSpecifier) {
919*67e74705SXin Li R.StartsNestedNameSpecifier = true;
920*67e74705SXin Li R.Priority = CCP_NestedNameSpecifier;
921*67e74705SXin Li } else
922*67e74705SXin Li AdjustResultPriorityForDecl(R);
923*67e74705SXin Li
924*67e74705SXin Li // If this result is supposed to have an informative qualifier, add one.
925*67e74705SXin Li if (R.QualifierIsInformative && !R.Qualifier &&
926*67e74705SXin Li !R.StartsNestedNameSpecifier) {
927*67e74705SXin Li const DeclContext *Ctx = R.Declaration->getDeclContext();
928*67e74705SXin Li if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
929*67e74705SXin Li R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr,
930*67e74705SXin Li Namespace);
931*67e74705SXin Li else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
932*67e74705SXin Li R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr,
933*67e74705SXin Li false, SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
934*67e74705SXin Li else
935*67e74705SXin Li R.QualifierIsInformative = false;
936*67e74705SXin Li }
937*67e74705SXin Li
938*67e74705SXin Li // Insert this result into the set of results and into the current shadow
939*67e74705SXin Li // map.
940*67e74705SXin Li SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
941*67e74705SXin Li Results.push_back(R);
942*67e74705SXin Li
943*67e74705SXin Li if (!AsNestedNameSpecifier)
944*67e74705SXin Li MaybeAddConstructorResults(R);
945*67e74705SXin Li }
946*67e74705SXin Li
AddResult(Result R,DeclContext * CurContext,NamedDecl * Hiding,bool InBaseClass=false)947*67e74705SXin Li void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
948*67e74705SXin Li NamedDecl *Hiding, bool InBaseClass = false) {
949*67e74705SXin Li if (R.Kind != Result::RK_Declaration) {
950*67e74705SXin Li // For non-declaration results, just add the result.
951*67e74705SXin Li Results.push_back(R);
952*67e74705SXin Li return;
953*67e74705SXin Li }
954*67e74705SXin Li
955*67e74705SXin Li // Look through using declarations.
956*67e74705SXin Li if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
957*67e74705SXin Li AddResult(Result(Using->getTargetDecl(),
958*67e74705SXin Li getBasePriority(Using->getTargetDecl()),
959*67e74705SXin Li R.Qualifier),
960*67e74705SXin Li CurContext, Hiding);
961*67e74705SXin Li return;
962*67e74705SXin Li }
963*67e74705SXin Li
964*67e74705SXin Li bool AsNestedNameSpecifier = false;
965*67e74705SXin Li if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
966*67e74705SXin Li return;
967*67e74705SXin Li
968*67e74705SXin Li // C++ constructors are never found by name lookup.
969*67e74705SXin Li if (isa<CXXConstructorDecl>(R.Declaration))
970*67e74705SXin Li return;
971*67e74705SXin Li
972*67e74705SXin Li if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
973*67e74705SXin Li return;
974*67e74705SXin Li
975*67e74705SXin Li // Make sure that any given declaration only shows up in the result set once.
976*67e74705SXin Li if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()).second)
977*67e74705SXin Li return;
978*67e74705SXin Li
979*67e74705SXin Li // If the filter is for nested-name-specifiers, then this result starts a
980*67e74705SXin Li // nested-name-specifier.
981*67e74705SXin Li if (AsNestedNameSpecifier) {
982*67e74705SXin Li R.StartsNestedNameSpecifier = true;
983*67e74705SXin Li R.Priority = CCP_NestedNameSpecifier;
984*67e74705SXin Li }
985*67e74705SXin Li else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
986*67e74705SXin Li isa<CXXRecordDecl>(R.Declaration->getDeclContext()
987*67e74705SXin Li ->getRedeclContext()))
988*67e74705SXin Li R.QualifierIsInformative = true;
989*67e74705SXin Li
990*67e74705SXin Li // If this result is supposed to have an informative qualifier, add one.
991*67e74705SXin Li if (R.QualifierIsInformative && !R.Qualifier &&
992*67e74705SXin Li !R.StartsNestedNameSpecifier) {
993*67e74705SXin Li const DeclContext *Ctx = R.Declaration->getDeclContext();
994*67e74705SXin Li if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
995*67e74705SXin Li R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr,
996*67e74705SXin Li Namespace);
997*67e74705SXin Li else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
998*67e74705SXin Li R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, false,
999*67e74705SXin Li SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
1000*67e74705SXin Li else
1001*67e74705SXin Li R.QualifierIsInformative = false;
1002*67e74705SXin Li }
1003*67e74705SXin Li
1004*67e74705SXin Li // Adjust the priority if this result comes from a base class.
1005*67e74705SXin Li if (InBaseClass)
1006*67e74705SXin Li R.Priority += CCD_InBaseClass;
1007*67e74705SXin Li
1008*67e74705SXin Li AdjustResultPriorityForDecl(R);
1009*67e74705SXin Li
1010*67e74705SXin Li if (HasObjectTypeQualifiers)
1011*67e74705SXin Li if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
1012*67e74705SXin Li if (Method->isInstance()) {
1013*67e74705SXin Li Qualifiers MethodQuals
1014*67e74705SXin Li = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
1015*67e74705SXin Li if (ObjectTypeQualifiers == MethodQuals)
1016*67e74705SXin Li R.Priority += CCD_ObjectQualifierMatch;
1017*67e74705SXin Li else if (ObjectTypeQualifiers - MethodQuals) {
1018*67e74705SXin Li // The method cannot be invoked, because doing so would drop
1019*67e74705SXin Li // qualifiers.
1020*67e74705SXin Li return;
1021*67e74705SXin Li }
1022*67e74705SXin Li }
1023*67e74705SXin Li
1024*67e74705SXin Li // Insert this result into the set of results.
1025*67e74705SXin Li Results.push_back(R);
1026*67e74705SXin Li
1027*67e74705SXin Li if (!AsNestedNameSpecifier)
1028*67e74705SXin Li MaybeAddConstructorResults(R);
1029*67e74705SXin Li }
1030*67e74705SXin Li
AddResult(Result R)1031*67e74705SXin Li void ResultBuilder::AddResult(Result R) {
1032*67e74705SXin Li assert(R.Kind != Result::RK_Declaration &&
1033*67e74705SXin Li "Declaration results need more context");
1034*67e74705SXin Li Results.push_back(R);
1035*67e74705SXin Li }
1036*67e74705SXin Li
1037*67e74705SXin Li /// \brief Enter into a new scope.
EnterNewScope()1038*67e74705SXin Li void ResultBuilder::EnterNewScope() { ShadowMaps.emplace_back(); }
1039*67e74705SXin Li
1040*67e74705SXin Li /// \brief Exit from the current scope.
ExitScope()1041*67e74705SXin Li void ResultBuilder::ExitScope() {
1042*67e74705SXin Li for (ShadowMap::iterator E = ShadowMaps.back().begin(),
1043*67e74705SXin Li EEnd = ShadowMaps.back().end();
1044*67e74705SXin Li E != EEnd;
1045*67e74705SXin Li ++E)
1046*67e74705SXin Li E->second.Destroy();
1047*67e74705SXin Li
1048*67e74705SXin Li ShadowMaps.pop_back();
1049*67e74705SXin Li }
1050*67e74705SXin Li
1051*67e74705SXin Li /// \brief Determines whether this given declaration will be found by
1052*67e74705SXin Li /// ordinary name lookup.
IsOrdinaryName(const NamedDecl * ND) const1053*67e74705SXin Li bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {
1054*67e74705SXin Li ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1055*67e74705SXin Li
1056*67e74705SXin Li // If name lookup finds a local extern declaration, then we are in a
1057*67e74705SXin Li // context where it behaves like an ordinary name.
1058*67e74705SXin Li unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1059*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus)
1060*67e74705SXin Li IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1061*67e74705SXin Li else if (SemaRef.getLangOpts().ObjC1) {
1062*67e74705SXin Li if (isa<ObjCIvarDecl>(ND))
1063*67e74705SXin Li return true;
1064*67e74705SXin Li }
1065*67e74705SXin Li
1066*67e74705SXin Li return ND->getIdentifierNamespace() & IDNS;
1067*67e74705SXin Li }
1068*67e74705SXin Li
1069*67e74705SXin Li /// \brief Determines whether this given declaration will be found by
1070*67e74705SXin Li /// ordinary name lookup but is not a type name.
IsOrdinaryNonTypeName(const NamedDecl * ND) const1071*67e74705SXin Li bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
1072*67e74705SXin Li ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1073*67e74705SXin Li if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
1074*67e74705SXin Li return false;
1075*67e74705SXin Li
1076*67e74705SXin Li unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1077*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus)
1078*67e74705SXin Li IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1079*67e74705SXin Li else if (SemaRef.getLangOpts().ObjC1) {
1080*67e74705SXin Li if (isa<ObjCIvarDecl>(ND))
1081*67e74705SXin Li return true;
1082*67e74705SXin Li }
1083*67e74705SXin Li
1084*67e74705SXin Li return ND->getIdentifierNamespace() & IDNS;
1085*67e74705SXin Li }
1086*67e74705SXin Li
IsIntegralConstantValue(const NamedDecl * ND) const1087*67e74705SXin Li bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const {
1088*67e74705SXin Li if (!IsOrdinaryNonTypeName(ND))
1089*67e74705SXin Li return 0;
1090*67e74705SXin Li
1091*67e74705SXin Li if (const ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
1092*67e74705SXin Li if (VD->getType()->isIntegralOrEnumerationType())
1093*67e74705SXin Li return true;
1094*67e74705SXin Li
1095*67e74705SXin Li return false;
1096*67e74705SXin Li }
1097*67e74705SXin Li
1098*67e74705SXin Li /// \brief Determines whether this given declaration will be found by
1099*67e74705SXin Li /// ordinary name lookup.
IsOrdinaryNonValueName(const NamedDecl * ND) const1100*67e74705SXin Li bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {
1101*67e74705SXin Li ND = cast<NamedDecl>(ND->getUnderlyingDecl());
1102*67e74705SXin Li
1103*67e74705SXin Li unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1104*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus)
1105*67e74705SXin Li IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
1106*67e74705SXin Li
1107*67e74705SXin Li return (ND->getIdentifierNamespace() & IDNS) &&
1108*67e74705SXin Li !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) &&
1109*67e74705SXin Li !isa<ObjCPropertyDecl>(ND);
1110*67e74705SXin Li }
1111*67e74705SXin Li
1112*67e74705SXin Li /// \brief Determines whether the given declaration is suitable as the
1113*67e74705SXin Li /// start of a C++ nested-name-specifier, e.g., a class or namespace.
IsNestedNameSpecifier(const NamedDecl * ND) const1114*67e74705SXin Li bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const {
1115*67e74705SXin Li // Allow us to find class templates, too.
1116*67e74705SXin Li if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1117*67e74705SXin Li ND = ClassTemplate->getTemplatedDecl();
1118*67e74705SXin Li
1119*67e74705SXin Li return SemaRef.isAcceptableNestedNameSpecifier(ND);
1120*67e74705SXin Li }
1121*67e74705SXin Li
1122*67e74705SXin Li /// \brief Determines whether the given declaration is an enumeration.
IsEnum(const NamedDecl * ND) const1123*67e74705SXin Li bool ResultBuilder::IsEnum(const NamedDecl *ND) const {
1124*67e74705SXin Li return isa<EnumDecl>(ND);
1125*67e74705SXin Li }
1126*67e74705SXin Li
1127*67e74705SXin Li /// \brief Determines whether the given declaration is a class or struct.
IsClassOrStruct(const NamedDecl * ND) const1128*67e74705SXin Li bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const {
1129*67e74705SXin Li // Allow us to find class templates, too.
1130*67e74705SXin Li if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1131*67e74705SXin Li ND = ClassTemplate->getTemplatedDecl();
1132*67e74705SXin Li
1133*67e74705SXin Li // For purposes of this check, interfaces match too.
1134*67e74705SXin Li if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
1135*67e74705SXin Li return RD->getTagKind() == TTK_Class ||
1136*67e74705SXin Li RD->getTagKind() == TTK_Struct ||
1137*67e74705SXin Li RD->getTagKind() == TTK_Interface;
1138*67e74705SXin Li
1139*67e74705SXin Li return false;
1140*67e74705SXin Li }
1141*67e74705SXin Li
1142*67e74705SXin Li /// \brief Determines whether the given declaration is a union.
IsUnion(const NamedDecl * ND) const1143*67e74705SXin Li bool ResultBuilder::IsUnion(const NamedDecl *ND) const {
1144*67e74705SXin Li // Allow us to find class templates, too.
1145*67e74705SXin Li if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1146*67e74705SXin Li ND = ClassTemplate->getTemplatedDecl();
1147*67e74705SXin Li
1148*67e74705SXin Li if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND))
1149*67e74705SXin Li return RD->getTagKind() == TTK_Union;
1150*67e74705SXin Li
1151*67e74705SXin Li return false;
1152*67e74705SXin Li }
1153*67e74705SXin Li
1154*67e74705SXin Li /// \brief Determines whether the given declaration is a namespace.
IsNamespace(const NamedDecl * ND) const1155*67e74705SXin Li bool ResultBuilder::IsNamespace(const NamedDecl *ND) const {
1156*67e74705SXin Li return isa<NamespaceDecl>(ND);
1157*67e74705SXin Li }
1158*67e74705SXin Li
1159*67e74705SXin Li /// \brief Determines whether the given declaration is a namespace or
1160*67e74705SXin Li /// namespace alias.
IsNamespaceOrAlias(const NamedDecl * ND) const1161*67e74705SXin Li bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const {
1162*67e74705SXin Li return isa<NamespaceDecl>(ND->getUnderlyingDecl());
1163*67e74705SXin Li }
1164*67e74705SXin Li
1165*67e74705SXin Li /// \brief Determines whether the given declaration is a type.
IsType(const NamedDecl * ND) const1166*67e74705SXin Li bool ResultBuilder::IsType(const NamedDecl *ND) const {
1167*67e74705SXin Li ND = ND->getUnderlyingDecl();
1168*67e74705SXin Li return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
1169*67e74705SXin Li }
1170*67e74705SXin Li
1171*67e74705SXin Li /// \brief Determines which members of a class should be visible via
1172*67e74705SXin Li /// "." or "->". Only value declarations, nested name specifiers, and
1173*67e74705SXin Li /// using declarations thereof should show up.
IsMember(const NamedDecl * ND) const1174*67e74705SXin Li bool ResultBuilder::IsMember(const NamedDecl *ND) const {
1175*67e74705SXin Li ND = ND->getUnderlyingDecl();
1176*67e74705SXin Li return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1177*67e74705SXin Li isa<ObjCPropertyDecl>(ND);
1178*67e74705SXin Li }
1179*67e74705SXin Li
isObjCReceiverType(ASTContext & C,QualType T)1180*67e74705SXin Li static bool isObjCReceiverType(ASTContext &C, QualType T) {
1181*67e74705SXin Li T = C.getCanonicalType(T);
1182*67e74705SXin Li switch (T->getTypeClass()) {
1183*67e74705SXin Li case Type::ObjCObject:
1184*67e74705SXin Li case Type::ObjCInterface:
1185*67e74705SXin Li case Type::ObjCObjectPointer:
1186*67e74705SXin Li return true;
1187*67e74705SXin Li
1188*67e74705SXin Li case Type::Builtin:
1189*67e74705SXin Li switch (cast<BuiltinType>(T)->getKind()) {
1190*67e74705SXin Li case BuiltinType::ObjCId:
1191*67e74705SXin Li case BuiltinType::ObjCClass:
1192*67e74705SXin Li case BuiltinType::ObjCSel:
1193*67e74705SXin Li return true;
1194*67e74705SXin Li
1195*67e74705SXin Li default:
1196*67e74705SXin Li break;
1197*67e74705SXin Li }
1198*67e74705SXin Li return false;
1199*67e74705SXin Li
1200*67e74705SXin Li default:
1201*67e74705SXin Li break;
1202*67e74705SXin Li }
1203*67e74705SXin Li
1204*67e74705SXin Li if (!C.getLangOpts().CPlusPlus)
1205*67e74705SXin Li return false;
1206*67e74705SXin Li
1207*67e74705SXin Li // FIXME: We could perform more analysis here to determine whether a
1208*67e74705SXin Li // particular class type has any conversions to Objective-C types. For now,
1209*67e74705SXin Li // just accept all class types.
1210*67e74705SXin Li return T->isDependentType() || T->isRecordType();
1211*67e74705SXin Li }
1212*67e74705SXin Li
IsObjCMessageReceiver(const NamedDecl * ND) const1213*67e74705SXin Li bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {
1214*67e74705SXin Li QualType T = getDeclUsageType(SemaRef.Context, ND);
1215*67e74705SXin Li if (T.isNull())
1216*67e74705SXin Li return false;
1217*67e74705SXin Li
1218*67e74705SXin Li T = SemaRef.Context.getBaseElementType(T);
1219*67e74705SXin Li return isObjCReceiverType(SemaRef.Context, T);
1220*67e74705SXin Li }
1221*67e74705SXin Li
IsObjCMessageReceiverOrLambdaCapture(const NamedDecl * ND) const1222*67e74705SXin Li bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const {
1223*67e74705SXin Li if (IsObjCMessageReceiver(ND))
1224*67e74705SXin Li return true;
1225*67e74705SXin Li
1226*67e74705SXin Li const VarDecl *Var = dyn_cast<VarDecl>(ND);
1227*67e74705SXin Li if (!Var)
1228*67e74705SXin Li return false;
1229*67e74705SXin Li
1230*67e74705SXin Li return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>();
1231*67e74705SXin Li }
1232*67e74705SXin Li
IsObjCCollection(const NamedDecl * ND) const1233*67e74705SXin Li bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {
1234*67e74705SXin Li if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) ||
1235*67e74705SXin Li (!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1236*67e74705SXin Li return false;
1237*67e74705SXin Li
1238*67e74705SXin Li QualType T = getDeclUsageType(SemaRef.Context, ND);
1239*67e74705SXin Li if (T.isNull())
1240*67e74705SXin Li return false;
1241*67e74705SXin Li
1242*67e74705SXin Li T = SemaRef.Context.getBaseElementType(T);
1243*67e74705SXin Li return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1244*67e74705SXin Li T->isObjCIdType() ||
1245*67e74705SXin Li (SemaRef.getLangOpts().CPlusPlus && T->isRecordType());
1246*67e74705SXin Li }
1247*67e74705SXin Li
IsImpossibleToSatisfy(const NamedDecl * ND) const1248*67e74705SXin Li bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const {
1249*67e74705SXin Li return false;
1250*67e74705SXin Li }
1251*67e74705SXin Li
1252*67e74705SXin Li /// \brief Determines whether the given declaration is an Objective-C
1253*67e74705SXin Li /// instance variable.
IsObjCIvar(const NamedDecl * ND) const1254*67e74705SXin Li bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const {
1255*67e74705SXin Li return isa<ObjCIvarDecl>(ND);
1256*67e74705SXin Li }
1257*67e74705SXin Li
1258*67e74705SXin Li namespace {
1259*67e74705SXin Li /// \brief Visible declaration consumer that adds a code-completion result
1260*67e74705SXin Li /// for each visible declaration.
1261*67e74705SXin Li class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1262*67e74705SXin Li ResultBuilder &Results;
1263*67e74705SXin Li DeclContext *CurContext;
1264*67e74705SXin Li
1265*67e74705SXin Li public:
CodeCompletionDeclConsumer(ResultBuilder & Results,DeclContext * CurContext)1266*67e74705SXin Li CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
1267*67e74705SXin Li : Results(Results), CurContext(CurContext) { }
1268*67e74705SXin Li
FoundDecl(NamedDecl * ND,NamedDecl * Hiding,DeclContext * Ctx,bool InBaseClass)1269*67e74705SXin Li void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
1270*67e74705SXin Li bool InBaseClass) override {
1271*67e74705SXin Li bool Accessible = true;
1272*67e74705SXin Li if (Ctx)
1273*67e74705SXin Li Accessible = Results.getSema().IsSimplyAccessible(ND, Ctx);
1274*67e74705SXin Li
1275*67e74705SXin Li ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr,
1276*67e74705SXin Li false, Accessible);
1277*67e74705SXin Li Results.AddResult(Result, CurContext, Hiding, InBaseClass);
1278*67e74705SXin Li }
1279*67e74705SXin Li };
1280*67e74705SXin Li }
1281*67e74705SXin Li
1282*67e74705SXin Li /// \brief Add type specifiers for the current language as keyword results.
AddTypeSpecifierResults(const LangOptions & LangOpts,ResultBuilder & Results)1283*67e74705SXin Li static void AddTypeSpecifierResults(const LangOptions &LangOpts,
1284*67e74705SXin Li ResultBuilder &Results) {
1285*67e74705SXin Li typedef CodeCompletionResult Result;
1286*67e74705SXin Li Results.AddResult(Result("short", CCP_Type));
1287*67e74705SXin Li Results.AddResult(Result("long", CCP_Type));
1288*67e74705SXin Li Results.AddResult(Result("signed", CCP_Type));
1289*67e74705SXin Li Results.AddResult(Result("unsigned", CCP_Type));
1290*67e74705SXin Li Results.AddResult(Result("void", CCP_Type));
1291*67e74705SXin Li Results.AddResult(Result("char", CCP_Type));
1292*67e74705SXin Li Results.AddResult(Result("int", CCP_Type));
1293*67e74705SXin Li Results.AddResult(Result("float", CCP_Type));
1294*67e74705SXin Li Results.AddResult(Result("double", CCP_Type));
1295*67e74705SXin Li Results.AddResult(Result("enum", CCP_Type));
1296*67e74705SXin Li Results.AddResult(Result("struct", CCP_Type));
1297*67e74705SXin Li Results.AddResult(Result("union", CCP_Type));
1298*67e74705SXin Li Results.AddResult(Result("const", CCP_Type));
1299*67e74705SXin Li Results.AddResult(Result("volatile", CCP_Type));
1300*67e74705SXin Li
1301*67e74705SXin Li if (LangOpts.C99) {
1302*67e74705SXin Li // C99-specific
1303*67e74705SXin Li Results.AddResult(Result("_Complex", CCP_Type));
1304*67e74705SXin Li Results.AddResult(Result("_Imaginary", CCP_Type));
1305*67e74705SXin Li Results.AddResult(Result("_Bool", CCP_Type));
1306*67e74705SXin Li Results.AddResult(Result("restrict", CCP_Type));
1307*67e74705SXin Li }
1308*67e74705SXin Li
1309*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
1310*67e74705SXin Li Results.getCodeCompletionTUInfo());
1311*67e74705SXin Li if (LangOpts.CPlusPlus) {
1312*67e74705SXin Li // C++-specific
1313*67e74705SXin Li Results.AddResult(Result("bool", CCP_Type +
1314*67e74705SXin Li (LangOpts.ObjC1? CCD_bool_in_ObjC : 0)));
1315*67e74705SXin Li Results.AddResult(Result("class", CCP_Type));
1316*67e74705SXin Li Results.AddResult(Result("wchar_t", CCP_Type));
1317*67e74705SXin Li
1318*67e74705SXin Li // typename qualified-id
1319*67e74705SXin Li Builder.AddTypedTextChunk("typename");
1320*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1321*67e74705SXin Li Builder.AddPlaceholderChunk("qualifier");
1322*67e74705SXin Li Builder.AddTextChunk("::");
1323*67e74705SXin Li Builder.AddPlaceholderChunk("name");
1324*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1325*67e74705SXin Li
1326*67e74705SXin Li if (LangOpts.CPlusPlus11) {
1327*67e74705SXin Li Results.AddResult(Result("auto", CCP_Type));
1328*67e74705SXin Li Results.AddResult(Result("char16_t", CCP_Type));
1329*67e74705SXin Li Results.AddResult(Result("char32_t", CCP_Type));
1330*67e74705SXin Li
1331*67e74705SXin Li Builder.AddTypedTextChunk("decltype");
1332*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1333*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1334*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1335*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1336*67e74705SXin Li }
1337*67e74705SXin Li }
1338*67e74705SXin Li
1339*67e74705SXin Li // GNU extensions
1340*67e74705SXin Li if (LangOpts.GNUMode) {
1341*67e74705SXin Li // FIXME: Enable when we actually support decimal floating point.
1342*67e74705SXin Li // Results.AddResult(Result("_Decimal32"));
1343*67e74705SXin Li // Results.AddResult(Result("_Decimal64"));
1344*67e74705SXin Li // Results.AddResult(Result("_Decimal128"));
1345*67e74705SXin Li
1346*67e74705SXin Li Builder.AddTypedTextChunk("typeof");
1347*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1348*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1349*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1350*67e74705SXin Li
1351*67e74705SXin Li Builder.AddTypedTextChunk("typeof");
1352*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1353*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1354*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1355*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1356*67e74705SXin Li }
1357*67e74705SXin Li
1358*67e74705SXin Li // Nullability
1359*67e74705SXin Li Results.AddResult(Result("_Nonnull", CCP_Type));
1360*67e74705SXin Li Results.AddResult(Result("_Null_unspecified", CCP_Type));
1361*67e74705SXin Li Results.AddResult(Result("_Nullable", CCP_Type));
1362*67e74705SXin Li }
1363*67e74705SXin Li
AddStorageSpecifiers(Sema::ParserCompletionContext CCC,const LangOptions & LangOpts,ResultBuilder & Results)1364*67e74705SXin Li static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
1365*67e74705SXin Li const LangOptions &LangOpts,
1366*67e74705SXin Li ResultBuilder &Results) {
1367*67e74705SXin Li typedef CodeCompletionResult Result;
1368*67e74705SXin Li // Note: we don't suggest either "auto" or "register", because both
1369*67e74705SXin Li // are pointless as storage specifiers. Elsewhere, we suggest "auto"
1370*67e74705SXin Li // in C++0x as a type specifier.
1371*67e74705SXin Li Results.AddResult(Result("extern"));
1372*67e74705SXin Li Results.AddResult(Result("static"));
1373*67e74705SXin Li }
1374*67e74705SXin Li
AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,const LangOptions & LangOpts,ResultBuilder & Results)1375*67e74705SXin Li static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
1376*67e74705SXin Li const LangOptions &LangOpts,
1377*67e74705SXin Li ResultBuilder &Results) {
1378*67e74705SXin Li typedef CodeCompletionResult Result;
1379*67e74705SXin Li switch (CCC) {
1380*67e74705SXin Li case Sema::PCC_Class:
1381*67e74705SXin Li case Sema::PCC_MemberTemplate:
1382*67e74705SXin Li if (LangOpts.CPlusPlus) {
1383*67e74705SXin Li Results.AddResult(Result("explicit"));
1384*67e74705SXin Li Results.AddResult(Result("friend"));
1385*67e74705SXin Li Results.AddResult(Result("mutable"));
1386*67e74705SXin Li Results.AddResult(Result("virtual"));
1387*67e74705SXin Li }
1388*67e74705SXin Li // Fall through
1389*67e74705SXin Li
1390*67e74705SXin Li case Sema::PCC_ObjCInterface:
1391*67e74705SXin Li case Sema::PCC_ObjCImplementation:
1392*67e74705SXin Li case Sema::PCC_Namespace:
1393*67e74705SXin Li case Sema::PCC_Template:
1394*67e74705SXin Li if (LangOpts.CPlusPlus || LangOpts.C99)
1395*67e74705SXin Li Results.AddResult(Result("inline"));
1396*67e74705SXin Li break;
1397*67e74705SXin Li
1398*67e74705SXin Li case Sema::PCC_ObjCInstanceVariableList:
1399*67e74705SXin Li case Sema::PCC_Expression:
1400*67e74705SXin Li case Sema::PCC_Statement:
1401*67e74705SXin Li case Sema::PCC_ForInit:
1402*67e74705SXin Li case Sema::PCC_Condition:
1403*67e74705SXin Li case Sema::PCC_RecoveryInFunction:
1404*67e74705SXin Li case Sema::PCC_Type:
1405*67e74705SXin Li case Sema::PCC_ParenthesizedExpression:
1406*67e74705SXin Li case Sema::PCC_LocalDeclarationSpecifiers:
1407*67e74705SXin Li break;
1408*67e74705SXin Li }
1409*67e74705SXin Li }
1410*67e74705SXin Li
1411*67e74705SXin Li static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1412*67e74705SXin Li static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1413*67e74705SXin Li static void AddObjCVisibilityResults(const LangOptions &LangOpts,
1414*67e74705SXin Li ResultBuilder &Results,
1415*67e74705SXin Li bool NeedAt);
1416*67e74705SXin Li static void AddObjCImplementationResults(const LangOptions &LangOpts,
1417*67e74705SXin Li ResultBuilder &Results,
1418*67e74705SXin Li bool NeedAt);
1419*67e74705SXin Li static void AddObjCInterfaceResults(const LangOptions &LangOpts,
1420*67e74705SXin Li ResultBuilder &Results,
1421*67e74705SXin Li bool NeedAt);
1422*67e74705SXin Li static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
1423*67e74705SXin Li
AddTypedefResult(ResultBuilder & Results)1424*67e74705SXin Li static void AddTypedefResult(ResultBuilder &Results) {
1425*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
1426*67e74705SXin Li Results.getCodeCompletionTUInfo());
1427*67e74705SXin Li Builder.AddTypedTextChunk("typedef");
1428*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1429*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1430*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1431*67e74705SXin Li Builder.AddPlaceholderChunk("name");
1432*67e74705SXin Li Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1433*67e74705SXin Li }
1434*67e74705SXin Li
WantTypesInContext(Sema::ParserCompletionContext CCC,const LangOptions & LangOpts)1435*67e74705SXin Li static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
1436*67e74705SXin Li const LangOptions &LangOpts) {
1437*67e74705SXin Li switch (CCC) {
1438*67e74705SXin Li case Sema::PCC_Namespace:
1439*67e74705SXin Li case Sema::PCC_Class:
1440*67e74705SXin Li case Sema::PCC_ObjCInstanceVariableList:
1441*67e74705SXin Li case Sema::PCC_Template:
1442*67e74705SXin Li case Sema::PCC_MemberTemplate:
1443*67e74705SXin Li case Sema::PCC_Statement:
1444*67e74705SXin Li case Sema::PCC_RecoveryInFunction:
1445*67e74705SXin Li case Sema::PCC_Type:
1446*67e74705SXin Li case Sema::PCC_ParenthesizedExpression:
1447*67e74705SXin Li case Sema::PCC_LocalDeclarationSpecifiers:
1448*67e74705SXin Li return true;
1449*67e74705SXin Li
1450*67e74705SXin Li case Sema::PCC_Expression:
1451*67e74705SXin Li case Sema::PCC_Condition:
1452*67e74705SXin Li return LangOpts.CPlusPlus;
1453*67e74705SXin Li
1454*67e74705SXin Li case Sema::PCC_ObjCInterface:
1455*67e74705SXin Li case Sema::PCC_ObjCImplementation:
1456*67e74705SXin Li return false;
1457*67e74705SXin Li
1458*67e74705SXin Li case Sema::PCC_ForInit:
1459*67e74705SXin Li return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99;
1460*67e74705SXin Li }
1461*67e74705SXin Li
1462*67e74705SXin Li llvm_unreachable("Invalid ParserCompletionContext!");
1463*67e74705SXin Li }
1464*67e74705SXin Li
getCompletionPrintingPolicy(const ASTContext & Context,const Preprocessor & PP)1465*67e74705SXin Li static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
1466*67e74705SXin Li const Preprocessor &PP) {
1467*67e74705SXin Li PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP);
1468*67e74705SXin Li Policy.AnonymousTagLocations = false;
1469*67e74705SXin Li Policy.SuppressStrongLifetime = true;
1470*67e74705SXin Li Policy.SuppressUnwrittenScope = true;
1471*67e74705SXin Li return Policy;
1472*67e74705SXin Li }
1473*67e74705SXin Li
1474*67e74705SXin Li /// \brief Retrieve a printing policy suitable for code completion.
getCompletionPrintingPolicy(Sema & S)1475*67e74705SXin Li static PrintingPolicy getCompletionPrintingPolicy(Sema &S) {
1476*67e74705SXin Li return getCompletionPrintingPolicy(S.Context, S.PP);
1477*67e74705SXin Li }
1478*67e74705SXin Li
1479*67e74705SXin Li /// \brief Retrieve the string representation of the given type as a string
1480*67e74705SXin Li /// that has the appropriate lifetime for code completion.
1481*67e74705SXin Li ///
1482*67e74705SXin Li /// This routine provides a fast path where we provide constant strings for
1483*67e74705SXin Li /// common type names.
GetCompletionTypeString(QualType T,ASTContext & Context,const PrintingPolicy & Policy,CodeCompletionAllocator & Allocator)1484*67e74705SXin Li static const char *GetCompletionTypeString(QualType T,
1485*67e74705SXin Li ASTContext &Context,
1486*67e74705SXin Li const PrintingPolicy &Policy,
1487*67e74705SXin Li CodeCompletionAllocator &Allocator) {
1488*67e74705SXin Li if (!T.getLocalQualifiers()) {
1489*67e74705SXin Li // Built-in type names are constant strings.
1490*67e74705SXin Li if (const BuiltinType *BT = dyn_cast<BuiltinType>(T))
1491*67e74705SXin Li return BT->getNameAsCString(Policy);
1492*67e74705SXin Li
1493*67e74705SXin Li // Anonymous tag types are constant strings.
1494*67e74705SXin Li if (const TagType *TagT = dyn_cast<TagType>(T))
1495*67e74705SXin Li if (TagDecl *Tag = TagT->getDecl())
1496*67e74705SXin Li if (!Tag->hasNameForLinkage()) {
1497*67e74705SXin Li switch (Tag->getTagKind()) {
1498*67e74705SXin Li case TTK_Struct: return "struct <anonymous>";
1499*67e74705SXin Li case TTK_Interface: return "__interface <anonymous>";
1500*67e74705SXin Li case TTK_Class: return "class <anonymous>";
1501*67e74705SXin Li case TTK_Union: return "union <anonymous>";
1502*67e74705SXin Li case TTK_Enum: return "enum <anonymous>";
1503*67e74705SXin Li }
1504*67e74705SXin Li }
1505*67e74705SXin Li }
1506*67e74705SXin Li
1507*67e74705SXin Li // Slow path: format the type as a string.
1508*67e74705SXin Li std::string Result;
1509*67e74705SXin Li T.getAsStringInternal(Result, Policy);
1510*67e74705SXin Li return Allocator.CopyString(Result);
1511*67e74705SXin Li }
1512*67e74705SXin Li
1513*67e74705SXin Li /// \brief Add a completion for "this", if we're in a member function.
addThisCompletion(Sema & S,ResultBuilder & Results)1514*67e74705SXin Li static void addThisCompletion(Sema &S, ResultBuilder &Results) {
1515*67e74705SXin Li QualType ThisTy = S.getCurrentThisType();
1516*67e74705SXin Li if (ThisTy.isNull())
1517*67e74705SXin Li return;
1518*67e74705SXin Li
1519*67e74705SXin Li CodeCompletionAllocator &Allocator = Results.getAllocator();
1520*67e74705SXin Li CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1521*67e74705SXin Li PrintingPolicy Policy = getCompletionPrintingPolicy(S);
1522*67e74705SXin Li Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy,
1523*67e74705SXin Li S.Context,
1524*67e74705SXin Li Policy,
1525*67e74705SXin Li Allocator));
1526*67e74705SXin Li Builder.AddTypedTextChunk("this");
1527*67e74705SXin Li Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1528*67e74705SXin Li }
1529*67e74705SXin Li
1530*67e74705SXin Li /// \brief Add language constructs that show up for "ordinary" names.
AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,Scope * S,Sema & SemaRef,ResultBuilder & Results)1531*67e74705SXin Li static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
1532*67e74705SXin Li Scope *S,
1533*67e74705SXin Li Sema &SemaRef,
1534*67e74705SXin Li ResultBuilder &Results) {
1535*67e74705SXin Li CodeCompletionAllocator &Allocator = Results.getAllocator();
1536*67e74705SXin Li CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1537*67e74705SXin Li
1538*67e74705SXin Li typedef CodeCompletionResult Result;
1539*67e74705SXin Li switch (CCC) {
1540*67e74705SXin Li case Sema::PCC_Namespace:
1541*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus) {
1542*67e74705SXin Li if (Results.includeCodePatterns()) {
1543*67e74705SXin Li // namespace <identifier> { declarations }
1544*67e74705SXin Li Builder.AddTypedTextChunk("namespace");
1545*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1546*67e74705SXin Li Builder.AddPlaceholderChunk("identifier");
1547*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1548*67e74705SXin Li Builder.AddPlaceholderChunk("declarations");
1549*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1550*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1551*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1552*67e74705SXin Li }
1553*67e74705SXin Li
1554*67e74705SXin Li // namespace identifier = identifier ;
1555*67e74705SXin Li Builder.AddTypedTextChunk("namespace");
1556*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1557*67e74705SXin Li Builder.AddPlaceholderChunk("name");
1558*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Equal);
1559*67e74705SXin Li Builder.AddPlaceholderChunk("namespace");
1560*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1561*67e74705SXin Li
1562*67e74705SXin Li // Using directives
1563*67e74705SXin Li Builder.AddTypedTextChunk("using");
1564*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1565*67e74705SXin Li Builder.AddTextChunk("namespace");
1566*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1567*67e74705SXin Li Builder.AddPlaceholderChunk("identifier");
1568*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1569*67e74705SXin Li
1570*67e74705SXin Li // asm(string-literal)
1571*67e74705SXin Li Builder.AddTypedTextChunk("asm");
1572*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1573*67e74705SXin Li Builder.AddPlaceholderChunk("string-literal");
1574*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1575*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1576*67e74705SXin Li
1577*67e74705SXin Li if (Results.includeCodePatterns()) {
1578*67e74705SXin Li // Explicit template instantiation
1579*67e74705SXin Li Builder.AddTypedTextChunk("template");
1580*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1581*67e74705SXin Li Builder.AddPlaceholderChunk("declaration");
1582*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1583*67e74705SXin Li }
1584*67e74705SXin Li }
1585*67e74705SXin Li
1586*67e74705SXin Li if (SemaRef.getLangOpts().ObjC1)
1587*67e74705SXin Li AddObjCTopLevelResults(Results, true);
1588*67e74705SXin Li
1589*67e74705SXin Li AddTypedefResult(Results);
1590*67e74705SXin Li // Fall through
1591*67e74705SXin Li
1592*67e74705SXin Li case Sema::PCC_Class:
1593*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus) {
1594*67e74705SXin Li // Using declaration
1595*67e74705SXin Li Builder.AddTypedTextChunk("using");
1596*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1597*67e74705SXin Li Builder.AddPlaceholderChunk("qualifier");
1598*67e74705SXin Li Builder.AddTextChunk("::");
1599*67e74705SXin Li Builder.AddPlaceholderChunk("name");
1600*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1601*67e74705SXin Li
1602*67e74705SXin Li // using typename qualifier::name (only in a dependent context)
1603*67e74705SXin Li if (SemaRef.CurContext->isDependentContext()) {
1604*67e74705SXin Li Builder.AddTypedTextChunk("using");
1605*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1606*67e74705SXin Li Builder.AddTextChunk("typename");
1607*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1608*67e74705SXin Li Builder.AddPlaceholderChunk("qualifier");
1609*67e74705SXin Li Builder.AddTextChunk("::");
1610*67e74705SXin Li Builder.AddPlaceholderChunk("name");
1611*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1612*67e74705SXin Li }
1613*67e74705SXin Li
1614*67e74705SXin Li if (CCC == Sema::PCC_Class) {
1615*67e74705SXin Li AddTypedefResult(Results);
1616*67e74705SXin Li
1617*67e74705SXin Li // public:
1618*67e74705SXin Li Builder.AddTypedTextChunk("public");
1619*67e74705SXin Li if (Results.includeCodePatterns())
1620*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Colon);
1621*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1622*67e74705SXin Li
1623*67e74705SXin Li // protected:
1624*67e74705SXin Li Builder.AddTypedTextChunk("protected");
1625*67e74705SXin Li if (Results.includeCodePatterns())
1626*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Colon);
1627*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1628*67e74705SXin Li
1629*67e74705SXin Li // private:
1630*67e74705SXin Li Builder.AddTypedTextChunk("private");
1631*67e74705SXin Li if (Results.includeCodePatterns())
1632*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Colon);
1633*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1634*67e74705SXin Li }
1635*67e74705SXin Li }
1636*67e74705SXin Li // Fall through
1637*67e74705SXin Li
1638*67e74705SXin Li case Sema::PCC_Template:
1639*67e74705SXin Li case Sema::PCC_MemberTemplate:
1640*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) {
1641*67e74705SXin Li // template < parameters >
1642*67e74705SXin Li Builder.AddTypedTextChunk("template");
1643*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1644*67e74705SXin Li Builder.AddPlaceholderChunk("parameters");
1645*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1646*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1647*67e74705SXin Li }
1648*67e74705SXin Li
1649*67e74705SXin Li AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1650*67e74705SXin Li AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1651*67e74705SXin Li break;
1652*67e74705SXin Li
1653*67e74705SXin Li case Sema::PCC_ObjCInterface:
1654*67e74705SXin Li AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true);
1655*67e74705SXin Li AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1656*67e74705SXin Li AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1657*67e74705SXin Li break;
1658*67e74705SXin Li
1659*67e74705SXin Li case Sema::PCC_ObjCImplementation:
1660*67e74705SXin Li AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true);
1661*67e74705SXin Li AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1662*67e74705SXin Li AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1663*67e74705SXin Li break;
1664*67e74705SXin Li
1665*67e74705SXin Li case Sema::PCC_ObjCInstanceVariableList:
1666*67e74705SXin Li AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true);
1667*67e74705SXin Li break;
1668*67e74705SXin Li
1669*67e74705SXin Li case Sema::PCC_RecoveryInFunction:
1670*67e74705SXin Li case Sema::PCC_Statement: {
1671*67e74705SXin Li AddTypedefResult(Results);
1672*67e74705SXin Li
1673*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() &&
1674*67e74705SXin Li SemaRef.getLangOpts().CXXExceptions) {
1675*67e74705SXin Li Builder.AddTypedTextChunk("try");
1676*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1677*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
1678*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1679*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1680*67e74705SXin Li Builder.AddTextChunk("catch");
1681*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1682*67e74705SXin Li Builder.AddPlaceholderChunk("declaration");
1683*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1684*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1685*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
1686*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1687*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1688*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1689*67e74705SXin Li }
1690*67e74705SXin Li if (SemaRef.getLangOpts().ObjC1)
1691*67e74705SXin Li AddObjCStatementResults(Results, true);
1692*67e74705SXin Li
1693*67e74705SXin Li if (Results.includeCodePatterns()) {
1694*67e74705SXin Li // if (condition) { statements }
1695*67e74705SXin Li Builder.AddTypedTextChunk("if");
1696*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1697*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus)
1698*67e74705SXin Li Builder.AddPlaceholderChunk("condition");
1699*67e74705SXin Li else
1700*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1701*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1702*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1703*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
1704*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1705*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1706*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1707*67e74705SXin Li
1708*67e74705SXin Li // switch (condition) { }
1709*67e74705SXin Li Builder.AddTypedTextChunk("switch");
1710*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1711*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus)
1712*67e74705SXin Li Builder.AddPlaceholderChunk("condition");
1713*67e74705SXin Li else
1714*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1715*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1716*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1717*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1718*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1719*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1720*67e74705SXin Li }
1721*67e74705SXin Li
1722*67e74705SXin Li // Switch-specific statements.
1723*67e74705SXin Li if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
1724*67e74705SXin Li // case expression:
1725*67e74705SXin Li Builder.AddTypedTextChunk("case");
1726*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1727*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1728*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Colon);
1729*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1730*67e74705SXin Li
1731*67e74705SXin Li // default:
1732*67e74705SXin Li Builder.AddTypedTextChunk("default");
1733*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Colon);
1734*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1735*67e74705SXin Li }
1736*67e74705SXin Li
1737*67e74705SXin Li if (Results.includeCodePatterns()) {
1738*67e74705SXin Li /// while (condition) { statements }
1739*67e74705SXin Li Builder.AddTypedTextChunk("while");
1740*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1741*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus)
1742*67e74705SXin Li Builder.AddPlaceholderChunk("condition");
1743*67e74705SXin Li else
1744*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1745*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1746*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1747*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
1748*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1749*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1750*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1751*67e74705SXin Li
1752*67e74705SXin Li // do { statements } while ( expression );
1753*67e74705SXin Li Builder.AddTypedTextChunk("do");
1754*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1755*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
1756*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1757*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1758*67e74705SXin Li Builder.AddTextChunk("while");
1759*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1760*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1761*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1762*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1763*67e74705SXin Li
1764*67e74705SXin Li // for ( for-init-statement ; condition ; expression ) { statements }
1765*67e74705SXin Li Builder.AddTypedTextChunk("for");
1766*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1767*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99)
1768*67e74705SXin Li Builder.AddPlaceholderChunk("init-statement");
1769*67e74705SXin Li else
1770*67e74705SXin Li Builder.AddPlaceholderChunk("init-expression");
1771*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1772*67e74705SXin Li Builder.AddPlaceholderChunk("condition");
1773*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1774*67e74705SXin Li Builder.AddPlaceholderChunk("inc-expression");
1775*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1776*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
1777*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1778*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
1779*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
1780*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
1781*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1782*67e74705SXin Li }
1783*67e74705SXin Li
1784*67e74705SXin Li if (S->getContinueParent()) {
1785*67e74705SXin Li // continue ;
1786*67e74705SXin Li Builder.AddTypedTextChunk("continue");
1787*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1788*67e74705SXin Li }
1789*67e74705SXin Li
1790*67e74705SXin Li if (S->getBreakParent()) {
1791*67e74705SXin Li // break ;
1792*67e74705SXin Li Builder.AddTypedTextChunk("break");
1793*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1794*67e74705SXin Li }
1795*67e74705SXin Li
1796*67e74705SXin Li // "return expression ;" or "return ;", depending on whether we
1797*67e74705SXin Li // know the function is void or not.
1798*67e74705SXin Li bool isVoid = false;
1799*67e74705SXin Li if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1800*67e74705SXin Li isVoid = Function->getReturnType()->isVoidType();
1801*67e74705SXin Li else if (ObjCMethodDecl *Method
1802*67e74705SXin Li = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1803*67e74705SXin Li isVoid = Method->getReturnType()->isVoidType();
1804*67e74705SXin Li else if (SemaRef.getCurBlock() &&
1805*67e74705SXin Li !SemaRef.getCurBlock()->ReturnType.isNull())
1806*67e74705SXin Li isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
1807*67e74705SXin Li Builder.AddTypedTextChunk("return");
1808*67e74705SXin Li if (!isVoid) {
1809*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1810*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1811*67e74705SXin Li }
1812*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1813*67e74705SXin Li
1814*67e74705SXin Li // goto identifier ;
1815*67e74705SXin Li Builder.AddTypedTextChunk("goto");
1816*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1817*67e74705SXin Li Builder.AddPlaceholderChunk("label");
1818*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1819*67e74705SXin Li
1820*67e74705SXin Li // Using directives
1821*67e74705SXin Li Builder.AddTypedTextChunk("using");
1822*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1823*67e74705SXin Li Builder.AddTextChunk("namespace");
1824*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1825*67e74705SXin Li Builder.AddPlaceholderChunk("identifier");
1826*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1827*67e74705SXin Li }
1828*67e74705SXin Li
1829*67e74705SXin Li // Fall through (for statement expressions).
1830*67e74705SXin Li case Sema::PCC_ForInit:
1831*67e74705SXin Li case Sema::PCC_Condition:
1832*67e74705SXin Li AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
1833*67e74705SXin Li // Fall through: conditions and statements can have expressions.
1834*67e74705SXin Li
1835*67e74705SXin Li case Sema::PCC_ParenthesizedExpression:
1836*67e74705SXin Li if (SemaRef.getLangOpts().ObjCAutoRefCount &&
1837*67e74705SXin Li CCC == Sema::PCC_ParenthesizedExpression) {
1838*67e74705SXin Li // (__bridge <type>)<expression>
1839*67e74705SXin Li Builder.AddTypedTextChunk("__bridge");
1840*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1841*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1842*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1843*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1844*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1845*67e74705SXin Li
1846*67e74705SXin Li // (__bridge_transfer <Objective-C type>)<expression>
1847*67e74705SXin Li Builder.AddTypedTextChunk("__bridge_transfer");
1848*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1849*67e74705SXin Li Builder.AddPlaceholderChunk("Objective-C type");
1850*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1851*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1852*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1853*67e74705SXin Li
1854*67e74705SXin Li // (__bridge_retained <CF type>)<expression>
1855*67e74705SXin Li Builder.AddTypedTextChunk("__bridge_retained");
1856*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1857*67e74705SXin Li Builder.AddPlaceholderChunk("CF type");
1858*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1859*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1860*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1861*67e74705SXin Li }
1862*67e74705SXin Li // Fall through
1863*67e74705SXin Li
1864*67e74705SXin Li case Sema::PCC_Expression: {
1865*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus) {
1866*67e74705SXin Li // 'this', if we're in a non-static member function.
1867*67e74705SXin Li addThisCompletion(SemaRef, Results);
1868*67e74705SXin Li
1869*67e74705SXin Li // true
1870*67e74705SXin Li Builder.AddResultTypeChunk("bool");
1871*67e74705SXin Li Builder.AddTypedTextChunk("true");
1872*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1873*67e74705SXin Li
1874*67e74705SXin Li // false
1875*67e74705SXin Li Builder.AddResultTypeChunk("bool");
1876*67e74705SXin Li Builder.AddTypedTextChunk("false");
1877*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1878*67e74705SXin Li
1879*67e74705SXin Li if (SemaRef.getLangOpts().RTTI) {
1880*67e74705SXin Li // dynamic_cast < type-id > ( expression )
1881*67e74705SXin Li Builder.AddTypedTextChunk("dynamic_cast");
1882*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1883*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1884*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1885*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1886*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1887*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1888*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1889*67e74705SXin Li }
1890*67e74705SXin Li
1891*67e74705SXin Li // static_cast < type-id > ( expression )
1892*67e74705SXin Li Builder.AddTypedTextChunk("static_cast");
1893*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1894*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1895*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1896*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1897*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1898*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1899*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1900*67e74705SXin Li
1901*67e74705SXin Li // reinterpret_cast < type-id > ( expression )
1902*67e74705SXin Li Builder.AddTypedTextChunk("reinterpret_cast");
1903*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1904*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1905*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1906*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1907*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1908*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1909*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1910*67e74705SXin Li
1911*67e74705SXin Li // const_cast < type-id > ( expression )
1912*67e74705SXin Li Builder.AddTypedTextChunk("const_cast");
1913*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
1914*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1915*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightAngle);
1916*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1917*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1918*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1919*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1920*67e74705SXin Li
1921*67e74705SXin Li if (SemaRef.getLangOpts().RTTI) {
1922*67e74705SXin Li // typeid ( expression-or-type )
1923*67e74705SXin Li Builder.AddResultTypeChunk("std::type_info");
1924*67e74705SXin Li Builder.AddTypedTextChunk("typeid");
1925*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1926*67e74705SXin Li Builder.AddPlaceholderChunk("expression-or-type");
1927*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1928*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1929*67e74705SXin Li }
1930*67e74705SXin Li
1931*67e74705SXin Li // new T ( ... )
1932*67e74705SXin Li Builder.AddTypedTextChunk("new");
1933*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1934*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1935*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1936*67e74705SXin Li Builder.AddPlaceholderChunk("expressions");
1937*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1938*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1939*67e74705SXin Li
1940*67e74705SXin Li // new T [ ] ( ... )
1941*67e74705SXin Li Builder.AddTypedTextChunk("new");
1942*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1943*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1944*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
1945*67e74705SXin Li Builder.AddPlaceholderChunk("size");
1946*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBracket);
1947*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1948*67e74705SXin Li Builder.AddPlaceholderChunk("expressions");
1949*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1950*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1951*67e74705SXin Li
1952*67e74705SXin Li // delete expression
1953*67e74705SXin Li Builder.AddResultTypeChunk("void");
1954*67e74705SXin Li Builder.AddTypedTextChunk("delete");
1955*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1956*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1957*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1958*67e74705SXin Li
1959*67e74705SXin Li // delete [] expression
1960*67e74705SXin Li Builder.AddResultTypeChunk("void");
1961*67e74705SXin Li Builder.AddTypedTextChunk("delete");
1962*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1963*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
1964*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBracket);
1965*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1966*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1967*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1968*67e74705SXin Li
1969*67e74705SXin Li if (SemaRef.getLangOpts().CXXExceptions) {
1970*67e74705SXin Li // throw expression
1971*67e74705SXin Li Builder.AddResultTypeChunk("void");
1972*67e74705SXin Li Builder.AddTypedTextChunk("throw");
1973*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1974*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1975*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1976*67e74705SXin Li }
1977*67e74705SXin Li
1978*67e74705SXin Li // FIXME: Rethrow?
1979*67e74705SXin Li
1980*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus11) {
1981*67e74705SXin Li // nullptr
1982*67e74705SXin Li Builder.AddResultTypeChunk("std::nullptr_t");
1983*67e74705SXin Li Builder.AddTypedTextChunk("nullptr");
1984*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1985*67e74705SXin Li
1986*67e74705SXin Li // alignof
1987*67e74705SXin Li Builder.AddResultTypeChunk("size_t");
1988*67e74705SXin Li Builder.AddTypedTextChunk("alignof");
1989*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1990*67e74705SXin Li Builder.AddPlaceholderChunk("type");
1991*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
1992*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
1993*67e74705SXin Li
1994*67e74705SXin Li // noexcept
1995*67e74705SXin Li Builder.AddResultTypeChunk("bool");
1996*67e74705SXin Li Builder.AddTypedTextChunk("noexcept");
1997*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1998*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
1999*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
2000*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
2001*67e74705SXin Li
2002*67e74705SXin Li // sizeof... expression
2003*67e74705SXin Li Builder.AddResultTypeChunk("size_t");
2004*67e74705SXin Li Builder.AddTypedTextChunk("sizeof...");
2005*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2006*67e74705SXin Li Builder.AddPlaceholderChunk("parameter-pack");
2007*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
2008*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
2009*67e74705SXin Li }
2010*67e74705SXin Li }
2011*67e74705SXin Li
2012*67e74705SXin Li if (SemaRef.getLangOpts().ObjC1) {
2013*67e74705SXin Li // Add "super", if we're in an Objective-C class with a superclass.
2014*67e74705SXin Li if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
2015*67e74705SXin Li // The interface can be NULL.
2016*67e74705SXin Li if (ObjCInterfaceDecl *ID = Method->getClassInterface())
2017*67e74705SXin Li if (ID->getSuperClass()) {
2018*67e74705SXin Li std::string SuperType;
2019*67e74705SXin Li SuperType = ID->getSuperClass()->getNameAsString();
2020*67e74705SXin Li if (Method->isInstanceMethod())
2021*67e74705SXin Li SuperType += " *";
2022*67e74705SXin Li
2023*67e74705SXin Li Builder.AddResultTypeChunk(Allocator.CopyString(SuperType));
2024*67e74705SXin Li Builder.AddTypedTextChunk("super");
2025*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
2026*67e74705SXin Li }
2027*67e74705SXin Li }
2028*67e74705SXin Li
2029*67e74705SXin Li AddObjCExpressionResults(Results, true);
2030*67e74705SXin Li }
2031*67e74705SXin Li
2032*67e74705SXin Li if (SemaRef.getLangOpts().C11) {
2033*67e74705SXin Li // _Alignof
2034*67e74705SXin Li Builder.AddResultTypeChunk("size_t");
2035*67e74705SXin Li if (SemaRef.PP.isMacroDefined("alignof"))
2036*67e74705SXin Li Builder.AddTypedTextChunk("alignof");
2037*67e74705SXin Li else
2038*67e74705SXin Li Builder.AddTypedTextChunk("_Alignof");
2039*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2040*67e74705SXin Li Builder.AddPlaceholderChunk("type");
2041*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
2042*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
2043*67e74705SXin Li }
2044*67e74705SXin Li
2045*67e74705SXin Li // sizeof expression
2046*67e74705SXin Li Builder.AddResultTypeChunk("size_t");
2047*67e74705SXin Li Builder.AddTypedTextChunk("sizeof");
2048*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2049*67e74705SXin Li Builder.AddPlaceholderChunk("expression-or-type");
2050*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
2051*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
2052*67e74705SXin Li break;
2053*67e74705SXin Li }
2054*67e74705SXin Li
2055*67e74705SXin Li case Sema::PCC_Type:
2056*67e74705SXin Li case Sema::PCC_LocalDeclarationSpecifiers:
2057*67e74705SXin Li break;
2058*67e74705SXin Li }
2059*67e74705SXin Li
2060*67e74705SXin Li if (WantTypesInContext(CCC, SemaRef.getLangOpts()))
2061*67e74705SXin Li AddTypeSpecifierResults(SemaRef.getLangOpts(), Results);
2062*67e74705SXin Li
2063*67e74705SXin Li if (SemaRef.getLangOpts().CPlusPlus && CCC != Sema::PCC_Type)
2064*67e74705SXin Li Results.AddResult(Result("operator"));
2065*67e74705SXin Li }
2066*67e74705SXin Li
2067*67e74705SXin Li /// \brief If the given declaration has an associated type, add it as a result
2068*67e74705SXin Li /// type chunk.
AddResultTypeChunk(ASTContext & Context,const PrintingPolicy & Policy,const NamedDecl * ND,QualType BaseType,CodeCompletionBuilder & Result)2069*67e74705SXin Li static void AddResultTypeChunk(ASTContext &Context,
2070*67e74705SXin Li const PrintingPolicy &Policy,
2071*67e74705SXin Li const NamedDecl *ND,
2072*67e74705SXin Li QualType BaseType,
2073*67e74705SXin Li CodeCompletionBuilder &Result) {
2074*67e74705SXin Li if (!ND)
2075*67e74705SXin Li return;
2076*67e74705SXin Li
2077*67e74705SXin Li // Skip constructors and conversion functions, which have their return types
2078*67e74705SXin Li // built into their names.
2079*67e74705SXin Li if (isa<CXXConstructorDecl>(ND) || isa<CXXConversionDecl>(ND))
2080*67e74705SXin Li return;
2081*67e74705SXin Li
2082*67e74705SXin Li // Determine the type of the declaration (if it has a type).
2083*67e74705SXin Li QualType T;
2084*67e74705SXin Li if (const FunctionDecl *Function = ND->getAsFunction())
2085*67e74705SXin Li T = Function->getReturnType();
2086*67e74705SXin Li else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
2087*67e74705SXin Li if (!BaseType.isNull())
2088*67e74705SXin Li T = Method->getSendResultType(BaseType);
2089*67e74705SXin Li else
2090*67e74705SXin Li T = Method->getReturnType();
2091*67e74705SXin Li } else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
2092*67e74705SXin Li T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
2093*67e74705SXin Li else if (isa<UnresolvedUsingValueDecl>(ND)) {
2094*67e74705SXin Li /* Do nothing: ignore unresolved using declarations*/
2095*67e74705SXin Li } else if (const ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(ND)) {
2096*67e74705SXin Li if (!BaseType.isNull())
2097*67e74705SXin Li T = Ivar->getUsageType(BaseType);
2098*67e74705SXin Li else
2099*67e74705SXin Li T = Ivar->getType();
2100*67e74705SXin Li } else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) {
2101*67e74705SXin Li T = Value->getType();
2102*67e74705SXin Li } else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) {
2103*67e74705SXin Li if (!BaseType.isNull())
2104*67e74705SXin Li T = Property->getUsageType(BaseType);
2105*67e74705SXin Li else
2106*67e74705SXin Li T = Property->getType();
2107*67e74705SXin Li }
2108*67e74705SXin Li
2109*67e74705SXin Li if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
2110*67e74705SXin Li return;
2111*67e74705SXin Li
2112*67e74705SXin Li Result.AddResultTypeChunk(GetCompletionTypeString(T, Context, Policy,
2113*67e74705SXin Li Result.getAllocator()));
2114*67e74705SXin Li }
2115*67e74705SXin Li
MaybeAddSentinel(Preprocessor & PP,const NamedDecl * FunctionOrMethod,CodeCompletionBuilder & Result)2116*67e74705SXin Li static void MaybeAddSentinel(Preprocessor &PP,
2117*67e74705SXin Li const NamedDecl *FunctionOrMethod,
2118*67e74705SXin Li CodeCompletionBuilder &Result) {
2119*67e74705SXin Li if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
2120*67e74705SXin Li if (Sentinel->getSentinel() == 0) {
2121*67e74705SXin Li if (PP.getLangOpts().ObjC1 && PP.isMacroDefined("nil"))
2122*67e74705SXin Li Result.AddTextChunk(", nil");
2123*67e74705SXin Li else if (PP.isMacroDefined("NULL"))
2124*67e74705SXin Li Result.AddTextChunk(", NULL");
2125*67e74705SXin Li else
2126*67e74705SXin Li Result.AddTextChunk(", (void*)0");
2127*67e74705SXin Li }
2128*67e74705SXin Li }
2129*67e74705SXin Li
formatObjCParamQualifiers(unsigned ObjCQuals,QualType & Type)2130*67e74705SXin Li static std::string formatObjCParamQualifiers(unsigned ObjCQuals,
2131*67e74705SXin Li QualType &Type) {
2132*67e74705SXin Li std::string Result;
2133*67e74705SXin Li if (ObjCQuals & Decl::OBJC_TQ_In)
2134*67e74705SXin Li Result += "in ";
2135*67e74705SXin Li else if (ObjCQuals & Decl::OBJC_TQ_Inout)
2136*67e74705SXin Li Result += "inout ";
2137*67e74705SXin Li else if (ObjCQuals & Decl::OBJC_TQ_Out)
2138*67e74705SXin Li Result += "out ";
2139*67e74705SXin Li if (ObjCQuals & Decl::OBJC_TQ_Bycopy)
2140*67e74705SXin Li Result += "bycopy ";
2141*67e74705SXin Li else if (ObjCQuals & Decl::OBJC_TQ_Byref)
2142*67e74705SXin Li Result += "byref ";
2143*67e74705SXin Li if (ObjCQuals & Decl::OBJC_TQ_Oneway)
2144*67e74705SXin Li Result += "oneway ";
2145*67e74705SXin Li if (ObjCQuals & Decl::OBJC_TQ_CSNullability) {
2146*67e74705SXin Li if (auto nullability = AttributedType::stripOuterNullability(Type)) {
2147*67e74705SXin Li switch (*nullability) {
2148*67e74705SXin Li case NullabilityKind::NonNull:
2149*67e74705SXin Li Result += "nonnull ";
2150*67e74705SXin Li break;
2151*67e74705SXin Li
2152*67e74705SXin Li case NullabilityKind::Nullable:
2153*67e74705SXin Li Result += "nullable ";
2154*67e74705SXin Li break;
2155*67e74705SXin Li
2156*67e74705SXin Li case NullabilityKind::Unspecified:
2157*67e74705SXin Li Result += "null_unspecified ";
2158*67e74705SXin Li break;
2159*67e74705SXin Li }
2160*67e74705SXin Li }
2161*67e74705SXin Li }
2162*67e74705SXin Li return Result;
2163*67e74705SXin Li }
2164*67e74705SXin Li
FormatFunctionParameter(const PrintingPolicy & Policy,const ParmVarDecl * Param,bool SuppressName=false,bool SuppressBlock=false,Optional<ArrayRef<QualType>> ObjCSubsts=None)2165*67e74705SXin Li static std::string FormatFunctionParameter(const PrintingPolicy &Policy,
2166*67e74705SXin Li const ParmVarDecl *Param,
2167*67e74705SXin Li bool SuppressName = false,
2168*67e74705SXin Li bool SuppressBlock = false,
2169*67e74705SXin Li Optional<ArrayRef<QualType>> ObjCSubsts = None) {
2170*67e74705SXin Li bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
2171*67e74705SXin Li if (Param->getType()->isDependentType() ||
2172*67e74705SXin Li !Param->getType()->isBlockPointerType()) {
2173*67e74705SXin Li // The argument for a dependent or non-block parameter is a placeholder
2174*67e74705SXin Li // containing that parameter's type.
2175*67e74705SXin Li std::string Result;
2176*67e74705SXin Li
2177*67e74705SXin Li if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
2178*67e74705SXin Li Result = Param->getIdentifier()->getName();
2179*67e74705SXin Li
2180*67e74705SXin Li QualType Type = Param->getType();
2181*67e74705SXin Li if (ObjCSubsts)
2182*67e74705SXin Li Type = Type.substObjCTypeArgs(Param->getASTContext(), *ObjCSubsts,
2183*67e74705SXin Li ObjCSubstitutionContext::Parameter);
2184*67e74705SXin Li if (ObjCMethodParam) {
2185*67e74705SXin Li Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier(),
2186*67e74705SXin Li Type);
2187*67e74705SXin Li Result += Type.getAsString(Policy) + ")";
2188*67e74705SXin Li if (Param->getIdentifier() && !SuppressName)
2189*67e74705SXin Li Result += Param->getIdentifier()->getName();
2190*67e74705SXin Li } else {
2191*67e74705SXin Li Type.getAsStringInternal(Result, Policy);
2192*67e74705SXin Li }
2193*67e74705SXin Li return Result;
2194*67e74705SXin Li }
2195*67e74705SXin Li
2196*67e74705SXin Li // The argument for a block pointer parameter is a block literal with
2197*67e74705SXin Li // the appropriate type.
2198*67e74705SXin Li FunctionTypeLoc Block;
2199*67e74705SXin Li FunctionProtoTypeLoc BlockProto;
2200*67e74705SXin Li TypeLoc TL;
2201*67e74705SXin Li if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
2202*67e74705SXin Li TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
2203*67e74705SXin Li while (true) {
2204*67e74705SXin Li // Look through typedefs.
2205*67e74705SXin Li if (!SuppressBlock) {
2206*67e74705SXin Li if (TypedefTypeLoc TypedefTL = TL.getAs<TypedefTypeLoc>()) {
2207*67e74705SXin Li if (TypeSourceInfo *InnerTSInfo =
2208*67e74705SXin Li TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) {
2209*67e74705SXin Li TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
2210*67e74705SXin Li continue;
2211*67e74705SXin Li }
2212*67e74705SXin Li }
2213*67e74705SXin Li
2214*67e74705SXin Li // Look through qualified types
2215*67e74705SXin Li if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) {
2216*67e74705SXin Li TL = QualifiedTL.getUnqualifiedLoc();
2217*67e74705SXin Li continue;
2218*67e74705SXin Li }
2219*67e74705SXin Li
2220*67e74705SXin Li if (AttributedTypeLoc AttrTL = TL.getAs<AttributedTypeLoc>()) {
2221*67e74705SXin Li TL = AttrTL.getModifiedLoc();
2222*67e74705SXin Li continue;
2223*67e74705SXin Li }
2224*67e74705SXin Li }
2225*67e74705SXin Li
2226*67e74705SXin Li // Try to get the function prototype behind the block pointer type,
2227*67e74705SXin Li // then we're done.
2228*67e74705SXin Li if (BlockPointerTypeLoc BlockPtr = TL.getAs<BlockPointerTypeLoc>()) {
2229*67e74705SXin Li TL = BlockPtr.getPointeeLoc().IgnoreParens();
2230*67e74705SXin Li Block = TL.getAs<FunctionTypeLoc>();
2231*67e74705SXin Li BlockProto = TL.getAs<FunctionProtoTypeLoc>();
2232*67e74705SXin Li }
2233*67e74705SXin Li break;
2234*67e74705SXin Li }
2235*67e74705SXin Li }
2236*67e74705SXin Li
2237*67e74705SXin Li if (!Block) {
2238*67e74705SXin Li // We were unable to find a FunctionProtoTypeLoc with parameter names
2239*67e74705SXin Li // for the block; just use the parameter type as a placeholder.
2240*67e74705SXin Li std::string Result;
2241*67e74705SXin Li if (!ObjCMethodParam && Param->getIdentifier())
2242*67e74705SXin Li Result = Param->getIdentifier()->getName();
2243*67e74705SXin Li
2244*67e74705SXin Li QualType Type = Param->getType().getUnqualifiedType();
2245*67e74705SXin Li
2246*67e74705SXin Li if (ObjCMethodParam) {
2247*67e74705SXin Li Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier(),
2248*67e74705SXin Li Type);
2249*67e74705SXin Li Result += Type.getAsString(Policy) + Result + ")";
2250*67e74705SXin Li if (Param->getIdentifier())
2251*67e74705SXin Li Result += Param->getIdentifier()->getName();
2252*67e74705SXin Li } else {
2253*67e74705SXin Li Type.getAsStringInternal(Result, Policy);
2254*67e74705SXin Li }
2255*67e74705SXin Li
2256*67e74705SXin Li return Result;
2257*67e74705SXin Li }
2258*67e74705SXin Li
2259*67e74705SXin Li // We have the function prototype behind the block pointer type, as it was
2260*67e74705SXin Li // written in the source.
2261*67e74705SXin Li std::string Result;
2262*67e74705SXin Li QualType ResultType = Block.getTypePtr()->getReturnType();
2263*67e74705SXin Li if (ObjCSubsts)
2264*67e74705SXin Li ResultType = ResultType.substObjCTypeArgs(Param->getASTContext(),
2265*67e74705SXin Li *ObjCSubsts,
2266*67e74705SXin Li ObjCSubstitutionContext::Result);
2267*67e74705SXin Li if (!ResultType->isVoidType() || SuppressBlock)
2268*67e74705SXin Li ResultType.getAsStringInternal(Result, Policy);
2269*67e74705SXin Li
2270*67e74705SXin Li // Format the parameter list.
2271*67e74705SXin Li std::string Params;
2272*67e74705SXin Li if (!BlockProto || Block.getNumParams() == 0) {
2273*67e74705SXin Li if (BlockProto && BlockProto.getTypePtr()->isVariadic())
2274*67e74705SXin Li Params = "(...)";
2275*67e74705SXin Li else
2276*67e74705SXin Li Params = "(void)";
2277*67e74705SXin Li } else {
2278*67e74705SXin Li Params += "(";
2279*67e74705SXin Li for (unsigned I = 0, N = Block.getNumParams(); I != N; ++I) {
2280*67e74705SXin Li if (I)
2281*67e74705SXin Li Params += ", ";
2282*67e74705SXin Li Params += FormatFunctionParameter(Policy, Block.getParam(I),
2283*67e74705SXin Li /*SuppressName=*/false,
2284*67e74705SXin Li /*SuppressBlock=*/true,
2285*67e74705SXin Li ObjCSubsts);
2286*67e74705SXin Li
2287*67e74705SXin Li if (I == N - 1 && BlockProto.getTypePtr()->isVariadic())
2288*67e74705SXin Li Params += ", ...";
2289*67e74705SXin Li }
2290*67e74705SXin Li Params += ")";
2291*67e74705SXin Li }
2292*67e74705SXin Li
2293*67e74705SXin Li if (SuppressBlock) {
2294*67e74705SXin Li // Format as a parameter.
2295*67e74705SXin Li Result = Result + " (^";
2296*67e74705SXin Li if (Param->getIdentifier())
2297*67e74705SXin Li Result += Param->getIdentifier()->getName();
2298*67e74705SXin Li Result += ")";
2299*67e74705SXin Li Result += Params;
2300*67e74705SXin Li } else {
2301*67e74705SXin Li // Format as a block literal argument.
2302*67e74705SXin Li Result = '^' + Result;
2303*67e74705SXin Li Result += Params;
2304*67e74705SXin Li
2305*67e74705SXin Li if (Param->getIdentifier())
2306*67e74705SXin Li Result += Param->getIdentifier()->getName();
2307*67e74705SXin Li }
2308*67e74705SXin Li
2309*67e74705SXin Li return Result;
2310*67e74705SXin Li }
2311*67e74705SXin Li
2312*67e74705SXin Li /// \brief Add function parameter chunks to the given code completion string.
AddFunctionParameterChunks(Preprocessor & PP,const PrintingPolicy & Policy,const FunctionDecl * Function,CodeCompletionBuilder & Result,unsigned Start=0,bool InOptional=false)2313*67e74705SXin Li static void AddFunctionParameterChunks(Preprocessor &PP,
2314*67e74705SXin Li const PrintingPolicy &Policy,
2315*67e74705SXin Li const FunctionDecl *Function,
2316*67e74705SXin Li CodeCompletionBuilder &Result,
2317*67e74705SXin Li unsigned Start = 0,
2318*67e74705SXin Li bool InOptional = false) {
2319*67e74705SXin Li bool FirstParameter = true;
2320*67e74705SXin Li
2321*67e74705SXin Li for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) {
2322*67e74705SXin Li const ParmVarDecl *Param = Function->getParamDecl(P);
2323*67e74705SXin Li
2324*67e74705SXin Li if (Param->hasDefaultArg() && !InOptional) {
2325*67e74705SXin Li // When we see an optional default argument, put that argument and
2326*67e74705SXin Li // the remaining default arguments into a new, optional string.
2327*67e74705SXin Li CodeCompletionBuilder Opt(Result.getAllocator(),
2328*67e74705SXin Li Result.getCodeCompletionTUInfo());
2329*67e74705SXin Li if (!FirstParameter)
2330*67e74705SXin Li Opt.AddChunk(CodeCompletionString::CK_Comma);
2331*67e74705SXin Li AddFunctionParameterChunks(PP, Policy, Function, Opt, P, true);
2332*67e74705SXin Li Result.AddOptionalChunk(Opt.TakeString());
2333*67e74705SXin Li break;
2334*67e74705SXin Li }
2335*67e74705SXin Li
2336*67e74705SXin Li if (FirstParameter)
2337*67e74705SXin Li FirstParameter = false;
2338*67e74705SXin Li else
2339*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_Comma);
2340*67e74705SXin Li
2341*67e74705SXin Li InOptional = false;
2342*67e74705SXin Li
2343*67e74705SXin Li // Format the placeholder string.
2344*67e74705SXin Li std::string PlaceholderStr = FormatFunctionParameter(Policy, Param);
2345*67e74705SXin Li
2346*67e74705SXin Li if (Function->isVariadic() && P == N - 1)
2347*67e74705SXin Li PlaceholderStr += ", ...";
2348*67e74705SXin Li
2349*67e74705SXin Li // Add the placeholder string.
2350*67e74705SXin Li Result.AddPlaceholderChunk(
2351*67e74705SXin Li Result.getAllocator().CopyString(PlaceholderStr));
2352*67e74705SXin Li }
2353*67e74705SXin Li
2354*67e74705SXin Li if (const FunctionProtoType *Proto
2355*67e74705SXin Li = Function->getType()->getAs<FunctionProtoType>())
2356*67e74705SXin Li if (Proto->isVariadic()) {
2357*67e74705SXin Li if (Proto->getNumParams() == 0)
2358*67e74705SXin Li Result.AddPlaceholderChunk("...");
2359*67e74705SXin Li
2360*67e74705SXin Li MaybeAddSentinel(PP, Function, Result);
2361*67e74705SXin Li }
2362*67e74705SXin Li }
2363*67e74705SXin Li
2364*67e74705SXin Li /// \brief Add template parameter chunks to the given code completion string.
AddTemplateParameterChunks(ASTContext & Context,const PrintingPolicy & Policy,const TemplateDecl * Template,CodeCompletionBuilder & Result,unsigned MaxParameters=0,unsigned Start=0,bool InDefaultArg=false)2365*67e74705SXin Li static void AddTemplateParameterChunks(ASTContext &Context,
2366*67e74705SXin Li const PrintingPolicy &Policy,
2367*67e74705SXin Li const TemplateDecl *Template,
2368*67e74705SXin Li CodeCompletionBuilder &Result,
2369*67e74705SXin Li unsigned MaxParameters = 0,
2370*67e74705SXin Li unsigned Start = 0,
2371*67e74705SXin Li bool InDefaultArg = false) {
2372*67e74705SXin Li bool FirstParameter = true;
2373*67e74705SXin Li
2374*67e74705SXin Li // Prefer to take the template parameter names from the first declaration of
2375*67e74705SXin Li // the template.
2376*67e74705SXin Li Template = cast<TemplateDecl>(Template->getCanonicalDecl());
2377*67e74705SXin Li
2378*67e74705SXin Li TemplateParameterList *Params = Template->getTemplateParameters();
2379*67e74705SXin Li TemplateParameterList::iterator PEnd = Params->end();
2380*67e74705SXin Li if (MaxParameters)
2381*67e74705SXin Li PEnd = Params->begin() + MaxParameters;
2382*67e74705SXin Li for (TemplateParameterList::iterator P = Params->begin() + Start;
2383*67e74705SXin Li P != PEnd; ++P) {
2384*67e74705SXin Li bool HasDefaultArg = false;
2385*67e74705SXin Li std::string PlaceholderStr;
2386*67e74705SXin Li if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
2387*67e74705SXin Li if (TTP->wasDeclaredWithTypename())
2388*67e74705SXin Li PlaceholderStr = "typename";
2389*67e74705SXin Li else
2390*67e74705SXin Li PlaceholderStr = "class";
2391*67e74705SXin Li
2392*67e74705SXin Li if (TTP->getIdentifier()) {
2393*67e74705SXin Li PlaceholderStr += ' ';
2394*67e74705SXin Li PlaceholderStr += TTP->getIdentifier()->getName();
2395*67e74705SXin Li }
2396*67e74705SXin Li
2397*67e74705SXin Li HasDefaultArg = TTP->hasDefaultArgument();
2398*67e74705SXin Li } else if (NonTypeTemplateParmDecl *NTTP
2399*67e74705SXin Li = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
2400*67e74705SXin Li if (NTTP->getIdentifier())
2401*67e74705SXin Li PlaceholderStr = NTTP->getIdentifier()->getName();
2402*67e74705SXin Li NTTP->getType().getAsStringInternal(PlaceholderStr, Policy);
2403*67e74705SXin Li HasDefaultArg = NTTP->hasDefaultArgument();
2404*67e74705SXin Li } else {
2405*67e74705SXin Li assert(isa<TemplateTemplateParmDecl>(*P));
2406*67e74705SXin Li TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
2407*67e74705SXin Li
2408*67e74705SXin Li // Since putting the template argument list into the placeholder would
2409*67e74705SXin Li // be very, very long, we just use an abbreviation.
2410*67e74705SXin Li PlaceholderStr = "template<...> class";
2411*67e74705SXin Li if (TTP->getIdentifier()) {
2412*67e74705SXin Li PlaceholderStr += ' ';
2413*67e74705SXin Li PlaceholderStr += TTP->getIdentifier()->getName();
2414*67e74705SXin Li }
2415*67e74705SXin Li
2416*67e74705SXin Li HasDefaultArg = TTP->hasDefaultArgument();
2417*67e74705SXin Li }
2418*67e74705SXin Li
2419*67e74705SXin Li if (HasDefaultArg && !InDefaultArg) {
2420*67e74705SXin Li // When we see an optional default argument, put that argument and
2421*67e74705SXin Li // the remaining default arguments into a new, optional string.
2422*67e74705SXin Li CodeCompletionBuilder Opt(Result.getAllocator(),
2423*67e74705SXin Li Result.getCodeCompletionTUInfo());
2424*67e74705SXin Li if (!FirstParameter)
2425*67e74705SXin Li Opt.AddChunk(CodeCompletionString::CK_Comma);
2426*67e74705SXin Li AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters,
2427*67e74705SXin Li P - Params->begin(), true);
2428*67e74705SXin Li Result.AddOptionalChunk(Opt.TakeString());
2429*67e74705SXin Li break;
2430*67e74705SXin Li }
2431*67e74705SXin Li
2432*67e74705SXin Li InDefaultArg = false;
2433*67e74705SXin Li
2434*67e74705SXin Li if (FirstParameter)
2435*67e74705SXin Li FirstParameter = false;
2436*67e74705SXin Li else
2437*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_Comma);
2438*67e74705SXin Li
2439*67e74705SXin Li // Add the placeholder string.
2440*67e74705SXin Li Result.AddPlaceholderChunk(
2441*67e74705SXin Li Result.getAllocator().CopyString(PlaceholderStr));
2442*67e74705SXin Li }
2443*67e74705SXin Li }
2444*67e74705SXin Li
2445*67e74705SXin Li /// \brief Add a qualifier to the given code-completion string, if the
2446*67e74705SXin Li /// provided nested-name-specifier is non-NULL.
2447*67e74705SXin Li static void
AddQualifierToCompletionString(CodeCompletionBuilder & Result,NestedNameSpecifier * Qualifier,bool QualifierIsInformative,ASTContext & Context,const PrintingPolicy & Policy)2448*67e74705SXin Li AddQualifierToCompletionString(CodeCompletionBuilder &Result,
2449*67e74705SXin Li NestedNameSpecifier *Qualifier,
2450*67e74705SXin Li bool QualifierIsInformative,
2451*67e74705SXin Li ASTContext &Context,
2452*67e74705SXin Li const PrintingPolicy &Policy) {
2453*67e74705SXin Li if (!Qualifier)
2454*67e74705SXin Li return;
2455*67e74705SXin Li
2456*67e74705SXin Li std::string PrintedNNS;
2457*67e74705SXin Li {
2458*67e74705SXin Li llvm::raw_string_ostream OS(PrintedNNS);
2459*67e74705SXin Li Qualifier->print(OS, Policy);
2460*67e74705SXin Li }
2461*67e74705SXin Li if (QualifierIsInformative)
2462*67e74705SXin Li Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS));
2463*67e74705SXin Li else
2464*67e74705SXin Li Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS));
2465*67e74705SXin Li }
2466*67e74705SXin Li
2467*67e74705SXin Li static void
AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder & Result,const FunctionDecl * Function)2468*67e74705SXin Li AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
2469*67e74705SXin Li const FunctionDecl *Function) {
2470*67e74705SXin Li const FunctionProtoType *Proto
2471*67e74705SXin Li = Function->getType()->getAs<FunctionProtoType>();
2472*67e74705SXin Li if (!Proto || !Proto->getTypeQuals())
2473*67e74705SXin Li return;
2474*67e74705SXin Li
2475*67e74705SXin Li // FIXME: Add ref-qualifier!
2476*67e74705SXin Li
2477*67e74705SXin Li // Handle single qualifiers without copying
2478*67e74705SXin Li if (Proto->getTypeQuals() == Qualifiers::Const) {
2479*67e74705SXin Li Result.AddInformativeChunk(" const");
2480*67e74705SXin Li return;
2481*67e74705SXin Li }
2482*67e74705SXin Li
2483*67e74705SXin Li if (Proto->getTypeQuals() == Qualifiers::Volatile) {
2484*67e74705SXin Li Result.AddInformativeChunk(" volatile");
2485*67e74705SXin Li return;
2486*67e74705SXin Li }
2487*67e74705SXin Li
2488*67e74705SXin Li if (Proto->getTypeQuals() == Qualifiers::Restrict) {
2489*67e74705SXin Li Result.AddInformativeChunk(" restrict");
2490*67e74705SXin Li return;
2491*67e74705SXin Li }
2492*67e74705SXin Li
2493*67e74705SXin Li // Handle multiple qualifiers.
2494*67e74705SXin Li std::string QualsStr;
2495*67e74705SXin Li if (Proto->isConst())
2496*67e74705SXin Li QualsStr += " const";
2497*67e74705SXin Li if (Proto->isVolatile())
2498*67e74705SXin Li QualsStr += " volatile";
2499*67e74705SXin Li if (Proto->isRestrict())
2500*67e74705SXin Li QualsStr += " restrict";
2501*67e74705SXin Li Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr));
2502*67e74705SXin Li }
2503*67e74705SXin Li
2504*67e74705SXin Li /// \brief Add the name of the given declaration
AddTypedNameChunk(ASTContext & Context,const PrintingPolicy & Policy,const NamedDecl * ND,CodeCompletionBuilder & Result)2505*67e74705SXin Li static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
2506*67e74705SXin Li const NamedDecl *ND,
2507*67e74705SXin Li CodeCompletionBuilder &Result) {
2508*67e74705SXin Li DeclarationName Name = ND->getDeclName();
2509*67e74705SXin Li if (!Name)
2510*67e74705SXin Li return;
2511*67e74705SXin Li
2512*67e74705SXin Li switch (Name.getNameKind()) {
2513*67e74705SXin Li case DeclarationName::CXXOperatorName: {
2514*67e74705SXin Li const char *OperatorName = nullptr;
2515*67e74705SXin Li switch (Name.getCXXOverloadedOperator()) {
2516*67e74705SXin Li case OO_None:
2517*67e74705SXin Li case OO_Conditional:
2518*67e74705SXin Li case NUM_OVERLOADED_OPERATORS:
2519*67e74705SXin Li OperatorName = "operator";
2520*67e74705SXin Li break;
2521*67e74705SXin Li
2522*67e74705SXin Li #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2523*67e74705SXin Li case OO_##Name: OperatorName = "operator" Spelling; break;
2524*67e74705SXin Li #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
2525*67e74705SXin Li #include "clang/Basic/OperatorKinds.def"
2526*67e74705SXin Li
2527*67e74705SXin Li case OO_New: OperatorName = "operator new"; break;
2528*67e74705SXin Li case OO_Delete: OperatorName = "operator delete"; break;
2529*67e74705SXin Li case OO_Array_New: OperatorName = "operator new[]"; break;
2530*67e74705SXin Li case OO_Array_Delete: OperatorName = "operator delete[]"; break;
2531*67e74705SXin Li case OO_Call: OperatorName = "operator()"; break;
2532*67e74705SXin Li case OO_Subscript: OperatorName = "operator[]"; break;
2533*67e74705SXin Li }
2534*67e74705SXin Li Result.AddTypedTextChunk(OperatorName);
2535*67e74705SXin Li break;
2536*67e74705SXin Li }
2537*67e74705SXin Li
2538*67e74705SXin Li case DeclarationName::Identifier:
2539*67e74705SXin Li case DeclarationName::CXXConversionFunctionName:
2540*67e74705SXin Li case DeclarationName::CXXDestructorName:
2541*67e74705SXin Li case DeclarationName::CXXLiteralOperatorName:
2542*67e74705SXin Li Result.AddTypedTextChunk(
2543*67e74705SXin Li Result.getAllocator().CopyString(ND->getNameAsString()));
2544*67e74705SXin Li break;
2545*67e74705SXin Li
2546*67e74705SXin Li case DeclarationName::CXXUsingDirective:
2547*67e74705SXin Li case DeclarationName::ObjCZeroArgSelector:
2548*67e74705SXin Li case DeclarationName::ObjCOneArgSelector:
2549*67e74705SXin Li case DeclarationName::ObjCMultiArgSelector:
2550*67e74705SXin Li break;
2551*67e74705SXin Li
2552*67e74705SXin Li case DeclarationName::CXXConstructorName: {
2553*67e74705SXin Li CXXRecordDecl *Record = nullptr;
2554*67e74705SXin Li QualType Ty = Name.getCXXNameType();
2555*67e74705SXin Li if (const RecordType *RecordTy = Ty->getAs<RecordType>())
2556*67e74705SXin Li Record = cast<CXXRecordDecl>(RecordTy->getDecl());
2557*67e74705SXin Li else if (const InjectedClassNameType *InjectedTy
2558*67e74705SXin Li = Ty->getAs<InjectedClassNameType>())
2559*67e74705SXin Li Record = InjectedTy->getDecl();
2560*67e74705SXin Li else {
2561*67e74705SXin Li Result.AddTypedTextChunk(
2562*67e74705SXin Li Result.getAllocator().CopyString(ND->getNameAsString()));
2563*67e74705SXin Li break;
2564*67e74705SXin Li }
2565*67e74705SXin Li
2566*67e74705SXin Li Result.AddTypedTextChunk(
2567*67e74705SXin Li Result.getAllocator().CopyString(Record->getNameAsString()));
2568*67e74705SXin Li if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
2569*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_LeftAngle);
2570*67e74705SXin Li AddTemplateParameterChunks(Context, Policy, Template, Result);
2571*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_RightAngle);
2572*67e74705SXin Li }
2573*67e74705SXin Li break;
2574*67e74705SXin Li }
2575*67e74705SXin Li }
2576*67e74705SXin Li }
2577*67e74705SXin Li
CreateCodeCompletionString(Sema & S,const CodeCompletionContext & CCContext,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,bool IncludeBriefComments)2578*67e74705SXin Li CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S,
2579*67e74705SXin Li const CodeCompletionContext &CCContext,
2580*67e74705SXin Li CodeCompletionAllocator &Allocator,
2581*67e74705SXin Li CodeCompletionTUInfo &CCTUInfo,
2582*67e74705SXin Li bool IncludeBriefComments) {
2583*67e74705SXin Li return CreateCodeCompletionString(S.Context, S.PP, CCContext, Allocator,
2584*67e74705SXin Li CCTUInfo, IncludeBriefComments);
2585*67e74705SXin Li }
2586*67e74705SXin Li
2587*67e74705SXin Li /// \brief If possible, create a new code completion string for the given
2588*67e74705SXin Li /// result.
2589*67e74705SXin Li ///
2590*67e74705SXin Li /// \returns Either a new, heap-allocated code completion string describing
2591*67e74705SXin Li /// how to use this result, or NULL to indicate that the string or name of the
2592*67e74705SXin Li /// result is all that is needed.
2593*67e74705SXin Li CodeCompletionString *
CreateCodeCompletionString(ASTContext & Ctx,Preprocessor & PP,const CodeCompletionContext & CCContext,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,bool IncludeBriefComments)2594*67e74705SXin Li CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
2595*67e74705SXin Li Preprocessor &PP,
2596*67e74705SXin Li const CodeCompletionContext &CCContext,
2597*67e74705SXin Li CodeCompletionAllocator &Allocator,
2598*67e74705SXin Li CodeCompletionTUInfo &CCTUInfo,
2599*67e74705SXin Li bool IncludeBriefComments) {
2600*67e74705SXin Li CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
2601*67e74705SXin Li
2602*67e74705SXin Li PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
2603*67e74705SXin Li if (Kind == RK_Pattern) {
2604*67e74705SXin Li Pattern->Priority = Priority;
2605*67e74705SXin Li Pattern->Availability = Availability;
2606*67e74705SXin Li
2607*67e74705SXin Li if (Declaration) {
2608*67e74705SXin Li Result.addParentContext(Declaration->getDeclContext());
2609*67e74705SXin Li Pattern->ParentName = Result.getParentName();
2610*67e74705SXin Li // Provide code completion comment for self.GetterName where
2611*67e74705SXin Li // GetterName is the getter method for a property with name
2612*67e74705SXin Li // different from the property name (declared via a property
2613*67e74705SXin Li // getter attribute.
2614*67e74705SXin Li const NamedDecl *ND = Declaration;
2615*67e74705SXin Li if (const ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(ND))
2616*67e74705SXin Li if (M->isPropertyAccessor())
2617*67e74705SXin Li if (const ObjCPropertyDecl *PDecl = M->findPropertyDecl())
2618*67e74705SXin Li if (PDecl->getGetterName() == M->getSelector() &&
2619*67e74705SXin Li PDecl->getIdentifier() != M->getIdentifier()) {
2620*67e74705SXin Li if (const RawComment *RC =
2621*67e74705SXin Li Ctx.getRawCommentForAnyRedecl(M)) {
2622*67e74705SXin Li Result.addBriefComment(RC->getBriefText(Ctx));
2623*67e74705SXin Li Pattern->BriefComment = Result.getBriefComment();
2624*67e74705SXin Li }
2625*67e74705SXin Li else if (const RawComment *RC =
2626*67e74705SXin Li Ctx.getRawCommentForAnyRedecl(PDecl)) {
2627*67e74705SXin Li Result.addBriefComment(RC->getBriefText(Ctx));
2628*67e74705SXin Li Pattern->BriefComment = Result.getBriefComment();
2629*67e74705SXin Li }
2630*67e74705SXin Li }
2631*67e74705SXin Li }
2632*67e74705SXin Li
2633*67e74705SXin Li return Pattern;
2634*67e74705SXin Li }
2635*67e74705SXin Li
2636*67e74705SXin Li if (Kind == RK_Keyword) {
2637*67e74705SXin Li Result.AddTypedTextChunk(Keyword);
2638*67e74705SXin Li return Result.TakeString();
2639*67e74705SXin Li }
2640*67e74705SXin Li
2641*67e74705SXin Li if (Kind == RK_Macro) {
2642*67e74705SXin Li const MacroInfo *MI = PP.getMacroInfo(Macro);
2643*67e74705SXin Li Result.AddTypedTextChunk(
2644*67e74705SXin Li Result.getAllocator().CopyString(Macro->getName()));
2645*67e74705SXin Li
2646*67e74705SXin Li if (!MI || !MI->isFunctionLike())
2647*67e74705SXin Li return Result.TakeString();
2648*67e74705SXin Li
2649*67e74705SXin Li // Format a function-like macro with placeholders for the arguments.
2650*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_LeftParen);
2651*67e74705SXin Li MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
2652*67e74705SXin Li
2653*67e74705SXin Li // C99 variadic macros add __VA_ARGS__ at the end. Skip it.
2654*67e74705SXin Li if (MI->isC99Varargs()) {
2655*67e74705SXin Li --AEnd;
2656*67e74705SXin Li
2657*67e74705SXin Li if (A == AEnd) {
2658*67e74705SXin Li Result.AddPlaceholderChunk("...");
2659*67e74705SXin Li }
2660*67e74705SXin Li }
2661*67e74705SXin Li
2662*67e74705SXin Li for (MacroInfo::arg_iterator A = MI->arg_begin(); A != AEnd; ++A) {
2663*67e74705SXin Li if (A != MI->arg_begin())
2664*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_Comma);
2665*67e74705SXin Li
2666*67e74705SXin Li if (MI->isVariadic() && (A+1) == AEnd) {
2667*67e74705SXin Li SmallString<32> Arg = (*A)->getName();
2668*67e74705SXin Li if (MI->isC99Varargs())
2669*67e74705SXin Li Arg += ", ...";
2670*67e74705SXin Li else
2671*67e74705SXin Li Arg += "...";
2672*67e74705SXin Li Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
2673*67e74705SXin Li break;
2674*67e74705SXin Li }
2675*67e74705SXin Li
2676*67e74705SXin Li // Non-variadic macros are simple.
2677*67e74705SXin Li Result.AddPlaceholderChunk(
2678*67e74705SXin Li Result.getAllocator().CopyString((*A)->getName()));
2679*67e74705SXin Li }
2680*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_RightParen);
2681*67e74705SXin Li return Result.TakeString();
2682*67e74705SXin Li }
2683*67e74705SXin Li
2684*67e74705SXin Li assert(Kind == RK_Declaration && "Missed a result kind?");
2685*67e74705SXin Li const NamedDecl *ND = Declaration;
2686*67e74705SXin Li Result.addParentContext(ND->getDeclContext());
2687*67e74705SXin Li
2688*67e74705SXin Li if (IncludeBriefComments) {
2689*67e74705SXin Li // Add documentation comment, if it exists.
2690*67e74705SXin Li if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(ND)) {
2691*67e74705SXin Li Result.addBriefComment(RC->getBriefText(Ctx));
2692*67e74705SXin Li }
2693*67e74705SXin Li else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
2694*67e74705SXin Li if (OMD->isPropertyAccessor())
2695*67e74705SXin Li if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl())
2696*67e74705SXin Li if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(PDecl))
2697*67e74705SXin Li Result.addBriefComment(RC->getBriefText(Ctx));
2698*67e74705SXin Li }
2699*67e74705SXin Li
2700*67e74705SXin Li if (StartsNestedNameSpecifier) {
2701*67e74705SXin Li Result.AddTypedTextChunk(
2702*67e74705SXin Li Result.getAllocator().CopyString(ND->getNameAsString()));
2703*67e74705SXin Li Result.AddTextChunk("::");
2704*67e74705SXin Li return Result.TakeString();
2705*67e74705SXin Li }
2706*67e74705SXin Li
2707*67e74705SXin Li for (const auto *I : ND->specific_attrs<AnnotateAttr>())
2708*67e74705SXin Li Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation()));
2709*67e74705SXin Li
2710*67e74705SXin Li AddResultTypeChunk(Ctx, Policy, ND, CCContext.getBaseType(), Result);
2711*67e74705SXin Li
2712*67e74705SXin Li if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
2713*67e74705SXin Li AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2714*67e74705SXin Li Ctx, Policy);
2715*67e74705SXin Li AddTypedNameChunk(Ctx, Policy, ND, Result);
2716*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_LeftParen);
2717*67e74705SXin Li AddFunctionParameterChunks(PP, Policy, Function, Result);
2718*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_RightParen);
2719*67e74705SXin Li AddFunctionTypeQualsToCompletionString(Result, Function);
2720*67e74705SXin Li return Result.TakeString();
2721*67e74705SXin Li }
2722*67e74705SXin Li
2723*67e74705SXin Li if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
2724*67e74705SXin Li AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2725*67e74705SXin Li Ctx, Policy);
2726*67e74705SXin Li FunctionDecl *Function = FunTmpl->getTemplatedDecl();
2727*67e74705SXin Li AddTypedNameChunk(Ctx, Policy, Function, Result);
2728*67e74705SXin Li
2729*67e74705SXin Li // Figure out which template parameters are deduced (or have default
2730*67e74705SXin Li // arguments).
2731*67e74705SXin Li llvm::SmallBitVector Deduced;
2732*67e74705SXin Li Sema::MarkDeducedTemplateParameters(Ctx, FunTmpl, Deduced);
2733*67e74705SXin Li unsigned LastDeducibleArgument;
2734*67e74705SXin Li for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
2735*67e74705SXin Li --LastDeducibleArgument) {
2736*67e74705SXin Li if (!Deduced[LastDeducibleArgument - 1]) {
2737*67e74705SXin Li // C++0x: Figure out if the template argument has a default. If so,
2738*67e74705SXin Li // the user doesn't need to type this argument.
2739*67e74705SXin Li // FIXME: We need to abstract template parameters better!
2740*67e74705SXin Li bool HasDefaultArg = false;
2741*67e74705SXin Li NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
2742*67e74705SXin Li LastDeducibleArgument - 1);
2743*67e74705SXin Li if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2744*67e74705SXin Li HasDefaultArg = TTP->hasDefaultArgument();
2745*67e74705SXin Li else if (NonTypeTemplateParmDecl *NTTP
2746*67e74705SXin Li = dyn_cast<NonTypeTemplateParmDecl>(Param))
2747*67e74705SXin Li HasDefaultArg = NTTP->hasDefaultArgument();
2748*67e74705SXin Li else {
2749*67e74705SXin Li assert(isa<TemplateTemplateParmDecl>(Param));
2750*67e74705SXin Li HasDefaultArg
2751*67e74705SXin Li = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
2752*67e74705SXin Li }
2753*67e74705SXin Li
2754*67e74705SXin Li if (!HasDefaultArg)
2755*67e74705SXin Li break;
2756*67e74705SXin Li }
2757*67e74705SXin Li }
2758*67e74705SXin Li
2759*67e74705SXin Li if (LastDeducibleArgument) {
2760*67e74705SXin Li // Some of the function template arguments cannot be deduced from a
2761*67e74705SXin Li // function call, so we introduce an explicit template argument list
2762*67e74705SXin Li // containing all of the arguments up to the first deducible argument.
2763*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_LeftAngle);
2764*67e74705SXin Li AddTemplateParameterChunks(Ctx, Policy, FunTmpl, Result,
2765*67e74705SXin Li LastDeducibleArgument);
2766*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_RightAngle);
2767*67e74705SXin Li }
2768*67e74705SXin Li
2769*67e74705SXin Li // Add the function parameters
2770*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_LeftParen);
2771*67e74705SXin Li AddFunctionParameterChunks(PP, Policy, Function, Result);
2772*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_RightParen);
2773*67e74705SXin Li AddFunctionTypeQualsToCompletionString(Result, Function);
2774*67e74705SXin Li return Result.TakeString();
2775*67e74705SXin Li }
2776*67e74705SXin Li
2777*67e74705SXin Li if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
2778*67e74705SXin Li AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2779*67e74705SXin Li Ctx, Policy);
2780*67e74705SXin Li Result.AddTypedTextChunk(
2781*67e74705SXin Li Result.getAllocator().CopyString(Template->getNameAsString()));
2782*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_LeftAngle);
2783*67e74705SXin Li AddTemplateParameterChunks(Ctx, Policy, Template, Result);
2784*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_RightAngle);
2785*67e74705SXin Li return Result.TakeString();
2786*67e74705SXin Li }
2787*67e74705SXin Li
2788*67e74705SXin Li if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
2789*67e74705SXin Li Selector Sel = Method->getSelector();
2790*67e74705SXin Li if (Sel.isUnarySelector()) {
2791*67e74705SXin Li Result.AddTypedTextChunk(Result.getAllocator().CopyString(
2792*67e74705SXin Li Sel.getNameForSlot(0)));
2793*67e74705SXin Li return Result.TakeString();
2794*67e74705SXin Li }
2795*67e74705SXin Li
2796*67e74705SXin Li std::string SelName = Sel.getNameForSlot(0).str();
2797*67e74705SXin Li SelName += ':';
2798*67e74705SXin Li if (StartParameter == 0)
2799*67e74705SXin Li Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName));
2800*67e74705SXin Li else {
2801*67e74705SXin Li Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName));
2802*67e74705SXin Li
2803*67e74705SXin Li // If there is only one parameter, and we're past it, add an empty
2804*67e74705SXin Li // typed-text chunk since there is nothing to type.
2805*67e74705SXin Li if (Method->param_size() == 1)
2806*67e74705SXin Li Result.AddTypedTextChunk("");
2807*67e74705SXin Li }
2808*67e74705SXin Li unsigned Idx = 0;
2809*67e74705SXin Li for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
2810*67e74705SXin Li PEnd = Method->param_end();
2811*67e74705SXin Li P != PEnd; (void)++P, ++Idx) {
2812*67e74705SXin Li if (Idx > 0) {
2813*67e74705SXin Li std::string Keyword;
2814*67e74705SXin Li if (Idx > StartParameter)
2815*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2816*67e74705SXin Li if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
2817*67e74705SXin Li Keyword += II->getName();
2818*67e74705SXin Li Keyword += ":";
2819*67e74705SXin Li if (Idx < StartParameter || AllParametersAreInformative)
2820*67e74705SXin Li Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword));
2821*67e74705SXin Li else
2822*67e74705SXin Li Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword));
2823*67e74705SXin Li }
2824*67e74705SXin Li
2825*67e74705SXin Li // If we're before the starting parameter, skip the placeholder.
2826*67e74705SXin Li if (Idx < StartParameter)
2827*67e74705SXin Li continue;
2828*67e74705SXin Li
2829*67e74705SXin Li std::string Arg;
2830*67e74705SXin Li QualType ParamType = (*P)->getType();
2831*67e74705SXin Li Optional<ArrayRef<QualType>> ObjCSubsts;
2832*67e74705SXin Li if (!CCContext.getBaseType().isNull())
2833*67e74705SXin Li ObjCSubsts = CCContext.getBaseType()->getObjCSubstitutions(Method);
2834*67e74705SXin Li
2835*67e74705SXin Li if (ParamType->isBlockPointerType() && !DeclaringEntity)
2836*67e74705SXin Li Arg = FormatFunctionParameter(Policy, *P, true,
2837*67e74705SXin Li /*SuppressBlock=*/false,
2838*67e74705SXin Li ObjCSubsts);
2839*67e74705SXin Li else {
2840*67e74705SXin Li if (ObjCSubsts)
2841*67e74705SXin Li ParamType = ParamType.substObjCTypeArgs(Ctx, *ObjCSubsts,
2842*67e74705SXin Li ObjCSubstitutionContext::Parameter);
2843*67e74705SXin Li Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier(),
2844*67e74705SXin Li ParamType);
2845*67e74705SXin Li Arg += ParamType.getAsString(Policy) + ")";
2846*67e74705SXin Li if (IdentifierInfo *II = (*P)->getIdentifier())
2847*67e74705SXin Li if (DeclaringEntity || AllParametersAreInformative)
2848*67e74705SXin Li Arg += II->getName();
2849*67e74705SXin Li }
2850*67e74705SXin Li
2851*67e74705SXin Li if (Method->isVariadic() && (P + 1) == PEnd)
2852*67e74705SXin Li Arg += ", ...";
2853*67e74705SXin Li
2854*67e74705SXin Li if (DeclaringEntity)
2855*67e74705SXin Li Result.AddTextChunk(Result.getAllocator().CopyString(Arg));
2856*67e74705SXin Li else if (AllParametersAreInformative)
2857*67e74705SXin Li Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg));
2858*67e74705SXin Li else
2859*67e74705SXin Li Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
2860*67e74705SXin Li }
2861*67e74705SXin Li
2862*67e74705SXin Li if (Method->isVariadic()) {
2863*67e74705SXin Li if (Method->param_size() == 0) {
2864*67e74705SXin Li if (DeclaringEntity)
2865*67e74705SXin Li Result.AddTextChunk(", ...");
2866*67e74705SXin Li else if (AllParametersAreInformative)
2867*67e74705SXin Li Result.AddInformativeChunk(", ...");
2868*67e74705SXin Li else
2869*67e74705SXin Li Result.AddPlaceholderChunk(", ...");
2870*67e74705SXin Li }
2871*67e74705SXin Li
2872*67e74705SXin Li MaybeAddSentinel(PP, Method, Result);
2873*67e74705SXin Li }
2874*67e74705SXin Li
2875*67e74705SXin Li return Result.TakeString();
2876*67e74705SXin Li }
2877*67e74705SXin Li
2878*67e74705SXin Li if (Qualifier)
2879*67e74705SXin Li AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
2880*67e74705SXin Li Ctx, Policy);
2881*67e74705SXin Li
2882*67e74705SXin Li Result.AddTypedTextChunk(
2883*67e74705SXin Li Result.getAllocator().CopyString(ND->getNameAsString()));
2884*67e74705SXin Li return Result.TakeString();
2885*67e74705SXin Li }
2886*67e74705SXin Li
2887*67e74705SXin Li /// \brief Add function overload parameter chunks to the given code completion
2888*67e74705SXin Li /// string.
AddOverloadParameterChunks(ASTContext & Context,const PrintingPolicy & Policy,const FunctionDecl * Function,const FunctionProtoType * Prototype,CodeCompletionBuilder & Result,unsigned CurrentArg,unsigned Start=0,bool InOptional=false)2889*67e74705SXin Li static void AddOverloadParameterChunks(ASTContext &Context,
2890*67e74705SXin Li const PrintingPolicy &Policy,
2891*67e74705SXin Li const FunctionDecl *Function,
2892*67e74705SXin Li const FunctionProtoType *Prototype,
2893*67e74705SXin Li CodeCompletionBuilder &Result,
2894*67e74705SXin Li unsigned CurrentArg,
2895*67e74705SXin Li unsigned Start = 0,
2896*67e74705SXin Li bool InOptional = false) {
2897*67e74705SXin Li bool FirstParameter = true;
2898*67e74705SXin Li unsigned NumParams = Function ? Function->getNumParams()
2899*67e74705SXin Li : Prototype->getNumParams();
2900*67e74705SXin Li
2901*67e74705SXin Li for (unsigned P = Start; P != NumParams; ++P) {
2902*67e74705SXin Li if (Function && Function->getParamDecl(P)->hasDefaultArg() && !InOptional) {
2903*67e74705SXin Li // When we see an optional default argument, put that argument and
2904*67e74705SXin Li // the remaining default arguments into a new, optional string.
2905*67e74705SXin Li CodeCompletionBuilder Opt(Result.getAllocator(),
2906*67e74705SXin Li Result.getCodeCompletionTUInfo());
2907*67e74705SXin Li if (!FirstParameter)
2908*67e74705SXin Li Opt.AddChunk(CodeCompletionString::CK_Comma);
2909*67e74705SXin Li // Optional sections are nested.
2910*67e74705SXin Li AddOverloadParameterChunks(Context, Policy, Function, Prototype, Opt,
2911*67e74705SXin Li CurrentArg, P, /*InOptional=*/true);
2912*67e74705SXin Li Result.AddOptionalChunk(Opt.TakeString());
2913*67e74705SXin Li return;
2914*67e74705SXin Li }
2915*67e74705SXin Li
2916*67e74705SXin Li if (FirstParameter)
2917*67e74705SXin Li FirstParameter = false;
2918*67e74705SXin Li else
2919*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_Comma);
2920*67e74705SXin Li
2921*67e74705SXin Li InOptional = false;
2922*67e74705SXin Li
2923*67e74705SXin Li // Format the placeholder string.
2924*67e74705SXin Li std::string Placeholder;
2925*67e74705SXin Li if (Function)
2926*67e74705SXin Li Placeholder = FormatFunctionParameter(Policy, Function->getParamDecl(P));
2927*67e74705SXin Li else
2928*67e74705SXin Li Placeholder = Prototype->getParamType(P).getAsString(Policy);
2929*67e74705SXin Li
2930*67e74705SXin Li if (P == CurrentArg)
2931*67e74705SXin Li Result.AddCurrentParameterChunk(
2932*67e74705SXin Li Result.getAllocator().CopyString(Placeholder));
2933*67e74705SXin Li else
2934*67e74705SXin Li Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Placeholder));
2935*67e74705SXin Li }
2936*67e74705SXin Li
2937*67e74705SXin Li if (Prototype && Prototype->isVariadic()) {
2938*67e74705SXin Li CodeCompletionBuilder Opt(Result.getAllocator(),
2939*67e74705SXin Li Result.getCodeCompletionTUInfo());
2940*67e74705SXin Li if (!FirstParameter)
2941*67e74705SXin Li Opt.AddChunk(CodeCompletionString::CK_Comma);
2942*67e74705SXin Li
2943*67e74705SXin Li if (CurrentArg < NumParams)
2944*67e74705SXin Li Opt.AddPlaceholderChunk("...");
2945*67e74705SXin Li else
2946*67e74705SXin Li Opt.AddCurrentParameterChunk("...");
2947*67e74705SXin Li
2948*67e74705SXin Li Result.AddOptionalChunk(Opt.TakeString());
2949*67e74705SXin Li }
2950*67e74705SXin Li }
2951*67e74705SXin Li
2952*67e74705SXin Li CodeCompletionString *
CreateSignatureString(unsigned CurrentArg,Sema & S,CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,bool IncludeBriefComments) const2953*67e74705SXin Li CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
2954*67e74705SXin Li unsigned CurrentArg, Sema &S,
2955*67e74705SXin Li CodeCompletionAllocator &Allocator,
2956*67e74705SXin Li CodeCompletionTUInfo &CCTUInfo,
2957*67e74705SXin Li bool IncludeBriefComments) const {
2958*67e74705SXin Li PrintingPolicy Policy = getCompletionPrintingPolicy(S);
2959*67e74705SXin Li
2960*67e74705SXin Li // FIXME: Set priority, availability appropriately.
2961*67e74705SXin Li CodeCompletionBuilder Result(Allocator,CCTUInfo, 1, CXAvailability_Available);
2962*67e74705SXin Li FunctionDecl *FDecl = getFunction();
2963*67e74705SXin Li const FunctionProtoType *Proto
2964*67e74705SXin Li = dyn_cast<FunctionProtoType>(getFunctionType());
2965*67e74705SXin Li if (!FDecl && !Proto) {
2966*67e74705SXin Li // Function without a prototype. Just give the return type and a
2967*67e74705SXin Li // highlighted ellipsis.
2968*67e74705SXin Li const FunctionType *FT = getFunctionType();
2969*67e74705SXin Li Result.AddResultTypeChunk(Result.getAllocator().CopyString(
2970*67e74705SXin Li FT->getReturnType().getAsString(Policy)));
2971*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_LeftParen);
2972*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
2973*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_RightParen);
2974*67e74705SXin Li return Result.TakeString();
2975*67e74705SXin Li }
2976*67e74705SXin Li
2977*67e74705SXin Li if (FDecl) {
2978*67e74705SXin Li if (IncludeBriefComments && CurrentArg < FDecl->getNumParams())
2979*67e74705SXin Li if (auto RC = S.getASTContext().getRawCommentForAnyRedecl(
2980*67e74705SXin Li FDecl->getParamDecl(CurrentArg)))
2981*67e74705SXin Li Result.addBriefComment(RC->getBriefText(S.getASTContext()));
2982*67e74705SXin Li AddResultTypeChunk(S.Context, Policy, FDecl, QualType(), Result);
2983*67e74705SXin Li Result.AddTextChunk(
2984*67e74705SXin Li Result.getAllocator().CopyString(FDecl->getNameAsString()));
2985*67e74705SXin Li } else {
2986*67e74705SXin Li Result.AddResultTypeChunk(
2987*67e74705SXin Li Result.getAllocator().CopyString(
2988*67e74705SXin Li Proto->getReturnType().getAsString(Policy)));
2989*67e74705SXin Li }
2990*67e74705SXin Li
2991*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_LeftParen);
2992*67e74705SXin Li AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto, Result,
2993*67e74705SXin Li CurrentArg);
2994*67e74705SXin Li Result.AddChunk(CodeCompletionString::CK_RightParen);
2995*67e74705SXin Li
2996*67e74705SXin Li return Result.TakeString();
2997*67e74705SXin Li }
2998*67e74705SXin Li
getMacroUsagePriority(StringRef MacroName,const LangOptions & LangOpts,bool PreferredTypeIsPointer)2999*67e74705SXin Li unsigned clang::getMacroUsagePriority(StringRef MacroName,
3000*67e74705SXin Li const LangOptions &LangOpts,
3001*67e74705SXin Li bool PreferredTypeIsPointer) {
3002*67e74705SXin Li unsigned Priority = CCP_Macro;
3003*67e74705SXin Li
3004*67e74705SXin Li // Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
3005*67e74705SXin Li if (MacroName.equals("nil") || MacroName.equals("NULL") ||
3006*67e74705SXin Li MacroName.equals("Nil")) {
3007*67e74705SXin Li Priority = CCP_Constant;
3008*67e74705SXin Li if (PreferredTypeIsPointer)
3009*67e74705SXin Li Priority = Priority / CCF_SimilarTypeMatch;
3010*67e74705SXin Li }
3011*67e74705SXin Li // Treat "YES", "NO", "true", and "false" as constants.
3012*67e74705SXin Li else if (MacroName.equals("YES") || MacroName.equals("NO") ||
3013*67e74705SXin Li MacroName.equals("true") || MacroName.equals("false"))
3014*67e74705SXin Li Priority = CCP_Constant;
3015*67e74705SXin Li // Treat "bool" as a type.
3016*67e74705SXin Li else if (MacroName.equals("bool"))
3017*67e74705SXin Li Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0);
3018*67e74705SXin Li
3019*67e74705SXin Li
3020*67e74705SXin Li return Priority;
3021*67e74705SXin Li }
3022*67e74705SXin Li
getCursorKindForDecl(const Decl * D)3023*67e74705SXin Li CXCursorKind clang::getCursorKindForDecl(const Decl *D) {
3024*67e74705SXin Li if (!D)
3025*67e74705SXin Li return CXCursor_UnexposedDecl;
3026*67e74705SXin Li
3027*67e74705SXin Li switch (D->getKind()) {
3028*67e74705SXin Li case Decl::Enum: return CXCursor_EnumDecl;
3029*67e74705SXin Li case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
3030*67e74705SXin Li case Decl::Field: return CXCursor_FieldDecl;
3031*67e74705SXin Li case Decl::Function:
3032*67e74705SXin Li return CXCursor_FunctionDecl;
3033*67e74705SXin Li case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
3034*67e74705SXin Li case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
3035*67e74705SXin Li case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
3036*67e74705SXin Li
3037*67e74705SXin Li case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
3038*67e74705SXin Li case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
3039*67e74705SXin Li case Decl::ObjCMethod:
3040*67e74705SXin Li return cast<ObjCMethodDecl>(D)->isInstanceMethod()
3041*67e74705SXin Li ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
3042*67e74705SXin Li case Decl::CXXMethod: return CXCursor_CXXMethod;
3043*67e74705SXin Li case Decl::CXXConstructor: return CXCursor_Constructor;
3044*67e74705SXin Li case Decl::CXXDestructor: return CXCursor_Destructor;
3045*67e74705SXin Li case Decl::CXXConversion: return CXCursor_ConversionFunction;
3046*67e74705SXin Li case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
3047*67e74705SXin Li case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
3048*67e74705SXin Li case Decl::ParmVar: return CXCursor_ParmDecl;
3049*67e74705SXin Li case Decl::Typedef: return CXCursor_TypedefDecl;
3050*67e74705SXin Li case Decl::TypeAlias: return CXCursor_TypeAliasDecl;
3051*67e74705SXin Li case Decl::TypeAliasTemplate: return CXCursor_TypeAliasTemplateDecl;
3052*67e74705SXin Li case Decl::Var: return CXCursor_VarDecl;
3053*67e74705SXin Li case Decl::Namespace: return CXCursor_Namespace;
3054*67e74705SXin Li case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
3055*67e74705SXin Li case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
3056*67e74705SXin Li case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
3057*67e74705SXin Li case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
3058*67e74705SXin Li case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
3059*67e74705SXin Li case Decl::ClassTemplate: return CXCursor_ClassTemplate;
3060*67e74705SXin Li case Decl::AccessSpec: return CXCursor_CXXAccessSpecifier;
3061*67e74705SXin Li case Decl::ClassTemplatePartialSpecialization:
3062*67e74705SXin Li return CXCursor_ClassTemplatePartialSpecialization;
3063*67e74705SXin Li case Decl::UsingDirective: return CXCursor_UsingDirective;
3064*67e74705SXin Li case Decl::StaticAssert: return CXCursor_StaticAssert;
3065*67e74705SXin Li case Decl::TranslationUnit: return CXCursor_TranslationUnit;
3066*67e74705SXin Li
3067*67e74705SXin Li case Decl::Using:
3068*67e74705SXin Li case Decl::UnresolvedUsingValue:
3069*67e74705SXin Li case Decl::UnresolvedUsingTypename:
3070*67e74705SXin Li return CXCursor_UsingDeclaration;
3071*67e74705SXin Li
3072*67e74705SXin Li case Decl::ObjCPropertyImpl:
3073*67e74705SXin Li switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) {
3074*67e74705SXin Li case ObjCPropertyImplDecl::Dynamic:
3075*67e74705SXin Li return CXCursor_ObjCDynamicDecl;
3076*67e74705SXin Li
3077*67e74705SXin Li case ObjCPropertyImplDecl::Synthesize:
3078*67e74705SXin Li return CXCursor_ObjCSynthesizeDecl;
3079*67e74705SXin Li }
3080*67e74705SXin Li
3081*67e74705SXin Li case Decl::Import:
3082*67e74705SXin Li return CXCursor_ModuleImportDecl;
3083*67e74705SXin Li
3084*67e74705SXin Li case Decl::ObjCTypeParam: return CXCursor_TemplateTypeParameter;
3085*67e74705SXin Li
3086*67e74705SXin Li default:
3087*67e74705SXin Li if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
3088*67e74705SXin Li switch (TD->getTagKind()) {
3089*67e74705SXin Li case TTK_Interface: // fall through
3090*67e74705SXin Li case TTK_Struct: return CXCursor_StructDecl;
3091*67e74705SXin Li case TTK_Class: return CXCursor_ClassDecl;
3092*67e74705SXin Li case TTK_Union: return CXCursor_UnionDecl;
3093*67e74705SXin Li case TTK_Enum: return CXCursor_EnumDecl;
3094*67e74705SXin Li }
3095*67e74705SXin Li }
3096*67e74705SXin Li }
3097*67e74705SXin Li
3098*67e74705SXin Li return CXCursor_UnexposedDecl;
3099*67e74705SXin Li }
3100*67e74705SXin Li
AddMacroResults(Preprocessor & PP,ResultBuilder & Results,bool IncludeUndefined,bool TargetTypeIsPointer=false)3101*67e74705SXin Li static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
3102*67e74705SXin Li bool IncludeUndefined,
3103*67e74705SXin Li bool TargetTypeIsPointer = false) {
3104*67e74705SXin Li typedef CodeCompletionResult Result;
3105*67e74705SXin Li
3106*67e74705SXin Li Results.EnterNewScope();
3107*67e74705SXin Li
3108*67e74705SXin Li for (Preprocessor::macro_iterator M = PP.macro_begin(),
3109*67e74705SXin Li MEnd = PP.macro_end();
3110*67e74705SXin Li M != MEnd; ++M) {
3111*67e74705SXin Li auto MD = PP.getMacroDefinition(M->first);
3112*67e74705SXin Li if (IncludeUndefined || MD) {
3113*67e74705SXin Li if (MacroInfo *MI = MD.getMacroInfo())
3114*67e74705SXin Li if (MI->isUsedForHeaderGuard())
3115*67e74705SXin Li continue;
3116*67e74705SXin Li
3117*67e74705SXin Li Results.AddResult(Result(M->first,
3118*67e74705SXin Li getMacroUsagePriority(M->first->getName(),
3119*67e74705SXin Li PP.getLangOpts(),
3120*67e74705SXin Li TargetTypeIsPointer)));
3121*67e74705SXin Li }
3122*67e74705SXin Li }
3123*67e74705SXin Li
3124*67e74705SXin Li Results.ExitScope();
3125*67e74705SXin Li
3126*67e74705SXin Li }
3127*67e74705SXin Li
AddPrettyFunctionResults(const LangOptions & LangOpts,ResultBuilder & Results)3128*67e74705SXin Li static void AddPrettyFunctionResults(const LangOptions &LangOpts,
3129*67e74705SXin Li ResultBuilder &Results) {
3130*67e74705SXin Li typedef CodeCompletionResult Result;
3131*67e74705SXin Li
3132*67e74705SXin Li Results.EnterNewScope();
3133*67e74705SXin Li
3134*67e74705SXin Li Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
3135*67e74705SXin Li Results.AddResult(Result("__FUNCTION__", CCP_Constant));
3136*67e74705SXin Li if (LangOpts.C99 || LangOpts.CPlusPlus11)
3137*67e74705SXin Li Results.AddResult(Result("__func__", CCP_Constant));
3138*67e74705SXin Li Results.ExitScope();
3139*67e74705SXin Li }
3140*67e74705SXin Li
HandleCodeCompleteResults(Sema * S,CodeCompleteConsumer * CodeCompleter,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)3141*67e74705SXin Li static void HandleCodeCompleteResults(Sema *S,
3142*67e74705SXin Li CodeCompleteConsumer *CodeCompleter,
3143*67e74705SXin Li CodeCompletionContext Context,
3144*67e74705SXin Li CodeCompletionResult *Results,
3145*67e74705SXin Li unsigned NumResults) {
3146*67e74705SXin Li if (CodeCompleter)
3147*67e74705SXin Li CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
3148*67e74705SXin Li }
3149*67e74705SXin Li
mapCodeCompletionContext(Sema & S,Sema::ParserCompletionContext PCC)3150*67e74705SXin Li static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
3151*67e74705SXin Li Sema::ParserCompletionContext PCC) {
3152*67e74705SXin Li switch (PCC) {
3153*67e74705SXin Li case Sema::PCC_Namespace:
3154*67e74705SXin Li return CodeCompletionContext::CCC_TopLevel;
3155*67e74705SXin Li
3156*67e74705SXin Li case Sema::PCC_Class:
3157*67e74705SXin Li return CodeCompletionContext::CCC_ClassStructUnion;
3158*67e74705SXin Li
3159*67e74705SXin Li case Sema::PCC_ObjCInterface:
3160*67e74705SXin Li return CodeCompletionContext::CCC_ObjCInterface;
3161*67e74705SXin Li
3162*67e74705SXin Li case Sema::PCC_ObjCImplementation:
3163*67e74705SXin Li return CodeCompletionContext::CCC_ObjCImplementation;
3164*67e74705SXin Li
3165*67e74705SXin Li case Sema::PCC_ObjCInstanceVariableList:
3166*67e74705SXin Li return CodeCompletionContext::CCC_ObjCIvarList;
3167*67e74705SXin Li
3168*67e74705SXin Li case Sema::PCC_Template:
3169*67e74705SXin Li case Sema::PCC_MemberTemplate:
3170*67e74705SXin Li if (S.CurContext->isFileContext())
3171*67e74705SXin Li return CodeCompletionContext::CCC_TopLevel;
3172*67e74705SXin Li if (S.CurContext->isRecord())
3173*67e74705SXin Li return CodeCompletionContext::CCC_ClassStructUnion;
3174*67e74705SXin Li return CodeCompletionContext::CCC_Other;
3175*67e74705SXin Li
3176*67e74705SXin Li case Sema::PCC_RecoveryInFunction:
3177*67e74705SXin Li return CodeCompletionContext::CCC_Recovery;
3178*67e74705SXin Li
3179*67e74705SXin Li case Sema::PCC_ForInit:
3180*67e74705SXin Li if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 ||
3181*67e74705SXin Li S.getLangOpts().ObjC1)
3182*67e74705SXin Li return CodeCompletionContext::CCC_ParenthesizedExpression;
3183*67e74705SXin Li else
3184*67e74705SXin Li return CodeCompletionContext::CCC_Expression;
3185*67e74705SXin Li
3186*67e74705SXin Li case Sema::PCC_Expression:
3187*67e74705SXin Li case Sema::PCC_Condition:
3188*67e74705SXin Li return CodeCompletionContext::CCC_Expression;
3189*67e74705SXin Li
3190*67e74705SXin Li case Sema::PCC_Statement:
3191*67e74705SXin Li return CodeCompletionContext::CCC_Statement;
3192*67e74705SXin Li
3193*67e74705SXin Li case Sema::PCC_Type:
3194*67e74705SXin Li return CodeCompletionContext::CCC_Type;
3195*67e74705SXin Li
3196*67e74705SXin Li case Sema::PCC_ParenthesizedExpression:
3197*67e74705SXin Li return CodeCompletionContext::CCC_ParenthesizedExpression;
3198*67e74705SXin Li
3199*67e74705SXin Li case Sema::PCC_LocalDeclarationSpecifiers:
3200*67e74705SXin Li return CodeCompletionContext::CCC_Type;
3201*67e74705SXin Li }
3202*67e74705SXin Li
3203*67e74705SXin Li llvm_unreachable("Invalid ParserCompletionContext!");
3204*67e74705SXin Li }
3205*67e74705SXin Li
3206*67e74705SXin Li /// \brief If we're in a C++ virtual member function, add completion results
3207*67e74705SXin Li /// that invoke the functions we override, since it's common to invoke the
3208*67e74705SXin Li /// overridden function as well as adding new functionality.
3209*67e74705SXin Li ///
3210*67e74705SXin Li /// \param S The semantic analysis object for which we are generating results.
3211*67e74705SXin Li ///
3212*67e74705SXin Li /// \param InContext This context in which the nested-name-specifier preceding
3213*67e74705SXin Li /// the code-completion point
MaybeAddOverrideCalls(Sema & S,DeclContext * InContext,ResultBuilder & Results)3214*67e74705SXin Li static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
3215*67e74705SXin Li ResultBuilder &Results) {
3216*67e74705SXin Li // Look through blocks.
3217*67e74705SXin Li DeclContext *CurContext = S.CurContext;
3218*67e74705SXin Li while (isa<BlockDecl>(CurContext))
3219*67e74705SXin Li CurContext = CurContext->getParent();
3220*67e74705SXin Li
3221*67e74705SXin Li
3222*67e74705SXin Li CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
3223*67e74705SXin Li if (!Method || !Method->isVirtual())
3224*67e74705SXin Li return;
3225*67e74705SXin Li
3226*67e74705SXin Li // We need to have names for all of the parameters, if we're going to
3227*67e74705SXin Li // generate a forwarding call.
3228*67e74705SXin Li for (auto P : Method->parameters())
3229*67e74705SXin Li if (!P->getDeclName())
3230*67e74705SXin Li return;
3231*67e74705SXin Li
3232*67e74705SXin Li PrintingPolicy Policy = getCompletionPrintingPolicy(S);
3233*67e74705SXin Li for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
3234*67e74705SXin Li MEnd = Method->end_overridden_methods();
3235*67e74705SXin Li M != MEnd; ++M) {
3236*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
3237*67e74705SXin Li Results.getCodeCompletionTUInfo());
3238*67e74705SXin Li const CXXMethodDecl *Overridden = *M;
3239*67e74705SXin Li if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
3240*67e74705SXin Li continue;
3241*67e74705SXin Li
3242*67e74705SXin Li // If we need a nested-name-specifier, add one now.
3243*67e74705SXin Li if (!InContext) {
3244*67e74705SXin Li NestedNameSpecifier *NNS
3245*67e74705SXin Li = getRequiredQualification(S.Context, CurContext,
3246*67e74705SXin Li Overridden->getDeclContext());
3247*67e74705SXin Li if (NNS) {
3248*67e74705SXin Li std::string Str;
3249*67e74705SXin Li llvm::raw_string_ostream OS(Str);
3250*67e74705SXin Li NNS->print(OS, Policy);
3251*67e74705SXin Li Builder.AddTextChunk(Results.getAllocator().CopyString(OS.str()));
3252*67e74705SXin Li }
3253*67e74705SXin Li } else if (!InContext->Equals(Overridden->getDeclContext()))
3254*67e74705SXin Li continue;
3255*67e74705SXin Li
3256*67e74705SXin Li Builder.AddTypedTextChunk(Results.getAllocator().CopyString(
3257*67e74705SXin Li Overridden->getNameAsString()));
3258*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
3259*67e74705SXin Li bool FirstParam = true;
3260*67e74705SXin Li for (auto P : Method->parameters()) {
3261*67e74705SXin Li if (FirstParam)
3262*67e74705SXin Li FirstParam = false;
3263*67e74705SXin Li else
3264*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Comma);
3265*67e74705SXin Li
3266*67e74705SXin Li Builder.AddPlaceholderChunk(
3267*67e74705SXin Li Results.getAllocator().CopyString(P->getIdentifier()->getName()));
3268*67e74705SXin Li }
3269*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
3270*67e74705SXin Li Results.AddResult(CodeCompletionResult(Builder.TakeString(),
3271*67e74705SXin Li CCP_SuperCompletion,
3272*67e74705SXin Li CXCursor_CXXMethod,
3273*67e74705SXin Li CXAvailability_Available,
3274*67e74705SXin Li Overridden));
3275*67e74705SXin Li Results.Ignore(Overridden);
3276*67e74705SXin Li }
3277*67e74705SXin Li }
3278*67e74705SXin Li
CodeCompleteModuleImport(SourceLocation ImportLoc,ModuleIdPath Path)3279*67e74705SXin Li void Sema::CodeCompleteModuleImport(SourceLocation ImportLoc,
3280*67e74705SXin Li ModuleIdPath Path) {
3281*67e74705SXin Li typedef CodeCompletionResult Result;
3282*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3283*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
3284*67e74705SXin Li CodeCompletionContext::CCC_Other);
3285*67e74705SXin Li Results.EnterNewScope();
3286*67e74705SXin Li
3287*67e74705SXin Li CodeCompletionAllocator &Allocator = Results.getAllocator();
3288*67e74705SXin Li CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
3289*67e74705SXin Li typedef CodeCompletionResult Result;
3290*67e74705SXin Li if (Path.empty()) {
3291*67e74705SXin Li // Enumerate all top-level modules.
3292*67e74705SXin Li SmallVector<Module *, 8> Modules;
3293*67e74705SXin Li PP.getHeaderSearchInfo().collectAllModules(Modules);
3294*67e74705SXin Li for (unsigned I = 0, N = Modules.size(); I != N; ++I) {
3295*67e74705SXin Li Builder.AddTypedTextChunk(
3296*67e74705SXin Li Builder.getAllocator().CopyString(Modules[I]->Name));
3297*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(),
3298*67e74705SXin Li CCP_Declaration,
3299*67e74705SXin Li CXCursor_ModuleImportDecl,
3300*67e74705SXin Li Modules[I]->isAvailable()
3301*67e74705SXin Li ? CXAvailability_Available
3302*67e74705SXin Li : CXAvailability_NotAvailable));
3303*67e74705SXin Li }
3304*67e74705SXin Li } else if (getLangOpts().Modules) {
3305*67e74705SXin Li // Load the named module.
3306*67e74705SXin Li Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path,
3307*67e74705SXin Li Module::AllVisible,
3308*67e74705SXin Li /*IsInclusionDirective=*/false);
3309*67e74705SXin Li // Enumerate submodules.
3310*67e74705SXin Li if (Mod) {
3311*67e74705SXin Li for (Module::submodule_iterator Sub = Mod->submodule_begin(),
3312*67e74705SXin Li SubEnd = Mod->submodule_end();
3313*67e74705SXin Li Sub != SubEnd; ++Sub) {
3314*67e74705SXin Li
3315*67e74705SXin Li Builder.AddTypedTextChunk(
3316*67e74705SXin Li Builder.getAllocator().CopyString((*Sub)->Name));
3317*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(),
3318*67e74705SXin Li CCP_Declaration,
3319*67e74705SXin Li CXCursor_ModuleImportDecl,
3320*67e74705SXin Li (*Sub)->isAvailable()
3321*67e74705SXin Li ? CXAvailability_Available
3322*67e74705SXin Li : CXAvailability_NotAvailable));
3323*67e74705SXin Li }
3324*67e74705SXin Li }
3325*67e74705SXin Li }
3326*67e74705SXin Li Results.ExitScope();
3327*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3328*67e74705SXin Li Results.data(),Results.size());
3329*67e74705SXin Li }
3330*67e74705SXin Li
CodeCompleteOrdinaryName(Scope * S,ParserCompletionContext CompletionContext)3331*67e74705SXin Li void Sema::CodeCompleteOrdinaryName(Scope *S,
3332*67e74705SXin Li ParserCompletionContext CompletionContext) {
3333*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3334*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
3335*67e74705SXin Li mapCodeCompletionContext(*this, CompletionContext));
3336*67e74705SXin Li Results.EnterNewScope();
3337*67e74705SXin Li
3338*67e74705SXin Li // Determine how to filter results, e.g., so that the names of
3339*67e74705SXin Li // values (functions, enumerators, function templates, etc.) are
3340*67e74705SXin Li // only allowed where we can have an expression.
3341*67e74705SXin Li switch (CompletionContext) {
3342*67e74705SXin Li case PCC_Namespace:
3343*67e74705SXin Li case PCC_Class:
3344*67e74705SXin Li case PCC_ObjCInterface:
3345*67e74705SXin Li case PCC_ObjCImplementation:
3346*67e74705SXin Li case PCC_ObjCInstanceVariableList:
3347*67e74705SXin Li case PCC_Template:
3348*67e74705SXin Li case PCC_MemberTemplate:
3349*67e74705SXin Li case PCC_Type:
3350*67e74705SXin Li case PCC_LocalDeclarationSpecifiers:
3351*67e74705SXin Li Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
3352*67e74705SXin Li break;
3353*67e74705SXin Li
3354*67e74705SXin Li case PCC_Statement:
3355*67e74705SXin Li case PCC_ParenthesizedExpression:
3356*67e74705SXin Li case PCC_Expression:
3357*67e74705SXin Li case PCC_ForInit:
3358*67e74705SXin Li case PCC_Condition:
3359*67e74705SXin Li if (WantTypesInContext(CompletionContext, getLangOpts()))
3360*67e74705SXin Li Results.setFilter(&ResultBuilder::IsOrdinaryName);
3361*67e74705SXin Li else
3362*67e74705SXin Li Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
3363*67e74705SXin Li
3364*67e74705SXin Li if (getLangOpts().CPlusPlus)
3365*67e74705SXin Li MaybeAddOverrideCalls(*this, /*InContext=*/nullptr, Results);
3366*67e74705SXin Li break;
3367*67e74705SXin Li
3368*67e74705SXin Li case PCC_RecoveryInFunction:
3369*67e74705SXin Li // Unfiltered
3370*67e74705SXin Li break;
3371*67e74705SXin Li }
3372*67e74705SXin Li
3373*67e74705SXin Li // If we are in a C++ non-static member function, check the qualifiers on
3374*67e74705SXin Li // the member function to filter/prioritize the results list.
3375*67e74705SXin Li if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
3376*67e74705SXin Li if (CurMethod->isInstance())
3377*67e74705SXin Li Results.setObjectTypeQualifiers(
3378*67e74705SXin Li Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
3379*67e74705SXin Li
3380*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
3381*67e74705SXin Li LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3382*67e74705SXin Li CodeCompleter->includeGlobals());
3383*67e74705SXin Li
3384*67e74705SXin Li AddOrdinaryNameResults(CompletionContext, S, *this, Results);
3385*67e74705SXin Li Results.ExitScope();
3386*67e74705SXin Li
3387*67e74705SXin Li switch (CompletionContext) {
3388*67e74705SXin Li case PCC_ParenthesizedExpression:
3389*67e74705SXin Li case PCC_Expression:
3390*67e74705SXin Li case PCC_Statement:
3391*67e74705SXin Li case PCC_RecoveryInFunction:
3392*67e74705SXin Li if (S->getFnParent())
3393*67e74705SXin Li AddPrettyFunctionResults(getLangOpts(), Results);
3394*67e74705SXin Li break;
3395*67e74705SXin Li
3396*67e74705SXin Li case PCC_Namespace:
3397*67e74705SXin Li case PCC_Class:
3398*67e74705SXin Li case PCC_ObjCInterface:
3399*67e74705SXin Li case PCC_ObjCImplementation:
3400*67e74705SXin Li case PCC_ObjCInstanceVariableList:
3401*67e74705SXin Li case PCC_Template:
3402*67e74705SXin Li case PCC_MemberTemplate:
3403*67e74705SXin Li case PCC_ForInit:
3404*67e74705SXin Li case PCC_Condition:
3405*67e74705SXin Li case PCC_Type:
3406*67e74705SXin Li case PCC_LocalDeclarationSpecifiers:
3407*67e74705SXin Li break;
3408*67e74705SXin Li }
3409*67e74705SXin Li
3410*67e74705SXin Li if (CodeCompleter->includeMacros())
3411*67e74705SXin Li AddMacroResults(PP, Results, false);
3412*67e74705SXin Li
3413*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3414*67e74705SXin Li Results.data(),Results.size());
3415*67e74705SXin Li }
3416*67e74705SXin Li
3417*67e74705SXin Li static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
3418*67e74705SXin Li ParsedType Receiver,
3419*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents,
3420*67e74705SXin Li bool AtArgumentExpression,
3421*67e74705SXin Li bool IsSuper,
3422*67e74705SXin Li ResultBuilder &Results);
3423*67e74705SXin Li
CodeCompleteDeclSpec(Scope * S,DeclSpec & DS,bool AllowNonIdentifiers,bool AllowNestedNameSpecifiers)3424*67e74705SXin Li void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
3425*67e74705SXin Li bool AllowNonIdentifiers,
3426*67e74705SXin Li bool AllowNestedNameSpecifiers) {
3427*67e74705SXin Li typedef CodeCompletionResult Result;
3428*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3429*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
3430*67e74705SXin Li AllowNestedNameSpecifiers
3431*67e74705SXin Li ? CodeCompletionContext::CCC_PotentiallyQualifiedName
3432*67e74705SXin Li : CodeCompletionContext::CCC_Name);
3433*67e74705SXin Li Results.EnterNewScope();
3434*67e74705SXin Li
3435*67e74705SXin Li // Type qualifiers can come after names.
3436*67e74705SXin Li Results.AddResult(Result("const"));
3437*67e74705SXin Li Results.AddResult(Result("volatile"));
3438*67e74705SXin Li if (getLangOpts().C99)
3439*67e74705SXin Li Results.AddResult(Result("restrict"));
3440*67e74705SXin Li
3441*67e74705SXin Li if (getLangOpts().CPlusPlus) {
3442*67e74705SXin Li if (AllowNonIdentifiers) {
3443*67e74705SXin Li Results.AddResult(Result("operator"));
3444*67e74705SXin Li }
3445*67e74705SXin Li
3446*67e74705SXin Li // Add nested-name-specifiers.
3447*67e74705SXin Li if (AllowNestedNameSpecifiers) {
3448*67e74705SXin Li Results.allowNestedNameSpecifiers();
3449*67e74705SXin Li Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
3450*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
3451*67e74705SXin Li LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
3452*67e74705SXin Li CodeCompleter->includeGlobals());
3453*67e74705SXin Li Results.setFilter(nullptr);
3454*67e74705SXin Li }
3455*67e74705SXin Li }
3456*67e74705SXin Li Results.ExitScope();
3457*67e74705SXin Li
3458*67e74705SXin Li // If we're in a context where we might have an expression (rather than a
3459*67e74705SXin Li // declaration), and what we've seen so far is an Objective-C type that could
3460*67e74705SXin Li // be a receiver of a class message, this may be a class message send with
3461*67e74705SXin Li // the initial opening bracket '[' missing. Add appropriate completions.
3462*67e74705SXin Li if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
3463*67e74705SXin Li DS.getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier &&
3464*67e74705SXin Li DS.getTypeSpecType() == DeclSpec::TST_typename &&
3465*67e74705SXin Li DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
3466*67e74705SXin Li DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
3467*67e74705SXin Li !DS.isTypeAltiVecVector() &&
3468*67e74705SXin Li S &&
3469*67e74705SXin Li (S->getFlags() & Scope::DeclScope) != 0 &&
3470*67e74705SXin Li (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
3471*67e74705SXin Li Scope::FunctionPrototypeScope |
3472*67e74705SXin Li Scope::AtCatchScope)) == 0) {
3473*67e74705SXin Li ParsedType T = DS.getRepAsType();
3474*67e74705SXin Li if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
3475*67e74705SXin Li AddClassMessageCompletions(*this, S, T, None, false, false, Results);
3476*67e74705SXin Li }
3477*67e74705SXin Li
3478*67e74705SXin Li // Note that we intentionally suppress macro results here, since we do not
3479*67e74705SXin Li // encourage using macros to produce the names of entities.
3480*67e74705SXin Li
3481*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
3482*67e74705SXin Li Results.getCompletionContext(),
3483*67e74705SXin Li Results.data(), Results.size());
3484*67e74705SXin Li }
3485*67e74705SXin Li
3486*67e74705SXin Li struct Sema::CodeCompleteExpressionData {
CodeCompleteExpressionDataSema::CodeCompleteExpressionData3487*67e74705SXin Li CodeCompleteExpressionData(QualType PreferredType = QualType())
3488*67e74705SXin Li : PreferredType(PreferredType), IntegralConstantExpression(false),
3489*67e74705SXin Li ObjCCollection(false) { }
3490*67e74705SXin Li
3491*67e74705SXin Li QualType PreferredType;
3492*67e74705SXin Li bool IntegralConstantExpression;
3493*67e74705SXin Li bool ObjCCollection;
3494*67e74705SXin Li SmallVector<Decl *, 4> IgnoreDecls;
3495*67e74705SXin Li };
3496*67e74705SXin Li
3497*67e74705SXin Li /// \brief Perform code-completion in an expression context when we know what
3498*67e74705SXin Li /// type we're looking for.
CodeCompleteExpression(Scope * S,const CodeCompleteExpressionData & Data)3499*67e74705SXin Li void Sema::CodeCompleteExpression(Scope *S,
3500*67e74705SXin Li const CodeCompleteExpressionData &Data) {
3501*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3502*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
3503*67e74705SXin Li CodeCompletionContext::CCC_Expression);
3504*67e74705SXin Li if (Data.ObjCCollection)
3505*67e74705SXin Li Results.setFilter(&ResultBuilder::IsObjCCollection);
3506*67e74705SXin Li else if (Data.IntegralConstantExpression)
3507*67e74705SXin Li Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
3508*67e74705SXin Li else if (WantTypesInContext(PCC_Expression, getLangOpts()))
3509*67e74705SXin Li Results.setFilter(&ResultBuilder::IsOrdinaryName);
3510*67e74705SXin Li else
3511*67e74705SXin Li Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
3512*67e74705SXin Li
3513*67e74705SXin Li if (!Data.PreferredType.isNull())
3514*67e74705SXin Li Results.setPreferredType(Data.PreferredType.getNonReferenceType());
3515*67e74705SXin Li
3516*67e74705SXin Li // Ignore any declarations that we were told that we don't care about.
3517*67e74705SXin Li for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
3518*67e74705SXin Li Results.Ignore(Data.IgnoreDecls[I]);
3519*67e74705SXin Li
3520*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
3521*67e74705SXin Li LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
3522*67e74705SXin Li CodeCompleter->includeGlobals());
3523*67e74705SXin Li
3524*67e74705SXin Li Results.EnterNewScope();
3525*67e74705SXin Li AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
3526*67e74705SXin Li Results.ExitScope();
3527*67e74705SXin Li
3528*67e74705SXin Li bool PreferredTypeIsPointer = false;
3529*67e74705SXin Li if (!Data.PreferredType.isNull())
3530*67e74705SXin Li PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
3531*67e74705SXin Li || Data.PreferredType->isMemberPointerType()
3532*67e74705SXin Li || Data.PreferredType->isBlockPointerType();
3533*67e74705SXin Li
3534*67e74705SXin Li if (S->getFnParent() &&
3535*67e74705SXin Li !Data.ObjCCollection &&
3536*67e74705SXin Li !Data.IntegralConstantExpression)
3537*67e74705SXin Li AddPrettyFunctionResults(getLangOpts(), Results);
3538*67e74705SXin Li
3539*67e74705SXin Li if (CodeCompleter->includeMacros())
3540*67e74705SXin Li AddMacroResults(PP, Results, false, PreferredTypeIsPointer);
3541*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
3542*67e74705SXin Li CodeCompletionContext(CodeCompletionContext::CCC_Expression,
3543*67e74705SXin Li Data.PreferredType),
3544*67e74705SXin Li Results.data(),Results.size());
3545*67e74705SXin Li }
3546*67e74705SXin Li
CodeCompletePostfixExpression(Scope * S,ExprResult E)3547*67e74705SXin Li void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
3548*67e74705SXin Li if (E.isInvalid())
3549*67e74705SXin Li CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
3550*67e74705SXin Li else if (getLangOpts().ObjC1)
3551*67e74705SXin Li CodeCompleteObjCInstanceMessage(S, E.get(), None, false);
3552*67e74705SXin Li }
3553*67e74705SXin Li
3554*67e74705SXin Li /// \brief The set of properties that have already been added, referenced by
3555*67e74705SXin Li /// property name.
3556*67e74705SXin Li typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
3557*67e74705SXin Li
3558*67e74705SXin Li /// \brief Retrieve the container definition, if any?
getContainerDef(ObjCContainerDecl * Container)3559*67e74705SXin Li static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) {
3560*67e74705SXin Li if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
3561*67e74705SXin Li if (Interface->hasDefinition())
3562*67e74705SXin Li return Interface->getDefinition();
3563*67e74705SXin Li
3564*67e74705SXin Li return Interface;
3565*67e74705SXin Li }
3566*67e74705SXin Li
3567*67e74705SXin Li if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3568*67e74705SXin Li if (Protocol->hasDefinition())
3569*67e74705SXin Li return Protocol->getDefinition();
3570*67e74705SXin Li
3571*67e74705SXin Li return Protocol;
3572*67e74705SXin Li }
3573*67e74705SXin Li return Container;
3574*67e74705SXin Li }
3575*67e74705SXin Li
AddObjCProperties(const CodeCompletionContext & CCContext,ObjCContainerDecl * Container,bool AllowCategories,bool AllowNullaryMethods,DeclContext * CurContext,AddedPropertiesSet & AddedProperties,ResultBuilder & Results)3576*67e74705SXin Li static void AddObjCProperties(const CodeCompletionContext &CCContext,
3577*67e74705SXin Li ObjCContainerDecl *Container,
3578*67e74705SXin Li bool AllowCategories,
3579*67e74705SXin Li bool AllowNullaryMethods,
3580*67e74705SXin Li DeclContext *CurContext,
3581*67e74705SXin Li AddedPropertiesSet &AddedProperties,
3582*67e74705SXin Li ResultBuilder &Results) {
3583*67e74705SXin Li typedef CodeCompletionResult Result;
3584*67e74705SXin Li
3585*67e74705SXin Li // Retrieve the definition.
3586*67e74705SXin Li Container = getContainerDef(Container);
3587*67e74705SXin Li
3588*67e74705SXin Li // Add properties in this container.
3589*67e74705SXin Li for (const auto *P : Container->instance_properties())
3590*67e74705SXin Li if (AddedProperties.insert(P->getIdentifier()).second)
3591*67e74705SXin Li Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr),
3592*67e74705SXin Li CurContext);
3593*67e74705SXin Li
3594*67e74705SXin Li // Add nullary methods
3595*67e74705SXin Li if (AllowNullaryMethods) {
3596*67e74705SXin Li ASTContext &Context = Container->getASTContext();
3597*67e74705SXin Li PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
3598*67e74705SXin Li for (auto *M : Container->methods()) {
3599*67e74705SXin Li if (M->getSelector().isUnarySelector())
3600*67e74705SXin Li if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0))
3601*67e74705SXin Li if (AddedProperties.insert(Name).second) {
3602*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
3603*67e74705SXin Li Results.getCodeCompletionTUInfo());
3604*67e74705SXin Li AddResultTypeChunk(Context, Policy, M, CCContext.getBaseType(),
3605*67e74705SXin Li Builder);
3606*67e74705SXin Li Builder.AddTypedTextChunk(
3607*67e74705SXin Li Results.getAllocator().CopyString(Name->getName()));
3608*67e74705SXin Li
3609*67e74705SXin Li Results.MaybeAddResult(Result(Builder.TakeString(), M,
3610*67e74705SXin Li CCP_MemberDeclaration + CCD_MethodAsProperty),
3611*67e74705SXin Li CurContext);
3612*67e74705SXin Li }
3613*67e74705SXin Li }
3614*67e74705SXin Li }
3615*67e74705SXin Li
3616*67e74705SXin Li
3617*67e74705SXin Li // Add properties in referenced protocols.
3618*67e74705SXin Li if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3619*67e74705SXin Li for (auto *P : Protocol->protocols())
3620*67e74705SXin Li AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods,
3621*67e74705SXin Li CurContext, AddedProperties, Results);
3622*67e74705SXin Li } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
3623*67e74705SXin Li if (AllowCategories) {
3624*67e74705SXin Li // Look through categories.
3625*67e74705SXin Li for (auto *Cat : IFace->known_categories())
3626*67e74705SXin Li AddObjCProperties(CCContext, Cat, AllowCategories, AllowNullaryMethods,
3627*67e74705SXin Li CurContext, AddedProperties, Results);
3628*67e74705SXin Li }
3629*67e74705SXin Li
3630*67e74705SXin Li // Look through protocols.
3631*67e74705SXin Li for (auto *I : IFace->all_referenced_protocols())
3632*67e74705SXin Li AddObjCProperties(CCContext, I, AllowCategories, AllowNullaryMethods,
3633*67e74705SXin Li CurContext, AddedProperties, Results);
3634*67e74705SXin Li
3635*67e74705SXin Li // Look in the superclass.
3636*67e74705SXin Li if (IFace->getSuperClass())
3637*67e74705SXin Li AddObjCProperties(CCContext, IFace->getSuperClass(), AllowCategories,
3638*67e74705SXin Li AllowNullaryMethods, CurContext,
3639*67e74705SXin Li AddedProperties, Results);
3640*67e74705SXin Li } else if (const ObjCCategoryDecl *Category
3641*67e74705SXin Li = dyn_cast<ObjCCategoryDecl>(Container)) {
3642*67e74705SXin Li // Look through protocols.
3643*67e74705SXin Li for (auto *P : Category->protocols())
3644*67e74705SXin Li AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods,
3645*67e74705SXin Li CurContext, AddedProperties, Results);
3646*67e74705SXin Li }
3647*67e74705SXin Li }
3648*67e74705SXin Li
CodeCompleteMemberReferenceExpr(Scope * S,Expr * Base,SourceLocation OpLoc,bool IsArrow)3649*67e74705SXin Li void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
3650*67e74705SXin Li SourceLocation OpLoc,
3651*67e74705SXin Li bool IsArrow) {
3652*67e74705SXin Li if (!Base || !CodeCompleter)
3653*67e74705SXin Li return;
3654*67e74705SXin Li
3655*67e74705SXin Li ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
3656*67e74705SXin Li if (ConvertedBase.isInvalid())
3657*67e74705SXin Li return;
3658*67e74705SXin Li Base = ConvertedBase.get();
3659*67e74705SXin Li
3660*67e74705SXin Li typedef CodeCompletionResult Result;
3661*67e74705SXin Li
3662*67e74705SXin Li QualType BaseType = Base->getType();
3663*67e74705SXin Li
3664*67e74705SXin Li if (IsArrow) {
3665*67e74705SXin Li if (const PointerType *Ptr = BaseType->getAs<PointerType>())
3666*67e74705SXin Li BaseType = Ptr->getPointeeType();
3667*67e74705SXin Li else if (BaseType->isObjCObjectPointerType())
3668*67e74705SXin Li /*Do nothing*/ ;
3669*67e74705SXin Li else
3670*67e74705SXin Li return;
3671*67e74705SXin Li }
3672*67e74705SXin Li
3673*67e74705SXin Li enum CodeCompletionContext::Kind contextKind;
3674*67e74705SXin Li
3675*67e74705SXin Li if (IsArrow) {
3676*67e74705SXin Li contextKind = CodeCompletionContext::CCC_ArrowMemberAccess;
3677*67e74705SXin Li }
3678*67e74705SXin Li else {
3679*67e74705SXin Li if (BaseType->isObjCObjectPointerType() ||
3680*67e74705SXin Li BaseType->isObjCObjectOrInterfaceType()) {
3681*67e74705SXin Li contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess;
3682*67e74705SXin Li }
3683*67e74705SXin Li else {
3684*67e74705SXin Li contextKind = CodeCompletionContext::CCC_DotMemberAccess;
3685*67e74705SXin Li }
3686*67e74705SXin Li }
3687*67e74705SXin Li
3688*67e74705SXin Li CodeCompletionContext CCContext(contextKind, BaseType);
3689*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3690*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
3691*67e74705SXin Li CCContext,
3692*67e74705SXin Li &ResultBuilder::IsMember);
3693*67e74705SXin Li Results.EnterNewScope();
3694*67e74705SXin Li if (const RecordType *Record = BaseType->getAs<RecordType>()) {
3695*67e74705SXin Li // Indicate that we are performing a member access, and the cv-qualifiers
3696*67e74705SXin Li // for the base object type.
3697*67e74705SXin Li Results.setObjectTypeQualifiers(BaseType.getQualifiers());
3698*67e74705SXin Li
3699*67e74705SXin Li // Access to a C/C++ class, struct, or union.
3700*67e74705SXin Li Results.allowNestedNameSpecifiers();
3701*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
3702*67e74705SXin Li LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
3703*67e74705SXin Li CodeCompleter->includeGlobals());
3704*67e74705SXin Li
3705*67e74705SXin Li if (getLangOpts().CPlusPlus) {
3706*67e74705SXin Li if (!Results.empty()) {
3707*67e74705SXin Li // The "template" keyword can follow "->" or "." in the grammar.
3708*67e74705SXin Li // However, we only want to suggest the template keyword if something
3709*67e74705SXin Li // is dependent.
3710*67e74705SXin Li bool IsDependent = BaseType->isDependentType();
3711*67e74705SXin Li if (!IsDependent) {
3712*67e74705SXin Li for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
3713*67e74705SXin Li if (DeclContext *Ctx = DepScope->getEntity()) {
3714*67e74705SXin Li IsDependent = Ctx->isDependentContext();
3715*67e74705SXin Li break;
3716*67e74705SXin Li }
3717*67e74705SXin Li }
3718*67e74705SXin Li
3719*67e74705SXin Li if (IsDependent)
3720*67e74705SXin Li Results.AddResult(Result("template"));
3721*67e74705SXin Li }
3722*67e74705SXin Li }
3723*67e74705SXin Li } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
3724*67e74705SXin Li // Objective-C property reference.
3725*67e74705SXin Li AddedPropertiesSet AddedProperties;
3726*67e74705SXin Li
3727*67e74705SXin Li // Add property results based on our interface.
3728*67e74705SXin Li const ObjCObjectPointerType *ObjCPtr
3729*67e74705SXin Li = BaseType->getAsObjCInterfacePointerType();
3730*67e74705SXin Li assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
3731*67e74705SXin Li AddObjCProperties(CCContext, ObjCPtr->getInterfaceDecl(), true,
3732*67e74705SXin Li /*AllowNullaryMethods=*/true, CurContext,
3733*67e74705SXin Li AddedProperties, Results);
3734*67e74705SXin Li
3735*67e74705SXin Li // Add properties from the protocols in a qualified interface.
3736*67e74705SXin Li for (auto *I : ObjCPtr->quals())
3737*67e74705SXin Li AddObjCProperties(CCContext, I, true, /*AllowNullaryMethods=*/true,
3738*67e74705SXin Li CurContext, AddedProperties, Results);
3739*67e74705SXin Li } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
3740*67e74705SXin Li (!IsArrow && BaseType->isObjCObjectType())) {
3741*67e74705SXin Li // Objective-C instance variable access.
3742*67e74705SXin Li ObjCInterfaceDecl *Class = nullptr;
3743*67e74705SXin Li if (const ObjCObjectPointerType *ObjCPtr
3744*67e74705SXin Li = BaseType->getAs<ObjCObjectPointerType>())
3745*67e74705SXin Li Class = ObjCPtr->getInterfaceDecl();
3746*67e74705SXin Li else
3747*67e74705SXin Li Class = BaseType->getAs<ObjCObjectType>()->getInterface();
3748*67e74705SXin Li
3749*67e74705SXin Li // Add all ivars from this class and its superclasses.
3750*67e74705SXin Li if (Class) {
3751*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
3752*67e74705SXin Li Results.setFilter(&ResultBuilder::IsObjCIvar);
3753*67e74705SXin Li LookupVisibleDecls(Class, LookupMemberName, Consumer,
3754*67e74705SXin Li CodeCompleter->includeGlobals());
3755*67e74705SXin Li }
3756*67e74705SXin Li }
3757*67e74705SXin Li
3758*67e74705SXin Li // FIXME: How do we cope with isa?
3759*67e74705SXin Li
3760*67e74705SXin Li Results.ExitScope();
3761*67e74705SXin Li
3762*67e74705SXin Li // Hand off the results found for code completion.
3763*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
3764*67e74705SXin Li Results.getCompletionContext(),
3765*67e74705SXin Li Results.data(),Results.size());
3766*67e74705SXin Li }
3767*67e74705SXin Li
CodeCompleteTag(Scope * S,unsigned TagSpec)3768*67e74705SXin Li void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
3769*67e74705SXin Li if (!CodeCompleter)
3770*67e74705SXin Li return;
3771*67e74705SXin Li
3772*67e74705SXin Li ResultBuilder::LookupFilter Filter = nullptr;
3773*67e74705SXin Li enum CodeCompletionContext::Kind ContextKind
3774*67e74705SXin Li = CodeCompletionContext::CCC_Other;
3775*67e74705SXin Li switch ((DeclSpec::TST)TagSpec) {
3776*67e74705SXin Li case DeclSpec::TST_enum:
3777*67e74705SXin Li Filter = &ResultBuilder::IsEnum;
3778*67e74705SXin Li ContextKind = CodeCompletionContext::CCC_EnumTag;
3779*67e74705SXin Li break;
3780*67e74705SXin Li
3781*67e74705SXin Li case DeclSpec::TST_union:
3782*67e74705SXin Li Filter = &ResultBuilder::IsUnion;
3783*67e74705SXin Li ContextKind = CodeCompletionContext::CCC_UnionTag;
3784*67e74705SXin Li break;
3785*67e74705SXin Li
3786*67e74705SXin Li case DeclSpec::TST_struct:
3787*67e74705SXin Li case DeclSpec::TST_class:
3788*67e74705SXin Li case DeclSpec::TST_interface:
3789*67e74705SXin Li Filter = &ResultBuilder::IsClassOrStruct;
3790*67e74705SXin Li ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
3791*67e74705SXin Li break;
3792*67e74705SXin Li
3793*67e74705SXin Li default:
3794*67e74705SXin Li llvm_unreachable("Unknown type specifier kind in CodeCompleteTag");
3795*67e74705SXin Li }
3796*67e74705SXin Li
3797*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3798*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(), ContextKind);
3799*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
3800*67e74705SXin Li
3801*67e74705SXin Li // First pass: look for tags.
3802*67e74705SXin Li Results.setFilter(Filter);
3803*67e74705SXin Li LookupVisibleDecls(S, LookupTagName, Consumer,
3804*67e74705SXin Li CodeCompleter->includeGlobals());
3805*67e74705SXin Li
3806*67e74705SXin Li if (CodeCompleter->includeGlobals()) {
3807*67e74705SXin Li // Second pass: look for nested name specifiers.
3808*67e74705SXin Li Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
3809*67e74705SXin Li LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
3810*67e74705SXin Li }
3811*67e74705SXin Li
3812*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
3813*67e74705SXin Li Results.data(),Results.size());
3814*67e74705SXin Li }
3815*67e74705SXin Li
CodeCompleteTypeQualifiers(DeclSpec & DS)3816*67e74705SXin Li void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
3817*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3818*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
3819*67e74705SXin Li CodeCompletionContext::CCC_TypeQualifiers);
3820*67e74705SXin Li Results.EnterNewScope();
3821*67e74705SXin Li if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
3822*67e74705SXin Li Results.AddResult("const");
3823*67e74705SXin Li if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
3824*67e74705SXin Li Results.AddResult("volatile");
3825*67e74705SXin Li if (getLangOpts().C99 &&
3826*67e74705SXin Li !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
3827*67e74705SXin Li Results.AddResult("restrict");
3828*67e74705SXin Li if (getLangOpts().C11 &&
3829*67e74705SXin Li !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
3830*67e74705SXin Li Results.AddResult("_Atomic");
3831*67e74705SXin Li if (getLangOpts().MSVCCompat &&
3832*67e74705SXin Li !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
3833*67e74705SXin Li Results.AddResult("__unaligned");
3834*67e74705SXin Li Results.ExitScope();
3835*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
3836*67e74705SXin Li Results.getCompletionContext(),
3837*67e74705SXin Li Results.data(), Results.size());
3838*67e74705SXin Li }
3839*67e74705SXin Li
CodeCompleteBracketDeclarator(Scope * S)3840*67e74705SXin Li void Sema::CodeCompleteBracketDeclarator(Scope *S) {
3841*67e74705SXin Li CodeCompleteExpression(S, QualType(getASTContext().getSizeType()));
3842*67e74705SXin Li }
3843*67e74705SXin Li
CodeCompleteCase(Scope * S)3844*67e74705SXin Li void Sema::CodeCompleteCase(Scope *S) {
3845*67e74705SXin Li if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
3846*67e74705SXin Li return;
3847*67e74705SXin Li
3848*67e74705SXin Li SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
3849*67e74705SXin Li QualType type = Switch->getCond()->IgnoreImplicit()->getType();
3850*67e74705SXin Li if (!type->isEnumeralType()) {
3851*67e74705SXin Li CodeCompleteExpressionData Data(type);
3852*67e74705SXin Li Data.IntegralConstantExpression = true;
3853*67e74705SXin Li CodeCompleteExpression(S, Data);
3854*67e74705SXin Li return;
3855*67e74705SXin Li }
3856*67e74705SXin Li
3857*67e74705SXin Li // Code-complete the cases of a switch statement over an enumeration type
3858*67e74705SXin Li // by providing the list of
3859*67e74705SXin Li EnumDecl *Enum = type->castAs<EnumType>()->getDecl();
3860*67e74705SXin Li if (EnumDecl *Def = Enum->getDefinition())
3861*67e74705SXin Li Enum = Def;
3862*67e74705SXin Li
3863*67e74705SXin Li // Determine which enumerators we have already seen in the switch statement.
3864*67e74705SXin Li // FIXME: Ideally, we would also be able to look *past* the code-completion
3865*67e74705SXin Li // token, in case we are code-completing in the middle of the switch and not
3866*67e74705SXin Li // at the end. However, we aren't able to do so at the moment.
3867*67e74705SXin Li llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
3868*67e74705SXin Li NestedNameSpecifier *Qualifier = nullptr;
3869*67e74705SXin Li for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
3870*67e74705SXin Li SC = SC->getNextSwitchCase()) {
3871*67e74705SXin Li CaseStmt *Case = dyn_cast<CaseStmt>(SC);
3872*67e74705SXin Li if (!Case)
3873*67e74705SXin Li continue;
3874*67e74705SXin Li
3875*67e74705SXin Li Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
3876*67e74705SXin Li if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
3877*67e74705SXin Li if (EnumConstantDecl *Enumerator
3878*67e74705SXin Li = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
3879*67e74705SXin Li // We look into the AST of the case statement to determine which
3880*67e74705SXin Li // enumerator was named. Alternatively, we could compute the value of
3881*67e74705SXin Li // the integral constant expression, then compare it against the
3882*67e74705SXin Li // values of each enumerator. However, value-based approach would not
3883*67e74705SXin Li // work as well with C++ templates where enumerators declared within a
3884*67e74705SXin Li // template are type- and value-dependent.
3885*67e74705SXin Li EnumeratorsSeen.insert(Enumerator);
3886*67e74705SXin Li
3887*67e74705SXin Li // If this is a qualified-id, keep track of the nested-name-specifier
3888*67e74705SXin Li // so that we can reproduce it as part of code completion, e.g.,
3889*67e74705SXin Li //
3890*67e74705SXin Li // switch (TagD.getKind()) {
3891*67e74705SXin Li // case TagDecl::TK_enum:
3892*67e74705SXin Li // break;
3893*67e74705SXin Li // case XXX
3894*67e74705SXin Li //
3895*67e74705SXin Li // At the XXX, our completions are TagDecl::TK_union,
3896*67e74705SXin Li // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
3897*67e74705SXin Li // TK_struct, and TK_class.
3898*67e74705SXin Li Qualifier = DRE->getQualifier();
3899*67e74705SXin Li }
3900*67e74705SXin Li }
3901*67e74705SXin Li
3902*67e74705SXin Li if (getLangOpts().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
3903*67e74705SXin Li // If there are no prior enumerators in C++, check whether we have to
3904*67e74705SXin Li // qualify the names of the enumerators that we suggest, because they
3905*67e74705SXin Li // may not be visible in this scope.
3906*67e74705SXin Li Qualifier = getRequiredQualification(Context, CurContext, Enum);
3907*67e74705SXin Li }
3908*67e74705SXin Li
3909*67e74705SXin Li // Add any enumerators that have not yet been mentioned.
3910*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
3911*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
3912*67e74705SXin Li CodeCompletionContext::CCC_Expression);
3913*67e74705SXin Li Results.EnterNewScope();
3914*67e74705SXin Li for (auto *E : Enum->enumerators()) {
3915*67e74705SXin Li if (EnumeratorsSeen.count(E))
3916*67e74705SXin Li continue;
3917*67e74705SXin Li
3918*67e74705SXin Li CodeCompletionResult R(E, CCP_EnumInCase, Qualifier);
3919*67e74705SXin Li Results.AddResult(R, CurContext, nullptr, false);
3920*67e74705SXin Li }
3921*67e74705SXin Li Results.ExitScope();
3922*67e74705SXin Li
3923*67e74705SXin Li //We need to make sure we're setting the right context,
3924*67e74705SXin Li //so only say we include macros if the code completer says we do
3925*67e74705SXin Li enum CodeCompletionContext::Kind kind = CodeCompletionContext::CCC_Other;
3926*67e74705SXin Li if (CodeCompleter->includeMacros()) {
3927*67e74705SXin Li AddMacroResults(PP, Results, false);
3928*67e74705SXin Li kind = CodeCompletionContext::CCC_OtherWithMacros;
3929*67e74705SXin Li }
3930*67e74705SXin Li
3931*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
3932*67e74705SXin Li kind,
3933*67e74705SXin Li Results.data(),Results.size());
3934*67e74705SXin Li }
3935*67e74705SXin Li
anyNullArguments(ArrayRef<Expr * > Args)3936*67e74705SXin Li static bool anyNullArguments(ArrayRef<Expr *> Args) {
3937*67e74705SXin Li if (Args.size() && !Args.data())
3938*67e74705SXin Li return true;
3939*67e74705SXin Li
3940*67e74705SXin Li for (unsigned I = 0; I != Args.size(); ++I)
3941*67e74705SXin Li if (!Args[I])
3942*67e74705SXin Li return true;
3943*67e74705SXin Li
3944*67e74705SXin Li return false;
3945*67e74705SXin Li }
3946*67e74705SXin Li
3947*67e74705SXin Li typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
3948*67e74705SXin Li
mergeCandidatesWithResults(Sema & SemaRef,SmallVectorImpl<ResultCandidate> & Results,OverloadCandidateSet & CandidateSet,SourceLocation Loc)3949*67e74705SXin Li static void mergeCandidatesWithResults(Sema &SemaRef,
3950*67e74705SXin Li SmallVectorImpl<ResultCandidate> &Results,
3951*67e74705SXin Li OverloadCandidateSet &CandidateSet,
3952*67e74705SXin Li SourceLocation Loc) {
3953*67e74705SXin Li if (!CandidateSet.empty()) {
3954*67e74705SXin Li // Sort the overload candidate set by placing the best overloads first.
3955*67e74705SXin Li std::stable_sort(
3956*67e74705SXin Li CandidateSet.begin(), CandidateSet.end(),
3957*67e74705SXin Li [&](const OverloadCandidate &X, const OverloadCandidate &Y) {
3958*67e74705SXin Li return isBetterOverloadCandidate(SemaRef, X, Y, Loc);
3959*67e74705SXin Li });
3960*67e74705SXin Li
3961*67e74705SXin Li // Add the remaining viable overload candidates as code-completion results.
3962*67e74705SXin Li for (auto &Candidate : CandidateSet)
3963*67e74705SXin Li if (Candidate.Viable)
3964*67e74705SXin Li Results.push_back(ResultCandidate(Candidate.Function));
3965*67e74705SXin Li }
3966*67e74705SXin Li }
3967*67e74705SXin Li
3968*67e74705SXin Li /// \brief Get the type of the Nth parameter from a given set of overload
3969*67e74705SXin Li /// candidates.
getParamType(Sema & SemaRef,ArrayRef<ResultCandidate> Candidates,unsigned N)3970*67e74705SXin Li static QualType getParamType(Sema &SemaRef,
3971*67e74705SXin Li ArrayRef<ResultCandidate> Candidates,
3972*67e74705SXin Li unsigned N) {
3973*67e74705SXin Li
3974*67e74705SXin Li // Given the overloads 'Candidates' for a function call matching all arguments
3975*67e74705SXin Li // up to N, return the type of the Nth parameter if it is the same for all
3976*67e74705SXin Li // overload candidates.
3977*67e74705SXin Li QualType ParamType;
3978*67e74705SXin Li for (auto &Candidate : Candidates) {
3979*67e74705SXin Li if (auto FType = Candidate.getFunctionType())
3980*67e74705SXin Li if (auto Proto = dyn_cast<FunctionProtoType>(FType))
3981*67e74705SXin Li if (N < Proto->getNumParams()) {
3982*67e74705SXin Li if (ParamType.isNull())
3983*67e74705SXin Li ParamType = Proto->getParamType(N);
3984*67e74705SXin Li else if (!SemaRef.Context.hasSameUnqualifiedType(
3985*67e74705SXin Li ParamType.getNonReferenceType(),
3986*67e74705SXin Li Proto->getParamType(N).getNonReferenceType()))
3987*67e74705SXin Li // Otherwise return a default-constructed QualType.
3988*67e74705SXin Li return QualType();
3989*67e74705SXin Li }
3990*67e74705SXin Li }
3991*67e74705SXin Li
3992*67e74705SXin Li return ParamType;
3993*67e74705SXin Li }
3994*67e74705SXin Li
CodeCompleteOverloadResults(Sema & SemaRef,Scope * S,MutableArrayRef<ResultCandidate> Candidates,unsigned CurrentArg,bool CompleteExpressionWithCurrentArg=true)3995*67e74705SXin Li static void CodeCompleteOverloadResults(Sema &SemaRef, Scope *S,
3996*67e74705SXin Li MutableArrayRef<ResultCandidate> Candidates,
3997*67e74705SXin Li unsigned CurrentArg,
3998*67e74705SXin Li bool CompleteExpressionWithCurrentArg = true) {
3999*67e74705SXin Li QualType ParamType;
4000*67e74705SXin Li if (CompleteExpressionWithCurrentArg)
4001*67e74705SXin Li ParamType = getParamType(SemaRef, Candidates, CurrentArg);
4002*67e74705SXin Li
4003*67e74705SXin Li if (ParamType.isNull())
4004*67e74705SXin Li SemaRef.CodeCompleteOrdinaryName(S, Sema::PCC_Expression);
4005*67e74705SXin Li else
4006*67e74705SXin Li SemaRef.CodeCompleteExpression(S, ParamType);
4007*67e74705SXin Li
4008*67e74705SXin Li if (!Candidates.empty())
4009*67e74705SXin Li SemaRef.CodeCompleter->ProcessOverloadCandidates(SemaRef, CurrentArg,
4010*67e74705SXin Li Candidates.data(),
4011*67e74705SXin Li Candidates.size());
4012*67e74705SXin Li }
4013*67e74705SXin Li
CodeCompleteCall(Scope * S,Expr * Fn,ArrayRef<Expr * > Args)4014*67e74705SXin Li void Sema::CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args) {
4015*67e74705SXin Li if (!CodeCompleter)
4016*67e74705SXin Li return;
4017*67e74705SXin Li
4018*67e74705SXin Li // When we're code-completing for a call, we fall back to ordinary
4019*67e74705SXin Li // name code-completion whenever we can't produce specific
4020*67e74705SXin Li // results. We may want to revisit this strategy in the future,
4021*67e74705SXin Li // e.g., by merging the two kinds of results.
4022*67e74705SXin Li
4023*67e74705SXin Li // FIXME: Provide support for variadic template functions.
4024*67e74705SXin Li
4025*67e74705SXin Li // Ignore type-dependent call expressions entirely.
4026*67e74705SXin Li if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args) ||
4027*67e74705SXin Li Expr::hasAnyTypeDependentArguments(Args)) {
4028*67e74705SXin Li CodeCompleteOrdinaryName(S, PCC_Expression);
4029*67e74705SXin Li return;
4030*67e74705SXin Li }
4031*67e74705SXin Li
4032*67e74705SXin Li // Build an overload candidate set based on the functions we find.
4033*67e74705SXin Li SourceLocation Loc = Fn->getExprLoc();
4034*67e74705SXin Li OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
4035*67e74705SXin Li
4036*67e74705SXin Li SmallVector<ResultCandidate, 8> Results;
4037*67e74705SXin Li
4038*67e74705SXin Li Expr *NakedFn = Fn->IgnoreParenCasts();
4039*67e74705SXin Li if (auto ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
4040*67e74705SXin Li AddOverloadedCallCandidates(ULE, Args, CandidateSet,
4041*67e74705SXin Li /*PartialOverloading=*/true);
4042*67e74705SXin Li else if (auto UME = dyn_cast<UnresolvedMemberExpr>(NakedFn)) {
4043*67e74705SXin Li TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
4044*67e74705SXin Li if (UME->hasExplicitTemplateArgs()) {
4045*67e74705SXin Li UME->copyTemplateArgumentsInto(TemplateArgsBuffer);
4046*67e74705SXin Li TemplateArgs = &TemplateArgsBuffer;
4047*67e74705SXin Li }
4048*67e74705SXin Li SmallVector<Expr *, 12> ArgExprs(1, UME->getBase());
4049*67e74705SXin Li ArgExprs.append(Args.begin(), Args.end());
4050*67e74705SXin Li UnresolvedSet<8> Decls;
4051*67e74705SXin Li Decls.append(UME->decls_begin(), UME->decls_end());
4052*67e74705SXin Li AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs,
4053*67e74705SXin Li /*SuppressUsedConversions=*/false,
4054*67e74705SXin Li /*PartialOverloading=*/true);
4055*67e74705SXin Li } else {
4056*67e74705SXin Li FunctionDecl *FD = nullptr;
4057*67e74705SXin Li if (auto MCE = dyn_cast<MemberExpr>(NakedFn))
4058*67e74705SXin Li FD = dyn_cast<FunctionDecl>(MCE->getMemberDecl());
4059*67e74705SXin Li else if (auto DRE = dyn_cast<DeclRefExpr>(NakedFn))
4060*67e74705SXin Li FD = dyn_cast<FunctionDecl>(DRE->getDecl());
4061*67e74705SXin Li if (FD) { // We check whether it's a resolved function declaration.
4062*67e74705SXin Li if (!getLangOpts().CPlusPlus ||
4063*67e74705SXin Li !FD->getType()->getAs<FunctionProtoType>())
4064*67e74705SXin Li Results.push_back(ResultCandidate(FD));
4065*67e74705SXin Li else
4066*67e74705SXin Li AddOverloadCandidate(FD, DeclAccessPair::make(FD, FD->getAccess()),
4067*67e74705SXin Li Args, CandidateSet,
4068*67e74705SXin Li /*SuppressUsedConversions=*/false,
4069*67e74705SXin Li /*PartialOverloading=*/true);
4070*67e74705SXin Li
4071*67e74705SXin Li } else if (auto DC = NakedFn->getType()->getAsCXXRecordDecl()) {
4072*67e74705SXin Li // If expression's type is CXXRecordDecl, it may overload the function
4073*67e74705SXin Li // call operator, so we check if it does and add them as candidates.
4074*67e74705SXin Li // A complete type is needed to lookup for member function call operators.
4075*67e74705SXin Li if (isCompleteType(Loc, NakedFn->getType())) {
4076*67e74705SXin Li DeclarationName OpName = Context.DeclarationNames
4077*67e74705SXin Li .getCXXOperatorName(OO_Call);
4078*67e74705SXin Li LookupResult R(*this, OpName, Loc, LookupOrdinaryName);
4079*67e74705SXin Li LookupQualifiedName(R, DC);
4080*67e74705SXin Li R.suppressDiagnostics();
4081*67e74705SXin Li SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
4082*67e74705SXin Li ArgExprs.append(Args.begin(), Args.end());
4083*67e74705SXin Li AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs, CandidateSet,
4084*67e74705SXin Li /*ExplicitArgs=*/nullptr,
4085*67e74705SXin Li /*SuppressUsedConversions=*/false,
4086*67e74705SXin Li /*PartialOverloading=*/true);
4087*67e74705SXin Li }
4088*67e74705SXin Li } else {
4089*67e74705SXin Li // Lastly we check whether expression's type is function pointer or
4090*67e74705SXin Li // function.
4091*67e74705SXin Li QualType T = NakedFn->getType();
4092*67e74705SXin Li if (!T->getPointeeType().isNull())
4093*67e74705SXin Li T = T->getPointeeType();
4094*67e74705SXin Li
4095*67e74705SXin Li if (auto FP = T->getAs<FunctionProtoType>()) {
4096*67e74705SXin Li if (!TooManyArguments(FP->getNumParams(), Args.size(),
4097*67e74705SXin Li /*PartialOverloading=*/true) ||
4098*67e74705SXin Li FP->isVariadic())
4099*67e74705SXin Li Results.push_back(ResultCandidate(FP));
4100*67e74705SXin Li } else if (auto FT = T->getAs<FunctionType>())
4101*67e74705SXin Li // No prototype and declaration, it may be a K & R style function.
4102*67e74705SXin Li Results.push_back(ResultCandidate(FT));
4103*67e74705SXin Li }
4104*67e74705SXin Li }
4105*67e74705SXin Li
4106*67e74705SXin Li mergeCandidatesWithResults(*this, Results, CandidateSet, Loc);
4107*67e74705SXin Li CodeCompleteOverloadResults(*this, S, Results, Args.size(),
4108*67e74705SXin Li !CandidateSet.empty());
4109*67e74705SXin Li }
4110*67e74705SXin Li
CodeCompleteConstructor(Scope * S,QualType Type,SourceLocation Loc,ArrayRef<Expr * > Args)4111*67e74705SXin Li void Sema::CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc,
4112*67e74705SXin Li ArrayRef<Expr *> Args) {
4113*67e74705SXin Li if (!CodeCompleter)
4114*67e74705SXin Li return;
4115*67e74705SXin Li
4116*67e74705SXin Li // A complete type is needed to lookup for constructors.
4117*67e74705SXin Li if (!isCompleteType(Loc, Type))
4118*67e74705SXin Li return;
4119*67e74705SXin Li
4120*67e74705SXin Li CXXRecordDecl *RD = Type->getAsCXXRecordDecl();
4121*67e74705SXin Li if (!RD) {
4122*67e74705SXin Li CodeCompleteExpression(S, Type);
4123*67e74705SXin Li return;
4124*67e74705SXin Li }
4125*67e74705SXin Li
4126*67e74705SXin Li // FIXME: Provide support for member initializers.
4127*67e74705SXin Li // FIXME: Provide support for variadic template constructors.
4128*67e74705SXin Li
4129*67e74705SXin Li OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
4130*67e74705SXin Li
4131*67e74705SXin Li for (auto C : LookupConstructors(RD)) {
4132*67e74705SXin Li if (auto FD = dyn_cast<FunctionDecl>(C)) {
4133*67e74705SXin Li AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()),
4134*67e74705SXin Li Args, CandidateSet,
4135*67e74705SXin Li /*SuppressUsedConversions=*/false,
4136*67e74705SXin Li /*PartialOverloading=*/true);
4137*67e74705SXin Li } else if (auto FTD = dyn_cast<FunctionTemplateDecl>(C)) {
4138*67e74705SXin Li AddTemplateOverloadCandidate(FTD,
4139*67e74705SXin Li DeclAccessPair::make(FTD, C->getAccess()),
4140*67e74705SXin Li /*ExplicitTemplateArgs=*/nullptr,
4141*67e74705SXin Li Args, CandidateSet,
4142*67e74705SXin Li /*SuppressUsedConversions=*/false,
4143*67e74705SXin Li /*PartialOverloading=*/true);
4144*67e74705SXin Li }
4145*67e74705SXin Li }
4146*67e74705SXin Li
4147*67e74705SXin Li SmallVector<ResultCandidate, 8> Results;
4148*67e74705SXin Li mergeCandidatesWithResults(*this, Results, CandidateSet, Loc);
4149*67e74705SXin Li CodeCompleteOverloadResults(*this, S, Results, Args.size());
4150*67e74705SXin Li }
4151*67e74705SXin Li
CodeCompleteInitializer(Scope * S,Decl * D)4152*67e74705SXin Li void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
4153*67e74705SXin Li ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
4154*67e74705SXin Li if (!VD) {
4155*67e74705SXin Li CodeCompleteOrdinaryName(S, PCC_Expression);
4156*67e74705SXin Li return;
4157*67e74705SXin Li }
4158*67e74705SXin Li
4159*67e74705SXin Li CodeCompleteExpression(S, VD->getType());
4160*67e74705SXin Li }
4161*67e74705SXin Li
CodeCompleteReturn(Scope * S)4162*67e74705SXin Li void Sema::CodeCompleteReturn(Scope *S) {
4163*67e74705SXin Li QualType ResultType;
4164*67e74705SXin Li if (isa<BlockDecl>(CurContext)) {
4165*67e74705SXin Li if (BlockScopeInfo *BSI = getCurBlock())
4166*67e74705SXin Li ResultType = BSI->ReturnType;
4167*67e74705SXin Li } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
4168*67e74705SXin Li ResultType = Function->getReturnType();
4169*67e74705SXin Li else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
4170*67e74705SXin Li ResultType = Method->getReturnType();
4171*67e74705SXin Li
4172*67e74705SXin Li if (ResultType.isNull())
4173*67e74705SXin Li CodeCompleteOrdinaryName(S, PCC_Expression);
4174*67e74705SXin Li else
4175*67e74705SXin Li CodeCompleteExpression(S, ResultType);
4176*67e74705SXin Li }
4177*67e74705SXin Li
CodeCompleteAfterIf(Scope * S)4178*67e74705SXin Li void Sema::CodeCompleteAfterIf(Scope *S) {
4179*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4180*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4181*67e74705SXin Li mapCodeCompletionContext(*this, PCC_Statement));
4182*67e74705SXin Li Results.setFilter(&ResultBuilder::IsOrdinaryName);
4183*67e74705SXin Li Results.EnterNewScope();
4184*67e74705SXin Li
4185*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
4186*67e74705SXin Li LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4187*67e74705SXin Li CodeCompleter->includeGlobals());
4188*67e74705SXin Li
4189*67e74705SXin Li AddOrdinaryNameResults(PCC_Statement, S, *this, Results);
4190*67e74705SXin Li
4191*67e74705SXin Li // "else" block
4192*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
4193*67e74705SXin Li Results.getCodeCompletionTUInfo());
4194*67e74705SXin Li Builder.AddTypedTextChunk("else");
4195*67e74705SXin Li if (Results.includeCodePatterns()) {
4196*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4197*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4198*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4199*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
4200*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4201*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4202*67e74705SXin Li }
4203*67e74705SXin Li Results.AddResult(Builder.TakeString());
4204*67e74705SXin Li
4205*67e74705SXin Li // "else if" block
4206*67e74705SXin Li Builder.AddTypedTextChunk("else");
4207*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4208*67e74705SXin Li Builder.AddTextChunk("if");
4209*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4210*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4211*67e74705SXin Li if (getLangOpts().CPlusPlus)
4212*67e74705SXin Li Builder.AddPlaceholderChunk("condition");
4213*67e74705SXin Li else
4214*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
4215*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4216*67e74705SXin Li if (Results.includeCodePatterns()) {
4217*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4218*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4219*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4220*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
4221*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
4222*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4223*67e74705SXin Li }
4224*67e74705SXin Li Results.AddResult(Builder.TakeString());
4225*67e74705SXin Li
4226*67e74705SXin Li Results.ExitScope();
4227*67e74705SXin Li
4228*67e74705SXin Li if (S->getFnParent())
4229*67e74705SXin Li AddPrettyFunctionResults(getLangOpts(), Results);
4230*67e74705SXin Li
4231*67e74705SXin Li if (CodeCompleter->includeMacros())
4232*67e74705SXin Li AddMacroResults(PP, Results, false);
4233*67e74705SXin Li
4234*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4235*67e74705SXin Li Results.data(),Results.size());
4236*67e74705SXin Li }
4237*67e74705SXin Li
CodeCompleteAssignmentRHS(Scope * S,Expr * LHS)4238*67e74705SXin Li void Sema::CodeCompleteAssignmentRHS(Scope *S, Expr *LHS) {
4239*67e74705SXin Li if (LHS)
4240*67e74705SXin Li CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
4241*67e74705SXin Li else
4242*67e74705SXin Li CodeCompleteOrdinaryName(S, PCC_Expression);
4243*67e74705SXin Li }
4244*67e74705SXin Li
CodeCompleteQualifiedId(Scope * S,CXXScopeSpec & SS,bool EnteringContext)4245*67e74705SXin Li void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
4246*67e74705SXin Li bool EnteringContext) {
4247*67e74705SXin Li if (!SS.getScopeRep() || !CodeCompleter)
4248*67e74705SXin Li return;
4249*67e74705SXin Li
4250*67e74705SXin Li DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
4251*67e74705SXin Li if (!Ctx)
4252*67e74705SXin Li return;
4253*67e74705SXin Li
4254*67e74705SXin Li // Try to instantiate any non-dependent declaration contexts before
4255*67e74705SXin Li // we look in them.
4256*67e74705SXin Li if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
4257*67e74705SXin Li return;
4258*67e74705SXin Li
4259*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4260*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4261*67e74705SXin Li CodeCompletionContext::CCC_Name);
4262*67e74705SXin Li Results.EnterNewScope();
4263*67e74705SXin Li
4264*67e74705SXin Li // The "template" keyword can follow "::" in the grammar, but only
4265*67e74705SXin Li // put it into the grammar if the nested-name-specifier is dependent.
4266*67e74705SXin Li NestedNameSpecifier *NNS = SS.getScopeRep();
4267*67e74705SXin Li if (!Results.empty() && NNS->isDependent())
4268*67e74705SXin Li Results.AddResult("template");
4269*67e74705SXin Li
4270*67e74705SXin Li // Add calls to overridden virtual functions, if there are any.
4271*67e74705SXin Li //
4272*67e74705SXin Li // FIXME: This isn't wonderful, because we don't know whether we're actually
4273*67e74705SXin Li // in a context that permits expressions. This is a general issue with
4274*67e74705SXin Li // qualified-id completions.
4275*67e74705SXin Li if (!EnteringContext)
4276*67e74705SXin Li MaybeAddOverrideCalls(*this, Ctx, Results);
4277*67e74705SXin Li Results.ExitScope();
4278*67e74705SXin Li
4279*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
4280*67e74705SXin Li LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
4281*67e74705SXin Li
4282*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4283*67e74705SXin Li Results.getCompletionContext(),
4284*67e74705SXin Li Results.data(),Results.size());
4285*67e74705SXin Li }
4286*67e74705SXin Li
CodeCompleteUsing(Scope * S)4287*67e74705SXin Li void Sema::CodeCompleteUsing(Scope *S) {
4288*67e74705SXin Li if (!CodeCompleter)
4289*67e74705SXin Li return;
4290*67e74705SXin Li
4291*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4292*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4293*67e74705SXin Li CodeCompletionContext::CCC_PotentiallyQualifiedName,
4294*67e74705SXin Li &ResultBuilder::IsNestedNameSpecifier);
4295*67e74705SXin Li Results.EnterNewScope();
4296*67e74705SXin Li
4297*67e74705SXin Li // If we aren't in class scope, we could see the "namespace" keyword.
4298*67e74705SXin Li if (!S->isClassScope())
4299*67e74705SXin Li Results.AddResult(CodeCompletionResult("namespace"));
4300*67e74705SXin Li
4301*67e74705SXin Li // After "using", we can see anything that would start a
4302*67e74705SXin Li // nested-name-specifier.
4303*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
4304*67e74705SXin Li LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4305*67e74705SXin Li CodeCompleter->includeGlobals());
4306*67e74705SXin Li Results.ExitScope();
4307*67e74705SXin Li
4308*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4309*67e74705SXin Li CodeCompletionContext::CCC_PotentiallyQualifiedName,
4310*67e74705SXin Li Results.data(),Results.size());
4311*67e74705SXin Li }
4312*67e74705SXin Li
CodeCompleteUsingDirective(Scope * S)4313*67e74705SXin Li void Sema::CodeCompleteUsingDirective(Scope *S) {
4314*67e74705SXin Li if (!CodeCompleter)
4315*67e74705SXin Li return;
4316*67e74705SXin Li
4317*67e74705SXin Li // After "using namespace", we expect to see a namespace name or namespace
4318*67e74705SXin Li // alias.
4319*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4320*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4321*67e74705SXin Li CodeCompletionContext::CCC_Namespace,
4322*67e74705SXin Li &ResultBuilder::IsNamespaceOrAlias);
4323*67e74705SXin Li Results.EnterNewScope();
4324*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
4325*67e74705SXin Li LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4326*67e74705SXin Li CodeCompleter->includeGlobals());
4327*67e74705SXin Li Results.ExitScope();
4328*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4329*67e74705SXin Li CodeCompletionContext::CCC_Namespace,
4330*67e74705SXin Li Results.data(),Results.size());
4331*67e74705SXin Li }
4332*67e74705SXin Li
CodeCompleteNamespaceDecl(Scope * S)4333*67e74705SXin Li void Sema::CodeCompleteNamespaceDecl(Scope *S) {
4334*67e74705SXin Li if (!CodeCompleter)
4335*67e74705SXin Li return;
4336*67e74705SXin Li
4337*67e74705SXin Li DeclContext *Ctx = S->getEntity();
4338*67e74705SXin Li if (!S->getParent())
4339*67e74705SXin Li Ctx = Context.getTranslationUnitDecl();
4340*67e74705SXin Li
4341*67e74705SXin Li bool SuppressedGlobalResults
4342*67e74705SXin Li = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
4343*67e74705SXin Li
4344*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4345*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4346*67e74705SXin Li SuppressedGlobalResults
4347*67e74705SXin Li ? CodeCompletionContext::CCC_Namespace
4348*67e74705SXin Li : CodeCompletionContext::CCC_Other,
4349*67e74705SXin Li &ResultBuilder::IsNamespace);
4350*67e74705SXin Li
4351*67e74705SXin Li if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
4352*67e74705SXin Li // We only want to see those namespaces that have already been defined
4353*67e74705SXin Li // within this scope, because its likely that the user is creating an
4354*67e74705SXin Li // extended namespace declaration. Keep track of the most recent
4355*67e74705SXin Li // definition of each namespace.
4356*67e74705SXin Li std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
4357*67e74705SXin Li for (DeclContext::specific_decl_iterator<NamespaceDecl>
4358*67e74705SXin Li NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
4359*67e74705SXin Li NS != NSEnd; ++NS)
4360*67e74705SXin Li OrigToLatest[NS->getOriginalNamespace()] = *NS;
4361*67e74705SXin Li
4362*67e74705SXin Li // Add the most recent definition (or extended definition) of each
4363*67e74705SXin Li // namespace to the list of results.
4364*67e74705SXin Li Results.EnterNewScope();
4365*67e74705SXin Li for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
4366*67e74705SXin Li NS = OrigToLatest.begin(),
4367*67e74705SXin Li NSEnd = OrigToLatest.end();
4368*67e74705SXin Li NS != NSEnd; ++NS)
4369*67e74705SXin Li Results.AddResult(CodeCompletionResult(
4370*67e74705SXin Li NS->second, Results.getBasePriority(NS->second),
4371*67e74705SXin Li nullptr),
4372*67e74705SXin Li CurContext, nullptr, false);
4373*67e74705SXin Li Results.ExitScope();
4374*67e74705SXin Li }
4375*67e74705SXin Li
4376*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4377*67e74705SXin Li Results.getCompletionContext(),
4378*67e74705SXin Li Results.data(),Results.size());
4379*67e74705SXin Li }
4380*67e74705SXin Li
CodeCompleteNamespaceAliasDecl(Scope * S)4381*67e74705SXin Li void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
4382*67e74705SXin Li if (!CodeCompleter)
4383*67e74705SXin Li return;
4384*67e74705SXin Li
4385*67e74705SXin Li // After "namespace", we expect to see a namespace or alias.
4386*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4387*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4388*67e74705SXin Li CodeCompletionContext::CCC_Namespace,
4389*67e74705SXin Li &ResultBuilder::IsNamespaceOrAlias);
4390*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
4391*67e74705SXin Li LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4392*67e74705SXin Li CodeCompleter->includeGlobals());
4393*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4394*67e74705SXin Li Results.getCompletionContext(),
4395*67e74705SXin Li Results.data(),Results.size());
4396*67e74705SXin Li }
4397*67e74705SXin Li
CodeCompleteOperatorName(Scope * S)4398*67e74705SXin Li void Sema::CodeCompleteOperatorName(Scope *S) {
4399*67e74705SXin Li if (!CodeCompleter)
4400*67e74705SXin Li return;
4401*67e74705SXin Li
4402*67e74705SXin Li typedef CodeCompletionResult Result;
4403*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4404*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4405*67e74705SXin Li CodeCompletionContext::CCC_Type,
4406*67e74705SXin Li &ResultBuilder::IsType);
4407*67e74705SXin Li Results.EnterNewScope();
4408*67e74705SXin Li
4409*67e74705SXin Li // Add the names of overloadable operators.
4410*67e74705SXin Li #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
4411*67e74705SXin Li if (std::strcmp(Spelling, "?")) \
4412*67e74705SXin Li Results.AddResult(Result(Spelling));
4413*67e74705SXin Li #include "clang/Basic/OperatorKinds.def"
4414*67e74705SXin Li
4415*67e74705SXin Li // Add any type names visible from the current scope
4416*67e74705SXin Li Results.allowNestedNameSpecifiers();
4417*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
4418*67e74705SXin Li LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
4419*67e74705SXin Li CodeCompleter->includeGlobals());
4420*67e74705SXin Li
4421*67e74705SXin Li // Add any type specifiers
4422*67e74705SXin Li AddTypeSpecifierResults(getLangOpts(), Results);
4423*67e74705SXin Li Results.ExitScope();
4424*67e74705SXin Li
4425*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4426*67e74705SXin Li CodeCompletionContext::CCC_Type,
4427*67e74705SXin Li Results.data(),Results.size());
4428*67e74705SXin Li }
4429*67e74705SXin Li
CodeCompleteConstructorInitializer(Decl * ConstructorD,ArrayRef<CXXCtorInitializer * > Initializers)4430*67e74705SXin Li void Sema::CodeCompleteConstructorInitializer(
4431*67e74705SXin Li Decl *ConstructorD,
4432*67e74705SXin Li ArrayRef <CXXCtorInitializer *> Initializers) {
4433*67e74705SXin Li if (!ConstructorD)
4434*67e74705SXin Li return;
4435*67e74705SXin Li
4436*67e74705SXin Li AdjustDeclIfTemplate(ConstructorD);
4437*67e74705SXin Li
4438*67e74705SXin Li CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ConstructorD);
4439*67e74705SXin Li if (!Constructor)
4440*67e74705SXin Li return;
4441*67e74705SXin Li
4442*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4443*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4444*67e74705SXin Li CodeCompletionContext::CCC_PotentiallyQualifiedName);
4445*67e74705SXin Li Results.EnterNewScope();
4446*67e74705SXin Li
4447*67e74705SXin Li // Fill in any already-initialized fields or base classes.
4448*67e74705SXin Li llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
4449*67e74705SXin Li llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
4450*67e74705SXin Li for (unsigned I = 0, E = Initializers.size(); I != E; ++I) {
4451*67e74705SXin Li if (Initializers[I]->isBaseInitializer())
4452*67e74705SXin Li InitializedBases.insert(
4453*67e74705SXin Li Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
4454*67e74705SXin Li else
4455*67e74705SXin Li InitializedFields.insert(cast<FieldDecl>(
4456*67e74705SXin Li Initializers[I]->getAnyMember()));
4457*67e74705SXin Li }
4458*67e74705SXin Li
4459*67e74705SXin Li // Add completions for base classes.
4460*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
4461*67e74705SXin Li Results.getCodeCompletionTUInfo());
4462*67e74705SXin Li PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
4463*67e74705SXin Li bool SawLastInitializer = Initializers.empty();
4464*67e74705SXin Li CXXRecordDecl *ClassDecl = Constructor->getParent();
4465*67e74705SXin Li for (const auto &Base : ClassDecl->bases()) {
4466*67e74705SXin Li if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))
4467*67e74705SXin Li .second) {
4468*67e74705SXin Li SawLastInitializer
4469*67e74705SXin Li = !Initializers.empty() &&
4470*67e74705SXin Li Initializers.back()->isBaseInitializer() &&
4471*67e74705SXin Li Context.hasSameUnqualifiedType(Base.getType(),
4472*67e74705SXin Li QualType(Initializers.back()->getBaseClass(), 0));
4473*67e74705SXin Li continue;
4474*67e74705SXin Li }
4475*67e74705SXin Li
4476*67e74705SXin Li Builder.AddTypedTextChunk(
4477*67e74705SXin Li Results.getAllocator().CopyString(
4478*67e74705SXin Li Base.getType().getAsString(Policy)));
4479*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4480*67e74705SXin Li Builder.AddPlaceholderChunk("args");
4481*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4482*67e74705SXin Li Results.AddResult(CodeCompletionResult(Builder.TakeString(),
4483*67e74705SXin Li SawLastInitializer? CCP_NextInitializer
4484*67e74705SXin Li : CCP_MemberDeclaration));
4485*67e74705SXin Li SawLastInitializer = false;
4486*67e74705SXin Li }
4487*67e74705SXin Li
4488*67e74705SXin Li // Add completions for virtual base classes.
4489*67e74705SXin Li for (const auto &Base : ClassDecl->vbases()) {
4490*67e74705SXin Li if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))
4491*67e74705SXin Li .second) {
4492*67e74705SXin Li SawLastInitializer
4493*67e74705SXin Li = !Initializers.empty() &&
4494*67e74705SXin Li Initializers.back()->isBaseInitializer() &&
4495*67e74705SXin Li Context.hasSameUnqualifiedType(Base.getType(),
4496*67e74705SXin Li QualType(Initializers.back()->getBaseClass(), 0));
4497*67e74705SXin Li continue;
4498*67e74705SXin Li }
4499*67e74705SXin Li
4500*67e74705SXin Li Builder.AddTypedTextChunk(
4501*67e74705SXin Li Builder.getAllocator().CopyString(
4502*67e74705SXin Li Base.getType().getAsString(Policy)));
4503*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4504*67e74705SXin Li Builder.AddPlaceholderChunk("args");
4505*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4506*67e74705SXin Li Results.AddResult(CodeCompletionResult(Builder.TakeString(),
4507*67e74705SXin Li SawLastInitializer? CCP_NextInitializer
4508*67e74705SXin Li : CCP_MemberDeclaration));
4509*67e74705SXin Li SawLastInitializer = false;
4510*67e74705SXin Li }
4511*67e74705SXin Li
4512*67e74705SXin Li // Add completions for members.
4513*67e74705SXin Li for (auto *Field : ClassDecl->fields()) {
4514*67e74705SXin Li if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))
4515*67e74705SXin Li .second) {
4516*67e74705SXin Li SawLastInitializer
4517*67e74705SXin Li = !Initializers.empty() &&
4518*67e74705SXin Li Initializers.back()->isAnyMemberInitializer() &&
4519*67e74705SXin Li Initializers.back()->getAnyMember() == Field;
4520*67e74705SXin Li continue;
4521*67e74705SXin Li }
4522*67e74705SXin Li
4523*67e74705SXin Li if (!Field->getDeclName())
4524*67e74705SXin Li continue;
4525*67e74705SXin Li
4526*67e74705SXin Li Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
4527*67e74705SXin Li Field->getIdentifier()->getName()));
4528*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4529*67e74705SXin Li Builder.AddPlaceholderChunk("args");
4530*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4531*67e74705SXin Li Results.AddResult(CodeCompletionResult(Builder.TakeString(),
4532*67e74705SXin Li SawLastInitializer? CCP_NextInitializer
4533*67e74705SXin Li : CCP_MemberDeclaration,
4534*67e74705SXin Li CXCursor_MemberRef,
4535*67e74705SXin Li CXAvailability_Available,
4536*67e74705SXin Li Field));
4537*67e74705SXin Li SawLastInitializer = false;
4538*67e74705SXin Li }
4539*67e74705SXin Li Results.ExitScope();
4540*67e74705SXin Li
4541*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4542*67e74705SXin Li Results.data(), Results.size());
4543*67e74705SXin Li }
4544*67e74705SXin Li
4545*67e74705SXin Li /// \brief Determine whether this scope denotes a namespace.
isNamespaceScope(Scope * S)4546*67e74705SXin Li static bool isNamespaceScope(Scope *S) {
4547*67e74705SXin Li DeclContext *DC = S->getEntity();
4548*67e74705SXin Li if (!DC)
4549*67e74705SXin Li return false;
4550*67e74705SXin Li
4551*67e74705SXin Li return DC->isFileContext();
4552*67e74705SXin Li }
4553*67e74705SXin Li
CodeCompleteLambdaIntroducer(Scope * S,LambdaIntroducer & Intro,bool AfterAmpersand)4554*67e74705SXin Li void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
4555*67e74705SXin Li bool AfterAmpersand) {
4556*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4557*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4558*67e74705SXin Li CodeCompletionContext::CCC_Other);
4559*67e74705SXin Li Results.EnterNewScope();
4560*67e74705SXin Li
4561*67e74705SXin Li // Note what has already been captured.
4562*67e74705SXin Li llvm::SmallPtrSet<IdentifierInfo *, 4> Known;
4563*67e74705SXin Li bool IncludedThis = false;
4564*67e74705SXin Li for (const auto &C : Intro.Captures) {
4565*67e74705SXin Li if (C.Kind == LCK_This) {
4566*67e74705SXin Li IncludedThis = true;
4567*67e74705SXin Li continue;
4568*67e74705SXin Li }
4569*67e74705SXin Li
4570*67e74705SXin Li Known.insert(C.Id);
4571*67e74705SXin Li }
4572*67e74705SXin Li
4573*67e74705SXin Li // Look for other capturable variables.
4574*67e74705SXin Li for (; S && !isNamespaceScope(S); S = S->getParent()) {
4575*67e74705SXin Li for (const auto *D : S->decls()) {
4576*67e74705SXin Li const auto *Var = dyn_cast<VarDecl>(D);
4577*67e74705SXin Li if (!Var ||
4578*67e74705SXin Li !Var->hasLocalStorage() ||
4579*67e74705SXin Li Var->hasAttr<BlocksAttr>())
4580*67e74705SXin Li continue;
4581*67e74705SXin Li
4582*67e74705SXin Li if (Known.insert(Var->getIdentifier()).second)
4583*67e74705SXin Li Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration),
4584*67e74705SXin Li CurContext, nullptr, false);
4585*67e74705SXin Li }
4586*67e74705SXin Li }
4587*67e74705SXin Li
4588*67e74705SXin Li // Add 'this', if it would be valid.
4589*67e74705SXin Li if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy)
4590*67e74705SXin Li addThisCompletion(*this, Results);
4591*67e74705SXin Li
4592*67e74705SXin Li Results.ExitScope();
4593*67e74705SXin Li
4594*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
4595*67e74705SXin Li Results.data(), Results.size());
4596*67e74705SXin Li }
4597*67e74705SXin Li
4598*67e74705SXin Li /// Macro that optionally prepends an "@" to the string literal passed in via
4599*67e74705SXin Li /// Keyword, depending on whether NeedAt is true or false.
4600*67e74705SXin Li #define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) ((NeedAt)? "@" Keyword : Keyword)
4601*67e74705SXin Li
AddObjCImplementationResults(const LangOptions & LangOpts,ResultBuilder & Results,bool NeedAt)4602*67e74705SXin Li static void AddObjCImplementationResults(const LangOptions &LangOpts,
4603*67e74705SXin Li ResultBuilder &Results,
4604*67e74705SXin Li bool NeedAt) {
4605*67e74705SXin Li typedef CodeCompletionResult Result;
4606*67e74705SXin Li // Since we have an implementation, we can end it.
4607*67e74705SXin Li Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end")));
4608*67e74705SXin Li
4609*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
4610*67e74705SXin Li Results.getCodeCompletionTUInfo());
4611*67e74705SXin Li if (LangOpts.ObjC2) {
4612*67e74705SXin Li // @dynamic
4613*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"dynamic"));
4614*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4615*67e74705SXin Li Builder.AddPlaceholderChunk("property");
4616*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4617*67e74705SXin Li
4618*67e74705SXin Li // @synthesize
4619*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synthesize"));
4620*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4621*67e74705SXin Li Builder.AddPlaceholderChunk("property");
4622*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4623*67e74705SXin Li }
4624*67e74705SXin Li }
4625*67e74705SXin Li
AddObjCInterfaceResults(const LangOptions & LangOpts,ResultBuilder & Results,bool NeedAt)4626*67e74705SXin Li static void AddObjCInterfaceResults(const LangOptions &LangOpts,
4627*67e74705SXin Li ResultBuilder &Results,
4628*67e74705SXin Li bool NeedAt) {
4629*67e74705SXin Li typedef CodeCompletionResult Result;
4630*67e74705SXin Li
4631*67e74705SXin Li // Since we have an interface or protocol, we can end it.
4632*67e74705SXin Li Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end")));
4633*67e74705SXin Li
4634*67e74705SXin Li if (LangOpts.ObjC2) {
4635*67e74705SXin Li // @property
4636*67e74705SXin Li Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"property")));
4637*67e74705SXin Li
4638*67e74705SXin Li // @required
4639*67e74705SXin Li Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"required")));
4640*67e74705SXin Li
4641*67e74705SXin Li // @optional
4642*67e74705SXin Li Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"optional")));
4643*67e74705SXin Li }
4644*67e74705SXin Li }
4645*67e74705SXin Li
AddObjCTopLevelResults(ResultBuilder & Results,bool NeedAt)4646*67e74705SXin Li static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
4647*67e74705SXin Li typedef CodeCompletionResult Result;
4648*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
4649*67e74705SXin Li Results.getCodeCompletionTUInfo());
4650*67e74705SXin Li
4651*67e74705SXin Li // @class name ;
4652*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"class"));
4653*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4654*67e74705SXin Li Builder.AddPlaceholderChunk("name");
4655*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4656*67e74705SXin Li
4657*67e74705SXin Li if (Results.includeCodePatterns()) {
4658*67e74705SXin Li // @interface name
4659*67e74705SXin Li // FIXME: Could introduce the whole pattern, including superclasses and
4660*67e74705SXin Li // such.
4661*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"interface"));
4662*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4663*67e74705SXin Li Builder.AddPlaceholderChunk("class");
4664*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4665*67e74705SXin Li
4666*67e74705SXin Li // @protocol name
4667*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol"));
4668*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4669*67e74705SXin Li Builder.AddPlaceholderChunk("protocol");
4670*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4671*67e74705SXin Li
4672*67e74705SXin Li // @implementation name
4673*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"implementation"));
4674*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4675*67e74705SXin Li Builder.AddPlaceholderChunk("class");
4676*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4677*67e74705SXin Li }
4678*67e74705SXin Li
4679*67e74705SXin Li // @compatibility_alias name
4680*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"compatibility_alias"));
4681*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4682*67e74705SXin Li Builder.AddPlaceholderChunk("alias");
4683*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4684*67e74705SXin Li Builder.AddPlaceholderChunk("class");
4685*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4686*67e74705SXin Li
4687*67e74705SXin Li if (Results.getSema().getLangOpts().Modules) {
4688*67e74705SXin Li // @import name
4689*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "import"));
4690*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4691*67e74705SXin Li Builder.AddPlaceholderChunk("module");
4692*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4693*67e74705SXin Li }
4694*67e74705SXin Li }
4695*67e74705SXin Li
CodeCompleteObjCAtDirective(Scope * S)4696*67e74705SXin Li void Sema::CodeCompleteObjCAtDirective(Scope *S) {
4697*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4698*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4699*67e74705SXin Li CodeCompletionContext::CCC_Other);
4700*67e74705SXin Li Results.EnterNewScope();
4701*67e74705SXin Li if (isa<ObjCImplDecl>(CurContext))
4702*67e74705SXin Li AddObjCImplementationResults(getLangOpts(), Results, false);
4703*67e74705SXin Li else if (CurContext->isObjCContainer())
4704*67e74705SXin Li AddObjCInterfaceResults(getLangOpts(), Results, false);
4705*67e74705SXin Li else
4706*67e74705SXin Li AddObjCTopLevelResults(Results, false);
4707*67e74705SXin Li Results.ExitScope();
4708*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4709*67e74705SXin Li CodeCompletionContext::CCC_Other,
4710*67e74705SXin Li Results.data(),Results.size());
4711*67e74705SXin Li }
4712*67e74705SXin Li
AddObjCExpressionResults(ResultBuilder & Results,bool NeedAt)4713*67e74705SXin Li static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
4714*67e74705SXin Li typedef CodeCompletionResult Result;
4715*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
4716*67e74705SXin Li Results.getCodeCompletionTUInfo());
4717*67e74705SXin Li
4718*67e74705SXin Li // @encode ( type-name )
4719*67e74705SXin Li const char *EncodeType = "char[]";
4720*67e74705SXin Li if (Results.getSema().getLangOpts().CPlusPlus ||
4721*67e74705SXin Li Results.getSema().getLangOpts().ConstStrings)
4722*67e74705SXin Li EncodeType = "const char[]";
4723*67e74705SXin Li Builder.AddResultTypeChunk(EncodeType);
4724*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"encode"));
4725*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4726*67e74705SXin Li Builder.AddPlaceholderChunk("type-name");
4727*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4728*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4729*67e74705SXin Li
4730*67e74705SXin Li // @protocol ( protocol-name )
4731*67e74705SXin Li Builder.AddResultTypeChunk("Protocol *");
4732*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol"));
4733*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4734*67e74705SXin Li Builder.AddPlaceholderChunk("protocol-name");
4735*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4736*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4737*67e74705SXin Li
4738*67e74705SXin Li // @selector ( selector )
4739*67e74705SXin Li Builder.AddResultTypeChunk("SEL");
4740*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"selector"));
4741*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4742*67e74705SXin Li Builder.AddPlaceholderChunk("selector");
4743*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4744*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4745*67e74705SXin Li
4746*67e74705SXin Li // @"string"
4747*67e74705SXin Li Builder.AddResultTypeChunk("NSString *");
4748*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"\""));
4749*67e74705SXin Li Builder.AddPlaceholderChunk("string");
4750*67e74705SXin Li Builder.AddTextChunk("\"");
4751*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4752*67e74705SXin Li
4753*67e74705SXin Li // @[objects, ...]
4754*67e74705SXin Li Builder.AddResultTypeChunk("NSArray *");
4755*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"["));
4756*67e74705SXin Li Builder.AddPlaceholderChunk("objects, ...");
4757*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBracket);
4758*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4759*67e74705SXin Li
4760*67e74705SXin Li // @{key : object, ...}
4761*67e74705SXin Li Builder.AddResultTypeChunk("NSDictionary *");
4762*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"{"));
4763*67e74705SXin Li Builder.AddPlaceholderChunk("key");
4764*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Colon);
4765*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4766*67e74705SXin Li Builder.AddPlaceholderChunk("object, ...");
4767*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4768*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4769*67e74705SXin Li
4770*67e74705SXin Li // @(expression)
4771*67e74705SXin Li Builder.AddResultTypeChunk("id");
4772*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "("));
4773*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
4774*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4775*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4776*67e74705SXin Li }
4777*67e74705SXin Li
AddObjCStatementResults(ResultBuilder & Results,bool NeedAt)4778*67e74705SXin Li static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
4779*67e74705SXin Li typedef CodeCompletionResult Result;
4780*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
4781*67e74705SXin Li Results.getCodeCompletionTUInfo());
4782*67e74705SXin Li
4783*67e74705SXin Li if (Results.includeCodePatterns()) {
4784*67e74705SXin Li // @try { statements } @catch ( declaration ) { statements } @finally
4785*67e74705SXin Li // { statements }
4786*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"try"));
4787*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4788*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
4789*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4790*67e74705SXin Li Builder.AddTextChunk("@catch");
4791*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4792*67e74705SXin Li Builder.AddPlaceholderChunk("parameter");
4793*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4794*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4795*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
4796*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4797*67e74705SXin Li Builder.AddTextChunk("@finally");
4798*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4799*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
4800*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4801*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4802*67e74705SXin Li }
4803*67e74705SXin Li
4804*67e74705SXin Li // @throw
4805*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"throw"));
4806*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4807*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
4808*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4809*67e74705SXin Li
4810*67e74705SXin Li if (Results.includeCodePatterns()) {
4811*67e74705SXin Li // @synchronized ( expression ) { statements }
4812*67e74705SXin Li Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synchronized"));
4813*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4814*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4815*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
4816*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
4817*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
4818*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
4819*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
4820*67e74705SXin Li Results.AddResult(Result(Builder.TakeString()));
4821*67e74705SXin Li }
4822*67e74705SXin Li }
4823*67e74705SXin Li
AddObjCVisibilityResults(const LangOptions & LangOpts,ResultBuilder & Results,bool NeedAt)4824*67e74705SXin Li static void AddObjCVisibilityResults(const LangOptions &LangOpts,
4825*67e74705SXin Li ResultBuilder &Results,
4826*67e74705SXin Li bool NeedAt) {
4827*67e74705SXin Li typedef CodeCompletionResult Result;
4828*67e74705SXin Li Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"private")));
4829*67e74705SXin Li Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"protected")));
4830*67e74705SXin Li Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"public")));
4831*67e74705SXin Li if (LangOpts.ObjC2)
4832*67e74705SXin Li Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"package")));
4833*67e74705SXin Li }
4834*67e74705SXin Li
CodeCompleteObjCAtVisibility(Scope * S)4835*67e74705SXin Li void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
4836*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4837*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4838*67e74705SXin Li CodeCompletionContext::CCC_Other);
4839*67e74705SXin Li Results.EnterNewScope();
4840*67e74705SXin Li AddObjCVisibilityResults(getLangOpts(), Results, false);
4841*67e74705SXin Li Results.ExitScope();
4842*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4843*67e74705SXin Li CodeCompletionContext::CCC_Other,
4844*67e74705SXin Li Results.data(),Results.size());
4845*67e74705SXin Li }
4846*67e74705SXin Li
CodeCompleteObjCAtStatement(Scope * S)4847*67e74705SXin Li void Sema::CodeCompleteObjCAtStatement(Scope *S) {
4848*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4849*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4850*67e74705SXin Li CodeCompletionContext::CCC_Other);
4851*67e74705SXin Li Results.EnterNewScope();
4852*67e74705SXin Li AddObjCStatementResults(Results, false);
4853*67e74705SXin Li AddObjCExpressionResults(Results, false);
4854*67e74705SXin Li Results.ExitScope();
4855*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4856*67e74705SXin Li CodeCompletionContext::CCC_Other,
4857*67e74705SXin Li Results.data(),Results.size());
4858*67e74705SXin Li }
4859*67e74705SXin Li
CodeCompleteObjCAtExpression(Scope * S)4860*67e74705SXin Li void Sema::CodeCompleteObjCAtExpression(Scope *S) {
4861*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4862*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4863*67e74705SXin Li CodeCompletionContext::CCC_Other);
4864*67e74705SXin Li Results.EnterNewScope();
4865*67e74705SXin Li AddObjCExpressionResults(Results, false);
4866*67e74705SXin Li Results.ExitScope();
4867*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4868*67e74705SXin Li CodeCompletionContext::CCC_Other,
4869*67e74705SXin Li Results.data(),Results.size());
4870*67e74705SXin Li }
4871*67e74705SXin Li
4872*67e74705SXin Li /// \brief Determine whether the addition of the given flag to an Objective-C
4873*67e74705SXin Li /// property's attributes will cause a conflict.
ObjCPropertyFlagConflicts(unsigned Attributes,unsigned NewFlag)4874*67e74705SXin Li static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
4875*67e74705SXin Li // Check if we've already added this flag.
4876*67e74705SXin Li if (Attributes & NewFlag)
4877*67e74705SXin Li return true;
4878*67e74705SXin Li
4879*67e74705SXin Li Attributes |= NewFlag;
4880*67e74705SXin Li
4881*67e74705SXin Li // Check for collisions with "readonly".
4882*67e74705SXin Li if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
4883*67e74705SXin Li (Attributes & ObjCDeclSpec::DQ_PR_readwrite))
4884*67e74705SXin Li return true;
4885*67e74705SXin Li
4886*67e74705SXin Li // Check for more than one of { assign, copy, retain, strong, weak }.
4887*67e74705SXin Li unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
4888*67e74705SXin Li ObjCDeclSpec::DQ_PR_unsafe_unretained |
4889*67e74705SXin Li ObjCDeclSpec::DQ_PR_copy |
4890*67e74705SXin Li ObjCDeclSpec::DQ_PR_retain |
4891*67e74705SXin Li ObjCDeclSpec::DQ_PR_strong |
4892*67e74705SXin Li ObjCDeclSpec::DQ_PR_weak);
4893*67e74705SXin Li if (AssignCopyRetMask &&
4894*67e74705SXin Li AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
4895*67e74705SXin Li AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained &&
4896*67e74705SXin Li AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
4897*67e74705SXin Li AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain &&
4898*67e74705SXin Li AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong &&
4899*67e74705SXin Li AssignCopyRetMask != ObjCDeclSpec::DQ_PR_weak)
4900*67e74705SXin Li return true;
4901*67e74705SXin Li
4902*67e74705SXin Li return false;
4903*67e74705SXin Li }
4904*67e74705SXin Li
CodeCompleteObjCPropertyFlags(Scope * S,ObjCDeclSpec & ODS)4905*67e74705SXin Li void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
4906*67e74705SXin Li if (!CodeCompleter)
4907*67e74705SXin Li return;
4908*67e74705SXin Li
4909*67e74705SXin Li unsigned Attributes = ODS.getPropertyAttributes();
4910*67e74705SXin Li
4911*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
4912*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
4913*67e74705SXin Li CodeCompletionContext::CCC_Other);
4914*67e74705SXin Li Results.EnterNewScope();
4915*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
4916*67e74705SXin Li Results.AddResult(CodeCompletionResult("readonly"));
4917*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
4918*67e74705SXin Li Results.AddResult(CodeCompletionResult("assign"));
4919*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes,
4920*67e74705SXin Li ObjCDeclSpec::DQ_PR_unsafe_unretained))
4921*67e74705SXin Li Results.AddResult(CodeCompletionResult("unsafe_unretained"));
4922*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
4923*67e74705SXin Li Results.AddResult(CodeCompletionResult("readwrite"));
4924*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
4925*67e74705SXin Li Results.AddResult(CodeCompletionResult("retain"));
4926*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_strong))
4927*67e74705SXin Li Results.AddResult(CodeCompletionResult("strong"));
4928*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
4929*67e74705SXin Li Results.AddResult(CodeCompletionResult("copy"));
4930*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
4931*67e74705SXin Li Results.AddResult(CodeCompletionResult("nonatomic"));
4932*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic))
4933*67e74705SXin Li Results.AddResult(CodeCompletionResult("atomic"));
4934*67e74705SXin Li
4935*67e74705SXin Li // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
4936*67e74705SXin Li if (getLangOpts().ObjCWeak || getLangOpts().getGC() != LangOptions::NonGC)
4937*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak))
4938*67e74705SXin Li Results.AddResult(CodeCompletionResult("weak"));
4939*67e74705SXin Li
4940*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
4941*67e74705SXin Li CodeCompletionBuilder Setter(Results.getAllocator(),
4942*67e74705SXin Li Results.getCodeCompletionTUInfo());
4943*67e74705SXin Li Setter.AddTypedTextChunk("setter");
4944*67e74705SXin Li Setter.AddTextChunk("=");
4945*67e74705SXin Li Setter.AddPlaceholderChunk("method");
4946*67e74705SXin Li Results.AddResult(CodeCompletionResult(Setter.TakeString()));
4947*67e74705SXin Li }
4948*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
4949*67e74705SXin Li CodeCompletionBuilder Getter(Results.getAllocator(),
4950*67e74705SXin Li Results.getCodeCompletionTUInfo());
4951*67e74705SXin Li Getter.AddTypedTextChunk("getter");
4952*67e74705SXin Li Getter.AddTextChunk("=");
4953*67e74705SXin Li Getter.AddPlaceholderChunk("method");
4954*67e74705SXin Li Results.AddResult(CodeCompletionResult(Getter.TakeString()));
4955*67e74705SXin Li }
4956*67e74705SXin Li if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nullability)) {
4957*67e74705SXin Li Results.AddResult(CodeCompletionResult("nonnull"));
4958*67e74705SXin Li Results.AddResult(CodeCompletionResult("nullable"));
4959*67e74705SXin Li Results.AddResult(CodeCompletionResult("null_unspecified"));
4960*67e74705SXin Li Results.AddResult(CodeCompletionResult("null_resettable"));
4961*67e74705SXin Li }
4962*67e74705SXin Li Results.ExitScope();
4963*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
4964*67e74705SXin Li CodeCompletionContext::CCC_Other,
4965*67e74705SXin Li Results.data(),Results.size());
4966*67e74705SXin Li }
4967*67e74705SXin Li
4968*67e74705SXin Li /// \brief Describes the kind of Objective-C method that we want to find
4969*67e74705SXin Li /// via code completion.
4970*67e74705SXin Li enum ObjCMethodKind {
4971*67e74705SXin Li MK_Any, ///< Any kind of method, provided it means other specified criteria.
4972*67e74705SXin Li MK_ZeroArgSelector, ///< Zero-argument (unary) selector.
4973*67e74705SXin Li MK_OneArgSelector ///< One-argument selector.
4974*67e74705SXin Li };
4975*67e74705SXin Li
isAcceptableObjCSelector(Selector Sel,ObjCMethodKind WantKind,ArrayRef<IdentifierInfo * > SelIdents,bool AllowSameLength=true)4976*67e74705SXin Li static bool isAcceptableObjCSelector(Selector Sel,
4977*67e74705SXin Li ObjCMethodKind WantKind,
4978*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents,
4979*67e74705SXin Li bool AllowSameLength = true) {
4980*67e74705SXin Li unsigned NumSelIdents = SelIdents.size();
4981*67e74705SXin Li if (NumSelIdents > Sel.getNumArgs())
4982*67e74705SXin Li return false;
4983*67e74705SXin Li
4984*67e74705SXin Li switch (WantKind) {
4985*67e74705SXin Li case MK_Any: break;
4986*67e74705SXin Li case MK_ZeroArgSelector: return Sel.isUnarySelector();
4987*67e74705SXin Li case MK_OneArgSelector: return Sel.getNumArgs() == 1;
4988*67e74705SXin Li }
4989*67e74705SXin Li
4990*67e74705SXin Li if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
4991*67e74705SXin Li return false;
4992*67e74705SXin Li
4993*67e74705SXin Li for (unsigned I = 0; I != NumSelIdents; ++I)
4994*67e74705SXin Li if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
4995*67e74705SXin Li return false;
4996*67e74705SXin Li
4997*67e74705SXin Li return true;
4998*67e74705SXin Li }
4999*67e74705SXin Li
isAcceptableObjCMethod(ObjCMethodDecl * Method,ObjCMethodKind WantKind,ArrayRef<IdentifierInfo * > SelIdents,bool AllowSameLength=true)5000*67e74705SXin Li static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
5001*67e74705SXin Li ObjCMethodKind WantKind,
5002*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents,
5003*67e74705SXin Li bool AllowSameLength = true) {
5004*67e74705SXin Li return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
5005*67e74705SXin Li AllowSameLength);
5006*67e74705SXin Li }
5007*67e74705SXin Li
5008*67e74705SXin Li namespace {
5009*67e74705SXin Li /// \brief A set of selectors, which is used to avoid introducing multiple
5010*67e74705SXin Li /// completions with the same selector into the result set.
5011*67e74705SXin Li typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
5012*67e74705SXin Li }
5013*67e74705SXin Li
5014*67e74705SXin Li /// \brief Add all of the Objective-C methods in the given Objective-C
5015*67e74705SXin Li /// container to the set of results.
5016*67e74705SXin Li ///
5017*67e74705SXin Li /// The container will be a class, protocol, category, or implementation of
5018*67e74705SXin Li /// any of the above. This mether will recurse to include methods from
5019*67e74705SXin Li /// the superclasses of classes along with their categories, protocols, and
5020*67e74705SXin Li /// implementations.
5021*67e74705SXin Li ///
5022*67e74705SXin Li /// \param Container the container in which we'll look to find methods.
5023*67e74705SXin Li ///
5024*67e74705SXin Li /// \param WantInstanceMethods Whether to add instance methods (only); if
5025*67e74705SXin Li /// false, this routine will add factory methods (only).
5026*67e74705SXin Li ///
5027*67e74705SXin Li /// \param CurContext the context in which we're performing the lookup that
5028*67e74705SXin Li /// finds methods.
5029*67e74705SXin Li ///
5030*67e74705SXin Li /// \param AllowSameLength Whether we allow a method to be added to the list
5031*67e74705SXin Li /// when it has the same number of parameters as we have selector identifiers.
5032*67e74705SXin Li ///
5033*67e74705SXin Li /// \param Results the structure into which we'll add results.
AddObjCMethods(ObjCContainerDecl * Container,bool WantInstanceMethods,ObjCMethodKind WantKind,ArrayRef<IdentifierInfo * > SelIdents,DeclContext * CurContext,VisitedSelectorSet & Selectors,bool AllowSameLength,ResultBuilder & Results,bool InOriginalClass=true)5034*67e74705SXin Li static void AddObjCMethods(ObjCContainerDecl *Container,
5035*67e74705SXin Li bool WantInstanceMethods,
5036*67e74705SXin Li ObjCMethodKind WantKind,
5037*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents,
5038*67e74705SXin Li DeclContext *CurContext,
5039*67e74705SXin Li VisitedSelectorSet &Selectors,
5040*67e74705SXin Li bool AllowSameLength,
5041*67e74705SXin Li ResultBuilder &Results,
5042*67e74705SXin Li bool InOriginalClass = true) {
5043*67e74705SXin Li typedef CodeCompletionResult Result;
5044*67e74705SXin Li Container = getContainerDef(Container);
5045*67e74705SXin Li ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
5046*67e74705SXin Li bool isRootClass = IFace && !IFace->getSuperClass();
5047*67e74705SXin Li for (auto *M : Container->methods()) {
5048*67e74705SXin Li // The instance methods on the root class can be messaged via the
5049*67e74705SXin Li // metaclass.
5050*67e74705SXin Li if (M->isInstanceMethod() == WantInstanceMethods ||
5051*67e74705SXin Li (isRootClass && !WantInstanceMethods)) {
5052*67e74705SXin Li // Check whether the selector identifiers we've been given are a
5053*67e74705SXin Li // subset of the identifiers for this particular method.
5054*67e74705SXin Li if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength))
5055*67e74705SXin Li continue;
5056*67e74705SXin Li
5057*67e74705SXin Li if (!Selectors.insert(M->getSelector()).second)
5058*67e74705SXin Li continue;
5059*67e74705SXin Li
5060*67e74705SXin Li Result R = Result(M, Results.getBasePriority(M), nullptr);
5061*67e74705SXin Li R.StartParameter = SelIdents.size();
5062*67e74705SXin Li R.AllParametersAreInformative = (WantKind != MK_Any);
5063*67e74705SXin Li if (!InOriginalClass)
5064*67e74705SXin Li R.Priority += CCD_InBaseClass;
5065*67e74705SXin Li Results.MaybeAddResult(R, CurContext);
5066*67e74705SXin Li }
5067*67e74705SXin Li }
5068*67e74705SXin Li
5069*67e74705SXin Li // Visit the protocols of protocols.
5070*67e74705SXin Li if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5071*67e74705SXin Li if (Protocol->hasDefinition()) {
5072*67e74705SXin Li const ObjCList<ObjCProtocolDecl> &Protocols
5073*67e74705SXin Li = Protocol->getReferencedProtocols();
5074*67e74705SXin Li for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
5075*67e74705SXin Li E = Protocols.end();
5076*67e74705SXin Li I != E; ++I)
5077*67e74705SXin Li AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
5078*67e74705SXin Li CurContext, Selectors, AllowSameLength, Results, false);
5079*67e74705SXin Li }
5080*67e74705SXin Li }
5081*67e74705SXin Li
5082*67e74705SXin Li if (!IFace || !IFace->hasDefinition())
5083*67e74705SXin Li return;
5084*67e74705SXin Li
5085*67e74705SXin Li // Add methods in protocols.
5086*67e74705SXin Li for (auto *I : IFace->protocols())
5087*67e74705SXin Li AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents,
5088*67e74705SXin Li CurContext, Selectors, AllowSameLength, Results, false);
5089*67e74705SXin Li
5090*67e74705SXin Li // Add methods in categories.
5091*67e74705SXin Li for (auto *CatDecl : IFace->known_categories()) {
5092*67e74705SXin Li AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
5093*67e74705SXin Li CurContext, Selectors, AllowSameLength,
5094*67e74705SXin Li Results, InOriginalClass);
5095*67e74705SXin Li
5096*67e74705SXin Li // Add a categories protocol methods.
5097*67e74705SXin Li const ObjCList<ObjCProtocolDecl> &Protocols
5098*67e74705SXin Li = CatDecl->getReferencedProtocols();
5099*67e74705SXin Li for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
5100*67e74705SXin Li E = Protocols.end();
5101*67e74705SXin Li I != E; ++I)
5102*67e74705SXin Li AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
5103*67e74705SXin Li CurContext, Selectors, AllowSameLength,
5104*67e74705SXin Li Results, false);
5105*67e74705SXin Li
5106*67e74705SXin Li // Add methods in category implementations.
5107*67e74705SXin Li if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
5108*67e74705SXin Li AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
5109*67e74705SXin Li CurContext, Selectors, AllowSameLength,
5110*67e74705SXin Li Results, InOriginalClass);
5111*67e74705SXin Li }
5112*67e74705SXin Li
5113*67e74705SXin Li // Add methods in superclass.
5114*67e74705SXin Li if (IFace->getSuperClass())
5115*67e74705SXin Li AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
5116*67e74705SXin Li SelIdents, CurContext, Selectors,
5117*67e74705SXin Li AllowSameLength, Results, false);
5118*67e74705SXin Li
5119*67e74705SXin Li // Add methods in our implementation, if any.
5120*67e74705SXin Li if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5121*67e74705SXin Li AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
5122*67e74705SXin Li CurContext, Selectors, AllowSameLength,
5123*67e74705SXin Li Results, InOriginalClass);
5124*67e74705SXin Li }
5125*67e74705SXin Li
5126*67e74705SXin Li
CodeCompleteObjCPropertyGetter(Scope * S)5127*67e74705SXin Li void Sema::CodeCompleteObjCPropertyGetter(Scope *S) {
5128*67e74705SXin Li // Try to find the interface where getters might live.
5129*67e74705SXin Li ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
5130*67e74705SXin Li if (!Class) {
5131*67e74705SXin Li if (ObjCCategoryDecl *Category
5132*67e74705SXin Li = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
5133*67e74705SXin Li Class = Category->getClassInterface();
5134*67e74705SXin Li
5135*67e74705SXin Li if (!Class)
5136*67e74705SXin Li return;
5137*67e74705SXin Li }
5138*67e74705SXin Li
5139*67e74705SXin Li // Find all of the potential getters.
5140*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5141*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
5142*67e74705SXin Li CodeCompletionContext::CCC_Other);
5143*67e74705SXin Li Results.EnterNewScope();
5144*67e74705SXin Li
5145*67e74705SXin Li VisitedSelectorSet Selectors;
5146*67e74705SXin Li AddObjCMethods(Class, true, MK_ZeroArgSelector, None, CurContext, Selectors,
5147*67e74705SXin Li /*AllowSameLength=*/true, Results);
5148*67e74705SXin Li Results.ExitScope();
5149*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
5150*67e74705SXin Li CodeCompletionContext::CCC_Other,
5151*67e74705SXin Li Results.data(),Results.size());
5152*67e74705SXin Li }
5153*67e74705SXin Li
CodeCompleteObjCPropertySetter(Scope * S)5154*67e74705SXin Li void Sema::CodeCompleteObjCPropertySetter(Scope *S) {
5155*67e74705SXin Li // Try to find the interface where setters might live.
5156*67e74705SXin Li ObjCInterfaceDecl *Class
5157*67e74705SXin Li = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext);
5158*67e74705SXin Li if (!Class) {
5159*67e74705SXin Li if (ObjCCategoryDecl *Category
5160*67e74705SXin Li = dyn_cast_or_null<ObjCCategoryDecl>(CurContext))
5161*67e74705SXin Li Class = Category->getClassInterface();
5162*67e74705SXin Li
5163*67e74705SXin Li if (!Class)
5164*67e74705SXin Li return;
5165*67e74705SXin Li }
5166*67e74705SXin Li
5167*67e74705SXin Li // Find all of the potential getters.
5168*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5169*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
5170*67e74705SXin Li CodeCompletionContext::CCC_Other);
5171*67e74705SXin Li Results.EnterNewScope();
5172*67e74705SXin Li
5173*67e74705SXin Li VisitedSelectorSet Selectors;
5174*67e74705SXin Li AddObjCMethods(Class, true, MK_OneArgSelector, None, CurContext,
5175*67e74705SXin Li Selectors, /*AllowSameLength=*/true, Results);
5176*67e74705SXin Li
5177*67e74705SXin Li Results.ExitScope();
5178*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
5179*67e74705SXin Li CodeCompletionContext::CCC_Other,
5180*67e74705SXin Li Results.data(),Results.size());
5181*67e74705SXin Li }
5182*67e74705SXin Li
CodeCompleteObjCPassingType(Scope * S,ObjCDeclSpec & DS,bool IsParameter)5183*67e74705SXin Li void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
5184*67e74705SXin Li bool IsParameter) {
5185*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5186*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
5187*67e74705SXin Li CodeCompletionContext::CCC_Type);
5188*67e74705SXin Li Results.EnterNewScope();
5189*67e74705SXin Li
5190*67e74705SXin Li // Add context-sensitive, Objective-C parameter-passing keywords.
5191*67e74705SXin Li bool AddedInOut = false;
5192*67e74705SXin Li if ((DS.getObjCDeclQualifier() &
5193*67e74705SXin Li (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
5194*67e74705SXin Li Results.AddResult("in");
5195*67e74705SXin Li Results.AddResult("inout");
5196*67e74705SXin Li AddedInOut = true;
5197*67e74705SXin Li }
5198*67e74705SXin Li if ((DS.getObjCDeclQualifier() &
5199*67e74705SXin Li (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
5200*67e74705SXin Li Results.AddResult("out");
5201*67e74705SXin Li if (!AddedInOut)
5202*67e74705SXin Li Results.AddResult("inout");
5203*67e74705SXin Li }
5204*67e74705SXin Li if ((DS.getObjCDeclQualifier() &
5205*67e74705SXin Li (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
5206*67e74705SXin Li ObjCDeclSpec::DQ_Oneway)) == 0) {
5207*67e74705SXin Li Results.AddResult("bycopy");
5208*67e74705SXin Li Results.AddResult("byref");
5209*67e74705SXin Li Results.AddResult("oneway");
5210*67e74705SXin Li }
5211*67e74705SXin Li if ((DS.getObjCDeclQualifier() & ObjCDeclSpec::DQ_CSNullability) == 0) {
5212*67e74705SXin Li Results.AddResult("nonnull");
5213*67e74705SXin Li Results.AddResult("nullable");
5214*67e74705SXin Li Results.AddResult("null_unspecified");
5215*67e74705SXin Li }
5216*67e74705SXin Li
5217*67e74705SXin Li // If we're completing the return type of an Objective-C method and the
5218*67e74705SXin Li // identifier IBAction refers to a macro, provide a completion item for
5219*67e74705SXin Li // an action, e.g.,
5220*67e74705SXin Li // IBAction)<#selector#>:(id)sender
5221*67e74705SXin Li if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
5222*67e74705SXin Li PP.isMacroDefined("IBAction")) {
5223*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
5224*67e74705SXin Li Results.getCodeCompletionTUInfo(),
5225*67e74705SXin Li CCP_CodePattern, CXAvailability_Available);
5226*67e74705SXin Li Builder.AddTypedTextChunk("IBAction");
5227*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
5228*67e74705SXin Li Builder.AddPlaceholderChunk("selector");
5229*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Colon);
5230*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
5231*67e74705SXin Li Builder.AddTextChunk("id");
5232*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
5233*67e74705SXin Li Builder.AddTextChunk("sender");
5234*67e74705SXin Li Results.AddResult(CodeCompletionResult(Builder.TakeString()));
5235*67e74705SXin Li }
5236*67e74705SXin Li
5237*67e74705SXin Li // If we're completing the return type, provide 'instancetype'.
5238*67e74705SXin Li if (!IsParameter) {
5239*67e74705SXin Li Results.AddResult(CodeCompletionResult("instancetype"));
5240*67e74705SXin Li }
5241*67e74705SXin Li
5242*67e74705SXin Li // Add various builtin type names and specifiers.
5243*67e74705SXin Li AddOrdinaryNameResults(PCC_Type, S, *this, Results);
5244*67e74705SXin Li Results.ExitScope();
5245*67e74705SXin Li
5246*67e74705SXin Li // Add the various type names
5247*67e74705SXin Li Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
5248*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
5249*67e74705SXin Li LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5250*67e74705SXin Li CodeCompleter->includeGlobals());
5251*67e74705SXin Li
5252*67e74705SXin Li if (CodeCompleter->includeMacros())
5253*67e74705SXin Li AddMacroResults(PP, Results, false);
5254*67e74705SXin Li
5255*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
5256*67e74705SXin Li CodeCompletionContext::CCC_Type,
5257*67e74705SXin Li Results.data(), Results.size());
5258*67e74705SXin Li }
5259*67e74705SXin Li
5260*67e74705SXin Li /// \brief When we have an expression with type "id", we may assume
5261*67e74705SXin Li /// that it has some more-specific class type based on knowledge of
5262*67e74705SXin Li /// common uses of Objective-C. This routine returns that class type,
5263*67e74705SXin Li /// or NULL if no better result could be determined.
GetAssumedMessageSendExprType(Expr * E)5264*67e74705SXin Li static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
5265*67e74705SXin Li ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
5266*67e74705SXin Li if (!Msg)
5267*67e74705SXin Li return nullptr;
5268*67e74705SXin Li
5269*67e74705SXin Li Selector Sel = Msg->getSelector();
5270*67e74705SXin Li if (Sel.isNull())
5271*67e74705SXin Li return nullptr;
5272*67e74705SXin Li
5273*67e74705SXin Li IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
5274*67e74705SXin Li if (!Id)
5275*67e74705SXin Li return nullptr;
5276*67e74705SXin Li
5277*67e74705SXin Li ObjCMethodDecl *Method = Msg->getMethodDecl();
5278*67e74705SXin Li if (!Method)
5279*67e74705SXin Li return nullptr;
5280*67e74705SXin Li
5281*67e74705SXin Li // Determine the class that we're sending the message to.
5282*67e74705SXin Li ObjCInterfaceDecl *IFace = nullptr;
5283*67e74705SXin Li switch (Msg->getReceiverKind()) {
5284*67e74705SXin Li case ObjCMessageExpr::Class:
5285*67e74705SXin Li if (const ObjCObjectType *ObjType
5286*67e74705SXin Li = Msg->getClassReceiver()->getAs<ObjCObjectType>())
5287*67e74705SXin Li IFace = ObjType->getInterface();
5288*67e74705SXin Li break;
5289*67e74705SXin Li
5290*67e74705SXin Li case ObjCMessageExpr::Instance: {
5291*67e74705SXin Li QualType T = Msg->getInstanceReceiver()->getType();
5292*67e74705SXin Li if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
5293*67e74705SXin Li IFace = Ptr->getInterfaceDecl();
5294*67e74705SXin Li break;
5295*67e74705SXin Li }
5296*67e74705SXin Li
5297*67e74705SXin Li case ObjCMessageExpr::SuperInstance:
5298*67e74705SXin Li case ObjCMessageExpr::SuperClass:
5299*67e74705SXin Li break;
5300*67e74705SXin Li }
5301*67e74705SXin Li
5302*67e74705SXin Li if (!IFace)
5303*67e74705SXin Li return nullptr;
5304*67e74705SXin Li
5305*67e74705SXin Li ObjCInterfaceDecl *Super = IFace->getSuperClass();
5306*67e74705SXin Li if (Method->isInstanceMethod())
5307*67e74705SXin Li return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
5308*67e74705SXin Li .Case("retain", IFace)
5309*67e74705SXin Li .Case("strong", IFace)
5310*67e74705SXin Li .Case("autorelease", IFace)
5311*67e74705SXin Li .Case("copy", IFace)
5312*67e74705SXin Li .Case("copyWithZone", IFace)
5313*67e74705SXin Li .Case("mutableCopy", IFace)
5314*67e74705SXin Li .Case("mutableCopyWithZone", IFace)
5315*67e74705SXin Li .Case("awakeFromCoder", IFace)
5316*67e74705SXin Li .Case("replacementObjectFromCoder", IFace)
5317*67e74705SXin Li .Case("class", IFace)
5318*67e74705SXin Li .Case("classForCoder", IFace)
5319*67e74705SXin Li .Case("superclass", Super)
5320*67e74705SXin Li .Default(nullptr);
5321*67e74705SXin Li
5322*67e74705SXin Li return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
5323*67e74705SXin Li .Case("new", IFace)
5324*67e74705SXin Li .Case("alloc", IFace)
5325*67e74705SXin Li .Case("allocWithZone", IFace)
5326*67e74705SXin Li .Case("class", IFace)
5327*67e74705SXin Li .Case("superclass", Super)
5328*67e74705SXin Li .Default(nullptr);
5329*67e74705SXin Li }
5330*67e74705SXin Li
5331*67e74705SXin Li // Add a special completion for a message send to "super", which fills in the
5332*67e74705SXin Li // most likely case of forwarding all of our arguments to the superclass
5333*67e74705SXin Li // function.
5334*67e74705SXin Li ///
5335*67e74705SXin Li /// \param S The semantic analysis object.
5336*67e74705SXin Li ///
5337*67e74705SXin Li /// \param NeedSuperKeyword Whether we need to prefix this completion with
5338*67e74705SXin Li /// the "super" keyword. Otherwise, we just need to provide the arguments.
5339*67e74705SXin Li ///
5340*67e74705SXin Li /// \param SelIdents The identifiers in the selector that have already been
5341*67e74705SXin Li /// provided as arguments for a send to "super".
5342*67e74705SXin Li ///
5343*67e74705SXin Li /// \param Results The set of results to augment.
5344*67e74705SXin Li ///
5345*67e74705SXin Li /// \returns the Objective-C method declaration that would be invoked by
5346*67e74705SXin Li /// this "super" completion. If NULL, no completion was added.
AddSuperSendCompletion(Sema & S,bool NeedSuperKeyword,ArrayRef<IdentifierInfo * > SelIdents,ResultBuilder & Results)5347*67e74705SXin Li static ObjCMethodDecl *AddSuperSendCompletion(
5348*67e74705SXin Li Sema &S, bool NeedSuperKeyword,
5349*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents,
5350*67e74705SXin Li ResultBuilder &Results) {
5351*67e74705SXin Li ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
5352*67e74705SXin Li if (!CurMethod)
5353*67e74705SXin Li return nullptr;
5354*67e74705SXin Li
5355*67e74705SXin Li ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
5356*67e74705SXin Li if (!Class)
5357*67e74705SXin Li return nullptr;
5358*67e74705SXin Li
5359*67e74705SXin Li // Try to find a superclass method with the same selector.
5360*67e74705SXin Li ObjCMethodDecl *SuperMethod = nullptr;
5361*67e74705SXin Li while ((Class = Class->getSuperClass()) && !SuperMethod) {
5362*67e74705SXin Li // Check in the class
5363*67e74705SXin Li SuperMethod = Class->getMethod(CurMethod->getSelector(),
5364*67e74705SXin Li CurMethod->isInstanceMethod());
5365*67e74705SXin Li
5366*67e74705SXin Li // Check in categories or class extensions.
5367*67e74705SXin Li if (!SuperMethod) {
5368*67e74705SXin Li for (const auto *Cat : Class->known_categories()) {
5369*67e74705SXin Li if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(),
5370*67e74705SXin Li CurMethod->isInstanceMethod())))
5371*67e74705SXin Li break;
5372*67e74705SXin Li }
5373*67e74705SXin Li }
5374*67e74705SXin Li }
5375*67e74705SXin Li
5376*67e74705SXin Li if (!SuperMethod)
5377*67e74705SXin Li return nullptr;
5378*67e74705SXin Li
5379*67e74705SXin Li // Check whether the superclass method has the same signature.
5380*67e74705SXin Li if (CurMethod->param_size() != SuperMethod->param_size() ||
5381*67e74705SXin Li CurMethod->isVariadic() != SuperMethod->isVariadic())
5382*67e74705SXin Li return nullptr;
5383*67e74705SXin Li
5384*67e74705SXin Li for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
5385*67e74705SXin Li CurPEnd = CurMethod->param_end(),
5386*67e74705SXin Li SuperP = SuperMethod->param_begin();
5387*67e74705SXin Li CurP != CurPEnd; ++CurP, ++SuperP) {
5388*67e74705SXin Li // Make sure the parameter types are compatible.
5389*67e74705SXin Li if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
5390*67e74705SXin Li (*SuperP)->getType()))
5391*67e74705SXin Li return nullptr;
5392*67e74705SXin Li
5393*67e74705SXin Li // Make sure we have a parameter name to forward!
5394*67e74705SXin Li if (!(*CurP)->getIdentifier())
5395*67e74705SXin Li return nullptr;
5396*67e74705SXin Li }
5397*67e74705SXin Li
5398*67e74705SXin Li // We have a superclass method. Now, form the send-to-super completion.
5399*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
5400*67e74705SXin Li Results.getCodeCompletionTUInfo());
5401*67e74705SXin Li
5402*67e74705SXin Li // Give this completion a return type.
5403*67e74705SXin Li AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod,
5404*67e74705SXin Li Results.getCompletionContext().getBaseType(),
5405*67e74705SXin Li Builder);
5406*67e74705SXin Li
5407*67e74705SXin Li // If we need the "super" keyword, add it (plus some spacing).
5408*67e74705SXin Li if (NeedSuperKeyword) {
5409*67e74705SXin Li Builder.AddTypedTextChunk("super");
5410*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5411*67e74705SXin Li }
5412*67e74705SXin Li
5413*67e74705SXin Li Selector Sel = CurMethod->getSelector();
5414*67e74705SXin Li if (Sel.isUnarySelector()) {
5415*67e74705SXin Li if (NeedSuperKeyword)
5416*67e74705SXin Li Builder.AddTextChunk(Builder.getAllocator().CopyString(
5417*67e74705SXin Li Sel.getNameForSlot(0)));
5418*67e74705SXin Li else
5419*67e74705SXin Li Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
5420*67e74705SXin Li Sel.getNameForSlot(0)));
5421*67e74705SXin Li } else {
5422*67e74705SXin Li ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
5423*67e74705SXin Li for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
5424*67e74705SXin Li if (I > SelIdents.size())
5425*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
5426*67e74705SXin Li
5427*67e74705SXin Li if (I < SelIdents.size())
5428*67e74705SXin Li Builder.AddInformativeChunk(
5429*67e74705SXin Li Builder.getAllocator().CopyString(
5430*67e74705SXin Li Sel.getNameForSlot(I) + ":"));
5431*67e74705SXin Li else if (NeedSuperKeyword || I > SelIdents.size()) {
5432*67e74705SXin Li Builder.AddTextChunk(
5433*67e74705SXin Li Builder.getAllocator().CopyString(
5434*67e74705SXin Li Sel.getNameForSlot(I) + ":"));
5435*67e74705SXin Li Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
5436*67e74705SXin Li (*CurP)->getIdentifier()->getName()));
5437*67e74705SXin Li } else {
5438*67e74705SXin Li Builder.AddTypedTextChunk(
5439*67e74705SXin Li Builder.getAllocator().CopyString(
5440*67e74705SXin Li Sel.getNameForSlot(I) + ":"));
5441*67e74705SXin Li Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
5442*67e74705SXin Li (*CurP)->getIdentifier()->getName()));
5443*67e74705SXin Li }
5444*67e74705SXin Li }
5445*67e74705SXin Li }
5446*67e74705SXin Li
5447*67e74705SXin Li Results.AddResult(CodeCompletionResult(Builder.TakeString(), SuperMethod,
5448*67e74705SXin Li CCP_SuperCompletion));
5449*67e74705SXin Li return SuperMethod;
5450*67e74705SXin Li }
5451*67e74705SXin Li
CodeCompleteObjCMessageReceiver(Scope * S)5452*67e74705SXin Li void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
5453*67e74705SXin Li typedef CodeCompletionResult Result;
5454*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5455*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
5456*67e74705SXin Li CodeCompletionContext::CCC_ObjCMessageReceiver,
5457*67e74705SXin Li getLangOpts().CPlusPlus11
5458*67e74705SXin Li ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
5459*67e74705SXin Li : &ResultBuilder::IsObjCMessageReceiver);
5460*67e74705SXin Li
5461*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Results, CurContext);
5462*67e74705SXin Li Results.EnterNewScope();
5463*67e74705SXin Li LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
5464*67e74705SXin Li CodeCompleter->includeGlobals());
5465*67e74705SXin Li
5466*67e74705SXin Li // If we are in an Objective-C method inside a class that has a superclass,
5467*67e74705SXin Li // add "super" as an option.
5468*67e74705SXin Li if (ObjCMethodDecl *Method = getCurMethodDecl())
5469*67e74705SXin Li if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
5470*67e74705SXin Li if (Iface->getSuperClass()) {
5471*67e74705SXin Li Results.AddResult(Result("super"));
5472*67e74705SXin Li
5473*67e74705SXin Li AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, None, Results);
5474*67e74705SXin Li }
5475*67e74705SXin Li
5476*67e74705SXin Li if (getLangOpts().CPlusPlus11)
5477*67e74705SXin Li addThisCompletion(*this, Results);
5478*67e74705SXin Li
5479*67e74705SXin Li Results.ExitScope();
5480*67e74705SXin Li
5481*67e74705SXin Li if (CodeCompleter->includeMacros())
5482*67e74705SXin Li AddMacroResults(PP, Results, false);
5483*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
5484*67e74705SXin Li Results.data(), Results.size());
5485*67e74705SXin Li
5486*67e74705SXin Li }
5487*67e74705SXin Li
CodeCompleteObjCSuperMessage(Scope * S,SourceLocation SuperLoc,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression)5488*67e74705SXin Li void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
5489*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents,
5490*67e74705SXin Li bool AtArgumentExpression) {
5491*67e74705SXin Li ObjCInterfaceDecl *CDecl = nullptr;
5492*67e74705SXin Li if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
5493*67e74705SXin Li // Figure out which interface we're in.
5494*67e74705SXin Li CDecl = CurMethod->getClassInterface();
5495*67e74705SXin Li if (!CDecl)
5496*67e74705SXin Li return;
5497*67e74705SXin Li
5498*67e74705SXin Li // Find the superclass of this class.
5499*67e74705SXin Li CDecl = CDecl->getSuperClass();
5500*67e74705SXin Li if (!CDecl)
5501*67e74705SXin Li return;
5502*67e74705SXin Li
5503*67e74705SXin Li if (CurMethod->isInstanceMethod()) {
5504*67e74705SXin Li // We are inside an instance method, which means that the message
5505*67e74705SXin Li // send [super ...] is actually calling an instance method on the
5506*67e74705SXin Li // current object.
5507*67e74705SXin Li return CodeCompleteObjCInstanceMessage(S, nullptr, SelIdents,
5508*67e74705SXin Li AtArgumentExpression,
5509*67e74705SXin Li CDecl);
5510*67e74705SXin Li }
5511*67e74705SXin Li
5512*67e74705SXin Li // Fall through to send to the superclass in CDecl.
5513*67e74705SXin Li } else {
5514*67e74705SXin Li // "super" may be the name of a type or variable. Figure out which
5515*67e74705SXin Li // it is.
5516*67e74705SXin Li IdentifierInfo *Super = getSuperIdentifier();
5517*67e74705SXin Li NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
5518*67e74705SXin Li LookupOrdinaryName);
5519*67e74705SXin Li if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
5520*67e74705SXin Li // "super" names an interface. Use it.
5521*67e74705SXin Li } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
5522*67e74705SXin Li if (const ObjCObjectType *Iface
5523*67e74705SXin Li = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
5524*67e74705SXin Li CDecl = Iface->getInterface();
5525*67e74705SXin Li } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
5526*67e74705SXin Li // "super" names an unresolved type; we can't be more specific.
5527*67e74705SXin Li } else {
5528*67e74705SXin Li // Assume that "super" names some kind of value and parse that way.
5529*67e74705SXin Li CXXScopeSpec SS;
5530*67e74705SXin Li SourceLocation TemplateKWLoc;
5531*67e74705SXin Li UnqualifiedId id;
5532*67e74705SXin Li id.setIdentifier(Super, SuperLoc);
5533*67e74705SXin Li ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id,
5534*67e74705SXin Li false, false);
5535*67e74705SXin Li return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
5536*67e74705SXin Li SelIdents,
5537*67e74705SXin Li AtArgumentExpression);
5538*67e74705SXin Li }
5539*67e74705SXin Li
5540*67e74705SXin Li // Fall through
5541*67e74705SXin Li }
5542*67e74705SXin Li
5543*67e74705SXin Li ParsedType Receiver;
5544*67e74705SXin Li if (CDecl)
5545*67e74705SXin Li Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
5546*67e74705SXin Li return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
5547*67e74705SXin Li AtArgumentExpression,
5548*67e74705SXin Li /*IsSuper=*/true);
5549*67e74705SXin Li }
5550*67e74705SXin Li
5551*67e74705SXin Li /// \brief Given a set of code-completion results for the argument of a message
5552*67e74705SXin Li /// send, determine the preferred type (if any) for that argument expression.
getPreferredArgumentTypeForMessageSend(ResultBuilder & Results,unsigned NumSelIdents)5553*67e74705SXin Li static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
5554*67e74705SXin Li unsigned NumSelIdents) {
5555*67e74705SXin Li typedef CodeCompletionResult Result;
5556*67e74705SXin Li ASTContext &Context = Results.getSema().Context;
5557*67e74705SXin Li
5558*67e74705SXin Li QualType PreferredType;
5559*67e74705SXin Li unsigned BestPriority = CCP_Unlikely * 2;
5560*67e74705SXin Li Result *ResultsData = Results.data();
5561*67e74705SXin Li for (unsigned I = 0, N = Results.size(); I != N; ++I) {
5562*67e74705SXin Li Result &R = ResultsData[I];
5563*67e74705SXin Li if (R.Kind == Result::RK_Declaration &&
5564*67e74705SXin Li isa<ObjCMethodDecl>(R.Declaration)) {
5565*67e74705SXin Li if (R.Priority <= BestPriority) {
5566*67e74705SXin Li const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
5567*67e74705SXin Li if (NumSelIdents <= Method->param_size()) {
5568*67e74705SXin Li QualType MyPreferredType = Method->parameters()[NumSelIdents - 1]
5569*67e74705SXin Li ->getType();
5570*67e74705SXin Li if (R.Priority < BestPriority || PreferredType.isNull()) {
5571*67e74705SXin Li BestPriority = R.Priority;
5572*67e74705SXin Li PreferredType = MyPreferredType;
5573*67e74705SXin Li } else if (!Context.hasSameUnqualifiedType(PreferredType,
5574*67e74705SXin Li MyPreferredType)) {
5575*67e74705SXin Li PreferredType = QualType();
5576*67e74705SXin Li }
5577*67e74705SXin Li }
5578*67e74705SXin Li }
5579*67e74705SXin Li }
5580*67e74705SXin Li }
5581*67e74705SXin Li
5582*67e74705SXin Li return PreferredType;
5583*67e74705SXin Li }
5584*67e74705SXin Li
AddClassMessageCompletions(Sema & SemaRef,Scope * S,ParsedType Receiver,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression,bool IsSuper,ResultBuilder & Results)5585*67e74705SXin Li static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
5586*67e74705SXin Li ParsedType Receiver,
5587*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents,
5588*67e74705SXin Li bool AtArgumentExpression,
5589*67e74705SXin Li bool IsSuper,
5590*67e74705SXin Li ResultBuilder &Results) {
5591*67e74705SXin Li typedef CodeCompletionResult Result;
5592*67e74705SXin Li ObjCInterfaceDecl *CDecl = nullptr;
5593*67e74705SXin Li
5594*67e74705SXin Li // If the given name refers to an interface type, retrieve the
5595*67e74705SXin Li // corresponding declaration.
5596*67e74705SXin Li if (Receiver) {
5597*67e74705SXin Li QualType T = SemaRef.GetTypeFromParser(Receiver, nullptr);
5598*67e74705SXin Li if (!T.isNull())
5599*67e74705SXin Li if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
5600*67e74705SXin Li CDecl = Interface->getInterface();
5601*67e74705SXin Li }
5602*67e74705SXin Li
5603*67e74705SXin Li // Add all of the factory methods in this Objective-C class, its protocols,
5604*67e74705SXin Li // superclasses, categories, implementation, etc.
5605*67e74705SXin Li Results.EnterNewScope();
5606*67e74705SXin Li
5607*67e74705SXin Li // If this is a send-to-super, try to add the special "super" send
5608*67e74705SXin Li // completion.
5609*67e74705SXin Li if (IsSuper) {
5610*67e74705SXin Li if (ObjCMethodDecl *SuperMethod
5611*67e74705SXin Li = AddSuperSendCompletion(SemaRef, false, SelIdents, Results))
5612*67e74705SXin Li Results.Ignore(SuperMethod);
5613*67e74705SXin Li }
5614*67e74705SXin Li
5615*67e74705SXin Li // If we're inside an Objective-C method definition, prefer its selector to
5616*67e74705SXin Li // others.
5617*67e74705SXin Li if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
5618*67e74705SXin Li Results.setPreferredSelector(CurMethod->getSelector());
5619*67e74705SXin Li
5620*67e74705SXin Li VisitedSelectorSet Selectors;
5621*67e74705SXin Li if (CDecl)
5622*67e74705SXin Li AddObjCMethods(CDecl, false, MK_Any, SelIdents,
5623*67e74705SXin Li SemaRef.CurContext, Selectors, AtArgumentExpression,
5624*67e74705SXin Li Results);
5625*67e74705SXin Li else {
5626*67e74705SXin Li // We're messaging "id" as a type; provide all class/factory methods.
5627*67e74705SXin Li
5628*67e74705SXin Li // If we have an external source, load the entire class method
5629*67e74705SXin Li // pool from the AST file.
5630*67e74705SXin Li if (SemaRef.getExternalSource()) {
5631*67e74705SXin Li for (uint32_t I = 0,
5632*67e74705SXin Li N = SemaRef.getExternalSource()->GetNumExternalSelectors();
5633*67e74705SXin Li I != N; ++I) {
5634*67e74705SXin Li Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I);
5635*67e74705SXin Li if (Sel.isNull() || SemaRef.MethodPool.count(Sel))
5636*67e74705SXin Li continue;
5637*67e74705SXin Li
5638*67e74705SXin Li SemaRef.ReadMethodPool(Sel);
5639*67e74705SXin Li }
5640*67e74705SXin Li }
5641*67e74705SXin Li
5642*67e74705SXin Li for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(),
5643*67e74705SXin Li MEnd = SemaRef.MethodPool.end();
5644*67e74705SXin Li M != MEnd; ++M) {
5645*67e74705SXin Li for (ObjCMethodList *MethList = &M->second.second;
5646*67e74705SXin Li MethList && MethList->getMethod();
5647*67e74705SXin Li MethList = MethList->getNext()) {
5648*67e74705SXin Li if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
5649*67e74705SXin Li continue;
5650*67e74705SXin Li
5651*67e74705SXin Li Result R(MethList->getMethod(),
5652*67e74705SXin Li Results.getBasePriority(MethList->getMethod()), nullptr);
5653*67e74705SXin Li R.StartParameter = SelIdents.size();
5654*67e74705SXin Li R.AllParametersAreInformative = false;
5655*67e74705SXin Li Results.MaybeAddResult(R, SemaRef.CurContext);
5656*67e74705SXin Li }
5657*67e74705SXin Li }
5658*67e74705SXin Li }
5659*67e74705SXin Li
5660*67e74705SXin Li Results.ExitScope();
5661*67e74705SXin Li }
5662*67e74705SXin Li
CodeCompleteObjCClassMessage(Scope * S,ParsedType Receiver,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression,bool IsSuper)5663*67e74705SXin Li void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
5664*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents,
5665*67e74705SXin Li bool AtArgumentExpression,
5666*67e74705SXin Li bool IsSuper) {
5667*67e74705SXin Li
5668*67e74705SXin Li QualType T = this->GetTypeFromParser(Receiver);
5669*67e74705SXin Li
5670*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5671*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
5672*67e74705SXin Li CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage,
5673*67e74705SXin Li T, SelIdents));
5674*67e74705SXin Li
5675*67e74705SXin Li AddClassMessageCompletions(*this, S, Receiver, SelIdents,
5676*67e74705SXin Li AtArgumentExpression, IsSuper, Results);
5677*67e74705SXin Li
5678*67e74705SXin Li // If we're actually at the argument expression (rather than prior to the
5679*67e74705SXin Li // selector), we're actually performing code completion for an expression.
5680*67e74705SXin Li // Determine whether we have a single, best method. If so, we can
5681*67e74705SXin Li // code-complete the expression using the corresponding parameter type as
5682*67e74705SXin Li // our preferred type, improving completion results.
5683*67e74705SXin Li if (AtArgumentExpression) {
5684*67e74705SXin Li QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
5685*67e74705SXin Li SelIdents.size());
5686*67e74705SXin Li if (PreferredType.isNull())
5687*67e74705SXin Li CodeCompleteOrdinaryName(S, PCC_Expression);
5688*67e74705SXin Li else
5689*67e74705SXin Li CodeCompleteExpression(S, PreferredType);
5690*67e74705SXin Li return;
5691*67e74705SXin Li }
5692*67e74705SXin Li
5693*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
5694*67e74705SXin Li Results.getCompletionContext(),
5695*67e74705SXin Li Results.data(), Results.size());
5696*67e74705SXin Li }
5697*67e74705SXin Li
CodeCompleteObjCInstanceMessage(Scope * S,Expr * Receiver,ArrayRef<IdentifierInfo * > SelIdents,bool AtArgumentExpression,ObjCInterfaceDecl * Super)5698*67e74705SXin Li void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
5699*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents,
5700*67e74705SXin Li bool AtArgumentExpression,
5701*67e74705SXin Li ObjCInterfaceDecl *Super) {
5702*67e74705SXin Li typedef CodeCompletionResult Result;
5703*67e74705SXin Li
5704*67e74705SXin Li Expr *RecExpr = static_cast<Expr *>(Receiver);
5705*67e74705SXin Li
5706*67e74705SXin Li // If necessary, apply function/array conversion to the receiver.
5707*67e74705SXin Li // C99 6.7.5.3p[7,8].
5708*67e74705SXin Li if (RecExpr) {
5709*67e74705SXin Li ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr);
5710*67e74705SXin Li if (Conv.isInvalid()) // conversion failed. bail.
5711*67e74705SXin Li return;
5712*67e74705SXin Li RecExpr = Conv.get();
5713*67e74705SXin Li }
5714*67e74705SXin Li QualType ReceiverType = RecExpr? RecExpr->getType()
5715*67e74705SXin Li : Super? Context.getObjCObjectPointerType(
5716*67e74705SXin Li Context.getObjCInterfaceType(Super))
5717*67e74705SXin Li : Context.getObjCIdType();
5718*67e74705SXin Li
5719*67e74705SXin Li // If we're messaging an expression with type "id" or "Class", check
5720*67e74705SXin Li // whether we know something special about the receiver that allows
5721*67e74705SXin Li // us to assume a more-specific receiver type.
5722*67e74705SXin Li if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) {
5723*67e74705SXin Li if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
5724*67e74705SXin Li if (ReceiverType->isObjCClassType())
5725*67e74705SXin Li return CodeCompleteObjCClassMessage(S,
5726*67e74705SXin Li ParsedType::make(Context.getObjCInterfaceType(IFace)),
5727*67e74705SXin Li SelIdents,
5728*67e74705SXin Li AtArgumentExpression, Super);
5729*67e74705SXin Li
5730*67e74705SXin Li ReceiverType = Context.getObjCObjectPointerType(
5731*67e74705SXin Li Context.getObjCInterfaceType(IFace));
5732*67e74705SXin Li }
5733*67e74705SXin Li } else if (RecExpr && getLangOpts().CPlusPlus) {
5734*67e74705SXin Li ExprResult Conv = PerformContextuallyConvertToObjCPointer(RecExpr);
5735*67e74705SXin Li if (Conv.isUsable()) {
5736*67e74705SXin Li RecExpr = Conv.get();
5737*67e74705SXin Li ReceiverType = RecExpr->getType();
5738*67e74705SXin Li }
5739*67e74705SXin Li }
5740*67e74705SXin Li
5741*67e74705SXin Li // Build the set of methods we can see.
5742*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5743*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
5744*67e74705SXin Li CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
5745*67e74705SXin Li ReceiverType, SelIdents));
5746*67e74705SXin Li
5747*67e74705SXin Li Results.EnterNewScope();
5748*67e74705SXin Li
5749*67e74705SXin Li // If this is a send-to-super, try to add the special "super" send
5750*67e74705SXin Li // completion.
5751*67e74705SXin Li if (Super) {
5752*67e74705SXin Li if (ObjCMethodDecl *SuperMethod
5753*67e74705SXin Li = AddSuperSendCompletion(*this, false, SelIdents, Results))
5754*67e74705SXin Li Results.Ignore(SuperMethod);
5755*67e74705SXin Li }
5756*67e74705SXin Li
5757*67e74705SXin Li // If we're inside an Objective-C method definition, prefer its selector to
5758*67e74705SXin Li // others.
5759*67e74705SXin Li if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
5760*67e74705SXin Li Results.setPreferredSelector(CurMethod->getSelector());
5761*67e74705SXin Li
5762*67e74705SXin Li // Keep track of the selectors we've already added.
5763*67e74705SXin Li VisitedSelectorSet Selectors;
5764*67e74705SXin Li
5765*67e74705SXin Li // Handle messages to Class. This really isn't a message to an instance
5766*67e74705SXin Li // method, so we treat it the same way we would treat a message send to a
5767*67e74705SXin Li // class method.
5768*67e74705SXin Li if (ReceiverType->isObjCClassType() ||
5769*67e74705SXin Li ReceiverType->isObjCQualifiedClassType()) {
5770*67e74705SXin Li if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
5771*67e74705SXin Li if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
5772*67e74705SXin Li AddObjCMethods(ClassDecl, false, MK_Any, SelIdents,
5773*67e74705SXin Li CurContext, Selectors, AtArgumentExpression, Results);
5774*67e74705SXin Li }
5775*67e74705SXin Li }
5776*67e74705SXin Li // Handle messages to a qualified ID ("id<foo>").
5777*67e74705SXin Li else if (const ObjCObjectPointerType *QualID
5778*67e74705SXin Li = ReceiverType->getAsObjCQualifiedIdType()) {
5779*67e74705SXin Li // Search protocols for instance methods.
5780*67e74705SXin Li for (auto *I : QualID->quals())
5781*67e74705SXin Li AddObjCMethods(I, true, MK_Any, SelIdents, CurContext,
5782*67e74705SXin Li Selectors, AtArgumentExpression, Results);
5783*67e74705SXin Li }
5784*67e74705SXin Li // Handle messages to a pointer to interface type.
5785*67e74705SXin Li else if (const ObjCObjectPointerType *IFacePtr
5786*67e74705SXin Li = ReceiverType->getAsObjCInterfacePointerType()) {
5787*67e74705SXin Li // Search the class, its superclasses, etc., for instance methods.
5788*67e74705SXin Li AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
5789*67e74705SXin Li CurContext, Selectors, AtArgumentExpression,
5790*67e74705SXin Li Results);
5791*67e74705SXin Li
5792*67e74705SXin Li // Search protocols for instance methods.
5793*67e74705SXin Li for (auto *I : IFacePtr->quals())
5794*67e74705SXin Li AddObjCMethods(I, true, MK_Any, SelIdents, CurContext,
5795*67e74705SXin Li Selectors, AtArgumentExpression, Results);
5796*67e74705SXin Li }
5797*67e74705SXin Li // Handle messages to "id".
5798*67e74705SXin Li else if (ReceiverType->isObjCIdType()) {
5799*67e74705SXin Li // We're messaging "id", so provide all instance methods we know
5800*67e74705SXin Li // about as code-completion results.
5801*67e74705SXin Li
5802*67e74705SXin Li // If we have an external source, load the entire class method
5803*67e74705SXin Li // pool from the AST file.
5804*67e74705SXin Li if (ExternalSource) {
5805*67e74705SXin Li for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5806*67e74705SXin Li I != N; ++I) {
5807*67e74705SXin Li Selector Sel = ExternalSource->GetExternalSelector(I);
5808*67e74705SXin Li if (Sel.isNull() || MethodPool.count(Sel))
5809*67e74705SXin Li continue;
5810*67e74705SXin Li
5811*67e74705SXin Li ReadMethodPool(Sel);
5812*67e74705SXin Li }
5813*67e74705SXin Li }
5814*67e74705SXin Li
5815*67e74705SXin Li for (GlobalMethodPool::iterator M = MethodPool.begin(),
5816*67e74705SXin Li MEnd = MethodPool.end();
5817*67e74705SXin Li M != MEnd; ++M) {
5818*67e74705SXin Li for (ObjCMethodList *MethList = &M->second.first;
5819*67e74705SXin Li MethList && MethList->getMethod();
5820*67e74705SXin Li MethList = MethList->getNext()) {
5821*67e74705SXin Li if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
5822*67e74705SXin Li continue;
5823*67e74705SXin Li
5824*67e74705SXin Li if (!Selectors.insert(MethList->getMethod()->getSelector()).second)
5825*67e74705SXin Li continue;
5826*67e74705SXin Li
5827*67e74705SXin Li Result R(MethList->getMethod(),
5828*67e74705SXin Li Results.getBasePriority(MethList->getMethod()), nullptr);
5829*67e74705SXin Li R.StartParameter = SelIdents.size();
5830*67e74705SXin Li R.AllParametersAreInformative = false;
5831*67e74705SXin Li Results.MaybeAddResult(R, CurContext);
5832*67e74705SXin Li }
5833*67e74705SXin Li }
5834*67e74705SXin Li }
5835*67e74705SXin Li Results.ExitScope();
5836*67e74705SXin Li
5837*67e74705SXin Li
5838*67e74705SXin Li // If we're actually at the argument expression (rather than prior to the
5839*67e74705SXin Li // selector), we're actually performing code completion for an expression.
5840*67e74705SXin Li // Determine whether we have a single, best method. If so, we can
5841*67e74705SXin Li // code-complete the expression using the corresponding parameter type as
5842*67e74705SXin Li // our preferred type, improving completion results.
5843*67e74705SXin Li if (AtArgumentExpression) {
5844*67e74705SXin Li QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results,
5845*67e74705SXin Li SelIdents.size());
5846*67e74705SXin Li if (PreferredType.isNull())
5847*67e74705SXin Li CodeCompleteOrdinaryName(S, PCC_Expression);
5848*67e74705SXin Li else
5849*67e74705SXin Li CodeCompleteExpression(S, PreferredType);
5850*67e74705SXin Li return;
5851*67e74705SXin Li }
5852*67e74705SXin Li
5853*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
5854*67e74705SXin Li Results.getCompletionContext(),
5855*67e74705SXin Li Results.data(),Results.size());
5856*67e74705SXin Li }
5857*67e74705SXin Li
CodeCompleteObjCForCollection(Scope * S,DeclGroupPtrTy IterationVar)5858*67e74705SXin Li void Sema::CodeCompleteObjCForCollection(Scope *S,
5859*67e74705SXin Li DeclGroupPtrTy IterationVar) {
5860*67e74705SXin Li CodeCompleteExpressionData Data;
5861*67e74705SXin Li Data.ObjCCollection = true;
5862*67e74705SXin Li
5863*67e74705SXin Li if (IterationVar.getAsOpaquePtr()) {
5864*67e74705SXin Li DeclGroupRef DG = IterationVar.get();
5865*67e74705SXin Li for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
5866*67e74705SXin Li if (*I)
5867*67e74705SXin Li Data.IgnoreDecls.push_back(*I);
5868*67e74705SXin Li }
5869*67e74705SXin Li }
5870*67e74705SXin Li
5871*67e74705SXin Li CodeCompleteExpression(S, Data);
5872*67e74705SXin Li }
5873*67e74705SXin Li
CodeCompleteObjCSelector(Scope * S,ArrayRef<IdentifierInfo * > SelIdents)5874*67e74705SXin Li void Sema::CodeCompleteObjCSelector(Scope *S,
5875*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents) {
5876*67e74705SXin Li // If we have an external source, load the entire class method
5877*67e74705SXin Li // pool from the AST file.
5878*67e74705SXin Li if (ExternalSource) {
5879*67e74705SXin Li for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
5880*67e74705SXin Li I != N; ++I) {
5881*67e74705SXin Li Selector Sel = ExternalSource->GetExternalSelector(I);
5882*67e74705SXin Li if (Sel.isNull() || MethodPool.count(Sel))
5883*67e74705SXin Li continue;
5884*67e74705SXin Li
5885*67e74705SXin Li ReadMethodPool(Sel);
5886*67e74705SXin Li }
5887*67e74705SXin Li }
5888*67e74705SXin Li
5889*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5890*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
5891*67e74705SXin Li CodeCompletionContext::CCC_SelectorName);
5892*67e74705SXin Li Results.EnterNewScope();
5893*67e74705SXin Li for (GlobalMethodPool::iterator M = MethodPool.begin(),
5894*67e74705SXin Li MEnd = MethodPool.end();
5895*67e74705SXin Li M != MEnd; ++M) {
5896*67e74705SXin Li
5897*67e74705SXin Li Selector Sel = M->first;
5898*67e74705SXin Li if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents))
5899*67e74705SXin Li continue;
5900*67e74705SXin Li
5901*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
5902*67e74705SXin Li Results.getCodeCompletionTUInfo());
5903*67e74705SXin Li if (Sel.isUnarySelector()) {
5904*67e74705SXin Li Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
5905*67e74705SXin Li Sel.getNameForSlot(0)));
5906*67e74705SXin Li Results.AddResult(Builder.TakeString());
5907*67e74705SXin Li continue;
5908*67e74705SXin Li }
5909*67e74705SXin Li
5910*67e74705SXin Li std::string Accumulator;
5911*67e74705SXin Li for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
5912*67e74705SXin Li if (I == SelIdents.size()) {
5913*67e74705SXin Li if (!Accumulator.empty()) {
5914*67e74705SXin Li Builder.AddInformativeChunk(Builder.getAllocator().CopyString(
5915*67e74705SXin Li Accumulator));
5916*67e74705SXin Li Accumulator.clear();
5917*67e74705SXin Li }
5918*67e74705SXin Li }
5919*67e74705SXin Li
5920*67e74705SXin Li Accumulator += Sel.getNameForSlot(I);
5921*67e74705SXin Li Accumulator += ':';
5922*67e74705SXin Li }
5923*67e74705SXin Li Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( Accumulator));
5924*67e74705SXin Li Results.AddResult(Builder.TakeString());
5925*67e74705SXin Li }
5926*67e74705SXin Li Results.ExitScope();
5927*67e74705SXin Li
5928*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
5929*67e74705SXin Li CodeCompletionContext::CCC_SelectorName,
5930*67e74705SXin Li Results.data(), Results.size());
5931*67e74705SXin Li }
5932*67e74705SXin Li
5933*67e74705SXin Li /// \brief Add all of the protocol declarations that we find in the given
5934*67e74705SXin Li /// (translation unit) context.
AddProtocolResults(DeclContext * Ctx,DeclContext * CurContext,bool OnlyForwardDeclarations,ResultBuilder & Results)5935*67e74705SXin Li static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
5936*67e74705SXin Li bool OnlyForwardDeclarations,
5937*67e74705SXin Li ResultBuilder &Results) {
5938*67e74705SXin Li typedef CodeCompletionResult Result;
5939*67e74705SXin Li
5940*67e74705SXin Li for (const auto *D : Ctx->decls()) {
5941*67e74705SXin Li // Record any protocols we find.
5942*67e74705SXin Li if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(D))
5943*67e74705SXin Li if (!OnlyForwardDeclarations || !Proto->hasDefinition())
5944*67e74705SXin Li Results.AddResult(Result(Proto, Results.getBasePriority(Proto),nullptr),
5945*67e74705SXin Li CurContext, nullptr, false);
5946*67e74705SXin Li }
5947*67e74705SXin Li }
5948*67e74705SXin Li
CodeCompleteObjCProtocolReferences(ArrayRef<IdentifierLocPair> Protocols)5949*67e74705SXin Li void Sema::CodeCompleteObjCProtocolReferences(
5950*67e74705SXin Li ArrayRef<IdentifierLocPair> Protocols) {
5951*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5952*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
5953*67e74705SXin Li CodeCompletionContext::CCC_ObjCProtocolName);
5954*67e74705SXin Li
5955*67e74705SXin Li if (CodeCompleter && CodeCompleter->includeGlobals()) {
5956*67e74705SXin Li Results.EnterNewScope();
5957*67e74705SXin Li
5958*67e74705SXin Li // Tell the result set to ignore all of the protocols we have
5959*67e74705SXin Li // already seen.
5960*67e74705SXin Li // FIXME: This doesn't work when caching code-completion results.
5961*67e74705SXin Li for (const IdentifierLocPair &Pair : Protocols)
5962*67e74705SXin Li if (ObjCProtocolDecl *Protocol = LookupProtocol(Pair.first,
5963*67e74705SXin Li Pair.second))
5964*67e74705SXin Li Results.Ignore(Protocol);
5965*67e74705SXin Li
5966*67e74705SXin Li // Add all protocols.
5967*67e74705SXin Li AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
5968*67e74705SXin Li Results);
5969*67e74705SXin Li
5970*67e74705SXin Li Results.ExitScope();
5971*67e74705SXin Li }
5972*67e74705SXin Li
5973*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
5974*67e74705SXin Li CodeCompletionContext::CCC_ObjCProtocolName,
5975*67e74705SXin Li Results.data(),Results.size());
5976*67e74705SXin Li }
5977*67e74705SXin Li
CodeCompleteObjCProtocolDecl(Scope *)5978*67e74705SXin Li void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
5979*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
5980*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
5981*67e74705SXin Li CodeCompletionContext::CCC_ObjCProtocolName);
5982*67e74705SXin Li
5983*67e74705SXin Li if (CodeCompleter && CodeCompleter->includeGlobals()) {
5984*67e74705SXin Li Results.EnterNewScope();
5985*67e74705SXin Li
5986*67e74705SXin Li // Add all protocols.
5987*67e74705SXin Li AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
5988*67e74705SXin Li Results);
5989*67e74705SXin Li
5990*67e74705SXin Li Results.ExitScope();
5991*67e74705SXin Li }
5992*67e74705SXin Li
5993*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
5994*67e74705SXin Li CodeCompletionContext::CCC_ObjCProtocolName,
5995*67e74705SXin Li Results.data(),Results.size());
5996*67e74705SXin Li }
5997*67e74705SXin Li
5998*67e74705SXin Li /// \brief Add all of the Objective-C interface declarations that we find in
5999*67e74705SXin Li /// the given (translation unit) context.
AddInterfaceResults(DeclContext * Ctx,DeclContext * CurContext,bool OnlyForwardDeclarations,bool OnlyUnimplemented,ResultBuilder & Results)6000*67e74705SXin Li static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
6001*67e74705SXin Li bool OnlyForwardDeclarations,
6002*67e74705SXin Li bool OnlyUnimplemented,
6003*67e74705SXin Li ResultBuilder &Results) {
6004*67e74705SXin Li typedef CodeCompletionResult Result;
6005*67e74705SXin Li
6006*67e74705SXin Li for (const auto *D : Ctx->decls()) {
6007*67e74705SXin Li // Record any interfaces we find.
6008*67e74705SXin Li if (const auto *Class = dyn_cast<ObjCInterfaceDecl>(D))
6009*67e74705SXin Li if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
6010*67e74705SXin Li (!OnlyUnimplemented || !Class->getImplementation()))
6011*67e74705SXin Li Results.AddResult(Result(Class, Results.getBasePriority(Class),nullptr),
6012*67e74705SXin Li CurContext, nullptr, false);
6013*67e74705SXin Li }
6014*67e74705SXin Li }
6015*67e74705SXin Li
CodeCompleteObjCInterfaceDecl(Scope * S)6016*67e74705SXin Li void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
6017*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6018*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
6019*67e74705SXin Li CodeCompletionContext::CCC_Other);
6020*67e74705SXin Li Results.EnterNewScope();
6021*67e74705SXin Li
6022*67e74705SXin Li if (CodeCompleter->includeGlobals()) {
6023*67e74705SXin Li // Add all classes.
6024*67e74705SXin Li AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
6025*67e74705SXin Li false, Results);
6026*67e74705SXin Li }
6027*67e74705SXin Li
6028*67e74705SXin Li Results.ExitScope();
6029*67e74705SXin Li
6030*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
6031*67e74705SXin Li CodeCompletionContext::CCC_ObjCInterfaceName,
6032*67e74705SXin Li Results.data(),Results.size());
6033*67e74705SXin Li }
6034*67e74705SXin Li
CodeCompleteObjCSuperclass(Scope * S,IdentifierInfo * ClassName,SourceLocation ClassNameLoc)6035*67e74705SXin Li void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
6036*67e74705SXin Li SourceLocation ClassNameLoc) {
6037*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6038*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
6039*67e74705SXin Li CodeCompletionContext::CCC_ObjCInterfaceName);
6040*67e74705SXin Li Results.EnterNewScope();
6041*67e74705SXin Li
6042*67e74705SXin Li // Make sure that we ignore the class we're currently defining.
6043*67e74705SXin Li NamedDecl *CurClass
6044*67e74705SXin Li = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
6045*67e74705SXin Li if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
6046*67e74705SXin Li Results.Ignore(CurClass);
6047*67e74705SXin Li
6048*67e74705SXin Li if (CodeCompleter->includeGlobals()) {
6049*67e74705SXin Li // Add all classes.
6050*67e74705SXin Li AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
6051*67e74705SXin Li false, Results);
6052*67e74705SXin Li }
6053*67e74705SXin Li
6054*67e74705SXin Li Results.ExitScope();
6055*67e74705SXin Li
6056*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
6057*67e74705SXin Li CodeCompletionContext::CCC_ObjCInterfaceName,
6058*67e74705SXin Li Results.data(),Results.size());
6059*67e74705SXin Li }
6060*67e74705SXin Li
CodeCompleteObjCImplementationDecl(Scope * S)6061*67e74705SXin Li void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
6062*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6063*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
6064*67e74705SXin Li CodeCompletionContext::CCC_Other);
6065*67e74705SXin Li Results.EnterNewScope();
6066*67e74705SXin Li
6067*67e74705SXin Li if (CodeCompleter->includeGlobals()) {
6068*67e74705SXin Li // Add all unimplemented classes.
6069*67e74705SXin Li AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
6070*67e74705SXin Li true, Results);
6071*67e74705SXin Li }
6072*67e74705SXin Li
6073*67e74705SXin Li Results.ExitScope();
6074*67e74705SXin Li
6075*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
6076*67e74705SXin Li CodeCompletionContext::CCC_ObjCInterfaceName,
6077*67e74705SXin Li Results.data(),Results.size());
6078*67e74705SXin Li }
6079*67e74705SXin Li
CodeCompleteObjCInterfaceCategory(Scope * S,IdentifierInfo * ClassName,SourceLocation ClassNameLoc)6080*67e74705SXin Li void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
6081*67e74705SXin Li IdentifierInfo *ClassName,
6082*67e74705SXin Li SourceLocation ClassNameLoc) {
6083*67e74705SXin Li typedef CodeCompletionResult Result;
6084*67e74705SXin Li
6085*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6086*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
6087*67e74705SXin Li CodeCompletionContext::CCC_ObjCCategoryName);
6088*67e74705SXin Li
6089*67e74705SXin Li // Ignore any categories we find that have already been implemented by this
6090*67e74705SXin Li // interface.
6091*67e74705SXin Li llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
6092*67e74705SXin Li NamedDecl *CurClass
6093*67e74705SXin Li = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
6094*67e74705SXin Li if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)){
6095*67e74705SXin Li for (const auto *Cat : Class->visible_categories())
6096*67e74705SXin Li CategoryNames.insert(Cat->getIdentifier());
6097*67e74705SXin Li }
6098*67e74705SXin Li
6099*67e74705SXin Li // Add all of the categories we know about.
6100*67e74705SXin Li Results.EnterNewScope();
6101*67e74705SXin Li TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
6102*67e74705SXin Li for (const auto *D : TU->decls())
6103*67e74705SXin Li if (const auto *Category = dyn_cast<ObjCCategoryDecl>(D))
6104*67e74705SXin Li if (CategoryNames.insert(Category->getIdentifier()).second)
6105*67e74705SXin Li Results.AddResult(Result(Category, Results.getBasePriority(Category),
6106*67e74705SXin Li nullptr),
6107*67e74705SXin Li CurContext, nullptr, false);
6108*67e74705SXin Li Results.ExitScope();
6109*67e74705SXin Li
6110*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
6111*67e74705SXin Li CodeCompletionContext::CCC_ObjCCategoryName,
6112*67e74705SXin Li Results.data(),Results.size());
6113*67e74705SXin Li }
6114*67e74705SXin Li
CodeCompleteObjCImplementationCategory(Scope * S,IdentifierInfo * ClassName,SourceLocation ClassNameLoc)6115*67e74705SXin Li void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
6116*67e74705SXin Li IdentifierInfo *ClassName,
6117*67e74705SXin Li SourceLocation ClassNameLoc) {
6118*67e74705SXin Li typedef CodeCompletionResult Result;
6119*67e74705SXin Li
6120*67e74705SXin Li // Find the corresponding interface. If we couldn't find the interface, the
6121*67e74705SXin Li // program itself is ill-formed. However, we'll try to be helpful still by
6122*67e74705SXin Li // providing the list of all of the categories we know about.
6123*67e74705SXin Li NamedDecl *CurClass
6124*67e74705SXin Li = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
6125*67e74705SXin Li ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
6126*67e74705SXin Li if (!Class)
6127*67e74705SXin Li return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
6128*67e74705SXin Li
6129*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6130*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
6131*67e74705SXin Li CodeCompletionContext::CCC_ObjCCategoryName);
6132*67e74705SXin Li
6133*67e74705SXin Li // Add all of the categories that have have corresponding interface
6134*67e74705SXin Li // declarations in this class and any of its superclasses, except for
6135*67e74705SXin Li // already-implemented categories in the class itself.
6136*67e74705SXin Li llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
6137*67e74705SXin Li Results.EnterNewScope();
6138*67e74705SXin Li bool IgnoreImplemented = true;
6139*67e74705SXin Li while (Class) {
6140*67e74705SXin Li for (const auto *Cat : Class->visible_categories()) {
6141*67e74705SXin Li if ((!IgnoreImplemented || !Cat->getImplementation()) &&
6142*67e74705SXin Li CategoryNames.insert(Cat->getIdentifier()).second)
6143*67e74705SXin Li Results.AddResult(Result(Cat, Results.getBasePriority(Cat), nullptr),
6144*67e74705SXin Li CurContext, nullptr, false);
6145*67e74705SXin Li }
6146*67e74705SXin Li
6147*67e74705SXin Li Class = Class->getSuperClass();
6148*67e74705SXin Li IgnoreImplemented = false;
6149*67e74705SXin Li }
6150*67e74705SXin Li Results.ExitScope();
6151*67e74705SXin Li
6152*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
6153*67e74705SXin Li CodeCompletionContext::CCC_ObjCCategoryName,
6154*67e74705SXin Li Results.data(),Results.size());
6155*67e74705SXin Li }
6156*67e74705SXin Li
CodeCompleteObjCPropertyDefinition(Scope * S)6157*67e74705SXin Li void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
6158*67e74705SXin Li CodeCompletionContext CCContext(CodeCompletionContext::CCC_Other);
6159*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6160*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
6161*67e74705SXin Li CCContext);
6162*67e74705SXin Li
6163*67e74705SXin Li // Figure out where this @synthesize lives.
6164*67e74705SXin Li ObjCContainerDecl *Container
6165*67e74705SXin Li = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
6166*67e74705SXin Li if (!Container ||
6167*67e74705SXin Li (!isa<ObjCImplementationDecl>(Container) &&
6168*67e74705SXin Li !isa<ObjCCategoryImplDecl>(Container)))
6169*67e74705SXin Li return;
6170*67e74705SXin Li
6171*67e74705SXin Li // Ignore any properties that have already been implemented.
6172*67e74705SXin Li Container = getContainerDef(Container);
6173*67e74705SXin Li for (const auto *D : Container->decls())
6174*67e74705SXin Li if (const auto *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(D))
6175*67e74705SXin Li Results.Ignore(PropertyImpl->getPropertyDecl());
6176*67e74705SXin Li
6177*67e74705SXin Li // Add any properties that we find.
6178*67e74705SXin Li AddedPropertiesSet AddedProperties;
6179*67e74705SXin Li Results.EnterNewScope();
6180*67e74705SXin Li if (ObjCImplementationDecl *ClassImpl
6181*67e74705SXin Li = dyn_cast<ObjCImplementationDecl>(Container))
6182*67e74705SXin Li AddObjCProperties(CCContext, ClassImpl->getClassInterface(), false,
6183*67e74705SXin Li /*AllowNullaryMethods=*/false, CurContext,
6184*67e74705SXin Li AddedProperties, Results);
6185*67e74705SXin Li else
6186*67e74705SXin Li AddObjCProperties(CCContext,
6187*67e74705SXin Li cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
6188*67e74705SXin Li false, /*AllowNullaryMethods=*/false, CurContext,
6189*67e74705SXin Li AddedProperties, Results);
6190*67e74705SXin Li Results.ExitScope();
6191*67e74705SXin Li
6192*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
6193*67e74705SXin Li CodeCompletionContext::CCC_Other,
6194*67e74705SXin Li Results.data(),Results.size());
6195*67e74705SXin Li }
6196*67e74705SXin Li
CodeCompleteObjCPropertySynthesizeIvar(Scope * S,IdentifierInfo * PropertyName)6197*67e74705SXin Li void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
6198*67e74705SXin Li IdentifierInfo *PropertyName) {
6199*67e74705SXin Li typedef CodeCompletionResult Result;
6200*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
6201*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
6202*67e74705SXin Li CodeCompletionContext::CCC_Other);
6203*67e74705SXin Li
6204*67e74705SXin Li // Figure out where this @synthesize lives.
6205*67e74705SXin Li ObjCContainerDecl *Container
6206*67e74705SXin Li = dyn_cast_or_null<ObjCContainerDecl>(CurContext);
6207*67e74705SXin Li if (!Container ||
6208*67e74705SXin Li (!isa<ObjCImplementationDecl>(Container) &&
6209*67e74705SXin Li !isa<ObjCCategoryImplDecl>(Container)))
6210*67e74705SXin Li return;
6211*67e74705SXin Li
6212*67e74705SXin Li // Figure out which interface we're looking into.
6213*67e74705SXin Li ObjCInterfaceDecl *Class = nullptr;
6214*67e74705SXin Li if (ObjCImplementationDecl *ClassImpl
6215*67e74705SXin Li = dyn_cast<ObjCImplementationDecl>(Container))
6216*67e74705SXin Li Class = ClassImpl->getClassInterface();
6217*67e74705SXin Li else
6218*67e74705SXin Li Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
6219*67e74705SXin Li ->getClassInterface();
6220*67e74705SXin Li
6221*67e74705SXin Li // Determine the type of the property we're synthesizing.
6222*67e74705SXin Li QualType PropertyType = Context.getObjCIdType();
6223*67e74705SXin Li if (Class) {
6224*67e74705SXin Li if (ObjCPropertyDecl *Property = Class->FindPropertyDeclaration(
6225*67e74705SXin Li PropertyName, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
6226*67e74705SXin Li PropertyType
6227*67e74705SXin Li = Property->getType().getNonReferenceType().getUnqualifiedType();
6228*67e74705SXin Li
6229*67e74705SXin Li // Give preference to ivars
6230*67e74705SXin Li Results.setPreferredType(PropertyType);
6231*67e74705SXin Li }
6232*67e74705SXin Li }
6233*67e74705SXin Li
6234*67e74705SXin Li // Add all of the instance variables in this class and its superclasses.
6235*67e74705SXin Li Results.EnterNewScope();
6236*67e74705SXin Li bool SawSimilarlyNamedIvar = false;
6237*67e74705SXin Li std::string NameWithPrefix;
6238*67e74705SXin Li NameWithPrefix += '_';
6239*67e74705SXin Li NameWithPrefix += PropertyName->getName();
6240*67e74705SXin Li std::string NameWithSuffix = PropertyName->getName().str();
6241*67e74705SXin Li NameWithSuffix += '_';
6242*67e74705SXin Li for(; Class; Class = Class->getSuperClass()) {
6243*67e74705SXin Li for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar;
6244*67e74705SXin Li Ivar = Ivar->getNextIvar()) {
6245*67e74705SXin Li Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), nullptr),
6246*67e74705SXin Li CurContext, nullptr, false);
6247*67e74705SXin Li
6248*67e74705SXin Li // Determine whether we've seen an ivar with a name similar to the
6249*67e74705SXin Li // property.
6250*67e74705SXin Li if ((PropertyName == Ivar->getIdentifier() ||
6251*67e74705SXin Li NameWithPrefix == Ivar->getName() ||
6252*67e74705SXin Li NameWithSuffix == Ivar->getName())) {
6253*67e74705SXin Li SawSimilarlyNamedIvar = true;
6254*67e74705SXin Li
6255*67e74705SXin Li // Reduce the priority of this result by one, to give it a slight
6256*67e74705SXin Li // advantage over other results whose names don't match so closely.
6257*67e74705SXin Li if (Results.size() &&
6258*67e74705SXin Li Results.data()[Results.size() - 1].Kind
6259*67e74705SXin Li == CodeCompletionResult::RK_Declaration &&
6260*67e74705SXin Li Results.data()[Results.size() - 1].Declaration == Ivar)
6261*67e74705SXin Li Results.data()[Results.size() - 1].Priority--;
6262*67e74705SXin Li }
6263*67e74705SXin Li }
6264*67e74705SXin Li }
6265*67e74705SXin Li
6266*67e74705SXin Li if (!SawSimilarlyNamedIvar) {
6267*67e74705SXin Li // Create ivar result _propName, that the user can use to synthesize
6268*67e74705SXin Li // an ivar of the appropriate type.
6269*67e74705SXin Li unsigned Priority = CCP_MemberDeclaration + 1;
6270*67e74705SXin Li typedef CodeCompletionResult Result;
6271*67e74705SXin Li CodeCompletionAllocator &Allocator = Results.getAllocator();
6272*67e74705SXin Li CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(),
6273*67e74705SXin Li Priority,CXAvailability_Available);
6274*67e74705SXin Li
6275*67e74705SXin Li PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
6276*67e74705SXin Li Builder.AddResultTypeChunk(GetCompletionTypeString(PropertyType, Context,
6277*67e74705SXin Li Policy, Allocator));
6278*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix));
6279*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), Priority,
6280*67e74705SXin Li CXCursor_ObjCIvarDecl));
6281*67e74705SXin Li }
6282*67e74705SXin Li
6283*67e74705SXin Li Results.ExitScope();
6284*67e74705SXin Li
6285*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
6286*67e74705SXin Li CodeCompletionContext::CCC_Other,
6287*67e74705SXin Li Results.data(),Results.size());
6288*67e74705SXin Li }
6289*67e74705SXin Li
6290*67e74705SXin Li // Mapping from selectors to the methods that implement that selector, along
6291*67e74705SXin Li // with the "in original class" flag.
6292*67e74705SXin Li typedef llvm::DenseMap<
6293*67e74705SXin Li Selector, llvm::PointerIntPair<ObjCMethodDecl *, 1, bool> > KnownMethodsMap;
6294*67e74705SXin Li
6295*67e74705SXin Li /// \brief Find all of the methods that reside in the given container
6296*67e74705SXin Li /// (and its superclasses, protocols, etc.) that meet the given
6297*67e74705SXin Li /// criteria. Insert those methods into the map of known methods,
6298*67e74705SXin Li /// indexed by selector so they can be easily found.
FindImplementableMethods(ASTContext & Context,ObjCContainerDecl * Container,bool WantInstanceMethods,QualType ReturnType,KnownMethodsMap & KnownMethods,bool InOriginalClass=true)6299*67e74705SXin Li static void FindImplementableMethods(ASTContext &Context,
6300*67e74705SXin Li ObjCContainerDecl *Container,
6301*67e74705SXin Li bool WantInstanceMethods,
6302*67e74705SXin Li QualType ReturnType,
6303*67e74705SXin Li KnownMethodsMap &KnownMethods,
6304*67e74705SXin Li bool InOriginalClass = true) {
6305*67e74705SXin Li if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
6306*67e74705SXin Li // Make sure we have a definition; that's what we'll walk.
6307*67e74705SXin Li if (!IFace->hasDefinition())
6308*67e74705SXin Li return;
6309*67e74705SXin Li
6310*67e74705SXin Li IFace = IFace->getDefinition();
6311*67e74705SXin Li Container = IFace;
6312*67e74705SXin Li
6313*67e74705SXin Li const ObjCList<ObjCProtocolDecl> &Protocols
6314*67e74705SXin Li = IFace->getReferencedProtocols();
6315*67e74705SXin Li for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6316*67e74705SXin Li E = Protocols.end();
6317*67e74705SXin Li I != E; ++I)
6318*67e74705SXin Li FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6319*67e74705SXin Li KnownMethods, InOriginalClass);
6320*67e74705SXin Li
6321*67e74705SXin Li // Add methods from any class extensions and categories.
6322*67e74705SXin Li for (auto *Cat : IFace->visible_categories()) {
6323*67e74705SXin Li FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
6324*67e74705SXin Li KnownMethods, false);
6325*67e74705SXin Li }
6326*67e74705SXin Li
6327*67e74705SXin Li // Visit the superclass.
6328*67e74705SXin Li if (IFace->getSuperClass())
6329*67e74705SXin Li FindImplementableMethods(Context, IFace->getSuperClass(),
6330*67e74705SXin Li WantInstanceMethods, ReturnType,
6331*67e74705SXin Li KnownMethods, false);
6332*67e74705SXin Li }
6333*67e74705SXin Li
6334*67e74705SXin Li if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
6335*67e74705SXin Li // Recurse into protocols.
6336*67e74705SXin Li const ObjCList<ObjCProtocolDecl> &Protocols
6337*67e74705SXin Li = Category->getReferencedProtocols();
6338*67e74705SXin Li for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6339*67e74705SXin Li E = Protocols.end();
6340*67e74705SXin Li I != E; ++I)
6341*67e74705SXin Li FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6342*67e74705SXin Li KnownMethods, InOriginalClass);
6343*67e74705SXin Li
6344*67e74705SXin Li // If this category is the original class, jump to the interface.
6345*67e74705SXin Li if (InOriginalClass && Category->getClassInterface())
6346*67e74705SXin Li FindImplementableMethods(Context, Category->getClassInterface(),
6347*67e74705SXin Li WantInstanceMethods, ReturnType, KnownMethods,
6348*67e74705SXin Li false);
6349*67e74705SXin Li }
6350*67e74705SXin Li
6351*67e74705SXin Li if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
6352*67e74705SXin Li // Make sure we have a definition; that's what we'll walk.
6353*67e74705SXin Li if (!Protocol->hasDefinition())
6354*67e74705SXin Li return;
6355*67e74705SXin Li Protocol = Protocol->getDefinition();
6356*67e74705SXin Li Container = Protocol;
6357*67e74705SXin Li
6358*67e74705SXin Li // Recurse into protocols.
6359*67e74705SXin Li const ObjCList<ObjCProtocolDecl> &Protocols
6360*67e74705SXin Li = Protocol->getReferencedProtocols();
6361*67e74705SXin Li for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6362*67e74705SXin Li E = Protocols.end();
6363*67e74705SXin Li I != E; ++I)
6364*67e74705SXin Li FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6365*67e74705SXin Li KnownMethods, false);
6366*67e74705SXin Li }
6367*67e74705SXin Li
6368*67e74705SXin Li // Add methods in this container. This operation occurs last because
6369*67e74705SXin Li // we want the methods from this container to override any methods
6370*67e74705SXin Li // we've previously seen with the same selector.
6371*67e74705SXin Li for (auto *M : Container->methods()) {
6372*67e74705SXin Li if (M->isInstanceMethod() == WantInstanceMethods) {
6373*67e74705SXin Li if (!ReturnType.isNull() &&
6374*67e74705SXin Li !Context.hasSameUnqualifiedType(ReturnType, M->getReturnType()))
6375*67e74705SXin Li continue;
6376*67e74705SXin Li
6377*67e74705SXin Li KnownMethods[M->getSelector()] =
6378*67e74705SXin Li KnownMethodsMap::mapped_type(M, InOriginalClass);
6379*67e74705SXin Li }
6380*67e74705SXin Li }
6381*67e74705SXin Li }
6382*67e74705SXin Li
6383*67e74705SXin Li /// \brief Add the parenthesized return or parameter type chunk to a code
6384*67e74705SXin Li /// completion string.
AddObjCPassingTypeChunk(QualType Type,unsigned ObjCDeclQuals,ASTContext & Context,const PrintingPolicy & Policy,CodeCompletionBuilder & Builder)6385*67e74705SXin Li static void AddObjCPassingTypeChunk(QualType Type,
6386*67e74705SXin Li unsigned ObjCDeclQuals,
6387*67e74705SXin Li ASTContext &Context,
6388*67e74705SXin Li const PrintingPolicy &Policy,
6389*67e74705SXin Li CodeCompletionBuilder &Builder) {
6390*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6391*67e74705SXin Li std::string Quals = formatObjCParamQualifiers(ObjCDeclQuals, Type);
6392*67e74705SXin Li if (!Quals.empty())
6393*67e74705SXin Li Builder.AddTextChunk(Builder.getAllocator().CopyString(Quals));
6394*67e74705SXin Li Builder.AddTextChunk(GetCompletionTypeString(Type, Context, Policy,
6395*67e74705SXin Li Builder.getAllocator()));
6396*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6397*67e74705SXin Li }
6398*67e74705SXin Li
6399*67e74705SXin Li /// \brief Determine whether the given class is or inherits from a class by
6400*67e74705SXin Li /// the given name.
InheritsFromClassNamed(ObjCInterfaceDecl * Class,StringRef Name)6401*67e74705SXin Li static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class,
6402*67e74705SXin Li StringRef Name) {
6403*67e74705SXin Li if (!Class)
6404*67e74705SXin Li return false;
6405*67e74705SXin Li
6406*67e74705SXin Li if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name)
6407*67e74705SXin Li return true;
6408*67e74705SXin Li
6409*67e74705SXin Li return InheritsFromClassNamed(Class->getSuperClass(), Name);
6410*67e74705SXin Li }
6411*67e74705SXin Li
6412*67e74705SXin Li /// \brief Add code completions for Objective-C Key-Value Coding (KVC) and
6413*67e74705SXin Li /// Key-Value Observing (KVO).
AddObjCKeyValueCompletions(ObjCPropertyDecl * Property,bool IsInstanceMethod,QualType ReturnType,ASTContext & Context,VisitedSelectorSet & KnownSelectors,ResultBuilder & Results)6414*67e74705SXin Li static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
6415*67e74705SXin Li bool IsInstanceMethod,
6416*67e74705SXin Li QualType ReturnType,
6417*67e74705SXin Li ASTContext &Context,
6418*67e74705SXin Li VisitedSelectorSet &KnownSelectors,
6419*67e74705SXin Li ResultBuilder &Results) {
6420*67e74705SXin Li IdentifierInfo *PropName = Property->getIdentifier();
6421*67e74705SXin Li if (!PropName || PropName->getLength() == 0)
6422*67e74705SXin Li return;
6423*67e74705SXin Li
6424*67e74705SXin Li PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
6425*67e74705SXin Li
6426*67e74705SXin Li // Builder that will create each code completion.
6427*67e74705SXin Li typedef CodeCompletionResult Result;
6428*67e74705SXin Li CodeCompletionAllocator &Allocator = Results.getAllocator();
6429*67e74705SXin Li CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
6430*67e74705SXin Li
6431*67e74705SXin Li // The selector table.
6432*67e74705SXin Li SelectorTable &Selectors = Context.Selectors;
6433*67e74705SXin Li
6434*67e74705SXin Li // The property name, copied into the code completion allocation region
6435*67e74705SXin Li // on demand.
6436*67e74705SXin Li struct KeyHolder {
6437*67e74705SXin Li CodeCompletionAllocator &Allocator;
6438*67e74705SXin Li StringRef Key;
6439*67e74705SXin Li const char *CopiedKey;
6440*67e74705SXin Li
6441*67e74705SXin Li KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key)
6442*67e74705SXin Li : Allocator(Allocator), Key(Key), CopiedKey(nullptr) {}
6443*67e74705SXin Li
6444*67e74705SXin Li operator const char *() {
6445*67e74705SXin Li if (CopiedKey)
6446*67e74705SXin Li return CopiedKey;
6447*67e74705SXin Li
6448*67e74705SXin Li return CopiedKey = Allocator.CopyString(Key);
6449*67e74705SXin Li }
6450*67e74705SXin Li } Key(Allocator, PropName->getName());
6451*67e74705SXin Li
6452*67e74705SXin Li // The uppercased name of the property name.
6453*67e74705SXin Li std::string UpperKey = PropName->getName();
6454*67e74705SXin Li if (!UpperKey.empty())
6455*67e74705SXin Li UpperKey[0] = toUppercase(UpperKey[0]);
6456*67e74705SXin Li
6457*67e74705SXin Li bool ReturnTypeMatchesProperty = ReturnType.isNull() ||
6458*67e74705SXin Li Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(),
6459*67e74705SXin Li Property->getType());
6460*67e74705SXin Li bool ReturnTypeMatchesVoid
6461*67e74705SXin Li = ReturnType.isNull() || ReturnType->isVoidType();
6462*67e74705SXin Li
6463*67e74705SXin Li // Add the normal accessor -(type)key.
6464*67e74705SXin Li if (IsInstanceMethod &&
6465*67e74705SXin Li KnownSelectors.insert(Selectors.getNullarySelector(PropName)).second &&
6466*67e74705SXin Li ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) {
6467*67e74705SXin Li if (ReturnType.isNull())
6468*67e74705SXin Li AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0,
6469*67e74705SXin Li Context, Policy, Builder);
6470*67e74705SXin Li
6471*67e74705SXin Li Builder.AddTypedTextChunk(Key);
6472*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6473*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6474*67e74705SXin Li }
6475*67e74705SXin Li
6476*67e74705SXin Li // If we have an integral or boolean property (or the user has provided
6477*67e74705SXin Li // an integral or boolean return type), add the accessor -(type)isKey.
6478*67e74705SXin Li if (IsInstanceMethod &&
6479*67e74705SXin Li ((!ReturnType.isNull() &&
6480*67e74705SXin Li (ReturnType->isIntegerType() || ReturnType->isBooleanType())) ||
6481*67e74705SXin Li (ReturnType.isNull() &&
6482*67e74705SXin Li (Property->getType()->isIntegerType() ||
6483*67e74705SXin Li Property->getType()->isBooleanType())))) {
6484*67e74705SXin Li std::string SelectorName = (Twine("is") + UpperKey).str();
6485*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6486*67e74705SXin Li if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
6487*67e74705SXin Li .second) {
6488*67e74705SXin Li if (ReturnType.isNull()) {
6489*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6490*67e74705SXin Li Builder.AddTextChunk("BOOL");
6491*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6492*67e74705SXin Li }
6493*67e74705SXin Li
6494*67e74705SXin Li Builder.AddTypedTextChunk(
6495*67e74705SXin Li Allocator.CopyString(SelectorId->getName()));
6496*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6497*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6498*67e74705SXin Li }
6499*67e74705SXin Li }
6500*67e74705SXin Li
6501*67e74705SXin Li // Add the normal mutator.
6502*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid &&
6503*67e74705SXin Li !Property->getSetterMethodDecl()) {
6504*67e74705SXin Li std::string SelectorName = (Twine("set") + UpperKey).str();
6505*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6506*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6507*67e74705SXin Li if (ReturnType.isNull()) {
6508*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6509*67e74705SXin Li Builder.AddTextChunk("void");
6510*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6511*67e74705SXin Li }
6512*67e74705SXin Li
6513*67e74705SXin Li Builder.AddTypedTextChunk(
6514*67e74705SXin Li Allocator.CopyString(SelectorId->getName()));
6515*67e74705SXin Li Builder.AddTypedTextChunk(":");
6516*67e74705SXin Li AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0,
6517*67e74705SXin Li Context, Policy, Builder);
6518*67e74705SXin Li Builder.AddTextChunk(Key);
6519*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
6520*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6521*67e74705SXin Li }
6522*67e74705SXin Li }
6523*67e74705SXin Li
6524*67e74705SXin Li // Indexed and unordered accessors
6525*67e74705SXin Li unsigned IndexedGetterPriority = CCP_CodePattern;
6526*67e74705SXin Li unsigned IndexedSetterPriority = CCP_CodePattern;
6527*67e74705SXin Li unsigned UnorderedGetterPriority = CCP_CodePattern;
6528*67e74705SXin Li unsigned UnorderedSetterPriority = CCP_CodePattern;
6529*67e74705SXin Li if (const ObjCObjectPointerType *ObjCPointer
6530*67e74705SXin Li = Property->getType()->getAs<ObjCObjectPointerType>()) {
6531*67e74705SXin Li if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) {
6532*67e74705SXin Li // If this interface type is not provably derived from a known
6533*67e74705SXin Li // collection, penalize the corresponding completions.
6534*67e74705SXin Li if (!InheritsFromClassNamed(IFace, "NSMutableArray")) {
6535*67e74705SXin Li IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
6536*67e74705SXin Li if (!InheritsFromClassNamed(IFace, "NSArray"))
6537*67e74705SXin Li IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
6538*67e74705SXin Li }
6539*67e74705SXin Li
6540*67e74705SXin Li if (!InheritsFromClassNamed(IFace, "NSMutableSet")) {
6541*67e74705SXin Li UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
6542*67e74705SXin Li if (!InheritsFromClassNamed(IFace, "NSSet"))
6543*67e74705SXin Li UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
6544*67e74705SXin Li }
6545*67e74705SXin Li }
6546*67e74705SXin Li } else {
6547*67e74705SXin Li IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
6548*67e74705SXin Li IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
6549*67e74705SXin Li UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
6550*67e74705SXin Li UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
6551*67e74705SXin Li }
6552*67e74705SXin Li
6553*67e74705SXin Li // Add -(NSUInteger)countOf<key>
6554*67e74705SXin Li if (IsInstanceMethod &&
6555*67e74705SXin Li (ReturnType.isNull() || ReturnType->isIntegerType())) {
6556*67e74705SXin Li std::string SelectorName = (Twine("countOf") + UpperKey).str();
6557*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6558*67e74705SXin Li if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
6559*67e74705SXin Li .second) {
6560*67e74705SXin Li if (ReturnType.isNull()) {
6561*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6562*67e74705SXin Li Builder.AddTextChunk("NSUInteger");
6563*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6564*67e74705SXin Li }
6565*67e74705SXin Li
6566*67e74705SXin Li Builder.AddTypedTextChunk(
6567*67e74705SXin Li Allocator.CopyString(SelectorId->getName()));
6568*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(),
6569*67e74705SXin Li std::min(IndexedGetterPriority,
6570*67e74705SXin Li UnorderedGetterPriority),
6571*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6572*67e74705SXin Li }
6573*67e74705SXin Li }
6574*67e74705SXin Li
6575*67e74705SXin Li // Indexed getters
6576*67e74705SXin Li // Add -(id)objectInKeyAtIndex:(NSUInteger)index
6577*67e74705SXin Li if (IsInstanceMethod &&
6578*67e74705SXin Li (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
6579*67e74705SXin Li std::string SelectorName
6580*67e74705SXin Li = (Twine("objectIn") + UpperKey + "AtIndex").str();
6581*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6582*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6583*67e74705SXin Li if (ReturnType.isNull()) {
6584*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6585*67e74705SXin Li Builder.AddTextChunk("id");
6586*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6587*67e74705SXin Li }
6588*67e74705SXin Li
6589*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6590*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6591*67e74705SXin Li Builder.AddTextChunk("NSUInteger");
6592*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6593*67e74705SXin Li Builder.AddTextChunk("index");
6594*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6595*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6596*67e74705SXin Li }
6597*67e74705SXin Li }
6598*67e74705SXin Li
6599*67e74705SXin Li // Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes
6600*67e74705SXin Li if (IsInstanceMethod &&
6601*67e74705SXin Li (ReturnType.isNull() ||
6602*67e74705SXin Li (ReturnType->isObjCObjectPointerType() &&
6603*67e74705SXin Li ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6604*67e74705SXin Li ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6605*67e74705SXin Li ->getName() == "NSArray"))) {
6606*67e74705SXin Li std::string SelectorName
6607*67e74705SXin Li = (Twine(Property->getName()) + "AtIndexes").str();
6608*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6609*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6610*67e74705SXin Li if (ReturnType.isNull()) {
6611*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6612*67e74705SXin Li Builder.AddTextChunk("NSArray *");
6613*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6614*67e74705SXin Li }
6615*67e74705SXin Li
6616*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6617*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6618*67e74705SXin Li Builder.AddTextChunk("NSIndexSet *");
6619*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6620*67e74705SXin Li Builder.AddTextChunk("indexes");
6621*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6622*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6623*67e74705SXin Li }
6624*67e74705SXin Li }
6625*67e74705SXin Li
6626*67e74705SXin Li // Add -(void)getKey:(type **)buffer range:(NSRange)inRange
6627*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6628*67e74705SXin Li std::string SelectorName = (Twine("get") + UpperKey).str();
6629*67e74705SXin Li IdentifierInfo *SelectorIds[2] = {
6630*67e74705SXin Li &Context.Idents.get(SelectorName),
6631*67e74705SXin Li &Context.Idents.get("range")
6632*67e74705SXin Li };
6633*67e74705SXin Li
6634*67e74705SXin Li if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
6635*67e74705SXin Li if (ReturnType.isNull()) {
6636*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6637*67e74705SXin Li Builder.AddTextChunk("void");
6638*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6639*67e74705SXin Li }
6640*67e74705SXin Li
6641*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6642*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6643*67e74705SXin Li Builder.AddPlaceholderChunk("object-type");
6644*67e74705SXin Li Builder.AddTextChunk(" **");
6645*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6646*67e74705SXin Li Builder.AddTextChunk("buffer");
6647*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6648*67e74705SXin Li Builder.AddTypedTextChunk("range:");
6649*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6650*67e74705SXin Li Builder.AddTextChunk("NSRange");
6651*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6652*67e74705SXin Li Builder.AddTextChunk("inRange");
6653*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
6654*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6655*67e74705SXin Li }
6656*67e74705SXin Li }
6657*67e74705SXin Li
6658*67e74705SXin Li // Mutable indexed accessors
6659*67e74705SXin Li
6660*67e74705SXin Li // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index
6661*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6662*67e74705SXin Li std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str();
6663*67e74705SXin Li IdentifierInfo *SelectorIds[2] = {
6664*67e74705SXin Li &Context.Idents.get("insertObject"),
6665*67e74705SXin Li &Context.Idents.get(SelectorName)
6666*67e74705SXin Li };
6667*67e74705SXin Li
6668*67e74705SXin Li if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
6669*67e74705SXin Li if (ReturnType.isNull()) {
6670*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6671*67e74705SXin Li Builder.AddTextChunk("void");
6672*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6673*67e74705SXin Li }
6674*67e74705SXin Li
6675*67e74705SXin Li Builder.AddTypedTextChunk("insertObject:");
6676*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6677*67e74705SXin Li Builder.AddPlaceholderChunk("object-type");
6678*67e74705SXin Li Builder.AddTextChunk(" *");
6679*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6680*67e74705SXin Li Builder.AddTextChunk("object");
6681*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6682*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6683*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6684*67e74705SXin Li Builder.AddPlaceholderChunk("NSUInteger");
6685*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6686*67e74705SXin Li Builder.AddTextChunk("index");
6687*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6688*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6689*67e74705SXin Li }
6690*67e74705SXin Li }
6691*67e74705SXin Li
6692*67e74705SXin Li // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes
6693*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6694*67e74705SXin Li std::string SelectorName = (Twine("insert") + UpperKey).str();
6695*67e74705SXin Li IdentifierInfo *SelectorIds[2] = {
6696*67e74705SXin Li &Context.Idents.get(SelectorName),
6697*67e74705SXin Li &Context.Idents.get("atIndexes")
6698*67e74705SXin Li };
6699*67e74705SXin Li
6700*67e74705SXin Li if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
6701*67e74705SXin Li if (ReturnType.isNull()) {
6702*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6703*67e74705SXin Li Builder.AddTextChunk("void");
6704*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6705*67e74705SXin Li }
6706*67e74705SXin Li
6707*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6708*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6709*67e74705SXin Li Builder.AddTextChunk("NSArray *");
6710*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6711*67e74705SXin Li Builder.AddTextChunk("array");
6712*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6713*67e74705SXin Li Builder.AddTypedTextChunk("atIndexes:");
6714*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6715*67e74705SXin Li Builder.AddPlaceholderChunk("NSIndexSet *");
6716*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6717*67e74705SXin Li Builder.AddTextChunk("indexes");
6718*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6719*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6720*67e74705SXin Li }
6721*67e74705SXin Li }
6722*67e74705SXin Li
6723*67e74705SXin Li // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index
6724*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6725*67e74705SXin Li std::string SelectorName
6726*67e74705SXin Li = (Twine("removeObjectFrom") + UpperKey + "AtIndex").str();
6727*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6728*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6729*67e74705SXin Li if (ReturnType.isNull()) {
6730*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6731*67e74705SXin Li Builder.AddTextChunk("void");
6732*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6733*67e74705SXin Li }
6734*67e74705SXin Li
6735*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6736*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6737*67e74705SXin Li Builder.AddTextChunk("NSUInteger");
6738*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6739*67e74705SXin Li Builder.AddTextChunk("index");
6740*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6741*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6742*67e74705SXin Li }
6743*67e74705SXin Li }
6744*67e74705SXin Li
6745*67e74705SXin Li // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes
6746*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6747*67e74705SXin Li std::string SelectorName
6748*67e74705SXin Li = (Twine("remove") + UpperKey + "AtIndexes").str();
6749*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6750*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6751*67e74705SXin Li if (ReturnType.isNull()) {
6752*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6753*67e74705SXin Li Builder.AddTextChunk("void");
6754*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6755*67e74705SXin Li }
6756*67e74705SXin Li
6757*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6758*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6759*67e74705SXin Li Builder.AddTextChunk("NSIndexSet *");
6760*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6761*67e74705SXin Li Builder.AddTextChunk("indexes");
6762*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6763*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6764*67e74705SXin Li }
6765*67e74705SXin Li }
6766*67e74705SXin Li
6767*67e74705SXin Li // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object
6768*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6769*67e74705SXin Li std::string SelectorName
6770*67e74705SXin Li = (Twine("replaceObjectIn") + UpperKey + "AtIndex").str();
6771*67e74705SXin Li IdentifierInfo *SelectorIds[2] = {
6772*67e74705SXin Li &Context.Idents.get(SelectorName),
6773*67e74705SXin Li &Context.Idents.get("withObject")
6774*67e74705SXin Li };
6775*67e74705SXin Li
6776*67e74705SXin Li if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
6777*67e74705SXin Li if (ReturnType.isNull()) {
6778*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6779*67e74705SXin Li Builder.AddTextChunk("void");
6780*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6781*67e74705SXin Li }
6782*67e74705SXin Li
6783*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6784*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6785*67e74705SXin Li Builder.AddPlaceholderChunk("NSUInteger");
6786*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6787*67e74705SXin Li Builder.AddTextChunk("index");
6788*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6789*67e74705SXin Li Builder.AddTypedTextChunk("withObject:");
6790*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6791*67e74705SXin Li Builder.AddTextChunk("id");
6792*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6793*67e74705SXin Li Builder.AddTextChunk("object");
6794*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6795*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6796*67e74705SXin Li }
6797*67e74705SXin Li }
6798*67e74705SXin Li
6799*67e74705SXin Li // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array
6800*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6801*67e74705SXin Li std::string SelectorName1
6802*67e74705SXin Li = (Twine("replace") + UpperKey + "AtIndexes").str();
6803*67e74705SXin Li std::string SelectorName2 = (Twine("with") + UpperKey).str();
6804*67e74705SXin Li IdentifierInfo *SelectorIds[2] = {
6805*67e74705SXin Li &Context.Idents.get(SelectorName1),
6806*67e74705SXin Li &Context.Idents.get(SelectorName2)
6807*67e74705SXin Li };
6808*67e74705SXin Li
6809*67e74705SXin Li if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
6810*67e74705SXin Li if (ReturnType.isNull()) {
6811*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6812*67e74705SXin Li Builder.AddTextChunk("void");
6813*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6814*67e74705SXin Li }
6815*67e74705SXin Li
6816*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName1 + ":"));
6817*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6818*67e74705SXin Li Builder.AddPlaceholderChunk("NSIndexSet *");
6819*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6820*67e74705SXin Li Builder.AddTextChunk("indexes");
6821*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6822*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName2 + ":"));
6823*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6824*67e74705SXin Li Builder.AddTextChunk("NSArray *");
6825*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6826*67e74705SXin Li Builder.AddTextChunk("array");
6827*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
6828*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6829*67e74705SXin Li }
6830*67e74705SXin Li }
6831*67e74705SXin Li
6832*67e74705SXin Li // Unordered getters
6833*67e74705SXin Li // - (NSEnumerator *)enumeratorOfKey
6834*67e74705SXin Li if (IsInstanceMethod &&
6835*67e74705SXin Li (ReturnType.isNull() ||
6836*67e74705SXin Li (ReturnType->isObjCObjectPointerType() &&
6837*67e74705SXin Li ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
6838*67e74705SXin Li ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
6839*67e74705SXin Li ->getName() == "NSEnumerator"))) {
6840*67e74705SXin Li std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str();
6841*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6842*67e74705SXin Li if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
6843*67e74705SXin Li .second) {
6844*67e74705SXin Li if (ReturnType.isNull()) {
6845*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6846*67e74705SXin Li Builder.AddTextChunk("NSEnumerator *");
6847*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6848*67e74705SXin Li }
6849*67e74705SXin Li
6850*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
6851*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
6852*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6853*67e74705SXin Li }
6854*67e74705SXin Li }
6855*67e74705SXin Li
6856*67e74705SXin Li // - (type *)memberOfKey:(type *)object
6857*67e74705SXin Li if (IsInstanceMethod &&
6858*67e74705SXin Li (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
6859*67e74705SXin Li std::string SelectorName = (Twine("memberOf") + UpperKey).str();
6860*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6861*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6862*67e74705SXin Li if (ReturnType.isNull()) {
6863*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6864*67e74705SXin Li Builder.AddPlaceholderChunk("object-type");
6865*67e74705SXin Li Builder.AddTextChunk(" *");
6866*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6867*67e74705SXin Li }
6868*67e74705SXin Li
6869*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6870*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6871*67e74705SXin Li if (ReturnType.isNull()) {
6872*67e74705SXin Li Builder.AddPlaceholderChunk("object-type");
6873*67e74705SXin Li Builder.AddTextChunk(" *");
6874*67e74705SXin Li } else {
6875*67e74705SXin Li Builder.AddTextChunk(GetCompletionTypeString(ReturnType, Context,
6876*67e74705SXin Li Policy,
6877*67e74705SXin Li Builder.getAllocator()));
6878*67e74705SXin Li }
6879*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6880*67e74705SXin Li Builder.AddTextChunk("object");
6881*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
6882*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6883*67e74705SXin Li }
6884*67e74705SXin Li }
6885*67e74705SXin Li
6886*67e74705SXin Li // Mutable unordered accessors
6887*67e74705SXin Li // - (void)addKeyObject:(type *)object
6888*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6889*67e74705SXin Li std::string SelectorName
6890*67e74705SXin Li = (Twine("add") + UpperKey + Twine("Object")).str();
6891*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6892*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6893*67e74705SXin Li if (ReturnType.isNull()) {
6894*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6895*67e74705SXin Li Builder.AddTextChunk("void");
6896*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6897*67e74705SXin Li }
6898*67e74705SXin Li
6899*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6900*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6901*67e74705SXin Li Builder.AddPlaceholderChunk("object-type");
6902*67e74705SXin Li Builder.AddTextChunk(" *");
6903*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6904*67e74705SXin Li Builder.AddTextChunk("object");
6905*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6906*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6907*67e74705SXin Li }
6908*67e74705SXin Li }
6909*67e74705SXin Li
6910*67e74705SXin Li // - (void)addKey:(NSSet *)objects
6911*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6912*67e74705SXin Li std::string SelectorName = (Twine("add") + UpperKey).str();
6913*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6914*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6915*67e74705SXin Li if (ReturnType.isNull()) {
6916*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6917*67e74705SXin Li Builder.AddTextChunk("void");
6918*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6919*67e74705SXin Li }
6920*67e74705SXin Li
6921*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6922*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6923*67e74705SXin Li Builder.AddTextChunk("NSSet *");
6924*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6925*67e74705SXin Li Builder.AddTextChunk("objects");
6926*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6927*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6928*67e74705SXin Li }
6929*67e74705SXin Li }
6930*67e74705SXin Li
6931*67e74705SXin Li // - (void)removeKeyObject:(type *)object
6932*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6933*67e74705SXin Li std::string SelectorName
6934*67e74705SXin Li = (Twine("remove") + UpperKey + Twine("Object")).str();
6935*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6936*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6937*67e74705SXin Li if (ReturnType.isNull()) {
6938*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6939*67e74705SXin Li Builder.AddTextChunk("void");
6940*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6941*67e74705SXin Li }
6942*67e74705SXin Li
6943*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6944*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6945*67e74705SXin Li Builder.AddPlaceholderChunk("object-type");
6946*67e74705SXin Li Builder.AddTextChunk(" *");
6947*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6948*67e74705SXin Li Builder.AddTextChunk("object");
6949*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6950*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6951*67e74705SXin Li }
6952*67e74705SXin Li }
6953*67e74705SXin Li
6954*67e74705SXin Li // - (void)removeKey:(NSSet *)objects
6955*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6956*67e74705SXin Li std::string SelectorName = (Twine("remove") + UpperKey).str();
6957*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6958*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6959*67e74705SXin Li if (ReturnType.isNull()) {
6960*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6961*67e74705SXin Li Builder.AddTextChunk("void");
6962*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6963*67e74705SXin Li }
6964*67e74705SXin Li
6965*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6966*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6967*67e74705SXin Li Builder.AddTextChunk("NSSet *");
6968*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6969*67e74705SXin Li Builder.AddTextChunk("objects");
6970*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6971*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6972*67e74705SXin Li }
6973*67e74705SXin Li }
6974*67e74705SXin Li
6975*67e74705SXin Li // - (void)intersectKey:(NSSet *)objects
6976*67e74705SXin Li if (IsInstanceMethod && ReturnTypeMatchesVoid) {
6977*67e74705SXin Li std::string SelectorName = (Twine("intersect") + UpperKey).str();
6978*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
6979*67e74705SXin Li if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
6980*67e74705SXin Li if (ReturnType.isNull()) {
6981*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6982*67e74705SXin Li Builder.AddTextChunk("void");
6983*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6984*67e74705SXin Li }
6985*67e74705SXin Li
6986*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
6987*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6988*67e74705SXin Li Builder.AddTextChunk("NSSet *");
6989*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
6990*67e74705SXin Li Builder.AddTextChunk("objects");
6991*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
6992*67e74705SXin Li CXCursor_ObjCInstanceMethodDecl));
6993*67e74705SXin Li }
6994*67e74705SXin Li }
6995*67e74705SXin Li
6996*67e74705SXin Li // Key-Value Observing
6997*67e74705SXin Li // + (NSSet *)keyPathsForValuesAffectingKey
6998*67e74705SXin Li if (!IsInstanceMethod &&
6999*67e74705SXin Li (ReturnType.isNull() ||
7000*67e74705SXin Li (ReturnType->isObjCObjectPointerType() &&
7001*67e74705SXin Li ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
7002*67e74705SXin Li ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl()
7003*67e74705SXin Li ->getName() == "NSSet"))) {
7004*67e74705SXin Li std::string SelectorName
7005*67e74705SXin Li = (Twine("keyPathsForValuesAffecting") + UpperKey).str();
7006*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7007*67e74705SXin Li if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
7008*67e74705SXin Li .second) {
7009*67e74705SXin Li if (ReturnType.isNull()) {
7010*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7011*67e74705SXin Li Builder.AddTextChunk("NSSet *");
7012*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
7013*67e74705SXin Li }
7014*67e74705SXin Li
7015*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
7016*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
7017*67e74705SXin Li CXCursor_ObjCClassMethodDecl));
7018*67e74705SXin Li }
7019*67e74705SXin Li }
7020*67e74705SXin Li
7021*67e74705SXin Li // + (BOOL)automaticallyNotifiesObserversForKey
7022*67e74705SXin Li if (!IsInstanceMethod &&
7023*67e74705SXin Li (ReturnType.isNull() ||
7024*67e74705SXin Li ReturnType->isIntegerType() ||
7025*67e74705SXin Li ReturnType->isBooleanType())) {
7026*67e74705SXin Li std::string SelectorName
7027*67e74705SXin Li = (Twine("automaticallyNotifiesObserversOf") + UpperKey).str();
7028*67e74705SXin Li IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
7029*67e74705SXin Li if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
7030*67e74705SXin Li .second) {
7031*67e74705SXin Li if (ReturnType.isNull()) {
7032*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7033*67e74705SXin Li Builder.AddTextChunk("BOOL");
7034*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
7035*67e74705SXin Li }
7036*67e74705SXin Li
7037*67e74705SXin Li Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
7038*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
7039*67e74705SXin Li CXCursor_ObjCClassMethodDecl));
7040*67e74705SXin Li }
7041*67e74705SXin Li }
7042*67e74705SXin Li }
7043*67e74705SXin Li
CodeCompleteObjCMethodDecl(Scope * S,bool IsInstanceMethod,ParsedType ReturnTy)7044*67e74705SXin Li void Sema::CodeCompleteObjCMethodDecl(Scope *S,
7045*67e74705SXin Li bool IsInstanceMethod,
7046*67e74705SXin Li ParsedType ReturnTy) {
7047*67e74705SXin Li // Determine the return type of the method we're declaring, if
7048*67e74705SXin Li // provided.
7049*67e74705SXin Li QualType ReturnType = GetTypeFromParser(ReturnTy);
7050*67e74705SXin Li Decl *IDecl = nullptr;
7051*67e74705SXin Li if (CurContext->isObjCContainer()) {
7052*67e74705SXin Li ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
7053*67e74705SXin Li IDecl = cast<Decl>(OCD);
7054*67e74705SXin Li }
7055*67e74705SXin Li // Determine where we should start searching for methods.
7056*67e74705SXin Li ObjCContainerDecl *SearchDecl = nullptr;
7057*67e74705SXin Li bool IsInImplementation = false;
7058*67e74705SXin Li if (Decl *D = IDecl) {
7059*67e74705SXin Li if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
7060*67e74705SXin Li SearchDecl = Impl->getClassInterface();
7061*67e74705SXin Li IsInImplementation = true;
7062*67e74705SXin Li } else if (ObjCCategoryImplDecl *CatImpl
7063*67e74705SXin Li = dyn_cast<ObjCCategoryImplDecl>(D)) {
7064*67e74705SXin Li SearchDecl = CatImpl->getCategoryDecl();
7065*67e74705SXin Li IsInImplementation = true;
7066*67e74705SXin Li } else
7067*67e74705SXin Li SearchDecl = dyn_cast<ObjCContainerDecl>(D);
7068*67e74705SXin Li }
7069*67e74705SXin Li
7070*67e74705SXin Li if (!SearchDecl && S) {
7071*67e74705SXin Li if (DeclContext *DC = S->getEntity())
7072*67e74705SXin Li SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
7073*67e74705SXin Li }
7074*67e74705SXin Li
7075*67e74705SXin Li if (!SearchDecl) {
7076*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
7077*67e74705SXin Li CodeCompletionContext::CCC_Other,
7078*67e74705SXin Li nullptr, 0);
7079*67e74705SXin Li return;
7080*67e74705SXin Li }
7081*67e74705SXin Li
7082*67e74705SXin Li // Find all of the methods that we could declare/implement here.
7083*67e74705SXin Li KnownMethodsMap KnownMethods;
7084*67e74705SXin Li FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
7085*67e74705SXin Li ReturnType, KnownMethods);
7086*67e74705SXin Li
7087*67e74705SXin Li // Add declarations or definitions for each of the known methods.
7088*67e74705SXin Li typedef CodeCompletionResult Result;
7089*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7090*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
7091*67e74705SXin Li CodeCompletionContext::CCC_Other);
7092*67e74705SXin Li Results.EnterNewScope();
7093*67e74705SXin Li PrintingPolicy Policy = getCompletionPrintingPolicy(*this);
7094*67e74705SXin Li for (KnownMethodsMap::iterator M = KnownMethods.begin(),
7095*67e74705SXin Li MEnd = KnownMethods.end();
7096*67e74705SXin Li M != MEnd; ++M) {
7097*67e74705SXin Li ObjCMethodDecl *Method = M->second.getPointer();
7098*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
7099*67e74705SXin Li Results.getCodeCompletionTUInfo());
7100*67e74705SXin Li
7101*67e74705SXin Li // If the result type was not already provided, add it to the
7102*67e74705SXin Li // pattern as (type).
7103*67e74705SXin Li if (ReturnType.isNull()) {
7104*67e74705SXin Li QualType ResTy = Method->getSendResultType().stripObjCKindOfType(Context);
7105*67e74705SXin Li AttributedType::stripOuterNullability(ResTy);
7106*67e74705SXin Li AddObjCPassingTypeChunk(ResTy,
7107*67e74705SXin Li Method->getObjCDeclQualifier(), Context, Policy,
7108*67e74705SXin Li Builder);
7109*67e74705SXin Li }
7110*67e74705SXin Li
7111*67e74705SXin Li Selector Sel = Method->getSelector();
7112*67e74705SXin Li
7113*67e74705SXin Li // Add the first part of the selector to the pattern.
7114*67e74705SXin Li Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
7115*67e74705SXin Li Sel.getNameForSlot(0)));
7116*67e74705SXin Li
7117*67e74705SXin Li // Add parameters to the pattern.
7118*67e74705SXin Li unsigned I = 0;
7119*67e74705SXin Li for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
7120*67e74705SXin Li PEnd = Method->param_end();
7121*67e74705SXin Li P != PEnd; (void)++P, ++I) {
7122*67e74705SXin Li // Add the part of the selector name.
7123*67e74705SXin Li if (I == 0)
7124*67e74705SXin Li Builder.AddTypedTextChunk(":");
7125*67e74705SXin Li else if (I < Sel.getNumArgs()) {
7126*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7127*67e74705SXin Li Builder.AddTypedTextChunk(
7128*67e74705SXin Li Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
7129*67e74705SXin Li } else
7130*67e74705SXin Li break;
7131*67e74705SXin Li
7132*67e74705SXin Li // Add the parameter type.
7133*67e74705SXin Li QualType ParamType;
7134*67e74705SXin Li if ((*P)->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
7135*67e74705SXin Li ParamType = (*P)->getType();
7136*67e74705SXin Li else
7137*67e74705SXin Li ParamType = (*P)->getOriginalType();
7138*67e74705SXin Li ParamType = ParamType.substObjCTypeArgs(Context, {},
7139*67e74705SXin Li ObjCSubstitutionContext::Parameter);
7140*67e74705SXin Li AttributedType::stripOuterNullability(ParamType);
7141*67e74705SXin Li AddObjCPassingTypeChunk(ParamType,
7142*67e74705SXin Li (*P)->getObjCDeclQualifier(),
7143*67e74705SXin Li Context, Policy,
7144*67e74705SXin Li Builder);
7145*67e74705SXin Li
7146*67e74705SXin Li if (IdentifierInfo *Id = (*P)->getIdentifier())
7147*67e74705SXin Li Builder.AddTextChunk(Builder.getAllocator().CopyString( Id->getName()));
7148*67e74705SXin Li }
7149*67e74705SXin Li
7150*67e74705SXin Li if (Method->isVariadic()) {
7151*67e74705SXin Li if (Method->param_size() > 0)
7152*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_Comma);
7153*67e74705SXin Li Builder.AddTextChunk("...");
7154*67e74705SXin Li }
7155*67e74705SXin Li
7156*67e74705SXin Li if (IsInImplementation && Results.includeCodePatterns()) {
7157*67e74705SXin Li // We will be defining the method here, so add a compound statement.
7158*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7159*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7160*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
7161*67e74705SXin Li if (!Method->getReturnType()->isVoidType()) {
7162*67e74705SXin Li // If the result type is not void, add a return clause.
7163*67e74705SXin Li Builder.AddTextChunk("return");
7164*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7165*67e74705SXin Li Builder.AddPlaceholderChunk("expression");
7166*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_SemiColon);
7167*67e74705SXin Li } else
7168*67e74705SXin Li Builder.AddPlaceholderChunk("statements");
7169*67e74705SXin Li
7170*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
7171*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7172*67e74705SXin Li }
7173*67e74705SXin Li
7174*67e74705SXin Li unsigned Priority = CCP_CodePattern;
7175*67e74705SXin Li if (!M->second.getInt())
7176*67e74705SXin Li Priority += CCD_InBaseClass;
7177*67e74705SXin Li
7178*67e74705SXin Li Results.AddResult(Result(Builder.TakeString(), Method, Priority));
7179*67e74705SXin Li }
7180*67e74705SXin Li
7181*67e74705SXin Li // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of
7182*67e74705SXin Li // the properties in this class and its categories.
7183*67e74705SXin Li if (Context.getLangOpts().ObjC2) {
7184*67e74705SXin Li SmallVector<ObjCContainerDecl *, 4> Containers;
7185*67e74705SXin Li Containers.push_back(SearchDecl);
7186*67e74705SXin Li
7187*67e74705SXin Li VisitedSelectorSet KnownSelectors;
7188*67e74705SXin Li for (KnownMethodsMap::iterator M = KnownMethods.begin(),
7189*67e74705SXin Li MEnd = KnownMethods.end();
7190*67e74705SXin Li M != MEnd; ++M)
7191*67e74705SXin Li KnownSelectors.insert(M->first);
7192*67e74705SXin Li
7193*67e74705SXin Li
7194*67e74705SXin Li ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl);
7195*67e74705SXin Li if (!IFace)
7196*67e74705SXin Li if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl))
7197*67e74705SXin Li IFace = Category->getClassInterface();
7198*67e74705SXin Li
7199*67e74705SXin Li if (IFace)
7200*67e74705SXin Li for (auto *Cat : IFace->visible_categories())
7201*67e74705SXin Li Containers.push_back(Cat);
7202*67e74705SXin Li
7203*67e74705SXin Li for (unsigned I = 0, N = Containers.size(); I != N; ++I)
7204*67e74705SXin Li for (auto *P : Containers[I]->instance_properties())
7205*67e74705SXin Li AddObjCKeyValueCompletions(P, IsInstanceMethod, ReturnType, Context,
7206*67e74705SXin Li KnownSelectors, Results);
7207*67e74705SXin Li }
7208*67e74705SXin Li
7209*67e74705SXin Li Results.ExitScope();
7210*67e74705SXin Li
7211*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
7212*67e74705SXin Li CodeCompletionContext::CCC_Other,
7213*67e74705SXin Li Results.data(),Results.size());
7214*67e74705SXin Li }
7215*67e74705SXin Li
CodeCompleteObjCMethodDeclSelector(Scope * S,bool IsInstanceMethod,bool AtParameterName,ParsedType ReturnTy,ArrayRef<IdentifierInfo * > SelIdents)7216*67e74705SXin Li void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
7217*67e74705SXin Li bool IsInstanceMethod,
7218*67e74705SXin Li bool AtParameterName,
7219*67e74705SXin Li ParsedType ReturnTy,
7220*67e74705SXin Li ArrayRef<IdentifierInfo *> SelIdents) {
7221*67e74705SXin Li // If we have an external source, load the entire class method
7222*67e74705SXin Li // pool from the AST file.
7223*67e74705SXin Li if (ExternalSource) {
7224*67e74705SXin Li for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
7225*67e74705SXin Li I != N; ++I) {
7226*67e74705SXin Li Selector Sel = ExternalSource->GetExternalSelector(I);
7227*67e74705SXin Li if (Sel.isNull() || MethodPool.count(Sel))
7228*67e74705SXin Li continue;
7229*67e74705SXin Li
7230*67e74705SXin Li ReadMethodPool(Sel);
7231*67e74705SXin Li }
7232*67e74705SXin Li }
7233*67e74705SXin Li
7234*67e74705SXin Li // Build the set of methods we can see.
7235*67e74705SXin Li typedef CodeCompletionResult Result;
7236*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7237*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
7238*67e74705SXin Li CodeCompletionContext::CCC_Other);
7239*67e74705SXin Li
7240*67e74705SXin Li if (ReturnTy)
7241*67e74705SXin Li Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
7242*67e74705SXin Li
7243*67e74705SXin Li Results.EnterNewScope();
7244*67e74705SXin Li for (GlobalMethodPool::iterator M = MethodPool.begin(),
7245*67e74705SXin Li MEnd = MethodPool.end();
7246*67e74705SXin Li M != MEnd; ++M) {
7247*67e74705SXin Li for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
7248*67e74705SXin Li &M->second.second;
7249*67e74705SXin Li MethList && MethList->getMethod();
7250*67e74705SXin Li MethList = MethList->getNext()) {
7251*67e74705SXin Li if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
7252*67e74705SXin Li continue;
7253*67e74705SXin Li
7254*67e74705SXin Li if (AtParameterName) {
7255*67e74705SXin Li // Suggest parameter names we've seen before.
7256*67e74705SXin Li unsigned NumSelIdents = SelIdents.size();
7257*67e74705SXin Li if (NumSelIdents &&
7258*67e74705SXin Li NumSelIdents <= MethList->getMethod()->param_size()) {
7259*67e74705SXin Li ParmVarDecl *Param =
7260*67e74705SXin Li MethList->getMethod()->parameters()[NumSelIdents - 1];
7261*67e74705SXin Li if (Param->getIdentifier()) {
7262*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
7263*67e74705SXin Li Results.getCodeCompletionTUInfo());
7264*67e74705SXin Li Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
7265*67e74705SXin Li Param->getIdentifier()->getName()));
7266*67e74705SXin Li Results.AddResult(Builder.TakeString());
7267*67e74705SXin Li }
7268*67e74705SXin Li }
7269*67e74705SXin Li
7270*67e74705SXin Li continue;
7271*67e74705SXin Li }
7272*67e74705SXin Li
7273*67e74705SXin Li Result R(MethList->getMethod(),
7274*67e74705SXin Li Results.getBasePriority(MethList->getMethod()), nullptr);
7275*67e74705SXin Li R.StartParameter = SelIdents.size();
7276*67e74705SXin Li R.AllParametersAreInformative = false;
7277*67e74705SXin Li R.DeclaringEntity = true;
7278*67e74705SXin Li Results.MaybeAddResult(R, CurContext);
7279*67e74705SXin Li }
7280*67e74705SXin Li }
7281*67e74705SXin Li
7282*67e74705SXin Li Results.ExitScope();
7283*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
7284*67e74705SXin Li CodeCompletionContext::CCC_Other,
7285*67e74705SXin Li Results.data(),Results.size());
7286*67e74705SXin Li }
7287*67e74705SXin Li
CodeCompletePreprocessorDirective(bool InConditional)7288*67e74705SXin Li void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
7289*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7290*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
7291*67e74705SXin Li CodeCompletionContext::CCC_PreprocessorDirective);
7292*67e74705SXin Li Results.EnterNewScope();
7293*67e74705SXin Li
7294*67e74705SXin Li // #if <condition>
7295*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
7296*67e74705SXin Li Results.getCodeCompletionTUInfo());
7297*67e74705SXin Li Builder.AddTypedTextChunk("if");
7298*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7299*67e74705SXin Li Builder.AddPlaceholderChunk("condition");
7300*67e74705SXin Li Results.AddResult(Builder.TakeString());
7301*67e74705SXin Li
7302*67e74705SXin Li // #ifdef <macro>
7303*67e74705SXin Li Builder.AddTypedTextChunk("ifdef");
7304*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7305*67e74705SXin Li Builder.AddPlaceholderChunk("macro");
7306*67e74705SXin Li Results.AddResult(Builder.TakeString());
7307*67e74705SXin Li
7308*67e74705SXin Li // #ifndef <macro>
7309*67e74705SXin Li Builder.AddTypedTextChunk("ifndef");
7310*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7311*67e74705SXin Li Builder.AddPlaceholderChunk("macro");
7312*67e74705SXin Li Results.AddResult(Builder.TakeString());
7313*67e74705SXin Li
7314*67e74705SXin Li if (InConditional) {
7315*67e74705SXin Li // #elif <condition>
7316*67e74705SXin Li Builder.AddTypedTextChunk("elif");
7317*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7318*67e74705SXin Li Builder.AddPlaceholderChunk("condition");
7319*67e74705SXin Li Results.AddResult(Builder.TakeString());
7320*67e74705SXin Li
7321*67e74705SXin Li // #else
7322*67e74705SXin Li Builder.AddTypedTextChunk("else");
7323*67e74705SXin Li Results.AddResult(Builder.TakeString());
7324*67e74705SXin Li
7325*67e74705SXin Li // #endif
7326*67e74705SXin Li Builder.AddTypedTextChunk("endif");
7327*67e74705SXin Li Results.AddResult(Builder.TakeString());
7328*67e74705SXin Li }
7329*67e74705SXin Li
7330*67e74705SXin Li // #include "header"
7331*67e74705SXin Li Builder.AddTypedTextChunk("include");
7332*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7333*67e74705SXin Li Builder.AddTextChunk("\"");
7334*67e74705SXin Li Builder.AddPlaceholderChunk("header");
7335*67e74705SXin Li Builder.AddTextChunk("\"");
7336*67e74705SXin Li Results.AddResult(Builder.TakeString());
7337*67e74705SXin Li
7338*67e74705SXin Li // #include <header>
7339*67e74705SXin Li Builder.AddTypedTextChunk("include");
7340*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7341*67e74705SXin Li Builder.AddTextChunk("<");
7342*67e74705SXin Li Builder.AddPlaceholderChunk("header");
7343*67e74705SXin Li Builder.AddTextChunk(">");
7344*67e74705SXin Li Results.AddResult(Builder.TakeString());
7345*67e74705SXin Li
7346*67e74705SXin Li // #define <macro>
7347*67e74705SXin Li Builder.AddTypedTextChunk("define");
7348*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7349*67e74705SXin Li Builder.AddPlaceholderChunk("macro");
7350*67e74705SXin Li Results.AddResult(Builder.TakeString());
7351*67e74705SXin Li
7352*67e74705SXin Li // #define <macro>(<args>)
7353*67e74705SXin Li Builder.AddTypedTextChunk("define");
7354*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7355*67e74705SXin Li Builder.AddPlaceholderChunk("macro");
7356*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7357*67e74705SXin Li Builder.AddPlaceholderChunk("args");
7358*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
7359*67e74705SXin Li Results.AddResult(Builder.TakeString());
7360*67e74705SXin Li
7361*67e74705SXin Li // #undef <macro>
7362*67e74705SXin Li Builder.AddTypedTextChunk("undef");
7363*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7364*67e74705SXin Li Builder.AddPlaceholderChunk("macro");
7365*67e74705SXin Li Results.AddResult(Builder.TakeString());
7366*67e74705SXin Li
7367*67e74705SXin Li // #line <number>
7368*67e74705SXin Li Builder.AddTypedTextChunk("line");
7369*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7370*67e74705SXin Li Builder.AddPlaceholderChunk("number");
7371*67e74705SXin Li Results.AddResult(Builder.TakeString());
7372*67e74705SXin Li
7373*67e74705SXin Li // #line <number> "filename"
7374*67e74705SXin Li Builder.AddTypedTextChunk("line");
7375*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7376*67e74705SXin Li Builder.AddPlaceholderChunk("number");
7377*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7378*67e74705SXin Li Builder.AddTextChunk("\"");
7379*67e74705SXin Li Builder.AddPlaceholderChunk("filename");
7380*67e74705SXin Li Builder.AddTextChunk("\"");
7381*67e74705SXin Li Results.AddResult(Builder.TakeString());
7382*67e74705SXin Li
7383*67e74705SXin Li // #error <message>
7384*67e74705SXin Li Builder.AddTypedTextChunk("error");
7385*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7386*67e74705SXin Li Builder.AddPlaceholderChunk("message");
7387*67e74705SXin Li Results.AddResult(Builder.TakeString());
7388*67e74705SXin Li
7389*67e74705SXin Li // #pragma <arguments>
7390*67e74705SXin Li Builder.AddTypedTextChunk("pragma");
7391*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7392*67e74705SXin Li Builder.AddPlaceholderChunk("arguments");
7393*67e74705SXin Li Results.AddResult(Builder.TakeString());
7394*67e74705SXin Li
7395*67e74705SXin Li if (getLangOpts().ObjC1) {
7396*67e74705SXin Li // #import "header"
7397*67e74705SXin Li Builder.AddTypedTextChunk("import");
7398*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7399*67e74705SXin Li Builder.AddTextChunk("\"");
7400*67e74705SXin Li Builder.AddPlaceholderChunk("header");
7401*67e74705SXin Li Builder.AddTextChunk("\"");
7402*67e74705SXin Li Results.AddResult(Builder.TakeString());
7403*67e74705SXin Li
7404*67e74705SXin Li // #import <header>
7405*67e74705SXin Li Builder.AddTypedTextChunk("import");
7406*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7407*67e74705SXin Li Builder.AddTextChunk("<");
7408*67e74705SXin Li Builder.AddPlaceholderChunk("header");
7409*67e74705SXin Li Builder.AddTextChunk(">");
7410*67e74705SXin Li Results.AddResult(Builder.TakeString());
7411*67e74705SXin Li }
7412*67e74705SXin Li
7413*67e74705SXin Li // #include_next "header"
7414*67e74705SXin Li Builder.AddTypedTextChunk("include_next");
7415*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7416*67e74705SXin Li Builder.AddTextChunk("\"");
7417*67e74705SXin Li Builder.AddPlaceholderChunk("header");
7418*67e74705SXin Li Builder.AddTextChunk("\"");
7419*67e74705SXin Li Results.AddResult(Builder.TakeString());
7420*67e74705SXin Li
7421*67e74705SXin Li // #include_next <header>
7422*67e74705SXin Li Builder.AddTypedTextChunk("include_next");
7423*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7424*67e74705SXin Li Builder.AddTextChunk("<");
7425*67e74705SXin Li Builder.AddPlaceholderChunk("header");
7426*67e74705SXin Li Builder.AddTextChunk(">");
7427*67e74705SXin Li Results.AddResult(Builder.TakeString());
7428*67e74705SXin Li
7429*67e74705SXin Li // #warning <message>
7430*67e74705SXin Li Builder.AddTypedTextChunk("warning");
7431*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7432*67e74705SXin Li Builder.AddPlaceholderChunk("message");
7433*67e74705SXin Li Results.AddResult(Builder.TakeString());
7434*67e74705SXin Li
7435*67e74705SXin Li // Note: #ident and #sccs are such crazy anachronisms that we don't provide
7436*67e74705SXin Li // completions for them. And __include_macros is a Clang-internal extension
7437*67e74705SXin Li // that we don't want to encourage anyone to use.
7438*67e74705SXin Li
7439*67e74705SXin Li // FIXME: we don't support #assert or #unassert, so don't suggest them.
7440*67e74705SXin Li Results.ExitScope();
7441*67e74705SXin Li
7442*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
7443*67e74705SXin Li CodeCompletionContext::CCC_PreprocessorDirective,
7444*67e74705SXin Li Results.data(), Results.size());
7445*67e74705SXin Li }
7446*67e74705SXin Li
CodeCompleteInPreprocessorConditionalExclusion(Scope * S)7447*67e74705SXin Li void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
7448*67e74705SXin Li CodeCompleteOrdinaryName(S,
7449*67e74705SXin Li S->getFnParent()? Sema::PCC_RecoveryInFunction
7450*67e74705SXin Li : Sema::PCC_Namespace);
7451*67e74705SXin Li }
7452*67e74705SXin Li
CodeCompletePreprocessorMacroName(bool IsDefinition)7453*67e74705SXin Li void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
7454*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7455*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
7456*67e74705SXin Li IsDefinition? CodeCompletionContext::CCC_MacroName
7457*67e74705SXin Li : CodeCompletionContext::CCC_MacroNameUse);
7458*67e74705SXin Li if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
7459*67e74705SXin Li // Add just the names of macros, not their arguments.
7460*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
7461*67e74705SXin Li Results.getCodeCompletionTUInfo());
7462*67e74705SXin Li Results.EnterNewScope();
7463*67e74705SXin Li for (Preprocessor::macro_iterator M = PP.macro_begin(),
7464*67e74705SXin Li MEnd = PP.macro_end();
7465*67e74705SXin Li M != MEnd; ++M) {
7466*67e74705SXin Li Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
7467*67e74705SXin Li M->first->getName()));
7468*67e74705SXin Li Results.AddResult(CodeCompletionResult(Builder.TakeString(),
7469*67e74705SXin Li CCP_CodePattern,
7470*67e74705SXin Li CXCursor_MacroDefinition));
7471*67e74705SXin Li }
7472*67e74705SXin Li Results.ExitScope();
7473*67e74705SXin Li } else if (IsDefinition) {
7474*67e74705SXin Li // FIXME: Can we detect when the user just wrote an include guard above?
7475*67e74705SXin Li }
7476*67e74705SXin Li
7477*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
7478*67e74705SXin Li Results.data(), Results.size());
7479*67e74705SXin Li }
7480*67e74705SXin Li
CodeCompletePreprocessorExpression()7481*67e74705SXin Li void Sema::CodeCompletePreprocessorExpression() {
7482*67e74705SXin Li ResultBuilder Results(*this, CodeCompleter->getAllocator(),
7483*67e74705SXin Li CodeCompleter->getCodeCompletionTUInfo(),
7484*67e74705SXin Li CodeCompletionContext::CCC_PreprocessorExpression);
7485*67e74705SXin Li
7486*67e74705SXin Li if (!CodeCompleter || CodeCompleter->includeMacros())
7487*67e74705SXin Li AddMacroResults(PP, Results, true);
7488*67e74705SXin Li
7489*67e74705SXin Li // defined (<macro>)
7490*67e74705SXin Li Results.EnterNewScope();
7491*67e74705SXin Li CodeCompletionBuilder Builder(Results.getAllocator(),
7492*67e74705SXin Li Results.getCodeCompletionTUInfo());
7493*67e74705SXin Li Builder.AddTypedTextChunk("defined");
7494*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7495*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7496*67e74705SXin Li Builder.AddPlaceholderChunk("macro");
7497*67e74705SXin Li Builder.AddChunk(CodeCompletionString::CK_RightParen);
7498*67e74705SXin Li Results.AddResult(Builder.TakeString());
7499*67e74705SXin Li Results.ExitScope();
7500*67e74705SXin Li
7501*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
7502*67e74705SXin Li CodeCompletionContext::CCC_PreprocessorExpression,
7503*67e74705SXin Li Results.data(), Results.size());
7504*67e74705SXin Li }
7505*67e74705SXin Li
CodeCompletePreprocessorMacroArgument(Scope * S,IdentifierInfo * Macro,MacroInfo * MacroInfo,unsigned Argument)7506*67e74705SXin Li void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
7507*67e74705SXin Li IdentifierInfo *Macro,
7508*67e74705SXin Li MacroInfo *MacroInfo,
7509*67e74705SXin Li unsigned Argument) {
7510*67e74705SXin Li // FIXME: In the future, we could provide "overload" results, much like we
7511*67e74705SXin Li // do for function calls.
7512*67e74705SXin Li
7513*67e74705SXin Li // Now just ignore this. There will be another code-completion callback
7514*67e74705SXin Li // for the expanded tokens.
7515*67e74705SXin Li }
7516*67e74705SXin Li
CodeCompleteNaturalLanguage()7517*67e74705SXin Li void Sema::CodeCompleteNaturalLanguage() {
7518*67e74705SXin Li HandleCodeCompleteResults(this, CodeCompleter,
7519*67e74705SXin Li CodeCompletionContext::CCC_NaturalLanguage,
7520*67e74705SXin Li nullptr, 0);
7521*67e74705SXin Li }
7522*67e74705SXin Li
GatherGlobalCodeCompletions(CodeCompletionAllocator & Allocator,CodeCompletionTUInfo & CCTUInfo,SmallVectorImpl<CodeCompletionResult> & Results)7523*67e74705SXin Li void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
7524*67e74705SXin Li CodeCompletionTUInfo &CCTUInfo,
7525*67e74705SXin Li SmallVectorImpl<CodeCompletionResult> &Results) {
7526*67e74705SXin Li ResultBuilder Builder(*this, Allocator, CCTUInfo,
7527*67e74705SXin Li CodeCompletionContext::CCC_Recovery);
7528*67e74705SXin Li if (!CodeCompleter || CodeCompleter->includeGlobals()) {
7529*67e74705SXin Li CodeCompletionDeclConsumer Consumer(Builder,
7530*67e74705SXin Li Context.getTranslationUnitDecl());
7531*67e74705SXin Li LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
7532*67e74705SXin Li Consumer);
7533*67e74705SXin Li }
7534*67e74705SXin Li
7535*67e74705SXin Li if (!CodeCompleter || CodeCompleter->includeMacros())
7536*67e74705SXin Li AddMacroResults(PP, Builder, true);
7537*67e74705SXin Li
7538*67e74705SXin Li Results.clear();
7539*67e74705SXin Li Results.insert(Results.end(),
7540*67e74705SXin Li Builder.data(), Builder.data() + Builder.size());
7541*67e74705SXin Li }
7542