https://github.com/torshepherd updated 
https://github.com/llvm/llvm-project/pull/95712

>From 2c9e7c16524b7ce3bf818e451279722dc45d3efc Mon Sep 17 00:00:00 2001
From: Tor Shepherd <tor.aksel.sheph...@gmail.com>
Date: Mon, 23 Sep 2024 23:12:23 -0400
Subject: [PATCH 1/5] just defaults

---
 clang-tools-extra/clangd/Config.h             |  1 +
 clang-tools-extra/clangd/ConfigCompile.cpp    |  6 +-
 clang-tools-extra/clangd/ConfigFragment.h     |  3 +
 clang-tools-extra/clangd/ConfigYAML.cpp       |  5 +-
 clang-tools-extra/clangd/InlayHints.cpp       | 61 ++++++++++++++++++-
 clang-tools-extra/clangd/Protocol.cpp         |  3 +
 clang-tools-extra/clangd/Protocol.h           |  9 +++
 .../clangd/unittests/InlayHintTests.cpp       | 29 +++++++++
 8 files changed, 112 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index 41143b9ebc8d27..6fb846aa99437f 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -148,6 +148,7 @@ struct Config {
     bool DeducedTypes = true;
     bool Designators = true;
     bool BlockEnd = false;
+    bool DefaultArguments = false;
     // Limit the length of type names in inlay hints. (0 means no limit)
     uint32_t TypeNameLimit = 32;
   } InlayHints;
diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index f32f674443ffeb..81bc68e4e93d89 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -43,7 +43,6 @@
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/SMLoc.h"
 #include "llvm/Support/SourceMgr.h"
-#include <algorithm>
 #include <memory>
 #include <optional>
 #include <string>
