[clang-tools-extra] 962a202 - [clangd] Place deduced return type hints after noexcept (#219829)

via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 9 00:09:05 PDT 2026


Author: Machillka
Date: 2026-09-09T15:08:59+08:00
New Revision: 962a202be1f642f119921413293e8325e2e06757

URL: https://github.com/llvm/llvm-project/commit/962a202be1f642f119921413293e8325e2e06757
DIFF: https://github.com/llvm/llvm-project/commit/962a202be1f642f119921413293e8325e2e06757.diff

LOG: [clangd] Place deduced return type hints after noexcept (#219829)

Deduced return type hints for functions and lambdas could appear before
a `noexcept` specifier, even though a trailing return type belongs after
the exception specification.

Use the end of the function type's local source range when it is
available. For lambdas without a function type location, keep the end of
the lambda introducer as a fallback.

Fixes clangd/clangd#2696

Assisted-by: Codex

Added: 
    

Modified: 
    clang-tools-extra/clangd/InlayHints.cpp
    clang-tools-extra/clangd/unittests/InlayHintTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp
index 5bae4cc040210..e982c2c2f1974 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -504,7 +504,7 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
             llvm::dyn_cast<FunctionProtoType>(D->getType().getTypePtr())) {
       if (!FPT->hasTrailingReturn()) {
         if (auto FTL = D->getFunctionTypeLoc())
-          addReturnTypeHint(D, FTL.getRParenLoc());
+          addReturnTypeHint(D, FTL.getLocalRangeEnd());
       }
     }
     if (Cfg.InlayHints.BlockEnd && D->isThisDeclarationADefinition()) {
@@ -601,10 +601,10 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
     FunctionDecl *D = E->getCallOperator();
     if (!E->hasExplicitResultType()) {
       SourceLocation TypeHintLoc;
-      if (!E->hasExplicitParameters())
+      if (auto FTL = D->getFunctionTypeLoc())
+        TypeHintLoc = FTL.getLocalRangeEnd();
+      else if (!E->hasExplicitParameters())
         TypeHintLoc = E->getIntroducerRange().getEnd();
-      else if (auto FTL = D->getFunctionTypeLoc())
-        TypeHintLoc = FTL.getRParenLoc();
       if (TypeHintLoc.isValid())
         addReturnTypeHint(D, TypeHintLoc);
     }

diff  --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index f5813ecc4dff5..ed074a3d7a0d6 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -1333,6 +1333,17 @@ TEST(TypeHints, Lambda) {
   assertTypeHints("auto $L[[x]] = <:$ret[[:>]]{return 42;};",
                   ExpectedHint{": (lambda)", "L"},
                   ExpectedHint{"-> int", "ret"});
+
+  // The return type follows the noexcept specifier in a lambda declarator.
+  // https://github.com/clangd/clangd/issues/2696
+  assertTypeHints(R"cpp(
+    void f() {
+      []() $ret[[noexcept]] {};
+      [] $retNoParams[[noexcept]] {};
+    }
+  )cpp",
+                  ExpectedHint{"-> void", "ret"},
+                  ExpectedHint{"-> void", "retNoParams"});
 }
 
 // Structured bindings tests.
@@ -1427,6 +1438,8 @@ TEST(TypeHints, ReturnTypeDeduction) {
 
     auto f5($noreturn[[)]] {}
 
+    auto f6() $retNoexcept[[noexcept]] { return 42; }
+
     // `auto` conversion operator
     struct A {
       operator auto($retConv[[)]] { return 42; }
@@ -1440,7 +1453,7 @@ TEST(TypeHints, ReturnTypeDeduction) {
   )cpp",
       ExpectedHint{"-> int", "ret1a"}, ExpectedHint{"-> int", "ret1b"},
       ExpectedHint{"-> int &", "ret2"}, ExpectedHint{"-> void", "noreturn"},
-      ExpectedHint{"-> int", "retConv"});
+      ExpectedHint{"-> int", "retNoexcept"}, ExpectedHint{"-> int", "retConv"});
 }
 
 TEST(TypeHints, DependentType) {


        


More information about the cfe-commits mailing list