Author: Oliver Hunt
Date: 2025-06-03T17:57:01-07:00
New Revision: f72054a0ccecb88c694713c44f3f42352d2340a2

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

LOG: [clang] Correct FixIt ranges for unused capture warnings (#141148)

Fixes #106445 by using the lexer to find the correct range for the
removal FixIts. Previously the ranges that were generated assuming no
unsurprising formatting, which for the most part works. Being correct in
all cases requires using the lexer to find the bounding tokens for the
region to remove.

As part of this it adds Sema::getRangeForNextToken to wrap
Lexer::findNextToken.

Added: 
    clang/test/FixIt/fixit-unused-lambda-capture-trailing-tokens.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Sema/Sema.h
    clang/lib/Sema/Sema.cpp
    clang/lib/Sema/SemaLambda.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 49ce9ef938fe9..d6b994d36df8a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -612,6 +612,8 @@ Improvements to Clang's diagnostics
   diagnostic group ``-Wimplicit-int-comparison-on-negation``, grouped under
   ``-Wimplicit-int-conversion``, so user can turn it off independently.
 
+- Improved the FixIts for unused lambda captures.
+
 Improvements to Clang's time-trace
 ----------------------------------
 

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 8040f1ac6af01..84d30561fecde 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -972,6 +972,13 @@ class Sema final : public SemaBase {
   /// Calls \c Lexer::getLocForEndOfToken()
   SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0);
 
+  /// Calls \c Lexer::findNextToken() to find the next token, and if the
+  /// locations of both ends of the token can be resolved it return that
+  /// range; Otherwise it returns an invalid SourceRange.
+  SourceRange getRangeForNextToken(
+      SourceLocation Loc, bool IncludeMacros, bool IncludeComments,
+      std::optional<tok::TokenKind> ExpectedToken = std::nullopt);
+
   /// Retrieve the module loader associated with the preprocessor.
   ModuleLoader &getModuleLoader() const;
 
@@ -9134,6 +9141,7 @@ class Sema final : public SemaBase {
   /// Diagnose if an explicit lambda capture is unused. Returns true if a
   /// diagnostic is emitted.
   bool DiagnoseUnusedLambdaCapture(SourceRange CaptureRange,
+                                   SourceRange FixItRange,
                                    const sema::Capture &From);
 
   /// Build a FieldDecl suitable to hold the given capture.

diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 925f2d455f745..370ade6dea7a1 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -84,6 +84,28 @@ SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, 
unsigned Offset) {
   return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
 }
 
+SourceRange
+Sema::getRangeForNextToken(SourceLocation Loc, bool IncludeMacros,
+                           bool IncludeComments,
+                           std::optional<tok::TokenKind> ExpectedToken) {
+  if (!Loc.isValid())
+    return SourceRange();
+  std::optional<Token> NextToken =
+      Lexer::findNextToken(Loc, SourceMgr, LangOpts, IncludeComments);
+  if (!NextToken)
+    return SourceRange();
+  if (ExpectedToken && NextToken->getKind() != *ExpectedToken)
+    return SourceRange();
+  SourceLocation TokenStart = NextToken->getLocation();
+  SourceLocation TokenEnd = NextToken->getLastLoc();
+  if (!TokenStart.isValid() || !TokenEnd.isValid())
+    return SourceRange();
+  if (!IncludeMacros && (TokenStart.isMacroID() || TokenEnd.isMacroID()))
+    return SourceRange();
+
+  return SourceRange(TokenStart, TokenEnd);
+}
+
 ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); }
 
 DarwinSDKInfo *