@@ -654,6 +653,11 @@ struct FragmentCompiler {
       Out.Apply.push_back([Value(**F.BlockEnd)](const Params &, Config &C) {
         C.InlayHints.BlockEnd = Value;
       });
+    if (F.DefaultArguments)
+      Out.Apply.push_back(
+          [Value(**F.DefaultArguments)](const Params &, Config &C) {
+            C.InlayHints.DefaultArguments = Value;
+          });
     if (F.TypeNameLimit)
       Out.Apply.push_back(
           [Value(**F.TypeNameLimit)](const Params &, Config &C) {
diff --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index f3e51a9b6dbc4b..3a591e3062e355 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -331,6 +331,9 @@ struct Fragment {
     std::optional<Located<bool>> Designators;
     /// Show defined symbol names at the end of a definition block.
     std::optional<Located<bool>> BlockEnd;
+    /// Show parameter names and default values of default arguments after all
+    /// of the explicit arguments.
+    std::optional<Located<bool>> DefaultArguments;
     /// Limit the length of type name hints. (0 means no limit)
     std::optional<Located<uint32_t>> TypeNameLimit;
   };
diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp 
b/clang-tools-extra/clangd/ConfigYAML.cpp
index 3e9b6a07d3b325..ed90e6d648b1c2 100644
--- a/clang-tools-extra/clangd/ConfigYAML.cpp
+++ b/clang-tools-extra/clangd/ConfigYAML.cpp
@@ -14,7 +14,6 @@
 #include "llvm/Support/YAMLParser.h"
 #include <optional>
 #include <string>
-#include <system_error>
 
 namespace clang {
 namespace clangd {
@@ -264,6 +263,10 @@ class Parser {
       if (auto Value = boolValue(N, "BlockEnd"))
         F.BlockEnd = *Value;
     });
+    Dict.handle("DefaultArguments", [&](Node &N) {
+      if (auto Value = boolValue(N, "DefaultArguments"))
+        F.DefaultArguments = *Value;
+    });
     Dict.handle("TypeNameLimit", [&](Node &N) {
       if (auto Value = uint32Value(N, "TypeNameLimit"))
         F.TypeNameLimit = *Value;
diff --git a/clang-tools-extra/clangd/InlayHints.cpp 
b/clang-tools-extra/clangd/InlayHints.cpp
index cd4f1931b3ce1d..72fa92a81ce800 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -11,9 +11,11 @@
 #include "Config.h"
 #include "HeuristicResolver.h"
 #include "ParsedAST.h"
+#include "Protocol.h"
 #include "SourceCode.h"
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
@@ -23,15 +25,22 @@
 #include "clang/AST/Type.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/SaveAndRestore.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <iterator>
 #include <optional>
 #include <string>
 
@@ -372,6 +381,25 @@ maybeDropCxxExplicitObjectParameters(ArrayRef<const 
ParmVarDecl *> Params) {
   return Params;
 }
 
+template <typename R, typename P>
+std::string joinAndTruncate(R &&Range, size_t MaxLength,
+                            P &&GetAsStringFunction) {
+  std::string Out;
+  llvm::raw_string_ostream OS(Out);
+  llvm::ListSeparator Sep(", ");
+  for (auto &&Element : Range) {
+    OS << Sep;
+    auto AsString = GetAsStringFunction(Element);
+    if (Out.size() + AsString.size() >= MaxLength) {
+      OS << "...";
+      break;
+    }
+    OS << AsString;
+  }
+  OS.flush();
+  return Out;
+}
+
 struct Callee {
   // Only one of Decl or Loc is set.
   // Loc is for calls through function pointers.
@@ -422,7 +450,8 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
     Callee.Decl = E->getConstructor();
     if (!Callee.Decl)
       return true;
-    processCall(Callee, {E->getArgs(), E->getNumArgs()});
+    processCall(Callee, E->getParenOrBraceRange().getEnd(),
+                {E->getArgs(), E->getNumArgs()});
     return true;
   }
 
@@ -495,7 +524,7 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
             dyn_cast_or_null<CXXMethodDecl>(Callee.Decl))
       if (IsFunctor || Method->hasCXXExplicitFunctionObjectParameter())
         Args = Args.drop_front(1);
-    processCall(Callee, Args);
+    processCall(Callee, E->getRParenLoc(), Args);
     return true;
   }
 
@@ -709,7 +738,8 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
 private:
   using NameVec = SmallVector<StringRef, 8>;
 
-  void processCall(Callee Callee, llvm::ArrayRef<const Expr *> Args) {
+  void processCall(Callee Callee, SourceRange LParenOrBraceRange,
+                   llvm::ArrayRef<const Expr *> Args) {
     assert(Callee.Decl || Callee.Loc);
 
     if (!Cfg.InlayHints.Parameters || Args.size() == 0)
@@ -721,6 +751,9 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
         if (Ctor->isCopyOrMoveConstructor())
           return;
 
+    SmallVector<std::string> FormattedDefaultArgs;
+    bool HasNonDefaultArgs = false;
+
     ArrayRef<const ParmVarDecl *> Params, ForwardedParams;
     // Resolve parameter packs to their forwarded parameter
     SmallVector<const ParmVarDecl *> ForwardedParamsStorage;
@@ -755,12 +788,33 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
       bool NameHint = shouldHintName(Args[I], Name);
       bool ReferenceHint = shouldHintReference(Params[I], ForwardedParams[I]);
 
+      bool IsDefault = isa<CXXDefaultArgExpr>(Args[I]);
+      HasNonDefaultArgs |= !IsDefault;
+      if (Cfg.InlayHints.DefaultArguments && IsDefault) {
+        auto SourceText = Lexer::getSourceText(
+            CharSourceRange::getTokenRange(Params[I]->getDefaultArgRange()),
+            AST.getSourceManager(), AST.getLangOpts());
+        FormattedDefaultArgs.emplace_back(llvm::formatv(
+            "{0}: {1}", Name,
+            SourceText.size() > Cfg.InlayHints.TypeNameLimit ? "..."
+                                                             : SourceText));
+      }
+
       if (NameHint || ReferenceHint) {
         addInlayHint(Args[I]->getSourceRange(), HintSide::Left,
                      InlayHintKind::Parameter, ReferenceHint ? "&" : "",
                      NameHint ? Name : "", ": ");
       }
     }
+
+    if (!FormattedDefaultArgs.empty()) {
+      std::string Hint =
+          joinAndTruncate(FormattedDefaultArgs, Cfg.InlayHints.TypeNameLimit,
+                          [](const auto &E) { return E; });
+      addInlayHint(LParenOrBraceRange, HintSide::Left,
+                   InlayHintKind::DefaultArgument,
+                   HasNonDefaultArgs ? ", " : "", Hint, "");
+    }
   }
 
   static bool isSetter(const FunctionDecl *Callee, const NameVec &ParamNames) {
@@ -968,6 +1022,7 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
       CHECK_KIND(Type, DeducedTypes);
       CHECK_KIND(Designator, Designators);
       CHECK_KIND(BlockEnd, BlockEnd);
+      CHECK_KIND(DefaultArgument, DefaultArguments);
 #undef CHECK_KIND
     }
 
diff --git a/clang-tools-extra/clangd/Protocol.cpp 
b/clang-tools-extra/clangd/Protocol.cpp
index c08f80442eaa06..295ccd26a40454 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -1477,6 +1477,7 @@ llvm::json::Value toJSON(const InlayHintKind &Kind) {
     return 2;
   case InlayHintKind::Designator:
   case InlayHintKind::BlockEnd:
+  case InlayHintKind::DefaultArgument:
     // This is an extension, don't serialize.
     return nullptr;
   }
@@ -1517,6 +1518,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 
InlayHintKind Kind) {
       return "designator";
     case InlayHintKind::BlockEnd:
       return "block-end";
+    case InlayHintKind::DefaultArgument:
+      return "default-argument";
     }
     llvm_unreachable("Unknown clang.clangd.InlayHintKind");
   };
diff --git a/clang-tools-extra/clangd/Protocol.h 
b/clang-tools-extra/clangd/Protocol.h
index a0f8b04bc4ffdb..52ca9f9afcfbf0 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -1681,6 +1681,15 @@ enum class InlayHintKind {
   /// This is a clangd extension.
   BlockEnd = 4,
 
+  /// An inlay hint that is for a default argument.
+  ///
+  /// An example of a parameter hint for a default argument:
+  ///    void foo(bool A = true);
+  ///    foo(^);
+  /// Adds an inlay hint "A = true".
+  /// This is a clangd extension.
+  DefaultArgument = 6,
+
   /// Other ideas for hints that are not currently implemented:
   ///
   /// * Chaining hints, showing the types of intermediate expressions
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp 
b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index a5a349e93037ad..a4c1ed388b7331 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -15,9 +15,12 @@
 #include "support/Context.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/raw_ostream.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include <optional>
 #include <string>
+#include <utility>
 #include <vector>
 
 namespace clang {
@@ -81,6 +84,7 @@ Config noHintsConfig() {
   C.InlayHints.DeducedTypes = false;
   C.InlayHints.Designators = false;
   C.InlayHints.BlockEnd = false;
+  C.InlayHints.DefaultArguments = false;
   return C;
 }
 
@@ -1465,6 +1469,31 @@ TEST(TypeHints, DefaultTemplateArgs) {
                   ExpectedHint{": A<float>", "binding"});
 }
 
+TEST(DefaultArguments, Smoke) {
+  Config Cfg;
+  Cfg.InlayHints.Parameters =
+      true; // To test interplay of parameters and default parameters
+  Cfg.InlayHints.DeducedTypes = false;
+  Cfg.InlayHints.Designators = false;
+  Cfg.InlayHints.BlockEnd = false;
+
+  Cfg.InlayHints.DefaultArguments = true;
+  WithContextValue WithCfg(Config::Key, std::move(Cfg));
+
+  const auto *Code = R"cpp(
+    int foo(int A = 4) { return A; }
+    int bar(int A, int B = 1, bool C = foo($default1[[)]]) { return A; }
+    int A = bar($explicit[[2]]$default2[[)]];
+  )cpp";
+
+  assertHints(InlayHintKind::DefaultArgument, Code,
+              ExpectedHint{"A: 4", "default1", Left},
+              ExpectedHint{", B: 1, C: foo()", "default2", Left});
+
+  assertHints(InlayHintKind::Parameter, Code,
+              ExpectedHint{"A: ", "explicit", Left});
+}
+
 TEST(TypeHints, Deduplication) {
   assertTypeHints(R"cpp(
     template <typename T>

>From 314253b393c683fa481ac9a13dec3ca0da27a46d Mon Sep 17 00:00:00 2001
From: Tor Shepherd <tor.aksel.sheph...@gmail.com>
Date: Mon, 30 Sep 2024 13:47:59 -0400
Subject: [PATCH 2/5] Fix hints for unnamed

---
 clang-tools-extra/clangd/InlayHints.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clangd/InlayHints.cpp 
b/clang-tools-extra/clangd/InlayHints.cpp
index 72fa92a81ce800..e7141ad0764b30 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -738,7 +738,7 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
 private:
   using NameVec = SmallVector<StringRef, 8>;
 
-  void processCall(Callee Callee, SourceRange LParenOrBraceRange,
+  void processCall(Callee Callee, SourceRange RParenOrBraceRange,
                    llvm::ArrayRef<const Expr *> Args) {
     assert(Callee.Decl || Callee.Loc);
 
@@ -795,7 +795,7 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
             CharSourceRange::getTokenRange(Params[I]->getDefaultArgRange()),
             AST.getSourceManager(), AST.getLangOpts());
         FormattedDefaultArgs.emplace_back(llvm::formatv(
-            "{0}: {1}", Name,
+            "{0}: {1}", Name.empty() ? "/*unused*/" : Name,
             SourceText.size() > Cfg.InlayHints.TypeNameLimit ? "..."
                                                              : SourceText));
       }
@@ -811,7 +811,7 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
       std::string Hint =
           joinAndTruncate(FormattedDefaultArgs, Cfg.InlayHints.TypeNameLimit,
                           [](const auto &E) { return E; });
-      addInlayHint(LParenOrBraceRange, HintSide::Left,
+      addInlayHint(RParenOrBraceRange, HintSide::Left,
                    InlayHintKind::DefaultArgument,
                    HasNonDefaultArgs ? ", " : "", Hint, "");
     }

>From 4aff731a7d56247209bf5cb47c5f2a0404ddc712 Mon Sep 17 00:00:00 2001
From: Tor Shepherd <tor.aksel.sheph...@gmail.com>
Date: Mon, 30 Sep 2024 14:18:09 -0400
Subject: [PATCH 3/5] fixes

---
 clang-tools-extra/clangd/InlayHints.cpp       | 21 ++++++++++++-------
 .../clangd/unittests/InlayHintTests.cpp       |  5 ++++-
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/clang-tools-extra/clangd/InlayHints.cpp 
b/clang-tools-extra/clangd/InlayHints.cpp
index e7141ad0764b30..66fef43e6728e8 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -785,19 +785,24 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
       }
 
       StringRef Name = ParameterNames[I];
-      bool NameHint = shouldHintName(Args[I], Name);
-      bool ReferenceHint = shouldHintReference(Params[I], ForwardedParams[I]);
+      const bool NameHint = shouldHintName(Args[I], Name);
+      const bool ReferenceHint =
+          shouldHintReference(Params[I], ForwardedParams[I]);
 
-      bool IsDefault = isa<CXXDefaultArgExpr>(Args[I]);
+      const bool IsDefault = isa<CXXDefaultArgExpr>(Args[I]);
       HasNonDefaultArgs |= !IsDefault;
       if (Cfg.InlayHints.DefaultArguments && IsDefault) {
-        auto SourceText = Lexer::getSourceText(
+        const auto SourceText = Lexer::getSourceText(
             CharSourceRange::getTokenRange(Params[I]->getDefaultArgRange()),
             AST.getSourceManager(), AST.getLangOpts());
-        FormattedDefaultArgs.emplace_back(llvm::formatv(
-            "{0}: {1}", Name.empty() ? "/*unused*/" : Name,
-            SourceText.size() > Cfg.InlayHints.TypeNameLimit ? "..."
-                                                             : SourceText));
+        const auto Abbrev = SourceText.size() > Cfg.InlayHints.TypeNameLimit
+                                ? "..."
+                                : SourceText;
+        if (NameHint)
+          FormattedDefaultArgs.emplace_back(
+              llvm::formatv("{0}: {1}", Name, Abbrev));
+        else
+          FormattedDefaultArgs.emplace_back(llvm::formatv("{0}", Abbrev));
       }
 
       if (NameHint || ReferenceHint) {
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp 
b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index a4c1ed388b7331..cfdabf78d25348 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -1484,11 +1484,14 @@ TEST(DefaultArguments, Smoke) {
     int foo(int A = 4) { return A; }
     int bar(int A, int B = 1, bool C = foo($default1[[)]]) { return A; }
     int A = bar($explicit[[2]]$default2[[)]];
+
+    void baz(int = 5) { if (false) baz($unnamed[[)]]; };
   )cpp";
 
   assertHints(InlayHintKind::DefaultArgument, Code,
               ExpectedHint{"A: 4", "default1", Left},
-              ExpectedHint{", B: 1, C: foo()", "default2", Left});
+              ExpectedHint{", B: 1, C: foo()", "default2", Left},
+              ExpectedHint{"5", "unnamed", Left});
 
   assertHints(InlayHintKind::Parameter, Code,
               ExpectedHint{"A: ", "explicit", Left});

>From fa5e8d62e817aba58cc3fbd4b3a42163607ce9ff Mon Sep 17 00:00:00 2001
From: Tor Shepherd <tor.aksel.sheph...@gmail.com>
Date: Mon, 30 Sep 2024 14:34:50 -0400
Subject: [PATCH 4/5] if

---
 clang-tools-extra/clangd/InlayHints.cpp | 30 ++++++++++++-------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/clang-tools-extra/clangd/InlayHints.cpp 
b/clang-tools-extra/clangd/InlayHints.cpp
index 66fef43e6728e8..3a63f65187bd23 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -791,21 +791,21 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
 
       const bool IsDefault = isa<CXXDefaultArgExpr>(Args[I]);
       HasNonDefaultArgs |= !IsDefault;
-      if (Cfg.InlayHints.DefaultArguments && IsDefault) {
-        const auto SourceText = Lexer::getSourceText(
-            CharSourceRange::getTokenRange(Params[I]->getDefaultArgRange()),
-            AST.getSourceManager(), AST.getLangOpts());
-        const auto Abbrev = SourceText.size() > Cfg.InlayHints.TypeNameLimit
-                                ? "..."
-                                : SourceText;
-        if (NameHint)
-          FormattedDefaultArgs.emplace_back(
-              llvm::formatv("{0}: {1}", Name, Abbrev));
-        else
-          FormattedDefaultArgs.emplace_back(llvm::formatv("{0}", Abbrev));
-      }
-
-      if (NameHint || ReferenceHint) {
+      if (IsDefault) {
+        if (Cfg.InlayHints.DefaultArguments) {
+          const auto SourceText = Lexer::getSourceText(
+              CharSourceRange::getTokenRange(Params[I]->getDefaultArgRange()),
+              AST.getSourceManager(), AST.getLangOpts());
+          const auto Abbrev = SourceText.size() > Cfg.InlayHints.TypeNameLimit
+                                  ? "..."
+                                  : SourceText;
+          if (NameHint)
+            FormattedDefaultArgs.emplace_back(
+                llvm::formatv("{0}: {1}", Name, Abbrev));
+          else
+            FormattedDefaultArgs.emplace_back(llvm::formatv("{0}", Abbrev));
+        }
+      } else if (NameHint || ReferenceHint) {
         addInlayHint(Args[I]->getSourceRange(), HintSide::Left,
                      InlayHintKind::Parameter, ReferenceHint ? "&" : "",
                      NameHint ? Name : "", ": ");

>From a1c88ade4aa44226df6353254d2904c7d5559baf Mon Sep 17 00:00:00 2001
From: Tor Shepherd <tor.aksel.sheph...@gmail.com>
Date: Mon, 14 Oct 2024 12:55:52 -0400
Subject: [PATCH 5/5] Comments and partial refactor

---
 clang-tools-extra/clangd/InlayHints.cpp       | 34 +++++++--------
 clang-tools-extra/clangd/Protocol.h           |  2 +-
 .../clangd/unittests/InlayHintTests.cpp       | 41 +++++++++++++++++++
 3 files changed, 60 insertions(+), 17 deletions(-)

diff --git a/clang-tools-extra/clangd/InlayHints.cpp 
b/clang-tools-extra/clangd/InlayHints.cpp
index 3a63f65187bd23..c4053fced81d6f 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -381,20 +381,18 @@ maybeDropCxxExplicitObjectParameters(ArrayRef<const 
ParmVarDecl *> Params) {
   return Params;
 }
 
-template <typename R, typename P>
-std::string joinAndTruncate(R &&Range, size_t MaxLength,
-                            P &&GetAsStringFunction) {
+template <typename R>
+std::string joinAndTruncate(const R &Range, size_t MaxLength) {
   std::string Out;
   llvm::raw_string_ostream OS(Out);
   llvm::ListSeparator Sep(", ");
   for (auto &&Element : Range) {
     OS << Sep;
-    auto AsString = GetAsStringFunction(Element);
-    if (Out.size() + AsString.size() >= MaxLength) {
+    if (Out.size() + Element.size() >= MaxLength) {
       OS << "...";
       break;
     }
-    OS << AsString;
+    OS << Element;
   }
   OS.flush();
   return Out;
@@ -738,11 +736,12 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
 private:
   using NameVec = SmallVector<StringRef, 8>;
 
-  void processCall(Callee Callee, SourceRange RParenOrBraceRange,
+  void processCall(Callee Callee, SourceLocation RParenOrBraceLoc,
                    llvm::ArrayRef<const Expr *> Args) {
     assert(Callee.Decl || Callee.Loc);
 
-    if (!Cfg.InlayHints.Parameters || Args.size() == 0)
+    if ((!Cfg.InlayHints.Parameters && !Cfg.InlayHints.DefaultArguments) ||
+        Args.size() == 0)
       return;
 
     // The parameter name of a move or copy constructor is not very 
interesting.
@@ -785,9 +784,11 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
       }
 
       StringRef Name = ParameterNames[I];
-      const bool NameHint = shouldHintName(Args[I], Name);
+      const bool NameHint =
+          shouldHintName(Args[I], Name) && Cfg.InlayHints.Parameters;
       const bool ReferenceHint =
-          shouldHintReference(Params[I], ForwardedParams[I]);
+          shouldHintReference(Params[I], ForwardedParams[I]) &&
+          Cfg.InlayHints.Parameters;
 
       const bool IsDefault = isa<CXXDefaultArgExpr>(Args[I]);
       HasNonDefaultArgs |= !IsDefault;
@@ -796,9 +797,11 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
           const auto SourceText = Lexer::getSourceText(
               CharSourceRange::getTokenRange(Params[I]->getDefaultArgRange()),
               AST.getSourceManager(), AST.getLangOpts());
-          const auto Abbrev = SourceText.size() > Cfg.InlayHints.TypeNameLimit
-                                  ? "..."
-                                  : SourceText;
+          const auto Abbrev =
+              (SourceText.size() > Cfg.InlayHints.TypeNameLimit ||
+               SourceText.contains("\n"))
+                  ? "..."
+                  : SourceText;
           if (NameHint)
             FormattedDefaultArgs.emplace_back(
                 llvm::formatv("{0}: {1}", Name, Abbrev));
@@ -814,9 +817,8 @@ class InlayHintVisitor : public 
RecursiveASTVisitor<InlayHintVisitor> {
 
     if (!FormattedDefaultArgs.empty()) {
       std::string Hint =
-          joinAndTruncate(FormattedDefaultArgs, Cfg.InlayHints.TypeNameLimit,
-                          [](const auto &E) { return E; });
-      addInlayHint(RParenOrBraceRange, HintSide::Left,
+          joinAndTruncate(FormattedDefaultArgs, Cfg.InlayHints.TypeNameLimit);
+      addInlayHint(SourceRange{RParenOrBraceLoc}, HintSide::Left,
                    InlayHintKind::DefaultArgument,
                    HasNonDefaultArgs ? ", " : "", Hint, "");
     }
diff --git a/clang-tools-extra/clangd/Protocol.h 
b/clang-tools-extra/clangd/Protocol.h
index 52ca9f9afcfbf0..5b28095758198d 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -1686,7 +1686,7 @@ enum class InlayHintKind {
   /// An example of a parameter hint for a default argument:
   ///    void foo(bool A = true);
   ///    foo(^);
-  /// Adds an inlay hint "A = true".
+  /// Adds an inlay hint "A: true".
   /// This is a clangd extension.
   DefaultArgument = 6,
 
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp 
b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index cfdabf78d25348..ebd002ba917fb5 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -1497,6 +1497,47 @@ TEST(DefaultArguments, Smoke) {
               ExpectedHint{"A: ", "explicit", Left});
 }
 
+TEST(DefaultArguments, WithoutParameterNames) {
+  Config Cfg;
+  Cfg.InlayHints.Parameters = false; // To test just default args this time
+  Cfg.InlayHints.DeducedTypes = false;
+  Cfg.InlayHints.Designators = false;
+  Cfg.InlayHints.BlockEnd = false;
+
+  Cfg.InlayHints.DefaultArguments = true;
+  WithContextValue WithCfg(Config::Key, std::move(Cfg));
+
+  const auto *Code = R"cpp(
+    struct Baz {
+      Baz(float a = 3 //
+                    + 2);
+    };
+    struct Foo {
+      Foo(int, Baz baz = //
+              Baz{$unnamed[[}]]
+
+          //
+      ) {}
+    };
+
+    int main() {
+      Foo foo1(1$paren[[)]];
+      Foo foo2{2$brace1[[}]];
+      Foo foo3 = {3$brace2[[}]];
+      auto foo4 = Foo{4$brace3[[}]];
+    }
+  )cpp";
+
+  assertHints(InlayHintKind::DefaultArgument, Code,
+              ExpectedHint{"...", "unnamed", Left},
+              ExpectedHint{", Baz{}", "paren", Left},
+              ExpectedHint{", Baz{}", "brace1", Left},
+              ExpectedHint{", Baz{}", "brace2", Left},
+              ExpectedHint{", Baz{}", "brace3", Left});
+
+  assertHints(InlayHintKind::Parameter, Code);
+}
+
 TEST(TypeHints, Deduplication) {
   assertTypeHints(R"cpp(
     template <typename T>

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to