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