1 //===--- InlayHints.cpp ------------------------------------------*- 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 #include "InlayHints.h"
9 #include "AST.h"
10 #include "Config.h"
11 #include "HeuristicResolver.h"
12 #include "ParsedAST.h"
13 #include "clang/AST/Decl.h"
14 #include "clang/AST/DeclarationName.h"
15 #include "clang/AST/ExprCXX.h"
16 #include "clang/AST/RecursiveASTVisitor.h"
17 #include "clang/Basic/Builtins.h"
18 #include "clang/Basic/SourceManager.h"
19 #include "llvm/ADT/ScopeExit.h"
20 
21 namespace clang {
22 namespace clangd {
23 namespace {
24 
25 // For now, inlay hints are always anchored at the left or right of their range.
26 enum class HintSide { Left, Right };
27 
28 // Helper class to iterate over the designator names of an aggregate type.
29 //
30 // For an array type, yields [0], [1], [2]...
31 // For aggregate classes, yields null for each base, then .field1, .field2, ...
32 class AggregateDesignatorNames {
33 public:
34   AggregateDesignatorNames(QualType T) {
35     if (!T.isNull()) {
36       T = T.getCanonicalType();
37       if (T->isArrayType()) {
38         IsArray = true;
39         Valid = true;
40         return;
41       }
42       if (const RecordDecl *RD = T->getAsRecordDecl()) {
43         Valid = true;
44         FieldsIt = RD->field_begin();
45         FieldsEnd = RD->field_end();
46         if (const auto *CRD = llvm::dyn_cast<CXXRecordDecl>(RD)) {
47           BasesIt = CRD->bases_begin();
48           BasesEnd = CRD->bases_end();
49           Valid = CRD->isAggregate();
50         }
51         OneField = Valid && BasesIt == BasesEnd && FieldsIt != FieldsEnd &&
52                    std::next(FieldsIt) == FieldsEnd;
53       }
54     }
55   }
56   // Returns false if the type was not an aggregate.
57   operator bool() { return Valid; }
58   // Advance to the next element in the aggregate.
59   void next() {
60     if (IsArray)
61       ++Index;
62     else if (BasesIt != BasesEnd)
63       ++BasesIt;
64     else if (FieldsIt != FieldsEnd)
65       ++FieldsIt;
66   }
67   // Print the designator to Out.
68   // Returns false if we could not produce a designator for this element.
69   bool append(std::string &Out, bool ForSubobject) {
70     if (IsArray) {
71       Out.push_back('[');
72       Out.append(std::to_string(Index));
73       Out.push_back(']');
74       return true;
75     }
76     if (BasesIt != BasesEnd)
77       return false; // Bases can't be designated. Should we make one up?
78     if (FieldsIt != FieldsEnd) {
79       llvm::StringRef FieldName;
80       if (const IdentifierInfo *II = FieldsIt->getIdentifier())
81         FieldName = II->getName();
82 
83       // For certain objects, their subobjects may be named directly.
84       if (ForSubobject &&
85           (FieldsIt->isAnonymousStructOrUnion() ||
86            // std::array<int,3> x = {1,2,3}. Designators not strictly valid!
87            (OneField && isReservedName(FieldName))))
88         return true;
89 
90       if (!FieldName.empty() && !isReservedName(FieldName)) {
91         Out.push_back('.');
92         Out.append(FieldName.begin(), FieldName.end());
93         return true;
94       }
95       return false;
96     }
97     return false;
98   }
99 
100 private:
101   bool Valid = false;
102   bool IsArray = false;
103   bool OneField = false; // e.g. std::array { T __elements[N]; }
104   unsigned Index = 0;
105   CXXRecordDecl::base_class_const_iterator BasesIt;
106   CXXRecordDecl::base_class_const_iterator BasesEnd;
107   RecordDecl::field_iterator FieldsIt;
108   RecordDecl::field_iterator FieldsEnd;
109 };
110 
111 // Collect designator labels describing the elements of an init list.
112 //
113 // This function contributes the designators of some (sub)object, which is
114 // represented by the semantic InitListExpr Sem.
115 // This includes any nested subobjects, but *only* if they are part of the same
116 // original syntactic init list (due to brace elision).
117 // In other words, it may descend into subobjects but not written init-lists.
118 //
119 // For example: struct Outer { Inner a,b; }; struct Inner { int x, y; }
120 //              Outer o{{1, 2}, 3};
121 // This function will be called with Sem = { {1, 2}, {3, ImplicitValue} }
122 // It should generate designators '.a:' and '.b.x:'.
123 // '.a:' is produced directly without recursing into the written sublist.
124 // (The written sublist will have a separate collectDesignators() call later).
125 // Recursion with Prefix='.b' and Sem = {3, ImplicitValue} produces '.b.x:'.
126 void collectDesignators(const InitListExpr *Sem,
127                         llvm::DenseMap<SourceLocation, std::string> &Out,
128                         const llvm::DenseSet<SourceLocation> &NestedBraces,
129                         std::string &Prefix) {
130   if (!Sem || Sem->isTransparent())
131     return;
132   assert(Sem->isSemanticForm());
133 
134   // The elements of the semantic form all correspond to direct subobjects of
135   // the aggregate type. `Fields` iterates over these subobject names.
136   AggregateDesignatorNames Fields(Sem->getType());
137   if (!Fields)
138     return;
139   for (const Expr *Init : Sem->inits()) {
140     auto Next = llvm::make_scope_exit([&, Size(Prefix.size())] {
141       Fields.next();       // Always advance to the next subobject name.
142       Prefix.resize(Size); // Erase any designator we appended.
143     });
144     if (llvm::isa<ImplicitValueInitExpr>(Init))
145       continue; // a "hole" for a subobject that was not explicitly initialized
146 
147     const auto *BraceElidedSubobject = llvm::dyn_cast<InitListExpr>(Init);
148     if (BraceElidedSubobject &&
149         NestedBraces.contains(BraceElidedSubobject->getLBraceLoc()))
150       BraceElidedSubobject = nullptr; // there were braces!
151 
152     if (!Fields.append(Prefix, BraceElidedSubobject != nullptr))
153       continue; // no designator available for this subobject
154     if (BraceElidedSubobject) {
155       // If the braces were elided, this aggregate subobject is initialized
156       // inline in the same syntactic list.
157       // Descend into the semantic list describing the subobject.
158       // (NestedBraces are still correct, they're from the same syntactic list).
159       collectDesignators(BraceElidedSubobject, Out, NestedBraces, Prefix);
160       continue;
161     }
162     Out.try_emplace(Init->getBeginLoc(), Prefix);
163   }
164 }
165 
166 // Get designators describing the elements of a (syntactic) init list.
167 // This does not produce designators for any explicitly-written nested lists.
168 llvm::DenseMap<SourceLocation, std::string>
169 getDesignators(const InitListExpr *Syn) {
170   assert(Syn->isSyntacticForm());
171 
172   // collectDesignators needs to know which InitListExprs in the semantic tree
173   // were actually written, but InitListExpr::isExplicit() lies.
174   // Instead, record where braces of sub-init-lists occur in the syntactic form.
175   llvm::DenseSet<SourceLocation> NestedBraces;
176   for (const Expr *Init : Syn->inits())
177     if (auto *Nested = llvm::dyn_cast<InitListExpr>(Init))
178       NestedBraces.insert(Nested->getLBraceLoc());
179 
180   // Traverse the semantic form to find the designators.
181   // We use their SourceLocation to correlate with the syntactic form later.
182   llvm::DenseMap<SourceLocation, std::string> Designators;
183   std::string EmptyPrefix;
184   collectDesignators(Syn->isSemanticForm() ? Syn : Syn->getSemanticForm(),
185                      Designators, NestedBraces, EmptyPrefix);
186   return Designators;
187 }
188 
189 class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
190 public:
191   InlayHintVisitor(std::vector<InlayHint> &Results, ParsedAST &AST,
192                    const Config &Cfg, llvm::Optional<Range> RestrictRange)
193       : Results(Results), AST(AST.getASTContext()), Cfg(Cfg),
194         RestrictRange(std::move(RestrictRange)),
195         MainFileID(AST.getSourceManager().getMainFileID()),
196         Resolver(AST.getHeuristicResolver()),
197         TypeHintPolicy(this->AST.getPrintingPolicy()),
198         StructuredBindingPolicy(this->AST.getPrintingPolicy()) {
199     bool Invalid = false;
200     llvm::StringRef Buf =
201         AST.getSourceManager().getBufferData(MainFileID, &Invalid);
202     MainFileBuf = Invalid ? StringRef{} : Buf;
203 
204     TypeHintPolicy.SuppressScope = true; // keep type names short
205     TypeHintPolicy.AnonymousTagLocations =
206         false; // do not print lambda locations
207 
208     // For structured bindings, print canonical types. This is important because
209     // for bindings that use the tuple_element protocol, the non-canonical types
210     // would be "tuple_element<I, A>::type".
211     // For "auto", we often prefer sugared types.
212     // Not setting PrintCanonicalTypes for "auto" allows
213     // SuppressDefaultTemplateArgs (set by default) to have an effect.
214     StructuredBindingPolicy = TypeHintPolicy;
215     StructuredBindingPolicy.PrintCanonicalTypes = true;
216   }
217 
218   bool VisitCXXConstructExpr(CXXConstructExpr *E) {
219     // Weed out constructor calls that don't look like a function call with
220     // an argument list, by checking the validity of getParenOrBraceRange().
221     // Also weed out std::initializer_list constructors as there are no names
222     // for the individual arguments.
223     if (!E->getParenOrBraceRange().isValid() ||
224         E->isStdInitListInitialization()) {
225       return true;
226     }
227 
228     processCall(E->getParenOrBraceRange().getBegin(), E->getConstructor(),
229                 {E->getArgs(), E->getNumArgs()});
230     return true;
231   }
232 
233   bool VisitCallExpr(CallExpr *E) {
234     if (!Cfg.InlayHints.Parameters)
235       return true;
236 
237     // Do not show parameter hints for operator calls written using operator
238     // syntax or user-defined literals. (Among other reasons, the resulting
239     // hints can look awkard, e.g. the expression can itself be a function
240     // argument and then we'd get two hints side by side).
241     if (isa<CXXOperatorCallExpr>(E) || isa<UserDefinedLiteral>(E))
242       return true;
243 
244     auto CalleeDecls = Resolver->resolveCalleeOfCallExpr(E);
245     if (CalleeDecls.size() != 1)
246       return true;
247     const FunctionDecl *Callee = nullptr;
248     if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecls[0]))
249       Callee = FD;
250     else if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(CalleeDecls[0]))
251       Callee = FTD->getTemplatedDecl();
252     if (!Callee)
253       return true;
254 
255     processCall(E->getRParenLoc(), Callee, {E->getArgs(), E->getNumArgs()});
256     return true;
257   }
258 
259   bool VisitFunctionDecl(FunctionDecl *D) {
260     if (auto *FPT =
261             llvm::dyn_cast<FunctionProtoType>(D->getType().getTypePtr())) {
262       if (!FPT->hasTrailingReturn()) {
263         if (auto FTL = D->getFunctionTypeLoc())
264           addReturnTypeHint(D, FTL.getRParenLoc());
265       }
266     }
267     return true;
268   }
269 
270   bool VisitLambdaExpr(LambdaExpr *E) {
271     FunctionDecl *D = E->getCallOperator();
272     if (!E->hasExplicitResultType())
273       addReturnTypeHint(D, E->hasExplicitParameters()
274                                ? D->getFunctionTypeLoc().getRParenLoc()
275                                : E->getIntroducerRange().getEnd());
276     return true;
277   }
278 
279   void addReturnTypeHint(FunctionDecl *D, SourceLocation Loc) {
280     auto *AT = D->getReturnType()->getContainedAutoType();
281     if (!AT || AT->getDeducedType().isNull())
282       return;
283     addTypeHint(Loc, D->getReturnType(), /*Prefix=*/"-> ");
284   }
285 
286   bool VisitVarDecl(VarDecl *D) {
287     // Do not show hints for the aggregate in a structured binding,
288     // but show hints for the individual bindings.
289     if (auto *DD = dyn_cast<DecompositionDecl>(D)) {
290       for (auto *Binding : DD->bindings()) {
291         addTypeHint(Binding->getLocation(), Binding->getType(), /*Prefix=*/": ",
292                     StructuredBindingPolicy);
293       }
294       return true;
295     }
296 
297     if (D->getType()->getContainedAutoType()) {
298       if (!D->getType()->isDependentType()) {
299         // Our current approach is to place the hint on the variable
300         // and accordingly print the full type
301         // (e.g. for `const auto& x = 42`, print `const int&`).
302         // Alternatively, we could place the hint on the `auto`
303         // (and then just print the type deduced for the `auto`).
304         addTypeHint(D->getLocation(), D->getType(), /*Prefix=*/": ");
305       }
306     }
307 
308     // Handle templates like `int foo(auto x)` with exactly one instantiation.
309     if (auto *PVD = llvm::dyn_cast<ParmVarDecl>(D)) {
310       if (D->getIdentifier() && PVD->getType()->isDependentType() &&
311           !getContainedAutoParamType(D->getTypeSourceInfo()->getTypeLoc())
312                .isNull()) {
313         if (auto *IPVD = getOnlyParamInstantiation(PVD))
314           addTypeHint(D->getLocation(), IPVD->getType(), /*Prefix=*/": ");
315       }
316     }
317 
318     return true;
319   }
320 
321   ParmVarDecl *getOnlyParamInstantiation(ParmVarDecl *D) {
322     auto *TemplateFunction = llvm::dyn_cast<FunctionDecl>(D->getDeclContext());
323     if (!TemplateFunction)
324       return nullptr;
325     auto *InstantiatedFunction = llvm::dyn_cast_or_null<FunctionDecl>(
326         getOnlyInstantiation(TemplateFunction));
327     if (!InstantiatedFunction)
328       return nullptr;
329 
330     unsigned ParamIdx = 0;
331     for (auto *Param : TemplateFunction->parameters()) {
332       // Can't reason about param indexes in the presence of preceding packs.
333       // And if this param is a pack, it may expand to multiple params.
334       if (Param->isParameterPack())
335         return nullptr;
336       if (Param == D)
337         break;
338       ++ParamIdx;
339     }
340     assert(ParamIdx < TemplateFunction->getNumParams() &&
341            "Couldn't find param in list?");
342     assert(ParamIdx < InstantiatedFunction->getNumParams() &&
343            "Instantiated function has fewer (non-pack) parameters?");
344     return InstantiatedFunction->getParamDecl(ParamIdx);
345   }
346 
347   bool VisitInitListExpr(InitListExpr *Syn) {
348     // We receive the syntactic form here (shouldVisitImplicitCode() is false).
349     // This is the one we will ultimately attach designators to.
350     // It may have subobject initializers inlined without braces. The *semantic*
351     // form of the init-list has nested init-lists for these.
352     // getDesignators will look at the semantic form to determine the labels.
353     assert(Syn->isSyntacticForm() && "RAV should not visit implicit code!");
354     if (!Cfg.InlayHints.Designators)
355       return true;
356     if (Syn->isIdiomaticZeroInitializer(AST.getLangOpts()))
357       return true;
358     llvm::DenseMap<SourceLocation, std::string> Designators =
359         getDesignators(Syn);
360     for (const Expr *Init : Syn->inits()) {
361       if (llvm::isa<DesignatedInitExpr>(Init))
362         continue;
363       auto It = Designators.find(Init->getBeginLoc());
364       if (It != Designators.end() &&
365           !isPrecededByParamNameComment(Init, It->second))
366         addDesignatorHint(Init->getSourceRange(), It->second);
367     }
368     return true;
369   }
370 
371   // FIXME: Handle RecoveryExpr to try to hint some invalid calls.
372 
373 private:
374   using NameVec = SmallVector<StringRef, 8>;
375 
376   // The purpose of Anchor is to deal with macros. It should be the call's
377   // opening or closing parenthesis or brace. (Always using the opening would
378   // make more sense but CallExpr only exposes the closing.) We heuristically
379   // assume that if this location does not come from a macro definition, then
380   // the entire argument list likely appears in the main file and can be hinted.
381   void processCall(SourceLocation Anchor, const FunctionDecl *Callee,
382                    llvm::ArrayRef<const Expr *> Args) {
383     if (!Cfg.InlayHints.Parameters || Args.size() == 0 || !Callee)
384       return;
385 
386     // If the anchor location comes from a macro defintion, there's nowhere to
387     // put hints.
388     if (!AST.getSourceManager().getTopMacroCallerLoc(Anchor).isFileID())
389       return;
390 
391     // The parameter name of a move or copy constructor is not very interesting.
392     if (auto *Ctor = dyn_cast<CXXConstructorDecl>(Callee))
393       if (Ctor->isCopyOrMoveConstructor())
394         return;
395 
396     // Resolve parameter packs to their forwarded parameter
397     auto ForwardedParams = resolveForwardingParameters(Callee);
398 
399     NameVec ParameterNames = chooseParameterNames(ForwardedParams);
400 
401     // Exclude setters (i.e. functions with one argument whose name begins with
402     // "set"), and builtins like std::move/forward/... as their parameter name
403     // is also not likely to be interesting.
404     if (isSetter(Callee, ParameterNames) || isSimpleBuiltin(Callee))
405       return;
406 
407     for (size_t I = 0; I < ParameterNames.size() && I < Args.size(); ++I) {
408       // Pack expansion expressions cause the 1:1 mapping between arguments and
409       // parameters to break down, so we don't add further inlay hints if we
410       // encounter one.
411       if (isa<PackExpansionExpr>(Args[I])) {
412         break;
413       }
414 
415       StringRef Name = ParameterNames[I];
416       bool NameHint = shouldHintName(Args[I], Name);
417       bool ReferenceHint =
418           shouldHintReference(Callee->getParamDecl(I), ForwardedParams[I]);
419 
420       if (NameHint || ReferenceHint) {
421         addInlayHint(Args[I]->getSourceRange(), HintSide::Left,
422                      InlayHintKind::Parameter, ReferenceHint ? "&" : "",
423                      NameHint ? Name : "", ": ");
424       }
425     }
426   }
427 
428   static bool isSetter(const FunctionDecl *Callee, const NameVec &ParamNames) {
429     if (ParamNames.size() != 1)
430       return false;
431 
432     StringRef Name = getSimpleName(*Callee);
433     if (!Name.startswith_insensitive("set"))
434       return false;
435 
436     // In addition to checking that the function has one parameter and its
437     // name starts with "set", also check that the part after "set" matches
438     // the name of the parameter (ignoring case). The idea here is that if
439     // the parameter name differs, it may contain extra information that
440     // may be useful to show in a hint, as in:
441     //   void setTimeout(int timeoutMillis);
442     // This currently doesn't handle cases where params use snake_case
443     // and functions don't, e.g.
444     //   void setExceptionHandler(EHFunc exception_handler);
445     // We could improve this by replacing `equals_insensitive` with some
446     // `sloppy_equals` which ignores case and also skips underscores.
447     StringRef WhatItIsSetting = Name.substr(3).ltrim("_");
448     return WhatItIsSetting.equals_insensitive(ParamNames[0]);
449   }
450 
451   // Checks if the callee is one of the builtins
452   // addressof, as_const, forward, move(_if_noexcept)
453   static bool isSimpleBuiltin(const FunctionDecl *Callee) {
454     switch (Callee->getBuiltinID()) {
455     case Builtin::BIaddressof:
456     case Builtin::BIas_const:
457     case Builtin::BIforward:
458     case Builtin::BImove:
459     case Builtin::BImove_if_noexcept:
460       return true;
461     default:
462       return false;
463     }
464   }
465 
466   bool shouldHintName(const Expr *Arg, StringRef ParamName) {
467     if (ParamName.empty())
468       return false;
469 
470     // If the argument expression is a single name and it matches the
471     // parameter name exactly, omit the name hint.
472     if (ParamName == getSpelledIdentifier(Arg))
473       return false;
474 
475     // Exclude argument expressions preceded by a /*paramName*/.
476     if (isPrecededByParamNameComment(Arg, ParamName))
477       return false;
478 
479     return true;
480   }
481 
482   bool shouldHintReference(const ParmVarDecl *Param,
483                            const ParmVarDecl *ForwardedParam) {
484     // We add a & hint only when the argument is passed as mutable reference.
485     // For parameters that are not part of an expanded pack, this is
486     // straightforward. For expanded pack parameters, it's likely that they will
487     // be forwarded to another function. In this situation, we only want to add
488     // the reference hint if the argument is actually being used via mutable
489     // reference. This means we need to check
490     // 1. whether the value category of the argument is preserved, i.e. each
491     //    pack expansion uses std::forward correctly.
492     // 2. whether the argument is ever copied/cast instead of passed
493     //    by-reference
494     // Instead of checking this explicitly, we use the following proxy:
495     // 1. the value category can only change from rvalue to lvalue during
496     //    forwarding, so checking whether both the parameter of the forwarding
497     //    function and the forwarded function are lvalue references detects such
498     //    a conversion.
499     // 2. if the argument is copied/cast somewhere in the chain of forwarding
500     //    calls, it can only be passed on to an rvalue reference or const lvalue
501     //    reference parameter. Thus if the forwarded parameter is a mutable
502     //    lvalue reference, it cannot have been copied/cast to on the way.
503     // Additionally, we should not add a reference hint if the forwarded
504     // parameter was only partially resolved, i.e. points to an expanded pack
505     // parameter, since we do not know how it will be used eventually.
506     auto Type = Param->getType();
507     auto ForwardedType = ForwardedParam->getType();
508     return Type->isLValueReferenceType() &&
509            ForwardedType->isLValueReferenceType() &&
510            !ForwardedType.getNonReferenceType().isConstQualified() &&
511            !isExpandedFromParameterPack(ForwardedParam);
512   }
513 
514   // Checks if "E" is spelled in the main file and preceded by a C-style comment
515   // whose contents match ParamName (allowing for whitespace and an optional "="
516   // at the end.
517   bool isPrecededByParamNameComment(const Expr *E, StringRef ParamName) {
518     auto &SM = AST.getSourceManager();
519     auto ExprStartLoc = SM.getTopMacroCallerLoc(E->getBeginLoc());
520     auto Decomposed = SM.getDecomposedLoc(ExprStartLoc);
521     if (Decomposed.first != MainFileID)
522       return false;
523 
524     StringRef SourcePrefix = MainFileBuf.substr(0, Decomposed.second);
525     // Allow whitespace between comment and expression.
526     SourcePrefix = SourcePrefix.rtrim();
527     // Check for comment ending.
528     if (!SourcePrefix.consume_back("*/"))
529       return false;
530     // Ignore some punctuation and whitespace around comment.
531     // In particular this allows designators to match nicely.
532     llvm::StringLiteral IgnoreChars = " =.";
533     SourcePrefix = SourcePrefix.rtrim(IgnoreChars);
534     ParamName = ParamName.trim(IgnoreChars);
535     // Other than that, the comment must contain exactly ParamName.
536     if (!SourcePrefix.consume_back(ParamName))
537       return false;
538     SourcePrefix = SourcePrefix.rtrim(IgnoreChars);
539     return SourcePrefix.endswith("/*");
540   }
541 
542   // If "E" spells a single unqualified identifier, return that name.
543   // Otherwise, return an empty string.
544   static StringRef getSpelledIdentifier(const Expr *E) {
545     E = E->IgnoreUnlessSpelledInSource();
546 
547     if (auto *DRE = dyn_cast<DeclRefExpr>(E))
548       if (!DRE->getQualifier())
549         return getSimpleName(*DRE->getDecl());
550 
551     if (auto *ME = dyn_cast<MemberExpr>(E))
552       if (!ME->getQualifier() && ME->isImplicitAccess())
553         return getSimpleName(*ME->getMemberDecl());
554 
555     return {};
556   }
557 
558   NameVec chooseParameterNames(SmallVector<const ParmVarDecl *> Parameters) {
559     NameVec ParameterNames;
560     for (const auto *P : Parameters) {
561       if (isExpandedFromParameterPack(P)) {
562         // If we haven't resolved a pack paramater (e.g. foo(Args... args)) to a
563         // non-pack parameter, then hinting as foo(args: 1, args: 2, args: 3) is
564         // unlikely to be useful.
565         ParameterNames.emplace_back();
566       } else {
567         auto SimpleName = getSimpleName(*P);
568         // If the parameter is unnamed in the declaration:
569         // attempt to get its name from the definition
570         if (SimpleName.empty()) {
571           if (const auto *PD = getParamDefinition(P)) {
572             SimpleName = getSimpleName(*PD);
573           }
574         }
575         ParameterNames.emplace_back(SimpleName);
576       }
577     }
578 
579     // Standard library functions often have parameter names that start
580     // with underscores, which makes the hints noisy, so strip them out.
581     for (auto &Name : ParameterNames)
582       stripLeadingUnderscores(Name);
583 
584     return ParameterNames;
585   }
586 
587   // for a ParmVarDecl from a function declaration, returns the corresponding
588   // ParmVarDecl from the definition if possible, nullptr otherwise.
589   static const ParmVarDecl *getParamDefinition(const ParmVarDecl *P) {
590     if (auto *Callee = dyn_cast<FunctionDecl>(P->getDeclContext())) {
591       if (auto *Def = Callee->getDefinition()) {
592         auto I = std::distance(
593             Callee->param_begin(),
594             std::find(Callee->param_begin(), Callee->param_end(), P));
595         if (I < Callee->getNumParams()) {
596           return Def->getParamDecl(I);
597         }
598       }
599     }
600     return nullptr;
601   }
602 
603   static void stripLeadingUnderscores(StringRef &Name) {
604     Name = Name.ltrim('_');
605   }
606 
607   static StringRef getSimpleName(const NamedDecl &D) {
608     if (IdentifierInfo *Ident = D.getDeclName().getAsIdentifierInfo()) {
609       return Ident->getName();
610     }
611 
612     return StringRef();
613   }
614 
615   // We pass HintSide rather than SourceLocation because we want to ensure
616   // it is in the same file as the common file range.
617   void addInlayHint(SourceRange R, HintSide Side, InlayHintKind Kind,
618                     llvm::StringRef Prefix, llvm::StringRef Label,
619                     llvm::StringRef Suffix) {
620     // We shouldn't get as far as adding a hint if the category is disabled.
621     // We'd like to disable as much of the analysis as possible above instead.
622     // Assert in debug mode but add a dynamic check in production.
623     assert(Cfg.InlayHints.Enabled && "Shouldn't get here if disabled!");
624     switch (Kind) {
625 #define CHECK_KIND(Enumerator, ConfigProperty)                                 \
626   case InlayHintKind::Enumerator:                                              \
627     assert(Cfg.InlayHints.ConfigProperty &&                                    \
628            "Shouldn't get here if kind is disabled!");                         \
629     if (!Cfg.InlayHints.ConfigProperty)                                        \
630       return;                                                                  \
631     break
632       CHECK_KIND(Parameter, Parameters);
633       CHECK_KIND(Type, DeducedTypes);
634       CHECK_KIND(Designator, Designators);
635 #undef CHECK_KIND
636     }
637 
638     auto FileRange =
639         toHalfOpenFileRange(AST.getSourceManager(), AST.getLangOpts(), R);
640     if (!FileRange)
641       return;
642     Range LSPRange{
643         sourceLocToPosition(AST.getSourceManager(), FileRange->getBegin()),
644         sourceLocToPosition(AST.getSourceManager(), FileRange->getEnd())};
645     Position LSPPos = Side == HintSide::Left ? LSPRange.start : LSPRange.end;
646     if (RestrictRange &&
647         (LSPPos < RestrictRange->start || !(LSPPos < RestrictRange->end)))
648       return;
649     // The hint may be in a file other than the main file (for example, a header
650     // file that was included after the preamble), do not show in that case.
651     if (!AST.getSourceManager().isWrittenInMainFile(FileRange->getBegin()))
652       return;
653     bool PadLeft = Prefix.consume_front(" ");
654     bool PadRight = Suffix.consume_back(" ");
655     Results.push_back(InlayHint{LSPPos, (Prefix + Label + Suffix).str(), Kind,
656                                 PadLeft, PadRight, LSPRange});
657   }
658 
659   void addTypeHint(SourceRange R, QualType T, llvm::StringRef Prefix) {
660     addTypeHint(R, T, Prefix, TypeHintPolicy);
661   }
662 
663   void addTypeHint(SourceRange R, QualType T, llvm::StringRef Prefix,
664                    const PrintingPolicy &Policy) {
665     if (!Cfg.InlayHints.DeducedTypes || T.isNull())
666       return;
667 
668     std::string TypeName = T.getAsString(Policy);
669     if (TypeName.length() < TypeNameLimit)
670       addInlayHint(R, HintSide::Right, InlayHintKind::Type, Prefix, TypeName,
671                    /*Suffix=*/"");
672   }
673 
674   void addDesignatorHint(SourceRange R, llvm::StringRef Text) {
675     addInlayHint(R, HintSide::Left, InlayHintKind::Designator,
676                  /*Prefix=*/"", Text, /*Suffix=*/"=");
677   }
678 
679   std::vector<InlayHint> &Results;
680   ASTContext &AST;
681   const Config &Cfg;
682   llvm::Optional<Range> RestrictRange;
683   FileID MainFileID;
684   StringRef MainFileBuf;
685   const HeuristicResolver *Resolver;
686   // We want to suppress default template arguments, but otherwise print
687   // canonical types. Unfortunately, they're conflicting policies so we can't
688   // have both. For regular types, suppressing template arguments is more
689   // important, whereas printing canonical types is crucial for structured
690   // bindings, so we use two separate policies. (See the constructor where
691   // the policies are initialized for more details.)
692   PrintingPolicy TypeHintPolicy;
693   PrintingPolicy StructuredBindingPolicy;
694 
695   static const size_t TypeNameLimit = 32;
696 };
697 
698 } // namespace
699 
700 std::vector<InlayHint> inlayHints(ParsedAST &AST,
701                                   llvm::Optional<Range> RestrictRange) {
702   std::vector<InlayHint> Results;
703   const auto &Cfg = Config::current();
704   if (!Cfg.InlayHints.Enabled)
705     return Results;
706   InlayHintVisitor Visitor(Results, AST, Cfg, std::move(RestrictRange));
707   Visitor.TraverseAST(AST.getASTContext());
708 
709   // De-duplicate hints. Duplicates can sometimes occur due to e.g. explicit
710   // template instantiations.
711   llvm::sort(Results);
712   Results.erase(std::unique(Results.begin(), Results.end()), Results.end());
713 
714   return Results;
715 }
716 
717 } // namespace clangd
718 } // namespace clang
719