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