Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Sema/SemaCodeComplete.cpp
35233 views
1
//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines the code-completion semantic actions.
10
//
11
//===----------------------------------------------------------------------===//
12
#include "clang/AST/ASTConcept.h"
13
#include "clang/AST/Decl.h"
14
#include "clang/AST/DeclBase.h"
15
#include "clang/AST/DeclCXX.h"
16
#include "clang/AST/DeclObjC.h"
17
#include "clang/AST/DeclTemplate.h"
18
#include "clang/AST/Expr.h"
19
#include "clang/AST/ExprCXX.h"
20
#include "clang/AST/ExprConcepts.h"
21
#include "clang/AST/ExprObjC.h"
22
#include "clang/AST/NestedNameSpecifier.h"
23
#include "clang/AST/OperationKinds.h"
24
#include "clang/AST/QualTypeNames.h"
25
#include "clang/AST/RecursiveASTVisitor.h"
26
#include "clang/AST/Type.h"
27
#include "clang/Basic/AttributeCommonInfo.h"
28
#include "clang/Basic/CharInfo.h"
29
#include "clang/Basic/OperatorKinds.h"
30
#include "clang/Basic/Specifiers.h"
31
#include "clang/Lex/HeaderSearch.h"
32
#include "clang/Lex/MacroInfo.h"
33
#include "clang/Lex/Preprocessor.h"
34
#include "clang/Sema/CodeCompleteConsumer.h"
35
#include "clang/Sema/DeclSpec.h"
36
#include "clang/Sema/Designator.h"
37
#include "clang/Sema/Lookup.h"
38
#include "clang/Sema/Overload.h"
39
#include "clang/Sema/ParsedAttr.h"
40
#include "clang/Sema/ParsedTemplate.h"
41
#include "clang/Sema/Scope.h"
42
#include "clang/Sema/ScopeInfo.h"
43
#include "clang/Sema/Sema.h"
44
#include "clang/Sema/SemaCodeCompletion.h"
45
#include "clang/Sema/SemaInternal.h"
46
#include "clang/Sema/SemaObjC.h"
47
#include "llvm/ADT/ArrayRef.h"
48
#include "llvm/ADT/DenseSet.h"
49
#include "llvm/ADT/SmallBitVector.h"
50
#include "llvm/ADT/SmallPtrSet.h"
51
#include "llvm/ADT/SmallString.h"
52
#include "llvm/ADT/StringExtras.h"
53
#include "llvm/ADT/StringSwitch.h"
54
#include "llvm/ADT/Twine.h"
55
#include "llvm/ADT/iterator_range.h"
56
#include "llvm/Support/Casting.h"
57
#include "llvm/Support/Path.h"
58
#include "llvm/Support/raw_ostream.h"
59
60
#include <list>
61
#include <map>
62
#include <optional>
63
#include <string>
64
#include <vector>
65
66
using namespace clang;
67
using namespace sema;
68
69
namespace {
70
/// A container of code-completion results.
71
class ResultBuilder {
72
public:
73
/// The type of a name-lookup filter, which can be provided to the
74
/// name-lookup routines to specify which declarations should be included in
75
/// the result set (when it returns true) and which declarations should be
76
/// filtered out (returns false).
77
typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const;
78
79
typedef CodeCompletionResult Result;
80
81
private:
82
/// The actual results we have found.
83
std::vector<Result> Results;
84
85
/// A record of all of the declarations we have found and placed
86
/// into the result set, used to ensure that no declaration ever gets into
87
/// the result set twice.
88
llvm::SmallPtrSet<const Decl *, 16> AllDeclsFound;
89
90
typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair;
91
92
/// An entry in the shadow map, which is optimized to store
93
/// a single (declaration, index) mapping (the common case) but
94
/// can also store a list of (declaration, index) mappings.
95
class ShadowMapEntry {
96
typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
97
98
/// Contains either the solitary NamedDecl * or a vector
99
/// of (declaration, index) pairs.
100
llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector *> DeclOrVector;
101
102
/// When the entry contains a single declaration, this is
103
/// the index associated with that entry.
104
unsigned SingleDeclIndex = 0;
105
106
public:
107
ShadowMapEntry() = default;
108
ShadowMapEntry(const ShadowMapEntry &) = delete;
109
ShadowMapEntry(ShadowMapEntry &&Move) { *this = std::move(Move); }
110
ShadowMapEntry &operator=(const ShadowMapEntry &) = delete;
111
ShadowMapEntry &operator=(ShadowMapEntry &&Move) {
112
SingleDeclIndex = Move.SingleDeclIndex;
113
DeclOrVector = Move.DeclOrVector;
114
Move.DeclOrVector = nullptr;
115
return *this;
116
}
117
118
void Add(const NamedDecl *ND, unsigned Index) {
119
if (DeclOrVector.isNull()) {
120
// 0 - > 1 elements: just set the single element information.
121
DeclOrVector = ND;
122
SingleDeclIndex = Index;
123
return;
124
}
125
126
if (const NamedDecl *PrevND =
127
DeclOrVector.dyn_cast<const NamedDecl *>()) {
128
// 1 -> 2 elements: create the vector of results and push in the
129
// existing declaration.
130
DeclIndexPairVector *Vec = new DeclIndexPairVector;
131
Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
132
DeclOrVector = Vec;
133
}
134
135
// Add the new element to the end of the vector.
136
DeclOrVector.get<DeclIndexPairVector *>()->push_back(
137
DeclIndexPair(ND, Index));
138
}
139
140
~ShadowMapEntry() {
141
if (DeclIndexPairVector *Vec =
142
DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
143
delete Vec;
144
DeclOrVector = ((NamedDecl *)nullptr);
145
}
146
}
147
148
// Iteration.
149
class iterator;
150
iterator begin() const;
151
iterator end() const;
152
};
153
154
/// A mapping from declaration names to the declarations that have
155
/// this name within a particular scope and their index within the list of
156
/// results.
157
typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
158
159
/// The semantic analysis object for which results are being
160
/// produced.
161
Sema &SemaRef;
162
163
/// The allocator used to allocate new code-completion strings.
164
CodeCompletionAllocator &Allocator;
165
166
CodeCompletionTUInfo &CCTUInfo;
167
168
/// If non-NULL, a filter function used to remove any code-completion
169
/// results that are not desirable.
170
LookupFilter Filter;
171
172
/// Whether we should allow declarations as
173
/// nested-name-specifiers that would otherwise be filtered out.
174
bool AllowNestedNameSpecifiers;
175
176
/// If set, the type that we would prefer our resulting value
177
/// declarations to have.
178
///
179
/// Closely matching the preferred type gives a boost to a result's
180
/// priority.
181
CanQualType PreferredType;
182
183
/// A list of shadow maps, which is used to model name hiding at
184
/// different levels of, e.g., the inheritance hierarchy.
185
std::list<ShadowMap> ShadowMaps;
186
187
/// Overloaded C++ member functions found by SemaLookup.
188
/// Used to determine when one overload is dominated by another.
189
llvm::DenseMap<std::pair<DeclContext *, /*Name*/uintptr_t>, ShadowMapEntry>
190
OverloadMap;
191
192
/// If we're potentially referring to a C++ member function, the set
193
/// of qualifiers applied to the object type.
194
Qualifiers ObjectTypeQualifiers;
195
/// The kind of the object expression, for rvalue/lvalue overloads.
196
ExprValueKind ObjectKind;
197
198
/// Whether the \p ObjectTypeQualifiers field is active.
199
bool HasObjectTypeQualifiers;
200
201
/// The selector that we prefer.
202
Selector PreferredSelector;
203
204
/// The completion context in which we are gathering results.
205
CodeCompletionContext CompletionContext;
206
207
/// If we are in an instance method definition, the \@implementation
208
/// object.
209
ObjCImplementationDecl *ObjCImplementation;
210
211
void AdjustResultPriorityForDecl(Result &R);
212
213
void MaybeAddConstructorResults(Result R);
214
215
public:
216
explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
217
CodeCompletionTUInfo &CCTUInfo,
218
const CodeCompletionContext &CompletionContext,
219
LookupFilter Filter = nullptr)
220
: SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo),
221
Filter(Filter), AllowNestedNameSpecifiers(false),
222
HasObjectTypeQualifiers(false), CompletionContext(CompletionContext),
223
ObjCImplementation(nullptr) {
224
// If this is an Objective-C instance method definition, dig out the
225
// corresponding implementation.
226
switch (CompletionContext.getKind()) {
227
case CodeCompletionContext::CCC_Expression:
228
case CodeCompletionContext::CCC_ObjCMessageReceiver:
229
case CodeCompletionContext::CCC_ParenthesizedExpression:
230
case CodeCompletionContext::CCC_Statement:
231
case CodeCompletionContext::CCC_TopLevelOrExpression:
232
case CodeCompletionContext::CCC_Recovery:
233
if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
234
if (Method->isInstanceMethod())
235
if (ObjCInterfaceDecl *Interface = Method->getClassInterface())
236
ObjCImplementation = Interface->getImplementation();
237
break;
238
239
default:
240
break;
241
}
242
}
243
244
/// Determine the priority for a reference to the given declaration.
245
unsigned getBasePriority(const NamedDecl *D);
246
247
/// Whether we should include code patterns in the completion
248
/// results.
249
bool includeCodePatterns() const {
250
return SemaRef.CodeCompletion().CodeCompleter &&
251
SemaRef.CodeCompletion().CodeCompleter->includeCodePatterns();
252
}
253
254
/// Set the filter used for code-completion results.
255
void setFilter(LookupFilter Filter) { this->Filter = Filter; }
256
257
Result *data() { return Results.empty() ? nullptr : &Results.front(); }
258
unsigned size() const { return Results.size(); }
259
bool empty() const { return Results.empty(); }
260
261
/// Specify the preferred type.
262
void setPreferredType(QualType T) {
263
PreferredType = SemaRef.Context.getCanonicalType(T);
264
}
265
266
/// Set the cv-qualifiers on the object type, for us in filtering
267
/// calls to member functions.
268
///
269
/// When there are qualifiers in this set, they will be used to filter
270
/// out member functions that aren't available (because there will be a
271
/// cv-qualifier mismatch) or prefer functions with an exact qualifier
272
/// match.
273
void setObjectTypeQualifiers(Qualifiers Quals, ExprValueKind Kind) {
274
ObjectTypeQualifiers = Quals;
275
ObjectKind = Kind;
276
HasObjectTypeQualifiers = true;
277
}
278
279
/// Set the preferred selector.
280
///
281
/// When an Objective-C method declaration result is added, and that
282
/// method's selector matches this preferred selector, we give that method
283
/// a slight priority boost.
284
void setPreferredSelector(Selector Sel) { PreferredSelector = Sel; }
285
286
/// Retrieve the code-completion context for which results are
287
/// being collected.
288
const CodeCompletionContext &getCompletionContext() const {
289
return CompletionContext;
290
}
291
292
/// Specify whether nested-name-specifiers are allowed.
293
void allowNestedNameSpecifiers(bool Allow = true) {
294
AllowNestedNameSpecifiers = Allow;
295
}
296
297
/// Return the semantic analysis object for which we are collecting
298
/// code completion results.
299
Sema &getSema() const { return SemaRef; }
300
301
/// Retrieve the allocator used to allocate code completion strings.
302
CodeCompletionAllocator &getAllocator() const { return Allocator; }
303
304
CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
305
306
/// Determine whether the given declaration is at all interesting
307
/// as a code-completion result.
308
///
309
/// \param ND the declaration that we are inspecting.
310
///
311
/// \param AsNestedNameSpecifier will be set true if this declaration is
312
/// only interesting when it is a nested-name-specifier.
313
bool isInterestingDecl(const NamedDecl *ND,
314
bool &AsNestedNameSpecifier) const;
315
316
/// Decide whether or not a use of function Decl can be a call.
317
///
318
/// \param ND the function declaration.
319
///
320
/// \param BaseExprType the object type in a member access expression,
321
/// if any.
322
bool canFunctionBeCalled(const NamedDecl *ND, QualType BaseExprType) const;
323
324
/// Decide whether or not a use of member function Decl can be a call.
325
///
326
/// \param Method the function declaration.
327
///
328
/// \param BaseExprType the object type in a member access expression,
329
/// if any.
330
bool canCxxMethodBeCalled(const CXXMethodDecl *Method,
331
QualType BaseExprType) const;
332
333
/// Check whether the result is hidden by the Hiding declaration.
334
///
335
/// \returns true if the result is hidden and cannot be found, false if
336
/// the hidden result could still be found. When false, \p R may be
337
/// modified to describe how the result can be found (e.g., via extra
338
/// qualification).
339
bool CheckHiddenResult(Result &R, DeclContext *CurContext,
340
const NamedDecl *Hiding);
341
342
/// Add a new result to this result set (if it isn't already in one
343
/// of the shadow maps), or replace an existing result (for, e.g., a
344
/// redeclaration).
345
///
346
/// \param R the result to add (if it is unique).
347
///
348
/// \param CurContext the context in which this result will be named.
349
void MaybeAddResult(Result R, DeclContext *CurContext = nullptr);
350
351
/// Add a new result to this result set, where we already know
352
/// the hiding declaration (if any).
353
///
354
/// \param R the result to add (if it is unique).
355
///
356
/// \param CurContext the context in which this result will be named.
357
///
358
/// \param Hiding the declaration that hides the result.
359
///
360
/// \param InBaseClass whether the result was found in a base
361
/// class of the searched context.
362
///
363
/// \param BaseExprType the type of expression that precedes the "." or "->"
364
/// in a member access expression.
365
void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
366
bool InBaseClass, QualType BaseExprType);
367
368
/// Add a new non-declaration result to this result set.
369
void AddResult(Result R);
370
371
/// Enter into a new scope.
372
void EnterNewScope();
373
374
/// Exit from the current scope.
375
void ExitScope();
376
377
/// Ignore this declaration, if it is seen again.
378
void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
379
380
/// Add a visited context.
381
void addVisitedContext(DeclContext *Ctx) {
382
CompletionContext.addVisitedContext(Ctx);
383
}
384
385
/// \name Name lookup predicates
386
///
387
/// These predicates can be passed to the name lookup functions to filter the
388
/// results of name lookup. All of the predicates have the same type, so that
389
///
390
//@{
391
bool IsOrdinaryName(const NamedDecl *ND) const;
392
bool IsOrdinaryNonTypeName(const NamedDecl *ND) const;
393
bool IsIntegralConstantValue(const NamedDecl *ND) const;
394
bool IsOrdinaryNonValueName(const NamedDecl *ND) const;
395
bool IsNestedNameSpecifier(const NamedDecl *ND) const;
396
bool IsEnum(const NamedDecl *ND) const;
397
bool IsClassOrStruct(const NamedDecl *ND) const;
398
bool IsUnion(const NamedDecl *ND) const;
399
bool IsNamespace(const NamedDecl *ND) const;
400
bool IsNamespaceOrAlias(const NamedDecl *ND) const;
401
bool IsType(const NamedDecl *ND) const;
402
bool IsMember(const NamedDecl *ND) const;
403
bool IsObjCIvar(const NamedDecl *ND) const;
404
bool IsObjCMessageReceiver(const NamedDecl *ND) const;
405
bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const;
406
bool IsObjCCollection(const NamedDecl *ND) const;
407
bool IsImpossibleToSatisfy(const NamedDecl *ND) const;
408
//@}
409
};
410
} // namespace
411
412
void PreferredTypeBuilder::enterReturn(Sema &S, SourceLocation Tok) {
413
if (!Enabled)
414
return;
415
if (isa<BlockDecl>(S.CurContext)) {
416
if (sema::BlockScopeInfo *BSI = S.getCurBlock()) {
417
ComputeType = nullptr;
418
Type = BSI->ReturnType;
419
ExpectedLoc = Tok;
420
}
421
} else if (const auto *Function = dyn_cast<FunctionDecl>(S.CurContext)) {
422
ComputeType = nullptr;
423
Type = Function->getReturnType();
424
ExpectedLoc = Tok;
425
} else if (const auto *Method = dyn_cast<ObjCMethodDecl>(S.CurContext)) {
426
ComputeType = nullptr;
427
Type = Method->getReturnType();
428
ExpectedLoc = Tok;
429
}
430
}
431
432
void PreferredTypeBuilder::enterVariableInit(SourceLocation Tok, Decl *D) {
433
if (!Enabled)
434
return;
435
auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
436
ComputeType = nullptr;
437
Type = VD ? VD->getType() : QualType();
438
ExpectedLoc = Tok;
439
}
440
441
static QualType getDesignatedType(QualType BaseType, const Designation &Desig);
442
443
void PreferredTypeBuilder::enterDesignatedInitializer(SourceLocation Tok,
444
QualType BaseType,
445
const Designation &D) {
446
if (!Enabled)
447
return;
448
ComputeType = nullptr;
449
Type = getDesignatedType(BaseType, D);
450
ExpectedLoc = Tok;
451
}
452
453
void PreferredTypeBuilder::enterFunctionArgument(
454
SourceLocation Tok, llvm::function_ref<QualType()> ComputeType) {
455
if (!Enabled)
456
return;
457
this->ComputeType = ComputeType;
458
Type = QualType();
459
ExpectedLoc = Tok;
460
}
461
462
void PreferredTypeBuilder::enterParenExpr(SourceLocation Tok,
463
SourceLocation LParLoc) {
464
if (!Enabled)
465
return;
466
// expected type for parenthesized expression does not change.
467
if (ExpectedLoc == LParLoc)
468
ExpectedLoc = Tok;
469
}
470
471
static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS,
472
tok::TokenKind Op) {
473
if (!LHS)
474
return QualType();
475
476
QualType LHSType = LHS->getType();
477
if (LHSType->isPointerType()) {
478
if (Op == tok::plus || Op == tok::plusequal || Op == tok::minusequal)
479
return S.getASTContext().getPointerDiffType();
480
// Pointer difference is more common than subtracting an int from a pointer.
481
if (Op == tok::minus)
482
return LHSType;
483
}
484
485
switch (Op) {
486
// No way to infer the type of RHS from LHS.
487
case tok::comma:
488
return QualType();
489
// Prefer the type of the left operand for all of these.
490
// Arithmetic operations.
491
case tok::plus:
492
case tok::plusequal:
493
case tok::minus:
494
case tok::minusequal:
495
case tok::percent:
496
case tok::percentequal:
497
case tok::slash:
498
case tok::slashequal:
499
case tok::star:
500
case tok::starequal:
501
// Assignment.
502
case tok::equal:
503
// Comparison operators.
504
case tok::equalequal:
505
case tok::exclaimequal:
506
case tok::less:
507
case tok::lessequal:
508
case tok::greater:
509
case tok::greaterequal:
510
case tok::spaceship:
511
return LHS->getType();
512
// Binary shifts are often overloaded, so don't try to guess those.
513
case tok::greatergreater:
514
case tok::greatergreaterequal:
515
case tok::lessless:
516
case tok::lesslessequal:
517
if (LHSType->isIntegralOrEnumerationType())
518
return S.getASTContext().IntTy;
519
return QualType();
520
// Logical operators, assume we want bool.
521
case tok::ampamp:
522
case tok::pipepipe:
523
case tok::caretcaret:
524
return S.getASTContext().BoolTy;
525
// Operators often used for bit manipulation are typically used with the type
526
// of the left argument.
527
case tok::pipe:
528
case tok::pipeequal:
529
case tok::caret:
530
case tok::caretequal:
531
case tok::amp:
532
case tok::ampequal:
533
if (LHSType->isIntegralOrEnumerationType())
534
return LHSType;
535
return QualType();
536
// RHS should be a pointer to a member of the 'LHS' type, but we can't give
537
// any particular type here.
538
case tok::periodstar:
539
case tok::arrowstar:
540
return QualType();
541
default:
542
// FIXME(ibiryukov): handle the missing op, re-add the assertion.
543
// assert(false && "unhandled binary op");
544
return QualType();
545
}
546
}
547
548
/// Get preferred type for an argument of an unary expression. \p ContextType is
549
/// preferred type of the whole unary expression.
550
static QualType getPreferredTypeOfUnaryArg(Sema &S, QualType ContextType,
551
tok::TokenKind Op) {
552
switch (Op) {
553
case tok::exclaim:
554
return S.getASTContext().BoolTy;
555
case tok::amp:
556
if (!ContextType.isNull() && ContextType->isPointerType())
557
return ContextType->getPointeeType();
558
return QualType();
559
case tok::star:
560
if (ContextType.isNull())
561
return QualType();
562
return S.getASTContext().getPointerType(ContextType.getNonReferenceType());
563
case tok::plus:
564
case tok::minus:
565
case tok::tilde:
566
case tok::minusminus:
567
case tok::plusplus:
568
if (ContextType.isNull())
569
return S.getASTContext().IntTy;
570
// leave as is, these operators typically return the same type.
571
return ContextType;
572
case tok::kw___real:
573
case tok::kw___imag:
574
return QualType();
575
default:
576
assert(false && "unhandled unary op");
577
return QualType();
578
}
579
}
580
581
void PreferredTypeBuilder::enterBinary(Sema &S, SourceLocation Tok, Expr *LHS,
582
tok::TokenKind Op) {
583
if (!Enabled)
584
return;
585
ComputeType = nullptr;
586
Type = getPreferredTypeOfBinaryRHS(S, LHS, Op);
587
ExpectedLoc = Tok;
588
}
589
590
void PreferredTypeBuilder::enterMemAccess(Sema &S, SourceLocation Tok,
591
Expr *Base) {
592
if (!Enabled || !Base)
593
return;
594
// Do we have expected type for Base?
595
if (ExpectedLoc != Base->getBeginLoc())
596
return;
597
// Keep the expected type, only update the location.
598
ExpectedLoc = Tok;
599
}
600
601
void PreferredTypeBuilder::enterUnary(Sema &S, SourceLocation Tok,
602
tok::TokenKind OpKind,
603
SourceLocation OpLoc) {
604
if (!Enabled)
605
return;
606
ComputeType = nullptr;
607
Type = getPreferredTypeOfUnaryArg(S, this->get(OpLoc), OpKind);
608
ExpectedLoc = Tok;
609
}
610
611
void PreferredTypeBuilder::enterSubscript(Sema &S, SourceLocation Tok,
612
Expr *LHS) {
613
if (!Enabled)
614
return;
615
ComputeType = nullptr;
616
Type = S.getASTContext().IntTy;
617
ExpectedLoc = Tok;
618
}
619
620
void PreferredTypeBuilder::enterTypeCast(SourceLocation Tok,
621
QualType CastType) {
622
if (!Enabled)
623
return;
624
ComputeType = nullptr;
625
Type = !CastType.isNull() ? CastType.getCanonicalType() : QualType();
626
ExpectedLoc = Tok;
627
}
628
629
void PreferredTypeBuilder::enterCondition(Sema &S, SourceLocation Tok) {
630
if (!Enabled)
631
return;
632
ComputeType = nullptr;
633
Type = S.getASTContext().BoolTy;
634
ExpectedLoc = Tok;
635
}
636
637
class ResultBuilder::ShadowMapEntry::iterator {
638
llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator;
639
unsigned SingleDeclIndex;
640
641
public:
642
typedef DeclIndexPair value_type;
643
typedef value_type reference;
644
typedef std::ptrdiff_t difference_type;
645
typedef std::input_iterator_tag iterator_category;
646
647
class pointer {
648
DeclIndexPair Value;
649
650
public:
651
pointer(const DeclIndexPair &Value) : Value(Value) {}
652
653
const DeclIndexPair *operator->() const { return &Value; }
654
};
655
656
iterator() : DeclOrIterator((NamedDecl *)nullptr), SingleDeclIndex(0) {}
657
658
iterator(const NamedDecl *SingleDecl, unsigned Index)
659
: DeclOrIterator(SingleDecl), SingleDeclIndex(Index) {}
660
661
iterator(const DeclIndexPair *Iterator)
662
: DeclOrIterator(Iterator), SingleDeclIndex(0) {}
663
664
iterator &operator++() {
665
if (DeclOrIterator.is<const NamedDecl *>()) {
666
DeclOrIterator = (NamedDecl *)nullptr;
667
SingleDeclIndex = 0;
668
return *this;
669
}
670
671
const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair *>();
672
++I;
673
DeclOrIterator = I;
674
return *this;
675
}
676
677
/*iterator operator++(int) {
678
iterator tmp(*this);
679
++(*this);
680
return tmp;
681
}*/
682
683
reference operator*() const {
684
if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>())
685
return reference(ND, SingleDeclIndex);
686
687
return *DeclOrIterator.get<const DeclIndexPair *>();
688
}
689
690
pointer operator->() const { return pointer(**this); }
691
692
friend bool operator==(const iterator &X, const iterator &Y) {
693
return X.DeclOrIterator.getOpaqueValue() ==
694
Y.DeclOrIterator.getOpaqueValue() &&
695
X.SingleDeclIndex == Y.SingleDeclIndex;
696
}
697
698
friend bool operator!=(const iterator &X, const iterator &Y) {
699
return !(X == Y);
700
}
701
};
702
703
ResultBuilder::ShadowMapEntry::iterator
704
ResultBuilder::ShadowMapEntry::begin() const {
705
if (DeclOrVector.isNull())
706
return iterator();
707
708
if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>())
709
return iterator(ND, SingleDeclIndex);
710
711
return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
712
}
713
714
ResultBuilder::ShadowMapEntry::iterator
715
ResultBuilder::ShadowMapEntry::end() const {
716
if (DeclOrVector.is<const NamedDecl *>() || DeclOrVector.isNull())
717
return iterator();
718
719
return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
720
}
721
722
/// Compute the qualification required to get from the current context
723
/// (\p CurContext) to the target context (\p TargetContext).
724
///
725
/// \param Context the AST context in which the qualification will be used.
726
///
727
/// \param CurContext the context where an entity is being named, which is
728
/// typically based on the current scope.
729
///
730
/// \param TargetContext the context in which the named entity actually
731
/// resides.
732
///
733
/// \returns a nested name specifier that refers into the target context, or
734
/// NULL if no qualification is needed.
735
static NestedNameSpecifier *
736
getRequiredQualification(ASTContext &Context, const DeclContext *CurContext,
737
const DeclContext *TargetContext) {
738
SmallVector<const DeclContext *, 4> TargetParents;
739
740
for (const DeclContext *CommonAncestor = TargetContext;
741
CommonAncestor && !CommonAncestor->Encloses(CurContext);
742
CommonAncestor = CommonAncestor->getLookupParent()) {
743
if (CommonAncestor->isTransparentContext() ||
744
CommonAncestor->isFunctionOrMethod())
745
continue;
746
747
TargetParents.push_back(CommonAncestor);
748
}
749
750
NestedNameSpecifier *Result = nullptr;
751
while (!TargetParents.empty()) {
752
const DeclContext *Parent = TargetParents.pop_back_val();
753
754
if (const auto *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
755
if (!Namespace->getIdentifier())
756
continue;
757
758
Result = NestedNameSpecifier::Create(Context, Result, Namespace);
759
} else if (const auto *TD = dyn_cast<TagDecl>(Parent))
760
Result = NestedNameSpecifier::Create(
761
Context, Result, false, Context.getTypeDeclType(TD).getTypePtr());
762
}
763
return Result;
764
}
765
766
// Some declarations have reserved names that we don't want to ever show.
767
// Filter out names reserved for the implementation if they come from a
768
// system header.
769
static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) {
770
// Debuggers want access to all identifiers, including reserved ones.
771
if (SemaRef.getLangOpts().DebuggerSupport)
772
return false;
773
774
ReservedIdentifierStatus Status = ND->isReserved(SemaRef.getLangOpts());
775
// Ignore reserved names for compiler provided decls.
776
if (isReservedInAllContexts(Status) && ND->getLocation().isInvalid())
777
return true;
778
779
// For system headers ignore only double-underscore names.
780
// This allows for system headers providing private symbols with a single
781
// underscore.
782
if (Status == ReservedIdentifierStatus::StartsWithDoubleUnderscore &&
783
SemaRef.SourceMgr.isInSystemHeader(
784
SemaRef.SourceMgr.getSpellingLoc(ND->getLocation())))
785
return true;
786
787
return false;
788
}
789
790
bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
791
bool &AsNestedNameSpecifier) const {
792
AsNestedNameSpecifier = false;
793
794
auto *Named = ND;
795
ND = ND->getUnderlyingDecl();
796
797
// Skip unnamed entities.
798
if (!ND->getDeclName())
799
return false;
800
801
// Friend declarations and declarations introduced due to friends are never
802
// added as results.
803
if (ND->getFriendObjectKind() == Decl::FOK_Undeclared)
804
return false;
805
806
// Class template (partial) specializations are never added as results.
807
if (isa<ClassTemplateSpecializationDecl>(ND) ||
808
isa<ClassTemplatePartialSpecializationDecl>(ND))
809
return false;
810
811
// Using declarations themselves are never added as results.
812
if (isa<UsingDecl>(ND))
813
return false;
814
815
if (shouldIgnoreDueToReservedName(ND, SemaRef))
816
return false;
817
818
if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
819
(isa<NamespaceDecl>(ND) && Filter != &ResultBuilder::IsNamespace &&
820
Filter != &ResultBuilder::IsNamespaceOrAlias && Filter != nullptr))
821
AsNestedNameSpecifier = true;
822
823
// Filter out any unwanted results.
824
if (Filter && !(this->*Filter)(Named)) {
825
// Check whether it is interesting as a nested-name-specifier.
826
if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus &&
827
IsNestedNameSpecifier(ND) &&
828
(Filter != &ResultBuilder::IsMember ||
829
(isa<CXXRecordDecl>(ND) &&
830
cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
831
AsNestedNameSpecifier = true;
832
return true;
833
}
834
835
return false;
836
}
837
// ... then it must be interesting!
838
return true;
839
}
840
841
bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
842
const NamedDecl *Hiding) {
843
// In C, there is no way to refer to a hidden name.
844
// FIXME: This isn't true; we can find a tag name hidden by an ordinary
845
// name if we introduce the tag type.
846
if (!SemaRef.getLangOpts().CPlusPlus)
847
return true;
848
849
const DeclContext *HiddenCtx =
850
R.Declaration->getDeclContext()->getRedeclContext();
851
852
// There is no way to qualify a name declared in a function or method.
853
if (HiddenCtx->isFunctionOrMethod())
854
return true;
855
856
if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
857
return true;
858
859
// We can refer to the result with the appropriate qualification. Do it.
860
R.Hidden = true;
861
R.QualifierIsInformative = false;
862
863
if (!R.Qualifier)
864
R.Qualifier = getRequiredQualification(SemaRef.Context, CurContext,
865
R.Declaration->getDeclContext());
866
return false;
867
}
868
869
/// A simplified classification of types used to determine whether two
870
/// types are "similar enough" when adjusting priorities.
871
SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
872
switch (T->getTypeClass()) {
873
case Type::Builtin:
874
switch (cast<BuiltinType>(T)->getKind()) {
875
case BuiltinType::Void:
876
return STC_Void;
877
878
case BuiltinType::NullPtr:
879
return STC_Pointer;
880
881
case BuiltinType::Overload:
882
case BuiltinType::Dependent:
883
return STC_Other;
884
885
case BuiltinType::ObjCId:
886
case BuiltinType::ObjCClass:
887
case BuiltinType::ObjCSel:
888
return STC_ObjectiveC;
889
890
default:
891
return STC_Arithmetic;
892
}
893
894
case Type::Complex:
895
return STC_Arithmetic;
896
897
case Type::Pointer:
898
return STC_Pointer;
899
900
case Type::BlockPointer:
901
return STC_Block;
902
903
case Type::LValueReference:
904
case Type::RValueReference:
905
return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType());
906
907
case Type::ConstantArray:
908
case Type::IncompleteArray:
909
case Type::VariableArray:
910
case Type::DependentSizedArray:
911
return STC_Array;
912
913
case Type::DependentSizedExtVector:
914
case Type::Vector:
915
case Type::ExtVector:
916
return STC_Arithmetic;
917
918
case Type::FunctionProto:
919
case Type::FunctionNoProto:
920
return STC_Function;
921
922
case Type::Record:
923
return STC_Record;
924
925
case Type::Enum:
926
return STC_Arithmetic;
927
928
case Type::ObjCObject:
929
case Type::ObjCInterface:
930
case Type::ObjCObjectPointer:
931
return STC_ObjectiveC;
932
933
default:
934
return STC_Other;
935
}
936
}
937
938
/// Get the type that a given expression will have if this declaration
939
/// is used as an expression in its "typical" code-completion form.
940
QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
941
ND = ND->getUnderlyingDecl();
942
943
if (const auto *Type = dyn_cast<TypeDecl>(ND))
944
return C.getTypeDeclType(Type);
945
if (const auto *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
946
return C.getObjCInterfaceType(Iface);
947
948
QualType T;
949
if (const FunctionDecl *Function = ND->getAsFunction())
950
T = Function->getCallResultType();
951
else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND))
952
T = Method->getSendResultType();
953
else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND))
954
T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
955
else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND))
956
T = Property->getType();
957
else if (const auto *Value = dyn_cast<ValueDecl>(ND))
958
T = Value->getType();
959
960
if (T.isNull())
961
return QualType();
962
963
// Dig through references, function pointers, and block pointers to
964
// get down to the likely type of an expression when the entity is
965
// used.
966
do {
967
if (const auto *Ref = T->getAs<ReferenceType>()) {
968
T = Ref->getPointeeType();
969
continue;
970
}
971
972
if (const auto *Pointer = T->getAs<PointerType>()) {
973
if (Pointer->getPointeeType()->isFunctionType()) {
974
T = Pointer->getPointeeType();
975
continue;
976
}
977
978
break;
979
}
980
981
if (const auto *Block = T->getAs<BlockPointerType>()) {
982
T = Block->getPointeeType();
983
continue;
984
}
985
986
if (const auto *Function = T->getAs<FunctionType>()) {
987
T = Function->getReturnType();
988
continue;
989
}
990
991
break;
992
} while (true);
993
994
return T;
995
}
996
997
unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) {
998
if (!ND)
999
return CCP_Unlikely;
1000
1001
// Context-based decisions.
1002
const DeclContext *LexicalDC = ND->getLexicalDeclContext();
1003
if (LexicalDC->isFunctionOrMethod()) {
1004
// _cmd is relatively rare
1005
if (const auto *ImplicitParam = dyn_cast<ImplicitParamDecl>(ND))
1006
if (ImplicitParam->getIdentifier() &&
1007
ImplicitParam->getIdentifier()->isStr("_cmd"))
1008
return CCP_ObjC_cmd;
1009
1010
return CCP_LocalDeclaration;
1011
}
1012
1013
const DeclContext *DC = ND->getDeclContext()->getRedeclContext();
1014
if (DC->isRecord() || isa<ObjCContainerDecl>(DC)) {
1015
// Explicit destructor calls are very rare.
1016
if (isa<CXXDestructorDecl>(ND))
1017
return CCP_Unlikely;
1018
// Explicit operator and conversion function calls are also very rare.
1019
auto DeclNameKind = ND->getDeclName().getNameKind();
1020
if (DeclNameKind == DeclarationName::CXXOperatorName ||
1021
DeclNameKind == DeclarationName::CXXLiteralOperatorName ||
1022
DeclNameKind == DeclarationName::CXXConversionFunctionName)
1023
return CCP_Unlikely;
1024
return CCP_MemberDeclaration;
1025
}
1026
1027
// Content-based decisions.
1028
if (isa<EnumConstantDecl>(ND))
1029
return CCP_Constant;
1030
1031
// Use CCP_Type for type declarations unless we're in a statement, Objective-C
1032
// message receiver, or parenthesized expression context. There, it's as
1033
// likely that the user will want to write a type as other declarations.
1034
if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
1035
!(CompletionContext.getKind() == CodeCompletionContext::CCC_Statement ||
1036
CompletionContext.getKind() ==
1037
CodeCompletionContext::CCC_ObjCMessageReceiver ||
1038
CompletionContext.getKind() ==
1039
CodeCompletionContext::CCC_ParenthesizedExpression))
1040
return CCP_Type;
1041
1042
return CCP_Declaration;
1043
}
1044
1045
void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
1046
// If this is an Objective-C method declaration whose selector matches our
1047
// preferred selector, give it a priority boost.
1048
if (!PreferredSelector.isNull())
1049
if (const auto *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
1050
if (PreferredSelector == Method->getSelector())
1051
R.Priority += CCD_SelectorMatch;
1052
1053
// If we have a preferred type, adjust the priority for results with exactly-
1054
// matching or nearly-matching types.
1055
if (!PreferredType.isNull()) {
1056
QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
1057
if (!T.isNull()) {
1058
CanQualType TC = SemaRef.Context.getCanonicalType(T);
1059
// Check for exactly-matching types (modulo qualifiers).
1060
if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
1061
R.Priority /= CCF_ExactTypeMatch;
1062
// Check for nearly-matching types, based on classification of each.
1063
else if ((getSimplifiedTypeClass(PreferredType) ==
1064
getSimplifiedTypeClass(TC)) &&
1065
!(PreferredType->isEnumeralType() && TC->isEnumeralType()))
1066
R.Priority /= CCF_SimilarTypeMatch;
1067
}
1068
}
1069
}
1070
1071
static DeclContext::lookup_result getConstructors(ASTContext &Context,
1072
const CXXRecordDecl *Record) {
1073
QualType RecordTy = Context.getTypeDeclType(Record);
1074
DeclarationName ConstructorName =
1075
Context.DeclarationNames.getCXXConstructorName(
1076
Context.getCanonicalType(RecordTy));
1077
return Record->lookup(ConstructorName);
1078
}
1079
1080
void ResultBuilder::MaybeAddConstructorResults(Result R) {
1081
if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration ||
1082
!CompletionContext.wantConstructorResults())
1083
return;
1084
1085
const NamedDecl *D = R.Declaration;
1086
const CXXRecordDecl *Record = nullptr;
1087
if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
1088
Record = ClassTemplate->getTemplatedDecl();
1089
else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
1090
// Skip specializations and partial specializations.
1091
if (isa<ClassTemplateSpecializationDecl>(Record))
1092
return;
1093
} else {
1094
// There are no constructors here.
1095
return;
1096
}
1097
1098
Record = Record->getDefinition();
1099
if (!Record)
1100
return;
1101
1102
for (NamedDecl *Ctor : getConstructors(SemaRef.Context, Record)) {
1103
R.Declaration = Ctor;
1104
R.CursorKind = getCursorKindForDecl(R.Declaration);
1105
Results.push_back(R);
1106
}
1107
}
1108
1109
static bool isConstructor(const Decl *ND) {
1110
if (const auto *Tmpl = dyn_cast<FunctionTemplateDecl>(ND))
1111
ND = Tmpl->getTemplatedDecl();
1112
return isa<CXXConstructorDecl>(ND);
1113
}
1114
1115
void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
1116
assert(!ShadowMaps.empty() && "Must enter into a results scope");
1117
1118
if (R.Kind != Result::RK_Declaration) {
1119
// For non-declaration results, just add the result.
1120
Results.push_back(R);
1121
return;
1122
}
1123
1124
// Look through using declarations.
1125
if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
1126
CodeCompletionResult Result(Using->getTargetDecl(),
1127
getBasePriority(Using->getTargetDecl()),
1128
R.Qualifier, false,
1129
(R.Availability == CXAvailability_Available ||
1130
R.Availability == CXAvailability_Deprecated),
1131
std::move(R.FixIts));
1132
Result.ShadowDecl = Using;
1133
MaybeAddResult(Result, CurContext);
1134
return;
1135
}
1136
1137
const Decl *CanonDecl = R.Declaration->getCanonicalDecl();
1138
unsigned IDNS = CanonDecl->getIdentifierNamespace();
1139
1140
bool AsNestedNameSpecifier = false;
1141
if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
1142
return;
1143
1144
// C++ constructors are never found by name lookup.
1145
if (isConstructor(R.Declaration))
1146
return;
1147
1148
ShadowMap &SMap = ShadowMaps.back();
1149
ShadowMapEntry::iterator I, IEnd;
1150
ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
1151
if (NamePos != SMap.end()) {
1152
I = NamePos->second.begin();
1153
IEnd = NamePos->second.end();
1154
}
1155
1156
for (; I != IEnd; ++I) {
1157
const NamedDecl *ND = I->first;
1158
unsigned Index = I->second;
1159
if (ND->getCanonicalDecl() == CanonDecl) {
1160
// This is a redeclaration. Always pick the newer declaration.
1161
Results[Index].Declaration = R.Declaration;
1162
1163
// We're done.
1164
return;
1165
}
1166
}
1167
1168
// This is a new declaration in this scope. However, check whether this
1169
// declaration name is hidden by a similarly-named declaration in an outer
1170
// scope.
1171
std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
1172
--SMEnd;
1173
for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
1174
ShadowMapEntry::iterator I, IEnd;
1175
ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
1176
if (NamePos != SM->end()) {
1177
I = NamePos->second.begin();
1178
IEnd = NamePos->second.end();
1179
}
1180
for (; I != IEnd; ++I) {
1181
// A tag declaration does not hide a non-tag declaration.
1182
if (I->first->hasTagIdentifierNamespace() &&
1183
(IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
1184
Decl::IDNS_LocalExtern | Decl::IDNS_ObjCProtocol)))
1185
continue;
1186
1187
// Protocols are in distinct namespaces from everything else.
1188
if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol) ||
1189
(IDNS & Decl::IDNS_ObjCProtocol)) &&
1190
I->first->getIdentifierNamespace() != IDNS)
1191
continue;
1192
1193
// The newly-added result is hidden by an entry in the shadow map.
1194
if (CheckHiddenResult(R, CurContext, I->first))
1195
return;
1196
1197
break;
1198
}
1199
}
1200
1201
// Make sure that any given declaration only shows up in the result set once.
1202
if (!AllDeclsFound.insert(CanonDecl).second)
1203
return;
1204
1205
// If the filter is for nested-name-specifiers, then this result starts a
1206
// nested-name-specifier.
1207
if (AsNestedNameSpecifier) {
1208
R.StartsNestedNameSpecifier = true;
1209
R.Priority = CCP_NestedNameSpecifier;
1210
} else
1211
AdjustResultPriorityForDecl(R);
1212
1213
// If this result is supposed to have an informative qualifier, add one.
1214
if (R.QualifierIsInformative && !R.Qualifier &&
1215
!R.StartsNestedNameSpecifier) {
1216
const DeclContext *Ctx = R.Declaration->getDeclContext();
1217
if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
1218
R.Qualifier =
1219
NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace);
1220
else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
1221
R.Qualifier = NestedNameSpecifier::Create(
1222
SemaRef.Context, nullptr, false,
1223
SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
1224
else
1225
R.QualifierIsInformative = false;
1226
}
1227
1228
// Insert this result into the set of results and into the current shadow
1229
// map.
1230
SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
1231
Results.push_back(R);
1232
1233
if (!AsNestedNameSpecifier)
1234
MaybeAddConstructorResults(R);
1235
}
1236
1237
static void setInBaseClass(ResultBuilder::Result &R) {
1238
R.Priority += CCD_InBaseClass;
1239
R.InBaseClass = true;
1240
}
1241
1242
enum class OverloadCompare { BothViable, Dominates, Dominated };
1243
// Will Candidate ever be called on the object, when overloaded with Incumbent?
1244
// Returns Dominates if Candidate is always called, Dominated if Incumbent is
1245
// always called, BothViable if either may be called depending on arguments.
1246
// Precondition: must actually be overloads!
1247
static OverloadCompare compareOverloads(const CXXMethodDecl &Candidate,
1248
const CXXMethodDecl &Incumbent,
1249
const Qualifiers &ObjectQuals,
1250
ExprValueKind ObjectKind) {
1251
// Base/derived shadowing is handled elsewhere.
1252
if (Candidate.getDeclContext() != Incumbent.getDeclContext())
1253
return OverloadCompare::BothViable;
1254
if (Candidate.isVariadic() != Incumbent.isVariadic() ||
1255
Candidate.getNumParams() != Incumbent.getNumParams() ||
1256
Candidate.getMinRequiredArguments() !=
1257
Incumbent.getMinRequiredArguments())
1258
return OverloadCompare::BothViable;
1259
for (unsigned I = 0, E = Candidate.getNumParams(); I != E; ++I)
1260
if (Candidate.parameters()[I]->getType().getCanonicalType() !=
1261
Incumbent.parameters()[I]->getType().getCanonicalType())
1262
return OverloadCompare::BothViable;
1263
if (!Candidate.specific_attrs<EnableIfAttr>().empty() ||
1264
!Incumbent.specific_attrs<EnableIfAttr>().empty())
1265
return OverloadCompare::BothViable;
1266
// At this point, we know calls can't pick one or the other based on
1267
// arguments, so one of the two must win. (Or both fail, handled elsewhere).
1268
RefQualifierKind CandidateRef = Candidate.getRefQualifier();
1269
RefQualifierKind IncumbentRef = Incumbent.getRefQualifier();
1270
if (CandidateRef != IncumbentRef) {
1271
// If the object kind is LValue/RValue, there's one acceptable ref-qualifier
1272
// and it can't be mixed with ref-unqualified overloads (in valid code).
1273
1274
// For xvalue objects, we prefer the rvalue overload even if we have to
1275
// add qualifiers (which is rare, because const&& is rare).
1276
if (ObjectKind == clang::VK_XValue)
1277
return CandidateRef == RQ_RValue ? OverloadCompare::Dominates
1278
: OverloadCompare::Dominated;
1279
}
1280
// Now the ref qualifiers are the same (or we're in some invalid state).
1281
// So make some decision based on the qualifiers.
1282
Qualifiers CandidateQual = Candidate.getMethodQualifiers();
1283
Qualifiers IncumbentQual = Incumbent.getMethodQualifiers();
1284
bool CandidateSuperset = CandidateQual.compatiblyIncludes(IncumbentQual);
1285
bool IncumbentSuperset = IncumbentQual.compatiblyIncludes(CandidateQual);
1286
if (CandidateSuperset == IncumbentSuperset)
1287
return OverloadCompare::BothViable;
1288
return IncumbentSuperset ? OverloadCompare::Dominates
1289
: OverloadCompare::Dominated;
1290
}
1291
1292
bool ResultBuilder::canCxxMethodBeCalled(const CXXMethodDecl *Method,
1293
QualType BaseExprType) const {
1294
// Find the class scope that we're currently in.
1295
// We could e.g. be inside a lambda, so walk up the DeclContext until we
1296
// find a CXXMethodDecl.
1297
DeclContext *CurContext = SemaRef.CurContext;
1298
const auto *CurrentClassScope = [&]() -> const CXXRecordDecl * {
1299
for (DeclContext *Ctx = CurContext; Ctx; Ctx = Ctx->getParent()) {
1300
const auto *CtxMethod = llvm::dyn_cast<CXXMethodDecl>(Ctx);
1301
if (CtxMethod && !CtxMethod->getParent()->isLambda()) {
1302
return CtxMethod->getParent();
1303
}
1304
}
1305
return nullptr;
1306
}();
1307
1308
// If we're not inside the scope of the method's class, it can't be a call.
1309
bool FunctionCanBeCall =
1310
CurrentClassScope &&
1311
(CurrentClassScope == Method->getParent() ||
1312
CurrentClassScope->isDerivedFrom(Method->getParent()));
1313
1314
// We skip the following calculation for exceptions if it's already true.
1315
if (FunctionCanBeCall)
1316
return true;
1317
1318
// Exception: foo->FooBase::bar() or foo->Foo::bar() *is* a call.
1319
if (const CXXRecordDecl *MaybeDerived =
1320
BaseExprType.isNull() ? nullptr
1321
: BaseExprType->getAsCXXRecordDecl()) {
1322
auto *MaybeBase = Method->getParent();
1323
FunctionCanBeCall =
1324
MaybeDerived == MaybeBase || MaybeDerived->isDerivedFrom(MaybeBase);
1325
}
1326
1327
return FunctionCanBeCall;
1328
}
1329
1330
bool ResultBuilder::canFunctionBeCalled(const NamedDecl *ND,
1331
QualType BaseExprType) const {
1332
// We apply heuristics only to CCC_Symbol:
1333
// * CCC_{Arrow,Dot}MemberAccess reflect member access expressions:
1334
// f.method() and f->method(). These are always calls.
1335
// * A qualified name to a member function may *not* be a call. We have to
1336
// subdivide the cases: For example, f.Base::method(), which is regarded as
1337
// CCC_Symbol, should be a call.
1338
// * Non-member functions and static member functions are always considered
1339
// calls.
1340
if (CompletionContext.getKind() == clang::CodeCompletionContext::CCC_Symbol) {
1341
if (const auto *FuncTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
1342
ND = FuncTmpl->getTemplatedDecl();
1343
}
1344
const auto *Method = dyn_cast<CXXMethodDecl>(ND);
1345
if (Method && !Method->isStatic()) {
1346
return canCxxMethodBeCalled(Method, BaseExprType);
1347
}
1348
}
1349
return true;
1350
}
1351
1352
void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
1353
NamedDecl *Hiding, bool InBaseClass = false,
1354
QualType BaseExprType = QualType()) {
1355
if (R.Kind != Result::RK_Declaration) {
1356
// For non-declaration results, just add the result.
1357
Results.push_back(R);
1358
return;
1359
}
1360
1361
// Look through using declarations.
1362
if (const auto *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
1363
CodeCompletionResult Result(Using->getTargetDecl(),
1364
getBasePriority(Using->getTargetDecl()),
1365
R.Qualifier, false,
1366
(R.Availability == CXAvailability_Available ||
1367
R.Availability == CXAvailability_Deprecated),
1368
std::move(R.FixIts));
1369
Result.ShadowDecl = Using;
1370
AddResult(Result, CurContext, Hiding, /*InBaseClass=*/false,
1371
/*BaseExprType=*/BaseExprType);
1372
return;
1373
}
1374
1375
bool AsNestedNameSpecifier = false;
1376
if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
1377
return;
1378
1379
// C++ constructors are never found by name lookup.
1380
if (isConstructor(R.Declaration))
1381
return;
1382
1383
if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
1384
return;
1385
1386
// Make sure that any given declaration only shows up in the result set once.
1387
if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()).second)
1388
return;
1389
1390
// If the filter is for nested-name-specifiers, then this result starts a
1391
// nested-name-specifier.
1392
if (AsNestedNameSpecifier) {
1393
R.StartsNestedNameSpecifier = true;
1394
R.Priority = CCP_NestedNameSpecifier;
1395
} else if (Filter == &ResultBuilder::IsMember && !R.Qualifier &&
1396
InBaseClass &&
1397
isa<CXXRecordDecl>(
1398
R.Declaration->getDeclContext()->getRedeclContext()))
1399
R.QualifierIsInformative = true;
1400
1401
// If this result is supposed to have an informative qualifier, add one.
1402
if (R.QualifierIsInformative && !R.Qualifier &&
1403
!R.StartsNestedNameSpecifier) {
1404
const DeclContext *Ctx = R.Declaration->getDeclContext();
1405
if (const auto *Namespace = dyn_cast<NamespaceDecl>(Ctx))
1406
R.Qualifier =
1407
NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace);
1408
else if (const auto *Tag = dyn_cast<TagDecl>(Ctx))
1409
R.Qualifier = NestedNameSpecifier::Create(
1410
SemaRef.Context, nullptr, false,
1411
SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
1412
else
1413
R.QualifierIsInformative = false;
1414
}
1415
1416
// Adjust the priority if this result comes from a base class.
1417
if (InBaseClass)
1418
setInBaseClass(R);
1419
1420
AdjustResultPriorityForDecl(R);
1421
1422
if (HasObjectTypeQualifiers)
1423
if (const auto *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
1424
if (Method->isInstance()) {
1425
Qualifiers MethodQuals = Method->getMethodQualifiers();
1426
if (ObjectTypeQualifiers == MethodQuals)
1427
R.Priority += CCD_ObjectQualifierMatch;
1428
else if (ObjectTypeQualifiers - MethodQuals) {
1429
// The method cannot be invoked, because doing so would drop
1430
// qualifiers.
1431
return;
1432
}
1433
// Detect cases where a ref-qualified method cannot be invoked.
1434
switch (Method->getRefQualifier()) {
1435
case RQ_LValue:
1436
if (ObjectKind != VK_LValue && !MethodQuals.hasConst())
1437
return;
1438
break;
1439
case RQ_RValue:
1440
if (ObjectKind == VK_LValue)
1441
return;
1442
break;
1443
case RQ_None:
1444
break;
1445
}
1446
1447
/// Check whether this dominates another overloaded method, which should
1448
/// be suppressed (or vice versa).
1449
/// Motivating case is const_iterator begin() const vs iterator begin().
1450
auto &OverloadSet = OverloadMap[std::make_pair(
1451
CurContext, Method->getDeclName().getAsOpaqueInteger())];
1452
for (const DeclIndexPair Entry : OverloadSet) {
1453
Result &Incumbent = Results[Entry.second];
1454
switch (compareOverloads(*Method,
1455
*cast<CXXMethodDecl>(Incumbent.Declaration),
1456
ObjectTypeQualifiers, ObjectKind)) {
1457
case OverloadCompare::Dominates:
1458
// Replace the dominated overload with this one.
1459
// FIXME: if the overload dominates multiple incumbents then we
1460
// should remove all. But two overloads is by far the common case.
1461
Incumbent = std::move(R);
1462
return;
1463
case OverloadCompare::Dominated:
1464
// This overload can't be called, drop it.
1465
return;
1466
case OverloadCompare::BothViable:
1467
break;
1468
}
1469
}
1470
OverloadSet.Add(Method, Results.size());
1471
}
1472
1473
R.FunctionCanBeCall = canFunctionBeCalled(R.getDeclaration(), BaseExprType);
1474
1475
// Insert this result into the set of results.
1476
Results.push_back(R);
1477
1478
if (!AsNestedNameSpecifier)
1479
MaybeAddConstructorResults(R);
1480
}
1481
1482
void ResultBuilder::AddResult(Result R) {
1483
assert(R.Kind != Result::RK_Declaration &&
1484
"Declaration results need more context");
1485
Results.push_back(R);
1486
}
1487
1488
/// Enter into a new scope.
1489
void ResultBuilder::EnterNewScope() { ShadowMaps.emplace_back(); }
1490
1491
/// Exit from the current scope.
1492
void ResultBuilder::ExitScope() {
1493
ShadowMaps.pop_back();
1494
}
1495
1496
/// Determines whether this given declaration will be found by
1497
/// ordinary name lookup.
1498
bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {
1499
ND = ND->getUnderlyingDecl();
1500
1501
// If name lookup finds a local extern declaration, then we are in a
1502
// context where it behaves like an ordinary name.
1503
unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1504
if (SemaRef.getLangOpts().CPlusPlus)
1505
IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1506
else if (SemaRef.getLangOpts().ObjC) {
1507
if (isa<ObjCIvarDecl>(ND))
1508
return true;
1509
}
1510
1511
return ND->getIdentifierNamespace() & IDNS;
1512
}
1513
1514
/// Determines whether this given declaration will be found by
1515
/// ordinary name lookup but is not a type name.
1516
bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
1517
ND = ND->getUnderlyingDecl();
1518
if (isa<TypeDecl>(ND))
1519
return false;
1520
// Objective-C interfaces names are not filtered by this method because they
1521
// can be used in a class property expression. We can still filter out
1522
// @class declarations though.
1523
if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
1524
if (!ID->getDefinition())
1525
return false;
1526
}
1527
1528
unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1529
if (SemaRef.getLangOpts().CPlusPlus)
1530
IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
1531
else if (SemaRef.getLangOpts().ObjC) {
1532
if (isa<ObjCIvarDecl>(ND))
1533
return true;
1534
}
1535
1536
return ND->getIdentifierNamespace() & IDNS;
1537
}
1538
1539
bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const {
1540
if (!IsOrdinaryNonTypeName(ND))
1541
return false;
1542
1543
if (const auto *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
1544
if (VD->getType()->isIntegralOrEnumerationType())
1545
return true;
1546
1547
return false;
1548
}
1549
1550
/// Determines whether this given declaration will be found by
1551
/// ordinary name lookup.
1552
bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {
1553
ND = ND->getUnderlyingDecl();
1554
1555
unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
1556
if (SemaRef.getLangOpts().CPlusPlus)
1557
IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
1558
1559
return (ND->getIdentifierNamespace() & IDNS) && !isa<ValueDecl>(ND) &&
1560
!isa<FunctionTemplateDecl>(ND) && !isa<ObjCPropertyDecl>(ND);
1561
}
1562
1563
/// Determines whether the given declaration is suitable as the
1564
/// start of a C++ nested-name-specifier, e.g., a class or namespace.
1565
bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const {
1566
// Allow us to find class templates, too.
1567
if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1568
ND = ClassTemplate->getTemplatedDecl();
1569
1570
return SemaRef.isAcceptableNestedNameSpecifier(ND);
1571
}
1572
1573
/// Determines whether the given declaration is an enumeration.
1574
bool ResultBuilder::IsEnum(const NamedDecl *ND) const {
1575
return isa<EnumDecl>(ND);
1576
}
1577
1578
/// Determines whether the given declaration is a class or struct.
1579
bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const {
1580
// Allow us to find class templates, too.
1581
if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1582
ND = ClassTemplate->getTemplatedDecl();
1583
1584
// For purposes of this check, interfaces match too.
1585
if (const auto *RD = dyn_cast<RecordDecl>(ND))
1586
return RD->getTagKind() == TagTypeKind::Class ||
1587
RD->getTagKind() == TagTypeKind::Struct ||
1588
RD->getTagKind() == TagTypeKind::Interface;
1589
1590
return false;
1591
}
1592
1593
/// Determines whether the given declaration is a union.
1594
bool ResultBuilder::IsUnion(const NamedDecl *ND) const {
1595
// Allow us to find class templates, too.
1596
if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
1597
ND = ClassTemplate->getTemplatedDecl();
1598
1599
if (const auto *RD = dyn_cast<RecordDecl>(ND))
1600
return RD->getTagKind() == TagTypeKind::Union;
1601
1602
return false;
1603
}
1604
1605
/// Determines whether the given declaration is a namespace.
1606
bool ResultBuilder::IsNamespace(const NamedDecl *ND) const {
1607
return isa<NamespaceDecl>(ND);
1608
}
1609
1610
/// Determines whether the given declaration is a namespace or
1611
/// namespace alias.
1612
bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const {
1613
return isa<NamespaceDecl>(ND->getUnderlyingDecl());
1614
}
1615
1616
/// Determines whether the given declaration is a type.
1617
bool ResultBuilder::IsType(const NamedDecl *ND) const {
1618
ND = ND->getUnderlyingDecl();
1619
return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
1620
}
1621
1622
/// Determines which members of a class should be visible via
1623
/// "." or "->". Only value declarations, nested name specifiers, and
1624
/// using declarations thereof should show up.
1625
bool ResultBuilder::IsMember(const NamedDecl *ND) const {
1626
ND = ND->getUnderlyingDecl();
1627
return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
1628
isa<ObjCPropertyDecl>(ND);
1629
}
1630
1631
static bool isObjCReceiverType(ASTContext &C, QualType T) {
1632
T = C.getCanonicalType(T);
1633
switch (T->getTypeClass()) {
1634
case Type::ObjCObject:
1635
case Type::ObjCInterface:
1636
case Type::ObjCObjectPointer:
1637
return true;
1638
1639
case Type::Builtin:
1640
switch (cast<BuiltinType>(T)->getKind()) {
1641
case BuiltinType::ObjCId:
1642
case BuiltinType::ObjCClass:
1643
case BuiltinType::ObjCSel:
1644
return true;
1645
1646
default:
1647
break;
1648
}
1649
return false;
1650
1651
default:
1652
break;
1653
}
1654
1655
if (!C.getLangOpts().CPlusPlus)
1656
return false;
1657
1658
// FIXME: We could perform more analysis here to determine whether a
1659
// particular class type has any conversions to Objective-C types. For now,
1660
// just accept all class types.
1661
return T->isDependentType() || T->isRecordType();
1662
}
1663
1664
bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {
1665
QualType T = getDeclUsageType(SemaRef.Context, ND);
1666
if (T.isNull())
1667
return false;
1668
1669
T = SemaRef.Context.getBaseElementType(T);
1670
return isObjCReceiverType(SemaRef.Context, T);
1671
}
1672
1673
bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(
1674
const NamedDecl *ND) const {
1675
if (IsObjCMessageReceiver(ND))
1676
return true;
1677
1678
const auto *Var = dyn_cast<VarDecl>(ND);
1679
if (!Var)
1680
return false;
1681
1682
return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>();
1683
}
1684
1685
bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {
1686
if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) ||
1687
(!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
1688
return false;
1689
1690
QualType T = getDeclUsageType(SemaRef.Context, ND);
1691
if (T.isNull())
1692
return false;
1693
1694
T = SemaRef.Context.getBaseElementType(T);
1695
return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
1696
T->isObjCIdType() ||
1697
(SemaRef.getLangOpts().CPlusPlus && T->isRecordType());
1698
}
1699
1700
bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const {
1701
return false;
1702
}
1703
1704
/// Determines whether the given declaration is an Objective-C
1705
/// instance variable.
1706
bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const {
1707
return isa<ObjCIvarDecl>(ND);
1708
}
1709
1710
namespace {
1711
1712
/// Visible declaration consumer that adds a code-completion result
1713
/// for each visible declaration.
1714
class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
1715
ResultBuilder &Results;
1716
DeclContext *InitialLookupCtx;
1717
// NamingClass and BaseType are used for access-checking. See
1718
// Sema::IsSimplyAccessible for details.
1719
CXXRecordDecl *NamingClass;
1720
QualType BaseType;
1721
std::vector<FixItHint> FixIts;
1722
1723
public:
1724
CodeCompletionDeclConsumer(
1725
ResultBuilder &Results, DeclContext *InitialLookupCtx,
1726
QualType BaseType = QualType(),
1727
std::vector<FixItHint> FixIts = std::vector<FixItHint>())
1728
: Results(Results), InitialLookupCtx(InitialLookupCtx),
1729
FixIts(std::move(FixIts)) {
1730
NamingClass = llvm::dyn_cast<CXXRecordDecl>(InitialLookupCtx);
1731
// If BaseType was not provided explicitly, emulate implicit 'this->'.
1732
if (BaseType.isNull()) {
1733
auto ThisType = Results.getSema().getCurrentThisType();
1734
if (!ThisType.isNull()) {
1735
assert(ThisType->isPointerType());
1736
BaseType = ThisType->getPointeeType();
1737
if (!NamingClass)
1738
NamingClass = BaseType->getAsCXXRecordDecl();
1739
}
1740
}
1741
this->BaseType = BaseType;
1742
}
1743
1744
void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
1745
bool InBaseClass) override {
1746
ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr,
1747
false, IsAccessible(ND, Ctx), FixIts);
1748
Results.AddResult(Result, InitialLookupCtx, Hiding, InBaseClass, BaseType);
1749
}
1750
1751
void EnteredContext(DeclContext *Ctx) override {
1752
Results.addVisitedContext(Ctx);
1753
}
1754
1755
private:
1756
bool IsAccessible(NamedDecl *ND, DeclContext *Ctx) {
1757
// Naming class to use for access check. In most cases it was provided
1758
// explicitly (e.g. member access (lhs.foo) or qualified lookup (X::)),
1759
// for unqualified lookup we fallback to the \p Ctx in which we found the
1760
// member.
1761
auto *NamingClass = this->NamingClass;
1762
QualType BaseType = this->BaseType;
1763
if (auto *Cls = llvm::dyn_cast_or_null<CXXRecordDecl>(Ctx)) {
1764
if (!NamingClass)
1765
NamingClass = Cls;
1766
// When we emulate implicit 'this->' in an unqualified lookup, we might
1767
// end up with an invalid naming class. In that case, we avoid emulating
1768
// 'this->' qualifier to satisfy preconditions of the access checking.
1769
if (NamingClass->getCanonicalDecl() != Cls->getCanonicalDecl() &&
1770
!NamingClass->isDerivedFrom(Cls)) {
1771
NamingClass = Cls;
1772
BaseType = QualType();
1773
}
1774
} else {
1775
// The decl was found outside the C++ class, so only ObjC access checks
1776
// apply. Those do not rely on NamingClass and BaseType, so we clear them
1777
// out.
1778
NamingClass = nullptr;
1779
BaseType = QualType();
1780
}
1781
return Results.getSema().IsSimplyAccessible(ND, NamingClass, BaseType);
1782
}
1783
};
1784
} // namespace
1785
1786
/// Add type specifiers for the current language as keyword results.
1787
static void AddTypeSpecifierResults(const LangOptions &LangOpts,
1788
ResultBuilder &Results) {
1789
typedef CodeCompletionResult Result;
1790
Results.AddResult(Result("short", CCP_Type));
1791
Results.AddResult(Result("long", CCP_Type));
1792
Results.AddResult(Result("signed", CCP_Type));
1793
Results.AddResult(Result("unsigned", CCP_Type));
1794
Results.AddResult(Result("void", CCP_Type));
1795
Results.AddResult(Result("char", CCP_Type));
1796
Results.AddResult(Result("int", CCP_Type));
1797
Results.AddResult(Result("float", CCP_Type));
1798
Results.AddResult(Result("double", CCP_Type));
1799
Results.AddResult(Result("enum", CCP_Type));
1800
Results.AddResult(Result("struct", CCP_Type));
1801
Results.AddResult(Result("union", CCP_Type));
1802
Results.AddResult(Result("const", CCP_Type));
1803
Results.AddResult(Result("volatile", CCP_Type));
1804
1805
if (LangOpts.C99) {
1806
// C99-specific
1807
Results.AddResult(Result("_Complex", CCP_Type));
1808
if (!LangOpts.C2y)
1809
Results.AddResult(Result("_Imaginary", CCP_Type));
1810
Results.AddResult(Result("_Bool", CCP_Type));
1811
Results.AddResult(Result("restrict", CCP_Type));
1812
}
1813
1814
CodeCompletionBuilder Builder(Results.getAllocator(),
1815
Results.getCodeCompletionTUInfo());
1816
if (LangOpts.CPlusPlus) {
1817
// C++-specific
1818
Results.AddResult(
1819
Result("bool", CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0)));
1820
Results.AddResult(Result("class", CCP_Type));
1821
Results.AddResult(Result("wchar_t", CCP_Type));
1822
1823
// typename name
1824
Builder.AddTypedTextChunk("typename");
1825
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1826
Builder.AddPlaceholderChunk("name");
1827
Results.AddResult(Result(Builder.TakeString()));
1828
1829
if (LangOpts.CPlusPlus11) {
1830
Results.AddResult(Result("auto", CCP_Type));
1831
Results.AddResult(Result("char16_t", CCP_Type));
1832
Results.AddResult(Result("char32_t", CCP_Type));
1833
1834
Builder.AddTypedTextChunk("decltype");
1835
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1836
Builder.AddPlaceholderChunk("expression");
1837
Builder.AddChunk(CodeCompletionString::CK_RightParen);
1838
Results.AddResult(Result(Builder.TakeString()));
1839
}
1840
} else
1841
Results.AddResult(Result("__auto_type", CCP_Type));
1842
1843
// GNU keywords
1844
if (LangOpts.GNUKeywords) {
1845
// FIXME: Enable when we actually support decimal floating point.
1846
// Results.AddResult(Result("_Decimal32"));
1847
// Results.AddResult(Result("_Decimal64"));
1848
// Results.AddResult(Result("_Decimal128"));
1849
1850
Builder.AddTypedTextChunk("typeof");
1851
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1852
Builder.AddPlaceholderChunk("expression");
1853
Results.AddResult(Result(Builder.TakeString()));
1854
1855
Builder.AddTypedTextChunk("typeof");
1856
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1857
Builder.AddPlaceholderChunk("type");
1858
Builder.AddChunk(CodeCompletionString::CK_RightParen);
1859
Results.AddResult(Result(Builder.TakeString()));
1860
}
1861
1862
// Nullability
1863
Results.AddResult(Result("_Nonnull", CCP_Type));
1864
Results.AddResult(Result("_Null_unspecified", CCP_Type));
1865
Results.AddResult(Result("_Nullable", CCP_Type));
1866
}
1867
1868
static void
1869
AddStorageSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC,
1870
const LangOptions &LangOpts, ResultBuilder &Results) {
1871
typedef CodeCompletionResult Result;
1872
// Note: we don't suggest either "auto" or "register", because both
1873
// are pointless as storage specifiers. Elsewhere, we suggest "auto"
1874
// in C++0x as a type specifier.
1875
Results.AddResult(Result("extern"));
1876
Results.AddResult(Result("static"));
1877
1878
if (LangOpts.CPlusPlus11) {
1879
CodeCompletionAllocator &Allocator = Results.getAllocator();
1880
CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
1881
1882
// alignas
1883
Builder.AddTypedTextChunk("alignas");
1884
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
1885
Builder.AddPlaceholderChunk("expression");
1886
Builder.AddChunk(CodeCompletionString::CK_RightParen);
1887
Results.AddResult(Result(Builder.TakeString()));
1888
1889
Results.AddResult(Result("constexpr"));
1890
Results.AddResult(Result("thread_local"));
1891
}
1892
}
1893
1894
static void
1895
AddFunctionSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC,
1896
const LangOptions &LangOpts, ResultBuilder &Results) {
1897
typedef CodeCompletionResult Result;
1898
switch (CCC) {
1899
case SemaCodeCompletion::PCC_Class:
1900
case SemaCodeCompletion::PCC_MemberTemplate:
1901
if (LangOpts.CPlusPlus) {
1902
Results.AddResult(Result("explicit"));
1903
Results.AddResult(Result("friend"));
1904
Results.AddResult(Result("mutable"));
1905
Results.AddResult(Result("virtual"));
1906
}
1907
[[fallthrough]];
1908
1909
case SemaCodeCompletion::PCC_ObjCInterface:
1910
case SemaCodeCompletion::PCC_ObjCImplementation:
1911
case SemaCodeCompletion::PCC_Namespace:
1912
case SemaCodeCompletion::PCC_Template:
1913
if (LangOpts.CPlusPlus || LangOpts.C99)
1914
Results.AddResult(Result("inline"));
1915
break;
1916
1917
case SemaCodeCompletion::PCC_ObjCInstanceVariableList:
1918
case SemaCodeCompletion::PCC_Expression:
1919
case SemaCodeCompletion::PCC_Statement:
1920
case SemaCodeCompletion::PCC_TopLevelOrExpression:
1921
case SemaCodeCompletion::PCC_ForInit:
1922
case SemaCodeCompletion::PCC_Condition:
1923
case SemaCodeCompletion::PCC_RecoveryInFunction:
1924
case SemaCodeCompletion::PCC_Type:
1925
case SemaCodeCompletion::PCC_ParenthesizedExpression:
1926
case SemaCodeCompletion::PCC_LocalDeclarationSpecifiers:
1927
break;
1928
}
1929
}
1930
1931
static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
1932
static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
1933
static void AddObjCVisibilityResults(const LangOptions &LangOpts,
1934
ResultBuilder &Results, bool NeedAt);
1935
static void AddObjCImplementationResults(const LangOptions &LangOpts,
1936
ResultBuilder &Results, bool NeedAt);
1937
static void AddObjCInterfaceResults(const LangOptions &LangOpts,
1938
ResultBuilder &Results, bool NeedAt);
1939
static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
1940
1941
static void AddTypedefResult(ResultBuilder &Results) {
1942
CodeCompletionBuilder Builder(Results.getAllocator(),
1943
Results.getCodeCompletionTUInfo());
1944
Builder.AddTypedTextChunk("typedef");
1945
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1946
Builder.AddPlaceholderChunk("type");
1947
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1948
Builder.AddPlaceholderChunk("name");
1949
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1950
Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1951
}
1952
1953
// using name = type
1954
static void AddUsingAliasResult(CodeCompletionBuilder &Builder,
1955
ResultBuilder &Results) {
1956
Builder.AddTypedTextChunk("using");
1957
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
1958
Builder.AddPlaceholderChunk("name");
1959
Builder.AddChunk(CodeCompletionString::CK_Equal);
1960
Builder.AddPlaceholderChunk("type");
1961
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
1962
Results.AddResult(CodeCompletionResult(Builder.TakeString()));
1963
}
1964
1965
static bool WantTypesInContext(SemaCodeCompletion::ParserCompletionContext CCC,
1966
const LangOptions &LangOpts) {
1967
switch (CCC) {
1968
case SemaCodeCompletion::PCC_Namespace:
1969
case SemaCodeCompletion::PCC_Class:
1970
case SemaCodeCompletion::PCC_ObjCInstanceVariableList:
1971
case SemaCodeCompletion::PCC_Template:
1972
case SemaCodeCompletion::PCC_MemberTemplate:
1973
case SemaCodeCompletion::PCC_Statement:
1974
case SemaCodeCompletion::PCC_RecoveryInFunction:
1975
case SemaCodeCompletion::PCC_Type:
1976
case SemaCodeCompletion::PCC_ParenthesizedExpression:
1977
case SemaCodeCompletion::PCC_LocalDeclarationSpecifiers:
1978
case SemaCodeCompletion::PCC_TopLevelOrExpression:
1979
return true;
1980
1981
case SemaCodeCompletion::PCC_Expression:
1982
case SemaCodeCompletion::PCC_Condition:
1983
return LangOpts.CPlusPlus;
1984
1985
case SemaCodeCompletion::PCC_ObjCInterface:
1986
case SemaCodeCompletion::PCC_ObjCImplementation:
1987
return false;
1988
1989
case SemaCodeCompletion::PCC_ForInit:
1990
return LangOpts.CPlusPlus || LangOpts.ObjC || LangOpts.C99;
1991
}
1992
1993
llvm_unreachable("Invalid ParserCompletionContext!");
1994
}
1995
1996
static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
1997
const Preprocessor &PP) {
1998
PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP);
1999
Policy.AnonymousTagLocations = false;
2000
Policy.SuppressStrongLifetime = true;
2001
Policy.SuppressUnwrittenScope = true;
2002
Policy.SuppressScope = true;
2003
Policy.CleanUglifiedParameters = true;
2004
return Policy;
2005
}
2006
2007
/// Retrieve a printing policy suitable for code completion.
2008
static PrintingPolicy getCompletionPrintingPolicy(Sema &S) {
2009
return getCompletionPrintingPolicy(S.Context, S.PP);
2010
}
2011
2012
/// Retrieve the string representation of the given type as a string
2013
/// that has the appropriate lifetime for code completion.
2014
///
2015
/// This routine provides a fast path where we provide constant strings for
2016
/// common type names.
2017
static const char *GetCompletionTypeString(QualType T, ASTContext &Context,
2018
const PrintingPolicy &Policy,
2019
CodeCompletionAllocator &Allocator) {
2020
if (!T.getLocalQualifiers()) {
2021
// Built-in type names are constant strings.
2022
if (const BuiltinType *BT = dyn_cast<BuiltinType>(T))
2023
return BT->getNameAsCString(Policy);
2024
2025
// Anonymous tag types are constant strings.
2026
if (const TagType *TagT = dyn_cast<TagType>(T))
2027
if (TagDecl *Tag = TagT->getDecl())
2028
if (!Tag->hasNameForLinkage()) {
2029
switch (Tag->getTagKind()) {
2030
case TagTypeKind::Struct:
2031
return "struct <anonymous>";
2032
case TagTypeKind::Interface:
2033
return "__interface <anonymous>";
2034
case TagTypeKind::Class:
2035
return "class <anonymous>";
2036
case TagTypeKind::Union:
2037
return "union <anonymous>";
2038
case TagTypeKind::Enum:
2039
return "enum <anonymous>";
2040
}
2041
}
2042
}
2043
2044
// Slow path: format the type as a string.
2045
std::string Result;
2046
T.getAsStringInternal(Result, Policy);
2047
return Allocator.CopyString(Result);
2048
}
2049
2050
/// Add a completion for "this", if we're in a member function.
2051
static void addThisCompletion(Sema &S, ResultBuilder &Results) {
2052
QualType ThisTy = S.getCurrentThisType();
2053
if (ThisTy.isNull())
2054
return;
2055
2056
CodeCompletionAllocator &Allocator = Results.getAllocator();
2057
CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
2058
PrintingPolicy Policy = getCompletionPrintingPolicy(S);
2059
Builder.AddResultTypeChunk(
2060
GetCompletionTypeString(ThisTy, S.Context, Policy, Allocator));
2061
Builder.AddTypedTextChunk("this");
2062
Results.AddResult(CodeCompletionResult(Builder.TakeString()));
2063
}
2064
2065
static void AddStaticAssertResult(CodeCompletionBuilder &Builder,
2066
ResultBuilder &Results,
2067
const LangOptions &LangOpts) {
2068
if (!LangOpts.CPlusPlus11)
2069
return;
2070
2071
Builder.AddTypedTextChunk("static_assert");
2072
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2073
Builder.AddPlaceholderChunk("expression");
2074
Builder.AddChunk(CodeCompletionString::CK_Comma);
2075
Builder.AddPlaceholderChunk("message");
2076
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2077
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2078
Results.AddResult(CodeCompletionResult(Builder.TakeString()));
2079
}
2080
2081
static void AddOverrideResults(ResultBuilder &Results,
2082
const CodeCompletionContext &CCContext,
2083
CodeCompletionBuilder &Builder) {
2084
Sema &S = Results.getSema();
2085
const auto *CR = llvm::dyn_cast<CXXRecordDecl>(S.CurContext);
2086
// If not inside a class/struct/union return empty.
2087
if (!CR)
2088
return;
2089
// First store overrides within current class.
2090
// These are stored by name to make querying fast in the later step.
2091
llvm::StringMap<std::vector<FunctionDecl *>> Overrides;
2092
for (auto *Method : CR->methods()) {
2093
if (!Method->isVirtual() || !Method->getIdentifier())
2094
continue;
2095
Overrides[Method->getName()].push_back(Method);
2096
}
2097
2098
for (const auto &Base : CR->bases()) {
2099
const auto *BR = Base.getType().getTypePtr()->getAsCXXRecordDecl();
2100
if (!BR)
2101
continue;
2102
for (auto *Method : BR->methods()) {
2103
if (!Method->isVirtual() || !Method->getIdentifier())
2104
continue;
2105
const auto it = Overrides.find(Method->getName());
2106
bool IsOverriden = false;
2107
if (it != Overrides.end()) {
2108
for (auto *MD : it->second) {
2109
// If the method in current body is not an overload of this virtual
2110
// function, then it overrides this one.
2111
if (!S.IsOverload(MD, Method, false)) {
2112
IsOverriden = true;
2113
break;
2114
}
2115
}
2116
}
2117
if (!IsOverriden) {
2118
// Generates a new CodeCompletionResult by taking this function and
2119
// converting it into an override declaration with only one chunk in the
2120
// final CodeCompletionString as a TypedTextChunk.
2121
CodeCompletionResult CCR(Method, 0);
2122
PrintingPolicy Policy =
2123
getCompletionPrintingPolicy(S.getASTContext(), S.getPreprocessor());
2124
auto *CCS = CCR.createCodeCompletionStringForOverride(
2125
S.getPreprocessor(), S.getASTContext(), Builder,
2126
/*IncludeBriefComments=*/false, CCContext, Policy);
2127
Results.AddResult(CodeCompletionResult(CCS, Method, CCP_CodePattern));
2128
}
2129
}
2130
}
2131
}
2132
2133
/// Add language constructs that show up for "ordinary" names.
2134
static void
2135
AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC,
2136
Scope *S, Sema &SemaRef, ResultBuilder &Results) {
2137
CodeCompletionAllocator &Allocator = Results.getAllocator();
2138
CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
2139
2140
typedef CodeCompletionResult Result;
2141
switch (CCC) {
2142
case SemaCodeCompletion::PCC_Namespace:
2143
if (SemaRef.getLangOpts().CPlusPlus) {
2144
if (Results.includeCodePatterns()) {
2145
// namespace <identifier> { declarations }
2146
Builder.AddTypedTextChunk("namespace");
2147
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2148
Builder.AddPlaceholderChunk("identifier");
2149
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2150
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2151
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2152
Builder.AddPlaceholderChunk("declarations");
2153
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2154
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2155
Results.AddResult(Result(Builder.TakeString()));
2156
}
2157
2158
// namespace identifier = identifier ;
2159
Builder.AddTypedTextChunk("namespace");
2160
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2161
Builder.AddPlaceholderChunk("name");
2162
Builder.AddChunk(CodeCompletionString::CK_Equal);
2163
Builder.AddPlaceholderChunk("namespace");
2164
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2165
Results.AddResult(Result(Builder.TakeString()));
2166
2167
// Using directives
2168
Builder.AddTypedTextChunk("using namespace");
2169
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2170
Builder.AddPlaceholderChunk("identifier");
2171
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2172
Results.AddResult(Result(Builder.TakeString()));
2173
2174
// asm(string-literal)
2175
Builder.AddTypedTextChunk("asm");
2176
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2177
Builder.AddPlaceholderChunk("string-literal");
2178
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2179
Results.AddResult(Result(Builder.TakeString()));
2180
2181
if (Results.includeCodePatterns()) {
2182
// Explicit template instantiation
2183
Builder.AddTypedTextChunk("template");
2184
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2185
Builder.AddPlaceholderChunk("declaration");
2186
Results.AddResult(Result(Builder.TakeString()));
2187
} else {
2188
Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword));
2189
}
2190
}
2191
2192
if (SemaRef.getLangOpts().ObjC)
2193
AddObjCTopLevelResults(Results, true);
2194
2195
AddTypedefResult(Results);
2196
[[fallthrough]];
2197
2198
case SemaCodeCompletion::PCC_Class:
2199
if (SemaRef.getLangOpts().CPlusPlus) {
2200
// Using declaration
2201
Builder.AddTypedTextChunk("using");
2202
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2203
Builder.AddPlaceholderChunk("qualifier");
2204
Builder.AddTextChunk("::");
2205
Builder.AddPlaceholderChunk("name");
2206
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2207
Results.AddResult(Result(Builder.TakeString()));
2208
2209
if (SemaRef.getLangOpts().CPlusPlus11)
2210
AddUsingAliasResult(Builder, Results);
2211
2212
// using typename qualifier::name (only in a dependent context)
2213
if (SemaRef.CurContext->isDependentContext()) {
2214
Builder.AddTypedTextChunk("using typename");
2215
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2216
Builder.AddPlaceholderChunk("qualifier");
2217
Builder.AddTextChunk("::");
2218
Builder.AddPlaceholderChunk("name");
2219
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2220
Results.AddResult(Result(Builder.TakeString()));
2221
}
2222
2223
AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
2224
2225
if (CCC == SemaCodeCompletion::PCC_Class) {
2226
AddTypedefResult(Results);
2227
2228
bool IsNotInheritanceScope = !S->isClassInheritanceScope();
2229
// public:
2230
Builder.AddTypedTextChunk("public");
2231
if (IsNotInheritanceScope && Results.includeCodePatterns())
2232
Builder.AddChunk(CodeCompletionString::CK_Colon);
2233
Results.AddResult(Result(Builder.TakeString()));
2234
2235
// protected:
2236
Builder.AddTypedTextChunk("protected");
2237
if (IsNotInheritanceScope && Results.includeCodePatterns())
2238
Builder.AddChunk(CodeCompletionString::CK_Colon);
2239
Results.AddResult(Result(Builder.TakeString()));
2240
2241
// private:
2242
Builder.AddTypedTextChunk("private");
2243
if (IsNotInheritanceScope && Results.includeCodePatterns())
2244
Builder.AddChunk(CodeCompletionString::CK_Colon);
2245
Results.AddResult(Result(Builder.TakeString()));
2246
2247
// FIXME: This adds override results only if we are at the first word of
2248
// the declaration/definition. Also call this from other sides to have
2249
// more use-cases.
2250
AddOverrideResults(Results, CodeCompletionContext::CCC_ClassStructUnion,
2251
Builder);
2252
}
2253
}
2254
[[fallthrough]];
2255
2256
case SemaCodeCompletion::PCC_Template:
2257
case SemaCodeCompletion::PCC_MemberTemplate:
2258
if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) {
2259
// template < parameters >
2260
Builder.AddTypedTextChunk("template");
2261
Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2262
Builder.AddPlaceholderChunk("parameters");
2263
Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2264
Results.AddResult(Result(Builder.TakeString()));
2265
} else {
2266
Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword));
2267
}
2268
2269
AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2270
AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2271
break;
2272
2273
case SemaCodeCompletion::PCC_ObjCInterface:
2274
AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true);
2275
AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2276
AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2277
break;
2278
2279
case SemaCodeCompletion::PCC_ObjCImplementation:
2280
AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true);
2281
AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2282
AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2283
break;
2284
2285
case SemaCodeCompletion::PCC_ObjCInstanceVariableList:
2286
AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true);
2287
break;
2288
2289
case SemaCodeCompletion::PCC_RecoveryInFunction:
2290
case SemaCodeCompletion::PCC_TopLevelOrExpression:
2291
case SemaCodeCompletion::PCC_Statement: {
2292
if (SemaRef.getLangOpts().CPlusPlus11)
2293
AddUsingAliasResult(Builder, Results);
2294
2295
AddTypedefResult(Results);
2296
2297
if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() &&
2298
SemaRef.getLangOpts().CXXExceptions) {
2299
Builder.AddTypedTextChunk("try");
2300
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2301
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2302
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2303
Builder.AddPlaceholderChunk("statements");
2304
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2305
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2306
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2307
Builder.AddTextChunk("catch");
2308
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2309
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2310
Builder.AddPlaceholderChunk("declaration");
2311
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2312
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2313
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2314
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2315
Builder.AddPlaceholderChunk("statements");
2316
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2317
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2318
Results.AddResult(Result(Builder.TakeString()));
2319
}
2320
if (SemaRef.getLangOpts().ObjC)
2321
AddObjCStatementResults(Results, true);
2322
2323
if (Results.includeCodePatterns()) {
2324
// if (condition) { statements }
2325
Builder.AddTypedTextChunk("if");
2326
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2327
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2328
if (SemaRef.getLangOpts().CPlusPlus)
2329
Builder.AddPlaceholderChunk("condition");
2330
else
2331
Builder.AddPlaceholderChunk("expression");
2332
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2333
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2334
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2335
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2336
Builder.AddPlaceholderChunk("statements");
2337
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2338
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2339
Results.AddResult(Result(Builder.TakeString()));
2340
2341
// switch (condition) { }
2342
Builder.AddTypedTextChunk("switch");
2343
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2344
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2345
if (SemaRef.getLangOpts().CPlusPlus)
2346
Builder.AddPlaceholderChunk("condition");
2347
else
2348
Builder.AddPlaceholderChunk("expression");
2349
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2350
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2351
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2352
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2353
Builder.AddPlaceholderChunk("cases");
2354
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2355
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2356
Results.AddResult(Result(Builder.TakeString()));
2357
}
2358
2359
// Switch-specific statements.
2360
if (SemaRef.getCurFunction() &&
2361
!SemaRef.getCurFunction()->SwitchStack.empty()) {
2362
// case expression:
2363
Builder.AddTypedTextChunk("case");
2364
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2365
Builder.AddPlaceholderChunk("expression");
2366
Builder.AddChunk(CodeCompletionString::CK_Colon);
2367
Results.AddResult(Result(Builder.TakeString()));
2368
2369
// default:
2370
Builder.AddTypedTextChunk("default");
2371
Builder.AddChunk(CodeCompletionString::CK_Colon);
2372
Results.AddResult(Result(Builder.TakeString()));
2373
}
2374
2375
if (Results.includeCodePatterns()) {
2376
/// while (condition) { statements }
2377
Builder.AddTypedTextChunk("while");
2378
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2379
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2380
if (SemaRef.getLangOpts().CPlusPlus)
2381
Builder.AddPlaceholderChunk("condition");
2382
else
2383
Builder.AddPlaceholderChunk("expression");
2384
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2385
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2386
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2387
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2388
Builder.AddPlaceholderChunk("statements");
2389
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2390
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2391
Results.AddResult(Result(Builder.TakeString()));
2392
2393
// do { statements } while ( expression );
2394
Builder.AddTypedTextChunk("do");
2395
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2396
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2397
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2398
Builder.AddPlaceholderChunk("statements");
2399
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2400
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2401
Builder.AddTextChunk("while");
2402
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2403
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2404
Builder.AddPlaceholderChunk("expression");
2405
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2406
Results.AddResult(Result(Builder.TakeString()));
2407
2408
// for ( for-init-statement ; condition ; expression ) { statements }
2409
Builder.AddTypedTextChunk("for");
2410
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2411
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2412
if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99)
2413
Builder.AddPlaceholderChunk("init-statement");
2414
else
2415
Builder.AddPlaceholderChunk("init-expression");
2416
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2417
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2418
Builder.AddPlaceholderChunk("condition");
2419
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2420
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2421
Builder.AddPlaceholderChunk("inc-expression");
2422
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2423
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2424
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2425
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2426
Builder.AddPlaceholderChunk("statements");
2427
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2428
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2429
Results.AddResult(Result(Builder.TakeString()));
2430
2431
if (SemaRef.getLangOpts().CPlusPlus11 || SemaRef.getLangOpts().ObjC) {
2432
// for ( range_declaration (:|in) range_expression ) { statements }
2433
Builder.AddTypedTextChunk("for");
2434
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2435
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2436
Builder.AddPlaceholderChunk("range-declaration");
2437
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2438
if (SemaRef.getLangOpts().ObjC)
2439
Builder.AddTextChunk("in");
2440
else
2441
Builder.AddChunk(CodeCompletionString::CK_Colon);
2442
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2443
Builder.AddPlaceholderChunk("range-expression");
2444
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2445
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2446
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
2447
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2448
Builder.AddPlaceholderChunk("statements");
2449
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
2450
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
2451
Results.AddResult(Result(Builder.TakeString()));
2452
}
2453
}
2454
2455
if (S->getContinueParent()) {
2456
// continue ;
2457
Builder.AddTypedTextChunk("continue");
2458
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2459
Results.AddResult(Result(Builder.TakeString()));
2460
}
2461
2462
if (S->getBreakParent()) {
2463
// break ;
2464
Builder.AddTypedTextChunk("break");
2465
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2466
Results.AddResult(Result(Builder.TakeString()));
2467
}
2468
2469
// "return expression ;" or "return ;", depending on the return type.
2470
QualType ReturnType;
2471
if (const auto *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
2472
ReturnType = Function->getReturnType();
2473
else if (const auto *Method = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
2474
ReturnType = Method->getReturnType();
2475
else if (SemaRef.getCurBlock() &&
2476
!SemaRef.getCurBlock()->ReturnType.isNull())
2477
ReturnType = SemaRef.getCurBlock()->ReturnType;;
2478
if (ReturnType.isNull() || ReturnType->isVoidType()) {
2479
Builder.AddTypedTextChunk("return");
2480
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2481
Results.AddResult(Result(Builder.TakeString()));
2482
} else {
2483
assert(!ReturnType.isNull());
2484
// "return expression ;"
2485
Builder.AddTypedTextChunk("return");
2486
Builder.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace);
2487
Builder.AddPlaceholderChunk("expression");
2488
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2489
Results.AddResult(Result(Builder.TakeString()));
2490
// When boolean, also add 'return true;' and 'return false;'.
2491
if (ReturnType->isBooleanType()) {
2492
Builder.AddTypedTextChunk("return true");
2493
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2494
Results.AddResult(Result(Builder.TakeString()));
2495
2496
Builder.AddTypedTextChunk("return false");
2497
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2498
Results.AddResult(Result(Builder.TakeString()));
2499
}
2500
// For pointers, suggest 'return nullptr' in C++.
2501
if (SemaRef.getLangOpts().CPlusPlus11 &&
2502
(ReturnType->isPointerType() || ReturnType->isMemberPointerType())) {
2503
Builder.AddTypedTextChunk("return nullptr");
2504
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2505
Results.AddResult(Result(Builder.TakeString()));
2506
}
2507
}
2508
2509
// goto identifier ;
2510
Builder.AddTypedTextChunk("goto");
2511
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2512
Builder.AddPlaceholderChunk("label");
2513
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2514
Results.AddResult(Result(Builder.TakeString()));
2515
2516
// Using directives
2517
Builder.AddTypedTextChunk("using namespace");
2518
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2519
Builder.AddPlaceholderChunk("identifier");
2520
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
2521
Results.AddResult(Result(Builder.TakeString()));
2522
2523
AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
2524
}
2525
[[fallthrough]];
2526
2527
// Fall through (for statement expressions).
2528
case SemaCodeCompletion::PCC_ForInit:
2529
case SemaCodeCompletion::PCC_Condition:
2530
AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
2531
// Fall through: conditions and statements can have expressions.
2532
[[fallthrough]];
2533
2534
case SemaCodeCompletion::PCC_ParenthesizedExpression:
2535
if (SemaRef.getLangOpts().ObjCAutoRefCount &&
2536
CCC == SemaCodeCompletion::PCC_ParenthesizedExpression) {
2537
// (__bridge <type>)<expression>
2538
Builder.AddTypedTextChunk("__bridge");
2539
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2540
Builder.AddPlaceholderChunk("type");
2541
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2542
Builder.AddPlaceholderChunk("expression");
2543
Results.AddResult(Result(Builder.TakeString()));
2544
2545
// (__bridge_transfer <Objective-C type>)<expression>
2546
Builder.AddTypedTextChunk("__bridge_transfer");
2547
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2548
Builder.AddPlaceholderChunk("Objective-C type");
2549
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2550
Builder.AddPlaceholderChunk("expression");
2551
Results.AddResult(Result(Builder.TakeString()));
2552
2553
// (__bridge_retained <CF type>)<expression>
2554
Builder.AddTypedTextChunk("__bridge_retained");
2555
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2556
Builder.AddPlaceholderChunk("CF type");
2557
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2558
Builder.AddPlaceholderChunk("expression");
2559
Results.AddResult(Result(Builder.TakeString()));
2560
}
2561
// Fall through
2562
[[fallthrough]];
2563
2564
case SemaCodeCompletion::PCC_Expression: {
2565
if (SemaRef.getLangOpts().CPlusPlus) {
2566
// 'this', if we're in a non-static member function.
2567
addThisCompletion(SemaRef, Results);
2568
2569
// true
2570
Builder.AddResultTypeChunk("bool");
2571
Builder.AddTypedTextChunk("true");
2572
Results.AddResult(Result(Builder.TakeString()));
2573
2574
// false
2575
Builder.AddResultTypeChunk("bool");
2576
Builder.AddTypedTextChunk("false");
2577
Results.AddResult(Result(Builder.TakeString()));
2578
2579
if (SemaRef.getLangOpts().RTTI) {
2580
// dynamic_cast < type-id > ( expression )
2581
Builder.AddTypedTextChunk("dynamic_cast");
2582
Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2583
Builder.AddPlaceholderChunk("type");
2584
Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2585
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2586
Builder.AddPlaceholderChunk("expression");
2587
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2588
Results.AddResult(Result(Builder.TakeString()));
2589
}
2590
2591
// static_cast < type-id > ( expression )
2592
Builder.AddTypedTextChunk("static_cast");
2593
Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2594
Builder.AddPlaceholderChunk("type");
2595
Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2596
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2597
Builder.AddPlaceholderChunk("expression");
2598
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2599
Results.AddResult(Result(Builder.TakeString()));
2600
2601
// reinterpret_cast < type-id > ( expression )
2602
Builder.AddTypedTextChunk("reinterpret_cast");
2603
Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2604
Builder.AddPlaceholderChunk("type");
2605
Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2606
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2607
Builder.AddPlaceholderChunk("expression");
2608
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2609
Results.AddResult(Result(Builder.TakeString()));
2610
2611
// const_cast < type-id > ( expression )
2612
Builder.AddTypedTextChunk("const_cast");
2613
Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
2614
Builder.AddPlaceholderChunk("type");
2615
Builder.AddChunk(CodeCompletionString::CK_RightAngle);
2616
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2617
Builder.AddPlaceholderChunk("expression");
2618
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2619
Results.AddResult(Result(Builder.TakeString()));
2620
2621
if (SemaRef.getLangOpts().RTTI) {
2622
// typeid ( expression-or-type )
2623
Builder.AddResultTypeChunk("std::type_info");
2624
Builder.AddTypedTextChunk("typeid");
2625
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2626
Builder.AddPlaceholderChunk("expression-or-type");
2627
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2628
Results.AddResult(Result(Builder.TakeString()));
2629
}
2630
2631
// new T ( ... )
2632
Builder.AddTypedTextChunk("new");
2633
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2634
Builder.AddPlaceholderChunk("type");
2635
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2636
Builder.AddPlaceholderChunk("expressions");
2637
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2638
Results.AddResult(Result(Builder.TakeString()));
2639
2640
// new T [ ] ( ... )
2641
Builder.AddTypedTextChunk("new");
2642
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2643
Builder.AddPlaceholderChunk("type");
2644
Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
2645
Builder.AddPlaceholderChunk("size");
2646
Builder.AddChunk(CodeCompletionString::CK_RightBracket);
2647
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2648
Builder.AddPlaceholderChunk("expressions");
2649
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2650
Results.AddResult(Result(Builder.TakeString()));
2651
2652
// delete expression
2653
Builder.AddResultTypeChunk("void");
2654
Builder.AddTypedTextChunk("delete");
2655
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2656
Builder.AddPlaceholderChunk("expression");
2657
Results.AddResult(Result(Builder.TakeString()));
2658
2659
// delete [] expression
2660
Builder.AddResultTypeChunk("void");
2661
Builder.AddTypedTextChunk("delete");
2662
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2663
Builder.AddChunk(CodeCompletionString::CK_LeftBracket);
2664
Builder.AddChunk(CodeCompletionString::CK_RightBracket);
2665
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2666
Builder.AddPlaceholderChunk("expression");
2667
Results.AddResult(Result(Builder.TakeString()));
2668
2669
if (SemaRef.getLangOpts().CXXExceptions) {
2670
// throw expression
2671
Builder.AddResultTypeChunk("void");
2672
Builder.AddTypedTextChunk("throw");
2673
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
2674
Builder.AddPlaceholderChunk("expression");
2675
Results.AddResult(Result(Builder.TakeString()));
2676
}
2677
2678
// FIXME: Rethrow?
2679
2680
if (SemaRef.getLangOpts().CPlusPlus11) {
2681
// nullptr
2682
Builder.AddResultTypeChunk("std::nullptr_t");
2683
Builder.AddTypedTextChunk("nullptr");
2684
Results.AddResult(Result(Builder.TakeString()));
2685
2686
// alignof
2687
Builder.AddResultTypeChunk("size_t");
2688
Builder.AddTypedTextChunk("alignof");
2689
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2690
Builder.AddPlaceholderChunk("type");
2691
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2692
Results.AddResult(Result(Builder.TakeString()));
2693
2694
// noexcept
2695
Builder.AddResultTypeChunk("bool");
2696
Builder.AddTypedTextChunk("noexcept");
2697
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2698
Builder.AddPlaceholderChunk("expression");
2699
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2700
Results.AddResult(Result(Builder.TakeString()));
2701
2702
// sizeof... expression
2703
Builder.AddResultTypeChunk("size_t");
2704
Builder.AddTypedTextChunk("sizeof...");
2705
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2706
Builder.AddPlaceholderChunk("parameter-pack");
2707
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2708
Results.AddResult(Result(Builder.TakeString()));
2709
}
2710
}
2711
2712
if (SemaRef.getLangOpts().ObjC) {
2713
// Add "super", if we're in an Objective-C class with a superclass.
2714
if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
2715
// The interface can be NULL.
2716
if (ObjCInterfaceDecl *ID = Method->getClassInterface())
2717
if (ID->getSuperClass()) {
2718
std::string SuperType;
2719
SuperType = ID->getSuperClass()->getNameAsString();
2720
if (Method->isInstanceMethod())
2721
SuperType += " *";
2722
2723
Builder.AddResultTypeChunk(Allocator.CopyString(SuperType));
2724
Builder.AddTypedTextChunk("super");
2725
Results.AddResult(Result(Builder.TakeString()));
2726
}
2727
}
2728
2729
AddObjCExpressionResults(Results, true);
2730
}
2731
2732
if (SemaRef.getLangOpts().C11) {
2733
// _Alignof
2734
Builder.AddResultTypeChunk("size_t");
2735
if (SemaRef.PP.isMacroDefined("alignof"))
2736
Builder.AddTypedTextChunk("alignof");
2737
else
2738
Builder.AddTypedTextChunk("_Alignof");
2739
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2740
Builder.AddPlaceholderChunk("type");
2741
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2742
Results.AddResult(Result(Builder.TakeString()));
2743
}
2744
2745
if (SemaRef.getLangOpts().C23) {
2746
// nullptr
2747
Builder.AddResultTypeChunk("nullptr_t");
2748
Builder.AddTypedTextChunk("nullptr");
2749
Results.AddResult(Result(Builder.TakeString()));
2750
}
2751
2752
// sizeof expression
2753
Builder.AddResultTypeChunk("size_t");
2754
Builder.AddTypedTextChunk("sizeof");
2755
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
2756
Builder.AddPlaceholderChunk("expression-or-type");
2757
Builder.AddChunk(CodeCompletionString::CK_RightParen);
2758
Results.AddResult(Result(Builder.TakeString()));
2759
break;
2760
}
2761
2762
case SemaCodeCompletion::PCC_Type:
2763
case SemaCodeCompletion::PCC_LocalDeclarationSpecifiers:
2764
break;
2765
}
2766
2767
if (WantTypesInContext(CCC, SemaRef.getLangOpts()))
2768
AddTypeSpecifierResults(SemaRef.getLangOpts(), Results);
2769
2770
if (SemaRef.getLangOpts().CPlusPlus && CCC != SemaCodeCompletion::PCC_Type)
2771
Results.AddResult(Result("operator"));
2772
}
2773
2774
/// If the given declaration has an associated type, add it as a result
2775
/// type chunk.
2776
static void AddResultTypeChunk(ASTContext &Context,
2777
const PrintingPolicy &Policy,
2778
const NamedDecl *ND, QualType BaseType,
2779
CodeCompletionBuilder &Result) {
2780
if (!ND)
2781
return;
2782
2783
// Skip constructors and conversion functions, which have their return types
2784
// built into their names.
2785
if (isConstructor(ND) || isa<CXXConversionDecl>(ND))
2786
return;
2787
2788
// Determine the type of the declaration (if it has a type).
2789
QualType T;
2790
if (const FunctionDecl *Function = ND->getAsFunction())
2791
T = Function->getReturnType();
2792
else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) {
2793
if (!BaseType.isNull())
2794
T = Method->getSendResultType(BaseType);
2795
else
2796
T = Method->getReturnType();
2797
} else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND)) {
2798
T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
2799
T = clang::TypeName::getFullyQualifiedType(T, Context);
2800
} else if (isa<UnresolvedUsingValueDecl>(ND)) {
2801
/* Do nothing: ignore unresolved using declarations*/
2802
} else if (const auto *Ivar = dyn_cast<ObjCIvarDecl>(ND)) {
2803
if (!BaseType.isNull())
2804
T = Ivar->getUsageType(BaseType);
2805
else
2806
T = Ivar->getType();
2807
} else if (const auto *Value = dyn_cast<ValueDecl>(ND)) {
2808
T = Value->getType();
2809
} else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND)) {
2810
if (!BaseType.isNull())
2811
T = Property->getUsageType(BaseType);
2812
else
2813
T = Property->getType();
2814
}
2815
2816
if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
2817
return;
2818
2819
Result.AddResultTypeChunk(
2820
GetCompletionTypeString(T, Context, Policy, Result.getAllocator()));
2821
}
2822
2823
static void MaybeAddSentinel(Preprocessor &PP,
2824
const NamedDecl *FunctionOrMethod,
2825
CodeCompletionBuilder &Result) {
2826
if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
2827
if (Sentinel->getSentinel() == 0) {
2828
if (PP.getLangOpts().ObjC && PP.isMacroDefined("nil"))
2829
Result.AddTextChunk(", nil");
2830
else if (PP.isMacroDefined("NULL"))
2831
Result.AddTextChunk(", NULL");
2832
else
2833
Result.AddTextChunk(", (void*)0");
2834
}
2835
}
2836
2837
static std::string formatObjCParamQualifiers(unsigned ObjCQuals,
2838
QualType &Type) {
2839
std::string Result;
2840
if (ObjCQuals & Decl::OBJC_TQ_In)
2841
Result += "in ";
2842
else if (ObjCQuals & Decl::OBJC_TQ_Inout)
2843
Result += "inout ";
2844
else if (ObjCQuals & Decl::OBJC_TQ_Out)
2845
Result += "out ";
2846
if (ObjCQuals & Decl::OBJC_TQ_Bycopy)
2847
Result += "bycopy ";
2848
else if (ObjCQuals & Decl::OBJC_TQ_Byref)
2849
Result += "byref ";
2850
if (ObjCQuals & Decl::OBJC_TQ_Oneway)
2851
Result += "oneway ";
2852
if (ObjCQuals & Decl::OBJC_TQ_CSNullability) {
2853
if (auto nullability = AttributedType::stripOuterNullability(Type)) {
2854
switch (*nullability) {
2855
case NullabilityKind::NonNull:
2856
Result += "nonnull ";
2857
break;
2858
2859
case NullabilityKind::Nullable:
2860
Result += "nullable ";
2861
break;
2862
2863
case NullabilityKind::Unspecified:
2864
Result += "null_unspecified ";
2865
break;
2866
2867
case NullabilityKind::NullableResult:
2868
llvm_unreachable("Not supported as a context-sensitive keyword!");
2869
break;
2870
}
2871
}
2872
}
2873
return Result;
2874
}
2875
2876
/// Tries to find the most appropriate type location for an Objective-C
2877
/// block placeholder.
2878
///
2879
/// This function ignores things like typedefs and qualifiers in order to
2880
/// present the most relevant and accurate block placeholders in code completion
2881
/// results.
2882
static void findTypeLocationForBlockDecl(const TypeSourceInfo *TSInfo,
2883
FunctionTypeLoc &Block,
2884
FunctionProtoTypeLoc &BlockProto,
2885
bool SuppressBlock = false) {
2886
if (!TSInfo)
2887
return;
2888
TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
2889
while (true) {
2890
// Look through typedefs.
2891
if (!SuppressBlock) {
2892
if (TypedefTypeLoc TypedefTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
2893
if (TypeSourceInfo *InnerTSInfo =
2894
TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) {
2895
TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
2896
continue;
2897
}
2898
}
2899
2900
// Look through qualified types
2901
if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) {
2902
TL = QualifiedTL.getUnqualifiedLoc();
2903
continue;
2904
}
2905
2906
if (AttributedTypeLoc AttrTL = TL.getAs<AttributedTypeLoc>()) {
2907
TL = AttrTL.getModifiedLoc();
2908
continue;
2909
}
2910
}
2911
2912
// Try to get the function prototype behind the block pointer type,
2913
// then we're done.
2914
if (BlockPointerTypeLoc BlockPtr = TL.getAs<BlockPointerTypeLoc>()) {
2915
TL = BlockPtr.getPointeeLoc().IgnoreParens();
2916
Block = TL.getAs<FunctionTypeLoc>();
2917
BlockProto = TL.getAs<FunctionProtoTypeLoc>();
2918
}
2919
break;
2920
}
2921
}
2922
2923
static std::string formatBlockPlaceholder(
2924
const PrintingPolicy &Policy, const NamedDecl *BlockDecl,
2925
FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto,
2926
bool SuppressBlockName = false, bool SuppressBlock = false,
2927
std::optional<ArrayRef<QualType>> ObjCSubsts = std::nullopt);
2928
2929
static std::string FormatFunctionParameter(
2930
const PrintingPolicy &Policy, const DeclaratorDecl *Param,
2931
bool SuppressName = false, bool SuppressBlock = false,
2932
std::optional<ArrayRef<QualType>> ObjCSubsts = std::nullopt) {
2933
// Params are unavailable in FunctionTypeLoc if the FunctionType is invalid.
2934
// It would be better to pass in the param Type, which is usually available.
2935
// But this case is rare, so just pretend we fell back to int as elsewhere.
2936
if (!Param)
2937
return "int";
2938
Decl::ObjCDeclQualifier ObjCQual = Decl::OBJC_TQ_None;
2939
if (const auto *PVD = dyn_cast<ParmVarDecl>(Param))
2940
ObjCQual = PVD->getObjCDeclQualifier();
2941
bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
2942
if (Param->getType()->isDependentType() ||
2943
!Param->getType()->isBlockPointerType()) {
2944
// The argument for a dependent or non-block parameter is a placeholder
2945
// containing that parameter's type.
2946
std::string Result;
2947
2948
if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
2949
Result = std::string(Param->getIdentifier()->deuglifiedName());
2950
2951
QualType Type = Param->getType();
2952
if (ObjCSubsts)
2953
Type = Type.substObjCTypeArgs(Param->getASTContext(), *ObjCSubsts,
2954
ObjCSubstitutionContext::Parameter);
2955
if (ObjCMethodParam) {
2956
Result = "(" + formatObjCParamQualifiers(ObjCQual, Type);
2957
Result += Type.getAsString(Policy) + ")";
2958
if (Param->getIdentifier() && !SuppressName)
2959
Result += Param->getIdentifier()->deuglifiedName();
2960
} else {
2961
Type.getAsStringInternal(Result, Policy);
2962
}
2963
return Result;
2964
}
2965
2966
// The argument for a block pointer parameter is a block literal with
2967
// the appropriate type.
2968
FunctionTypeLoc Block;
2969
FunctionProtoTypeLoc BlockProto;
2970
findTypeLocationForBlockDecl(Param->getTypeSourceInfo(), Block, BlockProto,
2971
SuppressBlock);
2972
// Try to retrieve the block type information from the property if this is a
2973
// parameter in a setter.
2974
if (!Block && ObjCMethodParam &&
2975
cast<ObjCMethodDecl>(Param->getDeclContext())->isPropertyAccessor()) {
2976
if (const auto *PD = cast<ObjCMethodDecl>(Param->getDeclContext())
2977
->findPropertyDecl(/*CheckOverrides=*/false))
2978
findTypeLocationForBlockDecl(PD->getTypeSourceInfo(), Block, BlockProto,
2979
SuppressBlock);
2980
}
2981
2982
if (!Block) {
2983
// We were unable to find a FunctionProtoTypeLoc with parameter names
2984
// for the block; just use the parameter type as a placeholder.
2985
std::string Result;
2986
if (!ObjCMethodParam && Param->getIdentifier())
2987
Result = std::string(Param->getIdentifier()->deuglifiedName());
2988
2989
QualType Type = Param->getType().getUnqualifiedType();
2990
2991
if (ObjCMethodParam) {
2992
Result = Type.getAsString(Policy);
2993
std::string Quals = formatObjCParamQualifiers(ObjCQual, Type);
2994
if (!Quals.empty())
2995
Result = "(" + Quals + " " + Result + ")";
2996
if (Result.back() != ')')
2997
Result += " ";
2998
if (Param->getIdentifier())
2999
Result += Param->getIdentifier()->deuglifiedName();
3000
} else {
3001
Type.getAsStringInternal(Result, Policy);
3002
}
3003
3004
return Result;
3005
}
3006
3007
// We have the function prototype behind the block pointer type, as it was
3008
// written in the source.
3009
return formatBlockPlaceholder(Policy, Param, Block, BlockProto,
3010
/*SuppressBlockName=*/false, SuppressBlock,
3011
ObjCSubsts);
3012
}
3013
3014
/// Returns a placeholder string that corresponds to an Objective-C block
3015
/// declaration.
3016
///
3017
/// \param BlockDecl A declaration with an Objective-C block type.
3018
///
3019
/// \param Block The most relevant type location for that block type.
3020
///
3021
/// \param SuppressBlockName Determines whether or not the name of the block
3022
/// declaration is included in the resulting string.
3023
static std::string
3024
formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl,
3025
FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto,
3026
bool SuppressBlockName, bool SuppressBlock,
3027
std::optional<ArrayRef<QualType>> ObjCSubsts) {
3028
std::string Result;
3029
QualType ResultType = Block.getTypePtr()->getReturnType();
3030
if (ObjCSubsts)
3031
ResultType =
3032
ResultType.substObjCTypeArgs(BlockDecl->getASTContext(), *ObjCSubsts,
3033
ObjCSubstitutionContext::Result);
3034
if (!ResultType->isVoidType() || SuppressBlock)
3035
ResultType.getAsStringInternal(Result, Policy);
3036
3037
// Format the parameter list.
3038
std::string Params;
3039
if (!BlockProto || Block.getNumParams() == 0) {
3040
if (BlockProto && BlockProto.getTypePtr()->isVariadic())
3041
Params = "(...)";
3042
else
3043
Params = "(void)";
3044
} else {
3045
Params += "(";
3046
for (unsigned I = 0, N = Block.getNumParams(); I != N; ++I) {
3047
if (I)
3048
Params += ", ";
3049
Params += FormatFunctionParameter(Policy, Block.getParam(I),
3050
/*SuppressName=*/false,
3051
/*SuppressBlock=*/true, ObjCSubsts);
3052
3053
if (I == N - 1 && BlockProto.getTypePtr()->isVariadic())
3054
Params += ", ...";
3055
}
3056
Params += ")";
3057
}
3058
3059
if (SuppressBlock) {
3060
// Format as a parameter.
3061
Result = Result + " (^";
3062
if (!SuppressBlockName && BlockDecl->getIdentifier())
3063
Result += BlockDecl->getIdentifier()->getName();
3064
Result += ")";
3065
Result += Params;
3066
} else {
3067
// Format as a block literal argument.
3068
Result = '^' + Result;
3069
Result += Params;
3070
3071
if (!SuppressBlockName && BlockDecl->getIdentifier())
3072
Result += BlockDecl->getIdentifier()->getName();
3073
}
3074
3075
return Result;
3076
}
3077
3078
static std::string GetDefaultValueString(const ParmVarDecl *Param,
3079
const SourceManager &SM,
3080
const LangOptions &LangOpts) {
3081
const SourceRange SrcRange = Param->getDefaultArgRange();
3082
CharSourceRange CharSrcRange = CharSourceRange::getTokenRange(SrcRange);
3083
bool Invalid = CharSrcRange.isInvalid();
3084
if (Invalid)
3085
return "";
3086
StringRef srcText =
3087
Lexer::getSourceText(CharSrcRange, SM, LangOpts, &Invalid);
3088
if (Invalid)
3089
return "";
3090
3091
if (srcText.empty() || srcText == "=") {
3092
// Lexer can't determine the value.
3093
// This happens if the code is incorrect (for example class is forward
3094
// declared).
3095
return "";
3096
}
3097
std::string DefValue(srcText.str());
3098
// FIXME: remove this check if the Lexer::getSourceText value is fixed and
3099
// this value always has (or always does not have) '=' in front of it
3100
if (DefValue.at(0) != '=') {
3101
// If we don't have '=' in front of value.
3102
// Lexer returns built-in types values without '=' and user-defined types
3103
// values with it.
3104
return " = " + DefValue;
3105
}
3106
return " " + DefValue;
3107
}
3108
3109
/// Add function parameter chunks to the given code completion string.
3110
static void AddFunctionParameterChunks(Preprocessor &PP,
3111
const PrintingPolicy &Policy,
3112
const FunctionDecl *Function,
3113
CodeCompletionBuilder &Result,
3114
unsigned Start = 0,
3115
bool InOptional = false) {
3116
bool FirstParameter = true;
3117
3118
for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) {
3119
const ParmVarDecl *Param = Function->getParamDecl(P);
3120
3121
if (Param->hasDefaultArg() && !InOptional) {
3122
// When we see an optional default argument, put that argument and
3123
// the remaining default arguments into a new, optional string.
3124
CodeCompletionBuilder Opt(Result.getAllocator(),
3125
Result.getCodeCompletionTUInfo());
3126
if (!FirstParameter)
3127
Opt.AddChunk(CodeCompletionString::CK_Comma);
3128
AddFunctionParameterChunks(PP, Policy, Function, Opt, P, true);
3129
Result.AddOptionalChunk(Opt.TakeString());
3130
break;
3131
}
3132
3133
if (FirstParameter)
3134
FirstParameter = false;
3135
else
3136
Result.AddChunk(CodeCompletionString::CK_Comma);
3137
3138
InOptional = false;
3139
3140
// Format the placeholder string.
3141
std::string PlaceholderStr = FormatFunctionParameter(Policy, Param);
3142
if (Param->hasDefaultArg())
3143
PlaceholderStr +=
3144
GetDefaultValueString(Param, PP.getSourceManager(), PP.getLangOpts());
3145
3146
if (Function->isVariadic() && P == N - 1)
3147
PlaceholderStr += ", ...";
3148
3149
// Add the placeholder string.
3150
Result.AddPlaceholderChunk(
3151
Result.getAllocator().CopyString(PlaceholderStr));
3152
}
3153
3154
if (const auto *Proto = Function->getType()->getAs<FunctionProtoType>())
3155
if (Proto->isVariadic()) {
3156
if (Proto->getNumParams() == 0)
3157
Result.AddPlaceholderChunk("...");
3158
3159
MaybeAddSentinel(PP, Function, Result);
3160
}
3161
}
3162
3163
/// Add template parameter chunks to the given code completion string.
3164
static void AddTemplateParameterChunks(
3165
ASTContext &Context, const PrintingPolicy &Policy,
3166
const TemplateDecl *Template, CodeCompletionBuilder &Result,
3167
unsigned MaxParameters = 0, unsigned Start = 0, bool InDefaultArg = false) {
3168
bool FirstParameter = true;
3169
3170
// Prefer to take the template parameter names from the first declaration of
3171
// the template.
3172
Template = cast<TemplateDecl>(Template->getCanonicalDecl());
3173
3174
TemplateParameterList *Params = Template->getTemplateParameters();
3175
TemplateParameterList::iterator PEnd = Params->end();
3176
if (MaxParameters)
3177
PEnd = Params->begin() + MaxParameters;
3178
for (TemplateParameterList::iterator P = Params->begin() + Start; P != PEnd;
3179
++P) {
3180
bool HasDefaultArg = false;
3181
std::string PlaceholderStr;
3182
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
3183
if (TTP->wasDeclaredWithTypename())
3184
PlaceholderStr = "typename";
3185
else if (const auto *TC = TTP->getTypeConstraint()) {
3186
llvm::raw_string_ostream OS(PlaceholderStr);
3187
TC->print(OS, Policy);
3188
} else
3189
PlaceholderStr = "class";
3190
3191
if (TTP->getIdentifier()) {
3192
PlaceholderStr += ' ';
3193
PlaceholderStr += TTP->getIdentifier()->deuglifiedName();
3194
}
3195
3196
HasDefaultArg = TTP->hasDefaultArgument();
3197
} else if (NonTypeTemplateParmDecl *NTTP =
3198
dyn_cast<NonTypeTemplateParmDecl>(*P)) {
3199
if (NTTP->getIdentifier())
3200
PlaceholderStr = std::string(NTTP->getIdentifier()->deuglifiedName());
3201
NTTP->getType().getAsStringInternal(PlaceholderStr, Policy);
3202
HasDefaultArg = NTTP->hasDefaultArgument();
3203
} else {
3204
assert(isa<TemplateTemplateParmDecl>(*P));
3205
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
3206
3207
// Since putting the template argument list into the placeholder would
3208
// be very, very long, we just use an abbreviation.
3209
PlaceholderStr = "template<...> class";
3210
if (TTP->getIdentifier()) {
3211
PlaceholderStr += ' ';
3212
PlaceholderStr += TTP->getIdentifier()->deuglifiedName();
3213
}
3214
3215
HasDefaultArg = TTP->hasDefaultArgument();
3216
}
3217
3218
if (HasDefaultArg && !InDefaultArg) {
3219
// When we see an optional default argument, put that argument and
3220
// the remaining default arguments into a new, optional string.
3221
CodeCompletionBuilder Opt(Result.getAllocator(),
3222
Result.getCodeCompletionTUInfo());
3223
if (!FirstParameter)
3224
Opt.AddChunk(CodeCompletionString::CK_Comma);
3225
AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters,
3226
P - Params->begin(), true);
3227
Result.AddOptionalChunk(Opt.TakeString());
3228
break;
3229
}
3230
3231
InDefaultArg = false;
3232
3233
if (FirstParameter)
3234
FirstParameter = false;
3235
else
3236
Result.AddChunk(CodeCompletionString::CK_Comma);
3237
3238
// Add the placeholder string.
3239
Result.AddPlaceholderChunk(
3240
Result.getAllocator().CopyString(PlaceholderStr));
3241
}
3242
}
3243
3244
/// Add a qualifier to the given code-completion string, if the
3245
/// provided nested-name-specifier is non-NULL.
3246
static void AddQualifierToCompletionString(CodeCompletionBuilder &Result,
3247
NestedNameSpecifier *Qualifier,
3248
bool QualifierIsInformative,
3249
ASTContext &Context,
3250
const PrintingPolicy &Policy) {
3251
if (!Qualifier)
3252
return;
3253
3254
std::string PrintedNNS;
3255
{
3256
llvm::raw_string_ostream OS(PrintedNNS);
3257
Qualifier->print(OS, Policy);
3258
}
3259
if (QualifierIsInformative)
3260
Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS));
3261
else
3262
Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS));
3263
}
3264
3265
static void
3266
AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
3267
const FunctionDecl *Function) {
3268
const auto *Proto = Function->getType()->getAs<FunctionProtoType>();
3269
if (!Proto || !Proto->getMethodQuals())
3270
return;
3271
3272
// FIXME: Add ref-qualifier!
3273
3274
// Handle single qualifiers without copying
3275
if (Proto->getMethodQuals().hasOnlyConst()) {
3276
Result.AddInformativeChunk(" const");
3277
return;
3278
}
3279
3280
if (Proto->getMethodQuals().hasOnlyVolatile()) {
3281
Result.AddInformativeChunk(" volatile");
3282
return;
3283
}
3284
3285
if (Proto->getMethodQuals().hasOnlyRestrict()) {
3286
Result.AddInformativeChunk(" restrict");
3287
return;
3288
}
3289
3290
// Handle multiple qualifiers.
3291
std::string QualsStr;
3292
if (Proto->isConst())
3293
QualsStr += " const";
3294
if (Proto->isVolatile())
3295
QualsStr += " volatile";
3296
if (Proto->isRestrict())
3297
QualsStr += " restrict";
3298
Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr));
3299
}
3300
3301
/// Add the name of the given declaration
3302
static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
3303
const NamedDecl *ND,
3304
CodeCompletionBuilder &Result) {
3305
DeclarationName Name = ND->getDeclName();
3306
if (!Name)
3307
return;
3308
3309
switch (Name.getNameKind()) {
3310
case DeclarationName::CXXOperatorName: {
3311
const char *OperatorName = nullptr;
3312
switch (Name.getCXXOverloadedOperator()) {
3313
case OO_None:
3314
case OO_Conditional:
3315
case NUM_OVERLOADED_OPERATORS:
3316
OperatorName = "operator";
3317
break;
3318
3319
#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
3320
case OO_##Name: \
3321
OperatorName = "operator" Spelling; \
3322
break;
3323
#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemberOnly)
3324
#include "clang/Basic/OperatorKinds.def"
3325
3326
case OO_New:
3327
OperatorName = "operator new";
3328
break;
3329
case OO_Delete:
3330
OperatorName = "operator delete";
3331
break;
3332
case OO_Array_New:
3333
OperatorName = "operator new[]";
3334
break;
3335
case OO_Array_Delete:
3336
OperatorName = "operator delete[]";
3337
break;
3338
case OO_Call:
3339
OperatorName = "operator()";
3340
break;
3341
case OO_Subscript:
3342
OperatorName = "operator[]";
3343
break;
3344
}
3345
Result.AddTypedTextChunk(OperatorName);
3346
break;
3347
}
3348
3349
case DeclarationName::Identifier:
3350
case DeclarationName::CXXConversionFunctionName:
3351
case DeclarationName::CXXDestructorName:
3352
case DeclarationName::CXXLiteralOperatorName:
3353
Result.AddTypedTextChunk(
3354
Result.getAllocator().CopyString(ND->getNameAsString()));
3355
break;
3356
3357
case DeclarationName::CXXDeductionGuideName:
3358
case DeclarationName::CXXUsingDirective:
3359
case DeclarationName::ObjCZeroArgSelector:
3360
case DeclarationName::ObjCOneArgSelector:
3361
case DeclarationName::ObjCMultiArgSelector:
3362
break;
3363
3364
case DeclarationName::CXXConstructorName: {
3365
CXXRecordDecl *Record = nullptr;
3366
QualType Ty = Name.getCXXNameType();
3367
if (const auto *RecordTy = Ty->getAs<RecordType>())
3368
Record = cast<CXXRecordDecl>(RecordTy->getDecl());
3369
else if (const auto *InjectedTy = Ty->getAs<InjectedClassNameType>())
3370
Record = InjectedTy->getDecl();
3371
else {
3372
Result.AddTypedTextChunk(
3373
Result.getAllocator().CopyString(ND->getNameAsString()));
3374
break;
3375
}
3376
3377
Result.AddTypedTextChunk(
3378
Result.getAllocator().CopyString(Record->getNameAsString()));
3379
if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
3380
Result.AddChunk(CodeCompletionString::CK_LeftAngle);
3381
AddTemplateParameterChunks(Context, Policy, Template, Result);
3382
Result.AddChunk(CodeCompletionString::CK_RightAngle);
3383
}
3384
break;
3385
}
3386
}
3387
}
3388
3389
CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(
3390
Sema &S, const CodeCompletionContext &CCContext,
3391
CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
3392
bool IncludeBriefComments) {
3393
return CreateCodeCompletionString(S.Context, S.PP, CCContext, Allocator,
3394
CCTUInfo, IncludeBriefComments);
3395
}
3396
3397
CodeCompletionString *CodeCompletionResult::CreateCodeCompletionStringForMacro(
3398
Preprocessor &PP, CodeCompletionAllocator &Allocator,
3399
CodeCompletionTUInfo &CCTUInfo) {
3400
assert(Kind == RK_Macro);
3401
CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
3402
const MacroInfo *MI = PP.getMacroInfo(Macro);
3403
Result.AddTypedTextChunk(Result.getAllocator().CopyString(Macro->getName()));
3404
3405
if (!MI || !MI->isFunctionLike())
3406
return Result.TakeString();
3407
3408
// Format a function-like macro with placeholders for the arguments.
3409
Result.AddChunk(CodeCompletionString::CK_LeftParen);
3410
MacroInfo::param_iterator A = MI->param_begin(), AEnd = MI->param_end();
3411
3412
// C99 variadic macros add __VA_ARGS__ at the end. Skip it.
3413
if (MI->isC99Varargs()) {
3414
--AEnd;
3415
3416
if (A == AEnd) {
3417
Result.AddPlaceholderChunk("...");
3418
}
3419
}
3420
3421
for (MacroInfo::param_iterator A = MI->param_begin(); A != AEnd; ++A) {
3422
if (A != MI->param_begin())
3423
Result.AddChunk(CodeCompletionString::CK_Comma);
3424
3425
if (MI->isVariadic() && (A + 1) == AEnd) {
3426
SmallString<32> Arg = (*A)->getName();
3427
if (MI->isC99Varargs())
3428
Arg += ", ...";
3429
else
3430
Arg += "...";
3431
Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
3432
break;
3433
}
3434
3435
// Non-variadic macros are simple.
3436
Result.AddPlaceholderChunk(
3437
Result.getAllocator().CopyString((*A)->getName()));
3438
}
3439
Result.AddChunk(CodeCompletionString::CK_RightParen);
3440
return Result.TakeString();
3441
}
3442
3443
/// If possible, create a new code completion string for the given
3444
/// result.
3445
///
3446
/// \returns Either a new, heap-allocated code completion string describing
3447
/// how to use this result, or NULL to indicate that the string or name of the
3448
/// result is all that is needed.
3449
CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(
3450
ASTContext &Ctx, Preprocessor &PP, const CodeCompletionContext &CCContext,
3451
CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
3452
bool IncludeBriefComments) {
3453
if (Kind == RK_Macro)
3454
return CreateCodeCompletionStringForMacro(PP, Allocator, CCTUInfo);
3455
3456
CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability);
3457
3458
PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP);
3459
if (Kind == RK_Pattern) {
3460
Pattern->Priority = Priority;
3461
Pattern->Availability = Availability;
3462
3463
if (Declaration) {
3464
Result.addParentContext(Declaration->getDeclContext());
3465
Pattern->ParentName = Result.getParentName();
3466
if (const RawComment *RC =
3467
getPatternCompletionComment(Ctx, Declaration)) {
3468
Result.addBriefComment(RC->getBriefText(Ctx));
3469
Pattern->BriefComment = Result.getBriefComment();
3470
}
3471
}
3472
3473
return Pattern;
3474
}
3475
3476
if (Kind == RK_Keyword) {
3477
Result.AddTypedTextChunk(Keyword);
3478
return Result.TakeString();
3479
}
3480
assert(Kind == RK_Declaration && "Missed a result kind?");
3481
return createCodeCompletionStringForDecl(
3482
PP, Ctx, Result, IncludeBriefComments, CCContext, Policy);
3483
}
3484
3485
static void printOverrideString(const CodeCompletionString &CCS,
3486
std::string &BeforeName,
3487
std::string &NameAndSignature) {
3488
bool SeenTypedChunk = false;
3489
for (auto &Chunk : CCS) {
3490
if (Chunk.Kind == CodeCompletionString::CK_Optional) {
3491
assert(SeenTypedChunk && "optional parameter before name");
3492
// Note that we put all chunks inside into NameAndSignature.
3493
printOverrideString(*Chunk.Optional, NameAndSignature, NameAndSignature);
3494
continue;
3495
}
3496
SeenTypedChunk |= Chunk.Kind == CodeCompletionString::CK_TypedText;
3497
if (SeenTypedChunk)
3498
NameAndSignature += Chunk.Text;
3499
else
3500
BeforeName += Chunk.Text;
3501
}
3502
}
3503
3504
CodeCompletionString *
3505
CodeCompletionResult::createCodeCompletionStringForOverride(
3506
Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result,
3507
bool IncludeBriefComments, const CodeCompletionContext &CCContext,
3508
PrintingPolicy &Policy) {
3509
auto *CCS = createCodeCompletionStringForDecl(PP, Ctx, Result,
3510
/*IncludeBriefComments=*/false,
3511
CCContext, Policy);
3512
std::string BeforeName;
3513
std::string NameAndSignature;
3514
// For overrides all chunks go into the result, none are informative.
3515
printOverrideString(*CCS, BeforeName, NameAndSignature);
3516
NameAndSignature += " override";
3517
3518
Result.AddTextChunk(Result.getAllocator().CopyString(BeforeName));
3519
Result.AddChunk(CodeCompletionString::CK_HorizontalSpace);
3520
Result.AddTypedTextChunk(Result.getAllocator().CopyString(NameAndSignature));
3521
return Result.TakeString();
3522
}
3523
3524
// FIXME: Right now this works well with lambdas. Add support for other functor
3525
// types like std::function.
3526
static const NamedDecl *extractFunctorCallOperator(const NamedDecl *ND) {
3527
const auto *VD = dyn_cast<VarDecl>(ND);
3528
if (!VD)
3529
return nullptr;
3530
const auto *RecordDecl = VD->getType()->getAsCXXRecordDecl();
3531
if (!RecordDecl || !RecordDecl->isLambda())
3532
return nullptr;
3533
return RecordDecl->getLambdaCallOperator();
3534
}
3535
3536
CodeCompletionString *CodeCompletionResult::createCodeCompletionStringForDecl(
3537
Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result,
3538
bool IncludeBriefComments, const CodeCompletionContext &CCContext,
3539
PrintingPolicy &Policy) {
3540
const NamedDecl *ND = Declaration;
3541
Result.addParentContext(ND->getDeclContext());
3542
3543
if (IncludeBriefComments) {
3544
// Add documentation comment, if it exists.
3545
if (const RawComment *RC = getCompletionComment(Ctx, Declaration)) {
3546
Result.addBriefComment(RC->getBriefText(Ctx));
3547
}
3548
}
3549
3550
if (StartsNestedNameSpecifier) {
3551
Result.AddTypedTextChunk(
3552
Result.getAllocator().CopyString(ND->getNameAsString()));
3553
Result.AddTextChunk("::");
3554
return Result.TakeString();
3555
}
3556
3557
for (const auto *I : ND->specific_attrs<AnnotateAttr>())
3558
Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation()));
3559
3560
auto AddFunctionTypeAndResult = [&](const FunctionDecl *Function) {
3561
AddResultTypeChunk(Ctx, Policy, Function, CCContext.getBaseType(), Result);
3562
AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
3563
Ctx, Policy);
3564
AddTypedNameChunk(Ctx, Policy, ND, Result);
3565
Result.AddChunk(CodeCompletionString::CK_LeftParen);
3566
AddFunctionParameterChunks(PP, Policy, Function, Result);
3567
Result.AddChunk(CodeCompletionString::CK_RightParen);
3568
AddFunctionTypeQualsToCompletionString(Result, Function);
3569
};
3570
3571
if (const auto *Function = dyn_cast<FunctionDecl>(ND)) {
3572
AddFunctionTypeAndResult(Function);
3573
return Result.TakeString();
3574
}
3575
3576
if (const auto *CallOperator =
3577
dyn_cast_or_null<FunctionDecl>(extractFunctorCallOperator(ND))) {
3578
AddFunctionTypeAndResult(CallOperator);
3579
return Result.TakeString();
3580
}
3581
3582
AddResultTypeChunk(Ctx, Policy, ND, CCContext.getBaseType(), Result);
3583
3584
if (const FunctionTemplateDecl *FunTmpl =
3585
dyn_cast<FunctionTemplateDecl>(ND)) {
3586
AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
3587
Ctx, Policy);
3588
FunctionDecl *Function = FunTmpl->getTemplatedDecl();
3589
AddTypedNameChunk(Ctx, Policy, Function, Result);
3590
3591
// Figure out which template parameters are deduced (or have default
3592
// arguments).
3593
// Note that we're creating a non-empty bit vector so that we can go
3594
// through the loop below to omit default template parameters for non-call
3595
// cases.
3596
llvm::SmallBitVector Deduced(FunTmpl->getTemplateParameters()->size());
3597
// Avoid running it if this is not a call: We should emit *all* template
3598
// parameters.
3599
if (FunctionCanBeCall)
3600
Sema::MarkDeducedTemplateParameters(Ctx, FunTmpl, Deduced);
3601
unsigned LastDeducibleArgument;
3602
for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
3603
--LastDeducibleArgument) {
3604
if (!Deduced[LastDeducibleArgument - 1]) {
3605
// C++0x: Figure out if the template argument has a default. If so,
3606
// the user doesn't need to type this argument.
3607
// FIXME: We need to abstract template parameters better!
3608
bool HasDefaultArg = false;
3609
NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
3610
LastDeducibleArgument - 1);
3611
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3612
HasDefaultArg = TTP->hasDefaultArgument();
3613
else if (NonTypeTemplateParmDecl *NTTP =
3614
dyn_cast<NonTypeTemplateParmDecl>(Param))
3615
HasDefaultArg = NTTP->hasDefaultArgument();
3616
else {
3617
assert(isa<TemplateTemplateParmDecl>(Param));
3618
HasDefaultArg =
3619
cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
3620
}
3621
3622
if (!HasDefaultArg)
3623
break;
3624
}
3625
}
3626
3627
if (LastDeducibleArgument || !FunctionCanBeCall) {
3628
// Some of the function template arguments cannot be deduced from a
3629
// function call, so we introduce an explicit template argument list
3630
// containing all of the arguments up to the first deducible argument.
3631
//
3632
// Or, if this isn't a call, emit all the template arguments
3633
// to disambiguate the (potential) overloads.
3634
//
3635
// FIXME: Detect cases where the function parameters can be deduced from
3636
// the surrounding context, as per [temp.deduct.funcaddr].
3637
// e.g.,
3638
// template <class T> void foo(T);
3639
// void (*f)(int) = foo;
3640
Result.AddChunk(CodeCompletionString::CK_LeftAngle);
3641
AddTemplateParameterChunks(Ctx, Policy, FunTmpl, Result,
3642
LastDeducibleArgument);
3643
Result.AddChunk(CodeCompletionString::CK_RightAngle);
3644
}
3645
3646
// Add the function parameters
3647
Result.AddChunk(CodeCompletionString::CK_LeftParen);
3648
AddFunctionParameterChunks(PP, Policy, Function, Result);
3649
Result.AddChunk(CodeCompletionString::CK_RightParen);
3650
AddFunctionTypeQualsToCompletionString(Result, Function);
3651
return Result.TakeString();
3652
}
3653
3654
if (const auto *Template = dyn_cast<TemplateDecl>(ND)) {
3655
AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
3656
Ctx, Policy);
3657
Result.AddTypedTextChunk(
3658
Result.getAllocator().CopyString(Template->getNameAsString()));
3659
Result.AddChunk(CodeCompletionString::CK_LeftAngle);
3660
AddTemplateParameterChunks(Ctx, Policy, Template, Result);
3661
Result.AddChunk(CodeCompletionString::CK_RightAngle);
3662
return Result.TakeString();
3663
}
3664
3665
if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) {
3666
Selector Sel = Method->getSelector();
3667
if (Sel.isUnarySelector()) {
3668
Result.AddTypedTextChunk(
3669
Result.getAllocator().CopyString(Sel.getNameForSlot(0)));
3670
return Result.TakeString();
3671
}
3672
3673
std::string SelName = Sel.getNameForSlot(0).str();
3674
SelName += ':';
3675
if (StartParameter == 0)
3676
Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName));
3677
else {
3678
Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName));
3679
3680
// If there is only one parameter, and we're past it, add an empty
3681
// typed-text chunk since there is nothing to type.
3682
if (Method->param_size() == 1)
3683
Result.AddTypedTextChunk("");
3684
}
3685
unsigned Idx = 0;
3686
// The extra Idx < Sel.getNumArgs() check is needed due to legacy C-style
3687
// method parameters.
3688
for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
3689
PEnd = Method->param_end();
3690
P != PEnd && Idx < Sel.getNumArgs(); (void)++P, ++Idx) {
3691
if (Idx > 0) {
3692
std::string Keyword;
3693
if (Idx > StartParameter)
3694
Result.AddChunk(CodeCompletionString::CK_HorizontalSpace);
3695
if (const IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
3696
Keyword += II->getName();
3697
Keyword += ":";
3698
if (Idx < StartParameter || AllParametersAreInformative)
3699
Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword));
3700
else
3701
Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword));
3702
}
3703
3704
// If we're before the starting parameter, skip the placeholder.
3705
if (Idx < StartParameter)
3706
continue;
3707
3708
std::string Arg;
3709
QualType ParamType = (*P)->getType();
3710
std::optional<ArrayRef<QualType>> ObjCSubsts;
3711
if (!CCContext.getBaseType().isNull())
3712
ObjCSubsts = CCContext.getBaseType()->getObjCSubstitutions(Method);
3713
3714
if (ParamType->isBlockPointerType() && !DeclaringEntity)
3715
Arg = FormatFunctionParameter(Policy, *P, true,
3716
/*SuppressBlock=*/false, ObjCSubsts);
3717
else {
3718
if (ObjCSubsts)
3719
ParamType = ParamType.substObjCTypeArgs(
3720
Ctx, *ObjCSubsts, ObjCSubstitutionContext::Parameter);
3721
Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier(),
3722
ParamType);
3723
Arg += ParamType.getAsString(Policy) + ")";
3724
if (const IdentifierInfo *II = (*P)->getIdentifier())
3725
if (DeclaringEntity || AllParametersAreInformative)
3726
Arg += II->getName();
3727
}
3728
3729
if (Method->isVariadic() && (P + 1) == PEnd)
3730
Arg += ", ...";
3731
3732
if (DeclaringEntity)
3733
Result.AddTextChunk(Result.getAllocator().CopyString(Arg));
3734
else if (AllParametersAreInformative)
3735
Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg));
3736
else
3737
Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg));
3738
}
3739
3740
if (Method->isVariadic()) {
3741
if (Method->param_size() == 0) {
3742
if (DeclaringEntity)
3743
Result.AddTextChunk(", ...");
3744
else if (AllParametersAreInformative)
3745
Result.AddInformativeChunk(", ...");
3746
else
3747
Result.AddPlaceholderChunk(", ...");
3748
}
3749
3750
MaybeAddSentinel(PP, Method, Result);
3751
}
3752
3753
return Result.TakeString();
3754
}
3755
3756
if (Qualifier)
3757
AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
3758
Ctx, Policy);
3759
3760
Result.AddTypedTextChunk(
3761
Result.getAllocator().CopyString(ND->getNameAsString()));
3762
return Result.TakeString();
3763
}
3764
3765
const RawComment *clang::getCompletionComment(const ASTContext &Ctx,
3766
const NamedDecl *ND) {
3767
if (!ND)
3768
return nullptr;
3769
if (auto *RC = Ctx.getRawCommentForAnyRedecl(ND))
3770
return RC;
3771
3772
// Try to find comment from a property for ObjC methods.
3773
const auto *M = dyn_cast<ObjCMethodDecl>(ND);
3774
if (!M)
3775
return nullptr;
3776
const ObjCPropertyDecl *PDecl = M->findPropertyDecl();
3777
if (!PDecl)
3778
return nullptr;
3779
3780
return Ctx.getRawCommentForAnyRedecl(PDecl);
3781
}
3782
3783
const RawComment *clang::getPatternCompletionComment(const ASTContext &Ctx,
3784
const NamedDecl *ND) {
3785
const auto *M = dyn_cast_or_null<ObjCMethodDecl>(ND);
3786
if (!M || !M->isPropertyAccessor())
3787
return nullptr;
3788
3789
// Provide code completion comment for self.GetterName where
3790
// GetterName is the getter method for a property with name
3791
// different from the property name (declared via a property
3792
// getter attribute.
3793
const ObjCPropertyDecl *PDecl = M->findPropertyDecl();
3794
if (!PDecl)
3795
return nullptr;
3796
if (PDecl->getGetterName() == M->getSelector() &&
3797
PDecl->getIdentifier() != M->getIdentifier()) {
3798
if (auto *RC = Ctx.getRawCommentForAnyRedecl(M))
3799
return RC;
3800
if (auto *RC = Ctx.getRawCommentForAnyRedecl(PDecl))
3801
return RC;
3802
}
3803
return nullptr;
3804
}
3805
3806
const RawComment *clang::getParameterComment(
3807
const ASTContext &Ctx,
3808
const CodeCompleteConsumer::OverloadCandidate &Result, unsigned ArgIndex) {
3809
auto FDecl = Result.getFunction();
3810
if (!FDecl)
3811
return nullptr;
3812
if (ArgIndex < FDecl->getNumParams())
3813
return Ctx.getRawCommentForAnyRedecl(FDecl->getParamDecl(ArgIndex));
3814
return nullptr;
3815
}
3816
3817
static void AddOverloadAggregateChunks(const RecordDecl *RD,
3818
const PrintingPolicy &Policy,
3819
CodeCompletionBuilder &Result,
3820
unsigned CurrentArg) {
3821
unsigned ChunkIndex = 0;
3822
auto AddChunk = [&](llvm::StringRef Placeholder) {
3823
if (ChunkIndex > 0)
3824
Result.AddChunk(CodeCompletionString::CK_Comma);
3825
const char *Copy = Result.getAllocator().CopyString(Placeholder);
3826
if (ChunkIndex == CurrentArg)
3827
Result.AddCurrentParameterChunk(Copy);
3828
else
3829
Result.AddPlaceholderChunk(Copy);
3830
++ChunkIndex;
3831
};
3832
// Aggregate initialization has all bases followed by all fields.
3833
// (Bases are not legal in C++11 but in that case we never get here).
3834
if (auto *CRD = llvm::dyn_cast<CXXRecordDecl>(RD)) {
3835
for (const auto &Base : CRD->bases())
3836
AddChunk(Base.getType().getAsString(Policy));
3837
}
3838
for (const auto &Field : RD->fields())
3839
AddChunk(FormatFunctionParameter(Policy, Field));
3840
}
3841
3842
/// Add function overload parameter chunks to the given code completion
3843
/// string.
3844
static void AddOverloadParameterChunks(
3845
ASTContext &Context, const PrintingPolicy &Policy,
3846
const FunctionDecl *Function, const FunctionProtoType *Prototype,
3847
FunctionProtoTypeLoc PrototypeLoc, CodeCompletionBuilder &Result,
3848
unsigned CurrentArg, unsigned Start = 0, bool InOptional = false) {
3849
if (!Function && !Prototype) {
3850
Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
3851
return;
3852
}
3853
3854
bool FirstParameter = true;
3855
unsigned NumParams =
3856
Function ? Function->getNumParams() : Prototype->getNumParams();
3857
3858
for (unsigned P = Start; P != NumParams; ++P) {
3859
if (Function && Function->getParamDecl(P)->hasDefaultArg() && !InOptional) {
3860
// When we see an optional default argument, put that argument and
3861
// the remaining default arguments into a new, optional string.
3862
CodeCompletionBuilder Opt(Result.getAllocator(),
3863
Result.getCodeCompletionTUInfo());
3864
if (!FirstParameter)
3865
Opt.AddChunk(CodeCompletionString::CK_Comma);
3866
// Optional sections are nested.
3867
AddOverloadParameterChunks(Context, Policy, Function, Prototype,
3868
PrototypeLoc, Opt, CurrentArg, P,
3869
/*InOptional=*/true);
3870
Result.AddOptionalChunk(Opt.TakeString());
3871
return;
3872
}
3873
3874
if (FirstParameter)
3875
FirstParameter = false;
3876
else
3877
Result.AddChunk(CodeCompletionString::CK_Comma);
3878
3879
InOptional = false;
3880
3881
// Format the placeholder string.
3882
std::string Placeholder;
3883
assert(P < Prototype->getNumParams());
3884
if (Function || PrototypeLoc) {
3885
const ParmVarDecl *Param =
3886
Function ? Function->getParamDecl(P) : PrototypeLoc.getParam(P);
3887
Placeholder = FormatFunctionParameter(Policy, Param);
3888
if (Param->hasDefaultArg())
3889
Placeholder += GetDefaultValueString(Param, Context.getSourceManager(),
3890
Context.getLangOpts());
3891
} else {
3892
Placeholder = Prototype->getParamType(P).getAsString(Policy);
3893
}
3894
3895
if (P == CurrentArg)
3896
Result.AddCurrentParameterChunk(
3897
Result.getAllocator().CopyString(Placeholder));
3898
else
3899
Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Placeholder));
3900
}
3901
3902
if (Prototype && Prototype->isVariadic()) {
3903
CodeCompletionBuilder Opt(Result.getAllocator(),
3904
Result.getCodeCompletionTUInfo());
3905
if (!FirstParameter)
3906
Opt.AddChunk(CodeCompletionString::CK_Comma);
3907
3908
if (CurrentArg < NumParams)
3909
Opt.AddPlaceholderChunk("...");
3910
else
3911
Opt.AddCurrentParameterChunk("...");
3912
3913
Result.AddOptionalChunk(Opt.TakeString());
3914
}
3915
}
3916
3917
static std::string
3918
formatTemplateParameterPlaceholder(const NamedDecl *Param, bool &Optional,
3919
const PrintingPolicy &Policy) {
3920
if (const auto *Type = dyn_cast<TemplateTypeParmDecl>(Param)) {
3921
Optional = Type->hasDefaultArgument();
3922
} else if (const auto *NonType = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3923
Optional = NonType->hasDefaultArgument();
3924
} else if (const auto *Template = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3925
Optional = Template->hasDefaultArgument();
3926
}
3927
std::string Result;
3928
llvm::raw_string_ostream OS(Result);
3929
Param->print(OS, Policy);
3930
return Result;
3931
}
3932
3933
static std::string templateResultType(const TemplateDecl *TD,
3934
const PrintingPolicy &Policy) {
3935
if (const auto *CTD = dyn_cast<ClassTemplateDecl>(TD))
3936
return CTD->getTemplatedDecl()->getKindName().str();
3937
if (const auto *VTD = dyn_cast<VarTemplateDecl>(TD))
3938
return VTD->getTemplatedDecl()->getType().getAsString(Policy);
3939
if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(TD))
3940
return FTD->getTemplatedDecl()->getReturnType().getAsString(Policy);
3941
if (isa<TypeAliasTemplateDecl>(TD))
3942
return "type";
3943
if (isa<TemplateTemplateParmDecl>(TD))
3944
return "class";
3945
if (isa<ConceptDecl>(TD))
3946
return "concept";
3947
return "";
3948
}
3949
3950
static CodeCompletionString *createTemplateSignatureString(
3951
const TemplateDecl *TD, CodeCompletionBuilder &Builder, unsigned CurrentArg,
3952
const PrintingPolicy &Policy) {
3953
llvm::ArrayRef<NamedDecl *> Params = TD->getTemplateParameters()->asArray();
3954
CodeCompletionBuilder OptionalBuilder(Builder.getAllocator(),
3955
Builder.getCodeCompletionTUInfo());
3956
std::string ResultType = templateResultType(TD, Policy);
3957
if (!ResultType.empty())
3958
Builder.AddResultTypeChunk(Builder.getAllocator().CopyString(ResultType));
3959
Builder.AddTextChunk(
3960
Builder.getAllocator().CopyString(TD->getNameAsString()));
3961
Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
3962
// Initially we're writing into the main string. Once we see an optional arg
3963
// (with default), we're writing into the nested optional chunk.
3964
CodeCompletionBuilder *Current = &Builder;
3965
for (unsigned I = 0; I < Params.size(); ++I) {
3966
bool Optional = false;
3967
std::string Placeholder =
3968
formatTemplateParameterPlaceholder(Params[I], Optional, Policy);
3969
if (Optional)
3970
Current = &OptionalBuilder;
3971
if (I > 0)
3972
Current->AddChunk(CodeCompletionString::CK_Comma);
3973
Current->AddChunk(I == CurrentArg
3974
? CodeCompletionString::CK_CurrentParameter
3975
: CodeCompletionString::CK_Placeholder,
3976
Current->getAllocator().CopyString(Placeholder));
3977
}
3978
// Add the optional chunk to the main string if we ever used it.
3979
if (Current == &OptionalBuilder)
3980
Builder.AddOptionalChunk(OptionalBuilder.TakeString());
3981
Builder.AddChunk(CodeCompletionString::CK_RightAngle);
3982
// For function templates, ResultType was the function's return type.
3983
// Give some clue this is a function. (Don't show the possibly-bulky params).
3984
if (isa<FunctionTemplateDecl>(TD))
3985
Builder.AddInformativeChunk("()");
3986
return Builder.TakeString();
3987
}
3988
3989
CodeCompletionString *
3990
CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
3991
unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator,
3992
CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments,
3993
bool Braced) const {
3994
PrintingPolicy Policy = getCompletionPrintingPolicy(S);
3995
// Show signatures of constructors as they are declared:
3996
// vector(int n) rather than vector<string>(int n)
3997
// This is less noisy without being less clear, and avoids tricky cases.
3998
Policy.SuppressTemplateArgsInCXXConstructors = true;
3999
4000
// FIXME: Set priority, availability appropriately.
4001
CodeCompletionBuilder Result(Allocator, CCTUInfo, 1,
4002
CXAvailability_Available);
4003
4004
if (getKind() == CK_Template)
4005
return createTemplateSignatureString(getTemplate(), Result, CurrentArg,
4006
Policy);
4007
4008
FunctionDecl *FDecl = getFunction();
4009
const FunctionProtoType *Proto =
4010
dyn_cast_or_null<FunctionProtoType>(getFunctionType());
4011
4012
// First, the name/type of the callee.
4013
if (getKind() == CK_Aggregate) {
4014
Result.AddTextChunk(
4015
Result.getAllocator().CopyString(getAggregate()->getName()));
4016
} else if (FDecl) {
4017
if (IncludeBriefComments) {
4018
if (auto RC = getParameterComment(S.getASTContext(), *this, CurrentArg))
4019
Result.addBriefComment(RC->getBriefText(S.getASTContext()));
4020
}
4021
AddResultTypeChunk(S.Context, Policy, FDecl, QualType(), Result);
4022
4023
std::string Name;
4024
llvm::raw_string_ostream OS(Name);
4025
FDecl->getDeclName().print(OS, Policy);
4026
Result.AddTextChunk(Result.getAllocator().CopyString(Name));
4027
} else {
4028
// Function without a declaration. Just give the return type.
4029
Result.AddResultTypeChunk(Result.getAllocator().CopyString(
4030
getFunctionType()->getReturnType().getAsString(Policy)));
4031
}
4032
4033
// Next, the brackets and parameters.
4034
Result.AddChunk(Braced ? CodeCompletionString::CK_LeftBrace
4035
: CodeCompletionString::CK_LeftParen);
4036
if (getKind() == CK_Aggregate)
4037
AddOverloadAggregateChunks(getAggregate(), Policy, Result, CurrentArg);
4038
else
4039
AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto,
4040
getFunctionProtoTypeLoc(), Result, CurrentArg);
4041
Result.AddChunk(Braced ? CodeCompletionString::CK_RightBrace
4042
: CodeCompletionString::CK_RightParen);
4043
4044
return Result.TakeString();
4045
}
4046
4047
unsigned clang::getMacroUsagePriority(StringRef MacroName,
4048
const LangOptions &LangOpts,
4049
bool PreferredTypeIsPointer) {
4050
unsigned Priority = CCP_Macro;
4051
4052
// Treat the "nil", "Nil" and "NULL" macros as null pointer constants.
4053
if (MacroName == "nil" || MacroName == "NULL" || MacroName == "Nil") {
4054
Priority = CCP_Constant;
4055
if (PreferredTypeIsPointer)
4056
Priority = Priority / CCF_SimilarTypeMatch;
4057
}
4058
// Treat "YES", "NO", "true", and "false" as constants.
4059
else if (MacroName == "YES" || MacroName == "NO" || MacroName == "true" ||
4060
MacroName == "false")
4061
Priority = CCP_Constant;
4062
// Treat "bool" as a type.
4063
else if (MacroName == "bool")
4064
Priority = CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0);
4065
4066
return Priority;
4067
}
4068
4069
CXCursorKind clang::getCursorKindForDecl(const Decl *D) {
4070
if (!D)
4071
return CXCursor_UnexposedDecl;
4072
4073
switch (D->getKind()) {
4074
case Decl::Enum:
4075
return CXCursor_EnumDecl;
4076
case Decl::EnumConstant:
4077
return CXCursor_EnumConstantDecl;
4078
case Decl::Field:
4079
return CXCursor_FieldDecl;
4080
case Decl::Function:
4081
return CXCursor_FunctionDecl;
4082
case Decl::ObjCCategory:
4083
return CXCursor_ObjCCategoryDecl;
4084
case Decl::ObjCCategoryImpl:
4085
return CXCursor_ObjCCategoryImplDecl;
4086
case Decl::ObjCImplementation:
4087
return CXCursor_ObjCImplementationDecl;
4088
4089
case Decl::ObjCInterface:
4090
return CXCursor_ObjCInterfaceDecl;
4091
case Decl::ObjCIvar:
4092
return CXCursor_ObjCIvarDecl;
4093
case Decl::ObjCMethod:
4094
return cast<ObjCMethodDecl>(D)->isInstanceMethod()
4095
? CXCursor_ObjCInstanceMethodDecl
4096
: CXCursor_ObjCClassMethodDecl;
4097
case Decl::CXXMethod:
4098
return CXCursor_CXXMethod;
4099
case Decl::CXXConstructor:
4100
return CXCursor_Constructor;
4101
case Decl::CXXDestructor:
4102
return CXCursor_Destructor;
4103
case Decl::CXXConversion:
4104
return CXCursor_ConversionFunction;
4105
case Decl::ObjCProperty:
4106
return CXCursor_ObjCPropertyDecl;
4107
case Decl::ObjCProtocol:
4108
return CXCursor_ObjCProtocolDecl;
4109
case Decl::ParmVar:
4110
return CXCursor_ParmDecl;
4111
case Decl::Typedef:
4112
return CXCursor_TypedefDecl;
4113
case Decl::TypeAlias:
4114
return CXCursor_TypeAliasDecl;
4115
case Decl::TypeAliasTemplate:
4116
return CXCursor_TypeAliasTemplateDecl;
4117
case Decl::Var:
4118
return CXCursor_VarDecl;
4119
case Decl::Namespace:
4120
return CXCursor_Namespace;
4121
case Decl::NamespaceAlias:
4122
return CXCursor_NamespaceAlias;
4123
case Decl::TemplateTypeParm:
4124
return CXCursor_TemplateTypeParameter;
4125
case Decl::NonTypeTemplateParm:
4126
return CXCursor_NonTypeTemplateParameter;
4127
case Decl::TemplateTemplateParm:
4128
return CXCursor_TemplateTemplateParameter;
4129
case Decl::FunctionTemplate:
4130
return CXCursor_FunctionTemplate;
4131
case Decl::ClassTemplate:
4132
return CXCursor_ClassTemplate;
4133
case Decl::AccessSpec:
4134
return CXCursor_CXXAccessSpecifier;
4135
case Decl::ClassTemplatePartialSpecialization:
4136
return CXCursor_ClassTemplatePartialSpecialization;
4137
case Decl::UsingDirective:
4138
return CXCursor_UsingDirective;
4139
case Decl::StaticAssert:
4140
return CXCursor_StaticAssert;
4141
case Decl::Friend:
4142
return CXCursor_FriendDecl;
4143
case Decl::TranslationUnit:
4144
return CXCursor_TranslationUnit;
4145
4146
case Decl::Using:
4147
case Decl::UnresolvedUsingValue:
4148
case Decl::UnresolvedUsingTypename:
4149
return CXCursor_UsingDeclaration;
4150
4151
case Decl::UsingEnum:
4152
return CXCursor_EnumDecl;
4153
4154
case Decl::ObjCPropertyImpl:
4155
switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) {
4156
case ObjCPropertyImplDecl::Dynamic:
4157
return CXCursor_ObjCDynamicDecl;
4158
4159
case ObjCPropertyImplDecl::Synthesize:
4160
return CXCursor_ObjCSynthesizeDecl;
4161
}
4162
llvm_unreachable("Unexpected Kind!");
4163
4164
case Decl::Import:
4165
return CXCursor_ModuleImportDecl;
4166
4167
case Decl::ObjCTypeParam:
4168
return CXCursor_TemplateTypeParameter;
4169
4170
case Decl::Concept:
4171
return CXCursor_ConceptDecl;
4172
4173
case Decl::LinkageSpec:
4174
return CXCursor_LinkageSpec;
4175
4176
default:
4177
if (const auto *TD = dyn_cast<TagDecl>(D)) {
4178
switch (TD->getTagKind()) {
4179
case TagTypeKind::Interface: // fall through
4180
case TagTypeKind::Struct:
4181
return CXCursor_StructDecl;
4182
case TagTypeKind::Class:
4183
return CXCursor_ClassDecl;
4184
case TagTypeKind::Union:
4185
return CXCursor_UnionDecl;
4186
case TagTypeKind::Enum:
4187
return CXCursor_EnumDecl;
4188
}
4189
}
4190
}
4191
4192
return CXCursor_UnexposedDecl;
4193
}
4194
4195
static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
4196
bool LoadExternal, bool IncludeUndefined,
4197
bool TargetTypeIsPointer = false) {
4198
typedef CodeCompletionResult Result;
4199
4200
Results.EnterNewScope();
4201
4202
for (Preprocessor::macro_iterator M = PP.macro_begin(LoadExternal),
4203
MEnd = PP.macro_end(LoadExternal);
4204
M != MEnd; ++M) {
4205
auto MD = PP.getMacroDefinition(M->first);
4206
if (IncludeUndefined || MD) {
4207
MacroInfo *MI = MD.getMacroInfo();
4208
if (MI && MI->isUsedForHeaderGuard())
4209
continue;
4210
4211
Results.AddResult(
4212
Result(M->first, MI,
4213
getMacroUsagePriority(M->first->getName(), PP.getLangOpts(),
4214
TargetTypeIsPointer)));
4215
}
4216
}
4217
4218
Results.ExitScope();
4219
}
4220
4221
static void AddPrettyFunctionResults(const LangOptions &LangOpts,
4222
ResultBuilder &Results) {
4223
typedef CodeCompletionResult Result;
4224
4225
Results.EnterNewScope();
4226
4227
Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
4228
Results.AddResult(Result("__FUNCTION__", CCP_Constant));
4229
if (LangOpts.C99 || LangOpts.CPlusPlus11)
4230
Results.AddResult(Result("__func__", CCP_Constant));
4231
Results.ExitScope();
4232
}
4233
4234
static void HandleCodeCompleteResults(Sema *S,
4235
CodeCompleteConsumer *CodeCompleter,
4236
const CodeCompletionContext &Context,
4237
CodeCompletionResult *Results,
4238
unsigned NumResults) {
4239
if (CodeCompleter)
4240
CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
4241
}
4242
4243
static CodeCompletionContext
4244
mapCodeCompletionContext(Sema &S,
4245
SemaCodeCompletion::ParserCompletionContext PCC) {
4246
switch (PCC) {
4247
case SemaCodeCompletion::PCC_Namespace:
4248
return CodeCompletionContext::CCC_TopLevel;
4249
4250
case SemaCodeCompletion::PCC_Class:
4251
return CodeCompletionContext::CCC_ClassStructUnion;
4252
4253
case SemaCodeCompletion::PCC_ObjCInterface:
4254
return CodeCompletionContext::CCC_ObjCInterface;
4255
4256
case SemaCodeCompletion::PCC_ObjCImplementation:
4257
return CodeCompletionContext::CCC_ObjCImplementation;
4258
4259
case SemaCodeCompletion::PCC_ObjCInstanceVariableList:
4260
return CodeCompletionContext::CCC_ObjCIvarList;
4261
4262
case SemaCodeCompletion::PCC_Template:
4263
case SemaCodeCompletion::PCC_MemberTemplate:
4264
if (S.CurContext->isFileContext())
4265
return CodeCompletionContext::CCC_TopLevel;
4266
if (S.CurContext->isRecord())
4267
return CodeCompletionContext::CCC_ClassStructUnion;
4268
return CodeCompletionContext::CCC_Other;
4269
4270
case SemaCodeCompletion::PCC_RecoveryInFunction:
4271
return CodeCompletionContext::CCC_Recovery;
4272
4273
case SemaCodeCompletion::PCC_ForInit:
4274
if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 ||
4275
S.getLangOpts().ObjC)
4276
return CodeCompletionContext::CCC_ParenthesizedExpression;
4277
else
4278
return CodeCompletionContext::CCC_Expression;
4279
4280
case SemaCodeCompletion::PCC_Expression:
4281
return CodeCompletionContext::CCC_Expression;
4282
case SemaCodeCompletion::PCC_Condition:
4283
return CodeCompletionContext(CodeCompletionContext::CCC_Expression,
4284
S.getASTContext().BoolTy);
4285
4286
case SemaCodeCompletion::PCC_Statement:
4287
return CodeCompletionContext::CCC_Statement;
4288
4289
case SemaCodeCompletion::PCC_Type:
4290
return CodeCompletionContext::CCC_Type;
4291
4292
case SemaCodeCompletion::PCC_ParenthesizedExpression:
4293
return CodeCompletionContext::CCC_ParenthesizedExpression;
4294
4295
case SemaCodeCompletion::PCC_LocalDeclarationSpecifiers:
4296
return CodeCompletionContext::CCC_Type;
4297
case SemaCodeCompletion::PCC_TopLevelOrExpression:
4298
return CodeCompletionContext::CCC_TopLevelOrExpression;
4299
}
4300
4301
llvm_unreachable("Invalid ParserCompletionContext!");
4302
}
4303
4304
/// If we're in a C++ virtual member function, add completion results
4305
/// that invoke the functions we override, since it's common to invoke the
4306
/// overridden function as well as adding new functionality.
4307
///
4308
/// \param S The semantic analysis object for which we are generating results.
4309
///
4310
/// \param InContext This context in which the nested-name-specifier preceding
4311
/// the code-completion point
4312
static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
4313
ResultBuilder &Results) {
4314
// Look through blocks.
4315
DeclContext *CurContext = S.CurContext;
4316
while (isa<BlockDecl>(CurContext))
4317
CurContext = CurContext->getParent();
4318
4319
CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
4320
if (!Method || !Method->isVirtual())
4321
return;
4322
4323
// We need to have names for all of the parameters, if we're going to
4324
// generate a forwarding call.
4325
for (auto *P : Method->parameters())
4326
if (!P->getDeclName())
4327
return;
4328
4329
PrintingPolicy Policy = getCompletionPrintingPolicy(S);
4330
for (const CXXMethodDecl *Overridden : Method->overridden_methods()) {
4331
CodeCompletionBuilder Builder(Results.getAllocator(),
4332
Results.getCodeCompletionTUInfo());
4333
if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
4334
continue;
4335
4336
// If we need a nested-name-specifier, add one now.
4337
if (!InContext) {
4338
NestedNameSpecifier *NNS = getRequiredQualification(
4339
S.Context, CurContext, Overridden->getDeclContext());
4340
if (NNS) {
4341
std::string Str;
4342
llvm::raw_string_ostream OS(Str);
4343
NNS->print(OS, Policy);
4344
Builder.AddTextChunk(Results.getAllocator().CopyString(Str));
4345
}
4346
} else if (!InContext->Equals(Overridden->getDeclContext()))
4347
continue;
4348
4349
Builder.AddTypedTextChunk(
4350
Results.getAllocator().CopyString(Overridden->getNameAsString()));
4351
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4352
bool FirstParam = true;
4353
for (auto *P : Method->parameters()) {
4354
if (FirstParam)
4355
FirstParam = false;
4356
else
4357
Builder.AddChunk(CodeCompletionString::CK_Comma);
4358
4359
Builder.AddPlaceholderChunk(
4360
Results.getAllocator().CopyString(P->getIdentifier()->getName()));
4361
}
4362
Builder.AddChunk(CodeCompletionString::CK_RightParen);
4363
Results.AddResult(CodeCompletionResult(
4364
Builder.TakeString(), CCP_SuperCompletion, CXCursor_CXXMethod,
4365
CXAvailability_Available, Overridden));
4366
Results.Ignore(Overridden);
4367
}
4368
}
4369
4370
void SemaCodeCompletion::CodeCompleteModuleImport(SourceLocation ImportLoc,
4371
ModuleIdPath Path) {
4372
typedef CodeCompletionResult Result;
4373
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
4374
CodeCompleter->getCodeCompletionTUInfo(),
4375
CodeCompletionContext::CCC_Other);
4376
Results.EnterNewScope();
4377
4378
CodeCompletionAllocator &Allocator = Results.getAllocator();
4379
CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
4380
typedef CodeCompletionResult Result;
4381
if (Path.empty()) {
4382
// Enumerate all top-level modules.
4383
SmallVector<Module *, 8> Modules;
4384
SemaRef.PP.getHeaderSearchInfo().collectAllModules(Modules);
4385
for (unsigned I = 0, N = Modules.size(); I != N; ++I) {
4386
Builder.AddTypedTextChunk(
4387
Builder.getAllocator().CopyString(Modules[I]->Name));
4388
Results.AddResult(Result(
4389
Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl,
4390
Modules[I]->isAvailable() ? CXAvailability_Available
4391
: CXAvailability_NotAvailable));
4392
}
4393
} else if (getLangOpts().Modules) {
4394
// Load the named module.
4395
Module *Mod = SemaRef.PP.getModuleLoader().loadModule(
4396
ImportLoc, Path, Module::AllVisible,
4397
/*IsInclusionDirective=*/false);
4398
// Enumerate submodules.
4399
if (Mod) {
4400
for (auto *Submodule : Mod->submodules()) {
4401
Builder.AddTypedTextChunk(
4402
Builder.getAllocator().CopyString(Submodule->Name));
4403
Results.AddResult(Result(
4404
Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl,
4405
Submodule->isAvailable() ? CXAvailability_Available
4406
: CXAvailability_NotAvailable));
4407
}
4408
}
4409
}
4410
Results.ExitScope();
4411
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
4412
Results.getCompletionContext(), Results.data(),
4413
Results.size());
4414
}
4415
4416
void SemaCodeCompletion::CodeCompleteOrdinaryName(
4417
Scope *S, SemaCodeCompletion::ParserCompletionContext CompletionContext) {
4418
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
4419
CodeCompleter->getCodeCompletionTUInfo(),
4420
mapCodeCompletionContext(SemaRef, CompletionContext));
4421
Results.EnterNewScope();
4422
4423
// Determine how to filter results, e.g., so that the names of
4424
// values (functions, enumerators, function templates, etc.) are
4425
// only allowed where we can have an expression.
4426
switch (CompletionContext) {
4427
case PCC_Namespace:
4428
case PCC_Class:
4429
case PCC_ObjCInterface:
4430
case PCC_ObjCImplementation:
4431
case PCC_ObjCInstanceVariableList:
4432
case PCC_Template:
4433
case PCC_MemberTemplate:
4434
case PCC_Type:
4435
case PCC_LocalDeclarationSpecifiers:
4436
Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
4437
break;
4438
4439
case PCC_Statement:
4440
case PCC_TopLevelOrExpression:
4441
case PCC_ParenthesizedExpression:
4442
case PCC_Expression:
4443
case PCC_ForInit:
4444
case PCC_Condition:
4445
if (WantTypesInContext(CompletionContext, getLangOpts()))
4446
Results.setFilter(&ResultBuilder::IsOrdinaryName);
4447
else
4448
Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
4449
4450
if (getLangOpts().CPlusPlus)
4451
MaybeAddOverrideCalls(SemaRef, /*InContext=*/nullptr, Results);
4452
break;
4453
4454
case PCC_RecoveryInFunction:
4455
// Unfiltered
4456
break;
4457
}
4458
4459
// If we are in a C++ non-static member function, check the qualifiers on
4460
// the member function to filter/prioritize the results list.
4461
auto ThisType = SemaRef.getCurrentThisType();
4462
if (!ThisType.isNull())
4463
Results.setObjectTypeQualifiers(ThisType->getPointeeType().getQualifiers(),
4464
VK_LValue);
4465
4466
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
4467
SemaRef.LookupVisibleDecls(S, SemaRef.LookupOrdinaryName, Consumer,
4468
CodeCompleter->includeGlobals(),
4469
CodeCompleter->loadExternal());
4470
4471
AddOrdinaryNameResults(CompletionContext, S, SemaRef, Results);
4472
Results.ExitScope();
4473
4474
switch (CompletionContext) {
4475
case PCC_ParenthesizedExpression:
4476
case PCC_Expression:
4477
case PCC_Statement:
4478
case PCC_TopLevelOrExpression:
4479
case PCC_RecoveryInFunction:
4480
if (S->getFnParent())
4481
AddPrettyFunctionResults(getLangOpts(), Results);
4482
break;
4483
4484
case PCC_Namespace:
4485
case PCC_Class:
4486
case PCC_ObjCInterface:
4487
case PCC_ObjCImplementation:
4488
case PCC_ObjCInstanceVariableList:
4489
case PCC_Template:
4490
case PCC_MemberTemplate:
4491
case PCC_ForInit:
4492
case PCC_Condition:
4493
case PCC_Type:
4494
case PCC_LocalDeclarationSpecifiers:
4495
break;
4496
}
4497
4498
if (CodeCompleter->includeMacros())
4499
AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
4500
4501
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
4502
Results.getCompletionContext(), Results.data(),
4503
Results.size());
4504
}
4505
4506
static void
4507
AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver,
4508
ArrayRef<const IdentifierInfo *> SelIdents,
4509
bool AtArgumentExpression, bool IsSuper,
4510
ResultBuilder &Results);
4511
4512
void SemaCodeCompletion::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
4513
bool AllowNonIdentifiers,
4514
bool AllowNestedNameSpecifiers) {
4515
typedef CodeCompletionResult Result;
4516
ResultBuilder Results(
4517
SemaRef, CodeCompleter->getAllocator(),
4518
CodeCompleter->getCodeCompletionTUInfo(),
4519
AllowNestedNameSpecifiers
4520
// FIXME: Try to separate codepath leading here to deduce whether we
4521
// need an existing symbol or a new one.
4522
? CodeCompletionContext::CCC_SymbolOrNewName
4523
: CodeCompletionContext::CCC_NewName);
4524
Results.EnterNewScope();
4525
4526
// Type qualifiers can come after names.
4527
Results.AddResult(Result("const"));
4528
Results.AddResult(Result("volatile"));
4529
if (getLangOpts().C99)
4530
Results.AddResult(Result("restrict"));
4531
4532
if (getLangOpts().CPlusPlus) {
4533
if (getLangOpts().CPlusPlus11 &&
4534
(DS.getTypeSpecType() == DeclSpec::TST_class ||
4535
DS.getTypeSpecType() == DeclSpec::TST_struct))
4536
Results.AddResult("final");
4537
4538
if (AllowNonIdentifiers) {
4539
Results.AddResult(Result("operator"));
4540
}
4541
4542
// Add nested-name-specifiers.
4543
if (AllowNestedNameSpecifiers) {
4544
Results.allowNestedNameSpecifiers();
4545
Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy);
4546
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
4547
SemaRef.LookupVisibleDecls(S, Sema::LookupNestedNameSpecifierName,
4548
Consumer, CodeCompleter->includeGlobals(),
4549
CodeCompleter->loadExternal());
4550
Results.setFilter(nullptr);
4551
}
4552
}
4553
Results.ExitScope();
4554
4555
// If we're in a context where we might have an expression (rather than a
4556
// declaration), and what we've seen so far is an Objective-C type that could
4557
// be a receiver of a class message, this may be a class message send with
4558
// the initial opening bracket '[' missing. Add appropriate completions.
4559
if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
4560
DS.getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier &&
4561
DS.getTypeSpecType() == DeclSpec::TST_typename &&
4562
DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
4563
DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified &&
4564
!DS.isTypeAltiVecVector() && S &&
4565
(S->getFlags() & Scope::DeclScope) != 0 &&
4566
(S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
4567
Scope::FunctionPrototypeScope | Scope::AtCatchScope)) ==
4568
0) {
4569
ParsedType T = DS.getRepAsType();
4570
if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType())
4571
AddClassMessageCompletions(SemaRef, S, T, std::nullopt, false, false,
4572
Results);
4573
}
4574
4575
// Note that we intentionally suppress macro results here, since we do not
4576
// encourage using macros to produce the names of entities.
4577
4578
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
4579
Results.getCompletionContext(), Results.data(),
4580
Results.size());
4581
}
4582
4583
static const char *underscoreAttrScope(llvm::StringRef Scope) {
4584
if (Scope == "clang")
4585
return "_Clang";
4586
if (Scope == "gnu")
4587
return "__gnu__";
4588
return nullptr;
4589
}
4590
4591
static const char *noUnderscoreAttrScope(llvm::StringRef Scope) {
4592
if (Scope == "_Clang")
4593
return "clang";
4594
if (Scope == "__gnu__")
4595
return "gnu";
4596
return nullptr;
4597
}
4598
4599
void SemaCodeCompletion::CodeCompleteAttribute(
4600
AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion,
4601
const IdentifierInfo *InScope) {
4602
if (Completion == AttributeCompletion::None)
4603
return;
4604
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
4605
CodeCompleter->getCodeCompletionTUInfo(),
4606
CodeCompletionContext::CCC_Attribute);
4607
4608
// We're going to iterate over the normalized spellings of the attribute.
4609
// These don't include "underscore guarding": the normalized spelling is
4610
// clang::foo but you can also write _Clang::__foo__.
4611
//
4612
// (Clang supports a mix like clang::__foo__ but we won't suggest it: either
4613
// you care about clashing with macros or you don't).
4614
//
4615
// So if we're already in a scope, we determine its canonical spellings
4616
// (for comparison with normalized attr spelling) and remember whether it was
4617
// underscore-guarded (so we know how to spell contained attributes).
4618
llvm::StringRef InScopeName;
4619
bool InScopeUnderscore = false;
4620
if (InScope) {
4621
InScopeName = InScope->getName();
4622
if (const char *NoUnderscore = noUnderscoreAttrScope(InScopeName)) {
4623
InScopeName = NoUnderscore;
4624
InScopeUnderscore = true;
4625
}
4626
}
4627
bool SyntaxSupportsGuards = Syntax == AttributeCommonInfo::AS_GNU ||
4628
Syntax == AttributeCommonInfo::AS_CXX11 ||
4629
Syntax == AttributeCommonInfo::AS_C23;
4630
4631
llvm::DenseSet<llvm::StringRef> FoundScopes;
4632
auto AddCompletions = [&](const ParsedAttrInfo &A) {
4633
if (A.IsTargetSpecific &&
4634
!A.existsInTarget(getASTContext().getTargetInfo()))
4635
return;
4636
if (!A.acceptsLangOpts(getLangOpts()))
4637
return;
4638
for (const auto &S : A.Spellings) {
4639
if (S.Syntax != Syntax)
4640
continue;
4641
llvm::StringRef Name = S.NormalizedFullName;
4642
llvm::StringRef Scope;
4643
if ((Syntax == AttributeCommonInfo::AS_CXX11 ||
4644
Syntax == AttributeCommonInfo::AS_C23)) {
4645
std::tie(Scope, Name) = Name.split("::");
4646
if (Name.empty()) // oops, unscoped
4647
std::swap(Name, Scope);
4648
}
4649
4650
// Do we just want a list of scopes rather than attributes?
4651
if (Completion == AttributeCompletion::Scope) {
4652
// Make sure to emit each scope only once.
4653
if (!Scope.empty() && FoundScopes.insert(Scope).second) {
4654
Results.AddResult(
4655
CodeCompletionResult(Results.getAllocator().CopyString(Scope)));
4656
// Include alternate form (__gnu__ instead of gnu).
4657
if (const char *Scope2 = underscoreAttrScope(Scope))
4658
Results.AddResult(CodeCompletionResult(Scope2));
4659
}
4660
continue;
4661
}
4662
4663
// If a scope was specified, it must match but we don't need to print it.
4664
if (!InScopeName.empty()) {
4665
if (Scope != InScopeName)
4666
continue;
4667
Scope = "";
4668
}
4669
4670
auto Add = [&](llvm::StringRef Scope, llvm::StringRef Name,
4671
bool Underscores) {
4672
CodeCompletionBuilder Builder(Results.getAllocator(),
4673
Results.getCodeCompletionTUInfo());
4674
llvm::SmallString<32> Text;
4675
if (!Scope.empty()) {
4676
Text.append(Scope);
4677
Text.append("::");
4678
}
4679
if (Underscores)
4680
Text.append("__");
4681
Text.append(Name);
4682
if (Underscores)
4683
Text.append("__");
4684
Builder.AddTypedTextChunk(Results.getAllocator().CopyString(Text));
4685
4686
if (!A.ArgNames.empty()) {
4687
Builder.AddChunk(CodeCompletionString::CK_LeftParen, "(");
4688
bool First = true;
4689
for (const char *Arg : A.ArgNames) {
4690
if (!First)
4691
Builder.AddChunk(CodeCompletionString::CK_Comma, ", ");
4692
First = false;
4693
Builder.AddPlaceholderChunk(Arg);
4694
}
4695
Builder.AddChunk(CodeCompletionString::CK_RightParen, ")");
4696
}
4697
4698
Results.AddResult(Builder.TakeString());
4699
};
4700
4701
// Generate the non-underscore-guarded result.
4702
// Note this is (a suffix of) the NormalizedFullName, no need to copy.
4703
// If an underscore-guarded scope was specified, only the
4704
// underscore-guarded attribute name is relevant.
4705
if (!InScopeUnderscore)
4706
Add(Scope, Name, /*Underscores=*/false);
4707
4708
// Generate the underscore-guarded version, for syntaxes that support it.
4709
// We skip this if the scope was already spelled and not guarded, or
4710
// we must spell it and can't guard it.
4711
if (!(InScope && !InScopeUnderscore) && SyntaxSupportsGuards) {
4712
llvm::SmallString<32> Guarded;
4713
if (Scope.empty()) {
4714
Add(Scope, Name, /*Underscores=*/true);
4715
} else {
4716
const char *GuardedScope = underscoreAttrScope(Scope);
4717
if (!GuardedScope)
4718
continue;
4719
Add(GuardedScope, Name, /*Underscores=*/true);
4720
}
4721
}
4722
4723
// It may be nice to include the Kind so we can look up the docs later.
4724
}
4725
};
4726
4727
for (const auto *A : ParsedAttrInfo::getAllBuiltin())
4728
AddCompletions(*A);
4729
for (const auto &Entry : ParsedAttrInfoRegistry::entries())
4730
AddCompletions(*Entry.instantiate());
4731
4732
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
4733
Results.getCompletionContext(), Results.data(),
4734
Results.size());
4735
}
4736
4737
struct SemaCodeCompletion::CodeCompleteExpressionData {
4738
CodeCompleteExpressionData(QualType PreferredType = QualType(),
4739
bool IsParenthesized = false)
4740
: PreferredType(PreferredType), IntegralConstantExpression(false),
4741
ObjCCollection(false), IsParenthesized(IsParenthesized) {}
4742
4743
QualType PreferredType;
4744
bool IntegralConstantExpression;
4745
bool ObjCCollection;
4746
bool IsParenthesized;
4747
SmallVector<Decl *, 4> IgnoreDecls;
4748
};
4749
4750
namespace {
4751
/// Information that allows to avoid completing redundant enumerators.
4752
struct CoveredEnumerators {
4753
llvm::SmallPtrSet<EnumConstantDecl *, 8> Seen;
4754
NestedNameSpecifier *SuggestedQualifier = nullptr;
4755
};
4756
} // namespace
4757
4758
static void AddEnumerators(ResultBuilder &Results, ASTContext &Context,
4759
EnumDecl *Enum, DeclContext *CurContext,
4760
const CoveredEnumerators &Enumerators) {
4761
NestedNameSpecifier *Qualifier = Enumerators.SuggestedQualifier;
4762
if (Context.getLangOpts().CPlusPlus && !Qualifier && Enumerators.Seen.empty()) {
4763
// If there are no prior enumerators in C++, check whether we have to
4764
// qualify the names of the enumerators that we suggest, because they
4765
// may not be visible in this scope.
4766
Qualifier = getRequiredQualification(Context, CurContext, Enum);
4767
}
4768
4769
Results.EnterNewScope();
4770
for (auto *E : Enum->enumerators()) {
4771
if (Enumerators.Seen.count(E))
4772
continue;
4773
4774
CodeCompletionResult R(E, CCP_EnumInCase, Qualifier);
4775
Results.AddResult(R, CurContext, nullptr, false);
4776
}
4777
Results.ExitScope();
4778
}
4779
4780
/// Try to find a corresponding FunctionProtoType for function-like types (e.g.
4781
/// function pointers, std::function, etc).
4782
static const FunctionProtoType *TryDeconstructFunctionLike(QualType T) {
4783
assert(!T.isNull());
4784
// Try to extract first template argument from std::function<> and similar.
4785
// Note we only handle the sugared types, they closely match what users wrote.
4786
// We explicitly choose to not handle ClassTemplateSpecializationDecl.
4787
if (auto *Specialization = T->getAs<TemplateSpecializationType>()) {
4788
if (Specialization->template_arguments().size() != 1)
4789
return nullptr;
4790
const TemplateArgument &Argument = Specialization->template_arguments()[0];
4791
if (Argument.getKind() != TemplateArgument::Type)
4792
return nullptr;
4793
return Argument.getAsType()->getAs<FunctionProtoType>();
4794
}
4795
// Handle other cases.
4796
if (T->isPointerType())
4797
T = T->getPointeeType();
4798
return T->getAs<FunctionProtoType>();
4799
}
4800
4801
/// Adds a pattern completion for a lambda expression with the specified
4802
/// parameter types and placeholders for parameter names.
4803
static void AddLambdaCompletion(ResultBuilder &Results,
4804
llvm::ArrayRef<QualType> Parameters,
4805
const LangOptions &LangOpts) {
4806
if (!Results.includeCodePatterns())
4807
return;
4808
CodeCompletionBuilder Completion(Results.getAllocator(),
4809
Results.getCodeCompletionTUInfo());
4810
// [](<parameters>) {}
4811
Completion.AddChunk(CodeCompletionString::CK_LeftBracket);
4812
Completion.AddPlaceholderChunk("=");
4813
Completion.AddChunk(CodeCompletionString::CK_RightBracket);
4814
if (!Parameters.empty()) {
4815
Completion.AddChunk(CodeCompletionString::CK_LeftParen);
4816
bool First = true;
4817
for (auto Parameter : Parameters) {
4818
if (!First)
4819
Completion.AddChunk(CodeCompletionString::ChunkKind::CK_Comma);
4820
else
4821
First = false;
4822
4823
constexpr llvm::StringLiteral NamePlaceholder = "!#!NAME_GOES_HERE!#!";
4824
std::string Type = std::string(NamePlaceholder);
4825
Parameter.getAsStringInternal(Type, PrintingPolicy(LangOpts));
4826
llvm::StringRef Prefix, Suffix;
4827
std::tie(Prefix, Suffix) = llvm::StringRef(Type).split(NamePlaceholder);
4828
Prefix = Prefix.rtrim();
4829
Suffix = Suffix.ltrim();
4830
4831
Completion.AddTextChunk(Completion.getAllocator().CopyString(Prefix));
4832
Completion.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4833
Completion.AddPlaceholderChunk("parameter");
4834
Completion.AddTextChunk(Completion.getAllocator().CopyString(Suffix));
4835
};
4836
Completion.AddChunk(CodeCompletionString::CK_RightParen);
4837
}
4838
Completion.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace);
4839
Completion.AddChunk(CodeCompletionString::CK_LeftBrace);
4840
Completion.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4841
Completion.AddPlaceholderChunk("body");
4842
Completion.AddChunk(CodeCompletionString::CK_HorizontalSpace);
4843
Completion.AddChunk(CodeCompletionString::CK_RightBrace);
4844
4845
Results.AddResult(Completion.TakeString());
4846
}
4847
4848
/// Perform code-completion in an expression context when we know what
4849
/// type we're looking for.
4850
void SemaCodeCompletion::CodeCompleteExpression(
4851
Scope *S, const CodeCompleteExpressionData &Data) {
4852
ResultBuilder Results(
4853
SemaRef, CodeCompleter->getAllocator(),
4854
CodeCompleter->getCodeCompletionTUInfo(),
4855
CodeCompletionContext(
4856
Data.IsParenthesized
4857
? CodeCompletionContext::CCC_ParenthesizedExpression
4858
: CodeCompletionContext::CCC_Expression,
4859
Data.PreferredType));
4860
auto PCC =
4861
Data.IsParenthesized ? PCC_ParenthesizedExpression : PCC_Expression;
4862
if (Data.ObjCCollection)
4863
Results.setFilter(&ResultBuilder::IsObjCCollection);
4864
else if (Data.IntegralConstantExpression)
4865
Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
4866
else if (WantTypesInContext(PCC, getLangOpts()))
4867
Results.setFilter(&ResultBuilder::IsOrdinaryName);
4868
else
4869
Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
4870
4871
if (!Data.PreferredType.isNull())
4872
Results.setPreferredType(Data.PreferredType.getNonReferenceType());
4873
4874
// Ignore any declarations that we were told that we don't care about.
4875
for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
4876
Results.Ignore(Data.IgnoreDecls[I]);
4877
4878
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
4879
SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
4880
CodeCompleter->includeGlobals(),
4881
CodeCompleter->loadExternal());
4882
4883
Results.EnterNewScope();
4884
AddOrdinaryNameResults(PCC, S, SemaRef, Results);
4885
Results.ExitScope();
4886
4887
bool PreferredTypeIsPointer = false;
4888
if (!Data.PreferredType.isNull()) {
4889
PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType() ||
4890
Data.PreferredType->isMemberPointerType() ||
4891
Data.PreferredType->isBlockPointerType();
4892
if (Data.PreferredType->isEnumeralType()) {
4893
EnumDecl *Enum = Data.PreferredType->castAs<EnumType>()->getDecl();
4894
if (auto *Def = Enum->getDefinition())
4895
Enum = Def;
4896
// FIXME: collect covered enumerators in cases like:
4897
// if (x == my_enum::one) { ... } else if (x == ^) {}
4898
AddEnumerators(Results, getASTContext(), Enum, SemaRef.CurContext,
4899
CoveredEnumerators());
4900
}
4901
}
4902
4903
if (S->getFnParent() && !Data.ObjCCollection &&
4904
!Data.IntegralConstantExpression)
4905
AddPrettyFunctionResults(getLangOpts(), Results);
4906
4907
if (CodeCompleter->includeMacros())
4908
AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false,
4909
PreferredTypeIsPointer);
4910
4911
// Complete a lambda expression when preferred type is a function.
4912
if (!Data.PreferredType.isNull() && getLangOpts().CPlusPlus11) {
4913
if (const FunctionProtoType *F =
4914
TryDeconstructFunctionLike(Data.PreferredType))
4915
AddLambdaCompletion(Results, F->getParamTypes(), getLangOpts());
4916
}
4917
4918
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
4919
Results.getCompletionContext(), Results.data(),
4920
Results.size());
4921
}
4922
4923
void SemaCodeCompletion::CodeCompleteExpression(Scope *S,
4924
QualType PreferredType,
4925
bool IsParenthesized) {
4926
return CodeCompleteExpression(
4927
S, CodeCompleteExpressionData(PreferredType, IsParenthesized));
4928
}
4929
4930
void SemaCodeCompletion::CodeCompletePostfixExpression(Scope *S, ExprResult E,
4931
QualType PreferredType) {
4932
if (E.isInvalid())
4933
CodeCompleteExpression(S, PreferredType);
4934
else if (getLangOpts().ObjC)
4935
CodeCompleteObjCInstanceMessage(S, E.get(), std::nullopt, false);
4936
}
4937
4938
/// The set of properties that have already been added, referenced by
4939
/// property name.
4940
typedef llvm::SmallPtrSet<const IdentifierInfo *, 16> AddedPropertiesSet;
4941
4942
/// Retrieve the container definition, if any?
4943
static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) {
4944
if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
4945
if (Interface->hasDefinition())
4946
return Interface->getDefinition();
4947
4948
return Interface;
4949
}
4950
4951
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4952
if (Protocol->hasDefinition())
4953
return Protocol->getDefinition();
4954
4955
return Protocol;
4956
}
4957
return Container;
4958
}
4959
4960
/// Adds a block invocation code completion result for the given block
4961
/// declaration \p BD.
4962
static void AddObjCBlockCall(ASTContext &Context, const PrintingPolicy &Policy,
4963
CodeCompletionBuilder &Builder,
4964
const NamedDecl *BD,
4965
const FunctionTypeLoc &BlockLoc,
4966
const FunctionProtoTypeLoc &BlockProtoLoc) {
4967
Builder.AddResultTypeChunk(
4968
GetCompletionTypeString(BlockLoc.getReturnLoc().getType(), Context,
4969
Policy, Builder.getAllocator()));
4970
4971
AddTypedNameChunk(Context, Policy, BD, Builder);
4972
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
4973
4974
if (BlockProtoLoc && BlockProtoLoc.getTypePtr()->isVariadic()) {
4975
Builder.AddPlaceholderChunk("...");
4976
} else {
4977
for (unsigned I = 0, N = BlockLoc.getNumParams(); I != N; ++I) {
4978
if (I)
4979
Builder.AddChunk(CodeCompletionString::CK_Comma);
4980
4981
// Format the placeholder string.
4982
std::string PlaceholderStr =
4983
FormatFunctionParameter(Policy, BlockLoc.getParam(I));
4984
4985
if (I == N - 1 && BlockProtoLoc &&
4986
BlockProtoLoc.getTypePtr()->isVariadic())
4987
PlaceholderStr += ", ...";
4988
4989
// Add the placeholder string.
4990
Builder.AddPlaceholderChunk(
4991
Builder.getAllocator().CopyString(PlaceholderStr));
4992
}
4993
}
4994
4995
Builder.AddChunk(CodeCompletionString::CK_RightParen);
4996
}
4997
4998
static void
4999
AddObjCProperties(const CodeCompletionContext &CCContext,
5000
ObjCContainerDecl *Container, bool AllowCategories,
5001
bool AllowNullaryMethods, DeclContext *CurContext,
5002
AddedPropertiesSet &AddedProperties, ResultBuilder &Results,
5003
bool IsBaseExprStatement = false,
5004
bool IsClassProperty = false, bool InOriginalClass = true) {
5005
typedef CodeCompletionResult Result;
5006
5007
// Retrieve the definition.
5008
Container = getContainerDef(Container);
5009
5010
// Add properties in this container.
5011
const auto AddProperty = [&](const ObjCPropertyDecl *P) {
5012
if (!AddedProperties.insert(P->getIdentifier()).second)
5013
return;
5014
5015
// FIXME: Provide block invocation completion for non-statement
5016
// expressions.
5017
if (!P->getType().getTypePtr()->isBlockPointerType() ||
5018
!IsBaseExprStatement) {
5019
Result R = Result(P, Results.getBasePriority(P), nullptr);
5020
if (!InOriginalClass)
5021
setInBaseClass(R);
5022
Results.MaybeAddResult(R, CurContext);
5023
return;
5024
}
5025
5026
// Block setter and invocation completion is provided only when we are able
5027
// to find the FunctionProtoTypeLoc with parameter names for the block.
5028
FunctionTypeLoc BlockLoc;
5029
FunctionProtoTypeLoc BlockProtoLoc;
5030
findTypeLocationForBlockDecl(P->getTypeSourceInfo(), BlockLoc,
5031
BlockProtoLoc);
5032
if (!BlockLoc) {
5033
Result R = Result(P, Results.getBasePriority(P), nullptr);
5034
if (!InOriginalClass)
5035
setInBaseClass(R);
5036
Results.MaybeAddResult(R, CurContext);
5037
return;
5038
}
5039
5040
// The default completion result for block properties should be the block
5041
// invocation completion when the base expression is a statement.
5042
CodeCompletionBuilder Builder(Results.getAllocator(),
5043
Results.getCodeCompletionTUInfo());
5044
AddObjCBlockCall(Container->getASTContext(),
5045
getCompletionPrintingPolicy(Results.getSema()), Builder, P,
5046
BlockLoc, BlockProtoLoc);
5047
Result R = Result(Builder.TakeString(), P, Results.getBasePriority(P));
5048
if (!InOriginalClass)
5049
setInBaseClass(R);
5050
Results.MaybeAddResult(R, CurContext);
5051
5052
// Provide additional block setter completion iff the base expression is a
5053
// statement and the block property is mutable.
5054
if (!P->isReadOnly()) {
5055
CodeCompletionBuilder Builder(Results.getAllocator(),
5056
Results.getCodeCompletionTUInfo());
5057
AddResultTypeChunk(Container->getASTContext(),
5058
getCompletionPrintingPolicy(Results.getSema()), P,
5059
CCContext.getBaseType(), Builder);
5060
Builder.AddTypedTextChunk(
5061
Results.getAllocator().CopyString(P->getName()));
5062
Builder.AddChunk(CodeCompletionString::CK_Equal);
5063
5064
std::string PlaceholderStr = formatBlockPlaceholder(
5065
getCompletionPrintingPolicy(Results.getSema()), P, BlockLoc,
5066
BlockProtoLoc, /*SuppressBlockName=*/true);
5067
// Add the placeholder string.
5068
Builder.AddPlaceholderChunk(
5069
Builder.getAllocator().CopyString(PlaceholderStr));
5070
5071
// When completing blocks properties that return void the default
5072
// property completion result should show up before the setter,
5073
// otherwise the setter completion should show up before the default
5074
// property completion, as we normally want to use the result of the
5075
// call.
5076
Result R =
5077
Result(Builder.TakeString(), P,
5078
Results.getBasePriority(P) +
5079
(BlockLoc.getTypePtr()->getReturnType()->isVoidType()
5080
? CCD_BlockPropertySetter
5081
: -CCD_BlockPropertySetter));
5082
if (!InOriginalClass)
5083
setInBaseClass(R);
5084
Results.MaybeAddResult(R, CurContext);
5085
}
5086
};
5087
5088
if (IsClassProperty) {
5089
for (const auto *P : Container->class_properties())
5090
AddProperty(P);
5091
} else {
5092
for (const auto *P : Container->instance_properties())
5093
AddProperty(P);
5094
}
5095
5096
// Add nullary methods or implicit class properties
5097
if (AllowNullaryMethods) {
5098
ASTContext &Context = Container->getASTContext();
5099
PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
5100
// Adds a method result
5101
const auto AddMethod = [&](const ObjCMethodDecl *M) {
5102
const IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0);
5103
if (!Name)
5104
return;
5105
if (!AddedProperties.insert(Name).second)
5106
return;
5107
CodeCompletionBuilder Builder(Results.getAllocator(),
5108
Results.getCodeCompletionTUInfo());
5109
AddResultTypeChunk(Context, Policy, M, CCContext.getBaseType(), Builder);
5110
Builder.AddTypedTextChunk(
5111
Results.getAllocator().CopyString(Name->getName()));
5112
Result R = Result(Builder.TakeString(), M,
5113
CCP_MemberDeclaration + CCD_MethodAsProperty);
5114
if (!InOriginalClass)
5115
setInBaseClass(R);
5116
Results.MaybeAddResult(R, CurContext);
5117
};
5118
5119
if (IsClassProperty) {
5120
for (const auto *M : Container->methods()) {
5121
// Gather the class method that can be used as implicit property
5122
// getters. Methods with arguments or methods that return void aren't
5123
// added to the results as they can't be used as a getter.
5124
if (!M->getSelector().isUnarySelector() ||
5125
M->getReturnType()->isVoidType() || M->isInstanceMethod())
5126
continue;
5127
AddMethod(M);
5128
}
5129
} else {
5130
for (auto *M : Container->methods()) {
5131
if (M->getSelector().isUnarySelector())
5132
AddMethod(M);
5133
}
5134
}
5135
}
5136
5137
// Add properties in referenced protocols.
5138
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5139
for (auto *P : Protocol->protocols())
5140
AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods,
5141
CurContext, AddedProperties, Results,
5142
IsBaseExprStatement, IsClassProperty,
5143
/*InOriginalClass*/ false);
5144
} else if (ObjCInterfaceDecl *IFace =
5145
dyn_cast<ObjCInterfaceDecl>(Container)) {
5146
if (AllowCategories) {
5147
// Look through categories.
5148
for (auto *Cat : IFace->known_categories())
5149
AddObjCProperties(CCContext, Cat, AllowCategories, AllowNullaryMethods,
5150
CurContext, AddedProperties, Results,
5151
IsBaseExprStatement, IsClassProperty,
5152
InOriginalClass);
5153
}
5154
5155
// Look through protocols.
5156
for (auto *I : IFace->all_referenced_protocols())
5157
AddObjCProperties(CCContext, I, AllowCategories, AllowNullaryMethods,
5158
CurContext, AddedProperties, Results,
5159
IsBaseExprStatement, IsClassProperty,
5160
/*InOriginalClass*/ false);
5161
5162
// Look in the superclass.
5163
if (IFace->getSuperClass())
5164
AddObjCProperties(CCContext, IFace->getSuperClass(), AllowCategories,
5165
AllowNullaryMethods, CurContext, AddedProperties,
5166
Results, IsBaseExprStatement, IsClassProperty,
5167
/*InOriginalClass*/ false);
5168
} else if (const auto *Category =
5169
dyn_cast<ObjCCategoryDecl>(Container)) {
5170
// Look through protocols.
5171
for (auto *P : Category->protocols())
5172
AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods,
5173
CurContext, AddedProperties, Results,
5174
IsBaseExprStatement, IsClassProperty,
5175
/*InOriginalClass*/ false);
5176
}
5177
}
5178
5179
static void
5180
AddRecordMembersCompletionResults(Sema &SemaRef, ResultBuilder &Results,
5181
Scope *S, QualType BaseType,
5182
ExprValueKind BaseKind, RecordDecl *RD,
5183
std::optional<FixItHint> AccessOpFixIt) {
5184
// Indicate that we are performing a member access, and the cv-qualifiers
5185
// for the base object type.
5186
Results.setObjectTypeQualifiers(BaseType.getQualifiers(), BaseKind);
5187
5188
// Access to a C/C++ class, struct, or union.
5189
Results.allowNestedNameSpecifiers();
5190
std::vector<FixItHint> FixIts;
5191
if (AccessOpFixIt)
5192
FixIts.emplace_back(*AccessOpFixIt);
5193
CodeCompletionDeclConsumer Consumer(Results, RD, BaseType, std::move(FixIts));
5194
SemaRef.LookupVisibleDecls(
5195
RD, Sema::LookupMemberName, Consumer,
5196
SemaRef.CodeCompletion().CodeCompleter->includeGlobals(),
5197
/*IncludeDependentBases=*/true,
5198
SemaRef.CodeCompletion().CodeCompleter->loadExternal());
5199
5200
if (SemaRef.getLangOpts().CPlusPlus) {
5201
if (!Results.empty()) {
5202
// The "template" keyword can follow "->" or "." in the grammar.
5203
// However, we only want to suggest the template keyword if something
5204
// is dependent.
5205
bool IsDependent = BaseType->isDependentType();
5206
if (!IsDependent) {
5207
for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
5208
if (DeclContext *Ctx = DepScope->getEntity()) {
5209
IsDependent = Ctx->isDependentContext();
5210
break;
5211
}
5212
}
5213
5214
if (IsDependent)
5215
Results.AddResult(CodeCompletionResult("template"));
5216
}
5217
}
5218
}
5219
5220
// Returns the RecordDecl inside the BaseType, falling back to primary template
5221
// in case of specializations. Since we might not have a decl for the
5222
// instantiation/specialization yet, e.g. dependent code.
5223
static RecordDecl *getAsRecordDecl(QualType BaseType) {
5224
BaseType = BaseType.getNonReferenceType();
5225
if (auto *RD = BaseType->getAsRecordDecl()) {
5226
if (const auto *CTSD =
5227
llvm::dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
5228
// Template might not be instantiated yet, fall back to primary template
5229
// in such cases.
5230
if (CTSD->getTemplateSpecializationKind() == TSK_Undeclared)
5231
RD = CTSD->getSpecializedTemplate()->getTemplatedDecl();
5232
}
5233
return RD;
5234
}
5235
5236
if (const auto *TST = BaseType->getAs<TemplateSpecializationType>()) {
5237
if (const auto *TD = dyn_cast_or_null<ClassTemplateDecl>(
5238
TST->getTemplateName().getAsTemplateDecl())) {
5239
return TD->getTemplatedDecl();
5240
}
5241
}
5242
5243
return nullptr;
5244
}
5245
5246
namespace {
5247
// Collects completion-relevant information about a concept-constrainted type T.
5248
// In particular, examines the constraint expressions to find members of T.
5249
//
5250
// The design is very simple: we walk down each constraint looking for
5251
// expressions of the form T.foo().
5252
// If we're extra lucky, the return type is specified.
5253
// We don't do any clever handling of && or || in constraint expressions, we
5254
// take members from both branches.
5255
//
5256
// For example, given:
5257
// template <class T> concept X = requires (T t, string& s) { t.print(s); };
5258
// template <X U> void foo(U u) { u.^ }
5259
// We want to suggest the inferred member function 'print(string)'.
5260
// We see that u has type U, so X<U> holds.
5261
// X<U> requires t.print(s) to be valid, where t has type U (substituted for T).
5262
// By looking at the CallExpr we find the signature of print().
5263
//
5264
// While we tend to know in advance which kind of members (access via . -> ::)
5265
// we want, it's simpler just to gather them all and post-filter.
5266
//
5267
// FIXME: some of this machinery could be used for non-concept type-parms too,
5268
// enabling completion for type parameters based on other uses of that param.
5269
//
5270
// FIXME: there are other cases where a type can be constrained by a concept,
5271
// e.g. inside `if constexpr(ConceptSpecializationExpr) { ... }`
5272
class ConceptInfo {
5273
public:
5274
// Describes a likely member of a type, inferred by concept constraints.
5275
// Offered as a code completion for T. T-> and T:: contexts.
5276
struct Member {
5277
// Always non-null: we only handle members with ordinary identifier names.
5278
const IdentifierInfo *Name = nullptr;
5279
// Set for functions we've seen called.
5280
// We don't have the declared parameter types, only the actual types of
5281
// arguments we've seen. These are still valuable, as it's hard to render
5282
// a useful function completion with neither parameter types nor names!
5283
std::optional<SmallVector<QualType, 1>> ArgTypes;
5284
// Whether this is accessed as T.member, T->member, or T::member.
5285
enum AccessOperator {
5286
Colons,
5287
Arrow,
5288
Dot,
5289
} Operator = Dot;
5290
// What's known about the type of a variable or return type of a function.
5291
const TypeConstraint *ResultType = nullptr;
5292
// FIXME: also track:
5293
// - kind of entity (function/variable/type), to expose structured results
5294
// - template args kinds/types, as a proxy for template params
5295
5296
// For now we simply return these results as "pattern" strings.
5297
CodeCompletionString *render(Sema &S, CodeCompletionAllocator &Alloc,
5298
CodeCompletionTUInfo &Info) const {
5299
CodeCompletionBuilder B(Alloc, Info);
5300
// Result type
5301
if (ResultType) {
5302
std::string AsString;
5303
{
5304
llvm::raw_string_ostream OS(AsString);
5305
QualType ExactType = deduceType(*ResultType);
5306
if (!ExactType.isNull())
5307
ExactType.print(OS, getCompletionPrintingPolicy(S));
5308
else
5309
ResultType->print(OS, getCompletionPrintingPolicy(S));
5310
}
5311
B.AddResultTypeChunk(Alloc.CopyString(AsString));
5312
}
5313
// Member name
5314
B.AddTypedTextChunk(Alloc.CopyString(Name->getName()));
5315
// Function argument list
5316
if (ArgTypes) {
5317
B.AddChunk(clang::CodeCompletionString::CK_LeftParen);
5318
bool First = true;
5319
for (QualType Arg : *ArgTypes) {
5320
if (First)
5321
First = false;
5322
else {
5323
B.AddChunk(clang::CodeCompletionString::CK_Comma);
5324
B.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace);
5325
}
5326
B.AddPlaceholderChunk(Alloc.CopyString(
5327
Arg.getAsString(getCompletionPrintingPolicy(S))));
5328
}
5329
B.AddChunk(clang::CodeCompletionString::CK_RightParen);
5330
}
5331
return B.TakeString();
5332
}
5333
};
5334
5335
// BaseType is the type parameter T to infer members from.
5336
// T must be accessible within S, as we use it to find the template entity
5337
// that T is attached to in order to gather the relevant constraints.
5338
ConceptInfo(const TemplateTypeParmType &BaseType, Scope *S) {
5339
auto *TemplatedEntity = getTemplatedEntity(BaseType.getDecl(), S);
5340
for (const Expr *E : constraintsForTemplatedEntity(TemplatedEntity))
5341
believe(E, &BaseType);
5342
}
5343
5344
std::vector<Member> members() {
5345
std::vector<Member> Results;
5346
for (const auto &E : this->Results)
5347
Results.push_back(E.second);
5348
llvm::sort(Results, [](const Member &L, const Member &R) {
5349
return L.Name->getName() < R.Name->getName();
5350
});
5351
return Results;
5352
}
5353
5354
private:
5355
// Infer members of T, given that the expression E (dependent on T) is true.
5356
void believe(const Expr *E, const TemplateTypeParmType *T) {
5357
if (!E || !T)
5358
return;
5359
if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(E)) {
5360
// If the concept is
5361
// template <class A, class B> concept CD = f<A, B>();
5362
// And the concept specialization is
5363
// CD<int, T>
5364
// Then we're substituting T for B, so we want to make f<A, B>() true
5365
// by adding members to B - i.e. believe(f<A, B>(), B);
5366
//
5367
// For simplicity:
5368
// - we don't attempt to substitute int for A
5369
// - when T is used in other ways (like CD<T*>) we ignore it
5370
ConceptDecl *CD = CSE->getNamedConcept();
5371
TemplateParameterList *Params = CD->getTemplateParameters();
5372
unsigned Index = 0;
5373
for (const auto &Arg : CSE->getTemplateArguments()) {
5374
if (Index >= Params->size())
5375
break; // Won't happen in valid code.
5376
if (isApprox(Arg, T)) {
5377
auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Params->getParam(Index));
5378
if (!TTPD)
5379
continue;
5380
// T was used as an argument, and bound to the parameter TT.
5381
auto *TT = cast<TemplateTypeParmType>(TTPD->getTypeForDecl());
5382
// So now we know the constraint as a function of TT is true.
5383
believe(CD->getConstraintExpr(), TT);
5384
// (concepts themselves have no associated constraints to require)
5385
}
5386
5387
++Index;
5388
}
5389
} else if (auto *BO = dyn_cast<BinaryOperator>(E)) {
5390
// For A && B, we can infer members from both branches.
5391
// For A || B, the union is still more useful than the intersection.
5392
if (BO->getOpcode() == BO_LAnd || BO->getOpcode() == BO_LOr) {
5393
believe(BO->getLHS(), T);
5394
believe(BO->getRHS(), T);
5395
}
5396
} else if (auto *RE = dyn_cast<RequiresExpr>(E)) {
5397
// A requires(){...} lets us infer members from each requirement.
5398
for (const concepts::Requirement *Req : RE->getRequirements()) {
5399
if (!Req->isDependent())
5400
continue; // Can't tell us anything about T.
5401
// Now Req cannot a substitution-error: those aren't dependent.
5402
5403
if (auto *TR = dyn_cast<concepts::TypeRequirement>(Req)) {
5404
// Do a full traversal so we get `foo` from `typename T::foo::bar`.
5405
QualType AssertedType = TR->getType()->getType();
5406
ValidVisitor(this, T).TraverseType(AssertedType);
5407
} else if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
5408
ValidVisitor Visitor(this, T);
5409
// If we have a type constraint on the value of the expression,
5410
// AND the whole outer expression describes a member, then we'll
5411
// be able to use the constraint to provide the return type.
5412
if (ER->getReturnTypeRequirement().isTypeConstraint()) {
5413
Visitor.OuterType =
5414
ER->getReturnTypeRequirement().getTypeConstraint();
5415
Visitor.OuterExpr = ER->getExpr();
5416
}
5417
Visitor.TraverseStmt(ER->getExpr());
5418
} else if (auto *NR = dyn_cast<concepts::NestedRequirement>(Req)) {
5419
believe(NR->getConstraintExpr(), T);
5420
}
5421
}
5422
}
5423
}
5424
5425
// This visitor infers members of T based on traversing expressions/types
5426
// that involve T. It is invoked with code known to be valid for T.
5427
class ValidVisitor : public RecursiveASTVisitor<ValidVisitor> {
5428
ConceptInfo *Outer;
5429
const TemplateTypeParmType *T;
5430
5431
CallExpr *Caller = nullptr;
5432
Expr *Callee = nullptr;
5433
5434
public:
5435
// If set, OuterExpr is constrained by OuterType.
5436
Expr *OuterExpr = nullptr;
5437
const TypeConstraint *OuterType = nullptr;
5438
5439
ValidVisitor(ConceptInfo *Outer, const TemplateTypeParmType *T)
5440
: Outer(Outer), T(T) {
5441
assert(T);
5442
}
5443
5444
// In T.foo or T->foo, `foo` is a member function/variable.
5445
bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
5446
const Type *Base = E->getBaseType().getTypePtr();
5447
bool IsArrow = E->isArrow();
5448
if (Base->isPointerType() && IsArrow) {
5449
IsArrow = false;
5450
Base = Base->getPointeeType().getTypePtr();
5451
}
5452
if (isApprox(Base, T))
5453
addValue(E, E->getMember(), IsArrow ? Member::Arrow : Member::Dot);
5454
return true;
5455
}
5456
5457
// In T::foo, `foo` is a static member function/variable.
5458
bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
5459
if (E->getQualifier() && isApprox(E->getQualifier()->getAsType(), T))
5460
addValue(E, E->getDeclName(), Member::Colons);
5461
return true;
5462
}
5463
5464
// In T::typename foo, `foo` is a type.
5465
bool VisitDependentNameType(DependentNameType *DNT) {
5466
const auto *Q = DNT->getQualifier();
5467
if (Q && isApprox(Q->getAsType(), T))
5468
addType(DNT->getIdentifier());
5469
return true;
5470
}
5471
5472
// In T::foo::bar, `foo` must be a type.
5473
// VisitNNS() doesn't exist, and TraverseNNS isn't always called :-(
5474
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) {
5475
if (NNSL) {
5476
NestedNameSpecifier *NNS = NNSL.getNestedNameSpecifier();
5477
const auto *Q = NNS->getPrefix();
5478
if (Q && isApprox(Q->getAsType(), T))
5479
addType(NNS->getAsIdentifier());
5480
}
5481
// FIXME: also handle T::foo<X>::bar
5482
return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL);
5483
}
5484
5485
// FIXME also handle T::foo<X>
5486
5487
// Track the innermost caller/callee relationship so we can tell if a
5488
// nested expr is being called as a function.
5489
bool VisitCallExpr(CallExpr *CE) {
5490
Caller = CE;
5491
Callee = CE->getCallee();
5492
return true;
5493
}
5494
5495
private:
5496
void addResult(Member &&M) {
5497
auto R = Outer->Results.try_emplace(M.Name);
5498
Member &O = R.first->second;
5499
// Overwrite existing if the new member has more info.
5500
// The preference of . vs :: vs -> is fairly arbitrary.
5501
if (/*Inserted*/ R.second ||
5502
std::make_tuple(M.ArgTypes.has_value(), M.ResultType != nullptr,
5503
M.Operator) > std::make_tuple(O.ArgTypes.has_value(),
5504
O.ResultType != nullptr,
5505
O.Operator))
5506
O = std::move(M);
5507
}
5508
5509
void addType(const IdentifierInfo *Name) {
5510
if (!Name)
5511
return;
5512
Member M;
5513
M.Name = Name;
5514
M.Operator = Member::Colons;
5515
addResult(std::move(M));
5516
}
5517
5518
void addValue(Expr *E, DeclarationName Name,
5519
Member::AccessOperator Operator) {
5520
if (!Name.isIdentifier())
5521
return;
5522
Member Result;
5523
Result.Name = Name.getAsIdentifierInfo();
5524
Result.Operator = Operator;
5525
// If this is the callee of an immediately-enclosing CallExpr, then
5526
// treat it as a method, otherwise it's a variable.
5527
if (Caller != nullptr && Callee == E) {
5528
Result.ArgTypes.emplace();
5529
for (const auto *Arg : Caller->arguments())
5530
Result.ArgTypes->push_back(Arg->getType());
5531
if (Caller == OuterExpr) {
5532
Result.ResultType = OuterType;
5533
}
5534
} else {
5535
if (E == OuterExpr)
5536
Result.ResultType = OuterType;
5537
}
5538
addResult(std::move(Result));
5539
}
5540
};
5541
5542
static bool isApprox(const TemplateArgument &Arg, const Type *T) {
5543
return Arg.getKind() == TemplateArgument::Type &&
5544
isApprox(Arg.getAsType().getTypePtr(), T);
5545
}
5546
5547
static bool isApprox(const Type *T1, const Type *T2) {
5548
return T1 && T2 &&
5549
T1->getCanonicalTypeUnqualified() ==
5550
T2->getCanonicalTypeUnqualified();
5551
}
5552
5553
// Returns the DeclContext immediately enclosed by the template parameter
5554
// scope. For primary templates, this is the templated (e.g.) CXXRecordDecl.
5555
// For specializations, this is e.g. ClassTemplatePartialSpecializationDecl.
5556
static DeclContext *getTemplatedEntity(const TemplateTypeParmDecl *D,
5557
Scope *S) {
5558
if (D == nullptr)
5559
return nullptr;
5560
Scope *Inner = nullptr;
5561
while (S) {
5562
if (S->isTemplateParamScope() && S->isDeclScope(D))
5563
return Inner ? Inner->getEntity() : nullptr;
5564
Inner = S;
5565
S = S->getParent();
5566
}
5567
return nullptr;
5568
}
5569
5570
// Gets all the type constraint expressions that might apply to the type
5571
// variables associated with DC (as returned by getTemplatedEntity()).
5572
static SmallVector<const Expr *, 1>
5573
constraintsForTemplatedEntity(DeclContext *DC) {
5574
SmallVector<const Expr *, 1> Result;
5575
if (DC == nullptr)
5576
return Result;
5577
// Primary templates can have constraints.
5578
if (const auto *TD = cast<Decl>(DC)->getDescribedTemplate())
5579
TD->getAssociatedConstraints(Result);
5580
// Partial specializations may have constraints.
5581
if (const auto *CTPSD =
5582
dyn_cast<ClassTemplatePartialSpecializationDecl>(DC))
5583
CTPSD->getAssociatedConstraints(Result);
5584
if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(DC))
5585
VTPSD->getAssociatedConstraints(Result);
5586
return Result;
5587
}
5588
5589
// Attempt to find the unique type satisfying a constraint.
5590
// This lets us show e.g. `int` instead of `std::same_as<int>`.
5591
static QualType deduceType(const TypeConstraint &T) {
5592
// Assume a same_as<T> return type constraint is std::same_as or equivalent.
5593
// In this case the return type is T.
5594
DeclarationName DN = T.getNamedConcept()->getDeclName();
5595
if (DN.isIdentifier() && DN.getAsIdentifierInfo()->isStr("same_as"))
5596
if (const auto *Args = T.getTemplateArgsAsWritten())
5597
if (Args->getNumTemplateArgs() == 1) {
5598
const auto &Arg = Args->arguments().front().getArgument();
5599
if (Arg.getKind() == TemplateArgument::Type)
5600
return Arg.getAsType();
5601
}
5602
return {};
5603
}
5604
5605
llvm::DenseMap<const IdentifierInfo *, Member> Results;
5606
};
5607
5608
// Returns a type for E that yields acceptable member completions.
5609
// In particular, when E->getType() is DependentTy, try to guess a likely type.
5610
// We accept some lossiness (like dropping parameters).
5611
// We only try to handle common expressions on the LHS of MemberExpr.
5612
QualType getApproximateType(const Expr *E) {
5613
if (E->getType().isNull())
5614
return QualType();
5615
E = E->IgnoreParenImpCasts();
5616
QualType Unresolved = E->getType();
5617
// We only resolve DependentTy, or undeduced autos (including auto* etc).
5618
if (!Unresolved->isSpecificBuiltinType(BuiltinType::Dependent)) {
5619
AutoType *Auto = Unresolved->getContainedAutoType();
5620
if (!Auto || !Auto->isUndeducedAutoType())
5621
return Unresolved;
5622
}
5623
// A call: approximate-resolve callee to a function type, get its return type
5624
if (const CallExpr *CE = llvm::dyn_cast<CallExpr>(E)) {
5625
QualType Callee = getApproximateType(CE->getCallee());
5626
if (Callee.isNull() ||
5627
Callee->isSpecificPlaceholderType(BuiltinType::BoundMember))
5628
Callee = Expr::findBoundMemberType(CE->getCallee());
5629
if (Callee.isNull())
5630
return Unresolved;
5631
5632
if (const auto *FnTypePtr = Callee->getAs<PointerType>()) {
5633
Callee = FnTypePtr->getPointeeType();
5634
} else if (const auto *BPT = Callee->getAs<BlockPointerType>()) {
5635
Callee = BPT->getPointeeType();
5636
}
5637
if (const FunctionType *FnType = Callee->getAs<FunctionType>())
5638
return FnType->getReturnType().getNonReferenceType();
5639
5640
// Unresolved call: try to guess the return type.
5641
if (const auto *OE = llvm::dyn_cast<OverloadExpr>(CE->getCallee())) {
5642
// If all candidates have the same approximate return type, use it.
5643
// Discard references and const to allow more to be "the same".
5644
// (In particular, if there's one candidate + ADL, resolve it).
5645
const Type *Common = nullptr;
5646
for (const auto *D : OE->decls()) {
5647
QualType ReturnType;
5648
if (const auto *FD = llvm::dyn_cast<FunctionDecl>(D))
5649
ReturnType = FD->getReturnType();
5650
else if (const auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(D))
5651
ReturnType = FTD->getTemplatedDecl()->getReturnType();
5652
if (ReturnType.isNull())
5653
continue;
5654
const Type *Candidate =
5655
ReturnType.getNonReferenceType().getCanonicalType().getTypePtr();
5656
if (Common && Common != Candidate)
5657
return Unresolved; // Multiple candidates.
5658
Common = Candidate;
5659
}
5660
if (Common != nullptr)
5661
return QualType(Common, 0);
5662
}
5663
}
5664
// A dependent member: approximate-resolve the base, then lookup.
5665
if (const auto *CDSME = llvm::dyn_cast<CXXDependentScopeMemberExpr>(E)) {
5666
QualType Base = CDSME->isImplicitAccess()
5667
? CDSME->getBaseType()
5668
: getApproximateType(CDSME->getBase());
5669
if (CDSME->isArrow() && !Base.isNull())
5670
Base = Base->getPointeeType(); // could handle unique_ptr etc here?
5671
auto *RD =
5672
Base.isNull()
5673
? nullptr
5674
: llvm::dyn_cast_or_null<CXXRecordDecl>(getAsRecordDecl(Base));
5675
if (RD && RD->isCompleteDefinition()) {
5676
// Look up member heuristically, including in bases.
5677
for (const auto *Member : RD->lookupDependentName(
5678
CDSME->getMember(), [](const NamedDecl *Member) {
5679
return llvm::isa<ValueDecl>(Member);
5680
})) {
5681
return llvm::cast<ValueDecl>(Member)->getType().getNonReferenceType();
5682
}
5683
}
5684
}
5685
// A reference to an `auto` variable: approximate-resolve its initializer.
5686
if (const auto *DRE = llvm::dyn_cast<DeclRefExpr>(E)) {
5687
if (const auto *VD = llvm::dyn_cast<VarDecl>(DRE->getDecl())) {
5688
if (VD->hasInit())
5689
return getApproximateType(VD->getInit());
5690
}
5691
}
5692
if (const auto *UO = llvm::dyn_cast<UnaryOperator>(E)) {
5693
if (UO->getOpcode() == UnaryOperatorKind::UO_Deref) {
5694
// We recurse into the subexpression because it could be of dependent
5695
// type.
5696
if (auto Pointee = getApproximateType(UO->getSubExpr())->getPointeeType();
5697
!Pointee.isNull())
5698
return Pointee;
5699
// Our caller expects a non-null result, even though the SubType is
5700
// supposed to have a pointee. Fall through to Unresolved anyway.
5701
}
5702
}
5703
return Unresolved;
5704
}
5705
5706
// If \p Base is ParenListExpr, assume a chain of comma operators and pick the
5707
// last expr. We expect other ParenListExprs to be resolved to e.g. constructor
5708
// calls before here. (So the ParenListExpr should be nonempty, but check just
5709
// in case)
5710
Expr *unwrapParenList(Expr *Base) {
5711
if (auto *PLE = llvm::dyn_cast_or_null<ParenListExpr>(Base)) {
5712
if (PLE->getNumExprs() == 0)
5713
return nullptr;
5714
Base = PLE->getExpr(PLE->getNumExprs() - 1);
5715
}
5716
return Base;
5717
}
5718
5719
} // namespace
5720
5721
void SemaCodeCompletion::CodeCompleteMemberReferenceExpr(
5722
Scope *S, Expr *Base, Expr *OtherOpBase, SourceLocation OpLoc, bool IsArrow,
5723
bool IsBaseExprStatement, QualType PreferredType) {
5724
Base = unwrapParenList(Base);
5725
OtherOpBase = unwrapParenList(OtherOpBase);
5726
if (!Base || !CodeCompleter)
5727
return;
5728
5729
ExprResult ConvertedBase =
5730
SemaRef.PerformMemberExprBaseConversion(Base, IsArrow);
5731
if (ConvertedBase.isInvalid())
5732
return;
5733
QualType ConvertedBaseType = getApproximateType(ConvertedBase.get());
5734
5735
enum CodeCompletionContext::Kind contextKind;
5736
5737
if (IsArrow) {
5738
if (const auto *Ptr = ConvertedBaseType->getAs<PointerType>())
5739
ConvertedBaseType = Ptr->getPointeeType();
5740
}
5741
5742
if (IsArrow) {
5743
contextKind = CodeCompletionContext::CCC_ArrowMemberAccess;
5744
} else {
5745
if (ConvertedBaseType->isObjCObjectPointerType() ||
5746
ConvertedBaseType->isObjCObjectOrInterfaceType()) {
5747
contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess;
5748
} else {
5749
contextKind = CodeCompletionContext::CCC_DotMemberAccess;
5750
}
5751
}
5752
5753
CodeCompletionContext CCContext(contextKind, ConvertedBaseType);
5754
CCContext.setPreferredType(PreferredType);
5755
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
5756
CodeCompleter->getCodeCompletionTUInfo(), CCContext,
5757
&ResultBuilder::IsMember);
5758
5759
auto DoCompletion = [&](Expr *Base, bool IsArrow,
5760
std::optional<FixItHint> AccessOpFixIt) -> bool {
5761
if (!Base)
5762
return false;
5763
5764
ExprResult ConvertedBase =
5765
SemaRef.PerformMemberExprBaseConversion(Base, IsArrow);
5766
if (ConvertedBase.isInvalid())
5767
return false;
5768
Base = ConvertedBase.get();
5769
5770
QualType BaseType = getApproximateType(Base);
5771
if (BaseType.isNull())
5772
return false;
5773
ExprValueKind BaseKind = Base->getValueKind();
5774
5775
if (IsArrow) {
5776
if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
5777
BaseType = Ptr->getPointeeType();
5778
BaseKind = VK_LValue;
5779
} else if (BaseType->isObjCObjectPointerType() ||
5780
BaseType->isTemplateTypeParmType()) {
5781
// Both cases (dot/arrow) handled below.
5782
} else {
5783
return false;
5784
}
5785
}
5786
5787
if (RecordDecl *RD = getAsRecordDecl(BaseType)) {
5788
AddRecordMembersCompletionResults(SemaRef, Results, S, BaseType, BaseKind,
5789
RD, std::move(AccessOpFixIt));
5790
} else if (const auto *TTPT =
5791
dyn_cast<TemplateTypeParmType>(BaseType.getTypePtr())) {
5792
auto Operator =
5793
IsArrow ? ConceptInfo::Member::Arrow : ConceptInfo::Member::Dot;
5794
for (const auto &R : ConceptInfo(*TTPT, S).members()) {
5795
if (R.Operator != Operator)
5796
continue;
5797
CodeCompletionResult Result(
5798
R.render(SemaRef, CodeCompleter->getAllocator(),
5799
CodeCompleter->getCodeCompletionTUInfo()));
5800
if (AccessOpFixIt)
5801
Result.FixIts.push_back(*AccessOpFixIt);
5802
Results.AddResult(std::move(Result));
5803
}
5804
} else if (!IsArrow && BaseType->isObjCObjectPointerType()) {
5805
// Objective-C property reference. Bail if we're performing fix-it code
5806
// completion since Objective-C properties are normally backed by ivars,
5807
// most Objective-C fix-its here would have little value.
5808
if (AccessOpFixIt) {
5809
return false;
5810
}
5811
AddedPropertiesSet AddedProperties;
5812
5813
if (const ObjCObjectPointerType *ObjCPtr =
5814
BaseType->getAsObjCInterfacePointerType()) {
5815
// Add property results based on our interface.
5816
assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
5817
AddObjCProperties(CCContext, ObjCPtr->getInterfaceDecl(), true,
5818
/*AllowNullaryMethods=*/true, SemaRef.CurContext,
5819
AddedProperties, Results, IsBaseExprStatement);
5820
}
5821
5822
// Add properties from the protocols in a qualified interface.
5823
for (auto *I : BaseType->castAs<ObjCObjectPointerType>()->quals())
5824
AddObjCProperties(CCContext, I, true, /*AllowNullaryMethods=*/true,
5825
SemaRef.CurContext, AddedProperties, Results,
5826
IsBaseExprStatement, /*IsClassProperty*/ false,
5827
/*InOriginalClass*/ false);
5828
} else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
5829
(!IsArrow && BaseType->isObjCObjectType())) {
5830
// Objective-C instance variable access. Bail if we're performing fix-it
5831
// code completion since Objective-C properties are normally backed by
5832
// ivars, most Objective-C fix-its here would have little value.
5833
if (AccessOpFixIt) {
5834
return false;
5835
}
5836
ObjCInterfaceDecl *Class = nullptr;
5837
if (const ObjCObjectPointerType *ObjCPtr =
5838
BaseType->getAs<ObjCObjectPointerType>())
5839
Class = ObjCPtr->getInterfaceDecl();
5840
else
5841
Class = BaseType->castAs<ObjCObjectType>()->getInterface();
5842
5843
// Add all ivars from this class and its superclasses.
5844
if (Class) {
5845
CodeCompletionDeclConsumer Consumer(Results, Class, BaseType);
5846
Results.setFilter(&ResultBuilder::IsObjCIvar);
5847
SemaRef.LookupVisibleDecls(Class, Sema::LookupMemberName, Consumer,
5848
CodeCompleter->includeGlobals(),
5849
/*IncludeDependentBases=*/false,
5850
CodeCompleter->loadExternal());
5851
}
5852
}
5853
5854
// FIXME: How do we cope with isa?
5855
return true;
5856
};
5857
5858
Results.EnterNewScope();
5859
5860
bool CompletionSucceded = DoCompletion(Base, IsArrow, std::nullopt);
5861
if (CodeCompleter->includeFixIts()) {
5862
const CharSourceRange OpRange =
5863
CharSourceRange::getTokenRange(OpLoc, OpLoc);
5864
CompletionSucceded |= DoCompletion(
5865
OtherOpBase, !IsArrow,
5866
FixItHint::CreateReplacement(OpRange, IsArrow ? "." : "->"));
5867
}
5868
5869
Results.ExitScope();
5870
5871
if (!CompletionSucceded)
5872
return;
5873
5874
// Hand off the results found for code completion.
5875
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
5876
Results.getCompletionContext(), Results.data(),
5877
Results.size());
5878
}
5879
5880
void SemaCodeCompletion::CodeCompleteObjCClassPropertyRefExpr(
5881
Scope *S, const IdentifierInfo &ClassName, SourceLocation ClassNameLoc,
5882
bool IsBaseExprStatement) {
5883
const IdentifierInfo *ClassNamePtr = &ClassName;
5884
ObjCInterfaceDecl *IFace =
5885
SemaRef.ObjC().getObjCInterfaceDecl(ClassNamePtr, ClassNameLoc);
5886
if (!IFace)
5887
return;
5888
CodeCompletionContext CCContext(
5889
CodeCompletionContext::CCC_ObjCPropertyAccess);
5890
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
5891
CodeCompleter->getCodeCompletionTUInfo(), CCContext,
5892
&ResultBuilder::IsMember);
5893
Results.EnterNewScope();
5894
AddedPropertiesSet AddedProperties;
5895
AddObjCProperties(CCContext, IFace, true,
5896
/*AllowNullaryMethods=*/true, SemaRef.CurContext,
5897
AddedProperties, Results, IsBaseExprStatement,
5898
/*IsClassProperty=*/true);
5899
Results.ExitScope();
5900
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
5901
Results.getCompletionContext(), Results.data(),
5902
Results.size());
5903
}
5904
5905
void SemaCodeCompletion::CodeCompleteTag(Scope *S, unsigned TagSpec) {
5906
if (!CodeCompleter)
5907
return;
5908
5909
ResultBuilder::LookupFilter Filter = nullptr;
5910
enum CodeCompletionContext::Kind ContextKind =
5911
CodeCompletionContext::CCC_Other;
5912
switch ((DeclSpec::TST)TagSpec) {
5913
case DeclSpec::TST_enum:
5914
Filter = &ResultBuilder::IsEnum;
5915
ContextKind = CodeCompletionContext::CCC_EnumTag;
5916
break;
5917
5918
case DeclSpec::TST_union:
5919
Filter = &ResultBuilder::IsUnion;
5920
ContextKind = CodeCompletionContext::CCC_UnionTag;
5921
break;
5922
5923
case DeclSpec::TST_struct:
5924
case DeclSpec::TST_class:
5925
case DeclSpec::TST_interface:
5926
Filter = &ResultBuilder::IsClassOrStruct;
5927
ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
5928
break;
5929
5930
default:
5931
llvm_unreachable("Unknown type specifier kind in CodeCompleteTag");
5932
}
5933
5934
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
5935
CodeCompleter->getCodeCompletionTUInfo(), ContextKind);
5936
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
5937
5938
// First pass: look for tags.
5939
Results.setFilter(Filter);
5940
SemaRef.LookupVisibleDecls(S, Sema::LookupTagName, Consumer,
5941
CodeCompleter->includeGlobals(),
5942
CodeCompleter->loadExternal());
5943
5944
if (CodeCompleter->includeGlobals()) {
5945
// Second pass: look for nested name specifiers.
5946
Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
5947
SemaRef.LookupVisibleDecls(S, Sema::LookupNestedNameSpecifierName, Consumer,
5948
CodeCompleter->includeGlobals(),
5949
CodeCompleter->loadExternal());
5950
}
5951
5952
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
5953
Results.getCompletionContext(), Results.data(),
5954
Results.size());
5955
}
5956
5957
static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results,
5958
const LangOptions &LangOpts) {
5959
if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
5960
Results.AddResult("const");
5961
if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
5962
Results.AddResult("volatile");
5963
if (LangOpts.C99 && !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
5964
Results.AddResult("restrict");
5965
if (LangOpts.C11 && !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
5966
Results.AddResult("_Atomic");
5967
if (LangOpts.MSVCCompat && !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
5968
Results.AddResult("__unaligned");
5969
}
5970
5971
void SemaCodeCompletion::CodeCompleteTypeQualifiers(DeclSpec &DS) {
5972
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
5973
CodeCompleter->getCodeCompletionTUInfo(),
5974
CodeCompletionContext::CCC_TypeQualifiers);
5975
Results.EnterNewScope();
5976
AddTypeQualifierResults(DS, Results, getLangOpts());
5977
Results.ExitScope();
5978
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
5979
Results.getCompletionContext(), Results.data(),
5980
Results.size());
5981
}
5982
5983
void SemaCodeCompletion::CodeCompleteFunctionQualifiers(
5984
DeclSpec &DS, Declarator &D, const VirtSpecifiers *VS) {
5985
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
5986
CodeCompleter->getCodeCompletionTUInfo(),
5987
CodeCompletionContext::CCC_TypeQualifiers);
5988
Results.EnterNewScope();
5989
AddTypeQualifierResults(DS, Results, getLangOpts());
5990
if (getLangOpts().CPlusPlus11) {
5991
Results.AddResult("noexcept");
5992
if (D.getContext() == DeclaratorContext::Member && !D.isCtorOrDtor() &&
5993
!D.isStaticMember()) {
5994
if (!VS || !VS->isFinalSpecified())
5995
Results.AddResult("final");
5996
if (!VS || !VS->isOverrideSpecified())
5997
Results.AddResult("override");
5998
}
5999
}
6000
Results.ExitScope();
6001
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6002
Results.getCompletionContext(), Results.data(),
6003
Results.size());
6004
}
6005
6006
void SemaCodeCompletion::CodeCompleteBracketDeclarator(Scope *S) {
6007
CodeCompleteExpression(S, QualType(getASTContext().getSizeType()));
6008
}
6009
6010
void SemaCodeCompletion::CodeCompleteCase(Scope *S) {
6011
if (SemaRef.getCurFunction()->SwitchStack.empty() || !CodeCompleter)
6012
return;
6013
6014
SwitchStmt *Switch =
6015
SemaRef.getCurFunction()->SwitchStack.back().getPointer();
6016
// Condition expression might be invalid, do not continue in this case.
6017
if (!Switch->getCond())
6018
return;
6019
QualType type = Switch->getCond()->IgnoreImplicit()->getType();
6020
if (!type->isEnumeralType()) {
6021
CodeCompleteExpressionData Data(type);
6022
Data.IntegralConstantExpression = true;
6023
CodeCompleteExpression(S, Data);
6024
return;
6025
}
6026
6027
// Code-complete the cases of a switch statement over an enumeration type
6028
// by providing the list of
6029
EnumDecl *Enum = type->castAs<EnumType>()->getDecl();
6030
if (EnumDecl *Def = Enum->getDefinition())
6031
Enum = Def;
6032
6033
// Determine which enumerators we have already seen in the switch statement.
6034
// FIXME: Ideally, we would also be able to look *past* the code-completion
6035
// token, in case we are code-completing in the middle of the switch and not
6036
// at the end. However, we aren't able to do so at the moment.
6037
CoveredEnumerators Enumerators;
6038
for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
6039
SC = SC->getNextSwitchCase()) {
6040
CaseStmt *Case = dyn_cast<CaseStmt>(SC);
6041
if (!Case)
6042
continue;
6043
6044
Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
6045
if (auto *DRE = dyn_cast<DeclRefExpr>(CaseVal))
6046
if (auto *Enumerator =
6047
dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
6048
// We look into the AST of the case statement to determine which
6049
// enumerator was named. Alternatively, we could compute the value of
6050
// the integral constant expression, then compare it against the
6051
// values of each enumerator. However, value-based approach would not
6052
// work as well with C++ templates where enumerators declared within a
6053
// template are type- and value-dependent.
6054
Enumerators.Seen.insert(Enumerator);
6055
6056
// If this is a qualified-id, keep track of the nested-name-specifier
6057
// so that we can reproduce it as part of code completion, e.g.,
6058
//
6059
// switch (TagD.getKind()) {
6060
// case TagDecl::TK_enum:
6061
// break;
6062
// case XXX
6063
//
6064
// At the XXX, our completions are TagDecl::TK_union,
6065
// TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
6066
// TK_struct, and TK_class.
6067
Enumerators.SuggestedQualifier = DRE->getQualifier();
6068
}
6069
}
6070
6071
// Add any enumerators that have not yet been mentioned.
6072
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6073
CodeCompleter->getCodeCompletionTUInfo(),
6074
CodeCompletionContext::CCC_Expression);
6075
AddEnumerators(Results, getASTContext(), Enum, SemaRef.CurContext,
6076
Enumerators);
6077
6078
if (CodeCompleter->includeMacros()) {
6079
AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
6080
}
6081
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6082
Results.getCompletionContext(), Results.data(),
6083
Results.size());
6084
}
6085
6086
static bool anyNullArguments(ArrayRef<Expr *> Args) {
6087
if (Args.size() && !Args.data())
6088
return true;
6089
6090
for (unsigned I = 0; I != Args.size(); ++I)
6091
if (!Args[I])
6092
return true;
6093
6094
return false;
6095
}
6096
6097
typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
6098
6099
static void mergeCandidatesWithResults(
6100
Sema &SemaRef, SmallVectorImpl<ResultCandidate> &Results,
6101
OverloadCandidateSet &CandidateSet, SourceLocation Loc, size_t ArgSize) {
6102
// Sort the overload candidate set by placing the best overloads first.
6103
llvm::stable_sort(CandidateSet, [&](const OverloadCandidate &X,
6104
const OverloadCandidate &Y) {
6105
return isBetterOverloadCandidate(SemaRef, X, Y, Loc,
6106
CandidateSet.getKind());
6107
});
6108
6109
// Add the remaining viable overload candidates as code-completion results.
6110
for (OverloadCandidate &Candidate : CandidateSet) {
6111
if (Candidate.Function) {
6112
if (Candidate.Function->isDeleted())
6113
continue;
6114
if (shouldEnforceArgLimit(/*PartialOverloading=*/true,
6115
Candidate.Function) &&
6116
Candidate.Function->getNumParams() <= ArgSize &&
6117
// Having zero args is annoying, normally we don't surface a function
6118
// with 2 params, if you already have 2 params, because you are
6119
// inserting the 3rd now. But with zero, it helps the user to figure
6120
// out there are no overloads that take any arguments. Hence we are
6121
// keeping the overload.
6122
ArgSize > 0)
6123
continue;
6124
}
6125
if (Candidate.Viable)
6126
Results.push_back(ResultCandidate(Candidate.Function));
6127
}
6128
}
6129
6130
/// Get the type of the Nth parameter from a given set of overload
6131
/// candidates.
6132
static QualType getParamType(Sema &SemaRef,
6133
ArrayRef<ResultCandidate> Candidates, unsigned N) {
6134
6135
// Given the overloads 'Candidates' for a function call matching all arguments
6136
// up to N, return the type of the Nth parameter if it is the same for all
6137
// overload candidates.
6138
QualType ParamType;
6139
for (auto &Candidate : Candidates) {
6140
QualType CandidateParamType = Candidate.getParamType(N);
6141
if (CandidateParamType.isNull())
6142
continue;
6143
if (ParamType.isNull()) {
6144
ParamType = CandidateParamType;
6145
continue;
6146
}
6147
if (!SemaRef.Context.hasSameUnqualifiedType(
6148
ParamType.getNonReferenceType(),
6149
CandidateParamType.getNonReferenceType()))
6150
// Two conflicting types, give up.
6151
return QualType();
6152
}
6153
6154
return ParamType;
6155
}
6156
6157
static QualType
6158
ProduceSignatureHelp(Sema &SemaRef, MutableArrayRef<ResultCandidate> Candidates,
6159
unsigned CurrentArg, SourceLocation OpenParLoc,
6160
bool Braced) {
6161
if (Candidates.empty())
6162
return QualType();
6163
if (SemaRef.getPreprocessor().isCodeCompletionReached())
6164
SemaRef.CodeCompletion().CodeCompleter->ProcessOverloadCandidates(
6165
SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc,
6166
Braced);
6167
return getParamType(SemaRef, Candidates, CurrentArg);
6168
}
6169
6170
// Given a callee expression `Fn`, if the call is through a function pointer,
6171
// try to find the declaration of the corresponding function pointer type,
6172
// so that we can recover argument names from it.
6173
static FunctionProtoTypeLoc GetPrototypeLoc(Expr *Fn) {
6174
TypeLoc Target;
6175
6176
if (const auto *T = Fn->getType().getTypePtr()->getAs<TypedefType>()) {
6177
Target = T->getDecl()->getTypeSourceInfo()->getTypeLoc();
6178
6179
} else if (const auto *DR = dyn_cast<DeclRefExpr>(Fn)) {
6180
const auto *D = DR->getDecl();
6181
if (const auto *const VD = dyn_cast<VarDecl>(D)) {
6182
Target = VD->getTypeSourceInfo()->getTypeLoc();
6183
}
6184
} else if (const auto *ME = dyn_cast<MemberExpr>(Fn)) {
6185
const auto *MD = ME->getMemberDecl();
6186
if (const auto *FD = dyn_cast<FieldDecl>(MD)) {
6187
Target = FD->getTypeSourceInfo()->getTypeLoc();
6188
}
6189
}
6190
6191
if (!Target)
6192
return {};
6193
6194
// Unwrap types that may be wrapping the function type
6195
while (true) {
6196
if (auto P = Target.getAs<PointerTypeLoc>()) {
6197
Target = P.getPointeeLoc();
6198
continue;
6199
}
6200
if (auto A = Target.getAs<AttributedTypeLoc>()) {
6201
Target = A.getModifiedLoc();
6202
continue;
6203
}
6204
if (auto P = Target.getAs<ParenTypeLoc>()) {
6205
Target = P.getInnerLoc();
6206
continue;
6207
}
6208
break;
6209
}
6210
6211
if (auto F = Target.getAs<FunctionProtoTypeLoc>()) {
6212
return F;
6213
}
6214
6215
return {};
6216
}
6217
6218
QualType
6219
SemaCodeCompletion::ProduceCallSignatureHelp(Expr *Fn, ArrayRef<Expr *> Args,
6220
SourceLocation OpenParLoc) {
6221
Fn = unwrapParenList(Fn);
6222
if (!CodeCompleter || !Fn)
6223
return QualType();
6224
6225
// FIXME: Provide support for variadic template functions.
6226
// Ignore type-dependent call expressions entirely.
6227
if (Fn->isTypeDependent() || anyNullArguments(Args))
6228
return QualType();
6229
// In presence of dependent args we surface all possible signatures using the
6230
// non-dependent args in the prefix. Afterwards we do a post filtering to make
6231
// sure provided candidates satisfy parameter count restrictions.
6232
auto ArgsWithoutDependentTypes =
6233
Args.take_while([](Expr *Arg) { return !Arg->isTypeDependent(); });
6234
6235
SmallVector<ResultCandidate, 8> Results;
6236
6237
Expr *NakedFn = Fn->IgnoreParenCasts();
6238
// Build an overload candidate set based on the functions we find.
6239
SourceLocation Loc = Fn->getExprLoc();
6240
OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
6241
6242
if (auto ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn)) {
6243
SemaRef.AddOverloadedCallCandidates(ULE, ArgsWithoutDependentTypes,
6244
CandidateSet,
6245
/*PartialOverloading=*/true);
6246
} else if (auto UME = dyn_cast<UnresolvedMemberExpr>(NakedFn)) {
6247
TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
6248
if (UME->hasExplicitTemplateArgs()) {
6249
UME->copyTemplateArgumentsInto(TemplateArgsBuffer);
6250
TemplateArgs = &TemplateArgsBuffer;
6251
}
6252
6253
// Add the base as first argument (use a nullptr if the base is implicit).
6254
SmallVector<Expr *, 12> ArgExprs(
6255
1, UME->isImplicitAccess() ? nullptr : UME->getBase());
6256
ArgExprs.append(ArgsWithoutDependentTypes.begin(),
6257
ArgsWithoutDependentTypes.end());
6258
UnresolvedSet<8> Decls;
6259
Decls.append(UME->decls_begin(), UME->decls_end());
6260
const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase();
6261
SemaRef.AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs,
6262
/*SuppressUserConversions=*/false,
6263
/*PartialOverloading=*/true,
6264
FirstArgumentIsBase);
6265
} else {
6266
FunctionDecl *FD = nullptr;
6267
if (auto *MCE = dyn_cast<MemberExpr>(NakedFn))
6268
FD = dyn_cast<FunctionDecl>(MCE->getMemberDecl());
6269
else if (auto *DRE = dyn_cast<DeclRefExpr>(NakedFn))
6270
FD = dyn_cast<FunctionDecl>(DRE->getDecl());
6271
if (FD) { // We check whether it's a resolved function declaration.
6272
if (!getLangOpts().CPlusPlus ||
6273
!FD->getType()->getAs<FunctionProtoType>())
6274
Results.push_back(ResultCandidate(FD));
6275
else
6276
SemaRef.AddOverloadCandidate(FD,
6277
DeclAccessPair::make(FD, FD->getAccess()),
6278
ArgsWithoutDependentTypes, CandidateSet,
6279
/*SuppressUserConversions=*/false,
6280
/*PartialOverloading=*/true);
6281
6282
} else if (auto DC = NakedFn->getType()->getAsCXXRecordDecl()) {
6283
// If expression's type is CXXRecordDecl, it may overload the function
6284
// call operator, so we check if it does and add them as candidates.
6285
// A complete type is needed to lookup for member function call operators.
6286
if (SemaRef.isCompleteType(Loc, NakedFn->getType())) {
6287
DeclarationName OpName =
6288
getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
6289
LookupResult R(SemaRef, OpName, Loc, Sema::LookupOrdinaryName);
6290
SemaRef.LookupQualifiedName(R, DC);
6291
R.suppressDiagnostics();
6292
SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
6293
ArgExprs.append(ArgsWithoutDependentTypes.begin(),
6294
ArgsWithoutDependentTypes.end());
6295
SemaRef.AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs,
6296
CandidateSet,
6297
/*ExplicitArgs=*/nullptr,
6298
/*SuppressUserConversions=*/false,
6299
/*PartialOverloading=*/true);
6300
}
6301
} else {
6302
// Lastly we check whether expression's type is function pointer or
6303
// function.
6304
6305
FunctionProtoTypeLoc P = GetPrototypeLoc(NakedFn);
6306
QualType T = NakedFn->getType();
6307
if (!T->getPointeeType().isNull())
6308
T = T->getPointeeType();
6309
6310
if (auto FP = T->getAs<FunctionProtoType>()) {
6311
if (!SemaRef.TooManyArguments(FP->getNumParams(),
6312
ArgsWithoutDependentTypes.size(),
6313
/*PartialOverloading=*/true) ||
6314
FP->isVariadic()) {
6315
if (P) {
6316
Results.push_back(ResultCandidate(P));
6317
} else {
6318
Results.push_back(ResultCandidate(FP));
6319
}
6320
}
6321
} else if (auto FT = T->getAs<FunctionType>())
6322
// No prototype and declaration, it may be a K & R style function.
6323
Results.push_back(ResultCandidate(FT));
6324
}
6325
}
6326
mergeCandidatesWithResults(SemaRef, Results, CandidateSet, Loc, Args.size());
6327
QualType ParamType = ProduceSignatureHelp(SemaRef, Results, Args.size(),
6328
OpenParLoc, /*Braced=*/false);
6329
return !CandidateSet.empty() ? ParamType : QualType();
6330
}
6331
6332
// Determine which param to continue aggregate initialization from after
6333
// a designated initializer.
6334
//
6335
// Given struct S { int a,b,c,d,e; }:
6336
// after `S{.b=1,` we want to suggest c to continue
6337
// after `S{.b=1, 2,` we continue with d (this is legal C and ext in C++)
6338
// after `S{.b=1, .a=2,` we continue with b (this is legal C and ext in C++)
6339
//
6340
// Possible outcomes:
6341
// - we saw a designator for a field, and continue from the returned index.
6342
// Only aggregate initialization is allowed.
6343
// - we saw a designator, but it was complex or we couldn't find the field.
6344
// Only aggregate initialization is possible, but we can't assist with it.
6345
// Returns an out-of-range index.
6346
// - we saw no designators, just positional arguments.
6347
// Returns std::nullopt.
6348
static std::optional<unsigned>
6349
getNextAggregateIndexAfterDesignatedInit(const ResultCandidate &Aggregate,
6350
ArrayRef<Expr *> Args) {
6351
static constexpr unsigned Invalid = std::numeric_limits<unsigned>::max();
6352
assert(Aggregate.getKind() == ResultCandidate::CK_Aggregate);
6353
6354
// Look for designated initializers.
6355
// They're in their syntactic form, not yet resolved to fields.
6356
const IdentifierInfo *DesignatedFieldName = nullptr;
6357
unsigned ArgsAfterDesignator = 0;
6358
for (const Expr *Arg : Args) {
6359
if (const auto *DIE = dyn_cast<DesignatedInitExpr>(Arg)) {
6360
if (DIE->size() == 1 && DIE->getDesignator(0)->isFieldDesignator()) {
6361
DesignatedFieldName = DIE->getDesignator(0)->getFieldName();
6362
ArgsAfterDesignator = 0;
6363
} else {
6364
return Invalid; // Complicated designator.
6365
}
6366
} else if (isa<DesignatedInitUpdateExpr>(Arg)) {
6367
return Invalid; // Unsupported.
6368
} else {
6369
++ArgsAfterDesignator;
6370
}
6371
}
6372
if (!DesignatedFieldName)
6373
return std::nullopt;
6374
6375
// Find the index within the class's fields.
6376
// (Probing getParamDecl() directly would be quadratic in number of fields).
6377
unsigned DesignatedIndex = 0;
6378
const FieldDecl *DesignatedField = nullptr;
6379
for (const auto *Field : Aggregate.getAggregate()->fields()) {
6380
if (Field->getIdentifier() == DesignatedFieldName) {
6381
DesignatedField = Field;
6382
break;
6383
}
6384
++DesignatedIndex;
6385
}
6386
if (!DesignatedField)
6387
return Invalid; // Designator referred to a missing field, give up.
6388
6389
// Find the index within the aggregate (which may have leading bases).
6390
unsigned AggregateSize = Aggregate.getNumParams();
6391
while (DesignatedIndex < AggregateSize &&
6392
Aggregate.getParamDecl(DesignatedIndex) != DesignatedField)
6393
++DesignatedIndex;
6394
6395
// Continue from the index after the last named field.
6396
return DesignatedIndex + ArgsAfterDesignator + 1;
6397
}
6398
6399
QualType SemaCodeCompletion::ProduceConstructorSignatureHelp(
6400
QualType Type, SourceLocation Loc, ArrayRef<Expr *> Args,
6401
SourceLocation OpenParLoc, bool Braced) {
6402
if (!CodeCompleter)
6403
return QualType();
6404
SmallVector<ResultCandidate, 8> Results;
6405
6406
// A complete type is needed to lookup for constructors.
6407
RecordDecl *RD =
6408
SemaRef.isCompleteType(Loc, Type) ? Type->getAsRecordDecl() : nullptr;
6409
if (!RD)
6410
return Type;
6411
CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD);
6412
6413
// Consider aggregate initialization.
6414
// We don't check that types so far are correct.
6415
// We also don't handle C99/C++17 brace-elision, we assume init-list elements
6416
// are 1:1 with fields.
6417
// FIXME: it would be nice to support "unwrapping" aggregates that contain
6418
// a single subaggregate, like std::array<T, N> -> T __elements[N].
6419
if (Braced && !RD->isUnion() &&
6420
(!getLangOpts().CPlusPlus || (CRD && CRD->isAggregate()))) {
6421
ResultCandidate AggregateSig(RD);
6422
unsigned AggregateSize = AggregateSig.getNumParams();
6423
6424
if (auto NextIndex =
6425
getNextAggregateIndexAfterDesignatedInit(AggregateSig, Args)) {
6426
// A designator was used, only aggregate init is possible.
6427
if (*NextIndex >= AggregateSize)
6428
return Type;
6429
Results.push_back(AggregateSig);
6430
return ProduceSignatureHelp(SemaRef, Results, *NextIndex, OpenParLoc,
6431
Braced);
6432
}
6433
6434
// Describe aggregate initialization, but also constructors below.
6435
if (Args.size() < AggregateSize)
6436
Results.push_back(AggregateSig);
6437
}
6438
6439
// FIXME: Provide support for member initializers.
6440
// FIXME: Provide support for variadic template constructors.
6441
6442
if (CRD) {
6443
OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
6444
for (NamedDecl *C : SemaRef.LookupConstructors(CRD)) {
6445
if (auto *FD = dyn_cast<FunctionDecl>(C)) {
6446
// FIXME: we can't yet provide correct signature help for initializer
6447
// list constructors, so skip them entirely.
6448
if (Braced && getLangOpts().CPlusPlus &&
6449
SemaRef.isInitListConstructor(FD))
6450
continue;
6451
SemaRef.AddOverloadCandidate(
6452
FD, DeclAccessPair::make(FD, C->getAccess()), Args, CandidateSet,
6453
/*SuppressUserConversions=*/false,
6454
/*PartialOverloading=*/true,
6455
/*AllowExplicit*/ true);
6456
} else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(C)) {
6457
if (Braced && getLangOpts().CPlusPlus &&
6458
SemaRef.isInitListConstructor(FTD->getTemplatedDecl()))
6459
continue;
6460
6461
SemaRef.AddTemplateOverloadCandidate(
6462
FTD, DeclAccessPair::make(FTD, C->getAccess()),
6463
/*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet,
6464
/*SuppressUserConversions=*/false,
6465
/*PartialOverloading=*/true);
6466
}
6467
}
6468
mergeCandidatesWithResults(SemaRef, Results, CandidateSet, Loc,
6469
Args.size());
6470
}
6471
6472
return ProduceSignatureHelp(SemaRef, Results, Args.size(), OpenParLoc,
6473
Braced);
6474
}
6475
6476
QualType SemaCodeCompletion::ProduceCtorInitMemberSignatureHelp(
6477
Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy,
6478
ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc,
6479
bool Braced) {
6480
if (!CodeCompleter)
6481
return QualType();
6482
6483
CXXConstructorDecl *Constructor =
6484
dyn_cast<CXXConstructorDecl>(ConstructorDecl);
6485
if (!Constructor)
6486
return QualType();
6487
// FIXME: Add support for Base class constructors as well.
6488
if (ValueDecl *MemberDecl = SemaRef.tryLookupCtorInitMemberDecl(
6489
Constructor->getParent(), SS, TemplateTypeTy, II))
6490
return ProduceConstructorSignatureHelp(MemberDecl->getType(),
6491
MemberDecl->getLocation(), ArgExprs,
6492
OpenParLoc, Braced);
6493
return QualType();
6494
}
6495
6496
static bool argMatchesTemplateParams(const ParsedTemplateArgument &Arg,
6497
unsigned Index,
6498
const TemplateParameterList &Params) {
6499
const NamedDecl *Param;
6500
if (Index < Params.size())
6501
Param = Params.getParam(Index);
6502
else if (Params.hasParameterPack())
6503
Param = Params.asArray().back();
6504
else
6505
return false; // too many args
6506
6507
switch (Arg.getKind()) {
6508
case ParsedTemplateArgument::Type:
6509
return llvm::isa<TemplateTypeParmDecl>(Param); // constraints not checked
6510
case ParsedTemplateArgument::NonType:
6511
return llvm::isa<NonTypeTemplateParmDecl>(Param); // type not checked
6512
case ParsedTemplateArgument::Template:
6513
return llvm::isa<TemplateTemplateParmDecl>(Param); // signature not checked
6514
}
6515
llvm_unreachable("Unhandled switch case");
6516
}
6517
6518
QualType SemaCodeCompletion::ProduceTemplateArgumentSignatureHelp(
6519
TemplateTy ParsedTemplate, ArrayRef<ParsedTemplateArgument> Args,
6520
SourceLocation LAngleLoc) {
6521
if (!CodeCompleter || !ParsedTemplate)
6522
return QualType();
6523
6524
SmallVector<ResultCandidate, 8> Results;
6525
auto Consider = [&](const TemplateDecl *TD) {
6526
// Only add if the existing args are compatible with the template.
6527
bool Matches = true;
6528
for (unsigned I = 0; I < Args.size(); ++I) {
6529
if (!argMatchesTemplateParams(Args[I], I, *TD->getTemplateParameters())) {
6530
Matches = false;
6531
break;
6532
}
6533
}
6534
if (Matches)
6535
Results.emplace_back(TD);
6536
};
6537
6538
TemplateName Template = ParsedTemplate.get();
6539
if (const auto *TD = Template.getAsTemplateDecl()) {
6540
Consider(TD);
6541
} else if (const auto *OTS = Template.getAsOverloadedTemplate()) {
6542
for (const NamedDecl *ND : *OTS)
6543
if (const auto *TD = llvm::dyn_cast<TemplateDecl>(ND))
6544
Consider(TD);
6545
}
6546
return ProduceSignatureHelp(SemaRef, Results, Args.size(), LAngleLoc,
6547
/*Braced=*/false);
6548
}
6549
6550
static QualType getDesignatedType(QualType BaseType, const Designation &Desig) {
6551
for (unsigned I = 0; I < Desig.getNumDesignators(); ++I) {
6552
if (BaseType.isNull())
6553
break;
6554
QualType NextType;
6555
const auto &D = Desig.getDesignator(I);
6556
if (D.isArrayDesignator() || D.isArrayRangeDesignator()) {
6557
if (BaseType->isArrayType())
6558
NextType = BaseType->getAsArrayTypeUnsafe()->getElementType();
6559
} else {
6560
assert(D.isFieldDesignator());
6561
auto *RD = getAsRecordDecl(BaseType);
6562
if (RD && RD->isCompleteDefinition()) {
6563
for (const auto *Member : RD->lookup(D.getFieldDecl()))
6564
if (const FieldDecl *FD = llvm::dyn_cast<FieldDecl>(Member)) {
6565
NextType = FD->getType();
6566
break;
6567
}
6568
}
6569
}
6570
BaseType = NextType;
6571
}
6572
return BaseType;
6573
}
6574
6575
void SemaCodeCompletion::CodeCompleteDesignator(
6576
QualType BaseType, llvm::ArrayRef<Expr *> InitExprs, const Designation &D) {
6577
BaseType = getDesignatedType(BaseType, D);
6578
if (BaseType.isNull())
6579
return;
6580
const auto *RD = getAsRecordDecl(BaseType);
6581
if (!RD || RD->fields().empty())
6582
return;
6583
6584
CodeCompletionContext CCC(CodeCompletionContext::CCC_DotMemberAccess,
6585
BaseType);
6586
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6587
CodeCompleter->getCodeCompletionTUInfo(), CCC);
6588
6589
Results.EnterNewScope();
6590
for (const Decl *D : RD->decls()) {
6591
const FieldDecl *FD;
6592
if (auto *IFD = dyn_cast<IndirectFieldDecl>(D))
6593
FD = IFD->getAnonField();
6594
else if (auto *DFD = dyn_cast<FieldDecl>(D))
6595
FD = DFD;
6596
else
6597
continue;
6598
6599
// FIXME: Make use of previous designators to mark any fields before those
6600
// inaccessible, and also compute the next initializer priority.
6601
ResultBuilder::Result Result(FD, Results.getBasePriority(FD));
6602
Results.AddResult(Result, SemaRef.CurContext, /*Hiding=*/nullptr);
6603
}
6604
Results.ExitScope();
6605
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6606
Results.getCompletionContext(), Results.data(),
6607
Results.size());
6608
}
6609
6610
void SemaCodeCompletion::CodeCompleteInitializer(Scope *S, Decl *D) {
6611
ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
6612
if (!VD) {
6613
CodeCompleteOrdinaryName(S, PCC_Expression);
6614
return;
6615
}
6616
6617
CodeCompleteExpressionData Data;
6618
Data.PreferredType = VD->getType();
6619
// Ignore VD to avoid completing the variable itself, e.g. in 'int foo = ^'.
6620
Data.IgnoreDecls.push_back(VD);
6621
6622
CodeCompleteExpression(S, Data);
6623
}
6624
6625
void SemaCodeCompletion::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {
6626
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6627
CodeCompleter->getCodeCompletionTUInfo(),
6628
mapCodeCompletionContext(SemaRef, PCC_Statement));
6629
Results.setFilter(&ResultBuilder::IsOrdinaryName);
6630
Results.EnterNewScope();
6631
6632
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
6633
SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
6634
CodeCompleter->includeGlobals(),
6635
CodeCompleter->loadExternal());
6636
6637
AddOrdinaryNameResults(PCC_Statement, S, SemaRef, Results);
6638
6639
// "else" block
6640
CodeCompletionBuilder Builder(Results.getAllocator(),
6641
Results.getCodeCompletionTUInfo());
6642
6643
auto AddElseBodyPattern = [&] {
6644
if (IsBracedThen) {
6645
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6646
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
6647
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6648
Builder.AddPlaceholderChunk("statements");
6649
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6650
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
6651
} else {
6652
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6653
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6654
Builder.AddPlaceholderChunk("statement");
6655
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
6656
}
6657
};
6658
Builder.AddTypedTextChunk("else");
6659
if (Results.includeCodePatterns())
6660
AddElseBodyPattern();
6661
Results.AddResult(Builder.TakeString());
6662
6663
// "else if" block
6664
Builder.AddTypedTextChunk("else if");
6665
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6666
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6667
if (getLangOpts().CPlusPlus)
6668
Builder.AddPlaceholderChunk("condition");
6669
else
6670
Builder.AddPlaceholderChunk("expression");
6671
Builder.AddChunk(CodeCompletionString::CK_RightParen);
6672
if (Results.includeCodePatterns()) {
6673
AddElseBodyPattern();
6674
}
6675
Results.AddResult(Builder.TakeString());
6676
6677
Results.ExitScope();
6678
6679
if (S->getFnParent())
6680
AddPrettyFunctionResults(getLangOpts(), Results);
6681
6682
if (CodeCompleter->includeMacros())
6683
AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
6684
6685
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6686
Results.getCompletionContext(), Results.data(),
6687
Results.size());
6688
}
6689
6690
void SemaCodeCompletion::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
6691
bool EnteringContext,
6692
bool IsUsingDeclaration,
6693
QualType BaseType,
6694
QualType PreferredType) {
6695
if (SS.isEmpty() || !CodeCompleter)
6696
return;
6697
6698
CodeCompletionContext CC(CodeCompletionContext::CCC_Symbol, PreferredType);
6699
CC.setIsUsingDeclaration(IsUsingDeclaration);
6700
CC.setCXXScopeSpecifier(SS);
6701
6702
// We want to keep the scope specifier even if it's invalid (e.g. the scope
6703
// "a::b::" is not corresponding to any context/namespace in the AST), since
6704
// it can be useful for global code completion which have information about
6705
// contexts/symbols that are not in the AST.
6706
if (SS.isInvalid()) {
6707
// As SS is invalid, we try to collect accessible contexts from the current
6708
// scope with a dummy lookup so that the completion consumer can try to
6709
// guess what the specified scope is.
6710
ResultBuilder DummyResults(SemaRef, CodeCompleter->getAllocator(),
6711
CodeCompleter->getCodeCompletionTUInfo(), CC);
6712
if (!PreferredType.isNull())
6713
DummyResults.setPreferredType(PreferredType);
6714
if (S->getEntity()) {
6715
CodeCompletionDeclConsumer Consumer(DummyResults, S->getEntity(),
6716
BaseType);
6717
SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
6718
/*IncludeGlobalScope=*/false,
6719
/*LoadExternal=*/false);
6720
}
6721
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6722
DummyResults.getCompletionContext(), nullptr, 0);
6723
return;
6724
}
6725
// Always pretend to enter a context to ensure that a dependent type
6726
// resolves to a dependent record.
6727
DeclContext *Ctx = SemaRef.computeDeclContext(SS, /*EnteringContext=*/true);
6728
6729
// Try to instantiate any non-dependent declaration contexts before
6730
// we look in them. Bail out if we fail.
6731
NestedNameSpecifier *NNS = SS.getScopeRep();
6732
if (NNS != nullptr && SS.isValid() && !NNS->isDependent()) {
6733
if (Ctx == nullptr || SemaRef.RequireCompleteDeclContext(SS, Ctx))
6734
return;
6735
}
6736
6737
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6738
CodeCompleter->getCodeCompletionTUInfo(), CC);
6739
if (!PreferredType.isNull())
6740
Results.setPreferredType(PreferredType);
6741
Results.EnterNewScope();
6742
6743
// The "template" keyword can follow "::" in the grammar, but only
6744
// put it into the grammar if the nested-name-specifier is dependent.
6745
// FIXME: results is always empty, this appears to be dead.
6746
if (!Results.empty() && NNS && NNS->isDependent())
6747
Results.AddResult("template");
6748
6749
// If the scope is a concept-constrained type parameter, infer nested
6750
// members based on the constraints.
6751
if (NNS) {
6752
if (const auto *TTPT =
6753
dyn_cast_or_null<TemplateTypeParmType>(NNS->getAsType())) {
6754
for (const auto &R : ConceptInfo(*TTPT, S).members()) {
6755
if (R.Operator != ConceptInfo::Member::Colons)
6756
continue;
6757
Results.AddResult(CodeCompletionResult(
6758
R.render(SemaRef, CodeCompleter->getAllocator(),
6759
CodeCompleter->getCodeCompletionTUInfo())));
6760
}
6761
}
6762
}
6763
6764
// Add calls to overridden virtual functions, if there are any.
6765
//
6766
// FIXME: This isn't wonderful, because we don't know whether we're actually
6767
// in a context that permits expressions. This is a general issue with
6768
// qualified-id completions.
6769
if (Ctx && !EnteringContext)
6770
MaybeAddOverrideCalls(SemaRef, Ctx, Results);
6771
Results.ExitScope();
6772
6773
if (Ctx &&
6774
(CodeCompleter->includeNamespaceLevelDecls() || !Ctx->isFileContext())) {
6775
CodeCompletionDeclConsumer Consumer(Results, Ctx, BaseType);
6776
SemaRef.LookupVisibleDecls(Ctx, Sema::LookupOrdinaryName, Consumer,
6777
/*IncludeGlobalScope=*/true,
6778
/*IncludeDependentBases=*/true,
6779
CodeCompleter->loadExternal());
6780
}
6781
6782
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6783
Results.getCompletionContext(), Results.data(),
6784
Results.size());
6785
}
6786
6787
void SemaCodeCompletion::CodeCompleteUsing(Scope *S) {
6788
if (!CodeCompleter)
6789
return;
6790
6791
// This can be both a using alias or using declaration, in the former we
6792
// expect a new name and a symbol in the latter case.
6793
CodeCompletionContext Context(CodeCompletionContext::CCC_SymbolOrNewName);
6794
Context.setIsUsingDeclaration(true);
6795
6796
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6797
CodeCompleter->getCodeCompletionTUInfo(), Context,
6798
&ResultBuilder::IsNestedNameSpecifier);
6799
Results.EnterNewScope();
6800
6801
// If we aren't in class scope, we could see the "namespace" keyword.
6802
if (!S->isClassScope())
6803
Results.AddResult(CodeCompletionResult("namespace"));
6804
6805
// After "using", we can see anything that would start a
6806
// nested-name-specifier.
6807
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
6808
SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
6809
CodeCompleter->includeGlobals(),
6810
CodeCompleter->loadExternal());
6811
Results.ExitScope();
6812
6813
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6814
Results.getCompletionContext(), Results.data(),
6815
Results.size());
6816
}
6817
6818
void SemaCodeCompletion::CodeCompleteUsingDirective(Scope *S) {
6819
if (!CodeCompleter)
6820
return;
6821
6822
// After "using namespace", we expect to see a namespace name or namespace
6823
// alias.
6824
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6825
CodeCompleter->getCodeCompletionTUInfo(),
6826
CodeCompletionContext::CCC_Namespace,
6827
&ResultBuilder::IsNamespaceOrAlias);
6828
Results.EnterNewScope();
6829
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
6830
SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
6831
CodeCompleter->includeGlobals(),
6832
CodeCompleter->loadExternal());
6833
Results.ExitScope();
6834
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6835
Results.getCompletionContext(), Results.data(),
6836
Results.size());
6837
}
6838
6839
void SemaCodeCompletion::CodeCompleteNamespaceDecl(Scope *S) {
6840
if (!CodeCompleter)
6841
return;
6842
6843
DeclContext *Ctx = S->getEntity();
6844
if (!S->getParent())
6845
Ctx = getASTContext().getTranslationUnitDecl();
6846
6847
bool SuppressedGlobalResults =
6848
Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx);
6849
6850
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6851
CodeCompleter->getCodeCompletionTUInfo(),
6852
SuppressedGlobalResults
6853
? CodeCompletionContext::CCC_Namespace
6854
: CodeCompletionContext::CCC_Other,
6855
&ResultBuilder::IsNamespace);
6856
6857
if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) {
6858
// We only want to see those namespaces that have already been defined
6859
// within this scope, because its likely that the user is creating an
6860
// extended namespace declaration. Keep track of the most recent
6861
// definition of each namespace.
6862
std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
6863
for (DeclContext::specific_decl_iterator<NamespaceDecl>
6864
NS(Ctx->decls_begin()),
6865
NSEnd(Ctx->decls_end());
6866
NS != NSEnd; ++NS)
6867
OrigToLatest[NS->getFirstDecl()] = *NS;
6868
6869
// Add the most recent definition (or extended definition) of each
6870
// namespace to the list of results.
6871
Results.EnterNewScope();
6872
for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
6873
NS = OrigToLatest.begin(),
6874
NSEnd = OrigToLatest.end();
6875
NS != NSEnd; ++NS)
6876
Results.AddResult(
6877
CodeCompletionResult(NS->second, Results.getBasePriority(NS->second),
6878
nullptr),
6879
SemaRef.CurContext, nullptr, false);
6880
Results.ExitScope();
6881
}
6882
6883
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6884
Results.getCompletionContext(), Results.data(),
6885
Results.size());
6886
}
6887
6888
void SemaCodeCompletion::CodeCompleteNamespaceAliasDecl(Scope *S) {
6889
if (!CodeCompleter)
6890
return;
6891
6892
// After "namespace", we expect to see a namespace or alias.
6893
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6894
CodeCompleter->getCodeCompletionTUInfo(),
6895
CodeCompletionContext::CCC_Namespace,
6896
&ResultBuilder::IsNamespaceOrAlias);
6897
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
6898
SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
6899
CodeCompleter->includeGlobals(),
6900
CodeCompleter->loadExternal());
6901
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6902
Results.getCompletionContext(), Results.data(),
6903
Results.size());
6904
}
6905
6906
void SemaCodeCompletion::CodeCompleteOperatorName(Scope *S) {
6907
if (!CodeCompleter)
6908
return;
6909
6910
typedef CodeCompletionResult Result;
6911
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6912
CodeCompleter->getCodeCompletionTUInfo(),
6913
CodeCompletionContext::CCC_Type,
6914
&ResultBuilder::IsType);
6915
Results.EnterNewScope();
6916
6917
// Add the names of overloadable operators. Note that OO_Conditional is not
6918
// actually overloadable.
6919
#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
6920
if (OO_##Name != OO_Conditional) \
6921
Results.AddResult(Result(Spelling));
6922
#include "clang/Basic/OperatorKinds.def"
6923
6924
// Add any type names visible from the current scope
6925
Results.allowNestedNameSpecifiers();
6926
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
6927
SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
6928
CodeCompleter->includeGlobals(),
6929
CodeCompleter->loadExternal());
6930
6931
// Add any type specifiers
6932
AddTypeSpecifierResults(getLangOpts(), Results);
6933
Results.ExitScope();
6934
6935
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6936
Results.getCompletionContext(), Results.data(),
6937
Results.size());
6938
}
6939
6940
void SemaCodeCompletion::CodeCompleteConstructorInitializer(
6941
Decl *ConstructorD, ArrayRef<CXXCtorInitializer *> Initializers) {
6942
if (!ConstructorD)
6943
return;
6944
6945
SemaRef.AdjustDeclIfTemplate(ConstructorD);
6946
6947
auto *Constructor = dyn_cast<CXXConstructorDecl>(ConstructorD);
6948
if (!Constructor)
6949
return;
6950
6951
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6952
CodeCompleter->getCodeCompletionTUInfo(),
6953
CodeCompletionContext::CCC_Symbol);
6954
Results.EnterNewScope();
6955
6956
// Fill in any already-initialized fields or base classes.
6957
llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
6958
llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
6959
for (unsigned I = 0, E = Initializers.size(); I != E; ++I) {
6960
if (Initializers[I]->isBaseInitializer())
6961
InitializedBases.insert(getASTContext().getCanonicalType(
6962
QualType(Initializers[I]->getBaseClass(), 0)));
6963
else
6964
InitializedFields.insert(
6965
cast<FieldDecl>(Initializers[I]->getAnyMember()));
6966
}
6967
6968
// Add completions for base classes.
6969
PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef);
6970
bool SawLastInitializer = Initializers.empty();
6971
CXXRecordDecl *ClassDecl = Constructor->getParent();
6972
6973
auto GenerateCCS = [&](const NamedDecl *ND, const char *Name) {
6974
CodeCompletionBuilder Builder(Results.getAllocator(),
6975
Results.getCodeCompletionTUInfo());
6976
Builder.AddTypedTextChunk(Name);
6977
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6978
if (const auto *Function = dyn_cast<FunctionDecl>(ND))
6979
AddFunctionParameterChunks(SemaRef.PP, Policy, Function, Builder);
6980
else if (const auto *FunTemplDecl = dyn_cast<FunctionTemplateDecl>(ND))
6981
AddFunctionParameterChunks(SemaRef.PP, Policy,
6982
FunTemplDecl->getTemplatedDecl(), Builder);
6983
Builder.AddChunk(CodeCompletionString::CK_RightParen);
6984
return Builder.TakeString();
6985
};
6986
auto AddDefaultCtorInit = [&](const char *Name, const char *Type,
6987
const NamedDecl *ND) {
6988
CodeCompletionBuilder Builder(Results.getAllocator(),
6989
Results.getCodeCompletionTUInfo());
6990
Builder.AddTypedTextChunk(Name);
6991
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6992
Builder.AddPlaceholderChunk(Type);
6993
Builder.AddChunk(CodeCompletionString::CK_RightParen);
6994
if (ND) {
6995
auto CCR = CodeCompletionResult(
6996
Builder.TakeString(), ND,
6997
SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration);
6998
if (isa<FieldDecl>(ND))
6999
CCR.CursorKind = CXCursor_MemberRef;
7000
return Results.AddResult(CCR);
7001
}
7002
return Results.AddResult(CodeCompletionResult(
7003
Builder.TakeString(),
7004
SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration));
7005
};
7006
auto AddCtorsWithName = [&](const CXXRecordDecl *RD, unsigned int Priority,
7007
const char *Name, const FieldDecl *FD) {
7008
if (!RD)
7009
return AddDefaultCtorInit(Name,
7010
FD ? Results.getAllocator().CopyString(
7011
FD->getType().getAsString(Policy))
7012
: Name,
7013
FD);
7014
auto Ctors = getConstructors(getASTContext(), RD);
7015
if (Ctors.begin() == Ctors.end())
7016
return AddDefaultCtorInit(Name, Name, RD);
7017
for (const NamedDecl *Ctor : Ctors) {
7018
auto CCR = CodeCompletionResult(GenerateCCS(Ctor, Name), RD, Priority);
7019
CCR.CursorKind = getCursorKindForDecl(Ctor);
7020
Results.AddResult(CCR);
7021
}
7022
};
7023
auto AddBase = [&](const CXXBaseSpecifier &Base) {
7024
const char *BaseName =
7025
Results.getAllocator().CopyString(Base.getType().getAsString(Policy));
7026
const auto *RD = Base.getType()->getAsCXXRecordDecl();
7027
AddCtorsWithName(
7028
RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration,
7029
BaseName, nullptr);
7030
};
7031
auto AddField = [&](const FieldDecl *FD) {
7032
const char *FieldName =
7033
Results.getAllocator().CopyString(FD->getIdentifier()->getName());
7034
const CXXRecordDecl *RD = FD->getType()->getAsCXXRecordDecl();
7035
AddCtorsWithName(
7036
RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration,
7037
FieldName, FD);
7038
};
7039
7040
for (const auto &Base : ClassDecl->bases()) {
7041
if (!InitializedBases
7042
.insert(getASTContext().getCanonicalType(Base.getType()))
7043
.second) {
7044
SawLastInitializer =
7045
!Initializers.empty() && Initializers.back()->isBaseInitializer() &&
7046
getASTContext().hasSameUnqualifiedType(
7047
Base.getType(), QualType(Initializers.back()->getBaseClass(), 0));
7048
continue;
7049
}
7050
7051
AddBase(Base);
7052
SawLastInitializer = false;
7053
}
7054
7055
// Add completions for virtual base classes.
7056
for (const auto &Base : ClassDecl->vbases()) {
7057
if (!InitializedBases
7058
.insert(getASTContext().getCanonicalType(Base.getType()))
7059
.second) {
7060
SawLastInitializer =
7061
!Initializers.empty() && Initializers.back()->isBaseInitializer() &&
7062
getASTContext().hasSameUnqualifiedType(
7063
Base.getType(), QualType(Initializers.back()->getBaseClass(), 0));
7064
continue;
7065
}
7066
7067
AddBase(Base);
7068
SawLastInitializer = false;
7069
}
7070
7071
// Add completions for members.
7072
for (auto *Field : ClassDecl->fields()) {
7073
if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))
7074
.second) {
7075
SawLastInitializer = !Initializers.empty() &&
7076
Initializers.back()->isAnyMemberInitializer() &&
7077
Initializers.back()->getAnyMember() == Field;
7078
continue;
7079
}
7080
7081
if (!Field->getDeclName())
7082
continue;
7083
7084
AddField(Field);
7085
SawLastInitializer = false;
7086
}
7087
Results.ExitScope();
7088
7089
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7090
Results.getCompletionContext(), Results.data(),
7091
Results.size());
7092
}
7093
7094
/// Determine whether this scope denotes a namespace.
7095
static bool isNamespaceScope(Scope *S) {
7096
DeclContext *DC = S->getEntity();
7097
if (!DC)
7098
return false;
7099
7100
return DC->isFileContext();
7101
}
7102
7103
void SemaCodeCompletion::CodeCompleteLambdaIntroducer(Scope *S,
7104
LambdaIntroducer &Intro,
7105
bool AfterAmpersand) {
7106
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7107
CodeCompleter->getCodeCompletionTUInfo(),
7108
CodeCompletionContext::CCC_Other);
7109
Results.EnterNewScope();
7110
7111
// Note what has already been captured.
7112
llvm::SmallPtrSet<IdentifierInfo *, 4> Known;
7113
bool IncludedThis = false;
7114
for (const auto &C : Intro.Captures) {
7115
if (C.Kind == LCK_This) {
7116
IncludedThis = true;
7117
continue;
7118
}
7119
7120
Known.insert(C.Id);
7121
}
7122
7123
// Look for other capturable variables.
7124
for (; S && !isNamespaceScope(S); S = S->getParent()) {
7125
for (const auto *D : S->decls()) {
7126
const auto *Var = dyn_cast<VarDecl>(D);
7127
if (!Var || !Var->hasLocalStorage() || Var->hasAttr<BlocksAttr>())
7128
continue;
7129
7130
if (Known.insert(Var->getIdentifier()).second)
7131
Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration),
7132
SemaRef.CurContext, nullptr, false);
7133
}
7134
}
7135
7136
// Add 'this', if it would be valid.
7137
if (!IncludedThis && !AfterAmpersand && Intro.Default != LCD_ByCopy)
7138
addThisCompletion(SemaRef, Results);
7139
7140
Results.ExitScope();
7141
7142
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7143
Results.getCompletionContext(), Results.data(),
7144
Results.size());
7145
}
7146
7147
void SemaCodeCompletion::CodeCompleteAfterFunctionEquals(Declarator &D) {
7148
if (!getLangOpts().CPlusPlus11)
7149
return;
7150
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7151
CodeCompleter->getCodeCompletionTUInfo(),
7152
CodeCompletionContext::CCC_Other);
7153
auto ShouldAddDefault = [&D, this]() {
7154
if (!D.isFunctionDeclarator())
7155
return false;
7156
auto &Id = D.getName();
7157
if (Id.getKind() == UnqualifiedIdKind::IK_DestructorName)
7158
return true;
7159
// FIXME(liuhui): Ideally, we should check the constructor parameter list to
7160
// verify that it is the default, copy or move constructor?
7161
if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName &&
7162
D.getFunctionTypeInfo().NumParams <= 1)
7163
return true;
7164
if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId) {
7165
auto Op = Id.OperatorFunctionId.Operator;
7166
// FIXME(liuhui): Ideally, we should check the function parameter list to
7167
// verify that it is the copy or move assignment?
7168
if (Op == OverloadedOperatorKind::OO_Equal)
7169
return true;
7170
if (getLangOpts().CPlusPlus20 &&
7171
(Op == OverloadedOperatorKind::OO_EqualEqual ||
7172
Op == OverloadedOperatorKind::OO_ExclaimEqual ||
7173
Op == OverloadedOperatorKind::OO_Less ||
7174
Op == OverloadedOperatorKind::OO_LessEqual ||
7175
Op == OverloadedOperatorKind::OO_Greater ||
7176
Op == OverloadedOperatorKind::OO_GreaterEqual ||
7177
Op == OverloadedOperatorKind::OO_Spaceship))
7178
return true;
7179
}
7180
return false;
7181
};
7182
7183
Results.EnterNewScope();
7184
if (ShouldAddDefault())
7185
Results.AddResult("default");
7186
// FIXME(liuhui): Ideally, we should only provide `delete` completion for the
7187
// first function declaration.
7188
Results.AddResult("delete");
7189
Results.ExitScope();
7190
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7191
Results.getCompletionContext(), Results.data(),
7192
Results.size());
7193
}
7194
7195
/// Macro that optionally prepends an "@" to the string literal passed in via
7196
/// Keyword, depending on whether NeedAt is true or false.
7197
#define OBJC_AT_KEYWORD_NAME(NeedAt, Keyword) ((NeedAt) ? "@" Keyword : Keyword)
7198
7199
static void AddObjCImplementationResults(const LangOptions &LangOpts,
7200
ResultBuilder &Results, bool NeedAt) {
7201
typedef CodeCompletionResult Result;
7202
// Since we have an implementation, we can end it.
7203
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end")));
7204
7205
CodeCompletionBuilder Builder(Results.getAllocator(),
7206
Results.getCodeCompletionTUInfo());
7207
if (LangOpts.ObjC) {
7208
// @dynamic
7209
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "dynamic"));
7210
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7211
Builder.AddPlaceholderChunk("property");
7212
Results.AddResult(Result(Builder.TakeString()));
7213
7214
// @synthesize
7215
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synthesize"));
7216
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7217
Builder.AddPlaceholderChunk("property");
7218
Results.AddResult(Result(Builder.TakeString()));
7219
}
7220
}
7221
7222
static void AddObjCInterfaceResults(const LangOptions &LangOpts,
7223
ResultBuilder &Results, bool NeedAt) {
7224
typedef CodeCompletionResult Result;
7225
7226
// Since we have an interface or protocol, we can end it.
7227
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end")));
7228
7229
if (LangOpts.ObjC) {
7230
// @property
7231
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "property")));
7232
7233
// @required
7234
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "required")));
7235
7236
// @optional
7237
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "optional")));
7238
}
7239
}
7240
7241
static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
7242
typedef CodeCompletionResult Result;
7243
CodeCompletionBuilder Builder(Results.getAllocator(),
7244
Results.getCodeCompletionTUInfo());
7245
7246
// @class name ;
7247
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "class"));
7248
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7249
Builder.AddPlaceholderChunk("name");
7250
Results.AddResult(Result(Builder.TakeString()));
7251
7252
if (Results.includeCodePatterns()) {
7253
// @interface name
7254
// FIXME: Could introduce the whole pattern, including superclasses and
7255
// such.
7256
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "interface"));
7257
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7258
Builder.AddPlaceholderChunk("class");
7259
Results.AddResult(Result(Builder.TakeString()));
7260
7261
// @protocol name
7262
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol"));
7263
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7264
Builder.AddPlaceholderChunk("protocol");
7265
Results.AddResult(Result(Builder.TakeString()));
7266
7267
// @implementation name
7268
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "implementation"));
7269
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7270
Builder.AddPlaceholderChunk("class");
7271
Results.AddResult(Result(Builder.TakeString()));
7272
}
7273
7274
// @compatibility_alias name
7275
Builder.AddTypedTextChunk(
7276
OBJC_AT_KEYWORD_NAME(NeedAt, "compatibility_alias"));
7277
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7278
Builder.AddPlaceholderChunk("alias");
7279
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7280
Builder.AddPlaceholderChunk("class");
7281
Results.AddResult(Result(Builder.TakeString()));
7282
7283
if (Results.getSema().getLangOpts().Modules) {
7284
// @import name
7285
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "import"));
7286
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7287
Builder.AddPlaceholderChunk("module");
7288
Results.AddResult(Result(Builder.TakeString()));
7289
}
7290
}
7291
7292
void SemaCodeCompletion::CodeCompleteObjCAtDirective(Scope *S) {
7293
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7294
CodeCompleter->getCodeCompletionTUInfo(),
7295
CodeCompletionContext::CCC_Other);
7296
Results.EnterNewScope();
7297
if (isa<ObjCImplDecl>(SemaRef.CurContext))
7298
AddObjCImplementationResults(getLangOpts(), Results, false);
7299
else if (SemaRef.CurContext->isObjCContainer())
7300
AddObjCInterfaceResults(getLangOpts(), Results, false);
7301
else
7302
AddObjCTopLevelResults(Results, false);
7303
Results.ExitScope();
7304
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7305
Results.getCompletionContext(), Results.data(),
7306
Results.size());
7307
}
7308
7309
static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
7310
typedef CodeCompletionResult Result;
7311
CodeCompletionBuilder Builder(Results.getAllocator(),
7312
Results.getCodeCompletionTUInfo());
7313
7314
// @encode ( type-name )
7315
const char *EncodeType = "char[]";
7316
if (Results.getSema().getLangOpts().CPlusPlus ||
7317
Results.getSema().getLangOpts().ConstStrings)
7318
EncodeType = "const char[]";
7319
Builder.AddResultTypeChunk(EncodeType);
7320
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "encode"));
7321
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7322
Builder.AddPlaceholderChunk("type-name");
7323
Builder.AddChunk(CodeCompletionString::CK_RightParen);
7324
Results.AddResult(Result(Builder.TakeString()));
7325
7326
// @protocol ( protocol-name )
7327
Builder.AddResultTypeChunk("Protocol *");
7328
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol"));
7329
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7330
Builder.AddPlaceholderChunk("protocol-name");
7331
Builder.AddChunk(CodeCompletionString::CK_RightParen);
7332
Results.AddResult(Result(Builder.TakeString()));
7333
7334
// @selector ( selector )
7335
Builder.AddResultTypeChunk("SEL");
7336
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "selector"));
7337
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7338
Builder.AddPlaceholderChunk("selector");
7339
Builder.AddChunk(CodeCompletionString::CK_RightParen);
7340
Results.AddResult(Result(Builder.TakeString()));
7341
7342
// @"string"
7343
Builder.AddResultTypeChunk("NSString *");
7344
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "\""));
7345
Builder.AddPlaceholderChunk("string");
7346
Builder.AddTextChunk("\"");
7347
Results.AddResult(Result(Builder.TakeString()));
7348
7349
// @[objects, ...]
7350
Builder.AddResultTypeChunk("NSArray *");
7351
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "["));
7352
Builder.AddPlaceholderChunk("objects, ...");
7353
Builder.AddChunk(CodeCompletionString::CK_RightBracket);
7354
Results.AddResult(Result(Builder.TakeString()));
7355
7356
// @{key : object, ...}
7357
Builder.AddResultTypeChunk("NSDictionary *");
7358
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "{"));
7359
Builder.AddPlaceholderChunk("key");
7360
Builder.AddChunk(CodeCompletionString::CK_Colon);
7361
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7362
Builder.AddPlaceholderChunk("object, ...");
7363
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7364
Results.AddResult(Result(Builder.TakeString()));
7365
7366
// @(expression)
7367
Builder.AddResultTypeChunk("id");
7368
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "("));
7369
Builder.AddPlaceholderChunk("expression");
7370
Builder.AddChunk(CodeCompletionString::CK_RightParen);
7371
Results.AddResult(Result(Builder.TakeString()));
7372
}
7373
7374
static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
7375
typedef CodeCompletionResult Result;
7376
CodeCompletionBuilder Builder(Results.getAllocator(),
7377
Results.getCodeCompletionTUInfo());
7378
7379
if (Results.includeCodePatterns()) {
7380
// @try { statements } @catch ( declaration ) { statements } @finally
7381
// { statements }
7382
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "try"));
7383
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7384
Builder.AddPlaceholderChunk("statements");
7385
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7386
Builder.AddTextChunk("@catch");
7387
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7388
Builder.AddPlaceholderChunk("parameter");
7389
Builder.AddChunk(CodeCompletionString::CK_RightParen);
7390
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7391
Builder.AddPlaceholderChunk("statements");
7392
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7393
Builder.AddTextChunk("@finally");
7394
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7395
Builder.AddPlaceholderChunk("statements");
7396
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7397
Results.AddResult(Result(Builder.TakeString()));
7398
}
7399
7400
// @throw
7401
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "throw"));
7402
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7403
Builder.AddPlaceholderChunk("expression");
7404
Results.AddResult(Result(Builder.TakeString()));
7405
7406
if (Results.includeCodePatterns()) {
7407
// @synchronized ( expression ) { statements }
7408
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synchronized"));
7409
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
7410
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7411
Builder.AddPlaceholderChunk("expression");
7412
Builder.AddChunk(CodeCompletionString::CK_RightParen);
7413
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
7414
Builder.AddPlaceholderChunk("statements");
7415
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
7416
Results.AddResult(Result(Builder.TakeString()));
7417
}
7418
}
7419
7420
static void AddObjCVisibilityResults(const LangOptions &LangOpts,
7421
ResultBuilder &Results, bool NeedAt) {
7422
typedef CodeCompletionResult Result;
7423
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "private")));
7424
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "protected")));
7425
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "public")));
7426
if (LangOpts.ObjC)
7427
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "package")));
7428
}
7429
7430
void SemaCodeCompletion::CodeCompleteObjCAtVisibility(Scope *S) {
7431
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7432
CodeCompleter->getCodeCompletionTUInfo(),
7433
CodeCompletionContext::CCC_Other);
7434
Results.EnterNewScope();
7435
AddObjCVisibilityResults(getLangOpts(), Results, false);
7436
Results.ExitScope();
7437
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7438
Results.getCompletionContext(), Results.data(),
7439
Results.size());
7440
}
7441
7442
void SemaCodeCompletion::CodeCompleteObjCAtStatement(Scope *S) {
7443
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7444
CodeCompleter->getCodeCompletionTUInfo(),
7445
CodeCompletionContext::CCC_Other);
7446
Results.EnterNewScope();
7447
AddObjCStatementResults(Results, false);
7448
AddObjCExpressionResults(Results, false);
7449
Results.ExitScope();
7450
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7451
Results.getCompletionContext(), Results.data(),
7452
Results.size());
7453
}
7454
7455
void SemaCodeCompletion::CodeCompleteObjCAtExpression(Scope *S) {
7456
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7457
CodeCompleter->getCodeCompletionTUInfo(),
7458
CodeCompletionContext::CCC_Other);
7459
Results.EnterNewScope();
7460
AddObjCExpressionResults(Results, false);
7461
Results.ExitScope();
7462
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7463
Results.getCompletionContext(), Results.data(),
7464
Results.size());
7465
}
7466
7467
/// Determine whether the addition of the given flag to an Objective-C
7468
/// property's attributes will cause a conflict.
7469
static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
7470
// Check if we've already added this flag.
7471
if (Attributes & NewFlag)
7472
return true;
7473
7474
Attributes |= NewFlag;
7475
7476
// Check for collisions with "readonly".
7477
if ((Attributes & ObjCPropertyAttribute::kind_readonly) &&
7478
(Attributes & ObjCPropertyAttribute::kind_readwrite))
7479
return true;
7480
7481
// Check for more than one of { assign, copy, retain, strong, weak }.
7482
unsigned AssignCopyRetMask =
7483
Attributes &
7484
(ObjCPropertyAttribute::kind_assign |
7485
ObjCPropertyAttribute::kind_unsafe_unretained |
7486
ObjCPropertyAttribute::kind_copy | ObjCPropertyAttribute::kind_retain |
7487
ObjCPropertyAttribute::kind_strong | ObjCPropertyAttribute::kind_weak);
7488
if (AssignCopyRetMask &&
7489
AssignCopyRetMask != ObjCPropertyAttribute::kind_assign &&
7490
AssignCopyRetMask != ObjCPropertyAttribute::kind_unsafe_unretained &&
7491
AssignCopyRetMask != ObjCPropertyAttribute::kind_copy &&
7492
AssignCopyRetMask != ObjCPropertyAttribute::kind_retain &&
7493
AssignCopyRetMask != ObjCPropertyAttribute::kind_strong &&
7494
AssignCopyRetMask != ObjCPropertyAttribute::kind_weak)
7495
return true;
7496
7497
return false;
7498
}
7499
7500
void SemaCodeCompletion::CodeCompleteObjCPropertyFlags(Scope *S,
7501
ObjCDeclSpec &ODS) {
7502
if (!CodeCompleter)
7503
return;
7504
7505
unsigned Attributes = ODS.getPropertyAttributes();
7506
7507
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7508
CodeCompleter->getCodeCompletionTUInfo(),
7509
CodeCompletionContext::CCC_Other);
7510
Results.EnterNewScope();
7511
if (!ObjCPropertyFlagConflicts(Attributes,
7512
ObjCPropertyAttribute::kind_readonly))
7513
Results.AddResult(CodeCompletionResult("readonly"));
7514
if (!ObjCPropertyFlagConflicts(Attributes,
7515
ObjCPropertyAttribute::kind_assign))
7516
Results.AddResult(CodeCompletionResult("assign"));
7517
if (!ObjCPropertyFlagConflicts(Attributes,
7518
ObjCPropertyAttribute::kind_unsafe_unretained))
7519
Results.AddResult(CodeCompletionResult("unsafe_unretained"));
7520
if (!ObjCPropertyFlagConflicts(Attributes,
7521
ObjCPropertyAttribute::kind_readwrite))
7522
Results.AddResult(CodeCompletionResult("readwrite"));
7523
if (!ObjCPropertyFlagConflicts(Attributes,
7524
ObjCPropertyAttribute::kind_retain))
7525
Results.AddResult(CodeCompletionResult("retain"));
7526
if (!ObjCPropertyFlagConflicts(Attributes,
7527
ObjCPropertyAttribute::kind_strong))
7528
Results.AddResult(CodeCompletionResult("strong"));
7529
if (!ObjCPropertyFlagConflicts(Attributes, ObjCPropertyAttribute::kind_copy))
7530
Results.AddResult(CodeCompletionResult("copy"));
7531
if (!ObjCPropertyFlagConflicts(Attributes,
7532
ObjCPropertyAttribute::kind_nonatomic))
7533
Results.AddResult(CodeCompletionResult("nonatomic"));
7534
if (!ObjCPropertyFlagConflicts(Attributes,
7535
ObjCPropertyAttribute::kind_atomic))
7536
Results.AddResult(CodeCompletionResult("atomic"));
7537
7538
// Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
7539
if (getLangOpts().ObjCWeak || getLangOpts().getGC() != LangOptions::NonGC)
7540
if (!ObjCPropertyFlagConflicts(Attributes,
7541
ObjCPropertyAttribute::kind_weak))
7542
Results.AddResult(CodeCompletionResult("weak"));
7543
7544
if (!ObjCPropertyFlagConflicts(Attributes,
7545
ObjCPropertyAttribute::kind_setter)) {
7546
CodeCompletionBuilder Setter(Results.getAllocator(),
7547
Results.getCodeCompletionTUInfo());
7548
Setter.AddTypedTextChunk("setter");
7549
Setter.AddTextChunk("=");
7550
Setter.AddPlaceholderChunk("method");
7551
Results.AddResult(CodeCompletionResult(Setter.TakeString()));
7552
}
7553
if (!ObjCPropertyFlagConflicts(Attributes,
7554
ObjCPropertyAttribute::kind_getter)) {
7555
CodeCompletionBuilder Getter(Results.getAllocator(),
7556
Results.getCodeCompletionTUInfo());
7557
Getter.AddTypedTextChunk("getter");
7558
Getter.AddTextChunk("=");
7559
Getter.AddPlaceholderChunk("method");
7560
Results.AddResult(CodeCompletionResult(Getter.TakeString()));
7561
}
7562
if (!ObjCPropertyFlagConflicts(Attributes,
7563
ObjCPropertyAttribute::kind_nullability)) {
7564
Results.AddResult(CodeCompletionResult("nonnull"));
7565
Results.AddResult(CodeCompletionResult("nullable"));
7566
Results.AddResult(CodeCompletionResult("null_unspecified"));
7567
Results.AddResult(CodeCompletionResult("null_resettable"));
7568
}
7569
Results.ExitScope();
7570
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7571
Results.getCompletionContext(), Results.data(),
7572
Results.size());
7573
}
7574
7575
/// Describes the kind of Objective-C method that we want to find
7576
/// via code completion.
7577
enum ObjCMethodKind {
7578
MK_Any, ///< Any kind of method, provided it means other specified criteria.
7579
MK_ZeroArgSelector, ///< Zero-argument (unary) selector.
7580
MK_OneArgSelector ///< One-argument selector.
7581
};
7582
7583
static bool isAcceptableObjCSelector(Selector Sel, ObjCMethodKind WantKind,
7584
ArrayRef<const IdentifierInfo *> SelIdents,
7585
bool AllowSameLength = true) {
7586
unsigned NumSelIdents = SelIdents.size();
7587
if (NumSelIdents > Sel.getNumArgs())
7588
return false;
7589
7590
switch (WantKind) {
7591
case MK_Any:
7592
break;
7593
case MK_ZeroArgSelector:
7594
return Sel.isUnarySelector();
7595
case MK_OneArgSelector:
7596
return Sel.getNumArgs() == 1;
7597
}
7598
7599
if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs())
7600
return false;
7601
7602
for (unsigned I = 0; I != NumSelIdents; ++I)
7603
if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
7604
return false;
7605
7606
return true;
7607
}
7608
7609
static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
7610
ObjCMethodKind WantKind,
7611
ArrayRef<const IdentifierInfo *> SelIdents,
7612
bool AllowSameLength = true) {
7613
return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
7614
AllowSameLength);
7615
}
7616
7617
/// A set of selectors, which is used to avoid introducing multiple
7618
/// completions with the same selector into the result set.
7619
typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet;
7620
7621
/// Add all of the Objective-C methods in the given Objective-C
7622
/// container to the set of results.
7623
///
7624
/// The container will be a class, protocol, category, or implementation of
7625
/// any of the above. This mether will recurse to include methods from
7626
/// the superclasses of classes along with their categories, protocols, and
7627
/// implementations.
7628
///
7629
/// \param Container the container in which we'll look to find methods.
7630
///
7631
/// \param WantInstanceMethods Whether to add instance methods (only); if
7632
/// false, this routine will add factory methods (only).
7633
///
7634
/// \param CurContext the context in which we're performing the lookup that
7635
/// finds methods.
7636
///
7637
/// \param AllowSameLength Whether we allow a method to be added to the list
7638
/// when it has the same number of parameters as we have selector identifiers.
7639
///
7640
/// \param Results the structure into which we'll add results.
7641
static void AddObjCMethods(ObjCContainerDecl *Container,
7642
bool WantInstanceMethods, ObjCMethodKind WantKind,
7643
ArrayRef<const IdentifierInfo *> SelIdents,
7644
DeclContext *CurContext,
7645
VisitedSelectorSet &Selectors, bool AllowSameLength,
7646
ResultBuilder &Results, bool InOriginalClass = true,
7647
bool IsRootClass = false) {
7648
typedef CodeCompletionResult Result;
7649
Container = getContainerDef(Container);
7650
ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
7651
IsRootClass = IsRootClass || (IFace && !IFace->getSuperClass());
7652
for (ObjCMethodDecl *M : Container->methods()) {
7653
// The instance methods on the root class can be messaged via the
7654
// metaclass.
7655
if (M->isInstanceMethod() == WantInstanceMethods ||
7656
(IsRootClass && !WantInstanceMethods)) {
7657
// Check whether the selector identifiers we've been given are a
7658
// subset of the identifiers for this particular method.
7659
if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength))
7660
continue;
7661
7662
if (!Selectors.insert(M->getSelector()).second)
7663
continue;
7664
7665
Result R = Result(M, Results.getBasePriority(M), nullptr);
7666
R.StartParameter = SelIdents.size();
7667
R.AllParametersAreInformative = (WantKind != MK_Any);
7668
if (!InOriginalClass)
7669
setInBaseClass(R);
7670
Results.MaybeAddResult(R, CurContext);
7671
}
7672
}
7673
7674
// Visit the protocols of protocols.
7675
if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
7676
if (Protocol->hasDefinition()) {
7677
const ObjCList<ObjCProtocolDecl> &Protocols =
7678
Protocol->getReferencedProtocols();
7679
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
7680
E = Protocols.end();
7681
I != E; ++I)
7682
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
7683
Selectors, AllowSameLength, Results, false, IsRootClass);
7684
}
7685
}
7686
7687
if (!IFace || !IFace->hasDefinition())
7688
return;
7689
7690
// Add methods in protocols.
7691
for (ObjCProtocolDecl *I : IFace->protocols())
7692
AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, CurContext,
7693
Selectors, AllowSameLength, Results, false, IsRootClass);
7694
7695
// Add methods in categories.
7696
for (ObjCCategoryDecl *CatDecl : IFace->known_categories()) {
7697
AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
7698
CurContext, Selectors, AllowSameLength, Results,
7699
InOriginalClass, IsRootClass);
7700
7701
// Add a categories protocol methods.
7702
const ObjCList<ObjCProtocolDecl> &Protocols =
7703
CatDecl->getReferencedProtocols();
7704
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
7705
E = Protocols.end();
7706
I != E; ++I)
7707
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
7708
Selectors, AllowSameLength, Results, false, IsRootClass);
7709
7710
// Add methods in category implementations.
7711
if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
7712
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
7713
Selectors, AllowSameLength, Results, InOriginalClass,
7714
IsRootClass);
7715
}
7716
7717
// Add methods in superclass.
7718
// Avoid passing in IsRootClass since root classes won't have super classes.
7719
if (IFace->getSuperClass())
7720
AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
7721
SelIdents, CurContext, Selectors, AllowSameLength, Results,
7722
/*IsRootClass=*/false);
7723
7724
// Add methods in our implementation, if any.
7725
if (ObjCImplementationDecl *Impl = IFace->getImplementation())
7726
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
7727
Selectors, AllowSameLength, Results, InOriginalClass,
7728
IsRootClass);
7729
}
7730
7731
void SemaCodeCompletion::CodeCompleteObjCPropertyGetter(Scope *S) {
7732
// Try to find the interface where getters might live.
7733
ObjCInterfaceDecl *Class =
7734
dyn_cast_or_null<ObjCInterfaceDecl>(SemaRef.CurContext);
7735
if (!Class) {
7736
if (ObjCCategoryDecl *Category =
7737
dyn_cast_or_null<ObjCCategoryDecl>(SemaRef.CurContext))
7738
Class = Category->getClassInterface();
7739
7740
if (!Class)
7741
return;
7742
}
7743
7744
// Find all of the potential getters.
7745
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7746
CodeCompleter->getCodeCompletionTUInfo(),
7747
CodeCompletionContext::CCC_Other);
7748
Results.EnterNewScope();
7749
7750
VisitedSelectorSet Selectors;
7751
AddObjCMethods(Class, true, MK_ZeroArgSelector, std::nullopt,
7752
SemaRef.CurContext, Selectors,
7753
/*AllowSameLength=*/true, Results);
7754
Results.ExitScope();
7755
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7756
Results.getCompletionContext(), Results.data(),
7757
Results.size());
7758
}
7759
7760
void SemaCodeCompletion::CodeCompleteObjCPropertySetter(Scope *S) {
7761
// Try to find the interface where setters might live.
7762
ObjCInterfaceDecl *Class =
7763
dyn_cast_or_null<ObjCInterfaceDecl>(SemaRef.CurContext);
7764
if (!Class) {
7765
if (ObjCCategoryDecl *Category =
7766
dyn_cast_or_null<ObjCCategoryDecl>(SemaRef.CurContext))
7767
Class = Category->getClassInterface();
7768
7769
if (!Class)
7770
return;
7771
}
7772
7773
// Find all of the potential getters.
7774
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7775
CodeCompleter->getCodeCompletionTUInfo(),
7776
CodeCompletionContext::CCC_Other);
7777
Results.EnterNewScope();
7778
7779
VisitedSelectorSet Selectors;
7780
AddObjCMethods(Class, true, MK_OneArgSelector, std::nullopt,
7781
SemaRef.CurContext, Selectors,
7782
/*AllowSameLength=*/true, Results);
7783
7784
Results.ExitScope();
7785
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7786
Results.getCompletionContext(), Results.data(),
7787
Results.size());
7788
}
7789
7790
void SemaCodeCompletion::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
7791
bool IsParameter) {
7792
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
7793
CodeCompleter->getCodeCompletionTUInfo(),
7794
CodeCompletionContext::CCC_Type);
7795
Results.EnterNewScope();
7796
7797
// Add context-sensitive, Objective-C parameter-passing keywords.
7798
bool AddedInOut = false;
7799
if ((DS.getObjCDeclQualifier() &
7800
(ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
7801
Results.AddResult("in");
7802
Results.AddResult("inout");
7803
AddedInOut = true;
7804
}
7805
if ((DS.getObjCDeclQualifier() &
7806
(ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
7807
Results.AddResult("out");
7808
if (!AddedInOut)
7809
Results.AddResult("inout");
7810
}
7811
if ((DS.getObjCDeclQualifier() &
7812
(ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
7813
ObjCDeclSpec::DQ_Oneway)) == 0) {
7814
Results.AddResult("bycopy");
7815
Results.AddResult("byref");
7816
Results.AddResult("oneway");
7817
}
7818
if ((DS.getObjCDeclQualifier() & ObjCDeclSpec::DQ_CSNullability) == 0) {
7819
Results.AddResult("nonnull");
7820
Results.AddResult("nullable");
7821
Results.AddResult("null_unspecified");
7822
}
7823
7824
// If we're completing the return type of an Objective-C method and the
7825
// identifier IBAction refers to a macro, provide a completion item for
7826
// an action, e.g.,
7827
// IBAction)<#selector#>:(id)sender
7828
if (DS.getObjCDeclQualifier() == 0 && !IsParameter &&
7829
SemaRef.PP.isMacroDefined("IBAction")) {
7830
CodeCompletionBuilder Builder(Results.getAllocator(),
7831
Results.getCodeCompletionTUInfo(),
7832
CCP_CodePattern, CXAvailability_Available);
7833
Builder.AddTypedTextChunk("IBAction");
7834
Builder.AddChunk(CodeCompletionString::CK_RightParen);
7835
Builder.AddPlaceholderChunk("selector");
7836
Builder.AddChunk(CodeCompletionString::CK_Colon);
7837
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
7838
Builder.AddTextChunk("id");
7839
Builder.AddChunk(CodeCompletionString::CK_RightParen);
7840
Builder.AddTextChunk("sender");
7841
Results.AddResult(CodeCompletionResult(Builder.TakeString()));
7842
}
7843
7844
// If we're completing the return type, provide 'instancetype'.
7845
if (!IsParameter) {
7846
Results.AddResult(CodeCompletionResult("instancetype"));
7847
}
7848
7849
// Add various builtin type names and specifiers.
7850
AddOrdinaryNameResults(PCC_Type, S, SemaRef, Results);
7851
Results.ExitScope();
7852
7853
// Add the various type names
7854
Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
7855
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
7856
SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
7857
CodeCompleter->includeGlobals(),
7858
CodeCompleter->loadExternal());
7859
7860
if (CodeCompleter->includeMacros())
7861
AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
7862
7863
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
7864
Results.getCompletionContext(), Results.data(),
7865
Results.size());
7866
}
7867
7868
/// When we have an expression with type "id", we may assume
7869
/// that it has some more-specific class type based on knowledge of
7870
/// common uses of Objective-C. This routine returns that class type,
7871
/// or NULL if no better result could be determined.
7872
static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
7873
auto *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
7874
if (!Msg)
7875
return nullptr;
7876
7877
Selector Sel = Msg->getSelector();
7878
if (Sel.isNull())
7879
return nullptr;
7880
7881
const IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
7882
if (!Id)
7883
return nullptr;
7884
7885
ObjCMethodDecl *Method = Msg->getMethodDecl();
7886
if (!Method)
7887
return nullptr;
7888
7889
// Determine the class that we're sending the message to.
7890
ObjCInterfaceDecl *IFace = nullptr;
7891
switch (Msg->getReceiverKind()) {
7892
case ObjCMessageExpr::Class:
7893
if (const ObjCObjectType *ObjType =
7894
Msg->getClassReceiver()->getAs<ObjCObjectType>())
7895
IFace = ObjType->getInterface();
7896
break;
7897
7898
case ObjCMessageExpr::Instance: {
7899
QualType T = Msg->getInstanceReceiver()->getType();
7900
if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
7901
IFace = Ptr->getInterfaceDecl();
7902
break;
7903
}
7904
7905
case ObjCMessageExpr::SuperInstance:
7906
case ObjCMessageExpr::SuperClass:
7907
break;
7908
}
7909
7910
if (!IFace)
7911
return nullptr;
7912
7913
ObjCInterfaceDecl *Super = IFace->getSuperClass();
7914
if (Method->isInstanceMethod())
7915
return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
7916
.Case("retain", IFace)
7917
.Case("strong", IFace)
7918
.Case("autorelease", IFace)
7919
.Case("copy", IFace)
7920
.Case("copyWithZone", IFace)
7921
.Case("mutableCopy", IFace)
7922
.Case("mutableCopyWithZone", IFace)
7923
.Case("awakeFromCoder", IFace)
7924
.Case("replacementObjectFromCoder", IFace)
7925
.Case("class", IFace)
7926
.Case("classForCoder", IFace)
7927
.Case("superclass", Super)
7928
.Default(nullptr);
7929
7930
return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
7931
.Case("new", IFace)
7932
.Case("alloc", IFace)
7933
.Case("allocWithZone", IFace)
7934
.Case("class", IFace)
7935
.Case("superclass", Super)
7936
.Default(nullptr);
7937
}
7938
7939
// Add a special completion for a message send to "super", which fills in the
7940
// most likely case of forwarding all of our arguments to the superclass
7941
// function.
7942
///
7943
/// \param S The semantic analysis object.
7944
///
7945
/// \param NeedSuperKeyword Whether we need to prefix this completion with
7946
/// the "super" keyword. Otherwise, we just need to provide the arguments.
7947
///
7948
/// \param SelIdents The identifiers in the selector that have already been
7949
/// provided as arguments for a send to "super".
7950
///
7951
/// \param Results The set of results to augment.
7952
///
7953
/// \returns the Objective-C method declaration that would be invoked by
7954
/// this "super" completion. If NULL, no completion was added.
7955
static ObjCMethodDecl *
7956
AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
7957
ArrayRef<const IdentifierInfo *> SelIdents,
7958
ResultBuilder &Results) {
7959
ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
7960
if (!CurMethod)
7961
return nullptr;
7962
7963
ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
7964
if (!Class)
7965
return nullptr;
7966
7967
// Try to find a superclass method with the same selector.
7968
ObjCMethodDecl *SuperMethod = nullptr;
7969
while ((Class = Class->getSuperClass()) && !SuperMethod) {
7970
// Check in the class
7971
SuperMethod = Class->getMethod(CurMethod->getSelector(),
7972
CurMethod->isInstanceMethod());
7973
7974
// Check in categories or class extensions.
7975
if (!SuperMethod) {
7976
for (const auto *Cat : Class->known_categories()) {
7977
if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(),
7978
CurMethod->isInstanceMethod())))
7979
break;
7980
}
7981
}
7982
}
7983
7984
if (!SuperMethod)
7985
return nullptr;
7986
7987
// Check whether the superclass method has the same signature.
7988
if (CurMethod->param_size() != SuperMethod->param_size() ||
7989
CurMethod->isVariadic() != SuperMethod->isVariadic())
7990
return nullptr;
7991
7992
for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
7993
CurPEnd = CurMethod->param_end(),
7994
SuperP = SuperMethod->param_begin();
7995
CurP != CurPEnd; ++CurP, ++SuperP) {
7996
// Make sure the parameter types are compatible.
7997
if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
7998
(*SuperP)->getType()))
7999
return nullptr;
8000
8001
// Make sure we have a parameter name to forward!
8002
if (!(*CurP)->getIdentifier())
8003
return nullptr;
8004
}
8005
8006
// We have a superclass method. Now, form the send-to-super completion.
8007
CodeCompletionBuilder Builder(Results.getAllocator(),
8008
Results.getCodeCompletionTUInfo());
8009
8010
// Give this completion a return type.
8011
AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod,
8012
Results.getCompletionContext().getBaseType(), Builder);
8013
8014
// If we need the "super" keyword, add it (plus some spacing).
8015
if (NeedSuperKeyword) {
8016
Builder.AddTypedTextChunk("super");
8017
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8018
}
8019
8020
Selector Sel = CurMethod->getSelector();
8021
if (Sel.isUnarySelector()) {
8022
if (NeedSuperKeyword)
8023
Builder.AddTextChunk(
8024
Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
8025
else
8026
Builder.AddTypedTextChunk(
8027
Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
8028
} else {
8029
ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
8030
for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
8031
if (I > SelIdents.size())
8032
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
8033
8034
if (I < SelIdents.size())
8035
Builder.AddInformativeChunk(
8036
Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
8037
else if (NeedSuperKeyword || I > SelIdents.size()) {
8038
Builder.AddTextChunk(
8039
Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
8040
Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
8041
(*CurP)->getIdentifier()->getName()));
8042
} else {
8043
Builder.AddTypedTextChunk(
8044
Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
8045
Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
8046
(*CurP)->getIdentifier()->getName()));
8047
}
8048
}
8049
}
8050
8051
Results.AddResult(CodeCompletionResult(Builder.TakeString(), SuperMethod,
8052
CCP_SuperCompletion));
8053
return SuperMethod;
8054
}
8055
8056
void SemaCodeCompletion::CodeCompleteObjCMessageReceiver(Scope *S) {
8057
typedef CodeCompletionResult Result;
8058
ResultBuilder Results(
8059
SemaRef, CodeCompleter->getAllocator(),
8060
CodeCompleter->getCodeCompletionTUInfo(),
8061
CodeCompletionContext::CCC_ObjCMessageReceiver,
8062
getLangOpts().CPlusPlus11
8063
? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
8064
: &ResultBuilder::IsObjCMessageReceiver);
8065
8066
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
8067
Results.EnterNewScope();
8068
SemaRef.LookupVisibleDecls(S, Sema::LookupOrdinaryName, Consumer,
8069
CodeCompleter->includeGlobals(),
8070
CodeCompleter->loadExternal());
8071
8072
// If we are in an Objective-C method inside a class that has a superclass,
8073
// add "super" as an option.
8074
if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
8075
if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
8076
if (Iface->getSuperClass()) {
8077
Results.AddResult(Result("super"));
8078
8079
AddSuperSendCompletion(SemaRef, /*NeedSuperKeyword=*/true, std::nullopt,
8080
Results);
8081
}
8082
8083
if (getLangOpts().CPlusPlus11)
8084
addThisCompletion(SemaRef, Results);
8085
8086
Results.ExitScope();
8087
8088
if (CodeCompleter->includeMacros())
8089
AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), false);
8090
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8091
Results.getCompletionContext(), Results.data(),
8092
Results.size());
8093
}
8094
8095
void SemaCodeCompletion::CodeCompleteObjCSuperMessage(
8096
Scope *S, SourceLocation SuperLoc,
8097
ArrayRef<const IdentifierInfo *> SelIdents, bool AtArgumentExpression) {
8098
ObjCInterfaceDecl *CDecl = nullptr;
8099
if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl()) {
8100
// Figure out which interface we're in.
8101
CDecl = CurMethod->getClassInterface();
8102
if (!CDecl)
8103
return;
8104
8105
// Find the superclass of this class.
8106
CDecl = CDecl->getSuperClass();
8107
if (!CDecl)
8108
return;
8109
8110
if (CurMethod->isInstanceMethod()) {
8111
// We are inside an instance method, which means that the message
8112
// send [super ...] is actually calling an instance method on the
8113
// current object.
8114
return CodeCompleteObjCInstanceMessage(S, nullptr, SelIdents,
8115
AtArgumentExpression, CDecl);
8116
}
8117
8118
// Fall through to send to the superclass in CDecl.
8119
} else {
8120
// "super" may be the name of a type or variable. Figure out which
8121
// it is.
8122
const IdentifierInfo *Super = SemaRef.getSuperIdentifier();
8123
NamedDecl *ND =
8124
SemaRef.LookupSingleName(S, Super, SuperLoc, Sema::LookupOrdinaryName);
8125
if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
8126
// "super" names an interface. Use it.
8127
} else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
8128
if (const ObjCObjectType *Iface =
8129
getASTContext().getTypeDeclType(TD)->getAs<ObjCObjectType>())
8130
CDecl = Iface->getInterface();
8131
} else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
8132
// "super" names an unresolved type; we can't be more specific.
8133
} else {
8134
// Assume that "super" names some kind of value and parse that way.
8135
CXXScopeSpec SS;
8136
SourceLocation TemplateKWLoc;
8137
UnqualifiedId id;
8138
id.setIdentifier(Super, SuperLoc);
8139
ExprResult SuperExpr =
8140
SemaRef.ActOnIdExpression(S, SS, TemplateKWLoc, id,
8141
/*HasTrailingLParen=*/false,
8142
/*IsAddressOfOperand=*/false);
8143
return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
8144
SelIdents, AtArgumentExpression);
8145
}
8146
8147
// Fall through
8148
}
8149
8150
ParsedType Receiver;
8151
if (CDecl)
8152
Receiver = ParsedType::make(getASTContext().getObjCInterfaceType(CDecl));
8153
return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
8154
AtArgumentExpression,
8155
/*IsSuper=*/true);
8156
}
8157
8158
/// Given a set of code-completion results for the argument of a message
8159
/// send, determine the preferred type (if any) for that argument expression.
8160
static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results,
8161
unsigned NumSelIdents) {
8162
typedef CodeCompletionResult Result;
8163
ASTContext &Context = Results.getSema().Context;
8164
8165
QualType PreferredType;
8166
unsigned BestPriority = CCP_Unlikely * 2;
8167
Result *ResultsData = Results.data();
8168
for (unsigned I = 0, N = Results.size(); I != N; ++I) {
8169
Result &R = ResultsData[I];
8170
if (R.Kind == Result::RK_Declaration &&
8171
isa<ObjCMethodDecl>(R.Declaration)) {
8172
if (R.Priority <= BestPriority) {
8173
const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
8174
if (NumSelIdents <= Method->param_size()) {
8175
QualType MyPreferredType =
8176
Method->parameters()[NumSelIdents - 1]->getType();
8177
if (R.Priority < BestPriority || PreferredType.isNull()) {
8178
BestPriority = R.Priority;
8179
PreferredType = MyPreferredType;
8180
} else if (!Context.hasSameUnqualifiedType(PreferredType,
8181
MyPreferredType)) {
8182
PreferredType = QualType();
8183
}
8184
}
8185
}
8186
}
8187
}
8188
8189
return PreferredType;
8190
}
8191
8192
static void
8193
AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver,
8194
ArrayRef<const IdentifierInfo *> SelIdents,
8195
bool AtArgumentExpression, bool IsSuper,
8196
ResultBuilder &Results) {
8197
typedef CodeCompletionResult Result;
8198
ObjCInterfaceDecl *CDecl = nullptr;
8199
8200
// If the given name refers to an interface type, retrieve the
8201
// corresponding declaration.
8202
if (Receiver) {
8203
QualType T = SemaRef.GetTypeFromParser(Receiver, nullptr);
8204
if (!T.isNull())
8205
if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
8206
CDecl = Interface->getInterface();
8207
}
8208
8209
// Add all of the factory methods in this Objective-C class, its protocols,
8210
// superclasses, categories, implementation, etc.
8211
Results.EnterNewScope();
8212
8213
// If this is a send-to-super, try to add the special "super" send
8214
// completion.
8215
if (IsSuper) {
8216
if (ObjCMethodDecl *SuperMethod =
8217
AddSuperSendCompletion(SemaRef, false, SelIdents, Results))
8218
Results.Ignore(SuperMethod);
8219
}
8220
8221
// If we're inside an Objective-C method definition, prefer its selector to
8222
// others.
8223
if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
8224
Results.setPreferredSelector(CurMethod->getSelector());
8225
8226
VisitedSelectorSet Selectors;
8227
if (CDecl)
8228
AddObjCMethods(CDecl, false, MK_Any, SelIdents, SemaRef.CurContext,
8229
Selectors, AtArgumentExpression, Results);
8230
else {
8231
// We're messaging "id" as a type; provide all class/factory methods.
8232
8233
// If we have an external source, load the entire class method
8234
// pool from the AST file.
8235
if (SemaRef.getExternalSource()) {
8236
for (uint32_t I = 0,
8237
N = SemaRef.getExternalSource()->GetNumExternalSelectors();
8238
I != N; ++I) {
8239
Selector Sel = SemaRef.getExternalSource()->GetExternalSelector(I);
8240
if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Sel))
8241
continue;
8242
8243
SemaRef.ObjC().ReadMethodPool(Sel);
8244
}
8245
}
8246
8247
for (SemaObjC::GlobalMethodPool::iterator
8248
M = SemaRef.ObjC().MethodPool.begin(),
8249
MEnd = SemaRef.ObjC().MethodPool.end();
8250
M != MEnd; ++M) {
8251
for (ObjCMethodList *MethList = &M->second.second;
8252
MethList && MethList->getMethod(); MethList = MethList->getNext()) {
8253
if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
8254
continue;
8255
8256
Result R(MethList->getMethod(),
8257
Results.getBasePriority(MethList->getMethod()), nullptr);
8258
R.StartParameter = SelIdents.size();
8259
R.AllParametersAreInformative = false;
8260
Results.MaybeAddResult(R, SemaRef.CurContext);
8261
}
8262
}
8263
}
8264
8265
Results.ExitScope();
8266
}
8267
8268
void SemaCodeCompletion::CodeCompleteObjCClassMessage(
8269
Scope *S, ParsedType Receiver, ArrayRef<const IdentifierInfo *> SelIdents,
8270
bool AtArgumentExpression, bool IsSuper) {
8271
8272
QualType T = SemaRef.GetTypeFromParser(Receiver);
8273
8274
ResultBuilder Results(
8275
SemaRef, CodeCompleter->getAllocator(),
8276
CodeCompleter->getCodeCompletionTUInfo(),
8277
CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage, T,
8278
SelIdents));
8279
8280
AddClassMessageCompletions(SemaRef, S, Receiver, SelIdents,
8281
AtArgumentExpression, IsSuper, Results);
8282
8283
// If we're actually at the argument expression (rather than prior to the
8284
// selector), we're actually performing code completion for an expression.
8285
// Determine whether we have a single, best method. If so, we can
8286
// code-complete the expression using the corresponding parameter type as
8287
// our preferred type, improving completion results.
8288
if (AtArgumentExpression) {
8289
QualType PreferredType =
8290
getPreferredArgumentTypeForMessageSend(Results, SelIdents.size());
8291
if (PreferredType.isNull())
8292
CodeCompleteOrdinaryName(S, PCC_Expression);
8293
else
8294
CodeCompleteExpression(S, PreferredType);
8295
return;
8296
}
8297
8298
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8299
Results.getCompletionContext(), Results.data(),
8300
Results.size());
8301
}
8302
8303
void SemaCodeCompletion::CodeCompleteObjCInstanceMessage(
8304
Scope *S, Expr *Receiver, ArrayRef<const IdentifierInfo *> SelIdents,
8305
bool AtArgumentExpression, ObjCInterfaceDecl *Super) {
8306
typedef CodeCompletionResult Result;
8307
ASTContext &Context = getASTContext();
8308
8309
Expr *RecExpr = static_cast<Expr *>(Receiver);
8310
8311
// If necessary, apply function/array conversion to the receiver.
8312
// C99 6.7.5.3p[7,8].
8313
if (RecExpr) {
8314
ExprResult Conv = SemaRef.DefaultFunctionArrayLvalueConversion(RecExpr);
8315
if (Conv.isInvalid()) // conversion failed. bail.
8316
return;
8317
RecExpr = Conv.get();
8318
}
8319
QualType ReceiverType = RecExpr
8320
? RecExpr->getType()
8321
: Super ? Context.getObjCObjectPointerType(
8322
Context.getObjCInterfaceType(Super))
8323
: Context.getObjCIdType();
8324
8325
// If we're messaging an expression with type "id" or "Class", check
8326
// whether we know something special about the receiver that allows
8327
// us to assume a more-specific receiver type.
8328
if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) {
8329
if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
8330
if (ReceiverType->isObjCClassType())
8331
return CodeCompleteObjCClassMessage(
8332
S, ParsedType::make(Context.getObjCInterfaceType(IFace)), SelIdents,
8333
AtArgumentExpression, Super);
8334
8335
ReceiverType =
8336
Context.getObjCObjectPointerType(Context.getObjCInterfaceType(IFace));
8337
}
8338
} else if (RecExpr && getLangOpts().CPlusPlus) {
8339
ExprResult Conv = SemaRef.PerformContextuallyConvertToObjCPointer(RecExpr);
8340
if (Conv.isUsable()) {
8341
RecExpr = Conv.get();
8342
ReceiverType = RecExpr->getType();
8343
}
8344
}
8345
8346
// Build the set of methods we can see.
8347
ResultBuilder Results(
8348
SemaRef, CodeCompleter->getAllocator(),
8349
CodeCompleter->getCodeCompletionTUInfo(),
8350
CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage,
8351
ReceiverType, SelIdents));
8352
8353
Results.EnterNewScope();
8354
8355
// If this is a send-to-super, try to add the special "super" send
8356
// completion.
8357
if (Super) {
8358
if (ObjCMethodDecl *SuperMethod =
8359
AddSuperSendCompletion(SemaRef, false, SelIdents, Results))
8360
Results.Ignore(SuperMethod);
8361
}
8362
8363
// If we're inside an Objective-C method definition, prefer its selector to
8364
// others.
8365
if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl())
8366
Results.setPreferredSelector(CurMethod->getSelector());
8367
8368
// Keep track of the selectors we've already added.
8369
VisitedSelectorSet Selectors;
8370
8371
// Handle messages to Class. This really isn't a message to an instance
8372
// method, so we treat it the same way we would treat a message send to a
8373
// class method.
8374
if (ReceiverType->isObjCClassType() ||
8375
ReceiverType->isObjCQualifiedClassType()) {
8376
if (ObjCMethodDecl *CurMethod = SemaRef.getCurMethodDecl()) {
8377
if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
8378
AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, SemaRef.CurContext,
8379
Selectors, AtArgumentExpression, Results);
8380
}
8381
}
8382
// Handle messages to a qualified ID ("id<foo>").
8383
else if (const ObjCObjectPointerType *QualID =
8384
ReceiverType->getAsObjCQualifiedIdType()) {
8385
// Search protocols for instance methods.
8386
for (auto *I : QualID->quals())
8387
AddObjCMethods(I, true, MK_Any, SelIdents, SemaRef.CurContext, Selectors,
8388
AtArgumentExpression, Results);
8389
}
8390
// Handle messages to a pointer to interface type.
8391
else if (const ObjCObjectPointerType *IFacePtr =
8392
ReceiverType->getAsObjCInterfacePointerType()) {
8393
// Search the class, its superclasses, etc., for instance methods.
8394
AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
8395
SemaRef.CurContext, Selectors, AtArgumentExpression,
8396
Results);
8397
8398
// Search protocols for instance methods.
8399
for (auto *I : IFacePtr->quals())
8400
AddObjCMethods(I, true, MK_Any, SelIdents, SemaRef.CurContext, Selectors,
8401
AtArgumentExpression, Results);
8402
}
8403
// Handle messages to "id".
8404
else if (ReceiverType->isObjCIdType()) {
8405
// We're messaging "id", so provide all instance methods we know
8406
// about as code-completion results.
8407
8408
// If we have an external source, load the entire class method
8409
// pool from the AST file.
8410
if (SemaRef.ExternalSource) {
8411
for (uint32_t I = 0,
8412
N = SemaRef.ExternalSource->GetNumExternalSelectors();
8413
I != N; ++I) {
8414
Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
8415
if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Sel))
8416
continue;
8417
8418
SemaRef.ObjC().ReadMethodPool(Sel);
8419
}
8420
}
8421
8422
for (SemaObjC::GlobalMethodPool::iterator
8423
M = SemaRef.ObjC().MethodPool.begin(),
8424
MEnd = SemaRef.ObjC().MethodPool.end();
8425
M != MEnd; ++M) {
8426
for (ObjCMethodList *MethList = &M->second.first;
8427
MethList && MethList->getMethod(); MethList = MethList->getNext()) {
8428
if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
8429
continue;
8430
8431
if (!Selectors.insert(MethList->getMethod()->getSelector()).second)
8432
continue;
8433
8434
Result R(MethList->getMethod(),
8435
Results.getBasePriority(MethList->getMethod()), nullptr);
8436
R.StartParameter = SelIdents.size();
8437
R.AllParametersAreInformative = false;
8438
Results.MaybeAddResult(R, SemaRef.CurContext);
8439
}
8440
}
8441
}
8442
Results.ExitScope();
8443
8444
// If we're actually at the argument expression (rather than prior to the
8445
// selector), we're actually performing code completion for an expression.
8446
// Determine whether we have a single, best method. If so, we can
8447
// code-complete the expression using the corresponding parameter type as
8448
// our preferred type, improving completion results.
8449
if (AtArgumentExpression) {
8450
QualType PreferredType =
8451
getPreferredArgumentTypeForMessageSend(Results, SelIdents.size());
8452
if (PreferredType.isNull())
8453
CodeCompleteOrdinaryName(S, PCC_Expression);
8454
else
8455
CodeCompleteExpression(S, PreferredType);
8456
return;
8457
}
8458
8459
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8460
Results.getCompletionContext(), Results.data(),
8461
Results.size());
8462
}
8463
8464
void SemaCodeCompletion::CodeCompleteObjCForCollection(
8465
Scope *S, DeclGroupPtrTy IterationVar) {
8466
CodeCompleteExpressionData Data;
8467
Data.ObjCCollection = true;
8468
8469
if (IterationVar.getAsOpaquePtr()) {
8470
DeclGroupRef DG = IterationVar.get();
8471
for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
8472
if (*I)
8473
Data.IgnoreDecls.push_back(*I);
8474
}
8475
}
8476
8477
CodeCompleteExpression(S, Data);
8478
}
8479
8480
void SemaCodeCompletion::CodeCompleteObjCSelector(
8481
Scope *S, ArrayRef<const IdentifierInfo *> SelIdents) {
8482
// If we have an external source, load the entire class method
8483
// pool from the AST file.
8484
if (SemaRef.ExternalSource) {
8485
for (uint32_t I = 0, N = SemaRef.ExternalSource->GetNumExternalSelectors();
8486
I != N; ++I) {
8487
Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
8488
if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Sel))
8489
continue;
8490
8491
SemaRef.ObjC().ReadMethodPool(Sel);
8492
}
8493
}
8494
8495
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8496
CodeCompleter->getCodeCompletionTUInfo(),
8497
CodeCompletionContext::CCC_SelectorName);
8498
Results.EnterNewScope();
8499
for (SemaObjC::GlobalMethodPool::iterator
8500
M = SemaRef.ObjC().MethodPool.begin(),
8501
MEnd = SemaRef.ObjC().MethodPool.end();
8502
M != MEnd; ++M) {
8503
8504
Selector Sel = M->first;
8505
if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents))
8506
continue;
8507
8508
CodeCompletionBuilder Builder(Results.getAllocator(),
8509
Results.getCodeCompletionTUInfo());
8510
if (Sel.isUnarySelector()) {
8511
Builder.AddTypedTextChunk(
8512
Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
8513
Results.AddResult(Builder.TakeString());
8514
continue;
8515
}
8516
8517
std::string Accumulator;
8518
for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
8519
if (I == SelIdents.size()) {
8520
if (!Accumulator.empty()) {
8521
Builder.AddInformativeChunk(
8522
Builder.getAllocator().CopyString(Accumulator));
8523
Accumulator.clear();
8524
}
8525
}
8526
8527
Accumulator += Sel.getNameForSlot(I);
8528
Accumulator += ':';
8529
}
8530
Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(Accumulator));
8531
Results.AddResult(Builder.TakeString());
8532
}
8533
Results.ExitScope();
8534
8535
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8536
Results.getCompletionContext(), Results.data(),
8537
Results.size());
8538
}
8539
8540
/// Add all of the protocol declarations that we find in the given
8541
/// (translation unit) context.
8542
static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
8543
bool OnlyForwardDeclarations,
8544
ResultBuilder &Results) {
8545
typedef CodeCompletionResult Result;
8546
8547
for (const auto *D : Ctx->decls()) {
8548
// Record any protocols we find.
8549
if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(D))
8550
if (!OnlyForwardDeclarations || !Proto->hasDefinition())
8551
Results.AddResult(
8552
Result(Proto, Results.getBasePriority(Proto), nullptr), CurContext,
8553
nullptr, false);
8554
}
8555
}
8556
8557
void SemaCodeCompletion::CodeCompleteObjCProtocolReferences(
8558
ArrayRef<IdentifierLocPair> Protocols) {
8559
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8560
CodeCompleter->getCodeCompletionTUInfo(),
8561
CodeCompletionContext::CCC_ObjCProtocolName);
8562
8563
if (CodeCompleter->includeGlobals()) {
8564
Results.EnterNewScope();
8565
8566
// Tell the result set to ignore all of the protocols we have
8567
// already seen.
8568
// FIXME: This doesn't work when caching code-completion results.
8569
for (const IdentifierLocPair &Pair : Protocols)
8570
if (ObjCProtocolDecl *Protocol =
8571
SemaRef.ObjC().LookupProtocol(Pair.first, Pair.second))
8572
Results.Ignore(Protocol);
8573
8574
// Add all protocols.
8575
AddProtocolResults(getASTContext().getTranslationUnitDecl(),
8576
SemaRef.CurContext, false, Results);
8577
8578
Results.ExitScope();
8579
}
8580
8581
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8582
Results.getCompletionContext(), Results.data(),
8583
Results.size());
8584
}
8585
8586
void SemaCodeCompletion::CodeCompleteObjCProtocolDecl(Scope *) {
8587
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8588
CodeCompleter->getCodeCompletionTUInfo(),
8589
CodeCompletionContext::CCC_ObjCProtocolName);
8590
8591
if (CodeCompleter->includeGlobals()) {
8592
Results.EnterNewScope();
8593
8594
// Add all protocols.
8595
AddProtocolResults(getASTContext().getTranslationUnitDecl(),
8596
SemaRef.CurContext, true, Results);
8597
8598
Results.ExitScope();
8599
}
8600
8601
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8602
Results.getCompletionContext(), Results.data(),
8603
Results.size());
8604
}
8605
8606
/// Add all of the Objective-C interface declarations that we find in
8607
/// the given (translation unit) context.
8608
static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
8609
bool OnlyForwardDeclarations,
8610
bool OnlyUnimplemented,
8611
ResultBuilder &Results) {
8612
typedef CodeCompletionResult Result;
8613
8614
for (const auto *D : Ctx->decls()) {
8615
// Record any interfaces we find.
8616
if (const auto *Class = dyn_cast<ObjCInterfaceDecl>(D))
8617
if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
8618
(!OnlyUnimplemented || !Class->getImplementation()))
8619
Results.AddResult(
8620
Result(Class, Results.getBasePriority(Class), nullptr), CurContext,
8621
nullptr, false);
8622
}
8623
}
8624
8625
void SemaCodeCompletion::CodeCompleteObjCInterfaceDecl(Scope *S) {
8626
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8627
CodeCompleter->getCodeCompletionTUInfo(),
8628
CodeCompletionContext::CCC_ObjCInterfaceName);
8629
Results.EnterNewScope();
8630
8631
if (CodeCompleter->includeGlobals()) {
8632
// Add all classes.
8633
AddInterfaceResults(getASTContext().getTranslationUnitDecl(),
8634
SemaRef.CurContext, false, false, Results);
8635
}
8636
8637
Results.ExitScope();
8638
8639
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8640
Results.getCompletionContext(), Results.data(),
8641
Results.size());
8642
}
8643
8644
void SemaCodeCompletion::CodeCompleteObjCClassForwardDecl(Scope *S) {
8645
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8646
CodeCompleter->getCodeCompletionTUInfo(),
8647
CodeCompletionContext::CCC_ObjCClassForwardDecl);
8648
Results.EnterNewScope();
8649
8650
if (CodeCompleter->includeGlobals()) {
8651
// Add all classes.
8652
AddInterfaceResults(getASTContext().getTranslationUnitDecl(),
8653
SemaRef.CurContext, false, false, Results);
8654
}
8655
8656
Results.ExitScope();
8657
8658
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8659
Results.getCompletionContext(), Results.data(),
8660
Results.size());
8661
}
8662
8663
void SemaCodeCompletion::CodeCompleteObjCSuperclass(
8664
Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {
8665
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8666
CodeCompleter->getCodeCompletionTUInfo(),
8667
CodeCompletionContext::CCC_ObjCInterfaceName);
8668
Results.EnterNewScope();
8669
8670
// Make sure that we ignore the class we're currently defining.
8671
NamedDecl *CurClass = SemaRef.LookupSingleName(
8672
SemaRef.TUScope, ClassName, ClassNameLoc, Sema::LookupOrdinaryName);
8673
if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
8674
Results.Ignore(CurClass);
8675
8676
if (CodeCompleter->includeGlobals()) {
8677
// Add all classes.
8678
AddInterfaceResults(getASTContext().getTranslationUnitDecl(),
8679
SemaRef.CurContext, false, false, Results);
8680
}
8681
8682
Results.ExitScope();
8683
8684
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8685
Results.getCompletionContext(), Results.data(),
8686
Results.size());
8687
}
8688
8689
void SemaCodeCompletion::CodeCompleteObjCImplementationDecl(Scope *S) {
8690
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8691
CodeCompleter->getCodeCompletionTUInfo(),
8692
CodeCompletionContext::CCC_ObjCImplementation);
8693
Results.EnterNewScope();
8694
8695
if (CodeCompleter->includeGlobals()) {
8696
// Add all unimplemented classes.
8697
AddInterfaceResults(getASTContext().getTranslationUnitDecl(),
8698
SemaRef.CurContext, false, true, Results);
8699
}
8700
8701
Results.ExitScope();
8702
8703
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8704
Results.getCompletionContext(), Results.data(),
8705
Results.size());
8706
}
8707
8708
void SemaCodeCompletion::CodeCompleteObjCInterfaceCategory(
8709
Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {
8710
typedef CodeCompletionResult Result;
8711
8712
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8713
CodeCompleter->getCodeCompletionTUInfo(),
8714
CodeCompletionContext::CCC_ObjCCategoryName);
8715
8716
// Ignore any categories we find that have already been implemented by this
8717
// interface.
8718
llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
8719
NamedDecl *CurClass = SemaRef.LookupSingleName(
8720
SemaRef.TUScope, ClassName, ClassNameLoc, Sema::LookupOrdinaryName);
8721
if (ObjCInterfaceDecl *Class =
8722
dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)) {
8723
for (const auto *Cat : Class->visible_categories())
8724
CategoryNames.insert(Cat->getIdentifier());
8725
}
8726
8727
// Add all of the categories we know about.
8728
Results.EnterNewScope();
8729
TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
8730
for (const auto *D : TU->decls())
8731
if (const auto *Category = dyn_cast<ObjCCategoryDecl>(D))
8732
if (CategoryNames.insert(Category->getIdentifier()).second)
8733
Results.AddResult(
8734
Result(Category, Results.getBasePriority(Category), nullptr),
8735
SemaRef.CurContext, nullptr, false);
8736
Results.ExitScope();
8737
8738
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8739
Results.getCompletionContext(), Results.data(),
8740
Results.size());
8741
}
8742
8743
void SemaCodeCompletion::CodeCompleteObjCImplementationCategory(
8744
Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc) {
8745
typedef CodeCompletionResult Result;
8746
8747
// Find the corresponding interface. If we couldn't find the interface, the
8748
// program itself is ill-formed. However, we'll try to be helpful still by
8749
// providing the list of all of the categories we know about.
8750
NamedDecl *CurClass = SemaRef.LookupSingleName(
8751
SemaRef.TUScope, ClassName, ClassNameLoc, Sema::LookupOrdinaryName);
8752
ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
8753
if (!Class)
8754
return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
8755
8756
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8757
CodeCompleter->getCodeCompletionTUInfo(),
8758
CodeCompletionContext::CCC_ObjCCategoryName);
8759
8760
// Add all of the categories that have corresponding interface
8761
// declarations in this class and any of its superclasses, except for
8762
// already-implemented categories in the class itself.
8763
llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
8764
Results.EnterNewScope();
8765
bool IgnoreImplemented = true;
8766
while (Class) {
8767
for (const auto *Cat : Class->visible_categories()) {
8768
if ((!IgnoreImplemented || !Cat->getImplementation()) &&
8769
CategoryNames.insert(Cat->getIdentifier()).second)
8770
Results.AddResult(Result(Cat, Results.getBasePriority(Cat), nullptr),
8771
SemaRef.CurContext, nullptr, false);
8772
}
8773
8774
Class = Class->getSuperClass();
8775
IgnoreImplemented = false;
8776
}
8777
Results.ExitScope();
8778
8779
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8780
Results.getCompletionContext(), Results.data(),
8781
Results.size());
8782
}
8783
8784
void SemaCodeCompletion::CodeCompleteObjCPropertyDefinition(Scope *S) {
8785
CodeCompletionContext CCContext(CodeCompletionContext::CCC_Other);
8786
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8787
CodeCompleter->getCodeCompletionTUInfo(), CCContext);
8788
8789
// Figure out where this @synthesize lives.
8790
ObjCContainerDecl *Container =
8791
dyn_cast_or_null<ObjCContainerDecl>(SemaRef.CurContext);
8792
if (!Container || (!isa<ObjCImplementationDecl>(Container) &&
8793
!isa<ObjCCategoryImplDecl>(Container)))
8794
return;
8795
8796
// Ignore any properties that have already been implemented.
8797
Container = getContainerDef(Container);
8798
for (const auto *D : Container->decls())
8799
if (const auto *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(D))
8800
Results.Ignore(PropertyImpl->getPropertyDecl());
8801
8802
// Add any properties that we find.
8803
AddedPropertiesSet AddedProperties;
8804
Results.EnterNewScope();
8805
if (ObjCImplementationDecl *ClassImpl =
8806
dyn_cast<ObjCImplementationDecl>(Container))
8807
AddObjCProperties(CCContext, ClassImpl->getClassInterface(), false,
8808
/*AllowNullaryMethods=*/false, SemaRef.CurContext,
8809
AddedProperties, Results);
8810
else
8811
AddObjCProperties(CCContext,
8812
cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
8813
false, /*AllowNullaryMethods=*/false, SemaRef.CurContext,
8814
AddedProperties, Results);
8815
Results.ExitScope();
8816
8817
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8818
Results.getCompletionContext(), Results.data(),
8819
Results.size());
8820
}
8821
8822
void SemaCodeCompletion::CodeCompleteObjCPropertySynthesizeIvar(
8823
Scope *S, IdentifierInfo *PropertyName) {
8824
typedef CodeCompletionResult Result;
8825
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
8826
CodeCompleter->getCodeCompletionTUInfo(),
8827
CodeCompletionContext::CCC_Other);
8828
8829
// Figure out where this @synthesize lives.
8830
ObjCContainerDecl *Container =
8831
dyn_cast_or_null<ObjCContainerDecl>(SemaRef.CurContext);
8832
if (!Container || (!isa<ObjCImplementationDecl>(Container) &&
8833
!isa<ObjCCategoryImplDecl>(Container)))
8834
return;
8835
8836
// Figure out which interface we're looking into.
8837
ObjCInterfaceDecl *Class = nullptr;
8838
if (ObjCImplementationDecl *ClassImpl =
8839
dyn_cast<ObjCImplementationDecl>(Container))
8840
Class = ClassImpl->getClassInterface();
8841
else
8842
Class = cast<ObjCCategoryImplDecl>(Container)
8843
->getCategoryDecl()
8844
->getClassInterface();
8845
8846
// Determine the type of the property we're synthesizing.
8847
QualType PropertyType = getASTContext().getObjCIdType();
8848
if (Class) {
8849
if (ObjCPropertyDecl *Property = Class->FindPropertyDeclaration(
8850
PropertyName, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
8851
PropertyType =
8852
Property->getType().getNonReferenceType().getUnqualifiedType();
8853
8854
// Give preference to ivars
8855
Results.setPreferredType(PropertyType);
8856
}
8857
}
8858
8859
// Add all of the instance variables in this class and its superclasses.
8860
Results.EnterNewScope();
8861
bool SawSimilarlyNamedIvar = false;
8862
std::string NameWithPrefix;
8863
NameWithPrefix += '_';
8864
NameWithPrefix += PropertyName->getName();
8865
std::string NameWithSuffix = PropertyName->getName().str();
8866
NameWithSuffix += '_';
8867
for (; Class; Class = Class->getSuperClass()) {
8868
for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar;
8869
Ivar = Ivar->getNextIvar()) {
8870
Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), nullptr),
8871
SemaRef.CurContext, nullptr, false);
8872
8873
// Determine whether we've seen an ivar with a name similar to the
8874
// property.
8875
if ((PropertyName == Ivar->getIdentifier() ||
8876
NameWithPrefix == Ivar->getName() ||
8877
NameWithSuffix == Ivar->getName())) {
8878
SawSimilarlyNamedIvar = true;
8879
8880
// Reduce the priority of this result by one, to give it a slight
8881
// advantage over other results whose names don't match so closely.
8882
if (Results.size() &&
8883
Results.data()[Results.size() - 1].Kind ==
8884
CodeCompletionResult::RK_Declaration &&
8885
Results.data()[Results.size() - 1].Declaration == Ivar)
8886
Results.data()[Results.size() - 1].Priority--;
8887
}
8888
}
8889
}
8890
8891
if (!SawSimilarlyNamedIvar) {
8892
// Create ivar result _propName, that the user can use to synthesize
8893
// an ivar of the appropriate type.
8894
unsigned Priority = CCP_MemberDeclaration + 1;
8895
typedef CodeCompletionResult Result;
8896
CodeCompletionAllocator &Allocator = Results.getAllocator();
8897
CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(),
8898
Priority, CXAvailability_Available);
8899
8900
PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef);
8901
Builder.AddResultTypeChunk(GetCompletionTypeString(
8902
PropertyType, getASTContext(), Policy, Allocator));
8903
Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix));
8904
Results.AddResult(
8905
Result(Builder.TakeString(), Priority, CXCursor_ObjCIvarDecl));
8906
}
8907
8908
Results.ExitScope();
8909
8910
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
8911
Results.getCompletionContext(), Results.data(),
8912
Results.size());
8913
}
8914
8915
// Mapping from selectors to the methods that implement that selector, along
8916
// with the "in original class" flag.
8917
typedef llvm::DenseMap<Selector,
8918
llvm::PointerIntPair<ObjCMethodDecl *, 1, bool>>
8919
KnownMethodsMap;
8920
8921
/// Find all of the methods that reside in the given container
8922
/// (and its superclasses, protocols, etc.) that meet the given
8923
/// criteria. Insert those methods into the map of known methods,
8924
/// indexed by selector so they can be easily found.
8925
static void FindImplementableMethods(ASTContext &Context,
8926
ObjCContainerDecl *Container,
8927
std::optional<bool> WantInstanceMethods,
8928
QualType ReturnType,
8929
KnownMethodsMap &KnownMethods,
8930
bool InOriginalClass = true) {
8931
if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
8932
// Make sure we have a definition; that's what we'll walk.
8933
if (!IFace->hasDefinition())
8934
return;
8935
8936
IFace = IFace->getDefinition();
8937
Container = IFace;
8938
8939
const ObjCList<ObjCProtocolDecl> &Protocols =
8940
IFace->getReferencedProtocols();
8941
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
8942
E = Protocols.end();
8943
I != E; ++I)
8944
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
8945
KnownMethods, InOriginalClass);
8946
8947
// Add methods from any class extensions and categories.
8948
for (auto *Cat : IFace->visible_categories()) {
8949
FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
8950
KnownMethods, false);
8951
}
8952
8953
// Visit the superclass.
8954
if (IFace->getSuperClass())
8955
FindImplementableMethods(Context, IFace->getSuperClass(),
8956
WantInstanceMethods, ReturnType, KnownMethods,
8957
false);
8958
}
8959
8960
if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
8961
// Recurse into protocols.
8962
const ObjCList<ObjCProtocolDecl> &Protocols =
8963
Category->getReferencedProtocols();
8964
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
8965
E = Protocols.end();
8966
I != E; ++I)
8967
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
8968
KnownMethods, InOriginalClass);
8969
8970
// If this category is the original class, jump to the interface.
8971
if (InOriginalClass && Category->getClassInterface())
8972
FindImplementableMethods(Context, Category->getClassInterface(),
8973
WantInstanceMethods, ReturnType, KnownMethods,
8974
false);
8975
}
8976
8977
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
8978
// Make sure we have a definition; that's what we'll walk.
8979
if (!Protocol->hasDefinition())
8980
return;
8981
Protocol = Protocol->getDefinition();
8982
Container = Protocol;
8983
8984
// Recurse into protocols.
8985
const ObjCList<ObjCProtocolDecl> &Protocols =
8986
Protocol->getReferencedProtocols();
8987
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
8988
E = Protocols.end();
8989
I != E; ++I)
8990
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
8991
KnownMethods, false);
8992
}
8993
8994
// Add methods in this container. This operation occurs last because
8995
// we want the methods from this container to override any methods
8996
// we've previously seen with the same selector.
8997
for (auto *M : Container->methods()) {
8998
if (!WantInstanceMethods || M->isInstanceMethod() == *WantInstanceMethods) {
8999
if (!ReturnType.isNull() &&
9000
!Context.hasSameUnqualifiedType(ReturnType, M->getReturnType()))
9001
continue;
9002
9003
KnownMethods[M->getSelector()] =
9004
KnownMethodsMap::mapped_type(M, InOriginalClass);
9005
}
9006
}
9007
}
9008
9009
/// Add the parenthesized return or parameter type chunk to a code
9010
/// completion string.
9011
static void AddObjCPassingTypeChunk(QualType Type, unsigned ObjCDeclQuals,
9012
ASTContext &Context,
9013
const PrintingPolicy &Policy,
9014
CodeCompletionBuilder &Builder) {
9015
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9016
std::string Quals = formatObjCParamQualifiers(ObjCDeclQuals, Type);
9017
if (!Quals.empty())
9018
Builder.AddTextChunk(Builder.getAllocator().CopyString(Quals));
9019
Builder.AddTextChunk(
9020
GetCompletionTypeString(Type, Context, Policy, Builder.getAllocator()));
9021
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9022
}
9023
9024
/// Determine whether the given class is or inherits from a class by
9025
/// the given name.
9026
static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, StringRef Name) {
9027
if (!Class)
9028
return false;
9029
9030
if (Class->getIdentifier() && Class->getIdentifier()->getName() == Name)
9031
return true;
9032
9033
return InheritsFromClassNamed(Class->getSuperClass(), Name);
9034
}
9035
9036
/// Add code completions for Objective-C Key-Value Coding (KVC) and
9037
/// Key-Value Observing (KVO).
9038
static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property,
9039
bool IsInstanceMethod,
9040
QualType ReturnType, ASTContext &Context,
9041
VisitedSelectorSet &KnownSelectors,
9042
ResultBuilder &Results) {
9043
IdentifierInfo *PropName = Property->getIdentifier();
9044
if (!PropName || PropName->getLength() == 0)
9045
return;
9046
9047
PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
9048
9049
// Builder that will create each code completion.
9050
typedef CodeCompletionResult Result;
9051
CodeCompletionAllocator &Allocator = Results.getAllocator();
9052
CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
9053
9054
// The selector table.
9055
SelectorTable &Selectors = Context.Selectors;
9056
9057
// The property name, copied into the code completion allocation region
9058
// on demand.
9059
struct KeyHolder {
9060
CodeCompletionAllocator &Allocator;
9061
StringRef Key;
9062
const char *CopiedKey;
9063
9064
KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key)
9065
: Allocator(Allocator), Key(Key), CopiedKey(nullptr) {}
9066
9067
operator const char *() {
9068
if (CopiedKey)
9069
return CopiedKey;
9070
9071
return CopiedKey = Allocator.CopyString(Key);
9072
}
9073
} Key(Allocator, PropName->getName());
9074
9075
// The uppercased name of the property name.
9076
std::string UpperKey = std::string(PropName->getName());
9077
if (!UpperKey.empty())
9078
UpperKey[0] = toUppercase(UpperKey[0]);
9079
9080
bool ReturnTypeMatchesProperty =
9081
ReturnType.isNull() ||
9082
Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(),
9083
Property->getType());
9084
bool ReturnTypeMatchesVoid = ReturnType.isNull() || ReturnType->isVoidType();
9085
9086
// Add the normal accessor -(type)key.
9087
if (IsInstanceMethod &&
9088
KnownSelectors.insert(Selectors.getNullarySelector(PropName)).second &&
9089
ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) {
9090
if (ReturnType.isNull())
9091
AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, Context, Policy,
9092
Builder);
9093
9094
Builder.AddTypedTextChunk(Key);
9095
Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
9096
CXCursor_ObjCInstanceMethodDecl));
9097
}
9098
9099
// If we have an integral or boolean property (or the user has provided
9100
// an integral or boolean return type), add the accessor -(type)isKey.
9101
if (IsInstanceMethod &&
9102
((!ReturnType.isNull() &&
9103
(ReturnType->isIntegerType() || ReturnType->isBooleanType())) ||
9104
(ReturnType.isNull() && (Property->getType()->isIntegerType() ||
9105
Property->getType()->isBooleanType())))) {
9106
std::string SelectorName = (Twine("is") + UpperKey).str();
9107
IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9108
if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
9109
.second) {
9110
if (ReturnType.isNull()) {
9111
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9112
Builder.AddTextChunk("BOOL");
9113
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9114
}
9115
9116
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName()));
9117
Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
9118
CXCursor_ObjCInstanceMethodDecl));
9119
}
9120
}
9121
9122
// Add the normal mutator.
9123
if (IsInstanceMethod && ReturnTypeMatchesVoid &&
9124
!Property->getSetterMethodDecl()) {
9125
std::string SelectorName = (Twine("set") + UpperKey).str();
9126
IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9127
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9128
if (ReturnType.isNull()) {
9129
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9130
Builder.AddTextChunk("void");
9131
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9132
}
9133
9134
Builder.AddTypedTextChunk(
9135
Allocator.CopyString(SelectorId->getName() + ":"));
9136
AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, Context, Policy,
9137
Builder);
9138
Builder.AddTextChunk(Key);
9139
Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
9140
CXCursor_ObjCInstanceMethodDecl));
9141
}
9142
}
9143
9144
// Indexed and unordered accessors
9145
unsigned IndexedGetterPriority = CCP_CodePattern;
9146
unsigned IndexedSetterPriority = CCP_CodePattern;
9147
unsigned UnorderedGetterPriority = CCP_CodePattern;
9148
unsigned UnorderedSetterPriority = CCP_CodePattern;
9149
if (const auto *ObjCPointer =
9150
Property->getType()->getAs<ObjCObjectPointerType>()) {
9151
if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) {
9152
// If this interface type is not provably derived from a known
9153
// collection, penalize the corresponding completions.
9154
if (!InheritsFromClassNamed(IFace, "NSMutableArray")) {
9155
IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
9156
if (!InheritsFromClassNamed(IFace, "NSArray"))
9157
IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
9158
}
9159
9160
if (!InheritsFromClassNamed(IFace, "NSMutableSet")) {
9161
UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
9162
if (!InheritsFromClassNamed(IFace, "NSSet"))
9163
UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
9164
}
9165
}
9166
} else {
9167
IndexedGetterPriority += CCD_ProbablyNotObjCCollection;
9168
IndexedSetterPriority += CCD_ProbablyNotObjCCollection;
9169
UnorderedGetterPriority += CCD_ProbablyNotObjCCollection;
9170
UnorderedSetterPriority += CCD_ProbablyNotObjCCollection;
9171
}
9172
9173
// Add -(NSUInteger)countOf<key>
9174
if (IsInstanceMethod &&
9175
(ReturnType.isNull() || ReturnType->isIntegerType())) {
9176
std::string SelectorName = (Twine("countOf") + UpperKey).str();
9177
IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9178
if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
9179
.second) {
9180
if (ReturnType.isNull()) {
9181
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9182
Builder.AddTextChunk("NSUInteger");
9183
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9184
}
9185
9186
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName()));
9187
Results.AddResult(
9188
Result(Builder.TakeString(),
9189
std::min(IndexedGetterPriority, UnorderedGetterPriority),
9190
CXCursor_ObjCInstanceMethodDecl));
9191
}
9192
}
9193
9194
// Indexed getters
9195
// Add -(id)objectInKeyAtIndex:(NSUInteger)index
9196
if (IsInstanceMethod &&
9197
(ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
9198
std::string SelectorName = (Twine("objectIn") + UpperKey + "AtIndex").str();
9199
IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9200
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9201
if (ReturnType.isNull()) {
9202
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9203
Builder.AddTextChunk("id");
9204
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9205
}
9206
9207
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9208
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9209
Builder.AddTextChunk("NSUInteger");
9210
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9211
Builder.AddTextChunk("index");
9212
Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
9213
CXCursor_ObjCInstanceMethodDecl));
9214
}
9215
}
9216
9217
// Add -(NSArray *)keyAtIndexes:(NSIndexSet *)indexes
9218
if (IsInstanceMethod &&
9219
(ReturnType.isNull() ||
9220
(ReturnType->isObjCObjectPointerType() &&
9221
ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
9222
ReturnType->castAs<ObjCObjectPointerType>()
9223
->getInterfaceDecl()
9224
->getName() == "NSArray"))) {
9225
std::string SelectorName = (Twine(Property->getName()) + "AtIndexes").str();
9226
IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9227
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9228
if (ReturnType.isNull()) {
9229
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9230
Builder.AddTextChunk("NSArray *");
9231
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9232
}
9233
9234
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9235
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9236
Builder.AddTextChunk("NSIndexSet *");
9237
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9238
Builder.AddTextChunk("indexes");
9239
Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
9240
CXCursor_ObjCInstanceMethodDecl));
9241
}
9242
}
9243
9244
// Add -(void)getKey:(type **)buffer range:(NSRange)inRange
9245
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9246
std::string SelectorName = (Twine("get") + UpperKey).str();
9247
const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName),
9248
&Context.Idents.get("range")};
9249
9250
if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9251
if (ReturnType.isNull()) {
9252
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9253
Builder.AddTextChunk("void");
9254
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9255
}
9256
9257
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9258
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9259
Builder.AddPlaceholderChunk("object-type");
9260
Builder.AddTextChunk(" **");
9261
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9262
Builder.AddTextChunk("buffer");
9263
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9264
Builder.AddTypedTextChunk("range:");
9265
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9266
Builder.AddTextChunk("NSRange");
9267
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9268
Builder.AddTextChunk("inRange");
9269
Results.AddResult(Result(Builder.TakeString(), IndexedGetterPriority,
9270
CXCursor_ObjCInstanceMethodDecl));
9271
}
9272
}
9273
9274
// Mutable indexed accessors
9275
9276
// - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index
9277
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9278
std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str();
9279
const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get("insertObject"),
9280
&Context.Idents.get(SelectorName)};
9281
9282
if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9283
if (ReturnType.isNull()) {
9284
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9285
Builder.AddTextChunk("void");
9286
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9287
}
9288
9289
Builder.AddTypedTextChunk("insertObject:");
9290
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9291
Builder.AddPlaceholderChunk("object-type");
9292
Builder.AddTextChunk(" *");
9293
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9294
Builder.AddTextChunk("object");
9295
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9296
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9297
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9298
Builder.AddPlaceholderChunk("NSUInteger");
9299
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9300
Builder.AddTextChunk("index");
9301
Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9302
CXCursor_ObjCInstanceMethodDecl));
9303
}
9304
}
9305
9306
// - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes
9307
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9308
std::string SelectorName = (Twine("insert") + UpperKey).str();
9309
const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName),
9310
&Context.Idents.get("atIndexes")};
9311
9312
if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9313
if (ReturnType.isNull()) {
9314
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9315
Builder.AddTextChunk("void");
9316
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9317
}
9318
9319
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9320
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9321
Builder.AddTextChunk("NSArray *");
9322
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9323
Builder.AddTextChunk("array");
9324
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9325
Builder.AddTypedTextChunk("atIndexes:");
9326
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9327
Builder.AddPlaceholderChunk("NSIndexSet *");
9328
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9329
Builder.AddTextChunk("indexes");
9330
Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9331
CXCursor_ObjCInstanceMethodDecl));
9332
}
9333
}
9334
9335
// -(void)removeObjectFromKeyAtIndex:(NSUInteger)index
9336
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9337
std::string SelectorName =
9338
(Twine("removeObjectFrom") + UpperKey + "AtIndex").str();
9339
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9340
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9341
if (ReturnType.isNull()) {
9342
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9343
Builder.AddTextChunk("void");
9344
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9345
}
9346
9347
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9348
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9349
Builder.AddTextChunk("NSUInteger");
9350
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9351
Builder.AddTextChunk("index");
9352
Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9353
CXCursor_ObjCInstanceMethodDecl));
9354
}
9355
}
9356
9357
// -(void)removeKeyAtIndexes:(NSIndexSet *)indexes
9358
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9359
std::string SelectorName = (Twine("remove") + UpperKey + "AtIndexes").str();
9360
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9361
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9362
if (ReturnType.isNull()) {
9363
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9364
Builder.AddTextChunk("void");
9365
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9366
}
9367
9368
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9369
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9370
Builder.AddTextChunk("NSIndexSet *");
9371
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9372
Builder.AddTextChunk("indexes");
9373
Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9374
CXCursor_ObjCInstanceMethodDecl));
9375
}
9376
}
9377
9378
// - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object
9379
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9380
std::string SelectorName =
9381
(Twine("replaceObjectIn") + UpperKey + "AtIndex").str();
9382
const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName),
9383
&Context.Idents.get("withObject")};
9384
9385
if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9386
if (ReturnType.isNull()) {
9387
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9388
Builder.AddTextChunk("void");
9389
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9390
}
9391
9392
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9393
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9394
Builder.AddPlaceholderChunk("NSUInteger");
9395
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9396
Builder.AddTextChunk("index");
9397
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9398
Builder.AddTypedTextChunk("withObject:");
9399
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9400
Builder.AddTextChunk("id");
9401
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9402
Builder.AddTextChunk("object");
9403
Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9404
CXCursor_ObjCInstanceMethodDecl));
9405
}
9406
}
9407
9408
// - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array
9409
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9410
std::string SelectorName1 =
9411
(Twine("replace") + UpperKey + "AtIndexes").str();
9412
std::string SelectorName2 = (Twine("with") + UpperKey).str();
9413
const IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName1),
9414
&Context.Idents.get(SelectorName2)};
9415
9416
if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) {
9417
if (ReturnType.isNull()) {
9418
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9419
Builder.AddTextChunk("void");
9420
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9421
}
9422
9423
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName1 + ":"));
9424
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9425
Builder.AddPlaceholderChunk("NSIndexSet *");
9426
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9427
Builder.AddTextChunk("indexes");
9428
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9429
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName2 + ":"));
9430
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9431
Builder.AddTextChunk("NSArray *");
9432
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9433
Builder.AddTextChunk("array");
9434
Results.AddResult(Result(Builder.TakeString(), IndexedSetterPriority,
9435
CXCursor_ObjCInstanceMethodDecl));
9436
}
9437
}
9438
9439
// Unordered getters
9440
// - (NSEnumerator *)enumeratorOfKey
9441
if (IsInstanceMethod &&
9442
(ReturnType.isNull() ||
9443
(ReturnType->isObjCObjectPointerType() &&
9444
ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
9445
ReturnType->castAs<ObjCObjectPointerType>()
9446
->getInterfaceDecl()
9447
->getName() == "NSEnumerator"))) {
9448
std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str();
9449
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9450
if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
9451
.second) {
9452
if (ReturnType.isNull()) {
9453
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9454
Builder.AddTextChunk("NSEnumerator *");
9455
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9456
}
9457
9458
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
9459
Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
9460
CXCursor_ObjCInstanceMethodDecl));
9461
}
9462
}
9463
9464
// - (type *)memberOfKey:(type *)object
9465
if (IsInstanceMethod &&
9466
(ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) {
9467
std::string SelectorName = (Twine("memberOf") + UpperKey).str();
9468
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9469
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9470
if (ReturnType.isNull()) {
9471
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9472
Builder.AddPlaceholderChunk("object-type");
9473
Builder.AddTextChunk(" *");
9474
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9475
}
9476
9477
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9478
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9479
if (ReturnType.isNull()) {
9480
Builder.AddPlaceholderChunk("object-type");
9481
Builder.AddTextChunk(" *");
9482
} else {
9483
Builder.AddTextChunk(GetCompletionTypeString(
9484
ReturnType, Context, Policy, Builder.getAllocator()));
9485
}
9486
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9487
Builder.AddTextChunk("object");
9488
Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority,
9489
CXCursor_ObjCInstanceMethodDecl));
9490
}
9491
}
9492
9493
// Mutable unordered accessors
9494
// - (void)addKeyObject:(type *)object
9495
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9496
std::string SelectorName =
9497
(Twine("add") + UpperKey + Twine("Object")).str();
9498
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9499
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9500
if (ReturnType.isNull()) {
9501
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9502
Builder.AddTextChunk("void");
9503
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9504
}
9505
9506
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9507
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9508
Builder.AddPlaceholderChunk("object-type");
9509
Builder.AddTextChunk(" *");
9510
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9511
Builder.AddTextChunk("object");
9512
Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
9513
CXCursor_ObjCInstanceMethodDecl));
9514
}
9515
}
9516
9517
// - (void)addKey:(NSSet *)objects
9518
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9519
std::string SelectorName = (Twine("add") + UpperKey).str();
9520
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9521
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9522
if (ReturnType.isNull()) {
9523
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9524
Builder.AddTextChunk("void");
9525
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9526
}
9527
9528
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9529
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9530
Builder.AddTextChunk("NSSet *");
9531
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9532
Builder.AddTextChunk("objects");
9533
Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
9534
CXCursor_ObjCInstanceMethodDecl));
9535
}
9536
}
9537
9538
// - (void)removeKeyObject:(type *)object
9539
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9540
std::string SelectorName =
9541
(Twine("remove") + UpperKey + Twine("Object")).str();
9542
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9543
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9544
if (ReturnType.isNull()) {
9545
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9546
Builder.AddTextChunk("void");
9547
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9548
}
9549
9550
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9551
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9552
Builder.AddPlaceholderChunk("object-type");
9553
Builder.AddTextChunk(" *");
9554
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9555
Builder.AddTextChunk("object");
9556
Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
9557
CXCursor_ObjCInstanceMethodDecl));
9558
}
9559
}
9560
9561
// - (void)removeKey:(NSSet *)objects
9562
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9563
std::string SelectorName = (Twine("remove") + UpperKey).str();
9564
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9565
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9566
if (ReturnType.isNull()) {
9567
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9568
Builder.AddTextChunk("void");
9569
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9570
}
9571
9572
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9573
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9574
Builder.AddTextChunk("NSSet *");
9575
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9576
Builder.AddTextChunk("objects");
9577
Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
9578
CXCursor_ObjCInstanceMethodDecl));
9579
}
9580
}
9581
9582
// - (void)intersectKey:(NSSet *)objects
9583
if (IsInstanceMethod && ReturnTypeMatchesVoid) {
9584
std::string SelectorName = (Twine("intersect") + UpperKey).str();
9585
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9586
if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) {
9587
if (ReturnType.isNull()) {
9588
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9589
Builder.AddTextChunk("void");
9590
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9591
}
9592
9593
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName + ":"));
9594
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9595
Builder.AddTextChunk("NSSet *");
9596
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9597
Builder.AddTextChunk("objects");
9598
Results.AddResult(Result(Builder.TakeString(), UnorderedSetterPriority,
9599
CXCursor_ObjCInstanceMethodDecl));
9600
}
9601
}
9602
9603
// Key-Value Observing
9604
// + (NSSet *)keyPathsForValuesAffectingKey
9605
if (!IsInstanceMethod &&
9606
(ReturnType.isNull() ||
9607
(ReturnType->isObjCObjectPointerType() &&
9608
ReturnType->castAs<ObjCObjectPointerType>()->getInterfaceDecl() &&
9609
ReturnType->castAs<ObjCObjectPointerType>()
9610
->getInterfaceDecl()
9611
->getName() == "NSSet"))) {
9612
std::string SelectorName =
9613
(Twine("keyPathsForValuesAffecting") + UpperKey).str();
9614
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9615
if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
9616
.second) {
9617
if (ReturnType.isNull()) {
9618
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9619
Builder.AddTextChunk("NSSet<NSString *> *");
9620
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9621
}
9622
9623
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
9624
Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
9625
CXCursor_ObjCClassMethodDecl));
9626
}
9627
}
9628
9629
// + (BOOL)automaticallyNotifiesObserversForKey
9630
if (!IsInstanceMethod &&
9631
(ReturnType.isNull() || ReturnType->isIntegerType() ||
9632
ReturnType->isBooleanType())) {
9633
std::string SelectorName =
9634
(Twine("automaticallyNotifiesObserversOf") + UpperKey).str();
9635
const IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName);
9636
if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId))
9637
.second) {
9638
if (ReturnType.isNull()) {
9639
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9640
Builder.AddTextChunk("BOOL");
9641
Builder.AddChunk(CodeCompletionString::CK_RightParen);
9642
}
9643
9644
Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName));
9645
Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern,
9646
CXCursor_ObjCClassMethodDecl));
9647
}
9648
}
9649
}
9650
9651
void SemaCodeCompletion::CodeCompleteObjCMethodDecl(
9652
Scope *S, std::optional<bool> IsInstanceMethod, ParsedType ReturnTy) {
9653
ASTContext &Context = getASTContext();
9654
// Determine the return type of the method we're declaring, if
9655
// provided.
9656
QualType ReturnType = SemaRef.GetTypeFromParser(ReturnTy);
9657
Decl *IDecl = nullptr;
9658
if (SemaRef.CurContext->isObjCContainer()) {
9659
ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(SemaRef.CurContext);
9660
IDecl = OCD;
9661
}
9662
// Determine where we should start searching for methods.
9663
ObjCContainerDecl *SearchDecl = nullptr;
9664
bool IsInImplementation = false;
9665
if (Decl *D = IDecl) {
9666
if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
9667
SearchDecl = Impl->getClassInterface();
9668
IsInImplementation = true;
9669
} else if (ObjCCategoryImplDecl *CatImpl =
9670
dyn_cast<ObjCCategoryImplDecl>(D)) {
9671
SearchDecl = CatImpl->getCategoryDecl();
9672
IsInImplementation = true;
9673
} else
9674
SearchDecl = dyn_cast<ObjCContainerDecl>(D);
9675
}
9676
9677
if (!SearchDecl && S) {
9678
if (DeclContext *DC = S->getEntity())
9679
SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
9680
}
9681
9682
if (!SearchDecl) {
9683
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
9684
CodeCompletionContext::CCC_Other, nullptr, 0);
9685
return;
9686
}
9687
9688
// Find all of the methods that we could declare/implement here.
9689
KnownMethodsMap KnownMethods;
9690
FindImplementableMethods(Context, SearchDecl, IsInstanceMethod, ReturnType,
9691
KnownMethods);
9692
9693
// Add declarations or definitions for each of the known methods.
9694
typedef CodeCompletionResult Result;
9695
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9696
CodeCompleter->getCodeCompletionTUInfo(),
9697
CodeCompletionContext::CCC_Other);
9698
Results.EnterNewScope();
9699
PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef);
9700
for (KnownMethodsMap::iterator M = KnownMethods.begin(),
9701
MEnd = KnownMethods.end();
9702
M != MEnd; ++M) {
9703
ObjCMethodDecl *Method = M->second.getPointer();
9704
CodeCompletionBuilder Builder(Results.getAllocator(),
9705
Results.getCodeCompletionTUInfo());
9706
9707
// Add the '-'/'+' prefix if it wasn't provided yet.
9708
if (!IsInstanceMethod) {
9709
Builder.AddTextChunk(Method->isInstanceMethod() ? "-" : "+");
9710
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9711
}
9712
9713
// If the result type was not already provided, add it to the
9714
// pattern as (type).
9715
if (ReturnType.isNull()) {
9716
QualType ResTy = Method->getSendResultType().stripObjCKindOfType(Context);
9717
AttributedType::stripOuterNullability(ResTy);
9718
AddObjCPassingTypeChunk(ResTy, Method->getObjCDeclQualifier(), Context,
9719
Policy, Builder);
9720
}
9721
9722
Selector Sel = Method->getSelector();
9723
9724
if (Sel.isUnarySelector()) {
9725
// Unary selectors have no arguments.
9726
Builder.AddTypedTextChunk(
9727
Builder.getAllocator().CopyString(Sel.getNameForSlot(0)));
9728
} else {
9729
// Add all parameters to the pattern.
9730
unsigned I = 0;
9731
for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
9732
PEnd = Method->param_end();
9733
P != PEnd; (void)++P, ++I) {
9734
// Add the part of the selector name.
9735
if (I == 0)
9736
Builder.AddTypedTextChunk(
9737
Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
9738
else if (I < Sel.getNumArgs()) {
9739
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9740
Builder.AddTypedTextChunk(
9741
Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
9742
} else
9743
break;
9744
9745
// Add the parameter type.
9746
QualType ParamType;
9747
if ((*P)->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability)
9748
ParamType = (*P)->getType();
9749
else
9750
ParamType = (*P)->getOriginalType();
9751
ParamType = ParamType.substObjCTypeArgs(
9752
Context, {}, ObjCSubstitutionContext::Parameter);
9753
AttributedType::stripOuterNullability(ParamType);
9754
AddObjCPassingTypeChunk(ParamType, (*P)->getObjCDeclQualifier(),
9755
Context, Policy, Builder);
9756
9757
if (IdentifierInfo *Id = (*P)->getIdentifier())
9758
Builder.AddTextChunk(
9759
Builder.getAllocator().CopyString(Id->getName()));
9760
}
9761
}
9762
9763
if (Method->isVariadic()) {
9764
if (Method->param_size() > 0)
9765
Builder.AddChunk(CodeCompletionString::CK_Comma);
9766
Builder.AddTextChunk("...");
9767
}
9768
9769
if (IsInImplementation && Results.includeCodePatterns()) {
9770
// We will be defining the method here, so add a compound statement.
9771
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9772
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
9773
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
9774
if (!Method->getReturnType()->isVoidType()) {
9775
// If the result type is not void, add a return clause.
9776
Builder.AddTextChunk("return");
9777
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9778
Builder.AddPlaceholderChunk("expression");
9779
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
9780
} else
9781
Builder.AddPlaceholderChunk("statements");
9782
9783
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
9784
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
9785
}
9786
9787
unsigned Priority = CCP_CodePattern;
9788
auto R = Result(Builder.TakeString(), Method, Priority);
9789
if (!M->second.getInt())
9790
setInBaseClass(R);
9791
Results.AddResult(std::move(R));
9792
}
9793
9794
// Add Key-Value-Coding and Key-Value-Observing accessor methods for all of
9795
// the properties in this class and its categories.
9796
if (Context.getLangOpts().ObjC) {
9797
SmallVector<ObjCContainerDecl *, 4> Containers;
9798
Containers.push_back(SearchDecl);
9799
9800
VisitedSelectorSet KnownSelectors;
9801
for (KnownMethodsMap::iterator M = KnownMethods.begin(),
9802
MEnd = KnownMethods.end();
9803
M != MEnd; ++M)
9804
KnownSelectors.insert(M->first);
9805
9806
ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl);
9807
if (!IFace)
9808
if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl))
9809
IFace = Category->getClassInterface();
9810
9811
if (IFace)
9812
llvm::append_range(Containers, IFace->visible_categories());
9813
9814
if (IsInstanceMethod) {
9815
for (unsigned I = 0, N = Containers.size(); I != N; ++I)
9816
for (auto *P : Containers[I]->instance_properties())
9817
AddObjCKeyValueCompletions(P, *IsInstanceMethod, ReturnType, Context,
9818
KnownSelectors, Results);
9819
}
9820
}
9821
9822
Results.ExitScope();
9823
9824
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
9825
Results.getCompletionContext(), Results.data(),
9826
Results.size());
9827
}
9828
9829
void SemaCodeCompletion::CodeCompleteObjCMethodDeclSelector(
9830
Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnTy,
9831
ArrayRef<const IdentifierInfo *> SelIdents) {
9832
// If we have an external source, load the entire class method
9833
// pool from the AST file.
9834
if (SemaRef.ExternalSource) {
9835
for (uint32_t I = 0, N = SemaRef.ExternalSource->GetNumExternalSelectors();
9836
I != N; ++I) {
9837
Selector Sel = SemaRef.ExternalSource->GetExternalSelector(I);
9838
if (Sel.isNull() || SemaRef.ObjC().MethodPool.count(Sel))
9839
continue;
9840
9841
SemaRef.ObjC().ReadMethodPool(Sel);
9842
}
9843
}
9844
9845
// Build the set of methods we can see.
9846
typedef CodeCompletionResult Result;
9847
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9848
CodeCompleter->getCodeCompletionTUInfo(),
9849
CodeCompletionContext::CCC_Other);
9850
9851
if (ReturnTy)
9852
Results.setPreferredType(
9853
SemaRef.GetTypeFromParser(ReturnTy).getNonReferenceType());
9854
9855
Results.EnterNewScope();
9856
for (SemaObjC::GlobalMethodPool::iterator
9857
M = SemaRef.ObjC().MethodPool.begin(),
9858
MEnd = SemaRef.ObjC().MethodPool.end();
9859
M != MEnd; ++M) {
9860
for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first
9861
: &M->second.second;
9862
MethList && MethList->getMethod(); MethList = MethList->getNext()) {
9863
if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents))
9864
continue;
9865
9866
if (AtParameterName) {
9867
// Suggest parameter names we've seen before.
9868
unsigned NumSelIdents = SelIdents.size();
9869
if (NumSelIdents &&
9870
NumSelIdents <= MethList->getMethod()->param_size()) {
9871
ParmVarDecl *Param =
9872
MethList->getMethod()->parameters()[NumSelIdents - 1];
9873
if (Param->getIdentifier()) {
9874
CodeCompletionBuilder Builder(Results.getAllocator(),
9875
Results.getCodeCompletionTUInfo());
9876
Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
9877
Param->getIdentifier()->getName()));
9878
Results.AddResult(Builder.TakeString());
9879
}
9880
}
9881
9882
continue;
9883
}
9884
9885
Result R(MethList->getMethod(),
9886
Results.getBasePriority(MethList->getMethod()), nullptr);
9887
R.StartParameter = SelIdents.size();
9888
R.AllParametersAreInformative = false;
9889
R.DeclaringEntity = true;
9890
Results.MaybeAddResult(R, SemaRef.CurContext);
9891
}
9892
}
9893
9894
Results.ExitScope();
9895
9896
if (!AtParameterName && !SelIdents.empty() &&
9897
SelIdents.front()->getName().starts_with("init")) {
9898
for (const auto &M : SemaRef.PP.macros()) {
9899
if (M.first->getName() != "NS_DESIGNATED_INITIALIZER")
9900
continue;
9901
Results.EnterNewScope();
9902
CodeCompletionBuilder Builder(Results.getAllocator(),
9903
Results.getCodeCompletionTUInfo());
9904
Builder.AddTypedTextChunk(
9905
Builder.getAllocator().CopyString(M.first->getName()));
9906
Results.AddResult(CodeCompletionResult(Builder.TakeString(), CCP_Macro,
9907
CXCursor_MacroDefinition));
9908
Results.ExitScope();
9909
}
9910
}
9911
9912
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
9913
Results.getCompletionContext(), Results.data(),
9914
Results.size());
9915
}
9916
9917
void SemaCodeCompletion::CodeCompletePreprocessorDirective(bool InConditional) {
9918
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
9919
CodeCompleter->getCodeCompletionTUInfo(),
9920
CodeCompletionContext::CCC_PreprocessorDirective);
9921
Results.EnterNewScope();
9922
9923
// #if <condition>
9924
CodeCompletionBuilder Builder(Results.getAllocator(),
9925
Results.getCodeCompletionTUInfo());
9926
Builder.AddTypedTextChunk("if");
9927
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9928
Builder.AddPlaceholderChunk("condition");
9929
Results.AddResult(Builder.TakeString());
9930
9931
// #ifdef <macro>
9932
Builder.AddTypedTextChunk("ifdef");
9933
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9934
Builder.AddPlaceholderChunk("macro");
9935
Results.AddResult(Builder.TakeString());
9936
9937
// #ifndef <macro>
9938
Builder.AddTypedTextChunk("ifndef");
9939
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9940
Builder.AddPlaceholderChunk("macro");
9941
Results.AddResult(Builder.TakeString());
9942
9943
if (InConditional) {
9944
// #elif <condition>
9945
Builder.AddTypedTextChunk("elif");
9946
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9947
Builder.AddPlaceholderChunk("condition");
9948
Results.AddResult(Builder.TakeString());
9949
9950
// #elifdef <macro>
9951
Builder.AddTypedTextChunk("elifdef");
9952
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9953
Builder.AddPlaceholderChunk("macro");
9954
Results.AddResult(Builder.TakeString());
9955
9956
// #elifndef <macro>
9957
Builder.AddTypedTextChunk("elifndef");
9958
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9959
Builder.AddPlaceholderChunk("macro");
9960
Results.AddResult(Builder.TakeString());
9961
9962
// #else
9963
Builder.AddTypedTextChunk("else");
9964
Results.AddResult(Builder.TakeString());
9965
9966
// #endif
9967
Builder.AddTypedTextChunk("endif");
9968
Results.AddResult(Builder.TakeString());
9969
}
9970
9971
// #include "header"
9972
Builder.AddTypedTextChunk("include");
9973
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9974
Builder.AddTextChunk("\"");
9975
Builder.AddPlaceholderChunk("header");
9976
Builder.AddTextChunk("\"");
9977
Results.AddResult(Builder.TakeString());
9978
9979
// #include <header>
9980
Builder.AddTypedTextChunk("include");
9981
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9982
Builder.AddTextChunk("<");
9983
Builder.AddPlaceholderChunk("header");
9984
Builder.AddTextChunk(">");
9985
Results.AddResult(Builder.TakeString());
9986
9987
// #define <macro>
9988
Builder.AddTypedTextChunk("define");
9989
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9990
Builder.AddPlaceholderChunk("macro");
9991
Results.AddResult(Builder.TakeString());
9992
9993
// #define <macro>(<args>)
9994
Builder.AddTypedTextChunk("define");
9995
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
9996
Builder.AddPlaceholderChunk("macro");
9997
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
9998
Builder.AddPlaceholderChunk("args");
9999
Builder.AddChunk(CodeCompletionString::CK_RightParen);
10000
Results.AddResult(Builder.TakeString());
10001
10002
// #undef <macro>
10003
Builder.AddTypedTextChunk("undef");
10004
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10005
Builder.AddPlaceholderChunk("macro");
10006
Results.AddResult(Builder.TakeString());
10007
10008
// #line <number>
10009
Builder.AddTypedTextChunk("line");
10010
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10011
Builder.AddPlaceholderChunk("number");
10012
Results.AddResult(Builder.TakeString());
10013
10014
// #line <number> "filename"
10015
Builder.AddTypedTextChunk("line");
10016
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10017
Builder.AddPlaceholderChunk("number");
10018
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10019
Builder.AddTextChunk("\"");
10020
Builder.AddPlaceholderChunk("filename");
10021
Builder.AddTextChunk("\"");
10022
Results.AddResult(Builder.TakeString());
10023
10024
// #error <message>
10025
Builder.AddTypedTextChunk("error");
10026
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10027
Builder.AddPlaceholderChunk("message");
10028
Results.AddResult(Builder.TakeString());
10029
10030
// #pragma <arguments>
10031
Builder.AddTypedTextChunk("pragma");
10032
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10033
Builder.AddPlaceholderChunk("arguments");
10034
Results.AddResult(Builder.TakeString());
10035
10036
if (getLangOpts().ObjC) {
10037
// #import "header"
10038
Builder.AddTypedTextChunk("import");
10039
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10040
Builder.AddTextChunk("\"");
10041
Builder.AddPlaceholderChunk("header");
10042
Builder.AddTextChunk("\"");
10043
Results.AddResult(Builder.TakeString());
10044
10045
// #import <header>
10046
Builder.AddTypedTextChunk("import");
10047
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10048
Builder.AddTextChunk("<");
10049
Builder.AddPlaceholderChunk("header");
10050
Builder.AddTextChunk(">");
10051
Results.AddResult(Builder.TakeString());
10052
}
10053
10054
// #include_next "header"
10055
Builder.AddTypedTextChunk("include_next");
10056
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10057
Builder.AddTextChunk("\"");
10058
Builder.AddPlaceholderChunk("header");
10059
Builder.AddTextChunk("\"");
10060
Results.AddResult(Builder.TakeString());
10061
10062
// #include_next <header>
10063
Builder.AddTypedTextChunk("include_next");
10064
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10065
Builder.AddTextChunk("<");
10066
Builder.AddPlaceholderChunk("header");
10067
Builder.AddTextChunk(">");
10068
Results.AddResult(Builder.TakeString());
10069
10070
// #warning <message>
10071
Builder.AddTypedTextChunk("warning");
10072
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10073
Builder.AddPlaceholderChunk("message");
10074
Results.AddResult(Builder.TakeString());
10075
10076
// Note: #ident and #sccs are such crazy anachronisms that we don't provide
10077
// completions for them. And __include_macros is a Clang-internal extension
10078
// that we don't want to encourage anyone to use.
10079
10080
// FIXME: we don't support #assert or #unassert, so don't suggest them.
10081
Results.ExitScope();
10082
10083
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
10084
Results.getCompletionContext(), Results.data(),
10085
Results.size());
10086
}
10087
10088
void SemaCodeCompletion::CodeCompleteInPreprocessorConditionalExclusion(
10089
Scope *S) {
10090
CodeCompleteOrdinaryName(S, S->getFnParent()
10091
? SemaCodeCompletion::PCC_RecoveryInFunction
10092
: SemaCodeCompletion::PCC_Namespace);
10093
}
10094
10095
void SemaCodeCompletion::CodeCompletePreprocessorMacroName(bool IsDefinition) {
10096
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10097
CodeCompleter->getCodeCompletionTUInfo(),
10098
IsDefinition ? CodeCompletionContext::CCC_MacroName
10099
: CodeCompletionContext::CCC_MacroNameUse);
10100
if (!IsDefinition && CodeCompleter->includeMacros()) {
10101
// Add just the names of macros, not their arguments.
10102
CodeCompletionBuilder Builder(Results.getAllocator(),
10103
Results.getCodeCompletionTUInfo());
10104
Results.EnterNewScope();
10105
for (Preprocessor::macro_iterator M = SemaRef.PP.macro_begin(),
10106
MEnd = SemaRef.PP.macro_end();
10107
M != MEnd; ++M) {
10108
Builder.AddTypedTextChunk(
10109
Builder.getAllocator().CopyString(M->first->getName()));
10110
Results.AddResult(CodeCompletionResult(
10111
Builder.TakeString(), CCP_CodePattern, CXCursor_MacroDefinition));
10112
}
10113
Results.ExitScope();
10114
} else if (IsDefinition) {
10115
// FIXME: Can we detect when the user just wrote an include guard above?
10116
}
10117
10118
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
10119
Results.getCompletionContext(), Results.data(),
10120
Results.size());
10121
}
10122
10123
void SemaCodeCompletion::CodeCompletePreprocessorExpression() {
10124
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10125
CodeCompleter->getCodeCompletionTUInfo(),
10126
CodeCompletionContext::CCC_PreprocessorExpression);
10127
10128
if (CodeCompleter->includeMacros())
10129
AddMacroResults(SemaRef.PP, Results, CodeCompleter->loadExternal(), true);
10130
10131
// defined (<macro>)
10132
Results.EnterNewScope();
10133
CodeCompletionBuilder Builder(Results.getAllocator(),
10134
Results.getCodeCompletionTUInfo());
10135
Builder.AddTypedTextChunk("defined");
10136
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
10137
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
10138
Builder.AddPlaceholderChunk("macro");
10139
Builder.AddChunk(CodeCompletionString::CK_RightParen);
10140
Results.AddResult(Builder.TakeString());
10141
Results.ExitScope();
10142
10143
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
10144
Results.getCompletionContext(), Results.data(),
10145
Results.size());
10146
}
10147
10148
void SemaCodeCompletion::CodeCompletePreprocessorMacroArgument(
10149
Scope *S, IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned Argument) {
10150
// FIXME: In the future, we could provide "overload" results, much like we
10151
// do for function calls.
10152
10153
// Now just ignore this. There will be another code-completion callback
10154
// for the expanded tokens.
10155
}
10156
10157
// This handles completion inside an #include filename, e.g. #include <foo/ba
10158
// We look for the directory "foo" under each directory on the include path,
10159
// list its files, and reassemble the appropriate #include.
10160
void SemaCodeCompletion::CodeCompleteIncludedFile(llvm::StringRef Dir,
10161
bool Angled) {
10162
// RelDir should use /, but unescaped \ is possible on windows!
10163
// Our completions will normalize to / for simplicity, this case is rare.
10164
std::string RelDir = llvm::sys::path::convert_to_slash(Dir);
10165
// We need the native slashes for the actual file system interactions.
10166
SmallString<128> NativeRelDir = StringRef(RelDir);
10167
llvm::sys::path::native(NativeRelDir);
10168
llvm::vfs::FileSystem &FS =
10169
SemaRef.getSourceManager().getFileManager().getVirtualFileSystem();
10170
10171
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10172
CodeCompleter->getCodeCompletionTUInfo(),
10173
CodeCompletionContext::CCC_IncludedFile);
10174
llvm::DenseSet<StringRef> SeenResults; // To deduplicate results.
10175
10176
// Helper: adds one file or directory completion result.
10177
auto AddCompletion = [&](StringRef Filename, bool IsDirectory) {
10178
SmallString<64> TypedChunk = Filename;
10179
// Directory completion is up to the slash, e.g. <sys/
10180
TypedChunk.push_back(IsDirectory ? '/' : Angled ? '>' : '"');
10181
auto R = SeenResults.insert(TypedChunk);
10182
if (R.second) { // New completion
10183
const char *InternedTyped = Results.getAllocator().CopyString(TypedChunk);
10184
*R.first = InternedTyped; // Avoid dangling StringRef.
10185
CodeCompletionBuilder Builder(CodeCompleter->getAllocator(),
10186
CodeCompleter->getCodeCompletionTUInfo());
10187
Builder.AddTypedTextChunk(InternedTyped);
10188
// The result is a "Pattern", which is pretty opaque.
10189
// We may want to include the real filename to allow smart ranking.
10190
Results.AddResult(CodeCompletionResult(Builder.TakeString()));
10191
}
10192
};
10193
10194
// Helper: scans IncludeDir for nice files, and adds results for each.
10195
auto AddFilesFromIncludeDir = [&](StringRef IncludeDir,
10196
bool IsSystem,
10197
DirectoryLookup::LookupType_t LookupType) {
10198
llvm::SmallString<128> Dir = IncludeDir;
10199
if (!NativeRelDir.empty()) {
10200
if (LookupType == DirectoryLookup::LT_Framework) {
10201
// For a framework dir, #include <Foo/Bar/> actually maps to
10202
// a path of Foo.framework/Headers/Bar/.
10203
auto Begin = llvm::sys::path::begin(NativeRelDir);
10204
auto End = llvm::sys::path::end(NativeRelDir);
10205
10206
llvm::sys::path::append(Dir, *Begin + ".framework", "Headers");
10207
llvm::sys::path::append(Dir, ++Begin, End);
10208
} else {
10209
llvm::sys::path::append(Dir, NativeRelDir);
10210
}
10211
}
10212
10213
const StringRef &Dirname = llvm::sys::path::filename(Dir);
10214
const bool isQt = Dirname.starts_with("Qt") || Dirname == "ActiveQt";
10215
const bool ExtensionlessHeaders =
10216
IsSystem || isQt || Dir.ends_with(".framework/Headers");
10217
std::error_code EC;
10218
unsigned Count = 0;
10219
for (auto It = FS.dir_begin(Dir, EC);
10220
!EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) {
10221
if (++Count == 2500) // If we happen to hit a huge directory,
10222
break; // bail out early so we're not too slow.
10223
StringRef Filename = llvm::sys::path::filename(It->path());
10224
10225
// To know whether a symlink should be treated as file or a directory, we
10226
// have to stat it. This should be cheap enough as there shouldn't be many
10227
// symlinks.
10228
llvm::sys::fs::file_type Type = It->type();
10229
if (Type == llvm::sys::fs::file_type::symlink_file) {
10230
if (auto FileStatus = FS.status(It->path()))
10231
Type = FileStatus->getType();
10232
}
10233
switch (Type) {
10234
case llvm::sys::fs::file_type::directory_file:
10235
// All entries in a framework directory must have a ".framework" suffix,
10236
// but the suffix does not appear in the source code's include/import.
10237
if (LookupType == DirectoryLookup::LT_Framework &&
10238
NativeRelDir.empty() && !Filename.consume_back(".framework"))
10239
break;
10240
10241
AddCompletion(Filename, /*IsDirectory=*/true);
10242
break;
10243
case llvm::sys::fs::file_type::regular_file: {
10244
// Only files that really look like headers. (Except in special dirs).
10245
const bool IsHeader = Filename.ends_with_insensitive(".h") ||
10246
Filename.ends_with_insensitive(".hh") ||
10247
Filename.ends_with_insensitive(".hpp") ||
10248
Filename.ends_with_insensitive(".hxx") ||
10249
Filename.ends_with_insensitive(".inc") ||
10250
(ExtensionlessHeaders && !Filename.contains('.'));
10251
if (!IsHeader)
10252
break;
10253
AddCompletion(Filename, /*IsDirectory=*/false);
10254
break;
10255
}
10256
default:
10257
break;
10258
}
10259
}
10260
};
10261
10262
// Helper: adds results relative to IncludeDir, if possible.
10263
auto AddFilesFromDirLookup = [&](const DirectoryLookup &IncludeDir,
10264
bool IsSystem) {
10265
switch (IncludeDir.getLookupType()) {
10266
case DirectoryLookup::LT_HeaderMap:
10267
// header maps are not (currently) enumerable.
10268
break;
10269
case DirectoryLookup::LT_NormalDir:
10270
AddFilesFromIncludeDir(IncludeDir.getDirRef()->getName(), IsSystem,
10271
DirectoryLookup::LT_NormalDir);
10272
break;
10273
case DirectoryLookup::LT_Framework:
10274
AddFilesFromIncludeDir(IncludeDir.getFrameworkDirRef()->getName(),
10275
IsSystem, DirectoryLookup::LT_Framework);
10276
break;
10277
}
10278
};
10279
10280
// Finally with all our helpers, we can scan the include path.
10281
// Do this in standard order so deduplication keeps the right file.
10282
// (In case we decide to add more details to the results later).
10283
const auto &S = SemaRef.PP.getHeaderSearchInfo();
10284
using llvm::make_range;
10285
if (!Angled) {
10286
// The current directory is on the include path for "quoted" includes.
10287
if (auto CurFile = SemaRef.PP.getCurrentFileLexer()->getFileEntry())
10288
AddFilesFromIncludeDir(CurFile->getDir().getName(), false,
10289
DirectoryLookup::LT_NormalDir);
10290
for (const auto &D : make_range(S.quoted_dir_begin(), S.quoted_dir_end()))
10291
AddFilesFromDirLookup(D, false);
10292
}
10293
for (const auto &D : make_range(S.angled_dir_begin(), S.angled_dir_end()))
10294
AddFilesFromDirLookup(D, false);
10295
for (const auto &D : make_range(S.system_dir_begin(), S.system_dir_end()))
10296
AddFilesFromDirLookup(D, true);
10297
10298
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
10299
Results.getCompletionContext(), Results.data(),
10300
Results.size());
10301
}
10302
10303
void SemaCodeCompletion::CodeCompleteNaturalLanguage() {
10304
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
10305
CodeCompletionContext::CCC_NaturalLanguage, nullptr,
10306
0);
10307
}
10308
10309
void SemaCodeCompletion::CodeCompleteAvailabilityPlatformName() {
10310
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
10311
CodeCompleter->getCodeCompletionTUInfo(),
10312
CodeCompletionContext::CCC_Other);
10313
Results.EnterNewScope();
10314
static const char *Platforms[] = {"macOS", "iOS", "watchOS", "tvOS"};
10315
for (const char *Platform : llvm::ArrayRef(Platforms)) {
10316
Results.AddResult(CodeCompletionResult(Platform));
10317
Results.AddResult(CodeCompletionResult(Results.getAllocator().CopyString(
10318
Twine(Platform) + "ApplicationExtension")));
10319
}
10320
Results.ExitScope();
10321
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
10322
Results.getCompletionContext(), Results.data(),
10323
Results.size());
10324
}
10325
10326
void SemaCodeCompletion::GatherGlobalCodeCompletions(
10327
CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo,
10328
SmallVectorImpl<CodeCompletionResult> &Results) {
10329
ResultBuilder Builder(SemaRef, Allocator, CCTUInfo,
10330
CodeCompletionContext::CCC_Recovery);
10331
if (!CodeCompleter || CodeCompleter->includeGlobals()) {
10332
CodeCompletionDeclConsumer Consumer(
10333
Builder, getASTContext().getTranslationUnitDecl());
10334
SemaRef.LookupVisibleDecls(getASTContext().getTranslationUnitDecl(),
10335
Sema::LookupAnyName, Consumer,
10336
!CodeCompleter || CodeCompleter->loadExternal());
10337
}
10338
10339
if (!CodeCompleter || CodeCompleter->includeMacros())
10340
AddMacroResults(SemaRef.PP, Builder,
10341
!CodeCompleter || CodeCompleter->loadExternal(), true);
10342
10343
Results.clear();
10344
Results.insert(Results.end(), Builder.data(),
10345
Builder.data() + Builder.size());
10346
}
10347
10348
SemaCodeCompletion::SemaCodeCompletion(Sema &S,
10349
CodeCompleteConsumer *CompletionConsumer)
10350
: SemaBase(S), CodeCompleter(CompletionConsumer) {}
10351
10352