diff  --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index aad16290422f5..2c00616bc62d7 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -2022,6 +2022,7 @@ bool Sema::CaptureHasSideEffects(const Capture &From) {
 }
 
 bool Sema::DiagnoseUnusedLambdaCapture(SourceRange CaptureRange,
+                                       SourceRange FixItRange,
                                        const Capture &From) {
   if (CaptureHasSideEffects(From))
     return false;
@@ -2041,7 +2042,12 @@ bool Sema::DiagnoseUnusedLambdaCapture(SourceRange 
CaptureRange,
   else
     diag << From.getVariable();
   diag << From.isNonODRUsed();
-  diag << FixItHint::CreateRemoval(CaptureRange);
+  // If we were able to resolve the fixit range we'll create a fixit,
+  // otherwise we just use the raw capture range for the diagnostic.
+  if (FixItRange.isValid())
+    diag << FixItHint::CreateRemoval(FixItRange);
+  else
+    diag << CaptureRange;
   return true;
 }
 
@@ -2095,6 +2101,39 @@ FieldDecl *Sema::BuildCaptureField(RecordDecl *RD,
   return Field;
 }
 
+static SourceRange
+ConstructFixItRangeForUnusedCapture(Sema &S, SourceRange CaptureRange,
+                                    SourceLocation PrevCaptureLoc,
+                                    bool CurHasPreviousCapture, bool IsLast) {
+  if (!CaptureRange.isValid())
+    return SourceRange();
+
+  auto GetTrailingEndLocation = [&](SourceLocation StartPoint) {
+    SourceRange NextToken = S.getRangeForNextToken(
+        StartPoint, /*IncludeMacros=*/false, /*IncludeComments=*/true);
+    if (!NextToken.isValid())
+      return SourceLocation();
+    // Return the last location preceding the next token
+    return NextToken.getBegin().getLocWithOffset(-1);
+  };
+
+  if (!CurHasPreviousCapture && !IsLast) {
+    // If there are no captures preceding this capture, remove the
+    // trailing comma and anything up to the next token
+    SourceRange CommaRange =
+        S.getRangeForNextToken(CaptureRange.getEnd(), /*IncludeMacros=*/false,
+                               /*IncludeComments=*/false, tok::comma);
+    SourceLocation FixItEnd = GetTrailingEndLocation(CommaRange.getBegin());
+    return SourceRange(CaptureRange.getBegin(), FixItEnd);
+  }
+
+  // Otherwise, remove the comma since the last used capture, and
+  // anything up to the next token
+  SourceLocation FixItStart = S.getLocForEndOfToken(PrevCaptureLoc);
+  SourceLocation FixItEnd = GetTrailingEndLocation(CaptureRange.getEnd());
+  return SourceRange(FixItStart, FixItEnd);
+}
+
 ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation 
EndLoc,
                                  LambdaScopeInfo *LSI) {
   // Collect information from the lambda scope.
@@ -2162,21 +2201,11 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation 
StartLoc, SourceLocation EndLoc,
             IsGenericLambda && From.isNonODRUsed() && From.isInitCapture();
         if (!NonODRUsedInitCapture) {
           bool IsLast = (I + 1) == LSI->NumExplicitCaptures;
-          SourceRange FixItRange;
-          if (CaptureRange.isValid()) {
-            if (!CurHasPreviousCapture && !IsLast) {
-              // If there are no captures preceding this capture, remove the
-              // following comma.
-              FixItRange = SourceRange(CaptureRange.getBegin(),
-                                       
getLocForEndOfToken(CaptureRange.getEnd()));
-            } else {
-              // Otherwise, remove the comma since the last used capture.
-              FixItRange = SourceRange(getLocForEndOfToken(PrevCaptureLoc),
-                                       CaptureRange.getEnd());
-            }
-          }
-
-          IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From);
+          SourceRange FixItRange = ConstructFixItRangeForUnusedCapture(
+              *this, CaptureRange, PrevCaptureLoc, CurHasPreviousCapture,
+              IsLast);
+          IsCaptureUsed =
+              !DiagnoseUnusedLambdaCapture(CaptureRange, FixItRange, From);
         }
       }
 

