File: | src/gnu/usr.bin/clang/libclangSema/../../../llvm/clang/lib/Sema/SemaCodeComplete.cpp |
Warning: | line 8703, column 9 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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/QualTypeNames.h" |
24 | #include "clang/AST/RecursiveASTVisitor.h" |
25 | #include "clang/AST/Type.h" |
26 | #include "clang/Basic/CharInfo.h" |
27 | #include "clang/Basic/OperatorKinds.h" |
28 | #include "clang/Basic/Specifiers.h" |
29 | #include "clang/Lex/HeaderSearch.h" |
30 | #include "clang/Lex/MacroInfo.h" |
31 | #include "clang/Lex/Preprocessor.h" |
32 | #include "clang/Sema/CodeCompleteConsumer.h" |
33 | #include "clang/Sema/DeclSpec.h" |
34 | #include "clang/Sema/Designator.h" |
35 | #include "clang/Sema/Lookup.h" |
36 | #include "clang/Sema/Overload.h" |
37 | #include "clang/Sema/Scope.h" |
38 | #include "clang/Sema/ScopeInfo.h" |
39 | #include "clang/Sema/Sema.h" |
40 | #include "clang/Sema/SemaInternal.h" |
41 | #include "llvm/ADT/ArrayRef.h" |
42 | #include "llvm/ADT/DenseSet.h" |
43 | #include "llvm/ADT/SmallBitVector.h" |
44 | #include "llvm/ADT/SmallPtrSet.h" |
45 | #include "llvm/ADT/SmallString.h" |
46 | #include "llvm/ADT/StringExtras.h" |
47 | #include "llvm/ADT/StringSwitch.h" |
48 | #include "llvm/ADT/Twine.h" |
49 | #include "llvm/ADT/iterator_range.h" |
50 | #include "llvm/Support/Casting.h" |
51 | #include "llvm/Support/Path.h" |
52 | #include "llvm/Support/raw_ostream.h" |
53 | #include <list> |
54 | #include <map> |
55 | #include <string> |
56 | #include <vector> |
57 | |
58 | using namespace clang; |
59 | using namespace sema; |
60 | |
61 | namespace { |
62 | /// A container of code-completion results. |
63 | class ResultBuilder { |
64 | public: |
65 | /// The type of a name-lookup filter, which can be provided to the |
66 | /// name-lookup routines to specify which declarations should be included in |
67 | /// the result set (when it returns true) and which declarations should be |
68 | /// filtered out (returns false). |
69 | typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const; |
70 | |
71 | typedef CodeCompletionResult Result; |
72 | |
73 | private: |
74 | /// The actual results we have found. |
75 | std::vector<Result> Results; |
76 | |
77 | /// A record of all of the declarations we have found and placed |
78 | /// into the result set, used to ensure that no declaration ever gets into |
79 | /// the result set twice. |
80 | llvm::SmallPtrSet<const Decl *, 16> AllDeclsFound; |
81 | |
82 | typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair; |
83 | |
84 | /// An entry in the shadow map, which is optimized to store |
85 | /// a single (declaration, index) mapping (the common case) but |
86 | /// can also store a list of (declaration, index) mappings. |
87 | class ShadowMapEntry { |
88 | typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector; |
89 | |
90 | /// Contains either the solitary NamedDecl * or a vector |
91 | /// of (declaration, index) pairs. |
92 | llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector *> DeclOrVector; |
93 | |
94 | /// When the entry contains a single declaration, this is |
95 | /// the index associated with that entry. |
96 | unsigned SingleDeclIndex; |
97 | |
98 | public: |
99 | ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) {} |
100 | ShadowMapEntry(const ShadowMapEntry &) = delete; |
101 | ShadowMapEntry(ShadowMapEntry &&Move) { *this = std::move(Move); } |
102 | ShadowMapEntry &operator=(const ShadowMapEntry &) = delete; |
103 | ShadowMapEntry &operator=(ShadowMapEntry &&Move) { |
104 | SingleDeclIndex = Move.SingleDeclIndex; |
105 | DeclOrVector = Move.DeclOrVector; |
106 | Move.DeclOrVector = nullptr; |
107 | return *this; |
108 | } |
109 | |
110 | void Add(const NamedDecl *ND, unsigned Index) { |
111 | if (DeclOrVector.isNull()) { |
112 | // 0 - > 1 elements: just set the single element information. |
113 | DeclOrVector = ND; |
114 | SingleDeclIndex = Index; |
115 | return; |
116 | } |
117 | |
118 | if (const NamedDecl *PrevND = |
119 | DeclOrVector.dyn_cast<const NamedDecl *>()) { |
120 | // 1 -> 2 elements: create the vector of results and push in the |
121 | // existing declaration. |
122 | DeclIndexPairVector *Vec = new DeclIndexPairVector; |
123 | Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex)); |
124 | DeclOrVector = Vec; |
125 | } |
126 | |
127 | // Add the new element to the end of the vector. |
128 | DeclOrVector.get<DeclIndexPairVector *>()->push_back( |
129 | DeclIndexPair(ND, Index)); |
130 | } |
131 | |
132 | ~ShadowMapEntry() { |
133 | if (DeclIndexPairVector *Vec = |
134 | DeclOrVector.dyn_cast<DeclIndexPairVector *>()) { |
135 | delete Vec; |
136 | DeclOrVector = ((NamedDecl *)nullptr); |
137 | } |
138 | } |
139 | |
140 | // Iteration. |
141 | class iterator; |
142 | iterator begin() const; |
143 | iterator end() const; |
144 | }; |
145 | |
146 | /// A mapping from declaration names to the declarations that have |
147 | /// this name within a particular scope and their index within the list of |
148 | /// results. |
149 | typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap; |
150 | |
151 | /// The semantic analysis object for which results are being |
152 | /// produced. |
153 | Sema &SemaRef; |
154 | |
155 | /// The allocator used to allocate new code-completion strings. |
156 | CodeCompletionAllocator &Allocator; |
157 | |
158 | CodeCompletionTUInfo &CCTUInfo; |
159 | |
160 | /// If non-NULL, a filter function used to remove any code-completion |
161 | /// results that are not desirable. |
162 | LookupFilter Filter; |
163 | |
164 | /// Whether we should allow declarations as |
165 | /// nested-name-specifiers that would otherwise be filtered out. |
166 | bool AllowNestedNameSpecifiers; |
167 | |
168 | /// If set, the type that we would prefer our resulting value |
169 | /// declarations to have. |
170 | /// |
171 | /// Closely matching the preferred type gives a boost to a result's |
172 | /// priority. |
173 | CanQualType PreferredType; |
174 | |
175 | /// A list of shadow maps, which is used to model name hiding at |
176 | /// different levels of, e.g., the inheritance hierarchy. |
177 | std::list<ShadowMap> ShadowMaps; |
178 | |
179 | /// Overloaded C++ member functions found by SemaLookup. |
180 | /// Used to determine when one overload is dominated by another. |
181 | llvm::DenseMap<std::pair<DeclContext *, /*Name*/uintptr_t>, ShadowMapEntry> |
182 | OverloadMap; |
183 | |
184 | /// If we're potentially referring to a C++ member function, the set |
185 | /// of qualifiers applied to the object type. |
186 | Qualifiers ObjectTypeQualifiers; |
187 | /// The kind of the object expression, for rvalue/lvalue overloads. |
188 | ExprValueKind ObjectKind; |
189 | |
190 | /// Whether the \p ObjectTypeQualifiers field is active. |
191 | bool HasObjectTypeQualifiers; |
192 | |
193 | /// The selector that we prefer. |
194 | Selector PreferredSelector; |
195 | |
196 | /// The completion context in which we are gathering results. |
197 | CodeCompletionContext CompletionContext; |
198 | |
199 | /// If we are in an instance method definition, the \@implementation |
200 | /// object. |
201 | ObjCImplementationDecl *ObjCImplementation; |
202 | |
203 | void AdjustResultPriorityForDecl(Result &R); |
204 | |
205 | void MaybeAddConstructorResults(Result R); |
206 | |
207 | public: |
208 | explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator, |
209 | CodeCompletionTUInfo &CCTUInfo, |
210 | const CodeCompletionContext &CompletionContext, |
211 | LookupFilter Filter = nullptr) |
212 | : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo), |
213 | Filter(Filter), AllowNestedNameSpecifiers(false), |
214 | HasObjectTypeQualifiers(false), CompletionContext(CompletionContext), |
215 | ObjCImplementation(nullptr) { |
216 | // If this is an Objective-C instance method definition, dig out the |
217 | // corresponding implementation. |
218 | switch (CompletionContext.getKind()) { |
219 | case CodeCompletionContext::CCC_Expression: |
220 | case CodeCompletionContext::CCC_ObjCMessageReceiver: |
221 | case CodeCompletionContext::CCC_ParenthesizedExpression: |
222 | case CodeCompletionContext::CCC_Statement: |
223 | case CodeCompletionContext::CCC_Recovery: |
224 | if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) |
225 | if (Method->isInstanceMethod()) |
226 | if (ObjCInterfaceDecl *Interface = Method->getClassInterface()) |
227 | ObjCImplementation = Interface->getImplementation(); |
228 | break; |
229 | |
230 | default: |
231 | break; |
232 | } |
233 | } |
234 | |
235 | /// Determine the priority for a reference to the given declaration. |
236 | unsigned getBasePriority(const NamedDecl *D); |
237 | |
238 | /// Whether we should include code patterns in the completion |
239 | /// results. |
240 | bool includeCodePatterns() const { |
241 | return SemaRef.CodeCompleter && |
242 | SemaRef.CodeCompleter->includeCodePatterns(); |
243 | } |
244 | |
245 | /// Set the filter used for code-completion results. |
246 | void setFilter(LookupFilter Filter) { this->Filter = Filter; } |
247 | |
248 | Result *data() { return Results.empty() ? nullptr : &Results.front(); } |
249 | unsigned size() const { return Results.size(); } |
250 | bool empty() const { return Results.empty(); } |
251 | |
252 | /// Specify the preferred type. |
253 | void setPreferredType(QualType T) { |
254 | PreferredType = SemaRef.Context.getCanonicalType(T); |
255 | } |
256 | |
257 | /// Set the cv-qualifiers on the object type, for us in filtering |
258 | /// calls to member functions. |
259 | /// |
260 | /// When there are qualifiers in this set, they will be used to filter |
261 | /// out member functions that aren't available (because there will be a |
262 | /// cv-qualifier mismatch) or prefer functions with an exact qualifier |
263 | /// match. |
264 | void setObjectTypeQualifiers(Qualifiers Quals, ExprValueKind Kind) { |
265 | ObjectTypeQualifiers = Quals; |
266 | ObjectKind = Kind; |
267 | HasObjectTypeQualifiers = true; |
268 | } |
269 | |
270 | /// Set the preferred selector. |
271 | /// |
272 | /// When an Objective-C method declaration result is added, and that |
273 | /// method's selector matches this preferred selector, we give that method |
274 | /// a slight priority boost. |
275 | void setPreferredSelector(Selector Sel) { PreferredSelector = Sel; } |
276 | |
277 | /// Retrieve the code-completion context for which results are |
278 | /// being collected. |
279 | const CodeCompletionContext &getCompletionContext() const { |
280 | return CompletionContext; |
281 | } |
282 | |
283 | /// Specify whether nested-name-specifiers are allowed. |
284 | void allowNestedNameSpecifiers(bool Allow = true) { |
285 | AllowNestedNameSpecifiers = Allow; |
286 | } |
287 | |
288 | /// Return the semantic analysis object for which we are collecting |
289 | /// code completion results. |
290 | Sema &getSema() const { return SemaRef; } |
291 | |
292 | /// Retrieve the allocator used to allocate code completion strings. |
293 | CodeCompletionAllocator &getAllocator() const { return Allocator; } |
294 | |
295 | CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; } |
296 | |
297 | /// Determine whether the given declaration is at all interesting |
298 | /// as a code-completion result. |
299 | /// |
300 | /// \param ND the declaration that we are inspecting. |
301 | /// |
302 | /// \param AsNestedNameSpecifier will be set true if this declaration is |
303 | /// only interesting when it is a nested-name-specifier. |
304 | bool isInterestingDecl(const NamedDecl *ND, |
305 | bool &AsNestedNameSpecifier) const; |
306 | |
307 | /// Check whether the result is hidden by the Hiding declaration. |
308 | /// |
309 | /// \returns true if the result is hidden and cannot be found, false if |
310 | /// the hidden result could still be found. When false, \p R may be |
311 | /// modified to describe how the result can be found (e.g., via extra |
312 | /// qualification). |
313 | bool CheckHiddenResult(Result &R, DeclContext *CurContext, |
314 | const NamedDecl *Hiding); |
315 | |
316 | /// Add a new result to this result set (if it isn't already in one |
317 | /// of the shadow maps), or replace an existing result (for, e.g., a |
318 | /// redeclaration). |
319 | /// |
320 | /// \param R the result to add (if it is unique). |
321 | /// |
322 | /// \param CurContext the context in which this result will be named. |
323 | void MaybeAddResult(Result R, DeclContext *CurContext = nullptr); |
324 | |
325 | /// Add a new result to this result set, where we already know |
326 | /// the hiding declaration (if any). |
327 | /// |
328 | /// \param R the result to add (if it is unique). |
329 | /// |
330 | /// \param CurContext the context in which this result will be named. |
331 | /// |
332 | /// \param Hiding the declaration that hides the result. |
333 | /// |
334 | /// \param InBaseClass whether the result was found in a base |
335 | /// class of the searched context. |
336 | void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding, |
337 | bool InBaseClass); |
338 | |
339 | /// Add a new non-declaration result to this result set. |
340 | void AddResult(Result R); |
341 | |
342 | /// Enter into a new scope. |
343 | void EnterNewScope(); |
344 | |
345 | /// Exit from the current scope. |
346 | void ExitScope(); |
347 | |
348 | /// Ignore this declaration, if it is seen again. |
349 | void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); } |
350 | |
351 | /// Add a visited context. |
352 | void addVisitedContext(DeclContext *Ctx) { |
353 | CompletionContext.addVisitedContext(Ctx); |
354 | } |
355 | |
356 | /// \name Name lookup predicates |
357 | /// |
358 | /// These predicates can be passed to the name lookup functions to filter the |
359 | /// results of name lookup. All of the predicates have the same type, so that |
360 | /// |
361 | //@{ |
362 | bool IsOrdinaryName(const NamedDecl *ND) const; |
363 | bool IsOrdinaryNonTypeName(const NamedDecl *ND) const; |
364 | bool IsIntegralConstantValue(const NamedDecl *ND) const; |
365 | bool IsOrdinaryNonValueName(const NamedDecl *ND) const; |
366 | bool IsNestedNameSpecifier(const NamedDecl *ND) const; |
367 | bool IsEnum(const NamedDecl *ND) const; |
368 | bool IsClassOrStruct(const NamedDecl *ND) const; |
369 | bool IsUnion(const NamedDecl *ND) const; |
370 | bool IsNamespace(const NamedDecl *ND) const; |
371 | bool IsNamespaceOrAlias(const NamedDecl *ND) const; |
372 | bool IsType(const NamedDecl *ND) const; |
373 | bool IsMember(const NamedDecl *ND) const; |
374 | bool IsObjCIvar(const NamedDecl *ND) const; |
375 | bool IsObjCMessageReceiver(const NamedDecl *ND) const; |
376 | bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const; |
377 | bool IsObjCCollection(const NamedDecl *ND) const; |
378 | bool IsImpossibleToSatisfy(const NamedDecl *ND) const; |
379 | //@} |
380 | }; |
381 | } // namespace |
382 | |
383 | void PreferredTypeBuilder::enterReturn(Sema &S, SourceLocation Tok) { |
384 | if (!Enabled) |
385 | return; |
386 | if (isa<BlockDecl>(S.CurContext)) { |
387 | if (sema::BlockScopeInfo *BSI = S.getCurBlock()) { |
388 | ComputeType = nullptr; |
389 | Type = BSI->ReturnType; |
390 | ExpectedLoc = Tok; |
391 | } |
392 | } else if (const auto *Function = dyn_cast<FunctionDecl>(S.CurContext)) { |
393 | ComputeType = nullptr; |
394 | Type = Function->getReturnType(); |
395 | ExpectedLoc = Tok; |
396 | } else if (const auto *Method = dyn_cast<ObjCMethodDecl>(S.CurContext)) { |
397 | ComputeType = nullptr; |
398 | Type = Method->getReturnType(); |
399 | ExpectedLoc = Tok; |
400 | } |
401 | } |
402 | |
403 | void PreferredTypeBuilder::enterVariableInit(SourceLocation Tok, Decl *D) { |
404 | if (!Enabled) |
405 | return; |
406 | auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D); |
407 | ComputeType = nullptr; |
408 | Type = VD ? VD->getType() : QualType(); |
409 | ExpectedLoc = Tok; |
410 | } |
411 | |
412 | static QualType getDesignatedType(QualType BaseType, const Designation &Desig); |
413 | |
414 | void PreferredTypeBuilder::enterDesignatedInitializer(SourceLocation Tok, |
415 | QualType BaseType, |
416 | const Designation &D) { |
417 | if (!Enabled) |
418 | return; |
419 | ComputeType = nullptr; |
420 | Type = getDesignatedType(BaseType, D); |
421 | ExpectedLoc = Tok; |
422 | } |
423 | |
424 | void PreferredTypeBuilder::enterFunctionArgument( |
425 | SourceLocation Tok, llvm::function_ref<QualType()> ComputeType) { |
426 | if (!Enabled) |
427 | return; |
428 | this->ComputeType = ComputeType; |
429 | Type = QualType(); |
430 | ExpectedLoc = Tok; |
431 | } |
432 | |
433 | void PreferredTypeBuilder::enterParenExpr(SourceLocation Tok, |
434 | SourceLocation LParLoc) { |
435 | if (!Enabled) |
436 | return; |
437 | // expected type for parenthesized expression does not change. |
438 | if (ExpectedLoc == LParLoc) |
439 | ExpectedLoc = Tok; |
440 | } |
441 | |
442 | static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS, |
443 | tok::TokenKind Op) { |
444 | if (!LHS) |
445 | return QualType(); |
446 | |
447 | QualType LHSType = LHS->getType(); |
448 | if (LHSType->isPointerType()) { |
449 | if (Op == tok::plus || Op == tok::plusequal || Op == tok::minusequal) |
450 | return S.getASTContext().getPointerDiffType(); |
451 | // Pointer difference is more common than subtracting an int from a pointer. |
452 | if (Op == tok::minus) |
453 | return LHSType; |
454 | } |
455 | |
456 | switch (Op) { |
457 | // No way to infer the type of RHS from LHS. |
458 | case tok::comma: |
459 | return QualType(); |
460 | // Prefer the type of the left operand for all of these. |
461 | // Arithmetic operations. |
462 | case tok::plus: |
463 | case tok::plusequal: |
464 | case tok::minus: |
465 | case tok::minusequal: |
466 | case tok::percent: |
467 | case tok::percentequal: |
468 | case tok::slash: |
469 | case tok::slashequal: |
470 | case tok::star: |
471 | case tok::starequal: |
472 | // Assignment. |
473 | case tok::equal: |
474 | // Comparison operators. |
475 | case tok::equalequal: |
476 | case tok::exclaimequal: |
477 | case tok::less: |
478 | case tok::lessequal: |
479 | case tok::greater: |
480 | case tok::greaterequal: |
481 | case tok::spaceship: |
482 | return LHS->getType(); |
483 | // Binary shifts are often overloaded, so don't try to guess those. |
484 | case tok::greatergreater: |
485 | case tok::greatergreaterequal: |
486 | case tok::lessless: |
487 | case tok::lesslessequal: |
488 | if (LHSType->isIntegralOrEnumerationType()) |
489 | return S.getASTContext().IntTy; |
490 | return QualType(); |
491 | // Logical operators, assume we want bool. |
492 | case tok::ampamp: |
493 | case tok::pipepipe: |
494 | case tok::caretcaret: |
495 | return S.getASTContext().BoolTy; |
496 | // Operators often used for bit manipulation are typically used with the type |
497 | // of the left argument. |
498 | case tok::pipe: |
499 | case tok::pipeequal: |
500 | case tok::caret: |
501 | case tok::caretequal: |
502 | case tok::amp: |
503 | case tok::ampequal: |
504 | if (LHSType->isIntegralOrEnumerationType()) |
505 | return LHSType; |
506 | return QualType(); |
507 | // RHS should be a pointer to a member of the 'LHS' type, but we can't give |
508 | // any particular type here. |
509 | case tok::periodstar: |
510 | case tok::arrowstar: |
511 | return QualType(); |
512 | default: |
513 | // FIXME(ibiryukov): handle the missing op, re-add the assertion. |
514 | // assert(false && "unhandled binary op"); |
515 | return QualType(); |
516 | } |
517 | } |
518 | |
519 | /// Get preferred type for an argument of an unary expression. \p ContextType is |
520 | /// preferred type of the whole unary expression. |
521 | static QualType getPreferredTypeOfUnaryArg(Sema &S, QualType ContextType, |
522 | tok::TokenKind Op) { |
523 | switch (Op) { |
524 | case tok::exclaim: |
525 | return S.getASTContext().BoolTy; |
526 | case tok::amp: |
527 | if (!ContextType.isNull() && ContextType->isPointerType()) |
528 | return ContextType->getPointeeType(); |
529 | return QualType(); |
530 | case tok::star: |
531 | if (ContextType.isNull()) |
532 | return QualType(); |
533 | return S.getASTContext().getPointerType(ContextType.getNonReferenceType()); |
534 | case tok::plus: |
535 | case tok::minus: |
536 | case tok::tilde: |
537 | case tok::minusminus: |
538 | case tok::plusplus: |
539 | if (ContextType.isNull()) |
540 | return S.getASTContext().IntTy; |
541 | // leave as is, these operators typically return the same type. |
542 | return ContextType; |
543 | case tok::kw___real: |
544 | case tok::kw___imag: |
545 | return QualType(); |
546 | default: |
547 | assert(false && "unhandled unary op")((void)0); |
548 | return QualType(); |
549 | } |
550 | } |
551 | |
552 | void PreferredTypeBuilder::enterBinary(Sema &S, SourceLocation Tok, Expr *LHS, |
553 | tok::TokenKind Op) { |
554 | if (!Enabled) |
555 | return; |
556 | ComputeType = nullptr; |
557 | Type = getPreferredTypeOfBinaryRHS(S, LHS, Op); |
558 | ExpectedLoc = Tok; |
559 | } |
560 | |
561 | void PreferredTypeBuilder::enterMemAccess(Sema &S, SourceLocation Tok, |
562 | Expr *Base) { |
563 | if (!Enabled || !Base) |
564 | return; |
565 | // Do we have expected type for Base? |
566 | if (ExpectedLoc != Base->getBeginLoc()) |
567 | return; |
568 | // Keep the expected type, only update the location. |
569 | ExpectedLoc = Tok; |
570 | return; |
571 | } |
572 | |
573 | void PreferredTypeBuilder::enterUnary(Sema &S, SourceLocation Tok, |
574 | tok::TokenKind OpKind, |
575 | SourceLocation OpLoc) { |
576 | if (!Enabled) |
577 | return; |
578 | ComputeType = nullptr; |
579 | Type = getPreferredTypeOfUnaryArg(S, this->get(OpLoc), OpKind); |
580 | ExpectedLoc = Tok; |
581 | } |
582 | |
583 | void PreferredTypeBuilder::enterSubscript(Sema &S, SourceLocation Tok, |
584 | Expr *LHS) { |
585 | if (!Enabled) |
586 | return; |
587 | ComputeType = nullptr; |
588 | Type = S.getASTContext().IntTy; |
589 | ExpectedLoc = Tok; |
590 | } |
591 | |
592 | void PreferredTypeBuilder::enterTypeCast(SourceLocation Tok, |
593 | QualType CastType) { |
594 | if (!Enabled) |
595 | return; |
596 | ComputeType = nullptr; |
597 | Type = !CastType.isNull() ? CastType.getCanonicalType() : QualType(); |
598 | ExpectedLoc = Tok; |
599 | } |
600 | |
601 | void PreferredTypeBuilder::enterCondition(Sema &S, SourceLocation Tok) { |
602 | if (!Enabled) |
603 | return; |
604 | ComputeType = nullptr; |
605 | Type = S.getASTContext().BoolTy; |
606 | ExpectedLoc = Tok; |
607 | } |
608 | |
609 | class ResultBuilder::ShadowMapEntry::iterator { |
610 | llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator; |
611 | unsigned SingleDeclIndex; |
612 | |
613 | public: |
614 | typedef DeclIndexPair value_type; |
615 | typedef value_type reference; |
616 | typedef std::ptrdiff_t difference_type; |
617 | typedef std::input_iterator_tag iterator_category; |
618 | |
619 | class pointer { |
620 | DeclIndexPair Value; |
621 | |
622 | public: |
623 | pointer(const DeclIndexPair &Value) : Value(Value) {} |
624 | |
625 | const DeclIndexPair *operator->() const { return &Value; } |
626 | }; |
627 | |
628 | iterator() : DeclOrIterator((NamedDecl *)nullptr), SingleDeclIndex(0) {} |
629 | |
630 | iterator(const NamedDecl *SingleDecl, unsigned Index) |
631 | : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) {} |
632 | |
633 | iterator(const DeclIndexPair *Iterator) |
634 | : DeclOrIterator(Iterator), SingleDeclIndex(0) {} |
635 | |
636 | iterator &operator++() { |
637 | if (DeclOrIterator.is<const NamedDecl *>()) { |
638 | DeclOrIterator = (NamedDecl *)nullptr; |
639 | SingleDeclIndex = 0; |
640 | return *this; |
641 | } |
642 | |
643 | const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair *>(); |
644 | ++I; |
645 | DeclOrIterator = I; |
646 | return *this; |
647 | } |
648 | |
649 | /*iterator operator++(int) { |
650 | iterator tmp(*this); |
651 | ++(*this); |
652 | return tmp; |
653 | }*/ |
654 | |
655 | reference operator*() const { |
656 | if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>()) |
657 | return reference(ND, SingleDeclIndex); |
658 | |
659 | return *DeclOrIterator.get<const DeclIndexPair *>(); |
660 | } |
661 | |
662 | pointer operator->() const { return pointer(**this); } |
663 | |
664 | friend bool operator==(const iterator &X, const iterator &Y) { |
665 | return X.DeclOrIterator.getOpaqueValue() == |
666 | Y.DeclOrIterator.getOpaqueValue() && |
667 | X.SingleDeclIndex == Y.SingleDeclIndex; |
668 | } |
669 | |
670 | friend bool operator!=(const iterator &X, const iterator &Y) { |
671 | return !(X == Y); |
672 | } |
673 | }; |
674 | |
675 | ResultBuilder::ShadowMapEntry::iterator |
676 | ResultBuilder::ShadowMapEntry::begin() const { |
677 | if (DeclOrVector.isNull()) |
678 | return iterator(); |
679 | |
680 | if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>()) |
681 | return iterator(ND, SingleDeclIndex); |
682 | |
683 | return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin()); |
684 | } |
685 | |
686 | ResultBuilder::ShadowMapEntry::iterator |
687 | ResultBuilder::ShadowMapEntry::end() const { |
688 | if (DeclOrVector.is<const NamedDecl *>() || DeclOrVector.isNull()) |
689 | return iterator(); |
690 | |
691 | return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end()); |
692 | } |
693 | |
694 | /// Compute the qualification required to get from the current context |
695 | /// (\p CurContext) to the target context (\p TargetContext). |
696 | /// |
697 | /// \param Context the AST context in which the qualification will be used. |
698 | /// |
699 | /// \param CurContext the context where an entity is being named, which is |
700 | /// typically based on the current scope. |
701 | /// |
702 | /// \param TargetContext the context in which the named entity actually |
703 | /// resides. |
704 | /// |
705 | /// \returns a nested name specifier that refers into the target context, or |
706 | /// NULL if no qualification is needed. |
707 | static NestedNameSpecifier * |
708 | getRequiredQualification(ASTContext &Context, const DeclContext *CurContext, |
709 | const DeclContext *TargetContext) { |
710 | SmallVector<const DeclContext *, 4> TargetParents; |
711 | |
712 | for (const DeclContext *CommonAncestor = TargetContext; |
713 | CommonAncestor && !CommonAncestor->Encloses(CurContext); |
714 | CommonAncestor = CommonAncestor->getLookupParent()) { |
715 | if (CommonAncestor->isTransparentContext() || |
716 | CommonAncestor->isFunctionOrMethod()) |
717 | continue; |
718 | |
719 | TargetParents.push_back(CommonAncestor); |
720 | } |
721 | |
722 | NestedNameSpecifier *Result = nullptr; |
723 | while (!TargetParents.empty()) { |
724 | const DeclContext *Parent = TargetParents.pop_back_val(); |
725 | |
726 | if (const auto *Namespace = dyn_cast<NamespaceDecl>(Parent)) { |
727 | if (!Namespace->getIdentifier()) |
728 | continue; |
729 | |
730 | Result = NestedNameSpecifier::Create(Context, Result, Namespace); |
731 | } else if (const auto *TD = dyn_cast<TagDecl>(Parent)) |
732 | Result = NestedNameSpecifier::Create( |
733 | Context, Result, false, Context.getTypeDeclType(TD).getTypePtr()); |
734 | } |
735 | return Result; |
736 | } |
737 | |
738 | // Some declarations have reserved names that we don't want to ever show. |
739 | // Filter out names reserved for the implementation if they come from a |
740 | // system header. |
741 | static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) { |
742 | ReservedIdentifierStatus Status = ND->isReserved(SemaRef.getLangOpts()); |
743 | // Ignore reserved names for compiler provided decls. |
744 | if ((Status != ReservedIdentifierStatus::NotReserved) && |
745 | (Status != ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope) && |
746 | ND->getLocation().isInvalid()) |
747 | return true; |
748 | |
749 | // For system headers ignore only double-underscore names. |
750 | // This allows for system headers providing private symbols with a single |
751 | // underscore. |
752 | if (Status == ReservedIdentifierStatus::StartsWithDoubleUnderscore && |
753 | SemaRef.SourceMgr.isInSystemHeader( |
754 | SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))) |
755 | return true; |
756 | |
757 | return false; |
758 | } |
759 | |
760 | bool ResultBuilder::isInterestingDecl(const NamedDecl *ND, |
761 | bool &AsNestedNameSpecifier) const { |
762 | AsNestedNameSpecifier = false; |
763 | |
764 | auto *Named = ND; |
765 | ND = ND->getUnderlyingDecl(); |
766 | |
767 | // Skip unnamed entities. |
768 | if (!ND->getDeclName()) |
769 | return false; |
770 | |
771 | // Friend declarations and declarations introduced due to friends are never |
772 | // added as results. |
773 | if (ND->getFriendObjectKind() == Decl::FOK_Undeclared) |
774 | return false; |
775 | |
776 | // Class template (partial) specializations are never added as results. |
777 | if (isa<ClassTemplateSpecializationDecl>(ND) || |
778 | isa<ClassTemplatePartialSpecializationDecl>(ND)) |
779 | return false; |
780 | |
781 | // Using declarations themselves are never added as results. |
782 | if (isa<UsingDecl>(ND)) |
783 | return false; |
784 | |
785 | if (shouldIgnoreDueToReservedName(ND, SemaRef)) |
786 | return false; |
787 | |
788 | if (Filter == &ResultBuilder::IsNestedNameSpecifier || |
789 | (isa<NamespaceDecl>(ND) && Filter != &ResultBuilder::IsNamespace && |
790 | Filter != &ResultBuilder::IsNamespaceOrAlias && Filter != nullptr)) |
791 | AsNestedNameSpecifier = true; |
792 | |
793 | // Filter out any unwanted results. |
794 | if (Filter && !(this->*Filter)(Named)) { |
795 | // Check whether it is interesting as a nested-name-specifier. |
796 | if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus && |
797 | IsNestedNameSpecifier(ND) && |
798 | (Filter != &ResultBuilder::IsMember || |
799 | (isa<CXXRecordDecl>(ND) && |
800 | cast<CXXRecordDecl>(ND)->isInjectedClassName()))) { |
801 | AsNestedNameSpecifier = true; |
802 | return true; |
803 | } |
804 | |
805 | return false; |
806 | } |
807 | // ... then it must be interesting! |
808 | return true; |
809 | } |
810 | |
811 | bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext, |
812 | const NamedDecl *Hiding) { |
813 | // In C, there is no way to refer to a hidden name. |
814 | // FIXME: This isn't true; we can find a tag name hidden by an ordinary |
815 | // name if we introduce the tag type. |
816 | if (!SemaRef.getLangOpts().CPlusPlus) |
817 | return true; |
818 | |
819 | const DeclContext *HiddenCtx = |
820 | R.Declaration->getDeclContext()->getRedeclContext(); |
821 | |
822 | // There is no way to qualify a name declared in a function or method. |
823 | if (HiddenCtx->isFunctionOrMethod()) |
824 | return true; |
825 | |
826 | if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext()) |
827 | return true; |
828 | |
829 | // We can refer to the result with the appropriate qualification. Do it. |
830 | R.Hidden = true; |
831 | R.QualifierIsInformative = false; |
832 | |
833 | if (!R.Qualifier) |
834 | R.Qualifier = getRequiredQualification(SemaRef.Context, CurContext, |
835 | R.Declaration->getDeclContext()); |
836 | return false; |
837 | } |
838 | |
839 | /// A simplified classification of types used to determine whether two |
840 | /// types are "similar enough" when adjusting priorities. |
841 | SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) { |
842 | switch (T->getTypeClass()) { |
843 | case Type::Builtin: |
844 | switch (cast<BuiltinType>(T)->getKind()) { |
845 | case BuiltinType::Void: |
846 | return STC_Void; |
847 | |
848 | case BuiltinType::NullPtr: |
849 | return STC_Pointer; |
850 | |
851 | case BuiltinType::Overload: |
852 | case BuiltinType::Dependent: |
853 | return STC_Other; |
854 | |
855 | case BuiltinType::ObjCId: |
856 | case BuiltinType::ObjCClass: |
857 | case BuiltinType::ObjCSel: |
858 | return STC_ObjectiveC; |
859 | |
860 | default: |
861 | return STC_Arithmetic; |
862 | } |
863 | |
864 | case Type::Complex: |
865 | return STC_Arithmetic; |
866 | |
867 | case Type::Pointer: |
868 | return STC_Pointer; |
869 | |
870 | case Type::BlockPointer: |
871 | return STC_Block; |
872 | |
873 | case Type::LValueReference: |
874 | case Type::RValueReference: |
875 | return getSimplifiedTypeClass(T->getAs<ReferenceType>()->getPointeeType()); |
876 | |
877 | case Type::ConstantArray: |
878 | case Type::IncompleteArray: |
879 | case Type::VariableArray: |
880 | case Type::DependentSizedArray: |
881 | return STC_Array; |
882 | |
883 | case Type::DependentSizedExtVector: |
884 | case Type::Vector: |
885 | case Type::ExtVector: |
886 | return STC_Arithmetic; |
887 | |
888 | case Type::FunctionProto: |
889 | case Type::FunctionNoProto: |
890 | return STC_Function; |
891 | |
892 | case Type::Record: |
893 | return STC_Record; |
894 | |
895 | case Type::Enum: |
896 | return STC_Arithmetic; |
897 | |
898 | case Type::ObjCObject: |
899 | case Type::ObjCInterface: |
900 | case Type::ObjCObjectPointer: |
901 | return STC_ObjectiveC; |
902 | |
903 | default: |
904 | return STC_Other; |
905 | } |
906 | } |
907 | |
908 | /// Get the type that a given expression will have if this declaration |
909 | /// is used as an expression in its "typical" code-completion form. |
910 | QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) { |
911 | ND = ND->getUnderlyingDecl(); |
912 | |
913 | if (const auto *Type = dyn_cast<TypeDecl>(ND)) |
914 | return C.getTypeDeclType(Type); |
915 | if (const auto *Iface = dyn_cast<ObjCInterfaceDecl>(ND)) |
916 | return C.getObjCInterfaceType(Iface); |
917 | |
918 | QualType T; |
919 | if (const FunctionDecl *Function = ND->getAsFunction()) |
920 | T = Function->getCallResultType(); |
921 | else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) |
922 | T = Method->getSendResultType(); |
923 | else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND)) |
924 | T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext())); |
925 | else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND)) |
926 | T = Property->getType(); |
927 | else if (const auto *Value = dyn_cast<ValueDecl>(ND)) |
928 | T = Value->getType(); |
929 | |
930 | if (T.isNull()) |
931 | return QualType(); |
932 | |
933 | // Dig through references, function pointers, and block pointers to |
934 | // get down to the likely type of an expression when the entity is |
935 | // used. |
936 | do { |
937 | if (const auto *Ref = T->getAs<ReferenceType>()) { |
938 | T = Ref->getPointeeType(); |
939 | continue; |
940 | } |
941 | |
942 | if (const auto *Pointer = T->getAs<PointerType>()) { |
943 | if (Pointer->getPointeeType()->isFunctionType()) { |
944 | T = Pointer->getPointeeType(); |
945 | continue; |
946 | } |
947 | |
948 | break; |
949 | } |
950 | |
951 | if (const auto *Block = T->getAs<BlockPointerType>()) { |
952 | T = Block->getPointeeType(); |
953 | continue; |
954 | } |
955 | |
956 | if (const auto *Function = T->getAs<FunctionType>()) { |
957 | T = Function->getReturnType(); |
958 | continue; |
959 | } |
960 | |
961 | break; |
962 | } while (true); |
963 | |
964 | return T; |
965 | } |
966 | |
967 | unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) { |
968 | if (!ND) |
969 | return CCP_Unlikely; |
970 | |
971 | // Context-based decisions. |
972 | const DeclContext *LexicalDC = ND->getLexicalDeclContext(); |
973 | if (LexicalDC->isFunctionOrMethod()) { |
974 | // _cmd is relatively rare |
975 | if (const auto *ImplicitParam = dyn_cast<ImplicitParamDecl>(ND)) |
976 | if (ImplicitParam->getIdentifier() && |
977 | ImplicitParam->getIdentifier()->isStr("_cmd")) |
978 | return CCP_ObjC_cmd; |
979 | |
980 | return CCP_LocalDeclaration; |
981 | } |
982 | |
983 | const DeclContext *DC = ND->getDeclContext()->getRedeclContext(); |
984 | if (DC->isRecord() || isa<ObjCContainerDecl>(DC)) { |
985 | // Explicit destructor calls are very rare. |
986 | if (isa<CXXDestructorDecl>(ND)) |
987 | return CCP_Unlikely; |
988 | // Explicit operator and conversion function calls are also very rare. |
989 | auto DeclNameKind = ND->getDeclName().getNameKind(); |
990 | if (DeclNameKind == DeclarationName::CXXOperatorName || |
991 | DeclNameKind == DeclarationName::CXXLiteralOperatorName || |
992 | DeclNameKind == DeclarationName::CXXConversionFunctionName) |
993 | return CCP_Unlikely; |
994 | return CCP_MemberDeclaration; |
995 | } |
996 | |
997 | // Content-based decisions. |
998 | if (isa<EnumConstantDecl>(ND)) |
999 | return CCP_Constant; |
1000 | |
1001 | // Use CCP_Type for type declarations unless we're in a statement, Objective-C |
1002 | // message receiver, or parenthesized expression context. There, it's as |
1003 | // likely that the user will want to write a type as other declarations. |
1004 | if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) && |
1005 | !(CompletionContext.getKind() == CodeCompletionContext::CCC_Statement || |
1006 | CompletionContext.getKind() == |
1007 | CodeCompletionContext::CCC_ObjCMessageReceiver || |
1008 | CompletionContext.getKind() == |
1009 | CodeCompletionContext::CCC_ParenthesizedExpression)) |
1010 | return CCP_Type; |
1011 | |
1012 | return CCP_Declaration; |
1013 | } |
1014 | |
1015 | void ResultBuilder::AdjustResultPriorityForDecl(Result &R) { |
1016 | // If this is an Objective-C method declaration whose selector matches our |
1017 | // preferred selector, give it a priority boost. |
1018 | if (!PreferredSelector.isNull()) |
1019 | if (const auto *Method = dyn_cast<ObjCMethodDecl>(R.Declaration)) |
1020 | if (PreferredSelector == Method->getSelector()) |
1021 | R.Priority += CCD_SelectorMatch; |
1022 | |
1023 | // If we have a preferred type, adjust the priority for results with exactly- |
1024 | // matching or nearly-matching types. |
1025 | if (!PreferredType.isNull()) { |
1026 | QualType T = getDeclUsageType(SemaRef.Context, R.Declaration); |
1027 | if (!T.isNull()) { |
1028 | CanQualType TC = SemaRef.Context.getCanonicalType(T); |
1029 | // Check for exactly-matching types (modulo qualifiers). |
1030 | if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) |
1031 | R.Priority /= CCF_ExactTypeMatch; |
1032 | // Check for nearly-matching types, based on classification of each. |
1033 | else if ((getSimplifiedTypeClass(PreferredType) == |
1034 | getSimplifiedTypeClass(TC)) && |
1035 | !(PreferredType->isEnumeralType() && TC->isEnumeralType())) |
1036 | R.Priority /= CCF_SimilarTypeMatch; |
1037 | } |
1038 | } |
1039 | } |
1040 | |
1041 | static DeclContext::lookup_result getConstructors(ASTContext &Context, |
1042 | const CXXRecordDecl *Record) { |
1043 | QualType RecordTy = Context.getTypeDeclType(Record); |
1044 | DeclarationName ConstructorName = |
1045 | Context.DeclarationNames.getCXXConstructorName( |
1046 | Context.getCanonicalType(RecordTy)); |
1047 | return Record->lookup(ConstructorName); |
1048 | } |
1049 | |
1050 | void ResultBuilder::MaybeAddConstructorResults(Result R) { |
1051 | if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration || |
1052 | !CompletionContext.wantConstructorResults()) |
1053 | return; |
1054 | |
1055 | const NamedDecl *D = R.Declaration; |
1056 | const CXXRecordDecl *Record = nullptr; |
1057 | if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) |
1058 | Record = ClassTemplate->getTemplatedDecl(); |
1059 | else if ((Record = dyn_cast<CXXRecordDecl>(D))) { |
1060 | // Skip specializations and partial specializations. |
1061 | if (isa<ClassTemplateSpecializationDecl>(Record)) |
1062 | return; |
1063 | } else { |
1064 | // There are no constructors here. |
1065 | return; |
1066 | } |
1067 | |
1068 | Record = Record->getDefinition(); |
1069 | if (!Record) |
1070 | return; |
1071 | |
1072 | for (NamedDecl *Ctor : getConstructors(SemaRef.Context, Record)) { |
1073 | R.Declaration = Ctor; |
1074 | R.CursorKind = getCursorKindForDecl(R.Declaration); |
1075 | Results.push_back(R); |
1076 | } |
1077 | } |
1078 | |
1079 | static bool isConstructor(const Decl *ND) { |
1080 | if (const auto *Tmpl = dyn_cast<FunctionTemplateDecl>(ND)) |
1081 | ND = Tmpl->getTemplatedDecl(); |
1082 | return isa<CXXConstructorDecl>(ND); |
1083 | } |
1084 | |
1085 | void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) { |
1086 | assert(!ShadowMaps.empty() && "Must enter into a results scope")((void)0); |
1087 | |
1088 | if (R.Kind != Result::RK_Declaration) { |
1089 | // For non-declaration results, just add the result. |
1090 | Results.push_back(R); |
1091 | return; |
1092 | } |
1093 | |
1094 | // Look through using declarations. |
1095 | if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) { |
1096 | CodeCompletionResult Result(Using->getTargetDecl(), |
1097 | getBasePriority(Using->getTargetDecl()), |
1098 | R.Qualifier); |
1099 | Result.ShadowDecl = Using; |
1100 | MaybeAddResult(Result, CurContext); |
1101 | return; |
1102 | } |
1103 | |
1104 | const Decl *CanonDecl = R.Declaration->getCanonicalDecl(); |
1105 | unsigned IDNS = CanonDecl->getIdentifierNamespace(); |
1106 | |
1107 | bool AsNestedNameSpecifier = false; |
1108 | if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier)) |
1109 | return; |
1110 | |
1111 | // C++ constructors are never found by name lookup. |
1112 | if (isConstructor(R.Declaration)) |
1113 | return; |
1114 | |
1115 | ShadowMap &SMap = ShadowMaps.back(); |
1116 | ShadowMapEntry::iterator I, IEnd; |
1117 | ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName()); |
1118 | if (NamePos != SMap.end()) { |
1119 | I = NamePos->second.begin(); |
1120 | IEnd = NamePos->second.end(); |
1121 | } |
1122 | |
1123 | for (; I != IEnd; ++I) { |
1124 | const NamedDecl *ND = I->first; |
1125 | unsigned Index = I->second; |
1126 | if (ND->getCanonicalDecl() == CanonDecl) { |
1127 | // This is a redeclaration. Always pick the newer declaration. |
1128 | Results[Index].Declaration = R.Declaration; |
1129 | |
1130 | // We're done. |
1131 | return; |
1132 | } |
1133 | } |
1134 | |
1135 | // This is a new declaration in this scope. However, check whether this |
1136 | // declaration name is hidden by a similarly-named declaration in an outer |
1137 | // scope. |
1138 | std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end(); |
1139 | --SMEnd; |
1140 | for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) { |
1141 | ShadowMapEntry::iterator I, IEnd; |
1142 | ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName()); |
1143 | if (NamePos != SM->end()) { |
1144 | I = NamePos->second.begin(); |
1145 | IEnd = NamePos->second.end(); |
1146 | } |
1147 | for (; I != IEnd; ++I) { |
1148 | // A tag declaration does not hide a non-tag declaration. |
1149 | if (I->first->hasTagIdentifierNamespace() && |
1150 | (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary | |
1151 | Decl::IDNS_LocalExtern | Decl::IDNS_ObjCProtocol))) |
1152 | continue; |
1153 | |
1154 | // Protocols are in distinct namespaces from everything else. |
1155 | if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol) || |
1156 | (IDNS & Decl::IDNS_ObjCProtocol)) && |
1157 | I->first->getIdentifierNamespace() != IDNS) |
1158 | continue; |
1159 | |
1160 | // The newly-added result is hidden by an entry in the shadow map. |
1161 | if (CheckHiddenResult(R, CurContext, I->first)) |
1162 | return; |
1163 | |
1164 | break; |
1165 | } |
1166 | } |
1167 | |
1168 | // Make sure that any given declaration only shows up in the result set once. |
1169 | if (!AllDeclsFound.insert(CanonDecl).second) |
1170 | return; |
1171 | |
1172 | // If the filter is for nested-name-specifiers, then this result starts a |
1173 | // nested-name-specifier. |
1174 | if (AsNestedNameSpecifier) { |
1175 | R.StartsNestedNameSpecifier = true; |
1176 | R.Priority = CCP_NestedNameSpecifier; |
1177 | } else |
1178 | AdjustResultPriorityForDecl(R); |
1179 | |
1180 | // If this result is supposed to have an informative qualifier, add one. |
1181 | if (R.QualifierIsInformative && !R.Qualifier && |
1182 | !R.StartsNestedNameSpecifier) { |
1183 | const DeclContext *Ctx = R.Declaration->getDeclContext(); |
1184 | if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx)) |
1185 | R.Qualifier = |
1186 | NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace); |
1187 | else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx)) |
1188 | R.Qualifier = NestedNameSpecifier::Create( |
1189 | SemaRef.Context, nullptr, false, |
1190 | SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); |
1191 | else |
1192 | R.QualifierIsInformative = false; |
1193 | } |
1194 | |
1195 | // Insert this result into the set of results and into the current shadow |
1196 | // map. |
1197 | SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size()); |
1198 | Results.push_back(R); |
1199 | |
1200 | if (!AsNestedNameSpecifier) |
1201 | MaybeAddConstructorResults(R); |
1202 | } |
1203 | |
1204 | static void setInBaseClass(ResultBuilder::Result &R) { |
1205 | R.Priority += CCD_InBaseClass; |
1206 | R.InBaseClass = true; |
1207 | } |
1208 | |
1209 | enum class OverloadCompare { BothViable, Dominates, Dominated }; |
1210 | // Will Candidate ever be called on the object, when overloaded with Incumbent? |
1211 | // Returns Dominates if Candidate is always called, Dominated if Incumbent is |
1212 | // always called, BothViable if either may be called dependending on arguments. |
1213 | // Precondition: must actually be overloads! |
1214 | static OverloadCompare compareOverloads(const CXXMethodDecl &Candidate, |
1215 | const CXXMethodDecl &Incumbent, |
1216 | const Qualifiers &ObjectQuals, |
1217 | ExprValueKind ObjectKind) { |
1218 | // Base/derived shadowing is handled elsewhere. |
1219 | if (Candidate.getDeclContext() != Incumbent.getDeclContext()) |
1220 | return OverloadCompare::BothViable; |
1221 | if (Candidate.isVariadic() != Incumbent.isVariadic() || |
1222 | Candidate.getNumParams() != Incumbent.getNumParams() || |
1223 | Candidate.getMinRequiredArguments() != |
1224 | Incumbent.getMinRequiredArguments()) |
1225 | return OverloadCompare::BothViable; |
1226 | for (unsigned I = 0, E = Candidate.getNumParams(); I != E; ++I) |
1227 | if (Candidate.parameters()[I]->getType().getCanonicalType() != |
1228 | Incumbent.parameters()[I]->getType().getCanonicalType()) |
1229 | return OverloadCompare::BothViable; |
1230 | if (!llvm::empty(Candidate.specific_attrs<EnableIfAttr>()) || |
1231 | !llvm::empty(Incumbent.specific_attrs<EnableIfAttr>())) |
1232 | return OverloadCompare::BothViable; |
1233 | // At this point, we know calls can't pick one or the other based on |
1234 | // arguments, so one of the two must win. (Or both fail, handled elsewhere). |
1235 | RefQualifierKind CandidateRef = Candidate.getRefQualifier(); |
1236 | RefQualifierKind IncumbentRef = Incumbent.getRefQualifier(); |
1237 | if (CandidateRef != IncumbentRef) { |
1238 | // If the object kind is LValue/RValue, there's one acceptable ref-qualifier |
1239 | // and it can't be mixed with ref-unqualified overloads (in valid code). |
1240 | |
1241 | // For xvalue objects, we prefer the rvalue overload even if we have to |
1242 | // add qualifiers (which is rare, because const&& is rare). |
1243 | if (ObjectKind == clang::VK_XValue) |
1244 | return CandidateRef == RQ_RValue ? OverloadCompare::Dominates |
1245 | : OverloadCompare::Dominated; |
1246 | } |
1247 | // Now the ref qualifiers are the same (or we're in some invalid state). |
1248 | // So make some decision based on the qualifiers. |
1249 | Qualifiers CandidateQual = Candidate.getMethodQualifiers(); |
1250 | Qualifiers IncumbentQual = Incumbent.getMethodQualifiers(); |
1251 | bool CandidateSuperset = CandidateQual.compatiblyIncludes(IncumbentQual); |
1252 | bool IncumbentSuperset = IncumbentQual.compatiblyIncludes(CandidateQual); |
1253 | if (CandidateSuperset == IncumbentSuperset) |
1254 | return OverloadCompare::BothViable; |
1255 | return IncumbentSuperset ? OverloadCompare::Dominates |
1256 | : OverloadCompare::Dominated; |
1257 | } |
1258 | |
1259 | void ResultBuilder::AddResult(Result R, DeclContext *CurContext, |
1260 | NamedDecl *Hiding, bool InBaseClass = false) { |
1261 | if (R.Kind != Result::RK_Declaration) { |
1262 | // For non-declaration results, just add the result. |
1263 | Results.push_back(R); |
1264 | return; |
1265 | } |
1266 | |
1267 | // Look through using declarations. |
1268 | if (const auto *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) { |
1269 | CodeCompletionResult Result(Using->getTargetDecl(), |
1270 | getBasePriority(Using->getTargetDecl()), |
1271 | R.Qualifier); |
1272 | Result.ShadowDecl = Using; |
1273 | AddResult(Result, CurContext, Hiding); |
1274 | return; |
1275 | } |
1276 | |
1277 | bool AsNestedNameSpecifier = false; |
1278 | if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier)) |
1279 | return; |
1280 | |
1281 | // C++ constructors are never found by name lookup. |
1282 | if (isConstructor(R.Declaration)) |
1283 | return; |
1284 | |
1285 | if (Hiding && CheckHiddenResult(R, CurContext, Hiding)) |
1286 | return; |
1287 | |
1288 | // Make sure that any given declaration only shows up in the result set once. |
1289 | if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()).second) |
1290 | return; |
1291 | |
1292 | // If the filter is for nested-name-specifiers, then this result starts a |
1293 | // nested-name-specifier. |
1294 | if (AsNestedNameSpecifier) { |
1295 | R.StartsNestedNameSpecifier = true; |
1296 | R.Priority = CCP_NestedNameSpecifier; |
1297 | } else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && |
1298 | InBaseClass && |
1299 | isa<CXXRecordDecl>( |
1300 | R.Declaration->getDeclContext()->getRedeclContext())) |
1301 | R.QualifierIsInformative = true; |
1302 | |
1303 | // If this result is supposed to have an informative qualifier, add one. |
1304 | if (R.QualifierIsInformative && !R.Qualifier && |
1305 | !R.StartsNestedNameSpecifier) { |
1306 | const DeclContext *Ctx = R.Declaration->getDeclContext(); |
1307 | if (const auto *Namespace = dyn_cast<NamespaceDecl>(Ctx)) |
1308 | R.Qualifier = |
1309 | NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace); |
1310 | else if (const auto *Tag = dyn_cast<TagDecl>(Ctx)) |
1311 | R.Qualifier = NestedNameSpecifier::Create( |
1312 | SemaRef.Context, nullptr, false, |
1313 | SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); |
1314 | else |
1315 | R.QualifierIsInformative = false; |
1316 | } |
1317 | |
1318 | // Adjust the priority if this result comes from a base class. |
1319 | if (InBaseClass) |
1320 | setInBaseClass(R); |
1321 | |
1322 | AdjustResultPriorityForDecl(R); |
1323 | |
1324 | if (HasObjectTypeQualifiers) |
1325 | if (const auto *Method = dyn_cast<CXXMethodDecl>(R.Declaration)) |
1326 | if (Method->isInstance()) { |
1327 | Qualifiers MethodQuals = Method->getMethodQualifiers(); |
1328 | if (ObjectTypeQualifiers == MethodQuals) |
1329 | R.Priority += CCD_ObjectQualifierMatch; |
1330 | else if (ObjectTypeQualifiers - MethodQuals) { |
1331 | // The method cannot be invoked, because doing so would drop |
1332 | // qualifiers. |
1333 | return; |
1334 | } |
1335 | // Detect cases where a ref-qualified method cannot be invoked. |
1336 | switch (Method->getRefQualifier()) { |
1337 | case RQ_LValue: |
1338 | if (ObjectKind != VK_LValue && !MethodQuals.hasConst()) |
1339 | return; |
1340 | break; |
1341 | case RQ_RValue: |
1342 | if (ObjectKind == VK_LValue) |
1343 | return; |
1344 | break; |
1345 | case RQ_None: |
1346 | break; |
1347 | } |
1348 | |
1349 | /// Check whether this dominates another overloaded method, which should |
1350 | /// be suppressed (or vice versa). |
1351 | /// Motivating case is const_iterator begin() const vs iterator begin(). |
1352 | auto &OverloadSet = OverloadMap[std::make_pair( |
1353 | CurContext, Method->getDeclName().getAsOpaqueInteger())]; |
1354 | for (const DeclIndexPair Entry : OverloadSet) { |
1355 | Result &Incumbent = Results[Entry.second]; |
1356 | switch (compareOverloads(*Method, |
1357 | *cast<CXXMethodDecl>(Incumbent.Declaration), |
1358 | ObjectTypeQualifiers, ObjectKind)) { |
1359 | case OverloadCompare::Dominates: |
1360 | // Replace the dominated overload with this one. |
1361 | // FIXME: if the overload dominates multiple incumbents then we |
1362 | // should remove all. But two overloads is by far the common case. |
1363 | Incumbent = std::move(R); |
1364 | return; |
1365 | case OverloadCompare::Dominated: |
1366 | // This overload can't be called, drop it. |
1367 | return; |
1368 | case OverloadCompare::BothViable: |
1369 | break; |
1370 | } |
1371 | } |
1372 | OverloadSet.Add(Method, Results.size()); |
1373 | } |
1374 | |
1375 | // Insert this result into the set of results. |
1376 | Results.push_back(R); |
1377 | |
1378 | if (!AsNestedNameSpecifier) |
1379 | MaybeAddConstructorResults(R); |
1380 | } |
1381 | |
1382 | void ResultBuilder::AddResult(Result R) { |
1383 | assert(R.Kind != Result::RK_Declaration &&((void)0) |
1384 | "Declaration results need more context")((void)0); |
1385 | Results.push_back(R); |
1386 | } |
1387 | |
1388 | /// Enter into a new scope. |
1389 | void ResultBuilder::EnterNewScope() { ShadowMaps.emplace_back(); } |
1390 | |
1391 | /// Exit from the current scope. |
1392 | void ResultBuilder::ExitScope() { |
1393 | ShadowMaps.pop_back(); |
1394 | } |
1395 | |
1396 | /// Determines whether this given declaration will be found by |
1397 | /// ordinary name lookup. |
1398 | bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const { |
1399 | ND = ND->getUnderlyingDecl(); |
1400 | |
1401 | // If name lookup finds a local extern declaration, then we are in a |
1402 | // context where it behaves like an ordinary name. |
1403 | unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; |
1404 | if (SemaRef.getLangOpts().CPlusPlus) |
1405 | IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; |
1406 | else if (SemaRef.getLangOpts().ObjC) { |
1407 | if (isa<ObjCIvarDecl>(ND)) |
1408 | return true; |
1409 | } |
1410 | |
1411 | return ND->getIdentifierNamespace() & IDNS; |
1412 | } |
1413 | |
1414 | /// Determines whether this given declaration will be found by |
1415 | /// ordinary name lookup but is not a type name. |
1416 | bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const { |
1417 | ND = ND->getUnderlyingDecl(); |
1418 | if (isa<TypeDecl>(ND)) |
1419 | return false; |
1420 | // Objective-C interfaces names are not filtered by this method because they |
1421 | // can be used in a class property expression. We can still filter out |
1422 | // @class declarations though. |
1423 | if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) { |
1424 | if (!ID->getDefinition()) |
1425 | return false; |
1426 | } |
1427 | |
1428 | unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; |
1429 | if (SemaRef.getLangOpts().CPlusPlus) |
1430 | IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; |
1431 | else if (SemaRef.getLangOpts().ObjC) { |
1432 | if (isa<ObjCIvarDecl>(ND)) |
1433 | return true; |
1434 | } |
1435 | |
1436 | return ND->getIdentifierNamespace() & IDNS; |
1437 | } |
1438 | |
1439 | bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const { |
1440 | if (!IsOrdinaryNonTypeName(ND)) |
1441 | return 0; |
1442 | |
1443 | if (const auto *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl())) |
1444 | if (VD->getType()->isIntegralOrEnumerationType()) |
1445 | return true; |
1446 | |
1447 | return false; |
1448 | } |
1449 | |
1450 | /// Determines whether this given declaration will be found by |
1451 | /// ordinary name lookup. |
1452 | bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const { |
1453 | ND = ND->getUnderlyingDecl(); |
1454 | |
1455 | unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; |
1456 | if (SemaRef.getLangOpts().CPlusPlus) |
1457 | IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace; |
1458 | |
1459 | return (ND->getIdentifierNamespace() & IDNS) && !isa<ValueDecl>(ND) && |
1460 | !isa<FunctionTemplateDecl>(ND) && !isa<ObjCPropertyDecl>(ND); |
1461 | } |
1462 | |
1463 | /// Determines whether the given declaration is suitable as the |
1464 | /// start of a C++ nested-name-specifier, e.g., a class or namespace. |
1465 | bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const { |
1466 | // Allow us to find class templates, too. |
1467 | if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) |
1468 | ND = ClassTemplate->getTemplatedDecl(); |
1469 | |
1470 | return SemaRef.isAcceptableNestedNameSpecifier(ND); |
1471 | } |
1472 | |
1473 | /// Determines whether the given declaration is an enumeration. |
1474 | bool ResultBuilder::IsEnum(const NamedDecl *ND) const { |
1475 | return isa<EnumDecl>(ND); |
1476 | } |
1477 | |
1478 | /// Determines whether the given declaration is a class or struct. |
1479 | bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const { |
1480 | // Allow us to find class templates, too. |
1481 | if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) |
1482 | ND = ClassTemplate->getTemplatedDecl(); |
1483 | |
1484 | // For purposes of this check, interfaces match too. |
1485 | if (const auto *RD = dyn_cast<RecordDecl>(ND)) |
1486 | return RD->getTagKind() == TTK_Class || RD->getTagKind() == TTK_Struct || |
1487 | RD->getTagKind() == TTK_Interface; |
1488 | |
1489 | return false; |
1490 | } |
1491 | |
1492 | /// Determines whether the given declaration is a union. |
1493 | bool ResultBuilder::IsUnion(const NamedDecl *ND) const { |
1494 | // Allow us to find class templates, too. |
1495 | if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) |
1496 | ND = ClassTemplate->getTemplatedDecl(); |
1497 | |
1498 | if (const auto *RD = dyn_cast<RecordDecl>(ND)) |
1499 | return RD->getTagKind() == TTK_Union; |
1500 | |
1501 | return false; |
1502 | } |
1503 | |
1504 | /// Determines whether the given declaration is a namespace. |
1505 | bool ResultBuilder::IsNamespace(const NamedDecl *ND) const { |
1506 | return isa<NamespaceDecl>(ND); |
1507 | } |
1508 | |
1509 | /// Determines whether the given declaration is a namespace or |
1510 | /// namespace alias. |
1511 | bool ResultBuilder::IsNamespaceOrAlias(const NamedDecl *ND) const { |
1512 | return isa<NamespaceDecl>(ND->getUnderlyingDecl()); |
1513 | } |
1514 | |
1515 | /// Determines whether the given declaration is a type. |
1516 | bool ResultBuilder::IsType(const NamedDecl *ND) const { |
1517 | ND = ND->getUnderlyingDecl(); |
1518 | return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND); |
1519 | } |
1520 | |
1521 | /// Determines which members of a class should be visible via |
1522 | /// "." or "->". Only value declarations, nested name specifiers, and |
1523 | /// using declarations thereof should show up. |
1524 | bool ResultBuilder::IsMember(const NamedDecl *ND) const { |
1525 | ND = ND->getUnderlyingDecl(); |
1526 | return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) || |
1527 | isa<ObjCPropertyDecl>(ND); |
1528 | } |
1529 | |
1530 | static bool isObjCReceiverType(ASTContext &C, QualType T) { |
1531 | T = C.getCanonicalType(T); |
1532 | switch (T->getTypeClass()) { |
1533 | case Type::ObjCObject: |
1534 | case Type::ObjCInterface: |
1535 | case Type::ObjCObjectPointer: |
1536 | return true; |
1537 | |
1538 | case Type::Builtin: |
1539 | switch (cast<BuiltinType>(T)->getKind()) { |
1540 | case BuiltinType::ObjCId: |
1541 | case BuiltinType::ObjCClass: |
1542 | case BuiltinType::ObjCSel: |
1543 | return true; |
1544 | |
1545 | default: |
1546 | break; |
1547 | } |
1548 | return false; |
1549 | |
1550 | default: |
1551 | break; |
1552 | } |
1553 | |
1554 | if (!C.getLangOpts().CPlusPlus) |
1555 | return false; |
1556 | |
1557 | // FIXME: We could perform more analysis here to determine whether a |
1558 | // particular class type has any conversions to Objective-C types. For now, |
1559 | // just accept all class types. |
1560 | return T->isDependentType() || T->isRecordType(); |
1561 | } |
1562 | |
1563 | bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const { |
1564 | QualType T = getDeclUsageType(SemaRef.Context, ND); |
1565 | if (T.isNull()) |
1566 | return false; |
1567 | |
1568 | T = SemaRef.Context.getBaseElementType(T); |
1569 | return isObjCReceiverType(SemaRef.Context, T); |
1570 | } |
1571 | |
1572 | bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture( |
1573 | const NamedDecl *ND) const { |
1574 | if (IsObjCMessageReceiver(ND)) |
1575 | return true; |
1576 | |
1577 | const auto *Var = dyn_cast<VarDecl>(ND); |
1578 | if (!Var) |
1579 | return false; |
1580 | |
1581 | return Var->hasLocalStorage() && !Var->hasAttr<BlocksAttr>(); |
1582 | } |
1583 | |
1584 | bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const { |
1585 | if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) || |
1586 | (!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND))) |
1587 | return false; |
1588 | |
1589 | QualType T = getDeclUsageType(SemaRef.Context, ND); |
1590 | if (T.isNull()) |
1591 | return false; |
1592 | |
1593 | T = SemaRef.Context.getBaseElementType(T); |
1594 | return T->isObjCObjectType() || T->isObjCObjectPointerType() || |
1595 | T->isObjCIdType() || |
1596 | (SemaRef.getLangOpts().CPlusPlus && T->isRecordType()); |
1597 | } |
1598 | |
1599 | bool ResultBuilder::IsImpossibleToSatisfy(const NamedDecl *ND) const { |
1600 | return false; |
1601 | } |
1602 | |
1603 | /// Determines whether the given declaration is an Objective-C |
1604 | /// instance variable. |
1605 | bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const { |
1606 | return isa<ObjCIvarDecl>(ND); |
1607 | } |
1608 | |
1609 | namespace { |
1610 | |
1611 | /// Visible declaration consumer that adds a code-completion result |
1612 | /// for each visible declaration. |
1613 | class CodeCompletionDeclConsumer : public VisibleDeclConsumer { |
1614 | ResultBuilder &Results; |
1615 | DeclContext *InitialLookupCtx; |
1616 | // NamingClass and BaseType are used for access-checking. See |
1617 | // Sema::IsSimplyAccessible for details. |
1618 | CXXRecordDecl *NamingClass; |
1619 | QualType BaseType; |
1620 | std::vector<FixItHint> FixIts; |
1621 | |
1622 | public: |
1623 | CodeCompletionDeclConsumer( |
1624 | ResultBuilder &Results, DeclContext *InitialLookupCtx, |
1625 | QualType BaseType = QualType(), |
1626 | std::vector<FixItHint> FixIts = std::vector<FixItHint>()) |
1627 | : Results(Results), InitialLookupCtx(InitialLookupCtx), |
1628 | FixIts(std::move(FixIts)) { |
1629 | NamingClass = llvm::dyn_cast<CXXRecordDecl>(InitialLookupCtx); |
1630 | // If BaseType was not provided explicitly, emulate implicit 'this->'. |
1631 | if (BaseType.isNull()) { |
1632 | auto ThisType = Results.getSema().getCurrentThisType(); |
1633 | if (!ThisType.isNull()) { |
1634 | assert(ThisType->isPointerType())((void)0); |
1635 | BaseType = ThisType->getPointeeType(); |
1636 | if (!NamingClass) |
1637 | NamingClass = BaseType->getAsCXXRecordDecl(); |
1638 | } |
1639 | } |
1640 | this->BaseType = BaseType; |
1641 | } |
1642 | |
1643 | void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, |
1644 | bool InBaseClass) override { |
1645 | ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr, |
1646 | false, IsAccessible(ND, Ctx), FixIts); |
1647 | Results.AddResult(Result, InitialLookupCtx, Hiding, InBaseClass); |
1648 | } |
1649 | |
1650 | void EnteredContext(DeclContext *Ctx) override { |
1651 | Results.addVisitedContext(Ctx); |
1652 | } |
1653 | |
1654 | private: |
1655 | bool IsAccessible(NamedDecl *ND, DeclContext *Ctx) { |
1656 | // Naming class to use for access check. In most cases it was provided |
1657 | // explicitly (e.g. member access (lhs.foo) or qualified lookup (X::)), |
1658 | // for unqualified lookup we fallback to the \p Ctx in which we found the |
1659 | // member. |
1660 | auto *NamingClass = this->NamingClass; |
1661 | QualType BaseType = this->BaseType; |
1662 | if (auto *Cls = llvm::dyn_cast_or_null<CXXRecordDecl>(Ctx)) { |
1663 | if (!NamingClass) |
1664 | NamingClass = Cls; |
1665 | // When we emulate implicit 'this->' in an unqualified lookup, we might |
1666 | // end up with an invalid naming class. In that case, we avoid emulating |
1667 | // 'this->' qualifier to satisfy preconditions of the access checking. |
1668 | if (NamingClass->getCanonicalDecl() != Cls->getCanonicalDecl() && |
1669 | !NamingClass->isDerivedFrom(Cls)) { |
1670 | NamingClass = Cls; |
1671 | BaseType = QualType(); |
1672 | } |
1673 | } else { |
1674 | // The decl was found outside the C++ class, so only ObjC access checks |
1675 | // apply. Those do not rely on NamingClass and BaseType, so we clear them |
1676 | // out. |
1677 | NamingClass = nullptr; |
1678 | BaseType = QualType(); |
1679 | } |
1680 | return Results.getSema().IsSimplyAccessible(ND, NamingClass, BaseType); |
1681 | } |
1682 | }; |
1683 | } // namespace |
1684 | |
1685 | /// Add type specifiers for the current language as keyword results. |
1686 | static void AddTypeSpecifierResults(const LangOptions &LangOpts, |
1687 | ResultBuilder &Results) { |
1688 | typedef CodeCompletionResult Result; |
1689 | Results.AddResult(Result("short", CCP_Type)); |
1690 | Results.AddResult(Result("long", CCP_Type)); |
1691 | Results.AddResult(Result("signed", CCP_Type)); |
1692 | Results.AddResult(Result("unsigned", CCP_Type)); |
1693 | Results.AddResult(Result("void", CCP_Type)); |
1694 | Results.AddResult(Result("char", CCP_Type)); |
1695 | Results.AddResult(Result("int", CCP_Type)); |
1696 | Results.AddResult(Result("float", CCP_Type)); |
1697 | Results.AddResult(Result("double", CCP_Type)); |
1698 | Results.AddResult(Result("enum", CCP_Type)); |
1699 | Results.AddResult(Result("struct", CCP_Type)); |
1700 | Results.AddResult(Result("union", CCP_Type)); |
1701 | Results.AddResult(Result("const", CCP_Type)); |
1702 | Results.AddResult(Result("volatile", CCP_Type)); |
1703 | |
1704 | if (LangOpts.C99) { |
1705 | // C99-specific |
1706 | Results.AddResult(Result("_Complex", CCP_Type)); |
1707 | Results.AddResult(Result("_Imaginary", CCP_Type)); |
1708 | Results.AddResult(Result("_Bool", CCP_Type)); |
1709 | Results.AddResult(Result("restrict", CCP_Type)); |
1710 | } |
1711 | |
1712 | CodeCompletionBuilder Builder(Results.getAllocator(), |
1713 | Results.getCodeCompletionTUInfo()); |
1714 | if (LangOpts.CPlusPlus) { |
1715 | // C++-specific |
1716 | Results.AddResult( |
1717 | Result("bool", CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0))); |
1718 | Results.AddResult(Result("class", CCP_Type)); |
1719 | Results.AddResult(Result("wchar_t", CCP_Type)); |
1720 | |
1721 | // typename name |
1722 | Builder.AddTypedTextChunk("typename"); |
1723 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
1724 | Builder.AddPlaceholderChunk("name"); |
1725 | Results.AddResult(Result(Builder.TakeString())); |
1726 | |
1727 | if (LangOpts.CPlusPlus11) { |
1728 | Results.AddResult(Result("auto", CCP_Type)); |
1729 | Results.AddResult(Result("char16_t", CCP_Type)); |
1730 | Results.AddResult(Result("char32_t", CCP_Type)); |
1731 | |
1732 | Builder.AddTypedTextChunk("decltype"); |
1733 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
1734 | Builder.AddPlaceholderChunk("expression"); |
1735 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
1736 | Results.AddResult(Result(Builder.TakeString())); |
1737 | } |
1738 | } else |
1739 | Results.AddResult(Result("__auto_type", CCP_Type)); |
1740 | |
1741 | // GNU keywords |
1742 | if (LangOpts.GNUKeywords) { |
1743 | // FIXME: Enable when we actually support decimal floating point. |
1744 | // Results.AddResult(Result("_Decimal32")); |
1745 | // Results.AddResult(Result("_Decimal64")); |
1746 | // Results.AddResult(Result("_Decimal128")); |
1747 | |
1748 | Builder.AddTypedTextChunk("typeof"); |
1749 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
1750 | Builder.AddPlaceholderChunk("expression"); |
1751 | Results.AddResult(Result(Builder.TakeString())); |
1752 | |
1753 | Builder.AddTypedTextChunk("typeof"); |
1754 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
1755 | Builder.AddPlaceholderChunk("type"); |
1756 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
1757 | Results.AddResult(Result(Builder.TakeString())); |
1758 | } |
1759 | |
1760 | // Nullability |
1761 | Results.AddResult(Result("_Nonnull", CCP_Type)); |
1762 | Results.AddResult(Result("_Null_unspecified", CCP_Type)); |
1763 | Results.AddResult(Result("_Nullable", CCP_Type)); |
1764 | } |
1765 | |
1766 | static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC, |
1767 | const LangOptions &LangOpts, |
1768 | ResultBuilder &Results) { |
1769 | typedef CodeCompletionResult Result; |
1770 | // Note: we don't suggest either "auto" or "register", because both |
1771 | // are pointless as storage specifiers. Elsewhere, we suggest "auto" |
1772 | // in C++0x as a type specifier. |
1773 | Results.AddResult(Result("extern")); |
1774 | Results.AddResult(Result("static")); |
1775 | |
1776 | if (LangOpts.CPlusPlus11) { |
1777 | CodeCompletionAllocator &Allocator = Results.getAllocator(); |
1778 | CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); |
1779 | |
1780 | // alignas |
1781 | Builder.AddTypedTextChunk("alignas"); |
1782 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
1783 | Builder.AddPlaceholderChunk("expression"); |
1784 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
1785 | Results.AddResult(Result(Builder.TakeString())); |
1786 | |
1787 | Results.AddResult(Result("constexpr")); |
1788 | Results.AddResult(Result("thread_local")); |
1789 | } |
1790 | } |
1791 | |
1792 | static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC, |
1793 | const LangOptions &LangOpts, |
1794 | ResultBuilder &Results) { |
1795 | typedef CodeCompletionResult Result; |
1796 | switch (CCC) { |
1797 | case Sema::PCC_Class: |
1798 | case Sema::PCC_MemberTemplate: |
1799 | if (LangOpts.CPlusPlus) { |
1800 | Results.AddResult(Result("explicit")); |
1801 | Results.AddResult(Result("friend")); |
1802 | Results.AddResult(Result("mutable")); |
1803 | Results.AddResult(Result("virtual")); |
1804 | } |
1805 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; |
1806 | |
1807 | case Sema::PCC_ObjCInterface: |
1808 | case Sema::PCC_ObjCImplementation: |
1809 | case Sema::PCC_Namespace: |
1810 | case Sema::PCC_Template: |
1811 | if (LangOpts.CPlusPlus || LangOpts.C99) |
1812 | Results.AddResult(Result("inline")); |
1813 | break; |
1814 | |
1815 | case Sema::PCC_ObjCInstanceVariableList: |
1816 | case Sema::PCC_Expression: |
1817 | case Sema::PCC_Statement: |
1818 | case Sema::PCC_ForInit: |
1819 | case Sema::PCC_Condition: |
1820 | case Sema::PCC_RecoveryInFunction: |
1821 | case Sema::PCC_Type: |
1822 | case Sema::PCC_ParenthesizedExpression: |
1823 | case Sema::PCC_LocalDeclarationSpecifiers: |
1824 | break; |
1825 | } |
1826 | } |
1827 | |
1828 | static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt); |
1829 | static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt); |
1830 | static void AddObjCVisibilityResults(const LangOptions &LangOpts, |
1831 | ResultBuilder &Results, bool NeedAt); |
1832 | static void AddObjCImplementationResults(const LangOptions &LangOpts, |
1833 | ResultBuilder &Results, bool NeedAt); |
1834 | static void AddObjCInterfaceResults(const LangOptions &LangOpts, |
1835 | ResultBuilder &Results, bool NeedAt); |
1836 | static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt); |
1837 | |
1838 | static void AddTypedefResult(ResultBuilder &Results) { |
1839 | CodeCompletionBuilder Builder(Results.getAllocator(), |
1840 | Results.getCodeCompletionTUInfo()); |
1841 | Builder.AddTypedTextChunk("typedef"); |
1842 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
1843 | Builder.AddPlaceholderChunk("type"); |
1844 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
1845 | Builder.AddPlaceholderChunk("name"); |
1846 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
1847 | Results.AddResult(CodeCompletionResult(Builder.TakeString())); |
1848 | } |
1849 | |
1850 | // using name = type |
1851 | static void AddUsingAliasResult(CodeCompletionBuilder &Builder, |
1852 | ResultBuilder &Results) { |
1853 | Builder.AddTypedTextChunk("using"); |
1854 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
1855 | Builder.AddPlaceholderChunk("name"); |
1856 | Builder.AddChunk(CodeCompletionString::CK_Equal); |
1857 | Builder.AddPlaceholderChunk("type"); |
1858 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
1859 | Results.AddResult(CodeCompletionResult(Builder.TakeString())); |
1860 | } |
1861 | |
1862 | static bool WantTypesInContext(Sema::ParserCompletionContext CCC, |
1863 | const LangOptions &LangOpts) { |
1864 | switch (CCC) { |
1865 | case Sema::PCC_Namespace: |
1866 | case Sema::PCC_Class: |
1867 | case Sema::PCC_ObjCInstanceVariableList: |
1868 | case Sema::PCC_Template: |
1869 | case Sema::PCC_MemberTemplate: |
1870 | case Sema::PCC_Statement: |
1871 | case Sema::PCC_RecoveryInFunction: |
1872 | case Sema::PCC_Type: |
1873 | case Sema::PCC_ParenthesizedExpression: |
1874 | case Sema::PCC_LocalDeclarationSpecifiers: |
1875 | return true; |
1876 | |
1877 | case Sema::PCC_Expression: |
1878 | case Sema::PCC_Condition: |
1879 | return LangOpts.CPlusPlus; |
1880 | |
1881 | case Sema::PCC_ObjCInterface: |
1882 | case Sema::PCC_ObjCImplementation: |
1883 | return false; |
1884 | |
1885 | case Sema::PCC_ForInit: |
1886 | return LangOpts.CPlusPlus || LangOpts.ObjC || LangOpts.C99; |
1887 | } |
1888 | |
1889 | llvm_unreachable("Invalid ParserCompletionContext!")__builtin_unreachable(); |
1890 | } |
1891 | |
1892 | static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context, |
1893 | const Preprocessor &PP) { |
1894 | PrintingPolicy Policy = Sema::getPrintingPolicy(Context, PP); |
1895 | Policy.AnonymousTagLocations = false; |
1896 | Policy.SuppressStrongLifetime = true; |
1897 | Policy.SuppressUnwrittenScope = true; |
1898 | Policy.SuppressScope = true; |
1899 | return Policy; |
1900 | } |
1901 | |
1902 | /// Retrieve a printing policy suitable for code completion. |
1903 | static PrintingPolicy getCompletionPrintingPolicy(Sema &S) { |
1904 | return getCompletionPrintingPolicy(S.Context, S.PP); |
1905 | } |
1906 | |
1907 | /// Retrieve the string representation of the given type as a string |
1908 | /// that has the appropriate lifetime for code completion. |
1909 | /// |
1910 | /// This routine provides a fast path where we provide constant strings for |
1911 | /// common type names. |
1912 | static const char *GetCompletionTypeString(QualType T, ASTContext &Context, |
1913 | const PrintingPolicy &Policy, |
1914 | CodeCompletionAllocator &Allocator) { |
1915 | if (!T.getLocalQualifiers()) { |
1916 | // Built-in type names are constant strings. |
1917 | if (const BuiltinType *BT = dyn_cast<BuiltinType>(T)) |
1918 | return BT->getNameAsCString(Policy); |
1919 | |
1920 | // Anonymous tag types are constant strings. |
1921 | if (const TagType *TagT = dyn_cast<TagType>(T)) |
1922 | if (TagDecl *Tag = TagT->getDecl()) |
1923 | if (!Tag->hasNameForLinkage()) { |
1924 | switch (Tag->getTagKind()) { |
1925 | case TTK_Struct: |
1926 | return "struct <anonymous>"; |
1927 | case TTK_Interface: |
1928 | return "__interface <anonymous>"; |
1929 | case TTK_Class: |
1930 | return "class <anonymous>"; |
1931 | case TTK_Union: |
1932 | return "union <anonymous>"; |
1933 | case TTK_Enum: |
1934 | return "enum <anonymous>"; |
1935 | } |
1936 | } |
1937 | } |
1938 | |
1939 | // Slow path: format the type as a string. |
1940 | std::string Result; |
1941 | T.getAsStringInternal(Result, Policy); |
1942 | return Allocator.CopyString(Result); |
1943 | } |
1944 | |
1945 | /// Add a completion for "this", if we're in a member function. |
1946 | static void addThisCompletion(Sema &S, ResultBuilder &Results) { |
1947 | QualType ThisTy = S.getCurrentThisType(); |
1948 | if (ThisTy.isNull()) |
1949 | return; |
1950 | |
1951 | CodeCompletionAllocator &Allocator = Results.getAllocator(); |
1952 | CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); |
1953 | PrintingPolicy Policy = getCompletionPrintingPolicy(S); |
1954 | Builder.AddResultTypeChunk( |
1955 | GetCompletionTypeString(ThisTy, S.Context, Policy, Allocator)); |
1956 | Builder.AddTypedTextChunk("this"); |
1957 | Results.AddResult(CodeCompletionResult(Builder.TakeString())); |
1958 | } |
1959 | |
1960 | static void AddStaticAssertResult(CodeCompletionBuilder &Builder, |
1961 | ResultBuilder &Results, |
1962 | const LangOptions &LangOpts) { |
1963 | if (!LangOpts.CPlusPlus11) |
1964 | return; |
1965 | |
1966 | Builder.AddTypedTextChunk("static_assert"); |
1967 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
1968 | Builder.AddPlaceholderChunk("expression"); |
1969 | Builder.AddChunk(CodeCompletionString::CK_Comma); |
1970 | Builder.AddPlaceholderChunk("message"); |
1971 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
1972 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
1973 | Results.AddResult(CodeCompletionResult(Builder.TakeString())); |
1974 | } |
1975 | |
1976 | static void AddOverrideResults(ResultBuilder &Results, |
1977 | const CodeCompletionContext &CCContext, |
1978 | CodeCompletionBuilder &Builder) { |
1979 | Sema &S = Results.getSema(); |
1980 | const auto *CR = llvm::dyn_cast<CXXRecordDecl>(S.CurContext); |
1981 | // If not inside a class/struct/union return empty. |
1982 | if (!CR) |
1983 | return; |
1984 | // First store overrides within current class. |
1985 | // These are stored by name to make querying fast in the later step. |
1986 | llvm::StringMap<std::vector<FunctionDecl *>> Overrides; |
1987 | for (auto *Method : CR->methods()) { |
1988 | if (!Method->isVirtual() || !Method->getIdentifier()) |
1989 | continue; |
1990 | Overrides[Method->getName()].push_back(Method); |
1991 | } |
1992 | |
1993 | for (const auto &Base : CR->bases()) { |
1994 | const auto *BR = Base.getType().getTypePtr()->getAsCXXRecordDecl(); |
1995 | if (!BR) |
1996 | continue; |
1997 | for (auto *Method : BR->methods()) { |
1998 | if (!Method->isVirtual() || !Method->getIdentifier()) |
1999 | continue; |
2000 | const auto it = Overrides.find(Method->getName()); |
2001 | bool IsOverriden = false; |
2002 | if (it != Overrides.end()) { |
2003 | for (auto *MD : it->second) { |
2004 | // If the method in current body is not an overload of this virtual |
2005 | // function, then it overrides this one. |
2006 | if (!S.IsOverload(MD, Method, false)) { |
2007 | IsOverriden = true; |
2008 | break; |
2009 | } |
2010 | } |
2011 | } |
2012 | if (!IsOverriden) { |
2013 | // Generates a new CodeCompletionResult by taking this function and |
2014 | // converting it into an override declaration with only one chunk in the |
2015 | // final CodeCompletionString as a TypedTextChunk. |
2016 | std::string OverrideSignature; |
2017 | llvm::raw_string_ostream OS(OverrideSignature); |
2018 | CodeCompletionResult CCR(Method, 0); |
2019 | PrintingPolicy Policy = |
2020 | getCompletionPrintingPolicy(S.getASTContext(), S.getPreprocessor()); |
2021 | auto *CCS = CCR.createCodeCompletionStringForOverride( |
2022 | S.getPreprocessor(), S.getASTContext(), Builder, |
2023 | /*IncludeBriefComments=*/false, CCContext, Policy); |
2024 | Results.AddResult(CodeCompletionResult(CCS, Method, CCP_CodePattern)); |
2025 | } |
2026 | } |
2027 | } |
2028 | } |
2029 | |
2030 | /// Add language constructs that show up for "ordinary" names. |
2031 | static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S, |
2032 | Sema &SemaRef, ResultBuilder &Results) { |
2033 | CodeCompletionAllocator &Allocator = Results.getAllocator(); |
2034 | CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); |
2035 | |
2036 | typedef CodeCompletionResult Result; |
2037 | switch (CCC) { |
2038 | case Sema::PCC_Namespace: |
2039 | if (SemaRef.getLangOpts().CPlusPlus) { |
2040 | if (Results.includeCodePatterns()) { |
2041 | // namespace <identifier> { declarations } |
2042 | Builder.AddTypedTextChunk("namespace"); |
2043 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2044 | Builder.AddPlaceholderChunk("identifier"); |
2045 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2046 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
2047 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2048 | Builder.AddPlaceholderChunk("declarations"); |
2049 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2050 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
2051 | Results.AddResult(Result(Builder.TakeString())); |
2052 | } |
2053 | |
2054 | // namespace identifier = identifier ; |
2055 | Builder.AddTypedTextChunk("namespace"); |
2056 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2057 | Builder.AddPlaceholderChunk("name"); |
2058 | Builder.AddChunk(CodeCompletionString::CK_Equal); |
2059 | Builder.AddPlaceholderChunk("namespace"); |
2060 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2061 | Results.AddResult(Result(Builder.TakeString())); |
2062 | |
2063 | // Using directives |
2064 | Builder.AddTypedTextChunk("using namespace"); |
2065 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2066 | Builder.AddPlaceholderChunk("identifier"); |
2067 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2068 | Results.AddResult(Result(Builder.TakeString())); |
2069 | |
2070 | // asm(string-literal) |
2071 | Builder.AddTypedTextChunk("asm"); |
2072 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2073 | Builder.AddPlaceholderChunk("string-literal"); |
2074 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2075 | Results.AddResult(Result(Builder.TakeString())); |
2076 | |
2077 | if (Results.includeCodePatterns()) { |
2078 | // Explicit template instantiation |
2079 | Builder.AddTypedTextChunk("template"); |
2080 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2081 | Builder.AddPlaceholderChunk("declaration"); |
2082 | Results.AddResult(Result(Builder.TakeString())); |
2083 | } else { |
2084 | Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword)); |
2085 | } |
2086 | } |
2087 | |
2088 | if (SemaRef.getLangOpts().ObjC) |
2089 | AddObjCTopLevelResults(Results, true); |
2090 | |
2091 | AddTypedefResult(Results); |
2092 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; |
2093 | |
2094 | case Sema::PCC_Class: |
2095 | if (SemaRef.getLangOpts().CPlusPlus) { |
2096 | // Using declaration |
2097 | Builder.AddTypedTextChunk("using"); |
2098 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2099 | Builder.AddPlaceholderChunk("qualifier"); |
2100 | Builder.AddTextChunk("::"); |
2101 | Builder.AddPlaceholderChunk("name"); |
2102 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2103 | Results.AddResult(Result(Builder.TakeString())); |
2104 | |
2105 | if (SemaRef.getLangOpts().CPlusPlus11) |
2106 | AddUsingAliasResult(Builder, Results); |
2107 | |
2108 | // using typename qualifier::name (only in a dependent context) |
2109 | if (SemaRef.CurContext->isDependentContext()) { |
2110 | Builder.AddTypedTextChunk("using typename"); |
2111 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2112 | Builder.AddPlaceholderChunk("qualifier"); |
2113 | Builder.AddTextChunk("::"); |
2114 | Builder.AddPlaceholderChunk("name"); |
2115 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2116 | Results.AddResult(Result(Builder.TakeString())); |
2117 | } |
2118 | |
2119 | AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts()); |
2120 | |
2121 | if (CCC == Sema::PCC_Class) { |
2122 | AddTypedefResult(Results); |
2123 | |
2124 | bool IsNotInheritanceScope = |
2125 | !(S->getFlags() & Scope::ClassInheritanceScope); |
2126 | // public: |
2127 | Builder.AddTypedTextChunk("public"); |
2128 | if (IsNotInheritanceScope && Results.includeCodePatterns()) |
2129 | Builder.AddChunk(CodeCompletionString::CK_Colon); |
2130 | Results.AddResult(Result(Builder.TakeString())); |
2131 | |
2132 | // protected: |
2133 | Builder.AddTypedTextChunk("protected"); |
2134 | if (IsNotInheritanceScope && Results.includeCodePatterns()) |
2135 | Builder.AddChunk(CodeCompletionString::CK_Colon); |
2136 | Results.AddResult(Result(Builder.TakeString())); |
2137 | |
2138 | // private: |
2139 | Builder.AddTypedTextChunk("private"); |
2140 | if (IsNotInheritanceScope && Results.includeCodePatterns()) |
2141 | Builder.AddChunk(CodeCompletionString::CK_Colon); |
2142 | Results.AddResult(Result(Builder.TakeString())); |
2143 | |
2144 | // FIXME: This adds override results only if we are at the first word of |
2145 | // the declaration/definition. Also call this from other sides to have |
2146 | // more use-cases. |
2147 | AddOverrideResults(Results, CodeCompletionContext::CCC_ClassStructUnion, |
2148 | Builder); |
2149 | } |
2150 | } |
2151 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; |
2152 | |
2153 | case Sema::PCC_Template: |
2154 | case Sema::PCC_MemberTemplate: |
2155 | if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) { |
2156 | // template < parameters > |
2157 | Builder.AddTypedTextChunk("template"); |
2158 | Builder.AddChunk(CodeCompletionString::CK_LeftAngle); |
2159 | Builder.AddPlaceholderChunk("parameters"); |
2160 | Builder.AddChunk(CodeCompletionString::CK_RightAngle); |
2161 | Results.AddResult(Result(Builder.TakeString())); |
2162 | } else { |
2163 | Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword)); |
2164 | } |
2165 | |
2166 | AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); |
2167 | AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results); |
2168 | break; |
2169 | |
2170 | case Sema::PCC_ObjCInterface: |
2171 | AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true); |
2172 | AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); |
2173 | AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results); |
2174 | break; |
2175 | |
2176 | case Sema::PCC_ObjCImplementation: |
2177 | AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true); |
2178 | AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); |
2179 | AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results); |
2180 | break; |
2181 | |
2182 | case Sema::PCC_ObjCInstanceVariableList: |
2183 | AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true); |
2184 | break; |
2185 | |
2186 | case Sema::PCC_RecoveryInFunction: |
2187 | case Sema::PCC_Statement: { |
2188 | if (SemaRef.getLangOpts().CPlusPlus11) |
2189 | AddUsingAliasResult(Builder, Results); |
2190 | |
2191 | AddTypedefResult(Results); |
2192 | |
2193 | if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() && |
2194 | SemaRef.getLangOpts().CXXExceptions) { |
2195 | Builder.AddTypedTextChunk("try"); |
2196 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2197 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
2198 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2199 | Builder.AddPlaceholderChunk("statements"); |
2200 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2201 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
2202 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2203 | Builder.AddTextChunk("catch"); |
2204 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2205 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2206 | Builder.AddPlaceholderChunk("declaration"); |
2207 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2208 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2209 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
2210 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2211 | Builder.AddPlaceholderChunk("statements"); |
2212 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2213 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
2214 | Results.AddResult(Result(Builder.TakeString())); |
2215 | } |
2216 | if (SemaRef.getLangOpts().ObjC) |
2217 | AddObjCStatementResults(Results, true); |
2218 | |
2219 | if (Results.includeCodePatterns()) { |
2220 | // if (condition) { statements } |
2221 | Builder.AddTypedTextChunk("if"); |
2222 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2223 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2224 | if (SemaRef.getLangOpts().CPlusPlus) |
2225 | Builder.AddPlaceholderChunk("condition"); |
2226 | else |
2227 | Builder.AddPlaceholderChunk("expression"); |
2228 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2229 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2230 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
2231 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2232 | Builder.AddPlaceholderChunk("statements"); |
2233 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2234 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
2235 | Results.AddResult(Result(Builder.TakeString())); |
2236 | |
2237 | // switch (condition) { } |
2238 | Builder.AddTypedTextChunk("switch"); |
2239 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2240 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2241 | if (SemaRef.getLangOpts().CPlusPlus) |
2242 | Builder.AddPlaceholderChunk("condition"); |
2243 | else |
2244 | Builder.AddPlaceholderChunk("expression"); |
2245 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2246 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2247 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
2248 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2249 | Builder.AddPlaceholderChunk("cases"); |
2250 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2251 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
2252 | Results.AddResult(Result(Builder.TakeString())); |
2253 | } |
2254 | |
2255 | // Switch-specific statements. |
2256 | if (SemaRef.getCurFunction() && |
2257 | !SemaRef.getCurFunction()->SwitchStack.empty()) { |
2258 | // case expression: |
2259 | Builder.AddTypedTextChunk("case"); |
2260 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2261 | Builder.AddPlaceholderChunk("expression"); |
2262 | Builder.AddChunk(CodeCompletionString::CK_Colon); |
2263 | Results.AddResult(Result(Builder.TakeString())); |
2264 | |
2265 | // default: |
2266 | Builder.AddTypedTextChunk("default"); |
2267 | Builder.AddChunk(CodeCompletionString::CK_Colon); |
2268 | Results.AddResult(Result(Builder.TakeString())); |
2269 | } |
2270 | |
2271 | if (Results.includeCodePatterns()) { |
2272 | /// while (condition) { statements } |
2273 | Builder.AddTypedTextChunk("while"); |
2274 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2275 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2276 | if (SemaRef.getLangOpts().CPlusPlus) |
2277 | Builder.AddPlaceholderChunk("condition"); |
2278 | else |
2279 | Builder.AddPlaceholderChunk("expression"); |
2280 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2281 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2282 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
2283 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2284 | Builder.AddPlaceholderChunk("statements"); |
2285 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2286 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
2287 | Results.AddResult(Result(Builder.TakeString())); |
2288 | |
2289 | // do { statements } while ( expression ); |
2290 | Builder.AddTypedTextChunk("do"); |
2291 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2292 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
2293 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2294 | Builder.AddPlaceholderChunk("statements"); |
2295 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2296 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
2297 | Builder.AddTextChunk("while"); |
2298 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2299 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2300 | Builder.AddPlaceholderChunk("expression"); |
2301 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2302 | Results.AddResult(Result(Builder.TakeString())); |
2303 | |
2304 | // for ( for-init-statement ; condition ; expression ) { statements } |
2305 | Builder.AddTypedTextChunk("for"); |
2306 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2307 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2308 | if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99) |
2309 | Builder.AddPlaceholderChunk("init-statement"); |
2310 | else |
2311 | Builder.AddPlaceholderChunk("init-expression"); |
2312 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2313 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2314 | Builder.AddPlaceholderChunk("condition"); |
2315 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2316 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2317 | Builder.AddPlaceholderChunk("inc-expression"); |
2318 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2319 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2320 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
2321 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2322 | Builder.AddPlaceholderChunk("statements"); |
2323 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2324 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
2325 | Results.AddResult(Result(Builder.TakeString())); |
2326 | |
2327 | if (SemaRef.getLangOpts().CPlusPlus11 || SemaRef.getLangOpts().ObjC) { |
2328 | // for ( range_declaration (:|in) range_expression ) { statements } |
2329 | Builder.AddTypedTextChunk("for"); |
2330 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2331 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2332 | Builder.AddPlaceholderChunk("range-declaration"); |
2333 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2334 | if (SemaRef.getLangOpts().ObjC) |
2335 | Builder.AddTextChunk("in"); |
2336 | else |
2337 | Builder.AddChunk(CodeCompletionString::CK_Colon); |
2338 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2339 | Builder.AddPlaceholderChunk("range-expression"); |
2340 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2341 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2342 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
2343 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2344 | Builder.AddPlaceholderChunk("statements"); |
2345 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
2346 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
2347 | Results.AddResult(Result(Builder.TakeString())); |
2348 | } |
2349 | } |
2350 | |
2351 | if (S->getContinueParent()) { |
2352 | // continue ; |
2353 | Builder.AddTypedTextChunk("continue"); |
2354 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2355 | Results.AddResult(Result(Builder.TakeString())); |
2356 | } |
2357 | |
2358 | if (S->getBreakParent()) { |
2359 | // break ; |
2360 | Builder.AddTypedTextChunk("break"); |
2361 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2362 | Results.AddResult(Result(Builder.TakeString())); |
2363 | } |
2364 | |
2365 | // "return expression ;" or "return ;", depending on the return type. |
2366 | QualType ReturnType; |
2367 | if (const auto *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext)) |
2368 | ReturnType = Function->getReturnType(); |
2369 | else if (const auto *Method = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext)) |
2370 | ReturnType = Method->getReturnType(); |
2371 | else if (SemaRef.getCurBlock() && |
2372 | !SemaRef.getCurBlock()->ReturnType.isNull()) |
2373 | ReturnType = SemaRef.getCurBlock()->ReturnType;; |
2374 | if (ReturnType.isNull() || ReturnType->isVoidType()) { |
2375 | Builder.AddTypedTextChunk("return"); |
2376 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2377 | Results.AddResult(Result(Builder.TakeString())); |
2378 | } else { |
2379 | assert(!ReturnType.isNull())((void)0); |
2380 | // "return expression ;" |
2381 | Builder.AddTypedTextChunk("return"); |
2382 | Builder.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace); |
2383 | Builder.AddPlaceholderChunk("expression"); |
2384 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2385 | Results.AddResult(Result(Builder.TakeString())); |
2386 | // When boolean, also add 'return true;' and 'return false;'. |
2387 | if (ReturnType->isBooleanType()) { |
2388 | Builder.AddTypedTextChunk("return true"); |
2389 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2390 | Results.AddResult(Result(Builder.TakeString())); |
2391 | |
2392 | Builder.AddTypedTextChunk("return false"); |
2393 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2394 | Results.AddResult(Result(Builder.TakeString())); |
2395 | } |
2396 | // For pointers, suggest 'return nullptr' in C++. |
2397 | if (SemaRef.getLangOpts().CPlusPlus11 && |
2398 | (ReturnType->isPointerType() || ReturnType->isMemberPointerType())) { |
2399 | Builder.AddTypedTextChunk("return nullptr"); |
2400 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2401 | Results.AddResult(Result(Builder.TakeString())); |
2402 | } |
2403 | } |
2404 | |
2405 | // goto identifier ; |
2406 | Builder.AddTypedTextChunk("goto"); |
2407 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2408 | Builder.AddPlaceholderChunk("label"); |
2409 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2410 | Results.AddResult(Result(Builder.TakeString())); |
2411 | |
2412 | // Using directives |
2413 | Builder.AddTypedTextChunk("using namespace"); |
2414 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2415 | Builder.AddPlaceholderChunk("identifier"); |
2416 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
2417 | Results.AddResult(Result(Builder.TakeString())); |
2418 | |
2419 | AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts()); |
2420 | } |
2421 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; |
2422 | |
2423 | // Fall through (for statement expressions). |
2424 | case Sema::PCC_ForInit: |
2425 | case Sema::PCC_Condition: |
2426 | AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); |
2427 | // Fall through: conditions and statements can have expressions. |
2428 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; |
2429 | |
2430 | case Sema::PCC_ParenthesizedExpression: |
2431 | if (SemaRef.getLangOpts().ObjCAutoRefCount && |
2432 | CCC == Sema::PCC_ParenthesizedExpression) { |
2433 | // (__bridge <type>)<expression> |
2434 | Builder.AddTypedTextChunk("__bridge"); |
2435 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2436 | Builder.AddPlaceholderChunk("type"); |
2437 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2438 | Builder.AddPlaceholderChunk("expression"); |
2439 | Results.AddResult(Result(Builder.TakeString())); |
2440 | |
2441 | // (__bridge_transfer <Objective-C type>)<expression> |
2442 | Builder.AddTypedTextChunk("__bridge_transfer"); |
2443 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2444 | Builder.AddPlaceholderChunk("Objective-C type"); |
2445 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2446 | Builder.AddPlaceholderChunk("expression"); |
2447 | Results.AddResult(Result(Builder.TakeString())); |
2448 | |
2449 | // (__bridge_retained <CF type>)<expression> |
2450 | Builder.AddTypedTextChunk("__bridge_retained"); |
2451 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2452 | Builder.AddPlaceholderChunk("CF type"); |
2453 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2454 | Builder.AddPlaceholderChunk("expression"); |
2455 | Results.AddResult(Result(Builder.TakeString())); |
2456 | } |
2457 | // Fall through |
2458 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; |
2459 | |
2460 | case Sema::PCC_Expression: { |
2461 | if (SemaRef.getLangOpts().CPlusPlus) { |
2462 | // 'this', if we're in a non-static member function. |
2463 | addThisCompletion(SemaRef, Results); |
2464 | |
2465 | // true |
2466 | Builder.AddResultTypeChunk("bool"); |
2467 | Builder.AddTypedTextChunk("true"); |
2468 | Results.AddResult(Result(Builder.TakeString())); |
2469 | |
2470 | // false |
2471 | Builder.AddResultTypeChunk("bool"); |
2472 | Builder.AddTypedTextChunk("false"); |
2473 | Results.AddResult(Result(Builder.TakeString())); |
2474 | |
2475 | if (SemaRef.getLangOpts().RTTI) { |
2476 | // dynamic_cast < type-id > ( expression ) |
2477 | Builder.AddTypedTextChunk("dynamic_cast"); |
2478 | Builder.AddChunk(CodeCompletionString::CK_LeftAngle); |
2479 | Builder.AddPlaceholderChunk("type"); |
2480 | Builder.AddChunk(CodeCompletionString::CK_RightAngle); |
2481 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2482 | Builder.AddPlaceholderChunk("expression"); |
2483 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2484 | Results.AddResult(Result(Builder.TakeString())); |
2485 | } |
2486 | |
2487 | // static_cast < type-id > ( expression ) |
2488 | Builder.AddTypedTextChunk("static_cast"); |
2489 | Builder.AddChunk(CodeCompletionString::CK_LeftAngle); |
2490 | Builder.AddPlaceholderChunk("type"); |
2491 | Builder.AddChunk(CodeCompletionString::CK_RightAngle); |
2492 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2493 | Builder.AddPlaceholderChunk("expression"); |
2494 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2495 | Results.AddResult(Result(Builder.TakeString())); |
2496 | |
2497 | // reinterpret_cast < type-id > ( expression ) |
2498 | Builder.AddTypedTextChunk("reinterpret_cast"); |
2499 | Builder.AddChunk(CodeCompletionString::CK_LeftAngle); |
2500 | Builder.AddPlaceholderChunk("type"); |
2501 | Builder.AddChunk(CodeCompletionString::CK_RightAngle); |
2502 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2503 | Builder.AddPlaceholderChunk("expression"); |
2504 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2505 | Results.AddResult(Result(Builder.TakeString())); |
2506 | |
2507 | // const_cast < type-id > ( expression ) |
2508 | Builder.AddTypedTextChunk("const_cast"); |
2509 | Builder.AddChunk(CodeCompletionString::CK_LeftAngle); |
2510 | Builder.AddPlaceholderChunk("type"); |
2511 | Builder.AddChunk(CodeCompletionString::CK_RightAngle); |
2512 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2513 | Builder.AddPlaceholderChunk("expression"); |
2514 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2515 | Results.AddResult(Result(Builder.TakeString())); |
2516 | |
2517 | if (SemaRef.getLangOpts().RTTI) { |
2518 | // typeid ( expression-or-type ) |
2519 | Builder.AddResultTypeChunk("std::type_info"); |
2520 | Builder.AddTypedTextChunk("typeid"); |
2521 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2522 | Builder.AddPlaceholderChunk("expression-or-type"); |
2523 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2524 | Results.AddResult(Result(Builder.TakeString())); |
2525 | } |
2526 | |
2527 | // new T ( ... ) |
2528 | Builder.AddTypedTextChunk("new"); |
2529 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2530 | Builder.AddPlaceholderChunk("type"); |
2531 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2532 | Builder.AddPlaceholderChunk("expressions"); |
2533 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2534 | Results.AddResult(Result(Builder.TakeString())); |
2535 | |
2536 | // new T [ ] ( ... ) |
2537 | Builder.AddTypedTextChunk("new"); |
2538 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2539 | Builder.AddPlaceholderChunk("type"); |
2540 | Builder.AddChunk(CodeCompletionString::CK_LeftBracket); |
2541 | Builder.AddPlaceholderChunk("size"); |
2542 | Builder.AddChunk(CodeCompletionString::CK_RightBracket); |
2543 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2544 | Builder.AddPlaceholderChunk("expressions"); |
2545 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2546 | Results.AddResult(Result(Builder.TakeString())); |
2547 | |
2548 | // delete expression |
2549 | Builder.AddResultTypeChunk("void"); |
2550 | Builder.AddTypedTextChunk("delete"); |
2551 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2552 | Builder.AddPlaceholderChunk("expression"); |
2553 | Results.AddResult(Result(Builder.TakeString())); |
2554 | |
2555 | // delete [] expression |
2556 | Builder.AddResultTypeChunk("void"); |
2557 | Builder.AddTypedTextChunk("delete"); |
2558 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2559 | Builder.AddChunk(CodeCompletionString::CK_LeftBracket); |
2560 | Builder.AddChunk(CodeCompletionString::CK_RightBracket); |
2561 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2562 | Builder.AddPlaceholderChunk("expression"); |
2563 | Results.AddResult(Result(Builder.TakeString())); |
2564 | |
2565 | if (SemaRef.getLangOpts().CXXExceptions) { |
2566 | // throw expression |
2567 | Builder.AddResultTypeChunk("void"); |
2568 | Builder.AddTypedTextChunk("throw"); |
2569 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
2570 | Builder.AddPlaceholderChunk("expression"); |
2571 | Results.AddResult(Result(Builder.TakeString())); |
2572 | } |
2573 | |
2574 | // FIXME: Rethrow? |
2575 | |
2576 | if (SemaRef.getLangOpts().CPlusPlus11) { |
2577 | // nullptr |
2578 | Builder.AddResultTypeChunk("std::nullptr_t"); |
2579 | Builder.AddTypedTextChunk("nullptr"); |
2580 | Results.AddResult(Result(Builder.TakeString())); |
2581 | |
2582 | // alignof |
2583 | Builder.AddResultTypeChunk("size_t"); |
2584 | Builder.AddTypedTextChunk("alignof"); |
2585 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2586 | Builder.AddPlaceholderChunk("type"); |
2587 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2588 | Results.AddResult(Result(Builder.TakeString())); |
2589 | |
2590 | // noexcept |
2591 | Builder.AddResultTypeChunk("bool"); |
2592 | Builder.AddTypedTextChunk("noexcept"); |
2593 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2594 | Builder.AddPlaceholderChunk("expression"); |
2595 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2596 | Results.AddResult(Result(Builder.TakeString())); |
2597 | |
2598 | // sizeof... expression |
2599 | Builder.AddResultTypeChunk("size_t"); |
2600 | Builder.AddTypedTextChunk("sizeof..."); |
2601 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2602 | Builder.AddPlaceholderChunk("parameter-pack"); |
2603 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2604 | Results.AddResult(Result(Builder.TakeString())); |
2605 | } |
2606 | } |
2607 | |
2608 | if (SemaRef.getLangOpts().ObjC) { |
2609 | // Add "super", if we're in an Objective-C class with a superclass. |
2610 | if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) { |
2611 | // The interface can be NULL. |
2612 | if (ObjCInterfaceDecl *ID = Method->getClassInterface()) |
2613 | if (ID->getSuperClass()) { |
2614 | std::string SuperType; |
2615 | SuperType = ID->getSuperClass()->getNameAsString(); |
2616 | if (Method->isInstanceMethod()) |
2617 | SuperType += " *"; |
2618 | |
2619 | Builder.AddResultTypeChunk(Allocator.CopyString(SuperType)); |
2620 | Builder.AddTypedTextChunk("super"); |
2621 | Results.AddResult(Result(Builder.TakeString())); |
2622 | } |
2623 | } |
2624 | |
2625 | AddObjCExpressionResults(Results, true); |
2626 | } |
2627 | |
2628 | if (SemaRef.getLangOpts().C11) { |
2629 | // _Alignof |
2630 | Builder.AddResultTypeChunk("size_t"); |
2631 | if (SemaRef.PP.isMacroDefined("alignof")) |
2632 | Builder.AddTypedTextChunk("alignof"); |
2633 | else |
2634 | Builder.AddTypedTextChunk("_Alignof"); |
2635 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2636 | Builder.AddPlaceholderChunk("type"); |
2637 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2638 | Results.AddResult(Result(Builder.TakeString())); |
2639 | } |
2640 | |
2641 | // sizeof expression |
2642 | Builder.AddResultTypeChunk("size_t"); |
2643 | Builder.AddTypedTextChunk("sizeof"); |
2644 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
2645 | Builder.AddPlaceholderChunk("expression-or-type"); |
2646 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
2647 | Results.AddResult(Result(Builder.TakeString())); |
2648 | break; |
2649 | } |
2650 | |
2651 | case Sema::PCC_Type: |
2652 | case Sema::PCC_LocalDeclarationSpecifiers: |
2653 | break; |
2654 | } |
2655 | |
2656 | if (WantTypesInContext(CCC, SemaRef.getLangOpts())) |
2657 | AddTypeSpecifierResults(SemaRef.getLangOpts(), Results); |
2658 | |
2659 | if (SemaRef.getLangOpts().CPlusPlus && CCC != Sema::PCC_Type) |
2660 | Results.AddResult(Result("operator")); |
2661 | } |
2662 | |
2663 | /// If the given declaration has an associated type, add it as a result |
2664 | /// type chunk. |
2665 | static void AddResultTypeChunk(ASTContext &Context, |
2666 | const PrintingPolicy &Policy, |
2667 | const NamedDecl *ND, QualType BaseType, |
2668 | CodeCompletionBuilder &Result) { |
2669 | if (!ND) |
2670 | return; |
2671 | |
2672 | // Skip constructors and conversion functions, which have their return types |
2673 | // built into their names. |
2674 | if (isConstructor(ND) || isa<CXXConversionDecl>(ND)) |
2675 | return; |
2676 | |
2677 | // Determine the type of the declaration (if it has a type). |
2678 | QualType T; |
2679 | if (const FunctionDecl *Function = ND->getAsFunction()) |
2680 | T = Function->getReturnType(); |
2681 | else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) { |
2682 | if (!BaseType.isNull()) |
2683 | T = Method->getSendResultType(BaseType); |
2684 | else |
2685 | T = Method->getReturnType(); |
2686 | } else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND)) { |
2687 | T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext())); |
2688 | T = clang::TypeName::getFullyQualifiedType(T, Context); |
2689 | } else if (isa<UnresolvedUsingValueDecl>(ND)) { |
2690 | /* Do nothing: ignore unresolved using declarations*/ |
2691 | } else if (const auto *Ivar = dyn_cast<ObjCIvarDecl>(ND)) { |
2692 | if (!BaseType.isNull()) |
2693 | T = Ivar->getUsageType(BaseType); |
2694 | else |
2695 | T = Ivar->getType(); |
2696 | } else if (const auto *Value = dyn_cast<ValueDecl>(ND)) { |
2697 | T = Value->getType(); |
2698 | } else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND)) { |
2699 | if (!BaseType.isNull()) |
2700 | T = Property->getUsageType(BaseType); |
2701 | else |
2702 | T = Property->getType(); |
2703 | } |
2704 | |
2705 | if (T.isNull() || Context.hasSameType(T, Context.DependentTy)) |
2706 | return; |
2707 | |
2708 | Result.AddResultTypeChunk( |
2709 | GetCompletionTypeString(T, Context, Policy, Result.getAllocator())); |
2710 | } |
2711 | |
2712 | static void MaybeAddSentinel(Preprocessor &PP, |
2713 | const NamedDecl *FunctionOrMethod, |
2714 | CodeCompletionBuilder &Result) { |
2715 | if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>()) |
2716 | if (Sentinel->getSentinel() == 0) { |
2717 | if (PP.getLangOpts().ObjC && PP.isMacroDefined("nil")) |
2718 | Result.AddTextChunk(", nil"); |
2719 | else if (PP.isMacroDefined("NULL")) |
2720 | Result.AddTextChunk(", NULL"); |
2721 | else |
2722 | Result.AddTextChunk(", (void*)0"); |
2723 | } |
2724 | } |
2725 | |
2726 | static std::string formatObjCParamQualifiers(unsigned ObjCQuals, |
2727 | QualType &Type) { |
2728 | std::string Result; |
2729 | if (ObjCQuals & Decl::OBJC_TQ_In) |
2730 | Result += "in "; |
2731 | else if (ObjCQuals & Decl::OBJC_TQ_Inout) |
2732 | Result += "inout "; |
2733 | else if (ObjCQuals & Decl::OBJC_TQ_Out) |
2734 | Result += "out "; |
2735 | if (ObjCQuals & Decl::OBJC_TQ_Bycopy) |
2736 | Result += "bycopy "; |
2737 | else if (ObjCQuals & Decl::OBJC_TQ_Byref) |
2738 | Result += "byref "; |
2739 | if (ObjCQuals & Decl::OBJC_TQ_Oneway) |
2740 | Result += "oneway "; |
2741 | if (ObjCQuals & Decl::OBJC_TQ_CSNullability) { |
2742 | if (auto nullability = AttributedType::stripOuterNullability(Type)) { |
2743 | switch (*nullability) { |
2744 | case NullabilityKind::NonNull: |
2745 | Result += "nonnull "; |
2746 | break; |
2747 | |
2748 | case NullabilityKind::Nullable: |
2749 | Result += "nullable "; |
2750 | break; |
2751 | |
2752 | case NullabilityKind::Unspecified: |
2753 | Result += "null_unspecified "; |
2754 | break; |
2755 | |
2756 | case NullabilityKind::NullableResult: |
2757 | llvm_unreachable("Not supported as a context-sensitive keyword!")__builtin_unreachable(); |
2758 | break; |
2759 | } |
2760 | } |
2761 | } |
2762 | return Result; |
2763 | } |
2764 | |
2765 | /// Tries to find the most appropriate type location for an Objective-C |
2766 | /// block placeholder. |
2767 | /// |
2768 | /// This function ignores things like typedefs and qualifiers in order to |
2769 | /// present the most relevant and accurate block placeholders in code completion |
2770 | /// results. |
2771 | static void findTypeLocationForBlockDecl(const TypeSourceInfo *TSInfo, |
2772 | FunctionTypeLoc &Block, |
2773 | FunctionProtoTypeLoc &BlockProto, |
2774 | bool SuppressBlock = false) { |
2775 | if (!TSInfo) |
2776 | return; |
2777 | TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc(); |
2778 | while (true) { |
2779 | // Look through typedefs. |
2780 | if (!SuppressBlock) { |
2781 | if (TypedefTypeLoc TypedefTL = TL.getAs<TypedefTypeLoc>()) { |
2782 | if (TypeSourceInfo *InnerTSInfo = |
2783 | TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) { |
2784 | TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc(); |
2785 | continue; |
2786 | } |
2787 | } |
2788 | |
2789 | // Look through qualified types |
2790 | if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) { |
2791 | TL = QualifiedTL.getUnqualifiedLoc(); |
2792 | continue; |
2793 | } |
2794 | |
2795 | if (AttributedTypeLoc AttrTL = TL.getAs<AttributedTypeLoc>()) { |
2796 | TL = AttrTL.getModifiedLoc(); |
2797 | continue; |
2798 | } |
2799 | } |
2800 | |
2801 | // Try to get the function prototype behind the block pointer type, |
2802 | // then we're done. |
2803 | if (BlockPointerTypeLoc BlockPtr = TL.getAs<BlockPointerTypeLoc>()) { |
2804 | TL = BlockPtr.getPointeeLoc().IgnoreParens(); |
2805 | Block = TL.getAs<FunctionTypeLoc>(); |
2806 | BlockProto = TL.getAs<FunctionProtoTypeLoc>(); |
2807 | } |
2808 | break; |
2809 | } |
2810 | } |
2811 | |
2812 | static std::string |
2813 | formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl, |
2814 | FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto, |
2815 | bool SuppressBlockName = false, |
2816 | bool SuppressBlock = false, |
2817 | Optional<ArrayRef<QualType>> ObjCSubsts = None); |
2818 | |
2819 | static std::string |
2820 | FormatFunctionParameter(const PrintingPolicy &Policy, const ParmVarDecl *Param, |
2821 | bool SuppressName = false, bool SuppressBlock = false, |
2822 | Optional<ArrayRef<QualType>> ObjCSubsts = None) { |
2823 | // Params are unavailable in FunctionTypeLoc if the FunctionType is invalid. |
2824 | // It would be better to pass in the param Type, which is usually avaliable. |
2825 | // But this case is rare, so just pretend we fell back to int as elsewhere. |
2826 | if (!Param) |
2827 | return "int"; |
2828 | bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext()); |
2829 | if (Param->getType()->isDependentType() || |
2830 | !Param->getType()->isBlockPointerType()) { |
2831 | // The argument for a dependent or non-block parameter is a placeholder |
2832 | // containing that parameter's type. |
2833 | std::string Result; |
2834 | |
2835 | if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName) |
2836 | Result = std::string(Param->getIdentifier()->getName()); |
2837 | |
2838 | QualType Type = Param->getType(); |
2839 | if (ObjCSubsts) |
2840 | Type = Type.substObjCTypeArgs(Param->getASTContext(), *ObjCSubsts, |
2841 | ObjCSubstitutionContext::Parameter); |
2842 | if (ObjCMethodParam) { |
2843 | Result = |
2844 | "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier(), Type); |
2845 | Result += Type.getAsString(Policy) + ")"; |
2846 | if (Param->getIdentifier() && !SuppressName) |
2847 | Result += Param->getIdentifier()->getName(); |
2848 | } else { |
2849 | Type.getAsStringInternal(Result, Policy); |
2850 | } |
2851 | return Result; |
2852 | } |
2853 | |
2854 | // The argument for a block pointer parameter is a block literal with |
2855 | // the appropriate type. |
2856 | FunctionTypeLoc Block; |
2857 | FunctionProtoTypeLoc BlockProto; |
2858 | findTypeLocationForBlockDecl(Param->getTypeSourceInfo(), Block, BlockProto, |
2859 | SuppressBlock); |
2860 | // Try to retrieve the block type information from the property if this is a |
2861 | // parameter in a setter. |
2862 | if (!Block && ObjCMethodParam && |
2863 | cast<ObjCMethodDecl>(Param->getDeclContext())->isPropertyAccessor()) { |
2864 | if (const auto *PD = cast<ObjCMethodDecl>(Param->getDeclContext()) |
2865 | ->findPropertyDecl(/*CheckOverrides=*/false)) |
2866 | findTypeLocationForBlockDecl(PD->getTypeSourceInfo(), Block, BlockProto, |
2867 | SuppressBlock); |
2868 | } |
2869 | |
2870 | if (!Block) { |
2871 | // We were unable to find a FunctionProtoTypeLoc with parameter names |
2872 | // for the block; just use the parameter type as a placeholder. |
2873 | std::string Result; |
2874 | if (!ObjCMethodParam && Param->getIdentifier()) |
2875 | Result = std::string(Param->getIdentifier()->getName()); |
2876 | |
2877 | QualType Type = Param->getType().getUnqualifiedType(); |
2878 | |
2879 | if (ObjCMethodParam) { |
2880 | Result = Type.getAsString(Policy); |
2881 | std::string Quals = |
2882 | formatObjCParamQualifiers(Param->getObjCDeclQualifier(), Type); |
2883 | if (!Quals.empty()) |
2884 | Result = "(" + Quals + " " + Result + ")"; |
2885 | if (Result.back() != ')') |
2886 | Result += " "; |
2887 | if (Param->getIdentifier()) |
2888 | Result += Param->getIdentifier()->getName(); |
2889 | } else { |
2890 | Type.getAsStringInternal(Result, Policy); |
2891 | } |
2892 | |
2893 | return Result; |
2894 | } |
2895 | |
2896 | // We have the function prototype behind the block pointer type, as it was |
2897 | // written in the source. |
2898 | return formatBlockPlaceholder(Policy, Param, Block, BlockProto, |
2899 | /*SuppressBlockName=*/false, SuppressBlock, |
2900 | ObjCSubsts); |
2901 | } |
2902 | |
2903 | /// Returns a placeholder string that corresponds to an Objective-C block |
2904 | /// declaration. |
2905 | /// |
2906 | /// \param BlockDecl A declaration with an Objective-C block type. |
2907 | /// |
2908 | /// \param Block The most relevant type location for that block type. |
2909 | /// |
2910 | /// \param SuppressBlockName Determines whether or not the name of the block |
2911 | /// declaration is included in the resulting string. |
2912 | static std::string |
2913 | formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl, |
2914 | FunctionTypeLoc &Block, FunctionProtoTypeLoc &BlockProto, |
2915 | bool SuppressBlockName, bool SuppressBlock, |
2916 | Optional<ArrayRef<QualType>> ObjCSubsts) { |
2917 | std::string Result; |
2918 | QualType ResultType = Block.getTypePtr()->getReturnType(); |
2919 | if (ObjCSubsts) |
2920 | ResultType = |
2921 | ResultType.substObjCTypeArgs(BlockDecl->getASTContext(), *ObjCSubsts, |
2922 | ObjCSubstitutionContext::Result); |
2923 | if (!ResultType->isVoidType() || SuppressBlock) |
2924 | ResultType.getAsStringInternal(Result, Policy); |
2925 | |
2926 | // Format the parameter list. |
2927 | std::string Params; |
2928 | if (!BlockProto || Block.getNumParams() == 0) { |
2929 | if (BlockProto && BlockProto.getTypePtr()->isVariadic()) |
2930 | Params = "(...)"; |
2931 | else |
2932 | Params = "(void)"; |
2933 | } else { |
2934 | Params += "("; |
2935 | for (unsigned I = 0, N = Block.getNumParams(); I != N; ++I) { |
2936 | if (I) |
2937 | Params += ", "; |
2938 | Params += FormatFunctionParameter(Policy, Block.getParam(I), |
2939 | /*SuppressName=*/false, |
2940 | /*SuppressBlock=*/true, ObjCSubsts); |
2941 | |
2942 | if (I == N - 1 && BlockProto.getTypePtr()->isVariadic()) |
2943 | Params += ", ..."; |
2944 | } |
2945 | Params += ")"; |
2946 | } |
2947 | |
2948 | if (SuppressBlock) { |
2949 | // Format as a parameter. |
2950 | Result = Result + " (^"; |
2951 | if (!SuppressBlockName && BlockDecl->getIdentifier()) |
2952 | Result += BlockDecl->getIdentifier()->getName(); |
2953 | Result += ")"; |
2954 | Result += Params; |
2955 | } else { |
2956 | // Format as a block literal argument. |
2957 | Result = '^' + Result; |
2958 | Result += Params; |
2959 | |
2960 | if (!SuppressBlockName && BlockDecl->getIdentifier()) |
2961 | Result += BlockDecl->getIdentifier()->getName(); |
2962 | } |
2963 | |
2964 | return Result; |
2965 | } |
2966 | |
2967 | static std::string GetDefaultValueString(const ParmVarDecl *Param, |
2968 | const SourceManager &SM, |
2969 | const LangOptions &LangOpts) { |
2970 | const SourceRange SrcRange = Param->getDefaultArgRange(); |
2971 | CharSourceRange CharSrcRange = CharSourceRange::getTokenRange(SrcRange); |
2972 | bool Invalid = CharSrcRange.isInvalid(); |
2973 | if (Invalid) |
2974 | return ""; |
2975 | StringRef srcText = |
2976 | Lexer::getSourceText(CharSrcRange, SM, LangOpts, &Invalid); |
2977 | if (Invalid) |
2978 | return ""; |
2979 | |
2980 | if (srcText.empty() || srcText == "=") { |
2981 | // Lexer can't determine the value. |
2982 | // This happens if the code is incorrect (for example class is forward |
2983 | // declared). |
2984 | return ""; |
2985 | } |
2986 | std::string DefValue(srcText.str()); |
2987 | // FIXME: remove this check if the Lexer::getSourceText value is fixed and |
2988 | // this value always has (or always does not have) '=' in front of it |
2989 | if (DefValue.at(0) != '=') { |
2990 | // If we don't have '=' in front of value. |
2991 | // Lexer returns built-in types values without '=' and user-defined types |
2992 | // values with it. |
2993 | return " = " + DefValue; |
2994 | } |
2995 | return " " + DefValue; |
2996 | } |
2997 | |
2998 | /// Add function parameter chunks to the given code completion string. |
2999 | static void AddFunctionParameterChunks(Preprocessor &PP, |
3000 | const PrintingPolicy &Policy, |
3001 | const FunctionDecl *Function, |
3002 | CodeCompletionBuilder &Result, |
3003 | unsigned Start = 0, |
3004 | bool InOptional = false) { |
3005 | bool FirstParameter = true; |
3006 | |
3007 | for (unsigned P = Start, N = Function->getNumParams(); P != N; ++P) { |
3008 | const ParmVarDecl *Param = Function->getParamDecl(P); |
3009 | |
3010 | if (Param->hasDefaultArg() && !InOptional) { |
3011 | // When we see an optional default argument, put that argument and |
3012 | // the remaining default arguments into a new, optional string. |
3013 | CodeCompletionBuilder Opt(Result.getAllocator(), |
3014 | Result.getCodeCompletionTUInfo()); |
3015 | if (!FirstParameter) |
3016 | Opt.AddChunk(CodeCompletionString::CK_Comma); |
3017 | AddFunctionParameterChunks(PP, Policy, Function, Opt, P, true); |
3018 | Result.AddOptionalChunk(Opt.TakeString()); |
3019 | break; |
3020 | } |
3021 | |
3022 | if (FirstParameter) |
3023 | FirstParameter = false; |
3024 | else |
3025 | Result.AddChunk(CodeCompletionString::CK_Comma); |
3026 | |
3027 | InOptional = false; |
3028 | |
3029 | // Format the placeholder string. |
3030 | std::string PlaceholderStr = FormatFunctionParameter(Policy, Param); |
3031 | if (Param->hasDefaultArg()) |
3032 | PlaceholderStr += |
3033 | GetDefaultValueString(Param, PP.getSourceManager(), PP.getLangOpts()); |
3034 | |
3035 | if (Function->isVariadic() && P == N - 1) |
3036 | PlaceholderStr += ", ..."; |
3037 | |
3038 | // Add the placeholder string. |
3039 | Result.AddPlaceholderChunk( |
3040 | Result.getAllocator().CopyString(PlaceholderStr)); |
3041 | } |
3042 | |
3043 | if (const auto *Proto = Function->getType()->getAs<FunctionProtoType>()) |
3044 | if (Proto->isVariadic()) { |
3045 | if (Proto->getNumParams() == 0) |
3046 | Result.AddPlaceholderChunk("..."); |
3047 | |
3048 | MaybeAddSentinel(PP, Function, Result); |
3049 | } |
3050 | } |
3051 | |
3052 | /// Add template parameter chunks to the given code completion string. |
3053 | static void AddTemplateParameterChunks( |
3054 | ASTContext &Context, const PrintingPolicy &Policy, |
3055 | const TemplateDecl *Template, CodeCompletionBuilder &Result, |
3056 | unsigned MaxParameters = 0, unsigned Start = 0, bool InDefaultArg = false) { |
3057 | bool FirstParameter = true; |
3058 | |
3059 | // Prefer to take the template parameter names from the first declaration of |
3060 | // the template. |
3061 | Template = cast<TemplateDecl>(Template->getCanonicalDecl()); |
3062 | |
3063 | TemplateParameterList *Params = Template->getTemplateParameters(); |
3064 | TemplateParameterList::iterator PEnd = Params->end(); |
3065 | if (MaxParameters) |
3066 | PEnd = Params->begin() + MaxParameters; |
3067 | for (TemplateParameterList::iterator P = Params->begin() + Start; P != PEnd; |
3068 | ++P) { |
3069 | bool HasDefaultArg = false; |
3070 | std::string PlaceholderStr; |
3071 | if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { |
3072 | if (TTP->wasDeclaredWithTypename()) |
3073 | PlaceholderStr = "typename"; |
3074 | else if (const auto *TC = TTP->getTypeConstraint()) { |
3075 | llvm::raw_string_ostream OS(PlaceholderStr); |
3076 | TC->print(OS, Policy); |
3077 | OS.flush(); |
3078 | } else |
3079 | PlaceholderStr = "class"; |
3080 | |
3081 | if (TTP->getIdentifier()) { |
3082 | PlaceholderStr += ' '; |
3083 | PlaceholderStr += TTP->getIdentifier()->getName(); |
3084 | } |
3085 | |
3086 | HasDefaultArg = TTP->hasDefaultArgument(); |
3087 | } else if (NonTypeTemplateParmDecl *NTTP = |
3088 | dyn_cast<NonTypeTemplateParmDecl>(*P)) { |
3089 | if (NTTP->getIdentifier()) |
3090 | PlaceholderStr = std::string(NTTP->getIdentifier()->getName()); |
3091 | NTTP->getType().getAsStringInternal(PlaceholderStr, Policy); |
3092 | HasDefaultArg = NTTP->hasDefaultArgument(); |
3093 | } else { |
3094 | assert(isa<TemplateTemplateParmDecl>(*P))((void)0); |
3095 | TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P); |
3096 | |
3097 | // Since putting the template argument list into the placeholder would |
3098 | // be very, very long, we just use an abbreviation. |
3099 | PlaceholderStr = "template<...> class"; |
3100 | if (TTP->getIdentifier()) { |
3101 | PlaceholderStr += ' '; |
3102 | PlaceholderStr += TTP->getIdentifier()->getName(); |
3103 | } |
3104 | |
3105 | HasDefaultArg = TTP->hasDefaultArgument(); |
3106 | } |
3107 | |
3108 | if (HasDefaultArg && !InDefaultArg) { |
3109 | // When we see an optional default argument, put that argument and |
3110 | // the remaining default arguments into a new, optional string. |
3111 | CodeCompletionBuilder Opt(Result.getAllocator(), |
3112 | Result.getCodeCompletionTUInfo()); |
3113 | if (!FirstParameter) |
3114 | Opt.AddChunk(CodeCompletionString::CK_Comma); |
3115 | AddTemplateParameterChunks(Context, Policy, Template, Opt, MaxParameters, |
3116 | P - Params->begin(), true); |
3117 | Result.AddOptionalChunk(Opt.TakeString()); |
3118 | break; |
3119 | } |
3120 | |
3121 | InDefaultArg = false; |
3122 | |
3123 | if (FirstParameter) |
3124 | FirstParameter = false; |
3125 | else |
3126 | Result.AddChunk(CodeCompletionString::CK_Comma); |
3127 | |
3128 | // Add the placeholder string. |
3129 | Result.AddPlaceholderChunk( |
3130 | Result.getAllocator().CopyString(PlaceholderStr)); |
3131 | } |
3132 | } |
3133 | |
3134 | /// Add a qualifier to the given code-completion string, if the |
3135 | /// provided nested-name-specifier is non-NULL. |
3136 | static void AddQualifierToCompletionString(CodeCompletionBuilder &Result, |
3137 | NestedNameSpecifier *Qualifier, |
3138 | bool QualifierIsInformative, |
3139 | ASTContext &Context, |
3140 | const PrintingPolicy &Policy) { |
3141 | if (!Qualifier) |
3142 | return; |
3143 | |
3144 | std::string PrintedNNS; |
3145 | { |
3146 | llvm::raw_string_ostream OS(PrintedNNS); |
3147 | Qualifier->print(OS, Policy); |
3148 | } |
3149 | if (QualifierIsInformative) |
3150 | Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS)); |
3151 | else |
3152 | Result.AddTextChunk(Result.getAllocator().CopyString(PrintedNNS)); |
3153 | } |
3154 | |
3155 | static void |
3156 | AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result, |
3157 | const FunctionDecl *Function) { |
3158 | const auto *Proto = Function->getType()->getAs<FunctionProtoType>(); |
3159 | if (!Proto || !Proto->getMethodQuals()) |
3160 | return; |
3161 | |
3162 | // FIXME: Add ref-qualifier! |
3163 | |
3164 | // Handle single qualifiers without copying |
3165 | if (Proto->getMethodQuals().hasOnlyConst()) { |
3166 | Result.AddInformativeChunk(" const"); |
3167 | return; |
3168 | } |
3169 | |
3170 | if (Proto->getMethodQuals().hasOnlyVolatile()) { |
3171 | Result.AddInformativeChunk(" volatile"); |
3172 | return; |
3173 | } |
3174 | |
3175 | if (Proto->getMethodQuals().hasOnlyRestrict()) { |
3176 | Result.AddInformativeChunk(" restrict"); |
3177 | return; |
3178 | } |
3179 | |
3180 | // Handle multiple qualifiers. |
3181 | std::string QualsStr; |
3182 | if (Proto->isConst()) |
3183 | QualsStr += " const"; |
3184 | if (Proto->isVolatile()) |
3185 | QualsStr += " volatile"; |
3186 | if (Proto->isRestrict()) |
3187 | QualsStr += " restrict"; |
3188 | Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr)); |
3189 | } |
3190 | |
3191 | /// Add the name of the given declaration |
3192 | static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, |
3193 | const NamedDecl *ND, |
3194 | CodeCompletionBuilder &Result) { |
3195 | DeclarationName Name = ND->getDeclName(); |
3196 | if (!Name) |
3197 | return; |
3198 | |
3199 | switch (Name.getNameKind()) { |
3200 | case DeclarationName::CXXOperatorName: { |
3201 | const char *OperatorName = nullptr; |
3202 | switch (Name.getCXXOverloadedOperator()) { |
3203 | case OO_None: |
3204 | case OO_Conditional: |
3205 | case NUM_OVERLOADED_OPERATORS: |
3206 | OperatorName = "operator"; |
3207 | break; |
3208 | |
3209 | #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ |
3210 | case OO_##Name: \ |
3211 | OperatorName = "operator" Spelling; \ |
3212 | break; |
3213 | #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemberOnly) |
3214 | #include "clang/Basic/OperatorKinds.def" |
3215 | |
3216 | case OO_New: |
3217 | OperatorName = "operator new"; |
3218 | break; |
3219 | case OO_Delete: |
3220 | OperatorName = "operator delete"; |
3221 | break; |
3222 | case OO_Array_New: |
3223 | OperatorName = "operator new[]"; |
3224 | break; |
3225 | case OO_Array_Delete: |
3226 | OperatorName = "operator delete[]"; |
3227 | break; |
3228 | case OO_Call: |
3229 | OperatorName = "operator()"; |
3230 | break; |
3231 | case OO_Subscript: |
3232 | OperatorName = "operator[]"; |
3233 | break; |
3234 | } |
3235 | Result.AddTypedTextChunk(OperatorName); |
3236 | break; |
3237 | } |
3238 | |
3239 | case DeclarationName::Identifier: |
3240 | case DeclarationName::CXXConversionFunctionName: |
3241 | case DeclarationName::CXXDestructorName: |
3242 | case DeclarationName::CXXLiteralOperatorName: |
3243 | Result.AddTypedTextChunk( |
3244 | Result.getAllocator().CopyString(ND->getNameAsString())); |
3245 | break; |
3246 | |
3247 | case DeclarationName::CXXDeductionGuideName: |
3248 | case DeclarationName::CXXUsingDirective: |
3249 | case DeclarationName::ObjCZeroArgSelector: |
3250 | case DeclarationName::ObjCOneArgSelector: |
3251 | case DeclarationName::ObjCMultiArgSelector: |
3252 | break; |
3253 | |
3254 | case DeclarationName::CXXConstructorName: { |
3255 | CXXRecordDecl *Record = nullptr; |
3256 | QualType Ty = Name.getCXXNameType(); |
3257 | if (const auto *RecordTy = Ty->getAs<RecordType>()) |
3258 | Record = cast<CXXRecordDecl>(RecordTy->getDecl()); |
3259 | else if (const auto *InjectedTy = Ty->getAs<InjectedClassNameType>()) |
3260 | Record = InjectedTy->getDecl(); |
3261 | else { |
3262 | Result.AddTypedTextChunk( |
3263 | Result.getAllocator().CopyString(ND->getNameAsString())); |
3264 | break; |
3265 | } |
3266 | |
3267 | Result.AddTypedTextChunk( |
3268 | Result.getAllocator().CopyString(Record->getNameAsString())); |
3269 | if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) { |
3270 | Result.AddChunk(CodeCompletionString::CK_LeftAngle); |
3271 | AddTemplateParameterChunks(Context, Policy, Template, Result); |
3272 | Result.AddChunk(CodeCompletionString::CK_RightAngle); |
3273 | } |
3274 | break; |
3275 | } |
3276 | } |
3277 | } |
3278 | |
3279 | CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString( |
3280 | Sema &S, const CodeCompletionContext &CCContext, |
3281 | CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, |
3282 | bool IncludeBriefComments) { |
3283 | return CreateCodeCompletionString(S.Context, S.PP, CCContext, Allocator, |
3284 | CCTUInfo, IncludeBriefComments); |
3285 | } |
3286 | |
3287 | CodeCompletionString *CodeCompletionResult::CreateCodeCompletionStringForMacro( |
3288 | Preprocessor &PP, CodeCompletionAllocator &Allocator, |
3289 | CodeCompletionTUInfo &CCTUInfo) { |
3290 | assert(Kind == RK_Macro)((void)0); |
3291 | CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability); |
3292 | const MacroInfo *MI = PP.getMacroInfo(Macro); |
3293 | Result.AddTypedTextChunk(Result.getAllocator().CopyString(Macro->getName())); |
3294 | |
3295 | if (!MI || !MI->isFunctionLike()) |
3296 | return Result.TakeString(); |
3297 | |
3298 | // Format a function-like macro with placeholders for the arguments. |
3299 | Result.AddChunk(CodeCompletionString::CK_LeftParen); |
3300 | MacroInfo::param_iterator A = MI->param_begin(), AEnd = MI->param_end(); |
3301 | |
3302 | // C99 variadic macros add __VA_ARGS__ at the end. Skip it. |
3303 | if (MI->isC99Varargs()) { |
3304 | --AEnd; |
3305 | |
3306 | if (A == AEnd) { |
3307 | Result.AddPlaceholderChunk("..."); |
3308 | } |
3309 | } |
3310 | |
3311 | for (MacroInfo::param_iterator A = MI->param_begin(); A != AEnd; ++A) { |
3312 | if (A != MI->param_begin()) |
3313 | Result.AddChunk(CodeCompletionString::CK_Comma); |
3314 | |
3315 | if (MI->isVariadic() && (A + 1) == AEnd) { |
3316 | SmallString<32> Arg = (*A)->getName(); |
3317 | if (MI->isC99Varargs()) |
3318 | Arg += ", ..."; |
3319 | else |
3320 | Arg += "..."; |
3321 | Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg)); |
3322 | break; |
3323 | } |
3324 | |
3325 | // Non-variadic macros are simple. |
3326 | Result.AddPlaceholderChunk( |
3327 | Result.getAllocator().CopyString((*A)->getName())); |
3328 | } |
3329 | Result.AddChunk(CodeCompletionString::CK_RightParen); |
3330 | return Result.TakeString(); |
3331 | } |
3332 | |
3333 | /// If possible, create a new code completion string for the given |
3334 | /// result. |
3335 | /// |
3336 | /// \returns Either a new, heap-allocated code completion string describing |
3337 | /// how to use this result, or NULL to indicate that the string or name of the |
3338 | /// result is all that is needed. |
3339 | CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString( |
3340 | ASTContext &Ctx, Preprocessor &PP, const CodeCompletionContext &CCContext, |
3341 | CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, |
3342 | bool IncludeBriefComments) { |
3343 | if (Kind == RK_Macro) |
3344 | return CreateCodeCompletionStringForMacro(PP, Allocator, CCTUInfo); |
3345 | |
3346 | CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability); |
3347 | |
3348 | PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP); |
3349 | if (Kind == RK_Pattern) { |
3350 | Pattern->Priority = Priority; |
3351 | Pattern->Availability = Availability; |
3352 | |
3353 | if (Declaration) { |
3354 | Result.addParentContext(Declaration->getDeclContext()); |
3355 | Pattern->ParentName = Result.getParentName(); |
3356 | if (const RawComment *RC = |
3357 | getPatternCompletionComment(Ctx, Declaration)) { |
3358 | Result.addBriefComment(RC->getBriefText(Ctx)); |
3359 | Pattern->BriefComment = Result.getBriefComment(); |
3360 | } |
3361 | } |
3362 | |
3363 | return Pattern; |
3364 | } |
3365 | |
3366 | if (Kind == RK_Keyword) { |
3367 | Result.AddTypedTextChunk(Keyword); |
3368 | return Result.TakeString(); |
3369 | } |
3370 | assert(Kind == RK_Declaration && "Missed a result kind?")((void)0); |
3371 | return createCodeCompletionStringForDecl( |
3372 | PP, Ctx, Result, IncludeBriefComments, CCContext, Policy); |
3373 | } |
3374 | |
3375 | static void printOverrideString(const CodeCompletionString &CCS, |
3376 | std::string &BeforeName, |
3377 | std::string &NameAndSignature) { |
3378 | bool SeenTypedChunk = false; |
3379 | for (auto &Chunk : CCS) { |
3380 | if (Chunk.Kind == CodeCompletionString::CK_Optional) { |
3381 | assert(SeenTypedChunk && "optional parameter before name")((void)0); |
3382 | // Note that we put all chunks inside into NameAndSignature. |
3383 | printOverrideString(*Chunk.Optional, NameAndSignature, NameAndSignature); |
3384 | continue; |
3385 | } |
3386 | SeenTypedChunk |= Chunk.Kind == CodeCompletionString::CK_TypedText; |
3387 | if (SeenTypedChunk) |
3388 | NameAndSignature += Chunk.Text; |
3389 | else |
3390 | BeforeName += Chunk.Text; |
3391 | } |
3392 | } |
3393 | |
3394 | CodeCompletionString * |
3395 | CodeCompletionResult::createCodeCompletionStringForOverride( |
3396 | Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result, |
3397 | bool IncludeBriefComments, const CodeCompletionContext &CCContext, |
3398 | PrintingPolicy &Policy) { |
3399 | auto *CCS = createCodeCompletionStringForDecl(PP, Ctx, Result, |
3400 | /*IncludeBriefComments=*/false, |
3401 | CCContext, Policy); |
3402 | std::string BeforeName; |
3403 | std::string NameAndSignature; |
3404 | // For overrides all chunks go into the result, none are informative. |
3405 | printOverrideString(*CCS, BeforeName, NameAndSignature); |
3406 | NameAndSignature += " override"; |
3407 | |
3408 | Result.AddTextChunk(Result.getAllocator().CopyString(BeforeName)); |
3409 | Result.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
3410 | Result.AddTypedTextChunk(Result.getAllocator().CopyString(NameAndSignature)); |
3411 | return Result.TakeString(); |
3412 | } |
3413 | |
3414 | // FIXME: Right now this works well with lambdas. Add support for other functor |
3415 | // types like std::function. |
3416 | static const NamedDecl *extractFunctorCallOperator(const NamedDecl *ND) { |
3417 | const auto *VD = dyn_cast<VarDecl>(ND); |
3418 | if (!VD) |
3419 | return nullptr; |
3420 | const auto *RecordDecl = VD->getType()->getAsCXXRecordDecl(); |
3421 | if (!RecordDecl || !RecordDecl->isLambda()) |
3422 | return nullptr; |
3423 | return RecordDecl->getLambdaCallOperator(); |
3424 | } |
3425 | |
3426 | CodeCompletionString *CodeCompletionResult::createCodeCompletionStringForDecl( |
3427 | Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result, |
3428 | bool IncludeBriefComments, const CodeCompletionContext &CCContext, |
3429 | PrintingPolicy &Policy) { |
3430 | const NamedDecl *ND = Declaration; |
3431 | Result.addParentContext(ND->getDeclContext()); |
3432 | |
3433 | if (IncludeBriefComments) { |
3434 | // Add documentation comment, if it exists. |
3435 | if (const RawComment *RC = getCompletionComment(Ctx, Declaration)) { |
3436 | Result.addBriefComment(RC->getBriefText(Ctx)); |
3437 | } |
3438 | } |
3439 | |
3440 | if (StartsNestedNameSpecifier) { |
3441 | Result.AddTypedTextChunk( |
3442 | Result.getAllocator().CopyString(ND->getNameAsString())); |
3443 | Result.AddTextChunk("::"); |
3444 | return Result.TakeString(); |
3445 | } |
3446 | |
3447 | for (const auto *I : ND->specific_attrs<AnnotateAttr>()) |
3448 | Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation())); |
3449 | |
3450 | auto AddFunctionTypeAndResult = [&](const FunctionDecl *Function) { |
3451 | AddResultTypeChunk(Ctx, Policy, Function, CCContext.getBaseType(), Result); |
3452 | AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, |
3453 | Ctx, Policy); |
3454 | AddTypedNameChunk(Ctx, Policy, ND, Result); |
3455 | Result.AddChunk(CodeCompletionString::CK_LeftParen); |
3456 | AddFunctionParameterChunks(PP, Policy, Function, Result); |
3457 | Result.AddChunk(CodeCompletionString::CK_RightParen); |
3458 | AddFunctionTypeQualsToCompletionString(Result, Function); |
3459 | }; |
3460 | |
3461 | if (const auto *Function = dyn_cast<FunctionDecl>(ND)) { |
3462 | AddFunctionTypeAndResult(Function); |
3463 | return Result.TakeString(); |
3464 | } |
3465 | |
3466 | if (const auto *CallOperator = |
3467 | dyn_cast_or_null<FunctionDecl>(extractFunctorCallOperator(ND))) { |
3468 | AddFunctionTypeAndResult(CallOperator); |
3469 | return Result.TakeString(); |
3470 | } |
3471 | |
3472 | AddResultTypeChunk(Ctx, Policy, ND, CCContext.getBaseType(), Result); |
3473 | |
3474 | if (const FunctionTemplateDecl *FunTmpl = |
3475 | dyn_cast<FunctionTemplateDecl>(ND)) { |
3476 | AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, |
3477 | Ctx, Policy); |
3478 | FunctionDecl *Function = FunTmpl->getTemplatedDecl(); |
3479 | AddTypedNameChunk(Ctx, Policy, Function, Result); |
3480 | |
3481 | // Figure out which template parameters are deduced (or have default |
3482 | // arguments). |
3483 | llvm::SmallBitVector Deduced; |
3484 | Sema::MarkDeducedTemplateParameters(Ctx, FunTmpl, Deduced); |
3485 | unsigned LastDeducibleArgument; |
3486 | for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0; |
3487 | --LastDeducibleArgument) { |
3488 | if (!Deduced[LastDeducibleArgument - 1]) { |
3489 | // C++0x: Figure out if the template argument has a default. If so, |
3490 | // the user doesn't need to type this argument. |
3491 | // FIXME: We need to abstract template parameters better! |
3492 | bool HasDefaultArg = false; |
3493 | NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam( |
3494 | LastDeducibleArgument - 1); |
3495 | if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) |
3496 | HasDefaultArg = TTP->hasDefaultArgument(); |
3497 | else if (NonTypeTemplateParmDecl *NTTP = |
3498 | dyn_cast<NonTypeTemplateParmDecl>(Param)) |
3499 | HasDefaultArg = NTTP->hasDefaultArgument(); |
3500 | else { |
3501 | assert(isa<TemplateTemplateParmDecl>(Param))((void)0); |
3502 | HasDefaultArg = |
3503 | cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument(); |
3504 | } |
3505 | |
3506 | if (!HasDefaultArg) |
3507 | break; |
3508 | } |
3509 | } |
3510 | |
3511 | if (LastDeducibleArgument) { |
3512 | // Some of the function template arguments cannot be deduced from a |
3513 | // function call, so we introduce an explicit template argument list |
3514 | // containing all of the arguments up to the first deducible argument. |
3515 | Result.AddChunk(CodeCompletionString::CK_LeftAngle); |
3516 | AddTemplateParameterChunks(Ctx, Policy, FunTmpl, Result, |
3517 | LastDeducibleArgument); |
3518 | Result.AddChunk(CodeCompletionString::CK_RightAngle); |
3519 | } |
3520 | |
3521 | // Add the function parameters |
3522 | Result.AddChunk(CodeCompletionString::CK_LeftParen); |
3523 | AddFunctionParameterChunks(PP, Policy, Function, Result); |
3524 | Result.AddChunk(CodeCompletionString::CK_RightParen); |
3525 | AddFunctionTypeQualsToCompletionString(Result, Function); |
3526 | return Result.TakeString(); |
3527 | } |
3528 | |
3529 | if (const auto *Template = dyn_cast<TemplateDecl>(ND)) { |
3530 | AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, |
3531 | Ctx, Policy); |
3532 | Result.AddTypedTextChunk( |
3533 | Result.getAllocator().CopyString(Template->getNameAsString())); |
3534 | Result.AddChunk(CodeCompletionString::CK_LeftAngle); |
3535 | AddTemplateParameterChunks(Ctx, Policy, Template, Result); |
3536 | Result.AddChunk(CodeCompletionString::CK_RightAngle); |
3537 | return Result.TakeString(); |
3538 | } |
3539 | |
3540 | if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) { |
3541 | Selector Sel = Method->getSelector(); |
3542 | if (Sel.isUnarySelector()) { |
3543 | Result.AddTypedTextChunk( |
3544 | Result.getAllocator().CopyString(Sel.getNameForSlot(0))); |
3545 | return Result.TakeString(); |
3546 | } |
3547 | |
3548 | std::string SelName = Sel.getNameForSlot(0).str(); |
3549 | SelName += ':'; |
3550 | if (StartParameter == 0) |
3551 | Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName)); |
3552 | else { |
3553 | Result.AddInformativeChunk(Result.getAllocator().CopyString(SelName)); |
3554 | |
3555 | // If there is only one parameter, and we're past it, add an empty |
3556 | // typed-text chunk since there is nothing to type. |
3557 | if (Method->param_size() == 1) |
3558 | Result.AddTypedTextChunk(""); |
3559 | } |
3560 | unsigned Idx = 0; |
3561 | // The extra Idx < Sel.getNumArgs() check is needed due to legacy C-style |
3562 | // method parameters. |
3563 | for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(), |
3564 | PEnd = Method->param_end(); |
3565 | P != PEnd && Idx < Sel.getNumArgs(); (void)++P, ++Idx) { |
3566 | if (Idx > 0) { |
3567 | std::string Keyword; |
3568 | if (Idx > StartParameter) |
3569 | Result.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
3570 | if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx)) |
3571 | Keyword += II->getName(); |
3572 | Keyword += ":"; |
3573 | if (Idx < StartParameter || AllParametersAreInformative) |
3574 | Result.AddInformativeChunk(Result.getAllocator().CopyString(Keyword)); |
3575 | else |
3576 | Result.AddTypedTextChunk(Result.getAllocator().CopyString(Keyword)); |
3577 | } |
3578 | |
3579 | // If we're before the starting parameter, skip the placeholder. |
3580 | if (Idx < StartParameter) |
3581 | continue; |
3582 | |
3583 | std::string Arg; |
3584 | QualType ParamType = (*P)->getType(); |
3585 | Optional<ArrayRef<QualType>> ObjCSubsts; |
3586 | if (!CCContext.getBaseType().isNull()) |
3587 | ObjCSubsts = CCContext.getBaseType()->getObjCSubstitutions(Method); |
3588 | |
3589 | if (ParamType->isBlockPointerType() && !DeclaringEntity) |
3590 | Arg = FormatFunctionParameter(Policy, *P, true, |
3591 | /*SuppressBlock=*/false, ObjCSubsts); |
3592 | else { |
3593 | if (ObjCSubsts) |
3594 | ParamType = ParamType.substObjCTypeArgs( |
3595 | Ctx, *ObjCSubsts, ObjCSubstitutionContext::Parameter); |
3596 | Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier(), |
3597 | ParamType); |
3598 | Arg += ParamType.getAsString(Policy) + ")"; |
3599 | if (IdentifierInfo *II = (*P)->getIdentifier()) |
3600 | if (DeclaringEntity || AllParametersAreInformative) |
3601 | Arg += II->getName(); |
3602 | } |
3603 | |
3604 | if (Method->isVariadic() && (P + 1) == PEnd) |
3605 | Arg += ", ..."; |
3606 | |
3607 | if (DeclaringEntity) |
3608 | Result.AddTextChunk(Result.getAllocator().CopyString(Arg)); |
3609 | else if (AllParametersAreInformative) |
3610 | Result.AddInformativeChunk(Result.getAllocator().CopyString(Arg)); |
3611 | else |
3612 | Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg)); |
3613 | } |
3614 | |
3615 | if (Method->isVariadic()) { |
3616 | if (Method->param_size() == 0) { |
3617 | if (DeclaringEntity) |
3618 | Result.AddTextChunk(", ..."); |
3619 | else if (AllParametersAreInformative) |
3620 | Result.AddInformativeChunk(", ..."); |
3621 | else |
3622 | Result.AddPlaceholderChunk(", ..."); |
3623 | } |
3624 | |
3625 | MaybeAddSentinel(PP, Method, Result); |
3626 | } |
3627 | |
3628 | return Result.TakeString(); |
3629 | } |
3630 | |
3631 | if (Qualifier) |
3632 | AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, |
3633 | Ctx, Policy); |
3634 | |
3635 | Result.AddTypedTextChunk( |
3636 | Result.getAllocator().CopyString(ND->getNameAsString())); |
3637 | return Result.TakeString(); |
3638 | } |
3639 | |
3640 | const RawComment *clang::getCompletionComment(const ASTContext &Ctx, |
3641 | const NamedDecl *ND) { |
3642 | if (!ND) |
3643 | return nullptr; |
3644 | if (auto *RC = Ctx.getRawCommentForAnyRedecl(ND)) |
3645 | return RC; |
3646 | |
3647 | // Try to find comment from a property for ObjC methods. |
3648 | const auto *M = dyn_cast<ObjCMethodDecl>(ND); |
3649 | if (!M) |
3650 | return nullptr; |
3651 | const ObjCPropertyDecl *PDecl = M->findPropertyDecl(); |
3652 | if (!PDecl) |
3653 | return nullptr; |
3654 | |
3655 | return Ctx.getRawCommentForAnyRedecl(PDecl); |
3656 | } |
3657 | |
3658 | const RawComment *clang::getPatternCompletionComment(const ASTContext &Ctx, |
3659 | const NamedDecl *ND) { |
3660 | const auto *M = dyn_cast_or_null<ObjCMethodDecl>(ND); |
3661 | if (!M || !M->isPropertyAccessor()) |
3662 | return nullptr; |
3663 | |
3664 | // Provide code completion comment for self.GetterName where |
3665 | // GetterName is the getter method for a property with name |
3666 | // different from the property name (declared via a property |
3667 | // getter attribute. |
3668 | const ObjCPropertyDecl *PDecl = M->findPropertyDecl(); |
3669 | if (!PDecl) |
3670 | return nullptr; |
3671 | if (PDecl->getGetterName() == M->getSelector() && |
3672 | PDecl->getIdentifier() != M->getIdentifier()) { |
3673 | if (auto *RC = Ctx.getRawCommentForAnyRedecl(M)) |
3674 | return RC; |
3675 | if (auto *RC = Ctx.getRawCommentForAnyRedecl(PDecl)) |
3676 | return RC; |
3677 | } |
3678 | return nullptr; |
3679 | } |
3680 | |
3681 | const RawComment *clang::getParameterComment( |
3682 | const ASTContext &Ctx, |
3683 | const CodeCompleteConsumer::OverloadCandidate &Result, unsigned ArgIndex) { |
3684 | auto FDecl = Result.getFunction(); |
3685 | if (!FDecl) |
3686 | return nullptr; |
3687 | if (ArgIndex < FDecl->getNumParams()) |
3688 | return Ctx.getRawCommentForAnyRedecl(FDecl->getParamDecl(ArgIndex)); |
3689 | return nullptr; |
3690 | } |
3691 | |
3692 | /// Add function overload parameter chunks to the given code completion |
3693 | /// string. |
3694 | static void AddOverloadParameterChunks(ASTContext &Context, |
3695 | const PrintingPolicy &Policy, |
3696 | const FunctionDecl *Function, |
3697 | const FunctionProtoType *Prototype, |
3698 | CodeCompletionBuilder &Result, |
3699 | unsigned CurrentArg, unsigned Start = 0, |
3700 | bool InOptional = false) { |
3701 | bool FirstParameter = true; |
3702 | unsigned NumParams = |
3703 | Function ? Function->getNumParams() : Prototype->getNumParams(); |
3704 | |
3705 | for (unsigned P = Start; P != NumParams; ++P) { |
3706 | if (Function && Function->getParamDecl(P)->hasDefaultArg() && !InOptional) { |
3707 | // When we see an optional default argument, put that argument and |
3708 | // the remaining default arguments into a new, optional string. |
3709 | CodeCompletionBuilder Opt(Result.getAllocator(), |
3710 | Result.getCodeCompletionTUInfo()); |
3711 | if (!FirstParameter) |
3712 | Opt.AddChunk(CodeCompletionString::CK_Comma); |
3713 | // Optional sections are nested. |
3714 | AddOverloadParameterChunks(Context, Policy, Function, Prototype, Opt, |
3715 | CurrentArg, P, /*InOptional=*/true); |
3716 | Result.AddOptionalChunk(Opt.TakeString()); |
3717 | return; |
3718 | } |
3719 | |
3720 | if (FirstParameter) |
3721 | FirstParameter = false; |
3722 | else |
3723 | Result.AddChunk(CodeCompletionString::CK_Comma); |
3724 | |
3725 | InOptional = false; |
3726 | |
3727 | // Format the placeholder string. |
3728 | std::string Placeholder; |
3729 | if (Function) { |
3730 | const ParmVarDecl *Param = Function->getParamDecl(P); |
3731 | Placeholder = FormatFunctionParameter(Policy, Param); |
3732 | if (Param->hasDefaultArg()) |
3733 | Placeholder += GetDefaultValueString(Param, Context.getSourceManager(), |
3734 | Context.getLangOpts()); |
3735 | } else { |
3736 | Placeholder = Prototype->getParamType(P).getAsString(Policy); |
3737 | } |
3738 | |
3739 | if (P == CurrentArg) |
3740 | Result.AddCurrentParameterChunk( |
3741 | Result.getAllocator().CopyString(Placeholder)); |
3742 | else |
3743 | Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Placeholder)); |
3744 | } |
3745 | |
3746 | if (Prototype && Prototype->isVariadic()) { |
3747 | CodeCompletionBuilder Opt(Result.getAllocator(), |
3748 | Result.getCodeCompletionTUInfo()); |
3749 | if (!FirstParameter) |
3750 | Opt.AddChunk(CodeCompletionString::CK_Comma); |
3751 | |
3752 | if (CurrentArg < NumParams) |
3753 | Opt.AddPlaceholderChunk("..."); |
3754 | else |
3755 | Opt.AddCurrentParameterChunk("..."); |
3756 | |
3757 | Result.AddOptionalChunk(Opt.TakeString()); |
3758 | } |
3759 | } |
3760 | |
3761 | CodeCompletionString * |
3762 | CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( |
3763 | unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator, |
3764 | CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments) const { |
3765 | PrintingPolicy Policy = getCompletionPrintingPolicy(S); |
3766 | // Show signatures of constructors as they are declared: |
3767 | // vector(int n) rather than vector<string>(int n) |
3768 | // This is less noisy without being less clear, and avoids tricky cases. |
3769 | Policy.SuppressTemplateArgsInCXXConstructors = true; |
3770 | |
3771 | // FIXME: Set priority, availability appropriately. |
3772 | CodeCompletionBuilder Result(Allocator, CCTUInfo, 1, |
3773 | CXAvailability_Available); |
3774 | FunctionDecl *FDecl = getFunction(); |
3775 | const FunctionProtoType *Proto = |
3776 | dyn_cast<FunctionProtoType>(getFunctionType()); |
3777 | if (!FDecl && !Proto) { |
3778 | // Function without a prototype. Just give the return type and a |
3779 | // highlighted ellipsis. |
3780 | const FunctionType *FT = getFunctionType(); |
3781 | Result.AddResultTypeChunk(Result.getAllocator().CopyString( |
3782 | FT->getReturnType().getAsString(Policy))); |
3783 | Result.AddChunk(CodeCompletionString::CK_LeftParen); |
3784 | Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "..."); |
3785 | Result.AddChunk(CodeCompletionString::CK_RightParen); |
3786 | return Result.TakeString(); |
3787 | } |
3788 | |
3789 | if (FDecl) { |
3790 | if (IncludeBriefComments) { |
3791 | if (auto RC = getParameterComment(S.getASTContext(), *this, CurrentArg)) |
3792 | Result.addBriefComment(RC->getBriefText(S.getASTContext())); |
3793 | } |
3794 | AddResultTypeChunk(S.Context, Policy, FDecl, QualType(), Result); |
3795 | |
3796 | std::string Name; |
3797 | llvm::raw_string_ostream OS(Name); |
3798 | FDecl->getDeclName().print(OS, Policy); |
3799 | Result.AddTextChunk(Result.getAllocator().CopyString(OS.str())); |
3800 | } else { |
3801 | Result.AddResultTypeChunk(Result.getAllocator().CopyString( |
3802 | Proto->getReturnType().getAsString(Policy))); |
3803 | } |
3804 | |
3805 | Result.AddChunk(CodeCompletionString::CK_LeftParen); |
3806 | AddOverloadParameterChunks(S.getASTContext(), Policy, FDecl, Proto, Result, |
3807 | CurrentArg); |
3808 | Result.AddChunk(CodeCompletionString::CK_RightParen); |
3809 | |
3810 | return Result.TakeString(); |
3811 | } |
3812 | |
3813 | unsigned clang::getMacroUsagePriority(StringRef MacroName, |
3814 | const LangOptions &LangOpts, |
3815 | bool PreferredTypeIsPointer) { |
3816 | unsigned Priority = CCP_Macro; |
3817 | |
3818 | // Treat the "nil", "Nil" and "NULL" macros as null pointer constants. |
3819 | if (MacroName.equals("nil") || MacroName.equals("NULL") || |
3820 | MacroName.equals("Nil")) { |
3821 | Priority = CCP_Constant; |
3822 | if (PreferredTypeIsPointer) |
3823 | Priority = Priority / CCF_SimilarTypeMatch; |
3824 | } |
3825 | // Treat "YES", "NO", "true", and "false" as constants. |
3826 | else if (MacroName.equals("YES") || MacroName.equals("NO") || |
3827 | MacroName.equals("true") || MacroName.equals("false")) |
3828 | Priority = CCP_Constant; |
3829 | // Treat "bool" as a type. |
3830 | else if (MacroName.equals("bool")) |
3831 | Priority = CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0); |
3832 | |
3833 | return Priority; |
3834 | } |
3835 | |
3836 | CXCursorKind clang::getCursorKindForDecl(const Decl *D) { |
3837 | if (!D) |
3838 | return CXCursor_UnexposedDecl; |
3839 | |
3840 | switch (D->getKind()) { |
3841 | case Decl::Enum: |
3842 | return CXCursor_EnumDecl; |
3843 | case Decl::EnumConstant: |
3844 | return CXCursor_EnumConstantDecl; |
3845 | case Decl::Field: |
3846 | return CXCursor_FieldDecl; |
3847 | case Decl::Function: |
3848 | return CXCursor_FunctionDecl; |
3849 | case Decl::ObjCCategory: |
3850 | return CXCursor_ObjCCategoryDecl; |
3851 | case Decl::ObjCCategoryImpl: |
3852 | return CXCursor_ObjCCategoryImplDecl; |
3853 | case Decl::ObjCImplementation: |
3854 | return CXCursor_ObjCImplementationDecl; |
3855 | |
3856 | case Decl::ObjCInterface: |
3857 | return CXCursor_ObjCInterfaceDecl; |
3858 | case Decl::ObjCIvar: |
3859 | return CXCursor_ObjCIvarDecl; |
3860 | case Decl::ObjCMethod: |
3861 | return cast<ObjCMethodDecl>(D)->isInstanceMethod() |
3862 | ? CXCursor_ObjCInstanceMethodDecl |
3863 | : CXCursor_ObjCClassMethodDecl; |
3864 | case Decl::CXXMethod: |
3865 | return CXCursor_CXXMethod; |
3866 | case Decl::CXXConstructor: |
3867 | return CXCursor_Constructor; |
3868 | case Decl::CXXDestructor: |
3869 | return CXCursor_Destructor; |
3870 | case Decl::CXXConversion: |
3871 | return CXCursor_ConversionFunction; |
3872 | case Decl::ObjCProperty: |
3873 | return CXCursor_ObjCPropertyDecl; |
3874 | case Decl::ObjCProtocol: |
3875 | return CXCursor_ObjCProtocolDecl; |
3876 | case Decl::ParmVar: |
3877 | return CXCursor_ParmDecl; |
3878 | case Decl::Typedef: |
3879 | return CXCursor_TypedefDecl; |
3880 | case Decl::TypeAlias: |
3881 | return CXCursor_TypeAliasDecl; |
3882 | case Decl::TypeAliasTemplate: |
3883 | return CXCursor_TypeAliasTemplateDecl; |
3884 | case Decl::Var: |
3885 | return CXCursor_VarDecl; |
3886 | case Decl::Namespace: |
3887 | return CXCursor_Namespace; |
3888 | case Decl::NamespaceAlias: |
3889 | return CXCursor_NamespaceAlias; |
3890 | case Decl::TemplateTypeParm: |
3891 | return CXCursor_TemplateTypeParameter; |
3892 | case Decl::NonTypeTemplateParm: |
3893 | return CXCursor_NonTypeTemplateParameter; |
3894 | case Decl::TemplateTemplateParm: |
3895 | return CXCursor_TemplateTemplateParameter; |
3896 | case Decl::FunctionTemplate: |
3897 | return CXCursor_FunctionTemplate; |
3898 | case Decl::ClassTemplate: |
3899 | return CXCursor_ClassTemplate; |
3900 | case Decl::AccessSpec: |
3901 | return CXCursor_CXXAccessSpecifier; |
3902 | case Decl::ClassTemplatePartialSpecialization: |
3903 | return CXCursor_ClassTemplatePartialSpecialization; |
3904 | case Decl::UsingDirective: |
3905 | return CXCursor_UsingDirective; |
3906 | case Decl::StaticAssert: |
3907 | return CXCursor_StaticAssert; |
3908 | case Decl::Friend: |
3909 | return CXCursor_FriendDecl; |
3910 | case Decl::TranslationUnit: |
3911 | return CXCursor_TranslationUnit; |
3912 | |
3913 | case Decl::Using: |
3914 | case Decl::UnresolvedUsingValue: |
3915 | case Decl::UnresolvedUsingTypename: |
3916 | return CXCursor_UsingDeclaration; |
3917 | |
3918 | case Decl::UsingEnum: |
3919 | return CXCursor_EnumDecl; |
3920 | |
3921 | case Decl::ObjCPropertyImpl: |
3922 | switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) { |
3923 | case ObjCPropertyImplDecl::Dynamic: |
3924 | return CXCursor_ObjCDynamicDecl; |
3925 | |
3926 | case ObjCPropertyImplDecl::Synthesize: |
3927 | return CXCursor_ObjCSynthesizeDecl; |
3928 | } |
3929 | llvm_unreachable("Unexpected Kind!")__builtin_unreachable(); |
3930 | |
3931 | case Decl::Import: |
3932 | return CXCursor_ModuleImportDecl; |
3933 | |
3934 | case Decl::ObjCTypeParam: |
3935 | return CXCursor_TemplateTypeParameter; |
3936 | |
3937 | default: |
3938 | if (const auto *TD = dyn_cast<TagDecl>(D)) { |
3939 | switch (TD->getTagKind()) { |
3940 | case TTK_Interface: // fall through |
3941 | case TTK_Struct: |
3942 | return CXCursor_StructDecl; |
3943 | case TTK_Class: |
3944 | return CXCursor_ClassDecl; |
3945 | case TTK_Union: |
3946 | return CXCursor_UnionDecl; |
3947 | case TTK_Enum: |
3948 | return CXCursor_EnumDecl; |
3949 | } |
3950 | } |
3951 | } |
3952 | |
3953 | return CXCursor_UnexposedDecl; |
3954 | } |
3955 | |
3956 | static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results, |
3957 | bool LoadExternal, bool IncludeUndefined, |
3958 | bool TargetTypeIsPointer = false) { |
3959 | typedef CodeCompletionResult Result; |
3960 | |
3961 | Results.EnterNewScope(); |
3962 | |
3963 | for (Preprocessor::macro_iterator M = PP.macro_begin(LoadExternal), |
3964 | MEnd = PP.macro_end(LoadExternal); |
3965 | M != MEnd; ++M) { |
3966 | auto MD = PP.getMacroDefinition(M->first); |
3967 | if (IncludeUndefined || MD) { |
3968 | MacroInfo *MI = MD.getMacroInfo(); |
3969 | if (MI && MI->isUsedForHeaderGuard()) |
3970 | continue; |
3971 | |
3972 | Results.AddResult( |
3973 | Result(M->first, MI, |
3974 | getMacroUsagePriority(M->first->getName(), PP.getLangOpts(), |
3975 | TargetTypeIsPointer))); |
3976 | } |
3977 | } |
3978 | |
3979 | Results.ExitScope(); |
3980 | } |
3981 | |
3982 | static void AddPrettyFunctionResults(const LangOptions &LangOpts, |
3983 | ResultBuilder &Results) { |
3984 | typedef CodeCompletionResult Result; |
3985 | |
3986 | Results.EnterNewScope(); |
3987 | |
3988 | Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant)); |
3989 | Results.AddResult(Result("__FUNCTION__", CCP_Constant)); |
3990 | if (LangOpts.C99 || LangOpts.CPlusPlus11) |
3991 | Results.AddResult(Result("__func__", CCP_Constant)); |
3992 | Results.ExitScope(); |
3993 | } |
3994 | |
3995 | static void HandleCodeCompleteResults(Sema *S, |
3996 | CodeCompleteConsumer *CodeCompleter, |
3997 | CodeCompletionContext Context, |
3998 | CodeCompletionResult *Results, |
3999 | unsigned NumResults) { |
4000 | if (CodeCompleter) |
4001 | CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults); |
4002 | } |
4003 | |
4004 | static CodeCompletionContext |
4005 | mapCodeCompletionContext(Sema &S, Sema::ParserCompletionContext PCC) { |
4006 | switch (PCC) { |
4007 | case Sema::PCC_Namespace: |
4008 | return CodeCompletionContext::CCC_TopLevel; |
4009 | |
4010 | case Sema::PCC_Class: |
4011 | return CodeCompletionContext::CCC_ClassStructUnion; |
4012 | |
4013 | case Sema::PCC_ObjCInterface: |
4014 | return CodeCompletionContext::CCC_ObjCInterface; |
4015 | |
4016 | case Sema::PCC_ObjCImplementation: |
4017 | return CodeCompletionContext::CCC_ObjCImplementation; |
4018 | |
4019 | case Sema::PCC_ObjCInstanceVariableList: |
4020 | return CodeCompletionContext::CCC_ObjCIvarList; |
4021 | |
4022 | case Sema::PCC_Template: |
4023 | case Sema::PCC_MemberTemplate: |
4024 | if (S.CurContext->isFileContext()) |
4025 | return CodeCompletionContext::CCC_TopLevel; |
4026 | if (S.CurContext->isRecord()) |
4027 | return CodeCompletionContext::CCC_ClassStructUnion; |
4028 | return CodeCompletionContext::CCC_Other; |
4029 | |
4030 | case Sema::PCC_RecoveryInFunction: |
4031 | return CodeCompletionContext::CCC_Recovery; |
4032 | |
4033 | case Sema::PCC_ForInit: |
4034 | if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 || |
4035 | S.getLangOpts().ObjC) |
4036 | return CodeCompletionContext::CCC_ParenthesizedExpression; |
4037 | else |
4038 | return CodeCompletionContext::CCC_Expression; |
4039 | |
4040 | case Sema::PCC_Expression: |
4041 | return CodeCompletionContext::CCC_Expression; |
4042 | case Sema::PCC_Condition: |
4043 | return CodeCompletionContext(CodeCompletionContext::CCC_Expression, |
4044 | S.getASTContext().BoolTy); |
4045 | |
4046 | case Sema::PCC_Statement: |
4047 | return CodeCompletionContext::CCC_Statement; |
4048 | |
4049 | case Sema::PCC_Type: |
4050 | return CodeCompletionContext::CCC_Type; |
4051 | |
4052 | case Sema::PCC_ParenthesizedExpression: |
4053 | return CodeCompletionContext::CCC_ParenthesizedExpression; |
4054 | |
4055 | case Sema::PCC_LocalDeclarationSpecifiers: |
4056 | return CodeCompletionContext::CCC_Type; |
4057 | } |
4058 | |
4059 | llvm_unreachable("Invalid ParserCompletionContext!")__builtin_unreachable(); |
4060 | } |
4061 | |
4062 | /// If we're in a C++ virtual member function, add completion results |
4063 | /// that invoke the functions we override, since it's common to invoke the |
4064 | /// overridden function as well as adding new functionality. |
4065 | /// |
4066 | /// \param S The semantic analysis object for which we are generating results. |
4067 | /// |
4068 | /// \param InContext This context in which the nested-name-specifier preceding |
4069 | /// the code-completion point |
4070 | static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext, |
4071 | ResultBuilder &Results) { |
4072 | // Look through blocks. |
4073 | DeclContext *CurContext = S.CurContext; |
4074 | while (isa<BlockDecl>(CurContext)) |
4075 | CurContext = CurContext->getParent(); |
4076 | |
4077 | CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext); |
4078 | if (!Method || !Method->isVirtual()) |
4079 | return; |
4080 | |
4081 | // We need to have names for all of the parameters, if we're going to |
4082 | // generate a forwarding call. |
4083 | for (auto P : Method->parameters()) |
4084 | if (!P->getDeclName()) |
4085 | return; |
4086 | |
4087 | PrintingPolicy Policy = getCompletionPrintingPolicy(S); |
4088 | for (const CXXMethodDecl *Overridden : Method->overridden_methods()) { |
4089 | CodeCompletionBuilder Builder(Results.getAllocator(), |
4090 | Results.getCodeCompletionTUInfo()); |
4091 | if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl()) |
4092 | continue; |
4093 | |
4094 | // If we need a nested-name-specifier, add one now. |
4095 | if (!InContext) { |
4096 | NestedNameSpecifier *NNS = getRequiredQualification( |
4097 | S.Context, CurContext, Overridden->getDeclContext()); |
4098 | if (NNS) { |
4099 | std::string Str; |
4100 | llvm::raw_string_ostream OS(Str); |
4101 | NNS->print(OS, Policy); |
4102 | Builder.AddTextChunk(Results.getAllocator().CopyString(OS.str())); |
4103 | } |
4104 | } else if (!InContext->Equals(Overridden->getDeclContext())) |
4105 | continue; |
4106 | |
4107 | Builder.AddTypedTextChunk( |
4108 | Results.getAllocator().CopyString(Overridden->getNameAsString())); |
4109 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
4110 | bool FirstParam = true; |
4111 | for (auto P : Method->parameters()) { |
4112 | if (FirstParam) |
4113 | FirstParam = false; |
4114 | else |
4115 | Builder.AddChunk(CodeCompletionString::CK_Comma); |
4116 | |
4117 | Builder.AddPlaceholderChunk( |
4118 | Results.getAllocator().CopyString(P->getIdentifier()->getName())); |
4119 | } |
4120 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
4121 | Results.AddResult(CodeCompletionResult( |
4122 | Builder.TakeString(), CCP_SuperCompletion, CXCursor_CXXMethod, |
4123 | CXAvailability_Available, Overridden)); |
4124 | Results.Ignore(Overridden); |
4125 | } |
4126 | } |
4127 | |
4128 | void Sema::CodeCompleteModuleImport(SourceLocation ImportLoc, |
4129 | ModuleIdPath Path) { |
4130 | typedef CodeCompletionResult Result; |
4131 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
4132 | CodeCompleter->getCodeCompletionTUInfo(), |
4133 | CodeCompletionContext::CCC_Other); |
4134 | Results.EnterNewScope(); |
4135 | |
4136 | CodeCompletionAllocator &Allocator = Results.getAllocator(); |
4137 | CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); |
4138 | typedef CodeCompletionResult Result; |
4139 | if (Path.empty()) { |
4140 | // Enumerate all top-level modules. |
4141 | SmallVector<Module *, 8> Modules; |
4142 | PP.getHeaderSearchInfo().collectAllModules(Modules); |
4143 | for (unsigned I = 0, N = Modules.size(); I != N; ++I) { |
4144 | Builder.AddTypedTextChunk( |
4145 | Builder.getAllocator().CopyString(Modules[I]->Name)); |
4146 | Results.AddResult(Result( |
4147 | Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl, |
4148 | Modules[I]->isAvailable() ? CXAvailability_Available |
4149 | : CXAvailability_NotAvailable)); |
4150 | } |
4151 | } else if (getLangOpts().Modules) { |
4152 | // Load the named module. |
4153 | Module *Mod = |
4154 | PP.getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible, |
4155 | /*IsInclusionDirective=*/false); |
4156 | // Enumerate submodules. |
4157 | if (Mod) { |
4158 | for (Module::submodule_iterator Sub = Mod->submodule_begin(), |
4159 | SubEnd = Mod->submodule_end(); |
4160 | Sub != SubEnd; ++Sub) { |
4161 | |
4162 | Builder.AddTypedTextChunk( |
4163 | Builder.getAllocator().CopyString((*Sub)->Name)); |
4164 | Results.AddResult(Result( |
4165 | Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl, |
4166 | (*Sub)->isAvailable() ? CXAvailability_Available |
4167 | : CXAvailability_NotAvailable)); |
4168 | } |
4169 | } |
4170 | } |
4171 | Results.ExitScope(); |
4172 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
4173 | Results.data(), Results.size()); |
4174 | } |
4175 | |
4176 | void Sema::CodeCompleteOrdinaryName(Scope *S, |
4177 | ParserCompletionContext CompletionContext) { |
4178 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
4179 | CodeCompleter->getCodeCompletionTUInfo(), |
4180 | mapCodeCompletionContext(*this, CompletionContext)); |
4181 | Results.EnterNewScope(); |
4182 | |
4183 | // Determine how to filter results, e.g., so that the names of |
4184 | // values (functions, enumerators, function templates, etc.) are |
4185 | // only allowed where we can have an expression. |
4186 | switch (CompletionContext) { |
4187 | case PCC_Namespace: |
4188 | case PCC_Class: |
4189 | case PCC_ObjCInterface: |
4190 | case PCC_ObjCImplementation: |
4191 | case PCC_ObjCInstanceVariableList: |
4192 | case PCC_Template: |
4193 | case PCC_MemberTemplate: |
4194 | case PCC_Type: |
4195 | case PCC_LocalDeclarationSpecifiers: |
4196 | Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName); |
4197 | break; |
4198 | |
4199 | case PCC_Statement: |
4200 | case PCC_ParenthesizedExpression: |
4201 | case PCC_Expression: |
4202 | case PCC_ForInit: |
4203 | case PCC_Condition: |
4204 | if (WantTypesInContext(CompletionContext, getLangOpts())) |
4205 | Results.setFilter(&ResultBuilder::IsOrdinaryName); |
4206 | else |
4207 | Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); |
4208 | |
4209 | if (getLangOpts().CPlusPlus) |
4210 | MaybeAddOverrideCalls(*this, /*InContext=*/nullptr, Results); |
4211 | break; |
4212 | |
4213 | case PCC_RecoveryInFunction: |
4214 | // Unfiltered |
4215 | break; |
4216 | } |
4217 | |
4218 | // If we are in a C++ non-static member function, check the qualifiers on |
4219 | // the member function to filter/prioritize the results list. |
4220 | auto ThisType = getCurrentThisType(); |
4221 | if (!ThisType.isNull()) |
4222 | Results.setObjectTypeQualifiers(ThisType->getPointeeType().getQualifiers(), |
4223 | VK_LValue); |
4224 | |
4225 | CodeCompletionDeclConsumer Consumer(Results, CurContext); |
4226 | LookupVisibleDecls(S, LookupOrdinaryName, Consumer, |
4227 | CodeCompleter->includeGlobals(), |
4228 | CodeCompleter->loadExternal()); |
4229 | |
4230 | AddOrdinaryNameResults(CompletionContext, S, *this, Results); |
4231 | Results.ExitScope(); |
4232 | |
4233 | switch (CompletionContext) { |
4234 | case PCC_ParenthesizedExpression: |
4235 | case PCC_Expression: |
4236 | case PCC_Statement: |
4237 | case PCC_RecoveryInFunction: |
4238 | if (S->getFnParent()) |
4239 | AddPrettyFunctionResults(getLangOpts(), Results); |
4240 | break; |
4241 | |
4242 | case PCC_Namespace: |
4243 | case PCC_Class: |
4244 | case PCC_ObjCInterface: |
4245 | case PCC_ObjCImplementation: |
4246 | case PCC_ObjCInstanceVariableList: |
4247 | case PCC_Template: |
4248 | case PCC_MemberTemplate: |
4249 | case PCC_ForInit: |
4250 | case PCC_Condition: |
4251 | case PCC_Type: |
4252 | case PCC_LocalDeclarationSpecifiers: |
4253 | break; |
4254 | } |
4255 | |
4256 | if (CodeCompleter->includeMacros()) |
4257 | AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false); |
4258 | |
4259 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
4260 | Results.data(), Results.size()); |
4261 | } |
4262 | |
4263 | static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, |
4264 | ParsedType Receiver, |
4265 | ArrayRef<IdentifierInfo *> SelIdents, |
4266 | bool AtArgumentExpression, bool IsSuper, |
4267 | ResultBuilder &Results); |
4268 | |
4269 | void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, |
4270 | bool AllowNonIdentifiers, |
4271 | bool AllowNestedNameSpecifiers) { |
4272 | typedef CodeCompletionResult Result; |
4273 | ResultBuilder Results( |
4274 | *this, CodeCompleter->getAllocator(), |
4275 | CodeCompleter->getCodeCompletionTUInfo(), |
4276 | AllowNestedNameSpecifiers |
4277 | // FIXME: Try to separate codepath leading here to deduce whether we |
4278 | // need an existing symbol or a new one. |
4279 | ? CodeCompletionContext::CCC_SymbolOrNewName |
4280 | : CodeCompletionContext::CCC_NewName); |
4281 | Results.EnterNewScope(); |
4282 | |
4283 | // Type qualifiers can come after names. |
4284 | Results.AddResult(Result("const")); |
4285 | Results.AddResult(Result("volatile")); |
4286 | if (getLangOpts().C99) |
4287 | Results.AddResult(Result("restrict")); |
4288 | |
4289 | if (getLangOpts().CPlusPlus) { |
4290 | if (getLangOpts().CPlusPlus11 && |
4291 | (DS.getTypeSpecType() == DeclSpec::TST_class || |
4292 | DS.getTypeSpecType() == DeclSpec::TST_struct)) |
4293 | Results.AddResult("final"); |
4294 | |
4295 | if (AllowNonIdentifiers) { |
4296 | Results.AddResult(Result("operator")); |
4297 | } |
4298 | |
4299 | // Add nested-name-specifiers. |
4300 | if (AllowNestedNameSpecifiers) { |
4301 | Results.allowNestedNameSpecifiers(); |
4302 | Results.setFilter(&ResultBuilder::IsImpossibleToSatisfy); |
4303 | CodeCompletionDeclConsumer Consumer(Results, CurContext); |
4304 | LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer, |
4305 | CodeCompleter->includeGlobals(), |
4306 | CodeCompleter->loadExternal()); |
4307 | Results.setFilter(nullptr); |
4308 | } |
4309 | } |
4310 | Results.ExitScope(); |
4311 | |
4312 | // If we're in a context where we might have an expression (rather than a |
4313 | // declaration), and what we've seen so far is an Objective-C type that could |
4314 | // be a receiver of a class message, this may be a class message send with |
4315 | // the initial opening bracket '[' missing. Add appropriate completions. |
4316 | if (AllowNonIdentifiers && !AllowNestedNameSpecifiers && |
4317 | DS.getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier && |
4318 | DS.getTypeSpecType() == DeclSpec::TST_typename && |
4319 | DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified && |
4320 | DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified && |
4321 | !DS.isTypeAltiVecVector() && S && |
4322 | (S->getFlags() & Scope::DeclScope) != 0 && |
4323 | (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope | |
4324 | Scope::FunctionPrototypeScope | Scope::AtCatchScope)) == |
4325 | 0) { |
4326 | ParsedType T = DS.getRepAsType(); |
4327 | if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType()) |
4328 | AddClassMessageCompletions(*this, S, T, None, false, false, Results); |
4329 | } |
4330 | |
4331 | // Note that we intentionally suppress macro results here, since we do not |
4332 | // encourage using macros to produce the names of entities. |
4333 | |
4334 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
4335 | Results.data(), Results.size()); |
4336 | } |
4337 | |
4338 | struct Sema::CodeCompleteExpressionData { |
4339 | CodeCompleteExpressionData(QualType PreferredType = QualType(), |
4340 | bool IsParenthesized = false) |
4341 | : PreferredType(PreferredType), IntegralConstantExpression(false), |
4342 | ObjCCollection(false), IsParenthesized(IsParenthesized) {} |
4343 | |
4344 | QualType PreferredType; |
4345 | bool IntegralConstantExpression; |
4346 | bool ObjCCollection; |
4347 | bool IsParenthesized; |
4348 | SmallVector<Decl *, 4> IgnoreDecls; |
4349 | }; |
4350 | |
4351 | namespace { |
4352 | /// Information that allows to avoid completing redundant enumerators. |
4353 | struct CoveredEnumerators { |
4354 | llvm::SmallPtrSet<EnumConstantDecl *, 8> Seen; |
4355 | NestedNameSpecifier *SuggestedQualifier = nullptr; |
4356 | }; |
4357 | } // namespace |
4358 | |
4359 | static void AddEnumerators(ResultBuilder &Results, ASTContext &Context, |
4360 | EnumDecl *Enum, DeclContext *CurContext, |
4361 | const CoveredEnumerators &Enumerators) { |
4362 | NestedNameSpecifier *Qualifier = Enumerators.SuggestedQualifier; |
4363 | if (Context.getLangOpts().CPlusPlus && !Qualifier && Enumerators.Seen.empty()) { |
4364 | // If there are no prior enumerators in C++, check whether we have to |
4365 | // qualify the names of the enumerators that we suggest, because they |
4366 | // may not be visible in this scope. |
4367 | Qualifier = getRequiredQualification(Context, CurContext, Enum); |
4368 | } |
4369 | |
4370 | Results.EnterNewScope(); |
4371 | for (auto *E : Enum->enumerators()) { |
4372 | if (Enumerators.Seen.count(E)) |
4373 | continue; |
4374 | |
4375 | CodeCompletionResult R(E, CCP_EnumInCase, Qualifier); |
4376 | Results.AddResult(R, CurContext, nullptr, false); |
4377 | } |
4378 | Results.ExitScope(); |
4379 | } |
4380 | |
4381 | /// Try to find a corresponding FunctionProtoType for function-like types (e.g. |
4382 | /// function pointers, std::function, etc). |
4383 | static const FunctionProtoType *TryDeconstructFunctionLike(QualType T) { |
4384 | assert(!T.isNull())((void)0); |
4385 | // Try to extract first template argument from std::function<> and similar. |
4386 | // Note we only handle the sugared types, they closely match what users wrote. |
4387 | // We explicitly choose to not handle ClassTemplateSpecializationDecl. |
4388 | if (auto *Specialization = T->getAs<TemplateSpecializationType>()) { |
4389 | if (Specialization->getNumArgs() != 1) |
4390 | return nullptr; |
4391 | const TemplateArgument &Argument = Specialization->getArg(0); |
4392 | if (Argument.getKind() != TemplateArgument::Type) |
4393 | return nullptr; |
4394 | return Argument.getAsType()->getAs<FunctionProtoType>(); |
4395 | } |
4396 | // Handle other cases. |
4397 | if (T->isPointerType()) |
4398 | T = T->getPointeeType(); |
4399 | return T->getAs<FunctionProtoType>(); |
4400 | } |
4401 | |
4402 | /// Adds a pattern completion for a lambda expression with the specified |
4403 | /// parameter types and placeholders for parameter names. |
4404 | static void AddLambdaCompletion(ResultBuilder &Results, |
4405 | llvm::ArrayRef<QualType> Parameters, |
4406 | const LangOptions &LangOpts) { |
4407 | if (!Results.includeCodePatterns()) |
4408 | return; |
4409 | CodeCompletionBuilder Completion(Results.getAllocator(), |
4410 | Results.getCodeCompletionTUInfo()); |
4411 | // [](<parameters>) {} |
4412 | Completion.AddChunk(CodeCompletionString::CK_LeftBracket); |
4413 | Completion.AddPlaceholderChunk("="); |
4414 | Completion.AddChunk(CodeCompletionString::CK_RightBracket); |
4415 | if (!Parameters.empty()) { |
4416 | Completion.AddChunk(CodeCompletionString::CK_LeftParen); |
4417 | bool First = true; |
4418 | for (auto Parameter : Parameters) { |
4419 | if (!First) |
4420 | Completion.AddChunk(CodeCompletionString::ChunkKind::CK_Comma); |
4421 | else |
4422 | First = false; |
4423 | |
4424 | constexpr llvm::StringLiteral NamePlaceholder = "!#!NAME_GOES_HERE!#!"; |
4425 | std::string Type = std::string(NamePlaceholder); |
4426 | Parameter.getAsStringInternal(Type, PrintingPolicy(LangOpts)); |
4427 | llvm::StringRef Prefix, Suffix; |
4428 | std::tie(Prefix, Suffix) = llvm::StringRef(Type).split(NamePlaceholder); |
4429 | Prefix = Prefix.rtrim(); |
4430 | Suffix = Suffix.ltrim(); |
4431 | |
4432 | Completion.AddTextChunk(Completion.getAllocator().CopyString(Prefix)); |
4433 | Completion.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
4434 | Completion.AddPlaceholderChunk("parameter"); |
4435 | Completion.AddTextChunk(Completion.getAllocator().CopyString(Suffix)); |
4436 | }; |
4437 | Completion.AddChunk(CodeCompletionString::CK_RightParen); |
4438 | } |
4439 | Completion.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace); |
4440 | Completion.AddChunk(CodeCompletionString::CK_LeftBrace); |
4441 | Completion.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
4442 | Completion.AddPlaceholderChunk("body"); |
4443 | Completion.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
4444 | Completion.AddChunk(CodeCompletionString::CK_RightBrace); |
4445 | |
4446 | Results.AddResult(Completion.TakeString()); |
4447 | } |
4448 | |
4449 | /// Perform code-completion in an expression context when we know what |
4450 | /// type we're looking for. |
4451 | void Sema::CodeCompleteExpression(Scope *S, |
4452 | const CodeCompleteExpressionData &Data) { |
4453 | ResultBuilder Results( |
4454 | *this, CodeCompleter->getAllocator(), |
4455 | CodeCompleter->getCodeCompletionTUInfo(), |
4456 | CodeCompletionContext( |
4457 | Data.IsParenthesized |
4458 | ? CodeCompletionContext::CCC_ParenthesizedExpression |
4459 | : CodeCompletionContext::CCC_Expression, |
4460 | Data.PreferredType)); |
4461 | auto PCC = |
4462 | Data.IsParenthesized ? PCC_ParenthesizedExpression : PCC_Expression; |
4463 | if (Data.ObjCCollection) |
4464 | Results.setFilter(&ResultBuilder::IsObjCCollection); |
4465 | else if (Data.IntegralConstantExpression) |
4466 | Results.setFilter(&ResultBuilder::IsIntegralConstantValue); |
4467 | else if (WantTypesInContext(PCC, getLangOpts())) |
4468 | Results.setFilter(&ResultBuilder::IsOrdinaryName); |
4469 | else |
4470 | Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName); |
4471 | |
4472 | if (!Data.PreferredType.isNull()) |
4473 | Results.setPreferredType(Data.PreferredType.getNonReferenceType()); |
4474 | |
4475 | // Ignore any declarations that we were told that we don't care about. |
4476 | for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I) |
4477 | Results.Ignore(Data.IgnoreDecls[I]); |
4478 | |
4479 | CodeCompletionDeclConsumer Consumer(Results, CurContext); |
4480 | LookupVisibleDecls(S, LookupOrdinaryName, Consumer, |
4481 | CodeCompleter->includeGlobals(), |
4482 | CodeCompleter->loadExternal()); |
4483 | |
4484 | Results.EnterNewScope(); |
4485 | AddOrdinaryNameResults(PCC, S, *this, Results); |
4486 | Results.ExitScope(); |
4487 | |
4488 | bool PreferredTypeIsPointer = false; |
4489 | if (!Data.PreferredType.isNull()) { |
4490 | PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType() || |
4491 | Data.PreferredType->isMemberPointerType() || |
4492 | Data.PreferredType->isBlockPointerType(); |
4493 | if (Data.PreferredType->isEnumeralType()) { |
4494 | EnumDecl *Enum = Data.PreferredType->castAs<EnumType>()->getDecl(); |
4495 | if (auto *Def = Enum->getDefinition()) |
4496 | Enum = Def; |
4497 | // FIXME: collect covered enumerators in cases like: |
4498 | // if (x == my_enum::one) { ... } else if (x == ^) {} |
4499 | AddEnumerators(Results, Context, Enum, CurContext, CoveredEnumerators()); |
4500 | } |
4501 | } |
4502 | |
4503 | if (S->getFnParent() && !Data.ObjCCollection && |
4504 | !Data.IntegralConstantExpression) |
4505 | AddPrettyFunctionResults(getLangOpts(), Results); |
4506 | |
4507 | if (CodeCompleter->includeMacros()) |
4508 | AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false, |
4509 | PreferredTypeIsPointer); |
4510 | |
4511 | // Complete a lambda expression when preferred type is a function. |
4512 | if (!Data.PreferredType.isNull() && getLangOpts().CPlusPlus11) { |
4513 | if (const FunctionProtoType *F = |
4514 | TryDeconstructFunctionLike(Data.PreferredType)) |
4515 | AddLambdaCompletion(Results, F->getParamTypes(), getLangOpts()); |
4516 | } |
4517 | |
4518 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
4519 | Results.data(), Results.size()); |
4520 | } |
4521 | |
4522 | void Sema::CodeCompleteExpression(Scope *S, QualType PreferredType, |
4523 | bool IsParenthesized) { |
4524 | return CodeCompleteExpression( |
4525 | S, CodeCompleteExpressionData(PreferredType, IsParenthesized)); |
4526 | } |
4527 | |
4528 | void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E, |
4529 | QualType PreferredType) { |
4530 | if (E.isInvalid()) |
4531 | CodeCompleteExpression(S, PreferredType); |
4532 | else if (getLangOpts().ObjC) |
4533 | CodeCompleteObjCInstanceMessage(S, E.get(), None, false); |
4534 | } |
4535 | |
4536 | /// The set of properties that have already been added, referenced by |
4537 | /// property name. |
4538 | typedef llvm::SmallPtrSet<IdentifierInfo *, 16> AddedPropertiesSet; |
4539 | |
4540 | /// Retrieve the container definition, if any? |
4541 | static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) { |
4542 | if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) { |
4543 | if (Interface->hasDefinition()) |
4544 | return Interface->getDefinition(); |
4545 | |
4546 | return Interface; |
4547 | } |
4548 | |
4549 | if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { |
4550 | if (Protocol->hasDefinition()) |
4551 | return Protocol->getDefinition(); |
4552 | |
4553 | return Protocol; |
4554 | } |
4555 | return Container; |
4556 | } |
4557 | |
4558 | /// Adds a block invocation code completion result for the given block |
4559 | /// declaration \p BD. |
4560 | static void AddObjCBlockCall(ASTContext &Context, const PrintingPolicy &Policy, |
4561 | CodeCompletionBuilder &Builder, |
4562 | const NamedDecl *BD, |
4563 | const FunctionTypeLoc &BlockLoc, |
4564 | const FunctionProtoTypeLoc &BlockProtoLoc) { |
4565 | Builder.AddResultTypeChunk( |
4566 | GetCompletionTypeString(BlockLoc.getReturnLoc().getType(), Context, |
4567 | Policy, Builder.getAllocator())); |
4568 | |
4569 | AddTypedNameChunk(Context, Policy, BD, Builder); |
4570 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
4571 | |
4572 | if (BlockProtoLoc && BlockProtoLoc.getTypePtr()->isVariadic()) { |
4573 | Builder.AddPlaceholderChunk("..."); |
4574 | } else { |
4575 | for (unsigned I = 0, N = BlockLoc.getNumParams(); I != N; ++I) { |
4576 | if (I) |
4577 | Builder.AddChunk(CodeCompletionString::CK_Comma); |
4578 | |
4579 | // Format the placeholder string. |
4580 | std::string PlaceholderStr = |
4581 | FormatFunctionParameter(Policy, BlockLoc.getParam(I)); |
4582 | |
4583 | if (I == N - 1 && BlockProtoLoc && |
4584 | BlockProtoLoc.getTypePtr()->isVariadic()) |
4585 | PlaceholderStr += ", ..."; |
4586 | |
4587 | // Add the placeholder string. |
4588 | Builder.AddPlaceholderChunk( |
4589 | Builder.getAllocator().CopyString(PlaceholderStr)); |
4590 | } |
4591 | } |
4592 | |
4593 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
4594 | } |
4595 | |
4596 | static void |
4597 | AddObjCProperties(const CodeCompletionContext &CCContext, |
4598 | ObjCContainerDecl *Container, bool AllowCategories, |
4599 | bool AllowNullaryMethods, DeclContext *CurContext, |
4600 | AddedPropertiesSet &AddedProperties, ResultBuilder &Results, |
4601 | bool IsBaseExprStatement = false, |
4602 | bool IsClassProperty = false, bool InOriginalClass = true) { |
4603 | typedef CodeCompletionResult Result; |
4604 | |
4605 | // Retrieve the definition. |
4606 | Container = getContainerDef(Container); |
4607 | |
4608 | // Add properties in this container. |
4609 | const auto AddProperty = [&](const ObjCPropertyDecl *P) { |
4610 | if (!AddedProperties.insert(P->getIdentifier()).second) |
4611 | return; |
4612 | |
4613 | // FIXME: Provide block invocation completion for non-statement |
4614 | // expressions. |
4615 | if (!P->getType().getTypePtr()->isBlockPointerType() || |
4616 | !IsBaseExprStatement) { |
4617 | Result R = Result(P, Results.getBasePriority(P), nullptr); |
4618 | if (!InOriginalClass) |
4619 | setInBaseClass(R); |
4620 | Results.MaybeAddResult(R, CurContext); |
4621 | return; |
4622 | } |
4623 | |
4624 | // Block setter and invocation completion is provided only when we are able |
4625 | // to find the FunctionProtoTypeLoc with parameter names for the block. |
4626 | FunctionTypeLoc BlockLoc; |
4627 | FunctionProtoTypeLoc BlockProtoLoc; |
4628 | findTypeLocationForBlockDecl(P->getTypeSourceInfo(), BlockLoc, |
4629 | BlockProtoLoc); |
4630 | if (!BlockLoc) { |
4631 | Result R = Result(P, Results.getBasePriority(P), nullptr); |
4632 | if (!InOriginalClass) |
4633 | setInBaseClass(R); |
4634 | Results.MaybeAddResult(R, CurContext); |
4635 | return; |
4636 | } |
4637 | |
4638 | // The default completion result for block properties should be the block |
4639 | // invocation completion when the base expression is a statement. |
4640 | CodeCompletionBuilder Builder(Results.getAllocator(), |
4641 | Results.getCodeCompletionTUInfo()); |
4642 | AddObjCBlockCall(Container->getASTContext(), |
4643 | getCompletionPrintingPolicy(Results.getSema()), Builder, P, |
4644 | BlockLoc, BlockProtoLoc); |
4645 | Result R = Result(Builder.TakeString(), P, Results.getBasePriority(P)); |
4646 | if (!InOriginalClass) |
4647 | setInBaseClass(R); |
4648 | Results.MaybeAddResult(R, CurContext); |
4649 | |
4650 | // Provide additional block setter completion iff the base expression is a |
4651 | // statement and the block property is mutable. |
4652 | if (!P->isReadOnly()) { |
4653 | CodeCompletionBuilder Builder(Results.getAllocator(), |
4654 | Results.getCodeCompletionTUInfo()); |
4655 | AddResultTypeChunk(Container->getASTContext(), |
4656 | getCompletionPrintingPolicy(Results.getSema()), P, |
4657 | CCContext.getBaseType(), Builder); |
4658 | Builder.AddTypedTextChunk( |
4659 | Results.getAllocator().CopyString(P->getName())); |
4660 | Builder.AddChunk(CodeCompletionString::CK_Equal); |
4661 | |
4662 | std::string PlaceholderStr = formatBlockPlaceholder( |
4663 | getCompletionPrintingPolicy(Results.getSema()), P, BlockLoc, |
4664 | BlockProtoLoc, /*SuppressBlockName=*/true); |
4665 | // Add the placeholder string. |
4666 | Builder.AddPlaceholderChunk( |
4667 | Builder.getAllocator().CopyString(PlaceholderStr)); |
4668 | |
4669 | // When completing blocks properties that return void the default |
4670 | // property completion result should show up before the setter, |
4671 | // otherwise the setter completion should show up before the default |
4672 | // property completion, as we normally want to use the result of the |
4673 | // call. |
4674 | Result R = |
4675 | Result(Builder.TakeString(), P, |
4676 | Results.getBasePriority(P) + |
4677 | (BlockLoc.getTypePtr()->getReturnType()->isVoidType() |
4678 | ? CCD_BlockPropertySetter |
4679 | : -CCD_BlockPropertySetter)); |
4680 | if (!InOriginalClass) |
4681 | setInBaseClass(R); |
4682 | Results.MaybeAddResult(R, CurContext); |
4683 | } |
4684 | }; |
4685 | |
4686 | if (IsClassProperty) { |
4687 | for (const auto *P : Container->class_properties()) |
4688 | AddProperty(P); |
4689 | } else { |
4690 | for (const auto *P : Container->instance_properties()) |
4691 | AddProperty(P); |
4692 | } |
4693 | |
4694 | // Add nullary methods or implicit class properties |
4695 | if (AllowNullaryMethods) { |
4696 | ASTContext &Context = Container->getASTContext(); |
4697 | PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema()); |
4698 | // Adds a method result |
4699 | const auto AddMethod = [&](const ObjCMethodDecl *M) { |
4700 | IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0); |
4701 | if (!Name) |
4702 | return; |
4703 | if (!AddedProperties.insert(Name).second) |
4704 | return; |
4705 | CodeCompletionBuilder Builder(Results.getAllocator(), |
4706 | Results.getCodeCompletionTUInfo()); |
4707 | AddResultTypeChunk(Context, Policy, M, CCContext.getBaseType(), Builder); |
4708 | Builder.AddTypedTextChunk( |
4709 | Results.getAllocator().CopyString(Name->getName())); |
4710 | Result R = Result(Builder.TakeString(), M, |
4711 | CCP_MemberDeclaration + CCD_MethodAsProperty); |
4712 | if (!InOriginalClass) |
4713 | setInBaseClass(R); |
4714 | Results.MaybeAddResult(R, CurContext); |
4715 | }; |
4716 | |
4717 | if (IsClassProperty) { |
4718 | for (const auto *M : Container->methods()) { |
4719 | // Gather the class method that can be used as implicit property |
4720 | // getters. Methods with arguments or methods that return void aren't |
4721 | // added to the results as they can't be used as a getter. |
4722 | if (!M->getSelector().isUnarySelector() || |
4723 | M->getReturnType()->isVoidType() || M->isInstanceMethod()) |
4724 | continue; |
4725 | AddMethod(M); |
4726 | } |
4727 | } else { |
4728 | for (auto *M : Container->methods()) { |
4729 | if (M->getSelector().isUnarySelector()) |
4730 | AddMethod(M); |
4731 | } |
4732 | } |
4733 | } |
4734 | |
4735 | // Add properties in referenced protocols. |
4736 | if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { |
4737 | for (auto *P : Protocol->protocols()) |
4738 | AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods, |
4739 | CurContext, AddedProperties, Results, |
4740 | IsBaseExprStatement, IsClassProperty, |
4741 | /*InOriginalClass*/ false); |
4742 | } else if (ObjCInterfaceDecl *IFace = |
4743 | dyn_cast<ObjCInterfaceDecl>(Container)) { |
4744 | if (AllowCategories) { |
4745 | // Look through categories. |
4746 | for (auto *Cat : IFace->known_categories()) |
4747 | AddObjCProperties(CCContext, Cat, AllowCategories, AllowNullaryMethods, |
4748 | CurContext, AddedProperties, Results, |
4749 | IsBaseExprStatement, IsClassProperty, |
4750 | InOriginalClass); |
4751 | } |
4752 | |
4753 | // Look through protocols. |
4754 | for (auto *I : IFace->all_referenced_protocols()) |
4755 | AddObjCProperties(CCContext, I, AllowCategories, AllowNullaryMethods, |
4756 | CurContext, AddedProperties, Results, |
4757 | IsBaseExprStatement, IsClassProperty, |
4758 | /*InOriginalClass*/ false); |
4759 | |
4760 | // Look in the superclass. |
4761 | if (IFace->getSuperClass()) |
4762 | AddObjCProperties(CCContext, IFace->getSuperClass(), AllowCategories, |
4763 | AllowNullaryMethods, CurContext, AddedProperties, |
4764 | Results, IsBaseExprStatement, IsClassProperty, |
4765 | /*InOriginalClass*/ false); |
4766 | } else if (const auto *Category = |
4767 | dyn_cast<ObjCCategoryDecl>(Container)) { |
4768 | // Look through protocols. |
4769 | for (auto *P : Category->protocols()) |
4770 | AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods, |
4771 | CurContext, AddedProperties, Results, |
4772 | IsBaseExprStatement, IsClassProperty, |
4773 | /*InOriginalClass*/ false); |
4774 | } |
4775 | } |
4776 | |
4777 | static void AddRecordMembersCompletionResults( |
4778 | Sema &SemaRef, ResultBuilder &Results, Scope *S, QualType BaseType, |
4779 | ExprValueKind BaseKind, RecordDecl *RD, Optional<FixItHint> AccessOpFixIt) { |
4780 | // Indicate that we are performing a member access, and the cv-qualifiers |
4781 | // for the base object type. |
4782 | Results.setObjectTypeQualifiers(BaseType.getQualifiers(), BaseKind); |
4783 | |
4784 | // Access to a C/C++ class, struct, or union. |
4785 | Results.allowNestedNameSpecifiers(); |
4786 | std::vector<FixItHint> FixIts; |
4787 | if (AccessOpFixIt) |
4788 | FixIts.emplace_back(AccessOpFixIt.getValue()); |
4789 | CodeCompletionDeclConsumer Consumer(Results, RD, BaseType, std::move(FixIts)); |
4790 | SemaRef.LookupVisibleDecls(RD, Sema::LookupMemberName, Consumer, |
4791 | SemaRef.CodeCompleter->includeGlobals(), |
4792 | /*IncludeDependentBases=*/true, |
4793 | SemaRef.CodeCompleter->loadExternal()); |
4794 | |
4795 | if (SemaRef.getLangOpts().CPlusPlus) { |
4796 | if (!Results.empty()) { |
4797 | // The "template" keyword can follow "->" or "." in the grammar. |
4798 | // However, we only want to suggest the template keyword if something |
4799 | // is dependent. |
4800 | bool IsDependent = BaseType->isDependentType(); |
4801 | if (!IsDependent) { |
4802 | for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent()) |
4803 | if (DeclContext *Ctx = DepScope->getEntity()) { |
4804 | IsDependent = Ctx->isDependentContext(); |
4805 | break; |
4806 | } |
4807 | } |
4808 | |
4809 | if (IsDependent) |
4810 | Results.AddResult(CodeCompletionResult("template")); |
4811 | } |
4812 | } |
4813 | } |
4814 | |
4815 | // Returns the RecordDecl inside the BaseType, falling back to primary template |
4816 | // in case of specializations. Since we might not have a decl for the |
4817 | // instantiation/specialization yet, e.g. dependent code. |
4818 | static RecordDecl *getAsRecordDecl(const QualType BaseType) { |
4819 | if (auto *RD = BaseType->getAsRecordDecl()) { |
4820 | if (const auto *CTSD = |
4821 | llvm::dyn_cast<ClassTemplateSpecializationDecl>(RD)) { |
4822 | // Template might not be instantiated yet, fall back to primary template |
4823 | // in such cases. |
4824 | if (CTSD->getTemplateSpecializationKind() == TSK_Undeclared) |
4825 | RD = CTSD->getSpecializedTemplate()->getTemplatedDecl(); |
4826 | } |
4827 | return RD; |
4828 | } |
4829 | |
4830 | if (const auto *TST = BaseType->getAs<TemplateSpecializationType>()) { |
4831 | if (const auto *TD = dyn_cast_or_null<ClassTemplateDecl>( |
4832 | TST->getTemplateName().getAsTemplateDecl())) { |
4833 | return TD->getTemplatedDecl(); |
4834 | } |
4835 | } |
4836 | |
4837 | return nullptr; |
4838 | } |
4839 | |
4840 | namespace { |
4841 | // Collects completion-relevant information about a concept-constrainted type T. |
4842 | // In particular, examines the constraint expressions to find members of T. |
4843 | // |
4844 | // The design is very simple: we walk down each constraint looking for |
4845 | // expressions of the form T.foo(). |
4846 | // If we're extra lucky, the return type is specified. |
4847 | // We don't do any clever handling of && or || in constraint expressions, we |
4848 | // take members from both branches. |
4849 | // |
4850 | // For example, given: |
4851 | // template <class T> concept X = requires (T t, string& s) { t.print(s); }; |
4852 | // template <X U> void foo(U u) { u.^ } |
4853 | // We want to suggest the inferred member function 'print(string)'. |
4854 | // We see that u has type U, so X<U> holds. |
4855 | // X<U> requires t.print(s) to be valid, where t has type U (substituted for T). |
4856 | // By looking at the CallExpr we find the signature of print(). |
4857 | // |
4858 | // While we tend to know in advance which kind of members (access via . -> ::) |
4859 | // we want, it's simpler just to gather them all and post-filter. |
4860 | // |
4861 | // FIXME: some of this machinery could be used for non-concept type-parms too, |
4862 | // enabling completion for type parameters based on other uses of that param. |
4863 | // |
4864 | // FIXME: there are other cases where a type can be constrained by a concept, |
4865 | // e.g. inside `if constexpr(ConceptSpecializationExpr) { ... }` |
4866 | class ConceptInfo { |
4867 | public: |
4868 | // Describes a likely member of a type, inferred by concept constraints. |
4869 | // Offered as a code completion for T. T-> and T:: contexts. |
4870 | struct Member { |
4871 | // Always non-null: we only handle members with ordinary identifier names. |
4872 | const IdentifierInfo *Name = nullptr; |
4873 | // Set for functions we've seen called. |
4874 | // We don't have the declared parameter types, only the actual types of |
4875 | // arguments we've seen. These are still valuable, as it's hard to render |
4876 | // a useful function completion with neither parameter types nor names! |
4877 | llvm::Optional<SmallVector<QualType, 1>> ArgTypes; |
4878 | // Whether this is accessed as T.member, T->member, or T::member. |
4879 | enum AccessOperator { |
4880 | Colons, |
4881 | Arrow, |
4882 | Dot, |
4883 | } Operator = Dot; |
4884 | // What's known about the type of a variable or return type of a function. |
4885 | const TypeConstraint *ResultType = nullptr; |
4886 | // FIXME: also track: |
4887 | // - kind of entity (function/variable/type), to expose structured results |
4888 | // - template args kinds/types, as a proxy for template params |
4889 | |
4890 | // For now we simply return these results as "pattern" strings. |
4891 | CodeCompletionString *render(Sema &S, CodeCompletionAllocator &Alloc, |
4892 | CodeCompletionTUInfo &Info) const { |
4893 | CodeCompletionBuilder B(Alloc, Info); |
4894 | // Result type |
4895 | if (ResultType) { |
4896 | std::string AsString; |
4897 | { |
4898 | llvm::raw_string_ostream OS(AsString); |
4899 | QualType ExactType = deduceType(*ResultType); |
4900 | if (!ExactType.isNull()) |
4901 | ExactType.print(OS, getCompletionPrintingPolicy(S)); |
4902 | else |
4903 | ResultType->print(OS, getCompletionPrintingPolicy(S)); |
4904 | } |
4905 | B.AddResultTypeChunk(Alloc.CopyString(AsString)); |
4906 | } |
4907 | // Member name |
4908 | B.AddTypedTextChunk(Alloc.CopyString(Name->getName())); |
4909 | // Function argument list |
4910 | if (ArgTypes) { |
4911 | B.AddChunk(clang::CodeCompletionString::CK_LeftParen); |
4912 | bool First = true; |
4913 | for (QualType Arg : *ArgTypes) { |
4914 | if (First) |
4915 | First = false; |
4916 | else { |
4917 | B.AddChunk(clang::CodeCompletionString::CK_Comma); |
4918 | B.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace); |
4919 | } |
4920 | B.AddPlaceholderChunk(Alloc.CopyString( |
4921 | Arg.getAsString(getCompletionPrintingPolicy(S)))); |
4922 | } |
4923 | B.AddChunk(clang::CodeCompletionString::CK_RightParen); |
4924 | } |
4925 | return B.TakeString(); |
4926 | } |
4927 | }; |
4928 | |
4929 | // BaseType is the type parameter T to infer members from. |
4930 | // T must be accessible within S, as we use it to find the template entity |
4931 | // that T is attached to in order to gather the relevant constraints. |
4932 | ConceptInfo(const TemplateTypeParmType &BaseType, Scope *S) { |
4933 | auto *TemplatedEntity = getTemplatedEntity(BaseType.getDecl(), S); |
4934 | for (const Expr *E : constraintsForTemplatedEntity(TemplatedEntity)) |
4935 | believe(E, &BaseType); |
4936 | } |
4937 | |
4938 | std::vector<Member> members() { |
4939 | std::vector<Member> Results; |
4940 | for (const auto &E : this->Results) |
4941 | Results.push_back(E.second); |
4942 | llvm::sort(Results, [](const Member &L, const Member &R) { |
4943 | return L.Name->getName() < R.Name->getName(); |
4944 | }); |
4945 | return Results; |
4946 | } |
4947 | |
4948 | private: |
4949 | // Infer members of T, given that the expression E (dependent on T) is true. |
4950 | void believe(const Expr *E, const TemplateTypeParmType *T) { |
4951 | if (!E || !T) |
4952 | return; |
4953 | if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(E)) { |
4954 | // If the concept is |
4955 | // template <class A, class B> concept CD = f<A, B>(); |
4956 | // And the concept specialization is |
4957 | // CD<int, T> |
4958 | // Then we're substituting T for B, so we want to make f<A, B>() true |
4959 | // by adding members to B - i.e. believe(f<A, B>(), B); |
4960 | // |
4961 | // For simplicity: |
4962 | // - we don't attempt to substitute int for A |
4963 | // - when T is used in other ways (like CD<T*>) we ignore it |
4964 | ConceptDecl *CD = CSE->getNamedConcept(); |
4965 | TemplateParameterList *Params = CD->getTemplateParameters(); |
4966 | unsigned Index = 0; |
4967 | for (const auto &Arg : CSE->getTemplateArguments()) { |
4968 | if (Index >= Params->size()) |
4969 | break; // Won't happen in valid code. |
4970 | if (isApprox(Arg, T)) { |
4971 | auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Params->getParam(Index)); |
4972 | if (!TTPD) |
4973 | continue; |
4974 | // T was used as an argument, and bound to the parameter TT. |
4975 | auto *TT = cast<TemplateTypeParmType>(TTPD->getTypeForDecl()); |
4976 | // So now we know the constraint as a function of TT is true. |
4977 | believe(CD->getConstraintExpr(), TT); |
4978 | // (concepts themselves have no associated constraints to require) |
4979 | } |
4980 | |
4981 | ++Index; |
4982 | } |
4983 | } else if (auto *BO = dyn_cast<BinaryOperator>(E)) { |
4984 | // For A && B, we can infer members from both branches. |
4985 | // For A || B, the union is still more useful than the intersection. |
4986 | if (BO->getOpcode() == BO_LAnd || BO->getOpcode() == BO_LOr) { |
4987 | believe(BO->getLHS(), T); |
4988 | believe(BO->getRHS(), T); |
4989 | } |
4990 | } else if (auto *RE = dyn_cast<RequiresExpr>(E)) { |
4991 | // A requires(){...} lets us infer members from each requirement. |
4992 | for (const concepts::Requirement *Req : RE->getRequirements()) { |
4993 | if (!Req->isDependent()) |
4994 | continue; // Can't tell us anything about T. |
4995 | // Now Req cannot a substitution-error: those aren't dependent. |
4996 | |
4997 | if (auto *TR = dyn_cast<concepts::TypeRequirement>(Req)) { |
4998 | // Do a full traversal so we get `foo` from `typename T::foo::bar`. |
4999 | QualType AssertedType = TR->getType()->getType(); |
5000 | ValidVisitor(this, T).TraverseType(AssertedType); |
5001 | } else if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) { |
5002 | ValidVisitor Visitor(this, T); |
5003 | // If we have a type constraint on the value of the expression, |
5004 | // AND the whole outer expression describes a member, then we'll |
5005 | // be able to use the constraint to provide the return type. |
5006 | if (ER->getReturnTypeRequirement().isTypeConstraint()) { |
5007 | Visitor.OuterType = |
5008 | ER->getReturnTypeRequirement().getTypeConstraint(); |
5009 | Visitor.OuterExpr = ER->getExpr(); |
5010 | } |
5011 | Visitor.TraverseStmt(ER->getExpr()); |
5012 | } else if (auto *NR = dyn_cast<concepts::NestedRequirement>(Req)) { |
5013 | believe(NR->getConstraintExpr(), T); |
5014 | } |
5015 | } |
5016 | } |
5017 | } |
5018 | |
5019 | // This visitor infers members of T based on traversing expressions/types |
5020 | // that involve T. It is invoked with code known to be valid for T. |
5021 | class ValidVisitor : public RecursiveASTVisitor<ValidVisitor> { |
5022 | ConceptInfo *Outer; |
5023 | const TemplateTypeParmType *T; |
5024 | |
5025 | CallExpr *Caller = nullptr; |
5026 | Expr *Callee = nullptr; |
5027 | |
5028 | public: |
5029 | // If set, OuterExpr is constrained by OuterType. |
5030 | Expr *OuterExpr = nullptr; |
5031 | const TypeConstraint *OuterType = nullptr; |
5032 | |
5033 | ValidVisitor(ConceptInfo *Outer, const TemplateTypeParmType *T) |
5034 | : Outer(Outer), T(T) { |
5035 | assert(T)((void)0); |
5036 | } |
5037 | |
5038 | // In T.foo or T->foo, `foo` is a member function/variable. |
5039 | bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) { |
5040 | const Type *Base = E->getBaseType().getTypePtr(); |
5041 | bool IsArrow = E->isArrow(); |
5042 | if (Base->isPointerType() && IsArrow) { |
5043 | IsArrow = false; |
5044 | Base = Base->getPointeeType().getTypePtr(); |
5045 | } |
5046 | if (isApprox(Base, T)) |
5047 | addValue(E, E->getMember(), IsArrow ? Member::Arrow : Member::Dot); |
5048 | return true; |
5049 | } |
5050 | |
5051 | // In T::foo, `foo` is a static member function/variable. |
5052 | bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { |
5053 | if (E->getQualifier() && isApprox(E->getQualifier()->getAsType(), T)) |
5054 | addValue(E, E->getDeclName(), Member::Colons); |
5055 | return true; |
5056 | } |
5057 | |
5058 | // In T::typename foo, `foo` is a type. |
5059 | bool VisitDependentNameType(DependentNameType *DNT) { |
5060 | const auto *Q = DNT->getQualifier(); |
5061 | if (Q && isApprox(Q->getAsType(), T)) |
5062 | addType(DNT->getIdentifier()); |
5063 | return true; |
5064 | } |
5065 | |
5066 | // In T::foo::bar, `foo` must be a type. |
5067 | // VisitNNS() doesn't exist, and TraverseNNS isn't always called :-( |
5068 | bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) { |
5069 | if (NNSL) { |
5070 | NestedNameSpecifier *NNS = NNSL.getNestedNameSpecifier(); |
5071 | const auto *Q = NNS->getPrefix(); |
5072 | if (Q && isApprox(Q->getAsType(), T)) |
5073 | addType(NNS->getAsIdentifier()); |
5074 | } |
5075 | // FIXME: also handle T::foo<X>::bar |
5076 | return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL); |
5077 | } |
5078 | |
5079 | // FIXME also handle T::foo<X> |
5080 | |
5081 | // Track the innermost caller/callee relationship so we can tell if a |
5082 | // nested expr is being called as a function. |
5083 | bool VisitCallExpr(CallExpr *CE) { |
5084 | Caller = CE; |
5085 | Callee = CE->getCallee(); |
5086 | return true; |
5087 | } |
5088 | |
5089 | private: |
5090 | void addResult(Member &&M) { |
5091 | auto R = Outer->Results.try_emplace(M.Name); |
5092 | Member &O = R.first->second; |
5093 | // Overwrite existing if the new member has more info. |
5094 | // The preference of . vs :: vs -> is fairly arbitrary. |
5095 | if (/*Inserted*/ R.second || |
5096 | std::make_tuple(M.ArgTypes.hasValue(), M.ResultType != nullptr, |
5097 | M.Operator) > std::make_tuple(O.ArgTypes.hasValue(), |
5098 | O.ResultType != nullptr, |
5099 | O.Operator)) |
5100 | O = std::move(M); |
5101 | } |
5102 | |
5103 | void addType(const IdentifierInfo *Name) { |
5104 | if (!Name) |
5105 | return; |
5106 | Member M; |
5107 | M.Name = Name; |
5108 | M.Operator = Member::Colons; |
5109 | addResult(std::move(M)); |
5110 | } |
5111 | |
5112 | void addValue(Expr *E, DeclarationName Name, |
5113 | Member::AccessOperator Operator) { |
5114 | if (!Name.isIdentifier()) |
5115 | return; |
5116 | Member Result; |
5117 | Result.Name = Name.getAsIdentifierInfo(); |
5118 | Result.Operator = Operator; |
5119 | // If this is the callee of an immediately-enclosing CallExpr, then |
5120 | // treat it as a method, otherwise it's a variable. |
5121 | if (Caller != nullptr && Callee == E) { |
5122 | Result.ArgTypes.emplace(); |
5123 | for (const auto *Arg : Caller->arguments()) |
5124 | Result.ArgTypes->push_back(Arg->getType()); |
5125 | if (Caller == OuterExpr) { |
5126 | Result.ResultType = OuterType; |
5127 | } |
5128 | } else { |
5129 | if (E == OuterExpr) |
5130 | Result.ResultType = OuterType; |
5131 | } |
5132 | addResult(std::move(Result)); |
5133 | } |
5134 | }; |
5135 | |
5136 | static bool isApprox(const TemplateArgument &Arg, const Type *T) { |
5137 | return Arg.getKind() == TemplateArgument::Type && |
5138 | isApprox(Arg.getAsType().getTypePtr(), T); |
5139 | } |
5140 | |
5141 | static bool isApprox(const Type *T1, const Type *T2) { |
5142 | return T1 && T2 && |
5143 | T1->getCanonicalTypeUnqualified() == |
5144 | T2->getCanonicalTypeUnqualified(); |
5145 | } |
5146 | |
5147 | // Returns the DeclContext immediately enclosed by the template parameter |
5148 | // scope. For primary templates, this is the templated (e.g.) CXXRecordDecl. |
5149 | // For specializations, this is e.g. ClassTemplatePartialSpecializationDecl. |
5150 | static DeclContext *getTemplatedEntity(const TemplateTypeParmDecl *D, |
5151 | Scope *S) { |
5152 | if (D == nullptr) |
5153 | return nullptr; |
5154 | Scope *Inner = nullptr; |
5155 | while (S) { |
5156 | if (S->isTemplateParamScope() && S->isDeclScope(D)) |
5157 | return Inner ? Inner->getEntity() : nullptr; |
5158 | Inner = S; |
5159 | S = S->getParent(); |
5160 | } |
5161 | return nullptr; |
5162 | } |
5163 | |
5164 | // Gets all the type constraint expressions that might apply to the type |
5165 | // variables associated with DC (as returned by getTemplatedEntity()). |
5166 | static SmallVector<const Expr *, 1> |
5167 | constraintsForTemplatedEntity(DeclContext *DC) { |
5168 | SmallVector<const Expr *, 1> Result; |
5169 | if (DC == nullptr) |
5170 | return Result; |
5171 | // Primary templates can have constraints. |
5172 | if (const auto *TD = cast<Decl>(DC)->getDescribedTemplate()) |
5173 | TD->getAssociatedConstraints(Result); |
5174 | // Partial specializations may have constraints. |
5175 | if (const auto *CTPSD = |
5176 | dyn_cast<ClassTemplatePartialSpecializationDecl>(DC)) |
5177 | CTPSD->getAssociatedConstraints(Result); |
5178 | if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(DC)) |
5179 | VTPSD->getAssociatedConstraints(Result); |
5180 | return Result; |
5181 | } |
5182 | |
5183 | // Attempt to find the unique type satisfying a constraint. |
5184 | // This lets us show e.g. `int` instead of `std::same_as<int>`. |
5185 | static QualType deduceType(const TypeConstraint &T) { |
5186 | // Assume a same_as<T> return type constraint is std::same_as or equivalent. |
5187 | // In this case the return type is T. |
5188 | DeclarationName DN = T.getNamedConcept()->getDeclName(); |
5189 | if (DN.isIdentifier() && DN.getAsIdentifierInfo()->isStr("same_as")) |
5190 | if (const auto *Args = T.getTemplateArgsAsWritten()) |
5191 | if (Args->getNumTemplateArgs() == 1) { |
5192 | const auto &Arg = Args->arguments().front().getArgument(); |
5193 | if (Arg.getKind() == TemplateArgument::Type) |
5194 | return Arg.getAsType(); |
5195 | } |
5196 | return {}; |
5197 | } |
5198 | |
5199 | llvm::DenseMap<const IdentifierInfo *, Member> Results; |
5200 | }; |
5201 | |
5202 | // Returns a type for E that yields acceptable member completions. |
5203 | // In particular, when E->getType() is DependentTy, try to guess a likely type. |
5204 | // We accept some lossiness (like dropping parameters). |
5205 | // We only try to handle common expressions on the LHS of MemberExpr. |
5206 | QualType getApproximateType(const Expr *E) { |
5207 | QualType Unresolved = E->getType(); |
5208 | if (Unresolved.isNull() || |
5209 | !Unresolved->isSpecificBuiltinType(BuiltinType::Dependent)) |
5210 | return Unresolved; |
5211 | E = E->IgnoreParens(); |
5212 | // A call: approximate-resolve callee to a function type, get its return type |
5213 | if (const CallExpr *CE = llvm::dyn_cast<CallExpr>(E)) { |
5214 | QualType Callee = getApproximateType(CE->getCallee()); |
5215 | if (Callee.isNull() || |
5216 | Callee->isSpecificPlaceholderType(BuiltinType::BoundMember)) |
5217 | Callee = Expr::findBoundMemberType(CE->getCallee()); |
5218 | if (Callee.isNull()) |
5219 | return Unresolved; |
5220 | |
5221 | if (const auto *FnTypePtr = Callee->getAs<PointerType>()) { |
5222 | Callee = FnTypePtr->getPointeeType(); |
5223 | } else if (const auto *BPT = Callee->getAs<BlockPointerType>()) { |
5224 | Callee = BPT->getPointeeType(); |
5225 | } |
5226 | if (const FunctionType *FnType = Callee->getAs<FunctionType>()) |
5227 | return FnType->getReturnType().getNonReferenceType(); |
5228 | |
5229 | // Unresolved call: try to guess the return type. |
5230 | if (const auto *OE = llvm::dyn_cast<OverloadExpr>(CE->getCallee())) { |
5231 | // If all candidates have the same approximate return type, use it. |
5232 | // Discard references and const to allow more to be "the same". |
5233 | // (In particular, if there's one candidate + ADL, resolve it). |
5234 | const Type *Common = nullptr; |
5235 | for (const auto *D : OE->decls()) { |
5236 | QualType ReturnType; |
5237 | if (const auto *FD = llvm::dyn_cast<FunctionDecl>(D)) |
5238 | ReturnType = FD->getReturnType(); |
5239 | else if (const auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(D)) |
5240 | ReturnType = FTD->getTemplatedDecl()->getReturnType(); |
5241 | if (ReturnType.isNull()) |
5242 | continue; |
5243 | const Type *Candidate = |
5244 | ReturnType.getNonReferenceType().getCanonicalType().getTypePtr(); |
5245 | if (Common && Common != Candidate) |
5246 | return Unresolved; // Multiple candidates. |
5247 | Common = Candidate; |
5248 | } |
5249 | if (Common != nullptr) |
5250 | return QualType(Common, 0); |
5251 | } |
5252 | } |
5253 | // A dependent member: approximate-resolve the base, then lookup. |
5254 | if (const auto *CDSME = llvm::dyn_cast<CXXDependentScopeMemberExpr>(E)) { |
5255 | QualType Base = CDSME->isImplicitAccess() |
5256 | ? CDSME->getBaseType() |
5257 | : getApproximateType(CDSME->getBase()); |
5258 | if (CDSME->isArrow() && !Base.isNull()) |
5259 | Base = Base->getPointeeType(); // could handle unique_ptr etc here? |
5260 | RecordDecl *RD = Base.isNull() ? nullptr : getAsRecordDecl(Base); |
5261 | if (RD && RD->isCompleteDefinition()) { |
5262 | for (const auto *Member : RD->lookup(CDSME->getMember())) |
5263 | if (const ValueDecl *VD = llvm::dyn_cast<ValueDecl>(Member)) |
5264 | return VD->getType().getNonReferenceType(); |
5265 | } |
5266 | } |
5267 | return Unresolved; |
5268 | } |
5269 | |
5270 | // If \p Base is ParenListExpr, assume a chain of comma operators and pick the |
5271 | // last expr. We expect other ParenListExprs to be resolved to e.g. constructor |
5272 | // calls before here. (So the ParenListExpr should be nonempty, but check just |
5273 | // in case) |
5274 | Expr *unwrapParenList(Expr *Base) { |
5275 | if (auto *PLE = llvm::dyn_cast_or_null<ParenListExpr>(Base)) { |
5276 | if (PLE->getNumExprs() == 0) |
5277 | return nullptr; |
5278 | Base = PLE->getExpr(PLE->getNumExprs() - 1); |
5279 | } |
5280 | return Base; |
5281 | } |
5282 | |
5283 | } // namespace |
5284 | |
5285 | void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, |
5286 | Expr *OtherOpBase, |
5287 | SourceLocation OpLoc, bool IsArrow, |
5288 | bool IsBaseExprStatement, |
5289 | QualType PreferredType) { |
5290 | Base = unwrapParenList(Base); |
5291 | OtherOpBase = unwrapParenList(OtherOpBase); |
5292 | if (!Base || !CodeCompleter) |
5293 | return; |
5294 | |
5295 | ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow); |
5296 | if (ConvertedBase.isInvalid()) |
5297 | return; |
5298 | QualType ConvertedBaseType = getApproximateType(ConvertedBase.get()); |
5299 | |
5300 | enum CodeCompletionContext::Kind contextKind; |
5301 | |
5302 | if (IsArrow) { |
5303 | if (const auto *Ptr = ConvertedBaseType->getAs<PointerType>()) |
5304 | ConvertedBaseType = Ptr->getPointeeType(); |
5305 | } |
5306 | |
5307 | if (IsArrow) { |
5308 | contextKind = CodeCompletionContext::CCC_ArrowMemberAccess; |
5309 | } else { |
5310 | if (ConvertedBaseType->isObjCObjectPointerType() || |
5311 | ConvertedBaseType->isObjCObjectOrInterfaceType()) { |
5312 | contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess; |
5313 | } else { |
5314 | contextKind = CodeCompletionContext::CCC_DotMemberAccess; |
5315 | } |
5316 | } |
5317 | |
5318 | CodeCompletionContext CCContext(contextKind, ConvertedBaseType); |
5319 | CCContext.setPreferredType(PreferredType); |
5320 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
5321 | CodeCompleter->getCodeCompletionTUInfo(), CCContext, |
5322 | &ResultBuilder::IsMember); |
5323 | |
5324 | auto DoCompletion = [&](Expr *Base, bool IsArrow, |
5325 | Optional<FixItHint> AccessOpFixIt) -> bool { |
5326 | if (!Base) |
5327 | return false; |
5328 | |
5329 | ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow); |
5330 | if (ConvertedBase.isInvalid()) |
5331 | return false; |
5332 | Base = ConvertedBase.get(); |
5333 | |
5334 | QualType BaseType = getApproximateType(Base); |
5335 | if (BaseType.isNull()) |
5336 | return false; |
5337 | ExprValueKind BaseKind = Base->getValueKind(); |
5338 | |
5339 | if (IsArrow) { |
5340 | if (const PointerType *Ptr = BaseType->getAs<PointerType>()) { |
5341 | BaseType = Ptr->getPointeeType(); |
5342 | BaseKind = VK_LValue; |
5343 | } else if (BaseType->isObjCObjectPointerType() || |
5344 | BaseType->isTemplateTypeParmType()) { |
5345 | // Both cases (dot/arrow) handled below. |
5346 | } else { |
5347 | return false; |
5348 | } |
5349 | } |
5350 | |
5351 | if (RecordDecl *RD = getAsRecordDecl(BaseType)) { |
5352 | AddRecordMembersCompletionResults(*this, Results, S, BaseType, BaseKind, |
5353 | RD, std::move(AccessOpFixIt)); |
5354 | } else if (const auto *TTPT = |
5355 | dyn_cast<TemplateTypeParmType>(BaseType.getTypePtr())) { |
5356 | auto Operator = |
5357 | IsArrow ? ConceptInfo::Member::Arrow : ConceptInfo::Member::Dot; |
5358 | for (const auto &R : ConceptInfo(*TTPT, S).members()) { |
5359 | if (R.Operator != Operator) |
5360 | continue; |
5361 | CodeCompletionResult Result( |
5362 | R.render(*this, CodeCompleter->getAllocator(), |
5363 | CodeCompleter->getCodeCompletionTUInfo())); |
5364 | if (AccessOpFixIt) |
5365 | Result.FixIts.push_back(*AccessOpFixIt); |
5366 | Results.AddResult(std::move(Result)); |
5367 | } |
5368 | } else if (!IsArrow && BaseType->isObjCObjectPointerType()) { |
5369 | // Objective-C property reference. Bail if we're performing fix-it code |
5370 | // completion since Objective-C properties are normally backed by ivars, |
5371 | // most Objective-C fix-its here would have little value. |
5372 | if (AccessOpFixIt.hasValue()) { |
5373 | return false; |
5374 | } |
5375 | AddedPropertiesSet AddedProperties; |
5376 | |
5377 | if (const ObjCObjectPointerType *ObjCPtr = |
5378 | BaseType->getAsObjCInterfacePointerType()) { |
5379 | // Add property results based on our interface. |
5380 | assert(ObjCPtr && "Non-NULL pointer guaranteed above!")((void)0); |
5381 | AddObjCProperties(CCContext, ObjCPtr->getInterfaceDecl(), true, |
5382 | /*AllowNullaryMethods=*/true, CurContext, |
5383 | AddedProperties, Results, IsBaseExprStatement); |
5384 | } |
5385 | |
5386 | // Add properties from the protocols in a qualified interface. |
5387 | for (auto *I : BaseType->castAs<ObjCObjectPointerType>()->quals()) |
5388 | AddObjCProperties(CCContext, I, true, /*AllowNullaryMethods=*/true, |
5389 | CurContext, AddedProperties, Results, |
5390 | IsBaseExprStatement, /*IsClassProperty*/ false, |
5391 | /*InOriginalClass*/ false); |
5392 | } else if ((IsArrow && BaseType->isObjCObjectPointerType()) || |
5393 | (!IsArrow && BaseType->isObjCObjectType())) { |
5394 | // Objective-C instance variable access. Bail if we're performing fix-it |
5395 | // code completion since Objective-C properties are normally backed by |
5396 | // ivars, most Objective-C fix-its here would have little value. |
5397 | if (AccessOpFixIt.hasValue()) { |
5398 | return false; |
5399 | } |
5400 | ObjCInterfaceDecl *Class = nullptr; |
5401 | if (const ObjCObjectPointerType *ObjCPtr = |
5402 | BaseType->getAs<ObjCObjectPointerType>()) |
5403 | Class = ObjCPtr->getInterfaceDecl(); |
5404 | else |
5405 | Class = BaseType->castAs<ObjCObjectType>()->getInterface(); |
5406 | |
5407 | // Add all ivars from this class and its superclasses. |
5408 | if (Class) { |
5409 | CodeCompletionDeclConsumer Consumer(Results, Class, BaseType); |
5410 | Results.setFilter(&ResultBuilder::IsObjCIvar); |
5411 | LookupVisibleDecls( |
5412 | Class, LookupMemberName, Consumer, CodeCompleter->includeGlobals(), |
5413 | /*IncludeDependentBases=*/false, CodeCompleter->loadExternal()); |
5414 | } |
5415 | } |
5416 | |
5417 | // FIXME: How do we cope with isa? |
5418 | return true; |
5419 | }; |
5420 | |
5421 | Results.EnterNewScope(); |
5422 | |
5423 | bool CompletionSucceded = DoCompletion(Base, IsArrow, None); |
5424 | if (CodeCompleter->includeFixIts()) { |
5425 | const CharSourceRange OpRange = |
5426 | CharSourceRange::getTokenRange(OpLoc, OpLoc); |
5427 | CompletionSucceded |= DoCompletion( |
5428 | OtherOpBase, !IsArrow, |
5429 | FixItHint::CreateReplacement(OpRange, IsArrow ? "." : "->")); |
5430 | } |
5431 | |
5432 | Results.ExitScope(); |
5433 | |
5434 | if (!CompletionSucceded) |
5435 | return; |
5436 | |
5437 | // Hand off the results found for code completion. |
5438 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
5439 | Results.data(), Results.size()); |
5440 | } |
5441 | |
5442 | void Sema::CodeCompleteObjCClassPropertyRefExpr(Scope *S, |
5443 | IdentifierInfo &ClassName, |
5444 | SourceLocation ClassNameLoc, |
5445 | bool IsBaseExprStatement) { |
5446 | IdentifierInfo *ClassNamePtr = &ClassName; |
5447 | ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(ClassNamePtr, ClassNameLoc); |
5448 | if (!IFace) |
5449 | return; |
5450 | CodeCompletionContext CCContext( |
5451 | CodeCompletionContext::CCC_ObjCPropertyAccess); |
5452 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
5453 | CodeCompleter->getCodeCompletionTUInfo(), CCContext, |
5454 | &ResultBuilder::IsMember); |
5455 | Results.EnterNewScope(); |
5456 | AddedPropertiesSet AddedProperties; |
5457 | AddObjCProperties(CCContext, IFace, true, |
5458 | /*AllowNullaryMethods=*/true, CurContext, AddedProperties, |
5459 | Results, IsBaseExprStatement, |
5460 | /*IsClassProperty=*/true); |
5461 | Results.ExitScope(); |
5462 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
5463 | Results.data(), Results.size()); |
5464 | } |
5465 | |
5466 | void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { |
5467 | if (!CodeCompleter) |
5468 | return; |
5469 | |
5470 | ResultBuilder::LookupFilter Filter = nullptr; |
5471 | enum CodeCompletionContext::Kind ContextKind = |
5472 | CodeCompletionContext::CCC_Other; |
5473 | switch ((DeclSpec::TST)TagSpec) { |
5474 | case DeclSpec::TST_enum: |
5475 | Filter = &ResultBuilder::IsEnum; |
5476 | ContextKind = CodeCompletionContext::CCC_EnumTag; |
5477 | break; |
5478 | |
5479 | case DeclSpec::TST_union: |
5480 | Filter = &ResultBuilder::IsUnion; |
5481 | ContextKind = CodeCompletionContext::CCC_UnionTag; |
5482 | break; |
5483 | |
5484 | case DeclSpec::TST_struct: |
5485 | case DeclSpec::TST_class: |
5486 | case DeclSpec::TST_interface: |
5487 | Filter = &ResultBuilder::IsClassOrStruct; |
5488 | ContextKind = CodeCompletionContext::CCC_ClassOrStructTag; |
5489 | break; |
5490 | |
5491 | default: |
5492 | llvm_unreachable("Unknown type specifier kind in CodeCompleteTag")__builtin_unreachable(); |
5493 | } |
5494 | |
5495 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
5496 | CodeCompleter->getCodeCompletionTUInfo(), ContextKind); |
5497 | CodeCompletionDeclConsumer Consumer(Results, CurContext); |
5498 | |
5499 | // First pass: look for tags. |
5500 | Results.setFilter(Filter); |
5501 | LookupVisibleDecls(S, LookupTagName, Consumer, |
5502 | CodeCompleter->includeGlobals(), |
5503 | CodeCompleter->loadExternal()); |
5504 | |
5505 | if (CodeCompleter->includeGlobals()) { |
5506 | // Second pass: look for nested name specifiers. |
5507 | Results.setFilter(&ResultBuilder::IsNestedNameSpecifier); |
5508 | LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer, |
5509 | CodeCompleter->includeGlobals(), |
5510 | CodeCompleter->loadExternal()); |
5511 | } |
5512 | |
5513 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
5514 | Results.data(), Results.size()); |
5515 | } |
5516 | |
5517 | static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results, |
5518 | const LangOptions &LangOpts) { |
5519 | if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const)) |
5520 | Results.AddResult("const"); |
5521 | if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile)) |
5522 | Results.AddResult("volatile"); |
5523 | if (LangOpts.C99 && !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict)) |
5524 | Results.AddResult("restrict"); |
5525 | if (LangOpts.C11 && !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic)) |
5526 | Results.AddResult("_Atomic"); |
5527 | if (LangOpts.MSVCCompat && !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned)) |
5528 | Results.AddResult("__unaligned"); |
5529 | } |
5530 | |
5531 | void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) { |
5532 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
5533 | CodeCompleter->getCodeCompletionTUInfo(), |
5534 | CodeCompletionContext::CCC_TypeQualifiers); |
5535 | Results.EnterNewScope(); |
5536 | AddTypeQualifierResults(DS, Results, LangOpts); |
5537 | Results.ExitScope(); |
5538 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
5539 | Results.data(), Results.size()); |
5540 | } |
5541 | |
5542 | void Sema::CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, |
5543 | const VirtSpecifiers *VS) { |
5544 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
5545 | CodeCompleter->getCodeCompletionTUInfo(), |
5546 | CodeCompletionContext::CCC_TypeQualifiers); |
5547 | Results.EnterNewScope(); |
5548 | AddTypeQualifierResults(DS, Results, LangOpts); |
5549 | if (LangOpts.CPlusPlus11) { |
5550 | Results.AddResult("noexcept"); |
5551 | if (D.getContext() == DeclaratorContext::Member && !D.isCtorOrDtor() && |
5552 | !D.isStaticMember()) { |
5553 | if (!VS || !VS->isFinalSpecified()) |
5554 | Results.AddResult("final"); |
5555 | if (!VS || !VS->isOverrideSpecified()) |
5556 | Results.AddResult("override"); |
5557 | } |
5558 | } |
5559 | Results.ExitScope(); |
5560 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
5561 | Results.data(), Results.size()); |
5562 | } |
5563 | |
5564 | void Sema::CodeCompleteBracketDeclarator(Scope *S) { |
5565 | CodeCompleteExpression(S, QualType(getASTContext().getSizeType())); |
5566 | } |
5567 | |
5568 | void Sema::CodeCompleteCase(Scope *S) { |
5569 | if (getCurFunction()->SwitchStack.empty() || !CodeCompleter) |
5570 | return; |
5571 | |
5572 | SwitchStmt *Switch = getCurFunction()->SwitchStack.back().getPointer(); |
5573 | // Condition expression might be invalid, do not continue in this case. |
5574 | if (!Switch->getCond()) |
5575 | return; |
5576 | QualType type = Switch->getCond()->IgnoreImplicit()->getType(); |
5577 | if (!type->isEnumeralType()) { |
5578 | CodeCompleteExpressionData Data(type); |
5579 | Data.IntegralConstantExpression = true; |
5580 | CodeCompleteExpression(S, Data); |
5581 | return; |
5582 | } |
5583 | |
5584 | // Code-complete the cases of a switch statement over an enumeration type |
5585 | // by providing the list of |
5586 | EnumDecl *Enum = type->castAs<EnumType>()->getDecl(); |
5587 | if (EnumDecl *Def = Enum->getDefinition()) |
5588 | Enum = Def; |
5589 | |
5590 | // Determine which enumerators we have already seen in the switch statement. |
5591 | // FIXME: Ideally, we would also be able to look *past* the code-completion |
5592 | // token, in case we are code-completing in the middle of the switch and not |
5593 | // at the end. However, we aren't able to do so at the moment. |
5594 | CoveredEnumerators Enumerators; |
5595 | for (SwitchCase *SC = Switch->getSwitchCaseList(); SC; |
5596 | SC = SC->getNextSwitchCase()) { |
5597 | CaseStmt *Case = dyn_cast<CaseStmt>(SC); |
5598 | if (!Case) |
5599 | continue; |
5600 | |
5601 | Expr *CaseVal = Case->getLHS()->IgnoreParenCasts(); |
5602 | if (auto *DRE = dyn_cast<DeclRefExpr>(CaseVal)) |
5603 | if (auto *Enumerator = |
5604 | dyn_cast<EnumConstantDecl>(DRE->getDecl())) { |
5605 | // We look into the AST of the case statement to determine which |
5606 | // enumerator was named. Alternatively, we could compute the value of |
5607 | // the integral constant expression, then compare it against the |
5608 | // values of each enumerator. However, value-based approach would not |
5609 | // work as well with C++ templates where enumerators declared within a |
5610 | // template are type- and value-dependent. |
5611 | Enumerators.Seen.insert(Enumerator); |
5612 | |
5613 | // If this is a qualified-id, keep track of the nested-name-specifier |
5614 | // so that we can reproduce it as part of code completion, e.g., |
5615 | // |
5616 | // switch (TagD.getKind()) { |
5617 | // case TagDecl::TK_enum: |
5618 | // break; |
5619 | // case XXX |
5620 | // |
5621 | // At the XXX, our completions are TagDecl::TK_union, |
5622 | // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union, |
5623 | // TK_struct, and TK_class. |
5624 | Enumerators.SuggestedQualifier = DRE->getQualifier(); |
5625 | } |
5626 | } |
5627 | |
5628 | // Add any enumerators that have not yet been mentioned. |
5629 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
5630 | CodeCompleter->getCodeCompletionTUInfo(), |
5631 | CodeCompletionContext::CCC_Expression); |
5632 | AddEnumerators(Results, Context, Enum, CurContext, Enumerators); |
5633 | |
5634 | if (CodeCompleter->includeMacros()) { |
5635 | AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false); |
5636 | } |
5637 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
5638 | Results.data(), Results.size()); |
5639 | } |
5640 | |
5641 | static bool anyNullArguments(ArrayRef<Expr *> Args) { |
5642 | if (Args.size() && !Args.data()) |
5643 | return true; |
5644 | |
5645 | for (unsigned I = 0; I != Args.size(); ++I) |
5646 | if (!Args[I]) |
5647 | return true; |
5648 | |
5649 | return false; |
5650 | } |
5651 | |
5652 | typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate; |
5653 | |
5654 | static void mergeCandidatesWithResults( |
5655 | Sema &SemaRef, SmallVectorImpl<ResultCandidate> &Results, |
5656 | OverloadCandidateSet &CandidateSet, SourceLocation Loc, size_t ArgSize) { |
5657 | // Sort the overload candidate set by placing the best overloads first. |
5658 | llvm::stable_sort(CandidateSet, [&](const OverloadCandidate &X, |
5659 | const OverloadCandidate &Y) { |
5660 | return isBetterOverloadCandidate(SemaRef, X, Y, Loc, |
5661 | CandidateSet.getKind()); |
5662 | }); |
5663 | |
5664 | // Add the remaining viable overload candidates as code-completion results. |
5665 | for (OverloadCandidate &Candidate : CandidateSet) { |
5666 | if (Candidate.Function) { |
5667 | if (Candidate.Function->isDeleted()) |
5668 | continue; |
5669 | if (!Candidate.Function->isVariadic() && |
5670 | Candidate.Function->getNumParams() <= ArgSize && |
5671 | // Having zero args is annoying, normally we don't surface a function |
5672 | // with 2 params, if you already have 2 params, because you are |
5673 | // inserting the 3rd now. But with zero, it helps the user to figure |
5674 | // out there are no overloads that take any arguments. Hence we are |
5675 | // keeping the overload. |
5676 | ArgSize > 0) |
5677 | continue; |
5678 | } |
5679 | if (Candidate.Viable) |
5680 | Results.push_back(ResultCandidate(Candidate.Function)); |
5681 | } |
5682 | } |
5683 | |
5684 | /// Get the type of the Nth parameter from a given set of overload |
5685 | /// candidates. |
5686 | static QualType getParamType(Sema &SemaRef, |
5687 | ArrayRef<ResultCandidate> Candidates, unsigned N) { |
5688 | |
5689 | // Given the overloads 'Candidates' for a function call matching all arguments |
5690 | // up to N, return the type of the Nth parameter if it is the same for all |
5691 | // overload candidates. |
5692 | QualType ParamType; |
5693 | for (auto &Candidate : Candidates) { |
5694 | if (const auto *FType = Candidate.getFunctionType()) |
5695 | if (const auto *Proto = dyn_cast<FunctionProtoType>(FType)) |
5696 | if (N < Proto->getNumParams()) { |
5697 | if (ParamType.isNull()) |
5698 | ParamType = Proto->getParamType(N); |
5699 | else if (!SemaRef.Context.hasSameUnqualifiedType( |
5700 | ParamType.getNonReferenceType(), |
5701 | Proto->getParamType(N).getNonReferenceType())) |
5702 | // Otherwise return a default-constructed QualType. |
5703 | return QualType(); |
5704 | } |
5705 | } |
5706 | |
5707 | return ParamType; |
5708 | } |
5709 | |
5710 | static QualType |
5711 | ProduceSignatureHelp(Sema &SemaRef, Scope *S, |
5712 | MutableArrayRef<ResultCandidate> Candidates, |
5713 | unsigned CurrentArg, SourceLocation OpenParLoc) { |
5714 | if (Candidates.empty()) |
5715 | return QualType(); |
5716 | if (SemaRef.getPreprocessor().isCodeCompletionReached()) |
5717 | SemaRef.CodeCompleter->ProcessOverloadCandidates( |
5718 | SemaRef, CurrentArg, Candidates.data(), Candidates.size(), OpenParLoc); |
5719 | return getParamType(SemaRef, Candidates, CurrentArg); |
5720 | } |
5721 | |
5722 | QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, |
5723 | ArrayRef<Expr *> Args, |
5724 | SourceLocation OpenParLoc) { |
5725 | Fn = unwrapParenList(Fn); |
5726 | if (!CodeCompleter || !Fn) |
5727 | return QualType(); |
5728 | |
5729 | // FIXME: Provide support for variadic template functions. |
5730 | // Ignore type-dependent call expressions entirely. |
5731 | if (Fn->isTypeDependent() || anyNullArguments(Args)) |
5732 | return QualType(); |
5733 | // In presence of dependent args we surface all possible signatures using the |
5734 | // non-dependent args in the prefix. Afterwards we do a post filtering to make |
5735 | // sure provided candidates satisfy parameter count restrictions. |
5736 | auto ArgsWithoutDependentTypes = |
5737 | Args.take_while([](Expr *Arg) { return !Arg->isTypeDependent(); }); |
5738 | |
5739 | SmallVector<ResultCandidate, 8> Results; |
5740 | |
5741 | Expr *NakedFn = Fn->IgnoreParenCasts(); |
5742 | // Build an overload candidate set based on the functions we find. |
5743 | SourceLocation Loc = Fn->getExprLoc(); |
5744 | OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); |
5745 | |
5746 | if (auto ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn)) { |
5747 | AddOverloadedCallCandidates(ULE, ArgsWithoutDependentTypes, CandidateSet, |
5748 | /*PartialOverloading=*/true); |
5749 | } else if (auto UME = dyn_cast<UnresolvedMemberExpr>(NakedFn)) { |
5750 | TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; |
5751 | if (UME->hasExplicitTemplateArgs()) { |
5752 | UME->copyTemplateArgumentsInto(TemplateArgsBuffer); |
5753 | TemplateArgs = &TemplateArgsBuffer; |
5754 | } |
5755 | |
5756 | // Add the base as first argument (use a nullptr if the base is implicit). |
5757 | SmallVector<Expr *, 12> ArgExprs( |
5758 | 1, UME->isImplicitAccess() ? nullptr : UME->getBase()); |
5759 | ArgExprs.append(ArgsWithoutDependentTypes.begin(), |
5760 | ArgsWithoutDependentTypes.end()); |
5761 | UnresolvedSet<8> Decls; |
5762 | Decls.append(UME->decls_begin(), UME->decls_end()); |
5763 | const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase(); |
5764 | AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs, |
5765 | /*SuppressUserConversions=*/false, |
5766 | /*PartialOverloading=*/true, FirstArgumentIsBase); |
5767 | } else { |
5768 | FunctionDecl *FD = nullptr; |
5769 | if (auto *MCE = dyn_cast<MemberExpr>(NakedFn)) |
5770 | FD = dyn_cast<FunctionDecl>(MCE->getMemberDecl()); |
5771 | else if (auto *DRE = dyn_cast<DeclRefExpr>(NakedFn)) |
5772 | FD = dyn_cast<FunctionDecl>(DRE->getDecl()); |
5773 | if (FD) { // We check whether it's a resolved function declaration. |
5774 | if (!getLangOpts().CPlusPlus || |
5775 | !FD->getType()->getAs<FunctionProtoType>()) |
5776 | Results.push_back(ResultCandidate(FD)); |
5777 | else |
5778 | AddOverloadCandidate(FD, DeclAccessPair::make(FD, FD->getAccess()), |
5779 | ArgsWithoutDependentTypes, CandidateSet, |
5780 | /*SuppressUserConversions=*/false, |
5781 | /*PartialOverloading=*/true); |
5782 | |
5783 | } else if (auto DC = NakedFn->getType()->getAsCXXRecordDecl()) { |
5784 | // If expression's type is CXXRecordDecl, it may overload the function |
5785 | // call operator, so we check if it does and add them as candidates. |
5786 | // A complete type is needed to lookup for member function call operators. |
5787 | if (isCompleteType(Loc, NakedFn->getType())) { |
5788 | DeclarationName OpName = |
5789 | Context.DeclarationNames.getCXXOperatorName(OO_Call); |
5790 | LookupResult R(*this, OpName, Loc, LookupOrdinaryName); |
5791 | LookupQualifiedName(R, DC); |
5792 | R.suppressDiagnostics(); |
5793 | SmallVector<Expr *, 12> ArgExprs(1, NakedFn); |
5794 | ArgExprs.append(ArgsWithoutDependentTypes.begin(), |
5795 | ArgsWithoutDependentTypes.end()); |
5796 | AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs, CandidateSet, |
5797 | /*ExplicitArgs=*/nullptr, |
5798 | /*SuppressUserConversions=*/false, |
5799 | /*PartialOverloading=*/true); |
5800 | } |
5801 | } else { |
5802 | // Lastly we check whether expression's type is function pointer or |
5803 | // function. |
5804 | QualType T = NakedFn->getType(); |
5805 | if (!T->getPointeeType().isNull()) |
5806 | T = T->getPointeeType(); |
5807 | |
5808 | if (auto FP = T->getAs<FunctionProtoType>()) { |
5809 | if (!TooManyArguments(FP->getNumParams(), |
5810 | ArgsWithoutDependentTypes.size(), |
5811 | /*PartialOverloading=*/true) || |
5812 | FP->isVariadic()) |
5813 | Results.push_back(ResultCandidate(FP)); |
5814 | } else if (auto FT = T->getAs<FunctionType>()) |
5815 | // No prototype and declaration, it may be a K & R style function. |
5816 | Results.push_back(ResultCandidate(FT)); |
5817 | } |
5818 | } |
5819 | mergeCandidatesWithResults(*this, Results, CandidateSet, Loc, Args.size()); |
5820 | QualType ParamType = |
5821 | ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc); |
5822 | return !CandidateSet.empty() ? ParamType : QualType(); |
5823 | } |
5824 | |
5825 | QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type, |
5826 | SourceLocation Loc, |
5827 | ArrayRef<Expr *> Args, |
5828 | SourceLocation OpenParLoc) { |
5829 | if (!CodeCompleter) |
5830 | return QualType(); |
5831 | |
5832 | // A complete type is needed to lookup for constructors. |
5833 | CXXRecordDecl *RD = |
5834 | isCompleteType(Loc, Type) ? Type->getAsCXXRecordDecl() : nullptr; |
5835 | if (!RD) |
5836 | return Type; |
5837 | |
5838 | // FIXME: Provide support for member initializers. |
5839 | // FIXME: Provide support for variadic template constructors. |
5840 | |
5841 | OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); |
5842 | |
5843 | for (NamedDecl *C : LookupConstructors(RD)) { |
5844 | if (auto *FD = dyn_cast<FunctionDecl>(C)) { |
5845 | AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), Args, |
5846 | CandidateSet, |
5847 | /*SuppressUserConversions=*/false, |
5848 | /*PartialOverloading=*/true, |
5849 | /*AllowExplicit*/ true); |
5850 | } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(C)) { |
5851 | AddTemplateOverloadCandidate( |
5852 | FTD, DeclAccessPair::make(FTD, C->getAccess()), |
5853 | /*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet, |
5854 | /*SuppressUserConversions=*/false, |
5855 | /*PartialOverloading=*/true); |
5856 | } |
5857 | } |
5858 | |
5859 | SmallVector<ResultCandidate, 8> Results; |
5860 | mergeCandidatesWithResults(*this, Results, CandidateSet, Loc, Args.size()); |
5861 | return ProduceSignatureHelp(*this, S, Results, Args.size(), OpenParLoc); |
5862 | } |
5863 | |
5864 | QualType Sema::ProduceCtorInitMemberSignatureHelp( |
5865 | Scope *S, Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy, |
5866 | ArrayRef<Expr *> ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc) { |
5867 | if (!CodeCompleter) |
5868 | return QualType(); |
5869 | |
5870 | CXXConstructorDecl *Constructor = |
5871 | dyn_cast<CXXConstructorDecl>(ConstructorDecl); |
5872 | if (!Constructor) |
5873 | return QualType(); |
5874 | // FIXME: Add support for Base class constructors as well. |
5875 | if (ValueDecl *MemberDecl = tryLookupCtorInitMemberDecl( |
5876 | Constructor->getParent(), SS, TemplateTypeTy, II)) |
5877 | return ProduceConstructorSignatureHelp(getCurScope(), MemberDecl->getType(), |
5878 | MemberDecl->getLocation(), ArgExprs, |
5879 | OpenParLoc); |
5880 | return QualType(); |
5881 | } |
5882 | |
5883 | static QualType getDesignatedType(QualType BaseType, const Designation &Desig) { |
5884 | for (unsigned I = 0; I < Desig.getNumDesignators(); ++I) { |
5885 | if (BaseType.isNull()) |
5886 | break; |
5887 | QualType NextType; |
5888 | const auto &D = Desig.getDesignator(I); |
5889 | if (D.isArrayDesignator() || D.isArrayRangeDesignator()) { |
5890 | if (BaseType->isArrayType()) |
5891 | NextType = BaseType->getAsArrayTypeUnsafe()->getElementType(); |
5892 | } else { |
5893 | assert(D.isFieldDesignator())((void)0); |
5894 | auto *RD = getAsRecordDecl(BaseType); |
5895 | if (RD && RD->isCompleteDefinition()) { |
5896 | for (const auto *Member : RD->lookup(D.getField())) |
5897 | if (const FieldDecl *FD = llvm::dyn_cast<FieldDecl>(Member)) { |
5898 | NextType = FD->getType(); |
5899 | break; |
5900 | } |
5901 | } |
5902 | } |
5903 | BaseType = NextType; |
5904 | } |
5905 | return BaseType; |
5906 | } |
5907 | |
5908 | void Sema::CodeCompleteDesignator(QualType BaseType, |
5909 | llvm::ArrayRef<Expr *> InitExprs, |
5910 | const Designation &D) { |
5911 | BaseType = getDesignatedType(BaseType, D); |
5912 | if (BaseType.isNull()) |
5913 | return; |
5914 | const auto *RD = getAsRecordDecl(BaseType); |
5915 | if (!RD || RD->fields().empty()) |
5916 | return; |
5917 | |
5918 | CodeCompletionContext CCC(CodeCompletionContext::CCC_DotMemberAccess, |
5919 | BaseType); |
5920 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
5921 | CodeCompleter->getCodeCompletionTUInfo(), CCC); |
5922 | |
5923 | Results.EnterNewScope(); |
5924 | for (const auto *FD : RD->fields()) { |
5925 | // FIXME: Make use of previous designators to mark any fields before those |
5926 | // inaccessible, and also compute the next initializer priority. |
5927 | ResultBuilder::Result Result(FD, Results.getBasePriority(FD)); |
5928 | Results.AddResult(Result, CurContext, /*Hiding=*/nullptr); |
5929 | } |
5930 | Results.ExitScope(); |
5931 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
5932 | Results.data(), Results.size()); |
5933 | } |
5934 | |
5935 | void Sema::CodeCompleteInitializer(Scope *S, Decl *D) { |
5936 | ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D); |
5937 | if (!VD) { |
5938 | CodeCompleteOrdinaryName(S, PCC_Expression); |
5939 | return; |
5940 | } |
5941 | |
5942 | CodeCompleteExpressionData Data; |
5943 | Data.PreferredType = VD->getType(); |
5944 | // Ignore VD to avoid completing the variable itself, e.g. in 'int foo = ^'. |
5945 | Data.IgnoreDecls.push_back(VD); |
5946 | |
5947 | CodeCompleteExpression(S, Data); |
5948 | } |
5949 | |
5950 | void Sema::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) { |
5951 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
5952 | CodeCompleter->getCodeCompletionTUInfo(), |
5953 | mapCodeCompletionContext(*this, PCC_Statement)); |
5954 | Results.setFilter(&ResultBuilder::IsOrdinaryName); |
5955 | Results.EnterNewScope(); |
5956 | |
5957 | CodeCompletionDeclConsumer Consumer(Results, CurContext); |
5958 | LookupVisibleDecls(S, LookupOrdinaryName, Consumer, |
5959 | CodeCompleter->includeGlobals(), |
5960 | CodeCompleter->loadExternal()); |
5961 | |
5962 | AddOrdinaryNameResults(PCC_Statement, S, *this, Results); |
5963 | |
5964 | // "else" block |
5965 | CodeCompletionBuilder Builder(Results.getAllocator(), |
5966 | Results.getCodeCompletionTUInfo()); |
5967 | |
5968 | auto AddElseBodyPattern = [&] { |
5969 | if (IsBracedThen) { |
5970 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
5971 | Builder.AddChunk(CodeCompletionString::CK_LeftBrace); |
5972 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
5973 | Builder.AddPlaceholderChunk("statements"); |
5974 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
5975 | Builder.AddChunk(CodeCompletionString::CK_RightBrace); |
5976 | } else { |
5977 | Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); |
5978 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
5979 | Builder.AddPlaceholderChunk("statement"); |
5980 | Builder.AddChunk(CodeCompletionString::CK_SemiColon); |
5981 | } |
5982 | }; |
5983 | Builder.AddTypedTextChunk("else"); |
5984 | if (Results.includeCodePatterns()) |
5985 | AddElseBodyPattern(); |
5986 | Results.AddResult(Builder.TakeString()); |
5987 | |
5988 | // "else if" block |
5989 | Builder.AddTypedTextChunk("else if"); |
5990 | Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); |
5991 | Builder.AddChunk(CodeCompletionString::CK_LeftParen); |
5992 | if (getLangOpts().CPlusPlus) |
5993 | Builder.AddPlaceholderChunk("condition"); |
5994 | else |
5995 | Builder.AddPlaceholderChunk("expression"); |
5996 | Builder.AddChunk(CodeCompletionString::CK_RightParen); |
5997 | if (Results.includeCodePatterns()) { |
5998 | AddElseBodyPattern(); |
5999 | } |
6000 | Results.AddResult(Builder.TakeString()); |
6001 | |
6002 | Results.ExitScope(); |
6003 | |
6004 | if (S->getFnParent()) |
6005 | AddPrettyFunctionResults(getLangOpts(), Results); |
6006 | |
6007 | if (CodeCompleter->includeMacros()) |
6008 | AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false); |
6009 | |
6010 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
6011 | Results.data(), Results.size()); |
6012 | } |
6013 | |
6014 | void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, |
6015 | bool EnteringContext, |
6016 | bool IsUsingDeclaration, QualType BaseType, |
6017 | QualType PreferredType) { |
6018 | if (SS.isEmpty() || !CodeCompleter) |
6019 | return; |
6020 | |
6021 | CodeCompletionContext CC(CodeCompletionContext::CCC_Symbol, PreferredType); |
6022 | CC.setIsUsingDeclaration(IsUsingDeclaration); |
6023 | CC.setCXXScopeSpecifier(SS); |
6024 | |
6025 | // We want to keep the scope specifier even if it's invalid (e.g. the scope |
6026 | // "a::b::" is not corresponding to any context/namespace in the AST), since |
6027 | // it can be useful for global code completion which have information about |
6028 | // contexts/symbols that are not in the AST. |
6029 | if (SS.isInvalid()) { |
6030 | // As SS is invalid, we try to collect accessible contexts from the current |
6031 | // scope with a dummy lookup so that the completion consumer can try to |
6032 | // guess what the specified scope is. |
6033 | ResultBuilder DummyResults(*this, CodeCompleter->getAllocator(), |
6034 | CodeCompleter->getCodeCompletionTUInfo(), CC); |
6035 | if (!PreferredType.isNull()) |
6036 | DummyResults.setPreferredType(PreferredType); |
6037 | if (S->getEntity()) { |
6038 | CodeCompletionDeclConsumer Consumer(DummyResults, S->getEntity(), |
6039 | BaseType); |
6040 | LookupVisibleDecls(S, LookupOrdinaryName, Consumer, |
6041 | /*IncludeGlobalScope=*/false, |
6042 | /*LoadExternal=*/false); |
6043 | } |
6044 | HandleCodeCompleteResults(this, CodeCompleter, |
6045 | DummyResults.getCompletionContext(), nullptr, 0); |
6046 | return; |
6047 | } |
6048 | // Always pretend to enter a context to ensure that a dependent type |
6049 | // resolves to a dependent record. |
6050 | DeclContext *Ctx = computeDeclContext(SS, /*EnteringContext=*/true); |
6051 | |
6052 | // Try to instantiate any non-dependent declaration contexts before |
6053 | // we look in them. Bail out if we fail. |
6054 | NestedNameSpecifier *NNS = SS.getScopeRep(); |
6055 | if (NNS != nullptr && SS.isValid() && !NNS->isDependent()) { |
6056 | if (Ctx == nullptr || RequireCompleteDeclContext(SS, Ctx)) |
6057 | return; |
6058 | } |
6059 | |
6060 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
6061 | CodeCompleter->getCodeCompletionTUInfo(), CC); |
6062 | if (!PreferredType.isNull()) |
6063 | Results.setPreferredType(PreferredType); |
6064 | Results.EnterNewScope(); |
6065 | |
6066 | // The "template" keyword can follow "::" in the grammar, but only |
6067 | // put it into the grammar if the nested-name-specifier is dependent. |
6068 | // FIXME: results is always empty, this appears to be dead. |
6069 | if (!Results.empty() && NNS->isDependent()) |
6070 | Results.AddResult("template"); |
6071 | |
6072 | // If the scope is a concept-constrained type parameter, infer nested |
6073 | // members based on the constraints. |
6074 | if (const auto *TTPT = |
6075 | dyn_cast_or_null<TemplateTypeParmType>(NNS->getAsType())) { |
6076 | for (const auto &R : ConceptInfo(*TTPT, S).members()) { |
6077 | if (R.Operator != ConceptInfo::Member::Colons) |
6078 | continue; |
6079 | Results.AddResult(CodeCompletionResult( |
6080 | R.render(*this, CodeCompleter->getAllocator(), |
6081 | CodeCompleter->getCodeCompletionTUInfo()))); |
6082 | } |
6083 | } |
6084 | |
6085 | // Add calls to overridden virtual functions, if there are any. |
6086 | // |
6087 | // FIXME: This isn't wonderful, because we don't know whether we're actually |
6088 | // in a context that permits expressions. This is a general issue with |
6089 | // qualified-id completions. |
6090 | if (Ctx && !EnteringContext) |
6091 | MaybeAddOverrideCalls(*this, Ctx, Results); |
6092 | Results.ExitScope(); |
6093 | |
6094 | if (Ctx && |
6095 | (CodeCompleter->includeNamespaceLevelDecls() || !Ctx->isFileContext())) { |
6096 | CodeCompletionDeclConsumer Consumer(Results, Ctx, BaseType); |
6097 | LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer, |
6098 | /*IncludeGlobalScope=*/true, |
6099 | /*IncludeDependentBases=*/true, |
6100 | CodeCompleter->loadExternal()); |
6101 | } |
6102 | |
6103 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
6104 | Results.data(), Results.size()); |
6105 | } |
6106 | |
6107 | void Sema::CodeCompleteUsing(Scope *S) { |
6108 | if (!CodeCompleter) |
6109 | return; |
6110 | |
6111 | // This can be both a using alias or using declaration, in the former we |
6112 | // expect a new name and a symbol in the latter case. |
6113 | CodeCompletionContext Context(CodeCompletionContext::CCC_SymbolOrNewName); |
6114 | Context.setIsUsingDeclaration(true); |
6115 | |
6116 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
6117 | CodeCompleter->getCodeCompletionTUInfo(), Context, |
6118 | &ResultBuilder::IsNestedNameSpecifier); |
6119 | Results.EnterNewScope(); |
6120 | |
6121 | // If we aren't in class scope, we could see the "namespace" keyword. |
6122 | if (!S->isClassScope()) |
6123 | Results.AddResult(CodeCompletionResult("namespace")); |
6124 | |
6125 | // After "using", we can see anything that would start a |
6126 | // nested-name-specifier. |
6127 | CodeCompletionDeclConsumer Consumer(Results, CurContext); |
6128 | LookupVisibleDecls(S, LookupOrdinaryName, Consumer, |
6129 | CodeCompleter->includeGlobals(), |
6130 | CodeCompleter->loadExternal()); |
6131 | Results.ExitScope(); |
6132 | |
6133 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
6134 | Results.data(), Results.size()); |
6135 | } |
6136 | |
6137 | void Sema::CodeCompleteUsingDirective(Scope *S) { |
6138 | if (!CodeCompleter) |
6139 | return; |
6140 | |
6141 | // After "using namespace", we expect to see a namespace name or namespace |
6142 | // alias. |
6143 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
6144 | CodeCompleter->getCodeCompletionTUInfo(), |
6145 | CodeCompletionContext::CCC_Namespace, |
6146 | &ResultBuilder::IsNamespaceOrAlias); |
6147 | Results.EnterNewScope(); |
6148 | CodeCompletionDeclConsumer Consumer(Results, CurContext); |
6149 | LookupVisibleDecls(S, LookupOrdinaryName, Consumer, |
6150 | CodeCompleter->includeGlobals(), |
6151 | CodeCompleter->loadExternal()); |
6152 | Results.ExitScope(); |
6153 | HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), |
6154 | Results.data(), Results.size()); |
6155 | } |
6156 | |
6157 | void Sema::CodeCompleteNamespaceDecl(Scope *S) { |
6158 | if (!CodeCompleter) |
6159 | return; |
6160 | |
6161 | DeclContext *Ctx = S->getEntity(); |
6162 | if (!S->getParent()) |
6163 | Ctx = Context.getTranslationUnitDecl(); |
6164 | |
6165 | bool SuppressedGlobalResults = |
6166 | Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx); |
6167 | |
6168 | ResultBuilder Results(*this, CodeCompleter->getAllocator(), |
6169 | CodeCompleter->getCodeCompletionTUInfo(), |
6170 | SuppressedGlobalResults |
6171 | ? CodeCompletionContext::CCC_Namespace |
6172 | : CodeCompletionContext::CCC_Other, |
6173 | &ResultBuilder::IsNamespace); |
6174 | |
6175 | if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) { |
6176 | // We only want to see those namespaces that have already been defined |
6177 | // within this scope, because its likely that the user is creating an |
6178 | // extended namespace declaration. Keep track of the most recent |
6179 | // definition of each namespace. |
6180 | std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest; |
6181 | for (DeclContext::specific_decl_iterator<NamespaceDecl> |
6182 | NS(Ctx->decls_begin()), |
6183 | NSEnd(Ctx->decls_end()); |
6184 | NS != NSEnd; ++NS) |
6185 | OrigToLatest[NS->getOriginalNamespace()] = *NS; |
6186 | |
6187 | // Add the most recent definition (or extended definition) of each |
6188 | // namespace to the list of results. |
6189 | Results.EnterNewScope(); |
6190 | for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator |
6191 | NS = OrigToLatest.begin(), |
6192 | NSEnd = OrigToLatest.end(); |
6193 | NS != NSEnd; ++NS) |
6194 | Results.AddResult( |
6195 | CodeCompletionResult(NS->second, Results.getBasePriority(NS->second), |
6196 | nullptr), |
6197 | CurContext, nullptr, false); |
6198 | Results.ExitScope(); |
6199 | } |