1111#include " Config.h"
1212#include " HeuristicResolver.h"
1313#include " ParsedAST.h"
14+ #include " Protocol.h"
1415#include " SourceCode.h"
1516#include " clang/AST/ASTDiagnostic.h"
1617#include " clang/AST/Decl.h"
18+ #include " clang/AST/DeclBase.h"
1719#include " clang/AST/DeclarationName.h"
1820#include " clang/AST/Expr.h"
1921#include " clang/AST/ExprCXX.h"
2325#include " clang/AST/Type.h"
2426#include " clang/Basic/Builtins.h"
2527#include " clang/Basic/OperatorKinds.h"
28+ #include " clang/Basic/SourceLocation.h"
2629#include " clang/Basic/SourceManager.h"
2730#include " llvm/ADT/DenseSet.h"
31+ #include " llvm/ADT/STLExtras.h"
32+ #include " llvm/ADT/SmallVector.h"
2833#include " llvm/ADT/StringExtras.h"
2934#include " llvm/ADT/StringRef.h"
3035#include " llvm/ADT/Twine.h"
3136#include " llvm/Support/Casting.h"
37+ #include " llvm/Support/ErrorHandling.h"
38+ #include " llvm/Support/FormatVariadic.h"
3239#include " llvm/Support/SaveAndRestore.h"
3340#include " llvm/Support/ScopedPrinter.h"
3441#include " llvm/Support/raw_ostream.h"
42+ #include < algorithm>
43+ #include < iterator>
3544#include < optional>
3645#include < string>
3746
@@ -372,6 +381,25 @@ maybeDropCxxExplicitObjectParameters(ArrayRef<const ParmVarDecl *> Params) {
372381 return Params;
373382}
374383
384+ template <typename R, typename P>
385+ std::string joinAndTruncate (R &&Range, size_t MaxLength,
386+ P &&GetAsStringFunction) {
387+ std::string Out;
388+ llvm::raw_string_ostream OS (Out);
389+ llvm::ListSeparator Sep (" , " );
390+ for (auto &&Element : Range) {
391+ OS << Sep;
392+ auto AsString = GetAsStringFunction (Element);
393+ if (Out.size () + AsString.size () >= MaxLength) {
394+ OS << " ..." ;
395+ break ;
396+ }
397+ OS << AsString;
398+ }
399+ OS.flush ();
400+ return Out;
401+ }
402+
375403struct Callee {
376404 // Only one of Decl or Loc is set.
377405 // Loc is for calls through function pointers.
@@ -422,7 +450,8 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
422450 Callee.Decl = E->getConstructor ();
423451 if (!Callee.Decl )
424452 return true ;
425- processCall (Callee, {E->getArgs (), E->getNumArgs ()});
453+ processCall (Callee, E->getParenOrBraceRange ().getEnd (),
454+ {E->getArgs (), E->getNumArgs ()});
426455 return true ;
427456 }
428457
@@ -495,7 +524,7 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
495524 dyn_cast_or_null<CXXMethodDecl>(Callee.Decl ))
496525 if (IsFunctor || Method->hasCXXExplicitFunctionObjectParameter ())
497526 Args = Args.drop_front (1 );
498- processCall (Callee, Args);
527+ processCall (Callee, E-> getRParenLoc (), Args);
499528 return true ;
500529 }
501530
@@ -709,7 +738,8 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
709738private:
710739 using NameVec = SmallVector<StringRef, 8 >;
711740
712- void processCall (Callee Callee, llvm::ArrayRef<const Expr *> Args) {
741+ void processCall (Callee Callee, SourceRange LParenOrBraceRange,
742+ llvm::ArrayRef<const Expr *> Args) {
713743 assert (Callee.Decl || Callee.Loc );
714744
715745 if (!Cfg.InlayHints .Parameters || Args.size () == 0 )
@@ -721,6 +751,9 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
721751 if (Ctor->isCopyOrMoveConstructor ())
722752 return ;
723753
754+ SmallVector<std::string> FormattedDefaultArgs;
755+ bool HasNonDefaultArgs = false ;
756+
724757 ArrayRef<const ParmVarDecl *> Params, ForwardedParams;
725758 // Resolve parameter packs to their forwarded parameter
726759 SmallVector<const ParmVarDecl *> ForwardedParamsStorage;
@@ -755,12 +788,33 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
755788 bool NameHint = shouldHintName (Args[I], Name);
756789 bool ReferenceHint = shouldHintReference (Params[I], ForwardedParams[I]);
757790
791+ bool IsDefault = isa<CXXDefaultArgExpr>(Args[I]);
792+ HasNonDefaultArgs |= !IsDefault;
793+ if (Cfg.InlayHints .DefaultArguments && IsDefault) {
794+ auto SourceText = Lexer::getSourceText (
795+ CharSourceRange::getTokenRange (Params[I]->getDefaultArgRange ()),
796+ AST.getSourceManager (), AST.getLangOpts ());
797+ FormattedDefaultArgs.emplace_back (llvm::formatv (
798+ " {0}: {1}" , Name,
799+ SourceText.size () > Cfg.InlayHints .TypeNameLimit ? " ..."
800+ : SourceText));
801+ }
802+
758803 if (NameHint || ReferenceHint) {
759804 addInlayHint (Args[I]->getSourceRange (), HintSide::Left,
760805 InlayHintKind::Parameter, ReferenceHint ? " &" : " " ,
761806 NameHint ? Name : " " , " : " );
762807 }
763808 }
809+
810+ if (!FormattedDefaultArgs.empty ()) {
811+ std::string Hint =
812+ joinAndTruncate (FormattedDefaultArgs, Cfg.InlayHints .TypeNameLimit ,
813+ [](const auto &E) { return E; });
814+ addInlayHint (LParenOrBraceRange, HintSide::Left,
815+ InlayHintKind::DefaultArgument,
816+ HasNonDefaultArgs ? " , " : " " , Hint, " " );
817+ }
764818 }
765819
766820 static bool isSetter (const FunctionDecl *Callee, const NameVec &ParamNames) {
@@ -968,6 +1022,7 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
9681022 CHECK_KIND (Type, DeducedTypes);
9691023 CHECK_KIND (Designator, Designators);
9701024 CHECK_KIND (BlockEnd, BlockEnd);
1025+ CHECK_KIND (DefaultArgument, DefaultArguments);
9711026#undef CHECK_KIND
9721027 }
9731028
0 commit comments