diff  --git a/clang/test/FixIt/fixit-unused-lambda-capture-trailing-tokens.cpp 
b/clang/test/FixIt/fixit-unused-lambda-capture-trailing-tokens.cpp
new file mode 100644
index 0000000000000..80250e6d1851f
--- /dev/null
+++ b/clang/test/FixIt/fixit-unused-lambda-capture-trailing-tokens.cpp
@@ -0,0 +1,491 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -x c++ -Wunused-lambda-capture -Wno-unused-value -std=c++1z 
-fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+// RUN: %clang_cc1 -x c++ -Wunused-lambda-capture -Wno-unused-value -std=c++1z 
-fsyntax-only %s 2>&1 | FileCheck --match-full-lines --strict-whitespace 
--check-prefix POINTER %s
+
+
+#define MACRO_CAPTURE(...) __VA_ARGS__
+#define M_A a
+#define M_B b
+
+int main() {
+    int a = 0, b = 0, c = 0, d = 0;
+    auto F0 = [a, &b]() mutable {
+    // CHECK: auto F0 = [a]()
+         // POINTER:{{^.*}}|     auto F0 = [a, &b]() mutable {
+    // POINTER-NEXT:{{^.*}}|                 ~~~^
+
+        a++;
+    };
+
+    auto F1 = [&a, &b]() {
+    // CHECK: auto F1 = []() {
+         // POINTER:{{^.*}}|     auto F1 = [&a, &b]() {
+    // POINTER-NEXT:{{^.*}}|                ~^~
+         // POINTER:{{^.*}}|     auto F1 = [&a, &b]() {
+    // POINTER-NEXT:{{^.*}}|                  ~~~^
+    };
+
+    auto F2 = [&a, b]() {
+    // CHECK: auto F2 = []() {
+         // POINTER:{{^.*}}|     auto F2 = [&a, b]() {
+    // POINTER-NEXT:{{^.*}}|                ~^~
+         // POINTER:{{^.*}}|     auto F2 = [&a, b]() {
+    // POINTER-NEXT:{{^.*}}|                  ~~^
+    };
+
+    auto F3 = [&a,
+         &b]() {
+    // CHECK: auto F3 = []() {
+         // POINTER:{{^.*}}|     auto F3 = [&a,
+    // POINTER-NEXT:{{^.*}}|                ~^~
+    // POINTER-NEXT:{{^.*}}|          &b]() {
+         // POINTER:{{^.*}}|     auto F3 = [&a,
+    // POINTER-NEXT:{{^.*}}|                  ~
+    // POINTER-NEXT:{{^.*}}|          &b]() {
+    // POINTER-NEXT:{{^.*}}|          ~^
+
+    };
+
+    auto F4 = [&a
+        , &b]() {
+    // CHECK: auto F4 = []() {
+         // POINTER:{{^.*}}|     auto F4 = [&a
+    // POINTER-NEXT:{{^.*}}|                ~^
+    // POINTER-NEXT:{{^.*}}|         , &b]() {
+    // POINTER-NEXT:{{^.*}}|         ~
+         // POINTER:{{^.*}}|     auto F4 = [&a
+    // POINTER-NEXT:{{^.*}}|                  {{$}}
+    // POINTER-NEXT:{{^.*}}|         , &b]() {
+    // POINTER-NEXT:{{^.*}}|         ~~~^
+    };
+    auto F5 = [&a ,&b]()  {
+    // CHECK: auto F5 = []() {
+         // POINTER:{{^.*}}|     auto F5 = [&a ,&b]()  {
+    // POINTER-NEXT:{{^.*}}|                ~^~~
+         // POINTER:{{^.*}}|     auto F5 = [&a ,&b]()  {
+    // POINTER-NEXT:{{^.*}}|                   ~~^
+    };
+
+    auto F0a = [a, &b]() mutable {
+    // CHECK: auto F0a = [a]() mutable {
+         // POINTER:{{^.*}}|     auto F0a = [a, &b]() mutable {
+    // POINTER-NEXT:{{^.*}}|                  ~~~^
+        a++;
+    };
+
+    auto F1a = [&a, &b]() {
+    // CHECK: auto F1a = [&a]() {
+         // POINTER:{{^.*}}|     auto F1a = [&a, &b]() {
+    // POINTER-NEXT:{{^.*}}|                   ~~~^
+        a++;
+    };
+
+    auto F2a = [&a, b]() {
+    // CHECK: auto F2a = [&a]() {
+         // POINTER:{{^.*}}|     auto F2a = [&a, b]() {
+    // POINTER-NEXT:{{^.*}}|                   ~~^
+        a++;
+    };
+
+    auto F3a = [&a,
+         &b]() {
+    // CHECK: auto F3a = [&a]() {
+         // POINTER:{{^.*}}|     auto F3a = [&a,
+    // POINTER-NEXT:{{^.*}}|                   ~
+    // POINTER-NEXT:{{^.*}}|          &b]() {
+    // POINTER-NEXT:{{^.*}}|          ~^
+        a++;
+    };
+
+    auto F4a = [&a
+        , &b]() {
+    // CHECK: auto F4a = [&a]() {
+         // POINTER:{{^.*}}|     auto F4a = [&a
+    // POINTER-NEXT:{{^.*}}|                   {{$}}
+    // POINTER-NEXT:{{^.*}}|         , &b]() {
+    // POINTER-NEXT:{{^.*}}|         ~~~^
+        a++;
+    };
+
+    auto F5a = [&a ,&b]() {
+    // CHECK: auto F5a = [&a]() {
+         // POINTER:{{^.*}}|     auto F5a = [&a ,&b]() {
+    // POINTER-NEXT:{{^.*}}|                    ~~^
+        a++;
+    };
+    auto F0b = [a, &b]() mutable {
+    // CHECK: auto F0b = [ &b]() mutable
+         // POINTER:{{^.*}}|     auto F0b = [a, &b]() mutable {
+    // POINTER-NEXT:{{^.*}}|                 ^~
+
+        b++;
+    };
+
+    auto F1b = [&a, &b]() {
+    // CHECK: auto F1b = [ &b]() {
+         // POINTER:{{^.*}}|     auto F1b = [&a, &b]() {
+    // POINTER-NEXT:{{^.*}}|                 ~^~
+        b++;
+    };
+
+    auto F2b = [&a, b]() mutable {
+    // CHECK: auto F2b = [ b]() mutable {
+         // POINTER:{{^.*}}|     auto F2b = [&a, b]() mutable {
+    // POINTER-NEXT:{{^.*}}|                 ~^~
+        b++;
+    };
+
+    auto F3b = [&a,
+         &b]() {
+    // CHECK: auto F3b = [ &b]() {
+         // POINTER:{{^.*}}|     auto F3b = [&a,
+    // POINTER-NEXT:{{^.*}}|                 ~^~
+    // POINTER-NEXT:{{^.*}}|          &b]() {
+        b++;
+    };
+
+    auto F4b = [&a
+        , &b]() {
+    // CHECK: auto F4b = [ &b]() {
+         // POINTER:{{^.*}}|     auto F4b = [&a
+    // POINTER-NEXT:{{^.*}}|                 ~^
+    // POINTER-NEXT:{{^.*}}|         , &b]() {
+    // POINTER-NEXT:{{^.*}}|         ~
+
+        b++;
+    };
+    auto F5b = [&a ,&b]() {
+    // CHECK: auto F5b = [&b]() {
+         // POINTER:{{^.*}}|     auto F5b = [&a ,&b]() {
+    // POINTER-NEXT:{{^.*}}|                 ~^~~
+        b++;
+    };
+
+    auto F6 = [&a, &b, &c]() {
+    // CHECK: auto F6 = [&a, &b]() {
+         // POINTER:{{^.*}}|     auto F6 = [&a, &b, &c]() {
+    // POINTER-NEXT:{{^.*}}|                      ~~~^
+        a++;
+        b++;
+    };
+    auto F7 = [&a, &b, &c]() {
+    // CHECK: auto F7 = [&a, &c]() {
+         // POINTER:{{^.*}}|     auto F7 = [&a, &b, &c]() {
+    // POINTER-NEXT:{{^.*}}|                  ~~~^
+        a++;
+        c++;
+    };
+    auto F8 = [&a, &b, &c]() {
+    // CHECK: auto F8 = [ &b, &c]() {
+         // POINTER:{{^.*}}|     auto F8 = [&a, &b, &c]() {
+    // POINTER-NEXT:{{^.*}}|                ~^~
+        b++;
+        c++;
+    };
+    auto F9 = [&a, &b    , &c]() {
+    // CHECK: auto F9 = [&a   , &c]() {
+         // POINTER:{{^.*}}|     auto F9 = [&a, &b    , &c]() {
+    // POINTER-NEXT:{{^.*}}|                  ~~~^
+        a++;
+        c++;
+    };
+    auto F10 = [&a,
+         &b, &c]() {
+    // CHECK: auto F10 = [&a, &c]() {
+         // POINTER:{{^.*}}|     auto F10 = [&a,
+    // POINTER-NEXT:{{^.*}}|                   ~
+    // POINTER-NEXT:{{^.*}}|          &b, &c]() {
+    // POINTER-NEXT:{{^.*}}|          ~^
+        a++;
+        c++;
+    };
+    auto F11 = [&a,  &b  ,
+         &c]() {
+    // CHECK: auto F11 = [&a ,
+    // CHECK-NEXT:      &c]() {
+         // POINTER:{{^.*}}|     auto F11 = [&a,  &b  ,
+    // POINTER-NEXT:{{^.*}}|                   ~~~~^
+        a++;
+        c++;
+    };
+    auto F12 = [a = 0,  b  ,
+         c]() mutable {
+    // CHECK: auto F12 = [ b  ,
+    // CHECK-NEXT:     c]() mutable {
+         // POINTER:{{^.*}}|     auto F12 = [a = 0,  b  ,
+    // POINTER-NEXT:{{^.*}}|                 ^~~~~~
+        b++;
+        c++;
+    };
+    auto F13 = [a,  b = 0 ,
+         c]() mutable {
+    // CHECK: auto F13 = [a ,
+    // CHECK-NEXT:     c]() mutable {
+         // POINTER:{{^.*}}|     auto F13 = [a,  b = 0 ,
+    // POINTER-NEXT:{{^.*}}|                  ~~~^~~~~
+        a++;
+        c++;
+    };
+    auto F14 = [a,  b ,
+         c
+        = 0]() mutable {
+    // CHECK: auto F14 = [a,  b]() mutable {
+         // POINTER:{{^.*}}|     auto F14 = [a,  b ,
+    // POINTER-NEXT:{{^.*}}|                       ~
+    // POINTER-NEXT:{{^.*}}|          c
+    // POINTER-NEXT:{{^.*}}|          ^
+    // POINTER-NEXT:{{^.*}}|         = 0]() mutable {
+    // POINTER-NEXT:{{^.*}}|         ~~~
+        a++;
+        b++;
+    };
+
+    // We want to remove everything including the comment
+    // as well as the comma following the capture of `a`
+    auto F15 = [&a /* comment */, &b]() {
+    // CHECK: auto F15 = [ &b]() {
+         // POINTER:{{^.*}}|     auto F15 = [&a /* comment */, &b]() {
+    // POINTER-NEXT:{{^.*}}|                 ~^~~~~~~~~~~~~~~~
+        b++;
+    };
+
+    // The comment preceding the first capture remains. This is more
+    // by design of the fixit logic than anything else, but we should
+    // consider the preceding comment might actually be a comment for
+    // the entire capture set, so maybe we do want it to hang around
+    auto F16 = [/* comment */ &a , &b]() {
+    // CHECK: auto F16 = [/* comment */ &b]() {
+         // POINTER:{{^.*}}|     auto F16 = [/* comment */ &a , &b]() {
+    // POINTER-NEXT:{{^.*}}|                               ~^~~
+        b++;
+    };
+
+    auto F16b = [&a ,    /* comment */ &b]() {
+    // CHECK: auto F16b = [ /* comment */ &b]() {
+         // POINTER:{{^.*}}|     auto F16b = [&a ,    /* comment */ &b]() {
+    // POINTER-NEXT:{{^.*}}|                  ~^~~
+        b++;
+    };
+
+    auto F17 = [&a /* comment */, &b]() {
+    // CHECK: auto F17 = [&a]() {
+         // POINTER:{{^.*}}|     auto F17 = [&a /* comment */, &b]() {
+    // POINTER-NEXT:{{^.*}}|                    ~~~~~~~~~~~~~~~~^
+
+        a++;
+    };
+
+    auto F18 = [&a , /* comment */ &b]() {
+    // CHECK: auto F18 = [&a]() {
+         // POINTER:{{^.*}}|     auto F18 = [&a , /* comment */ &b]() {
+    // POINTER-NEXT:{{^.*}}|                    ~~~~~~~~~~~~~~~~~^
+
+        a++;
+    };
+
+    auto F19 = [&a /* comment */, &b /* comment */]() {
+    // CHECK: auto F19 = [&a /* comment */]() {
+         // POINTER:{{^.*}}|     auto F19 = [&a /* comment */, &b /* comment 
*/]() {
+    // POINTER-NEXT:{{^.*}}|                    ~~~~~~~~~~~~~~~~^
+
+        a++;
+    };
+
+    auto F20 = [MACRO_CAPTURE(&a, &b)]() {
+    // CHECK: auto F20 = [MACRO_CAPTURE(&a, &b)]() {
+         // POINTER:{{^.*}}|     auto F20 = [MACRO_CAPTURE(&a, &b)]() {
+    // POINTER-NEXT:{{^.*}}|                               ~^
+          // POINTER:{{^.*}}|     auto F20 = [MACRO_CAPTURE(&a, &b)]() {
+    // POINTER-NEXT:{{^.*}}|                                   ~^
+    };
+
+    auto F21 = [MACRO_CAPTURE(&a), &b]() {
+    // CHECK: auto F21 = []() {
+         // POINTER:{{^.*}}|     auto F21 = [MACRO_CAPTURE(&a), &b]() {
+    // POINTER-NEXT:{{^.*}}|                 ~~~~~~~~~~~~~~~^~~
+         // POINTER:{{^.*}}|     auto F21 = [MACRO_CAPTURE(&a), &b]() {
+    // POINTER-NEXT:{{^.*}}|                                  ~~~^
+    };
+
+    auto F22 = [MACRO_CAPTURE(&a,) &b]() {
+    // CHECK: auto F22 = [MACRO_CAPTURE(&a,) &b]() {
+         // POINTER:{{^.*}}|     auto F22 = [MACRO_CAPTURE(&a,) &b]() {
+    // POINTER-NEXT:{{^.*}}|                               ~^
+         // POINTER:{{^.*}}|     auto F22 = [MACRO_CAPTURE(&a,) &b]() {
+    // POINTER-NEXT:{{^.*}}|                                    ~^
+    };
+    auto F23 = [&a MACRO_CAPTURE(, &b)]() {
+    // CHECK: auto F23 = [&a]() {
+         // POINTER:{{^.*}}|     auto F23 = [&a MACRO_CAPTURE(, &b)]() {
+    // POINTER-NEXT:{{^.*}}|                 ~^
+         // POINTER:{{^.*}}|     auto F23 = [&a MACRO_CAPTURE(, &b)]() {
+    // POINTER-NEXT:{{^.*}}|                    ~~~~~~~~~~~~~~~~~^~
+    };
+    auto F24 = [&a, MACRO_CAPTURE(&b)]() {
+    // CHECK: auto F24 = []() {
+         // POINTER:{{^.*}}|     auto F24 = [&a, MACRO_CAPTURE(&b)]() {
+    // POINTER-NEXT:{{^.*}}|                 ~^~
+         // POINTER:{{^.*}}|     auto F24 = [&a, MACRO_CAPTURE(&b)]() {
+    // POINTER-NEXT:{{^.*}}|                   ~~~~~~~~~~~~~~~~~^~
+    };
+
+    auto F20a = [MACRO_CAPTURE(&a, &b)]() {
+    // CHECK: auto F20a = [MACRO_CAPTURE(&a, &b)]() {
+         // POINTER:{{^.*}}|     auto F20a = [MACRO_CAPTURE(&a, &b)]() {
+    // POINTER-NEXT:{{^.*}}|                                    ~^
+      a++;
+    };
+
+    auto F21a = [MACRO_CAPTURE(&a), &b]() {
+    // CHECK: auto F21a = [MACRO_CAPTURE(&a)]() {
+         // POINTER:{{^.*}}|     auto F21a = [MACRO_CAPTURE(&a), &b]() {
+    // POINTER-NEXT:{{^.*}}|                                   ~~~^
+      a++;
+    };
+
+    auto F22a = [MACRO_CAPTURE(&a,) &b]() {
+    // CHECK: auto F22a = [MACRO_CAPTURE(&a,) &b]() {
+         // POINTER:{{^.*}}|     auto F22a = [MACRO_CAPTURE(&a,) &b]() {
+    // POINTER-NEXT:{{^.*}}|                                     ~^
+      a++;
+    };
+    auto F23a = [&a MACRO_CAPTURE(, &b)]() {
+    // CHECK: auto F23a = [&a]() {
+         // POINTER:{{^.*}}|     auto F23a = [&a MACRO_CAPTURE(, &b)]() {
+    // POINTER-NEXT:{{^.*}}|                     ~~~~~~~~~~~~~~~~~^~
+      a++;
+    };
+    auto F24a = [&a, MACRO_CAPTURE(&b)]() {
+    // CHECK: auto F24a = [&a]() {
+         // POINTER:{{^.*}}|     auto F24a = [&a, MACRO_CAPTURE(&b)]() {
+    // POINTER-NEXT:{{^.*}}|                    ~~~~~~~~~~~~~~~~~^~
+      a++;
+    };
+    auto F20b = [MACRO_CAPTURE(&a, &b)]() {
+    // CHECK: auto F20b = [MACRO_CAPTURE(&a, &b)]() {
+         // POINTER:{{^.*}}|     auto F20b = [MACRO_CAPTURE(&a, &b)]() {
+    // POINTER-NEXT:{{^.*}}|                                ~^
+      b++;
+    };
+
+    auto F21b = [MACRO_CAPTURE(&a), &b]() {
+    // CHECK: auto F21b = [ &b]() {
+         // POINTER:{{^.*}}|     auto F21b = [MACRO_CAPTURE(&a), &b]() {
+    // POINTER-NEXT:{{^.*}}|                  ~~~~~~~~~~~~~~~^~~
+      b++;
+    };
+
+    auto F22b = [MACRO_CAPTURE(&a,) &b]() {
+    // CHECK: auto F22b = [MACRO_CAPTURE(&a,) &b]() {
+         // POINTER:{{^.*}}|     auto F22b = [MACRO_CAPTURE(&a,) &b]() {
+    // POINTER-NEXT:{{^.*}}|                                ~^
+      b++;
+    };
+    auto F23b = [&a MACRO_CAPTURE(, &b)]() {
+    // CHECK: auto F23b = [&a MACRO_CAPTURE(, &b)]() {
+         // POINTER:{{^.*}}|     auto F23b = [&a MACRO_CAPTURE(, &b)]() {
+    // POINTER-NEXT:{{^.*}}|                  ~^
+      b++;
+    };
+    auto F24b = [&a, MACRO_CAPTURE(&b)]() {
+    // CHECK: auto F24b = [ MACRO_CAPTURE(&b)]() {
+         // POINTER:{{^.*}}|     auto F24b = [&a, MACRO_CAPTURE(&b)]() {
+    // POINTER-NEXT:{{^.*}}|                  ~^~
+      b++;
+    };
+
+    auto F25ma = [&M_A, &b]() {
+    // CHECK:     auto F25ma = []() {
+         // POINTER:{{^.*}}|     auto F25ma = [&M_A, &b]() {
+    // POINTER-NEXT:{{^.*}}|                   ~^~~~
+         // POINTER:{{^.*}}|     auto F25ma = [&M_A, &b]() {
+    // POINTER-NEXT:{{^.*}}|                       ~~~^
+    };
+    auto F25mb = [&a, &M_B]() {
+    // CHECK: auto F25mb = []() {
+         // POINTER:{{^.*}}|     auto F25mb = [&a, &M_B]() {
+    // POINTER-NEXT:{{^.*}}|                   ~^~
+         // POINTER:{{^.*}}|     auto F25mb = [&a, &M_B]() {
+    // POINTER-NEXT:{{^.*}}|                     ~~~^~~
+    };
+
+    auto F25mab = [&M_A, &b]() {
+    // CHECK: auto F25mab = [ &b]() {
+         // POINTER:{{^.*}}|     auto F25mab = [&M_A, &b]() {
+    // POINTER-NEXT:{{^.*}}|                    ~^~~~
+        b++;
+    };
+    auto F25amb = [&a, &M_B]() {
+    //CHECK: auto F25amb = []() {
+         // POINTER:{{^.*}}|     auto F25amb = [&a, &M_B]() {
+    // POINTER-NEXT:{{^.*}}|                    ~^~
+         // POINTER:{{^.*}}|     auto F25amb = [&a, &M_B]() {
+    // POINTER-NEXT:{{^.*}}|                      ~~~^~~
+    };
+
+    auto F26 = [&a, &b, &c, &d]() {
+    // CHECK: auto F26 = [&a, &b]() {
+         // POINTER:{{^.*}}|     auto F26 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                       ~~~^
+         // POINTER:{{^.*}}|     auto F26 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                           ~~~^
+
+        (void)a;
+        (void)b;
+    };
+
+    auto F27 = [&a, &b, &c, &d]() {
+    // CHECK: auto F27 = [&a, &c]() {
+         // POINTER:{{^.*}}|     auto F27 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                   ~~~^
+         // POINTER:{{^.*}}|     auto F27 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                           ~~~^
+
+        (void)a;
+        (void)c;
+    };
+
+    auto F28 = [&a, &b, &c, &d]() {
+        // CHECK: auto F28 = [&a, &d]() {
+         // POINTER:{{^.*}}|     auto F28 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                   ~~~^
+         // POINTER:{{^.*}}|     auto F28 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                       ~~~^
+
+        (void)a;
+        (void)d;
+    };
+
+    auto F29 = [&a, &b, &c, &d]() {
+    // CHECK: auto F29 = [ &b, &c]() {
+         // POINTER:{{^.*}}|     auto F29 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                 ~^~
+         // POINTER:{{^.*}}|     auto F29 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                           ~~~^
+
+        (void)b;
+        (void)c;
+    };
+
+    auto F30 = [&a, &b, &c, &d]() {
+    // CHECK: auto F30 = [ &b, &d]() {
+         // POINTER:{{^.*}}|     auto F30 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                 ~^~
+         // POINTER:{{^.*}}|     auto F30 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                       ~~~^
+
+        (void)b;
+        (void)d;
+    };
+
+    auto F31 = [&a, &b, &c, &d]() {
+    // CHECK: auto F31 = [ &c, &d]() {
+         // POINTER:{{^.*}}|     auto F31 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                 ~^~
+         // POINTER:{{^.*}}|     auto F31 = [&a, &b, &c, &d]() {
+    // POINTER-NEXT:{{^.*}}|                     ~^~
+        (void)c;
+        (void)d;
+    };
+}


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

Reply via email to