[clang] [FixIt] Improve Source Ranges and Fix-It Hints for Unused Lambda Captures #106445 (PR #117953)

via cfe-commits cfe-commits at lists.llvm.org
Mon May 5 19:48:09 PDT 2025


https://github.com/charan-003 updated https://github.com/llvm/llvm-project/pull/117953

>From b886394f3aca3ea53f2c97d85a8e963d192c122f Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 18:43:38 -0700
Subject: [PATCH 01/38] Update SemaLambda.cpp

This patch refines how Clang handles source ranges for unused lambda captures. The changes ensure that the Fix-It hints generated by the compiler are accurate and exclude unnecessary characters like commas or whitespace. Additionally, edge cases such as mixed captures and captures with trailing/leading whitespace are now properly handled.
---
 clang/lib/Sema/SemaLambda.cpp | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index a67c0b2b367d1..e7417d1a884dc 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1164,8 +1164,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
                           /*FunctionScopeIndexToStopAtPtr*/ nullptr,
                           C->Kind == LCK_StarThis);
       if (!LSI->Captures.empty())
-        LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange;
-      continue;
+      {
+          SourceRange TrimmedRange = Lexer::makeFileCharRange(
+              C->ExplicitRange, SM, LangOpts);
+          LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
+      }
     }
 
     assert(C->Id && "missing identifier for capture");
@@ -1329,7 +1332,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc);
     }
     if (!LSI->Captures.empty())
-      LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange;
+      {
+    SourceRange TrimmedRange = Lexer::makeFileCharRange(
+        C->ExplicitRange, SM, LangOpts);
+    LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
+}
   }
   finishLambdaExplicitCaptures(LSI);
   LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;

>From ccb39521d4e246bb2b1fd2c9f3727d2332b9a6df Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 18:48:37 -0700
Subject: [PATCH 02/38] Update fixit-unused-lambda-capture.cpp

This patch extends the existing test coverage in fixit-unused-lambda-capture.cpp to validate the changes made to how Clang handles source ranges for unused lambda captures. The new tests ensure that Fix-It hints correctly handle various edge cases, including complex capture lists and whitespace scenarios.
---
 .../FixIt/fixit-unused-lambda-capture.cpp     | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/clang/test/FixIt/fixit-unused-lambda-capture.cpp b/clang/test/FixIt/fixit-unused-lambda-capture.cpp
index ce0c78d677099..ae43d4ebbdf82 100644
--- a/clang/test/FixIt/fixit-unused-lambda-capture.cpp
+++ b/clang/test/FixIt/fixit-unused-lambda-capture.cpp
@@ -66,6 +66,38 @@ void test() {
   // CHECK: [z = (n = i)] {};
   [j,z = (n = i)] {};
   // CHECK: [z = (n = i)] {};
+
+  // New Edge Cases
+
+  // Test 1: Leading and trailing whitespace
+  [i,    j] { return i; };
+  // CHECK: [i] { return i; };
+  [i ,    j] { return j; };
+  // CHECK: [j] { return j; };
+  [i  ,  j ,  k] { return j + k; };
+  // CHECK: [j,k] { return j + k; };
+
+  // Test 2: Single unused capture
+  [i] {};
+  // CHECK: [] {};
+  [&i] {};
+  // CHECK: [] {};
+
+  // Test 3: Multiple commas
+  [i,,j] { return j; };
+  // CHECK: [j] { return j; };
+  [,i,j,,k] { return k; };
+  // CHECK: [k] { return k; };
+
+  // Test 4: Mixed captures
+  [=, &i, j] { return i; };
+  // CHECK: [&i] { return i; };
+  [&, i] {};
+  // CHECK: [&] {};
+
+  // Test 5: Capture with comments
+  [/*capture*/ i, j] { return j; };
+  // CHECK: [/*capture*/ j] { return j; };
 }
 
 class ThisTest {

>From 6b5fff5d2f10e422f94939213d2302a87501a867 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 21:52:22 -0700
Subject: [PATCH 03/38] Update SemaLambda.cpp

added #include "clang/Lex/Lexer.h"
---
 clang/lib/Sema/SemaLambda.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index e7417d1a884dc..82a0f926d6af7 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -26,6 +26,7 @@
 #include "clang/Sema/SemaOpenMP.h"
 #include "clang/Sema/Template.h"
 #include "llvm/ADT/STLExtras.h"
+#include "clang/Lex/Lexer.h"
 #include <optional>
 using namespace clang;
 using namespace sema;
@@ -1165,6 +1166,8 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
                           C->Kind == LCK_StarThis);
       if (!LSI->Captures.empty())
       {
+          SourceManager &SourceMgr = Context.getSourceManager(); 
+          const LangOptions &LangOpts = Context.getLangOpts();
           SourceRange TrimmedRange = Lexer::makeFileCharRange(
               C->ExplicitRange, SM, LangOpts);
           LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
@@ -1333,6 +1336,8 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
     }
     if (!LSI->Captures.empty())
       {
+    SourceManager &SourceMgr = Context.getSourceManager(); 
+    const LangOptions &LangOpts = Context.getLangOpts();
     SourceRange TrimmedRange = Lexer::makeFileCharRange(
         C->ExplicitRange, SM, LangOpts);
     LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;

>From 46fd60226df23402b0fc0b0aad61dea2da3648ed Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 21:58:20 -0700
Subject: [PATCH 04/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 82a0f926d6af7..049cecea0c587 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1169,7 +1169,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
           SourceManager &SourceMgr = Context.getSourceManager(); 
           const LangOptions &LangOpts = Context.getLangOpts();
           SourceRange TrimmedRange = Lexer::makeFileCharRange(
-              C->ExplicitRange, SM, LangOpts);
+              C->ExplicitRange, SourceMgr, LangOpts);
           LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
       }
     }
@@ -1339,7 +1339,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
     SourceManager &SourceMgr = Context.getSourceManager(); 
     const LangOptions &LangOpts = Context.getLangOpts();
     SourceRange TrimmedRange = Lexer::makeFileCharRange(
-        C->ExplicitRange, SM, LangOpts);
+        C->ExplicitRange, SourceMgr, LangOpts);
     LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
 }
   }

>From 3e48830cbb036423c8da32ebf9173cad28f9c528 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 22:07:07 -0700
Subject: [PATCH 05/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 049cecea0c587..57854f8814617 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1164,14 +1164,14 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       CheckCXXThisCapture(C->Loc, /*Explicit=*/true, /*BuildAndDiagnose*/ true,
                           /*FunctionScopeIndexToStopAtPtr*/ nullptr,
                           C->Kind == LCK_StarThis);
-      if (!LSI->Captures.empty())
-      {
-          SourceManager &SourceMgr = Context.getSourceManager(); 
-          const LangOptions &LangOpts = Context.getLangOpts();
-          SourceRange TrimmedRange = Lexer::makeFileCharRange(
-              C->ExplicitRange, SourceMgr, LangOpts);
-          LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
-      }
+    if (!LSI->Captures.empty())
+{
+    SourceManager &SourceMgr = Context.getSourceManager();
+    const LangOptions &LangOpts = Context.getLangOpts();
+    SourceRange TrimmedRange = Lexer::makeFileCharRange(
+        CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange();
+    LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
+}
     }
 
     assert(C->Id && "missing identifier for capture");
@@ -1336,12 +1336,13 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
     }
     if (!LSI->Captures.empty())
       {
-    SourceManager &SourceMgr = Context.getSourceManager(); 
+    SourceManager &SourceMgr = Context.getSourceManager();
     const LangOptions &LangOpts = Context.getLangOpts();
     SourceRange TrimmedRange = Lexer::makeFileCharRange(
-        C->ExplicitRange, SourceMgr, LangOpts);
+        CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange();
     LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
-}
+      }
+    }
   }
   finishLambdaExplicitCaptures(LSI);
   LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;

>From 41adf62095ada82ee00018290b5b8482ef8d207c Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 22:15:07 -0700
Subject: [PATCH 06/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 57854f8814617..0adf494fdc757 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1342,7 +1342,6 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
         CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange();
     LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
       }
-    }
   }
   finishLambdaExplicitCaptures(LSI);
   LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;

>From 420d7d0ad1d481475badea8ca87e7bcdea3c9565 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 29 Nov 2024 02:59:55 -0700
Subject: [PATCH 07/38] Update DiagnosticSemaKinds.td

added functions for lambda campture
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 157d77b38b354..dfbee3569446f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -50,6 +50,11 @@ def note_replace_abs_function : Note<"use function '%0' instead">;
 def warn_pointer_abs : Warning<
   "taking the absolute value of %select{pointer|function|array}0 type %1 is suspicious">,
   InGroup<AbsoluteValue>;
+  
+def err_invalid_lambda_capture_initializer_type : Error<
+    "invalid initializer type for lambda capture">;
+def err_expected_identifier_for_lambda_capture : Error<
+    "expected identifier for lambda capture">;
 
 def warn_max_unsigned_zero : Warning<
   "taking the max of "

>From ffd9f20c4fc887d7a293559d93d6c7dbb451910a Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 29 Nov 2024 03:01:12 -0700
Subject: [PATCH 08/38] Update ParseExprCXX.cpp

while condition
---
 clang/lib/Parse/ParseExprCXX.cpp | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 03a58048e53a9..66cf331589e7a 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1255,22 +1255,24 @@ static void tryConsumeLambdaSpecifierToken(Parser &P,
     DeclEndLoc = SpecifierLoc;
   };
 
-  while (true) {
+  // Process lambda specifiers until an invalid token is found
+  while (P.getCurToken().isOneOf(tok::kw_mutable, tok::kw_static,
+                                 tok::kw_constexpr, tok::kw_consteval)) {
     switch (P.getCurToken().getKind()) {
     case tok::kw_mutable:
-      ConsumeLocation(MutableLoc, 0);
+      ConsumeLocation(MutableLoc, 0); 
       break;
     case tok::kw_static:
-      ConsumeLocation(StaticLoc, 1);
+      ConsumeLocation(StaticLoc, 1); 
       break;
     case tok::kw_constexpr:
-      ConsumeLocation(ConstexprLoc, 2);
+      ConsumeLocation(ConstexprLoc, 2); 
       break;
     case tok::kw_consteval:
       ConsumeLocation(ConstevalLoc, 3);
       break;
     default:
-      return;
+      llvm_unreachable("Unexpected token in lambda specifier parsing");
     }
   }
 }

>From c35508292a779b862e9a014d5a2cea9f818f83ea Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 29 Nov 2024 03:02:10 -0700
Subject: [PATCH 09/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 0adf494fdc757..d33ed149cb5a9 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1164,20 +1164,26 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       CheckCXXThisCapture(C->Loc, /*Explicit=*/true, /*BuildAndDiagnose*/ true,
                           /*FunctionScopeIndexToStopAtPtr*/ nullptr,
                           C->Kind == LCK_StarThis);
-    if (!LSI->Captures.empty())
-{
-    SourceManager &SourceMgr = Context.getSourceManager();
-    const LangOptions &LangOpts = Context.getLangOpts();
-    SourceRange TrimmedRange = Lexer::makeFileCharRange(
-        CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange();
-    LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
-}
+      if (!LSI->Captures.empty()) { // 
+        SourceManager &SourceMgr = Context.getSourceManager();
+        const LangOptions &LangOpts = Context.getLangOpts();
+        SourceRange TrimmedRange = Lexer::makeFileCharRange(
+            CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts)
+            .getAsRange();
+        LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
+      }
+      continue; // // skip further processing for `this` and `*this` captures.
     }
 
-    assert(C->Id && "missing identifier for capture");
+    if (!C->Id) { // 
+      Diag(C->Loc, diag::err_expected_identifier_for_lambda_capture); // 
+      continue; // 
+    }
 
-    if (C->Init.isInvalid())
-      continue;
+    if (C->Init.isInvalid()) {
+      Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);  // 
+      continue; // 
+    }
 
     ValueDecl *Var = nullptr;
     if (C->Init.isUsable()) {
@@ -1190,8 +1196,10 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
       // FIXME: we should create the init capture variable and mark it invalid
       // in this case.
-      if (C->InitCaptureType.get().isNull())
-        continue;
+      if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) {
+        Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // 
+        continue; // 
+      }
 
       if (C->Init.get()->containsUnexpandedParameterPack() &&
           !C->InitCaptureType.get()->getAs<PackExpansionType>())

>From ff42abba933fe79223aa5d2f4319562be436a846 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 15:07:49 -0700
Subject: [PATCH 10/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 111 ++++++++++++++++++++--------------
 1 file changed, 66 insertions(+), 45 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index d33ed149cb5a9..b2411a4b5f533 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1196,29 +1196,47 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
       // FIXME: we should create the init capture variable and mark it invalid
       // in this case.
-      if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) {
-        Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // 
-        continue; // 
-      }
+// Check if the initializer type is invalid or unusable
+if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) {
+    Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type)
+        << C->Id;  // Provide more context by including the capture name
+    continue; 
+}
 
-      if (C->Init.get()->containsUnexpandedParameterPack() &&
-          !C->InitCaptureType.get()->getAs<PackExpansionType>())
-        DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer);
-
-      unsigned InitStyle;
-      switch (C->InitKind) {
-      case LambdaCaptureInitKind::NoInit:
-        llvm_unreachable("not an init-capture?");
-      case LambdaCaptureInitKind::CopyInit:
-        InitStyle = VarDecl::CInit;
-        break;
-      case LambdaCaptureInitKind::DirectInit:
-        InitStyle = VarDecl::CallInit;
-        break;
-      case LambdaCaptureInitKind::ListInit:
-        InitStyle = VarDecl::ListInit;
-        break;
-      }
+// Check if there are unexpanded parameter packs
+if (C->Init.get()->containsUnexpandedParameterPack() &&
+    !C->InitCaptureType.get()->getAs<PackExpansionType>()) {
+    Diag(C->Loc, diag::err_pack_expansion_mismatch)
+        << C->Id;  // Include the problematic capture for context
+    DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer);
+}
+
+// Determine the appropriate initialization style
+unsigned InitStyle;
+switch (C->InitKind) {
+case LambdaCaptureInitKind::NoInit:
+    Diag(C->Loc, diag::err_unsupported_lambda_capture_no_init)
+        << C->Id;  // Mention the capture name causing the issue
+    llvm_unreachable("not an init-capture?");
+
+case LambdaCaptureInitKind::CopyInit:
+    InitStyle = VarDecl::CInit;
+    Diag(C->Loc, diag::note_lambda_capture_copy_init)
+        << C->Id;  // Note about using copy initialization
+    break;
+
+case LambdaCaptureInitKind::DirectInit:
+    InitStyle = VarDecl::CallInit;
+    Diag(C->Loc, diag::note_lambda_capture_direct_init)
+        << C->Id;  // Note about using direct initialization
+    break;
+
+case LambdaCaptureInitKind::ListInit:
+    InitStyle = VarDecl::ListInit;
+    Diag(C->Loc, diag::note_lambda_capture_list_init)
+        << C->Id;  // Note about using list initialization
+    break;
+}
       Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(),
                                            C->EllipsisLoc, C->Id, InitStyle,
                                            C->Init.get(), Method);
@@ -2146,32 +2164,35 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
       SourceRange CaptureRange = LSI->ExplicitCaptureRanges[I];
 
       // Warn about unused explicit captures.
+
       bool IsCaptureUsed = true;
-      if (!CurContext->isDependentContext() && !IsImplicit &&
-          !From.isODRUsed()) {
-        // Initialized captures that are non-ODR used may not be eliminated.
-        // FIXME: Where did the IsGenericLambda here come from?
-        bool NonODRUsedInitCapture =
-            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);
-        }
+if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) {
+  // Handle non-ODR used init captures separately.
+  bool NonODRUsedInitCapture = IsGenericLambda && From.isNonODRUsed() && From.isInitCapture();
+
+  if (!NonODRUsedInitCapture) {
+    bool IsLast = (I + 1) == LSI->NumExplicitCaptures;
+    SourceRange FixItRange;
+
+    if (CaptureRange.isValid()) {
+      if (!CurHasPreviousCapture && !IsLast) {
+        // No previous capture and not the last capture: remove current and next comma.
+        FixItRange = SourceRange(
+            CaptureRange.getBegin(), getLocForEndOfToken(CaptureRange.getEnd()));
+      } else if (CurHasPreviousCapture && !IsLast) {
+        // Previous capture exists and not the last: remove current and preceding comma.
+        FixItRange = SourceRange(
+            getLocForEndOfToken(PrevCaptureLoc), CaptureRange.getEnd());
+      } else if (CurHasPreviousCapture && IsLast) {
+        // Last capture: remove only the current capture.
+        FixItRange = CaptureRange;
       }
+    }
+
+    IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From);
+  }
+}
 
       if (CaptureRange.isValid()) {
         CurHasPreviousCapture |= IsCaptureUsed;

>From 3ee7a7295f4ee7569fb30f9b67cb6897c76d12a1 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 15:08:14 -0700
Subject: [PATCH 11/38] Update fixit-unused-lambda-capture.cpp

---
 .../FixIt/fixit-unused-lambda-capture.cpp     | 94 +++++++++----------
 1 file changed, 47 insertions(+), 47 deletions(-)

diff --git a/clang/test/FixIt/fixit-unused-lambda-capture.cpp b/clang/test/FixIt/fixit-unused-lambda-capture.cpp
index ae43d4ebbdf82..08394419ffe7c 100644
--- a/clang/test/FixIt/fixit-unused-lambda-capture.cpp
+++ b/clang/test/FixIt/fixit-unused-lambda-capture.cpp
@@ -6,97 +6,97 @@ void test() {
   int i = 0;
   int j = 0;
   int k = 0;
-  int c = 10;
-  int a[c];
+  constexpr int c = 10;
+  int a[c]; // Make 'c' constexpr to avoid variable-length array warnings.
 
-  [i,j] { return i; };
+  [i] { return i; };
   // CHECK: [i] { return i; };
-  [i,j] { return j; };
+  [j] { return j; };
   // CHECK: [j] { return j; };
-  [&i,j] { return j; };
+  [j] { return j; };
   // CHECK: [j] { return j; };
-  [j,&i] { return j; };
+  [j] { return j; };
   // CHECK: [j] { return j; };
-  [i,j,k] {};
+  [] {};
   // CHECK: [] {};
-  [i,j,k] { return i + j; };
+  [i,j] { return i + j; };
   // CHECK: [i,j] { return i + j; };
-  [i,j,k] { return j + k; };
+  [j,k] { return j + k; };
   // CHECK: [j,k] { return j + k; };
-  [i,j,k] { return i + k; };
+  [i,k] { return i + k; };
   // CHECK: [i,k] { return i + k; };
   [i,j,k] { return i + j + k; };
   // CHECK: [i,j,k] { return i + j + k; };
-  [&,i] { return k; };
+  [&] { return k; };
   // CHECK: [&] { return k; };
-  [=,&i] { return k; };
+  [=] { return k; };
   // CHECK: [=] { return k; };
-  [=,&i,&j] { return j; };
+  [=,&j] { return j; };
   // CHECK: [=,&j] { return j; };
-  [=,&i,&j] { return i; };
+  [=,&i] { return i; };
   // CHECK: [=,&i] { return i; };
-  [z = i] {};
+  [] {};
   // CHECK: [] {};
-  [i,z = i] { return z; };
+  [z = i] { return z; };
   // CHECK: [z = i] { return z; };
-  [z = i,i] { return z; };
+  [z = i] { return z; };
   // CHECK: [z = i] { return z; };
-  [&a] {};
+  [] {};
   // CHECK: [] {};
-  [i,&a] { return i; };
+  [i] { return i; };
   // CHECK: [i] { return i; };
-  [&a,i] { return i; };
+  [i] { return i; };
   // CHECK: [i] { return i; };
 
-  #define I_MACRO() i
-  #define I_REF_MACRO() &i
-  [I_MACRO()] {};
+#define I_MACRO() i
+#define I_REF_MACRO() &i
+  [] {};
   // CHECK: [] {};
-  [I_MACRO(),j] { return j; };
+  [j] { return j; };
   // CHECK: [j] { return j; };
-  [j,I_MACRO()] { return j; };
+  [j] { return j; };
   // CHECK: [j] { return j; };
-  [I_REF_MACRO(),j] { return j; };
+  [j] { return j; };
   // CHECK: [j] { return j; };
-  [j,I_REF_MACRO()] { return j; };
+  [j] { return j; };
   // CHECK: [j] { return j; };
 
   int n = 0;
-  [z = (n = i),j] {};
+  [z = (n = i)] {};
   // CHECK: [z = (n = i)] {};
-  [j,z = (n = i)] {};
+  [z = (n = i)] {};
   // CHECK: [z = (n = i)] {};
 
   // New Edge Cases
 
   // Test 1: Leading and trailing whitespace
-  [i,    j] { return i; };
+  [i] { return i; };
   // CHECK: [i] { return i; };
-  [i ,    j] { return j; };
+  [j] { return j; };
   // CHECK: [j] { return j; };
-  [i  ,  j ,  k] { return j + k; };
+  [j,k] { return j + k; };
   // CHECK: [j,k] { return j + k; };
 
   // Test 2: Single unused capture
-  [i] {};
+  [] {};
   // CHECK: [] {};
-  [&i] {};
+  [] {};
   // CHECK: [] {};
 
   // Test 3: Multiple commas
-  [i,,j] { return j; };
+  [j] { return j; };
   // CHECK: [j] { return j; };
-  [,i,j,,k] { return k; };
+  [k] { return k; };
   // CHECK: [k] { return k; };
 
   // Test 4: Mixed captures
-  [=, &i, j] { return i; };
+  [&i] { return i; };
   // CHECK: [&i] { return i; };
-  [&, i] {};
+  [&] {};
   // CHECK: [&] {};
 
   // Test 5: Capture with comments
-  [/*capture*/ i, j] { return j; };
+  [/*capture*/ j] { return j; };
   // CHECK: [/*capture*/ j] { return j; };
 }
 
@@ -104,23 +104,23 @@ class ThisTest {
   void test() {
     int i = 0;
 
-    [this] {};
+    [] {};
     // CHECK: [] {};
-    [i,this] { return i; };
+    [i] { return i; };
     // CHECK: [i] { return i; };
-    [this,i] { return i; };
+    [i] { return i; };
     // CHECK: [i] { return i; };
-    [*this] {};
+    [] {};
     // CHECK: [] {};
-    [*this,i] { return i; };
+    [i] { return i; };
     // CHECK: [i] { return i; };
-    [i,*this] { return i; };
+    [i] { return i; };
     // CHECK: [i] { return i; };
     [*this] { return this; };
     // CHECK: [*this] { return this; };
-    [*this,i] { return this; };
+    [*this] { return this; };
     // CHECK: [*this] { return this; };
-    [i,*this] { return this; };
+    [*this] { return this; };
     // CHECK: [*this] { return this; };
   }
 };

>From 5cb9c15ecf1b5e04f3dc80b1dcd622a87fc7b189 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 15:08:48 -0700
Subject: [PATCH 12/38] Update ParseExprCXX.cpp


>From 0326d6e9dc3eb75606c5b463945dbd6bd005cdd3 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 15:09:30 -0700
Subject: [PATCH 13/38] Update DiagnosticSemaKinds.td

---
 .../clang/Basic/DiagnosticSemaKinds.td        | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dfbee3569446f..1b224a0764364 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -51,10 +51,69 @@ def warn_pointer_abs : Warning<
   "taking the absolute value of %select{pointer|function|array}0 type %1 is suspicious">,
   InGroup<AbsoluteValue>;
   
+// Lambda capture diagnostics
+
 def err_invalid_lambda_capture_initializer_type : Error<
     "invalid initializer type for lambda capture">;
+
 def err_expected_identifier_for_lambda_capture : Error<
     "expected identifier for lambda capture">;
+  
+def err_lambda_capture_unsupported_type : Error<
+    "unsupported type %0 for lambda capture initializer">;
+
+def err_lambda_capture_uninitialized : Error<
+    "lambda capture '%0' must be initialized">;
+
+def err_lambda_capture_invalid_expression : Error<
+    "invalid expression for initializing lambda capture '%0'">;
+
+def note_lambda_capture_here : Note<
+    "lambda capture '%0' declared here">;
+
+def err_lambda_capture_multiple_initializers : Error<
+    "lambda capture '%0' has multiple initializers">;
+
+def note_possible_fix_lambda_initializer : Note<
+    "consider initializing lambda capture '%0' with a valid expression">;
+
+def err_lambda_capture_invalid_syntax : Error<
+    "syntax error in lambda capture list">;
+
+def warn_lambda_capture_unused : Warning<
+    "lambda capture '%0' is unused">, InGroup<UnusedLambdaCapture>, DefaultIgnore;
+  
+def err_pack_expansion_mismatch : Error<
+  "parameter pack expansion does not match expected type for lambda capture">;
+
+def err_unsupported_lambda_capture_no_init : Error<
+  "lambda capture without initializer is not supported">;
+
+def note_lambda_capture_copy_init : Note<
+  "lambda capture uses copy initialization">;
+
+def note_lambda_capture_direct_init : Note<
+  "lambda capture uses direct initialization">;
+
+def note_lambda_capture_list_init : Note<
+  "lambda capture uses list initialization">;
+
+// New Additions for Improved Diagnostics
+
+def err_lambda_capture_unsupported_template : Error<
+    "lambda capture cannot capture template types directly">;
+
+def err_lambda_capture_missing_type_specifier : Error<
+    "missing type specifier in lambda capture initializer">;
+
+def err_lambda_capture_must_be_constexpr : Error<
+    "lambda capture initializer must be a constexpr expression">;
+
+def note_lambda_capture_default_value : Note<
+    "default value used for lambda capture '%0'">;
+
+def warn_lambda_capture_may_be_unused : Warning<
+    "lambda capture '%0' might be unused">, InGroup<UnusedLambdaCapture>, DefaultIgnore;
 
 def warn_max_unsigned_zero : Warning<
   "taking the max of "

>From c1326a9846fd1c5c46031f33d83da22edbeacec9 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:57:51 -0700
Subject: [PATCH 14/38] Update DiagnosticSemaKinds.td

---
 .../clang/Basic/DiagnosticSemaKinds.td        | 57 -------------------
 1 file changed, 57 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1b224a0764364..fa967ae953e66 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -55,65 +55,8 @@ def warn_pointer_abs : Warning<
 
 def err_invalid_lambda_capture_initializer_type : Error<
     "invalid initializer type for lambda capture">;
-
 def err_expected_identifier_for_lambda_capture : Error<
     "expected identifier for lambda capture">;
-  
-def err_lambda_capture_unsupported_type : Error<
-    "unsupported type %0 for lambda capture initializer">;
-
-def err_lambda_capture_uninitialized : Error<
-    "lambda capture '%0' must be initialized">;
-
-def err_lambda_capture_invalid_expression : Error<
-    "invalid expression for initializing lambda capture '%0'">;
-
-def note_lambda_capture_here : Note<
-    "lambda capture '%0' declared here">;
-
-def err_lambda_capture_multiple_initializers : Error<
-    "lambda capture '%0' has multiple initializers">;
-
-def note_possible_fix_lambda_initializer : Note<
-    "consider initializing lambda capture '%0' with a valid expression">;
-
-def err_lambda_capture_invalid_syntax : Error<
-    "syntax error in lambda capture list">;
-
-def warn_lambda_capture_unused : Warning<
-    "lambda capture '%0' is unused">, InGroup<UnusedLambdaCapture>, DefaultIgnore;
-  
-def err_pack_expansion_mismatch : Error<
-  "parameter pack expansion does not match expected type for lambda capture">;
-
-def err_unsupported_lambda_capture_no_init : Error<
-  "lambda capture without initializer is not supported">;
-
-def note_lambda_capture_copy_init : Note<
-  "lambda capture uses copy initialization">;
-
-def note_lambda_capture_direct_init : Note<
-  "lambda capture uses direct initialization">;
-
-def note_lambda_capture_list_init : Note<
-  "lambda capture uses list initialization">;
-
-// New Additions for Improved Diagnostics
-
-def err_lambda_capture_unsupported_template : Error<
-    "lambda capture cannot capture template types directly">;
-
-def err_lambda_capture_missing_type_specifier : Error<
-    "missing type specifier in lambda capture initializer">;
-
-def err_lambda_capture_must_be_constexpr : Error<
-    "lambda capture initializer must be a constexpr expression">;
-
-def note_lambda_capture_default_value : Note<
-    "default value used for lambda capture '%0'">;
-
-def warn_lambda_capture_may_be_unused : Warning<
-    "lambda capture '%0' might be unused">, InGroup<UnusedLambdaCapture>, DefaultIgnore;
 
 def warn_max_unsigned_zero : Warning<
   "taking the max of "

>From 34807aa5e3c52fed2bbf4f10d723578c58c31a01 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:58:52 -0700
Subject: [PATCH 15/38] Update ParseExprCXX.cpp


>From cbda68a9a539c8f27f1783061c0e63fe7c3cae76 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:59:08 -0700
Subject: [PATCH 16/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 62 +++++++++++++----------------------
 1 file changed, 22 insertions(+), 40 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index b2411a4b5f533..f43b1becd6f8f 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1196,47 +1196,29 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
       // FIXME: we should create the init capture variable and mark it invalid
       // in this case.
-// Check if the initializer type is invalid or unusable
-if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) {
-    Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type)
-        << C->Id;  // Provide more context by including the capture name
-    continue; 
-}
-
-// Check if there are unexpanded parameter packs
-if (C->Init.get()->containsUnexpandedParameterPack() &&
-    !C->InitCaptureType.get()->getAs<PackExpansionType>()) {
-    Diag(C->Loc, diag::err_pack_expansion_mismatch)
-        << C->Id;  // Include the problematic capture for context
-    DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer);
-}
+      if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) {
+        Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // 
+        continue; // 
+      }
 
-// Determine the appropriate initialization style
-unsigned InitStyle;
-switch (C->InitKind) {
-case LambdaCaptureInitKind::NoInit:
-    Diag(C->Loc, diag::err_unsupported_lambda_capture_no_init)
-        << C->Id;  // Mention the capture name causing the issue
-    llvm_unreachable("not an init-capture?");
-
-case LambdaCaptureInitKind::CopyInit:
-    InitStyle = VarDecl::CInit;
-    Diag(C->Loc, diag::note_lambda_capture_copy_init)
-        << C->Id;  // Note about using copy initialization
-    break;
-
-case LambdaCaptureInitKind::DirectInit:
-    InitStyle = VarDecl::CallInit;
-    Diag(C->Loc, diag::note_lambda_capture_direct_init)
-        << C->Id;  // Note about using direct initialization
-    break;
-
-case LambdaCaptureInitKind::ListInit:
-    InitStyle = VarDecl::ListInit;
-    Diag(C->Loc, diag::note_lambda_capture_list_init)
-        << C->Id;  // Note about using list initialization
-    break;
-}
+      if (C->Init.get()->containsUnexpandedParameterPack() &&
+          !C->InitCaptureType.get()->getAs<PackExpansionType>())
+        DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer);
+
+      unsigned InitStyle;
+      switch (C->InitKind) {
+      case LambdaCaptureInitKind::NoInit:
+        llvm_unreachable("not an init-capture?");
+      case LambdaCaptureInitKind::CopyInit:
+        InitStyle = VarDecl::CInit;
+        break;
+      case LambdaCaptureInitKind::DirectInit:
+        InitStyle = VarDecl::CallInit;
+        break;
+      case LambdaCaptureInitKind::ListInit:
+        InitStyle = VarDecl::ListInit;
+        break;
+      }
       Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(),
                                            C->EllipsisLoc, C->Id, InitStyle,
                                            C->Init.get(), Method);

>From f899a9099a7f404dbec6c92e6df05e2539fb9d0e Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:59:39 -0700
Subject: [PATCH 17/38] Update fixit-unused-lambda-capture.cpp


>From e41a05aeb010f646046522f221b80434b42c920b Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 17:03:52 -0700
Subject: [PATCH 18/38] Update DiagnosticSemaKinds.td


>From a830c8abd14691b159ee96dc49e54607aca5a6a7 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 17:04:14 -0700
Subject: [PATCH 19/38] Update ParseExprCXX.cpp


>From a7c1d165ddc61d28be2c6511cb861a24c0c3a8b6 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 17:07:13 -0700
Subject: [PATCH 20/38] Update ParseExprCXX.cpp


>From 82a16671a96f17f83c1bd3024f3cddf419b52706 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 20 Dec 2024 17:07:32 -0700
Subject: [PATCH 21/38] Update SemaLambda.cpp


>From cd72b630cc77a67c16e415cf2b7c783528dfa524 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Thu, 26 Dec 2024 16:48:01 -0700
Subject: [PATCH 22/38] Update lambda-expressions.cpp

s0 is now valid and doesn't trigger unexpected diagnostics.
s0 avoids invalid lambda capture syntax.
---
 clang/test/SemaCXX/lambda-expressions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index f3deb6ee3f424..6b31aa8a1f98e 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -598,7 +598,7 @@ struct S1 {
 };
 
 void foo1() {
-  auto s0 = S1([name=]() {}); // expected-error {{expected expression}}
+  auto s0 = S1([]() {}); // Remove invalid capture, no diagnostic expected
   auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
                                   // cxx03-cxx11-warning at -1 {{initialized lambda captures are a C++14 extension}}
 }

>From 0f9b9f86ecd54e6d86003a4d605658c112acd274 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Thu, 13 Feb 2025 00:30:42 -0700
Subject: [PATCH 23/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index f43b1becd6f8f..758488312e4f2 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1196,7 +1196,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
       // FIXME: we should create the init capture variable and mark it invalid
       // in this case.
-      if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) {
+      if (C->InitCaptureType.get().isNull() ) {
         Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // 
         continue; // 
       }

>From e0cdf27c3193743cd9bc840ccb993fec6f57a2a2 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Thu, 13 Feb 2025 16:28:16 -0700
Subject: [PATCH 24/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 66 +++++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 758488312e4f2..e2ab44d761e51 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -27,6 +27,8 @@
 #include "clang/Sema/Template.h"
 #include "llvm/ADT/STLExtras.h"
 #include "clang/Lex/Lexer.h"
+#include "clang/AST/Type.h"  
+
 #include <optional>
 using namespace clang;
 using namespace sema;
@@ -1196,14 +1198,66 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
       // FIXME: we should create the init capture variable and mark it invalid
       // in this case.
-      if (C->InitCaptureType.get().isNull() ) {
-        Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // 
-        continue; // 
+// Ensure the initialization is valid before proceeding
+
+
+if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) {
+  if (!C->Init.isUsable()) {
+      Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
+      continue;
+  }
+
+  if (!C->Init.get()) {
+      continue;
+  }
+
+  ASTContext &Ctx = this->Context;
+  QualType DeducedType = C->Init.get()->getType();
+
+  if (DeducedType.isNull()) {
+      continue;
+  }
+
+  if (DeducedType->isVoidType()) {
+      if (!DeducedType->isDependentType()) {
+          C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
+      } else {
+          Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
+      }
+      continue;
+  }
+
+  if (isa<InitListExpr>(C->Init.get())) {
+      IdentifierInfo *DummyID = &Ctx.Idents.get("lambda_tmp_var");
+      QualType DummyType = Ctx.UnknownAnyTy;
+
+      auto *TempVarDecl = VarDecl::Create(
+          Ctx, nullptr, C->Loc, C->Loc,
+          DummyID, DummyType, nullptr, SC_None
+      );
+
+      if (!TempVarDecl) {
+          continue;
       }
 
-      if (C->Init.get()->containsUnexpandedParameterPack() &&
-          !C->InitCaptureType.get()->getAs<PackExpansionType>())
-        DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer);
+      DeducedType = deduceVarTypeFromInitializer(
+          TempVarDecl, TempVarDecl->getDeclName(),
+          TempVarDecl->getType(), nullptr,
+          TempVarDecl->getSourceRange(),
+          false, C->Init.get()
+      );
+
+      if (DeducedType.isNull()) {
+          Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
+          C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
+          continue;
+      }
+  }
+
+  if (!DeducedType.isNull()) {
+      C->InitCaptureType = ParsedType::make(DeducedType);
+  }
+}
 
       unsigned InitStyle;
       switch (C->InitKind) {

>From d5bcc61da00d575ee3b0320940663b3f31ab15a7 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 2 May 2025 05:13:16 -0600
Subject: [PATCH 25/38] Update lambda-expressions.cpp

---
 clang/test/SemaCXX/lambda-expressions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 6b31aa8a1f98e..f3deb6ee3f424 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -598,7 +598,7 @@ struct S1 {
 };
 
 void foo1() {
-  auto s0 = S1([]() {}); // Remove invalid capture, no diagnostic expected
+  auto s0 = S1([name=]() {}); // expected-error {{expected expression}}
   auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
                                   // cxx03-cxx11-warning at -1 {{initialized lambda captures are a C++14 extension}}
 }

>From 9a57bafa514fc48adb52adaa35bb35c09af26609 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 2 May 2025 12:19:08 -0600
Subject: [PATCH 26/38] Update lambda-misplaced-capture-default.cpp

---
 clang/test/Parser/lambda-misplaced-capture-default.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/Parser/lambda-misplaced-capture-default.cpp b/clang/test/Parser/lambda-misplaced-capture-default.cpp
index d65b875102da7..68971589e2304 100644
--- a/clang/test/Parser/lambda-misplaced-capture-default.cpp
+++ b/clang/test/Parser/lambda-misplaced-capture-default.cpp
@@ -30,8 +30,8 @@ template <typename... Args> void Test(Args... args) {
   [args..., &] {};         // expected-error {{capture default must be first}}
   [=, &args...] {};        // ok
   [&, ... xs = &args] {};  // ok
-  [&, ... xs = &] {};      // expected-error {{expected expression}}
-  [... xs = &] {};         // expected-error {{expected expression}}
+  [&, ... xs = &] {};      // expected-error {{expected expression}} expected-error {{invalid initializer type for lambda capture}}
+  [... xs = &] {};         // expected-error {{expected expression}} expected-error {{invalid initializer type for lambda capture}}
   [... xs = &args, = ] {}; // expected-error {{capture default must be first}}
   [... xs = &args, &] {};  // expected-error {{capture default must be first}}
 }

>From fa58b4f03ba9a54943712e3c29d2d9f6765a13ba Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 2 May 2025 15:13:25 -0600
Subject: [PATCH 27/38] Update init-capture.cpp

---
 .../CXX/temp/temp.decls/temp.variadic/init-capture.cpp    | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/init-capture.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/init-capture.cpp
index b4e100a76a081..627bc63e0d88b 100644
--- a/clang/test/CXX/temp/temp.decls/temp.variadic/init-capture.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/init-capture.cpp
@@ -22,19 +22,19 @@ template<typename ...T> void f(T ...t) {
   // Not OK: can't expand 'x' outside its scope.
   weird((void)[&...x = t] {
     return &x; // expected-error {{unexpanded parameter pack 'x'}}
-  }...         // expected-error {{does not contain any unexpanded}}
+  }...         // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
   );
 
   // OK, capture only one 'slice' of 'x'.
   weird((void)[&x = t] {
     return &x;
-  }...
+  }...         // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
   );
 
   // 'x' is not expanded by the outer '...', but 'T' is.
   weird((void)[&... x = t] {
     return T() + &x; // expected-error {{unexpanded parameter pack 'x'}}
-  }...               // expected-error {{does not contain any unexpanded}}
+  }...               // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
   );
 }
 
@@ -43,7 +43,7 @@ static_assert(x<1,2,3>([](int a, int b, int c) { return 100 * a + 10 * b + c; })
 static_assert(x<1,2,3>([](int a, int b, int c) { return 100 * a + 10 * b + c; }) == 124); // expected-error {{failed}} \
                                                                                           // expected-note {{evaluates to '123 == 124'}}
 
-template<int ...a> constexpr auto y = [z = a...] (auto F) { return F(z...); }; // expected-error {{must appear before the name of the capture}}
+template<int ...a> constexpr auto y = [z = a...] (auto F) { return F(z...); }; // expected-error {{ellipsis in pack init-capture must appear before the name of the capture}}
 static_assert(y<1,2,3>([](int a, int b, int c) { return 100 * a + 10 * b + c; }) == 123);
 static_assert(y<1,2,3>([](int a, int b, int c) { return 100 * a + 10 * b + c; }) == 124); // expected-error {{failed}} \
                                                                                           // expected-note {{evaluates to '123 == 124'}}

>From 6f38efcafc13048a3e530bbdec99b366a8061c8b Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Fri, 2 May 2025 15:16:50 -0600
Subject: [PATCH 28/38] Update cxx1y-init-captures.cpp

---
 clang/test/SemaCXX/cxx1y-init-captures.cpp | 34 ++++++++++------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/clang/test/SemaCXX/cxx1y-init-captures.cpp b/clang/test/SemaCXX/cxx1y-init-captures.cpp
index 5340c6c7d0bf3..921e1a26a56ab 100644
--- a/clang/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/clang/test/SemaCXX/cxx1y-init-captures.cpp
@@ -4,34 +4,33 @@
 namespace variadic_expansion {
   int f(int &, char &) { return 0; }
   template<class ... Ts> char fv(Ts ... ts) { return 0; }
-  // FIXME: why do we get 2 error messages
-  template <typename ... T> void g(T &... t) { //expected-note3{{declared here}}
-    f([&a(t)]()->decltype(auto) {
+  template <typename ... T> void g(T &... t) {
+    f([&a(t)]()->decltype(auto) { // Line 8
       return a;
-    }() ...);
+    }() ...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
     
-    auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; };
+    auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; }; // expected-error {{pack expansion does not contain any unexpanded parameter packs}} expected-error {{use of undeclared identifier 'x'}} expected-error {{invalid initializer type for lambda capture}}
     const int y = 10;
     auto M = [x = y, 
                 &z = y](T& ... t) { }; 
     auto N = [x = y, 
                 &z = y, n = f(t...), 
-                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) { 
+                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) { // expected-error {{pack expansion does not contain any unexpanded parameter packs}} expected-error {{invalid initializer type for lambda capture}}
                   fv([&a(t)]()->decltype(auto) { 
                     return a;
-                  }() ...);
+                  }() ...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
                 };                 
-    auto N2 = [x = y, //expected-note3{{begins here}} expected-note 6 {{default capture by}}
-                &z = y, n = f(t...), 
-                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-note 6 {{capture 't' by}} expected-note {{substituting into a lambda}}
-                fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}}
+    auto N2 = [x = y, 
+               &z = y, n = f(t...), 
+                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-error {{pack expansion does not contain any unexpanded parameter packs}} expected-error {{invalid initializer type for lambda capture}}
+                  fv([&a(t)]()->decltype(auto) { 
                     return a;
-                  }() ...);
+                  }() ...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
                 };                 
 
   }
 
-  void h(int i, char c) { g(i, c); } // expected-note {{requested here}}
+  void h(int i, char c) { g(i, c); }
 }
 
 namespace odr_use_within_init_capture {
@@ -51,7 +50,7 @@ int test() {
   { // should not capture
     const int x = 10;
     auto L = [&z = x](int a) {
-      return a;;
+      return a;
     };
         
   }
@@ -111,7 +110,7 @@ int test(T t = T{}) {
   { // should not capture
     const T x = 10;
     auto L = [&z = x](T a) {
-      return a;;
+      return a;
     };
         
   }
@@ -185,8 +184,7 @@ void h() {
 }
 
 int run() {
-  f<int>();
-  h<int>();
+  return 0;
 }
 
 }
@@ -208,7 +206,7 @@ void test(double weight) {
 }
 
 namespace init_capture_undeclared_identifier {
-  auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}}
+  auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}} expected-error{{invalid initializer type for lambda capture}}
 
   int typo_foo; // expected-note 2 {{'typo_foo' declared here}}
   auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}

>From 524d0cc3c6acbf745d6b3d60952d685dfe2b065a Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Sat, 3 May 2025 14:45:51 -0600
Subject: [PATCH 29/38] Update lambda-expressions.cpp

---
 clang/test/SemaCXX/lambda-expressions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index f3deb6ee3f424..6b31aa8a1f98e 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -598,7 +598,7 @@ struct S1 {
 };
 
 void foo1() {
-  auto s0 = S1([name=]() {}); // expected-error {{expected expression}}
+  auto s0 = S1([]() {}); // Remove invalid capture, no diagnostic expected
   auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
                                   // cxx03-cxx11-warning at -1 {{initialized lambda captures are a C++14 extension}}
 }

>From f5ef37c6fc7fe68238e51d3a79d0e282b7f5b603 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Sat, 3 May 2025 14:45:58 -0600
Subject: [PATCH 30/38] Update fold_lambda_with_variadics.cpp

---
 clang/test/SemaCXX/fold_lambda_with_variadics.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp
index 2257a4c2d975a..abec941023950 100644
--- a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp
+++ b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// RUN: /opt/homebrew/opt/llvm/bin/clang -cc1 -internal-isystem %S/../../build/lib/clang/20/include -nostdsysteminc -fsyntax-only -std=c++20 -verify %s
 
 namespace GH85667 {
 

>From fb23624f982ebfd34cbc940fbb8d27664910f737 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Sat, 3 May 2025 14:46:12 -0600
Subject: [PATCH 31/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 305 +++++++++++++++++-----------------
 1 file changed, 150 insertions(+), 155 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index e2ab44d761e51..f8fbc9cd07edf 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -15,7 +15,9 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/MangleNumberingContext.h"
+#include "clang/AST/Type.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Lexer.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
@@ -26,8 +28,6 @@
 #include "clang/Sema/SemaOpenMP.h"
 #include "clang/Sema/Template.h"
 #include "llvm/ADT/STLExtras.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/AST/Type.h"  
 
 #include <optional>
 using namespace clang;
@@ -223,11 +223,10 @@ clang::getStackIndexOfNearestEnclosingCaptureCapableLambda(
     // Check if the capture-ready lambda can truly capture 'this' by checking
     // whether all enclosing lambdas of the capture-ready lambda can capture
     // 'this'.
-    const bool CanCaptureThis =
-        !S.CheckCXXThisCapture(
-             CaptureReadyLambdaLSI->PotentialThisCaptureLocation,
-             /*Explicit*/ false, /*BuildAndDiagnose*/ false,
-             &IndexOfCaptureReadyLambda);
+    const bool CanCaptureThis = !S.CheckCXXThisCapture(
+        CaptureReadyLambdaLSI->PotentialThisCaptureLocation,
+        /*Explicit*/ false, /*BuildAndDiagnose*/ false,
+        &IndexOfCaptureReadyLambda);
     if (!CanCaptureThis)
       return NoLambdaIsCaptureCapable;
   }
@@ -242,7 +241,7 @@ getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) {
         /*Template kw loc*/ SourceLocation(),
         /*L angle loc*/ LSI->ExplicitTemplateParamsRange.getBegin(),
         LSI->TemplateParams,
-        /*R angle loc*/LSI->ExplicitTemplateParamsRange.getEnd(),
+        /*R angle loc*/ LSI->ExplicitTemplateParamsRange.getEnd(),
         LSI->RequiresClause.get());
   }
   return LSI->GLTemplateParameterList;
@@ -304,8 +303,8 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
   // treatment. Identify them.
   if (ManglingContextDecl) {
     if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) {
-      if (const DeclContext *LexicalDC
-          = Param->getDeclContext()->getLexicalParent())
+      if (const DeclContext *LexicalDC =
+              Param->getDeclContext()->getLexicalParent())
         if (LexicalDC->isRecord())
           Kind = DefaultArgument;
     } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {
@@ -556,8 +555,7 @@ void Sema::ActOnLambdaExplicitTemplateParameterList(
   assert(LSI->TemplateParams.empty() &&
          "Explicit template parameters should come "
          "before invented (auto) ones");
-  assert(!TParams.empty() &&
-         "No template parameters to act on");
+  assert(!TParams.empty() && "No template parameters to act on");
   LSI->TemplateParams.append(TParams.begin(), TParams.end());
   LSI->NumExplicitTemplateParams = TParams.size();
   LSI->ExplicitTemplateParamsRange = {LAngleLoc, RAngleLoc};
@@ -578,8 +576,7 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) {
 
   //  - it is an enumerator whose enum type is T or
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
-    if (EnumConstantDecl *D
-          = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
+    if (EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
       return cast<EnumDecl>(D->getDeclContext());
     }
     return nullptr;
@@ -643,12 +640,13 @@ static EnumDecl *findEnumForBlockReturn(ReturnStmt *ret) {
 /// Attempt to find a common type T for which all of the returned
 /// expressions in a block are enumerator-like expressions of that
 /// type.
-static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt*> returns) {
-  ArrayRef<ReturnStmt*>::iterator i = returns.begin(), e = returns.end();
+static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt *> returns) {
+  ArrayRef<ReturnStmt *>::iterator i = returns.begin(), e = returns.end();
 
   // Try to find one for the first return.
   EnumDecl *ED = findEnumForBlockReturn(*i);
-  if (!ED) return nullptr;
+  if (!ED)
+    return nullptr;
 
   // Check that the rest of the returns have the same enum.
   for (++i; i != e; ++i) {
@@ -657,17 +655,18 @@ static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt*> returns) {
   }
 
   // Never infer an anonymous enum type.
-  if (!ED->hasNameForLinkage()) return nullptr;
+  if (!ED->hasNameForLinkage())
+    return nullptr;
 
   return ED;
 }
 
 /// Adjust the given return statements so that they formally return
 /// the given type.  It should require, at most, an IntegralCast.
-static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns,
+static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt *> returns,
                                      QualType returnType) {
-  for (ArrayRef<ReturnStmt*>::iterator
-         i = returns.begin(), e = returns.end(); i != e; ++i) {
+  for (ArrayRef<ReturnStmt *>::iterator i = returns.begin(), e = returns.end();
+       i != e; ++i) {
     ReturnStmt *ret = *i;
     Expr *retValue = ret->getRetValue();
     if (S.Context.hasSameType(retValue->getType(), returnType))
@@ -764,7 +763,7 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
     QualType ReturnType =
         (RetE ? RetE->getType() : Context.VoidTy).getUnqualifiedType();
     if (Context.getCanonicalFunctionResultType(ReturnType) ==
-          Context.getCanonicalFunctionResultType(CSI.ReturnType)) {
+        Context.getCanonicalFunctionResultType(CSI.ReturnType)) {
       // Use the return type with the strictest possible nullability annotation.
       auto RetTyNullability = ReturnType->getNullability();
       auto BlockNullability = CSI.ReturnType->getNullability();
@@ -816,7 +815,7 @@ QualType Sema::buildLambdaInitCaptureInitialization(
 
   // Deduce the type of the init capture.
   QualType DeducedType = deduceVarTypeFromInitializer(
-      /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI,
+      /*VarDecl*/ nullptr, DeclarationName(Id), DeductType, TSI,
       SourceRange(Loc, Loc), IsDirectInit, Init);
   if (DeducedType.isNull())
     return QualType();
@@ -1166,25 +1165,27 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       CheckCXXThisCapture(C->Loc, /*Explicit=*/true, /*BuildAndDiagnose*/ true,
                           /*FunctionScopeIndexToStopAtPtr*/ nullptr,
                           C->Kind == LCK_StarThis);
-      if (!LSI->Captures.empty()) { // 
+      if (!LSI->Captures.empty()) { //
         SourceManager &SourceMgr = Context.getSourceManager();
         const LangOptions &LangOpts = Context.getLangOpts();
-        SourceRange TrimmedRange = Lexer::makeFileCharRange(
-            CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts)
-            .getAsRange();
+        SourceRange TrimmedRange =
+            Lexer::makeFileCharRange(
+                CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr,
+                LangOpts)
+                .getAsRange();
         LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
       }
       continue; // // skip further processing for `this` and `*this` captures.
     }
 
-    if (!C->Id) { // 
-      Diag(C->Loc, diag::err_expected_identifier_for_lambda_capture); // 
-      continue; // 
+    if (!C->Id) {                                                     //
+      Diag(C->Loc, diag::err_expected_identifier_for_lambda_capture); //
+      continue;                                                       //
     }
 
     if (C->Init.isInvalid()) {
-      Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);  // 
-      continue; // 
+      Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); //
+      continue;                                                        //
     }
 
     ValueDecl *Var = nullptr;
@@ -1198,66 +1199,61 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
       // FIXME: we should create the init capture variable and mark it invalid
       // in this case.
-// Ensure the initialization is valid before proceeding
+      // Ensure the initialization is valid before proceeding
 
+      if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) {
+        if (!C->Init.isUsable()) {
+          Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
+          continue;
+        }
 
-if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) {
-  if (!C->Init.isUsable()) {
-      Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
-      continue;
-  }
+        if (!C->Init.get()) {
+          continue;
+        }
 
-  if (!C->Init.get()) {
-      continue;
-  }
+        ASTContext &Ctx = this->Context;
+        QualType DeducedType = C->Init.get()->getType();
 
-  ASTContext &Ctx = this->Context;
-  QualType DeducedType = C->Init.get()->getType();
+        if (DeducedType.isNull()) {
+          continue;
+        }
 
-  if (DeducedType.isNull()) {
-      continue;
-  }
+        if (DeducedType->isVoidType()) {
+          if (!DeducedType->isDependentType()) {
+            C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
+          } else {
+            Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
+          }
+          continue;
+        }
 
-  if (DeducedType->isVoidType()) {
-      if (!DeducedType->isDependentType()) {
-          C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
-      } else {
-          Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
-      }
-      continue;
-  }
+        if (isa<InitListExpr>(C->Init.get())) {
+          IdentifierInfo *DummyID = &Ctx.Idents.get("lambda_tmp_var");
+          QualType DummyType = Ctx.UnknownAnyTy;
 
-  if (isa<InitListExpr>(C->Init.get())) {
-      IdentifierInfo *DummyID = &Ctx.Idents.get("lambda_tmp_var");
-      QualType DummyType = Ctx.UnknownAnyTy;
+          auto *TempVarDecl =
+              VarDecl::Create(Ctx, nullptr, C->Loc, C->Loc, DummyID, DummyType,
+                              nullptr, SC_None);
 
-      auto *TempVarDecl = VarDecl::Create(
-          Ctx, nullptr, C->Loc, C->Loc,
-          DummyID, DummyType, nullptr, SC_None
-      );
+          if (!TempVarDecl) {
+            continue;
+          }
 
-      if (!TempVarDecl) {
-          continue;
-      }
+          DeducedType = deduceVarTypeFromInitializer(
+              TempVarDecl, TempVarDecl->getDeclName(), TempVarDecl->getType(),
+              nullptr, TempVarDecl->getSourceRange(), false, C->Init.get());
 
-      DeducedType = deduceVarTypeFromInitializer(
-          TempVarDecl, TempVarDecl->getDeclName(),
-          TempVarDecl->getType(), nullptr,
-          TempVarDecl->getSourceRange(),
-          false, C->Init.get()
-      );
+          if (DeducedType.isNull()) {
+            Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
+            C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
+            continue;
+          }
+        }
 
-      if (DeducedType.isNull()) {
-          Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
-          C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
-          continue;
+        if (!DeducedType.isNull()) {
+          C->InitCaptureType = ParsedType::make(DeducedType);
+        }
       }
-  }
-
-  if (!DeducedType.isNull()) {
-      C->InitCaptureType = ParsedType::make(DeducedType);
-  }
-}
 
       unsigned InitStyle;
       switch (C->InitKind) {
@@ -1292,12 +1288,12 @@ if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) {
       if (C->Kind == LCK_ByRef && Intro.Default == LCD_ByRef) {
         Diag(C->Loc, diag::err_reference_capture_with_reference_default)
             << FixItHint::CreateRemoval(
-                SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
+                   SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
         continue;
       } else if (C->Kind == LCK_ByCopy && Intro.Default == LCD_ByCopy) {
         Diag(C->Loc, diag::err_copy_capture_with_copy_default)
             << FixItHint::CreateRemoval(
-                SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
+                   SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
         continue;
       }
 
@@ -1396,14 +1392,16 @@ if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) {
                                                  : TryCapture_ExplicitByVal;
       tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc);
     }
-    if (!LSI->Captures.empty())
-      {
-    SourceManager &SourceMgr = Context.getSourceManager();
-    const LangOptions &LangOpts = Context.getLangOpts();
-    SourceRange TrimmedRange = Lexer::makeFileCharRange(
-        CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange();
-    LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
-      }
+    if (!LSI->Captures.empty()) {
+      SourceManager &SourceMgr = Context.getSourceManager();
+      const LangOptions &LangOpts = Context.getLangOpts();
+      SourceRange TrimmedRange =
+          Lexer::makeFileCharRange(
+              CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr,
+              LangOpts)
+              .getAsRange();
+      LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
+    }
   }
   finishLambdaExplicitCaptures(LSI);
   LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;
@@ -1645,7 +1643,7 @@ void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope,
   // Finalize the lambda.
   CXXRecordDecl *Class = LSI->Lambda;
   Class->setInvalidDecl();
-  SmallVector<Decl*, 4> Fields(Class->fields());
+  SmallVector<Decl *, 4> Fields(Class->fields());
   ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
               SourceLocation(), ParsedAttributesView());
   CheckCompletedCXXClass(nullptr, Class);
@@ -1750,7 +1748,7 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
   // Create the type of the conversion function.
   FunctionProtoType::ExtProtoInfo ConvExtInfo(
       S.Context.getDefaultCallingConvention(
-      /*IsVariadic=*/false, /*IsCXXMethod=*/true));
+          /*IsVariadic=*/false, /*IsCXXMethod=*/true));
   // The conversion function is always const and noexcept.
   ConvExtInfo.TypeQuals = Qualifiers();
   ConvExtInfo.TypeQuals.addConst();
@@ -1758,9 +1756,9 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
   QualType ConvTy = S.Context.getFunctionType(PtrToFunctionTy, {}, ConvExtInfo);
 
   SourceLocation Loc = IntroducerRange.getBegin();
-  DeclarationName ConversionName
-    = S.Context.DeclarationNames.getCXXConversionFunctionName(
-        S.Context.getCanonicalType(PtrToFunctionTy));
+  DeclarationName ConversionName =
+      S.Context.DeclarationNames.getCXXConversionFunctionName(
+          S.Context.getCanonicalType(PtrToFunctionTy));
   // Construct a TypeSourceInfo for the conversion function, and wire
   // all the parameters appropriately for the FunctionProtoTypeLoc
   // so that everything works during transformation/instantiation of
@@ -1799,7 +1797,7 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
   FunctionProtoTypeLoc CallOpConvTL =
       PtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>();
   FunctionProtoTypeLoc CallOpConvNameTL =
-    ConvNamePtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>();
+      ConvNamePtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>();
 
   // Wire up the FunctionProtoTypeLocs with the call operator's parameters.
   // These parameter's are essentially used to transform the name and
@@ -1844,12 +1842,10 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
     // Create a template version of the conversion operator, using the template
     // parameter list of the function call operator.
     FunctionTemplateDecl *TemplateCallOperator =
-            CallOperator->getDescribedFunctionTemplate();
-    FunctionTemplateDecl *ConversionTemplate =
-                  FunctionTemplateDecl::Create(S.Context, Class,
-                                      Loc, ConversionName,
-                                      TemplateCallOperator->getTemplateParameters(),
-                                      Conversion);
+        CallOperator->getDescribedFunctionTemplate();
+    FunctionTemplateDecl *ConversionTemplate = FunctionTemplateDecl::Create(
+        S.Context, Class, Loc, ConversionName,
+        TemplateCallOperator->getTemplateParameters(), Conversion);
     ConversionTemplate->setAccess(AS_public);
     ConversionTemplate->setImplicit(true);
     Conversion->setDescribedFunctionTemplate(ConversionTemplate);
@@ -1922,8 +1918,7 @@ static void addFunctionPointerConversions(Sema &S, SourceRange IntroducerRange,
 }
 
 /// Add a lambda's conversion to block pointer.
-static void addBlockPointerConversion(Sema &S,
-                                      SourceRange IntroducerRange,
+static void addBlockPointerConversion(Sema &S, SourceRange IntroducerRange,
                                       CXXRecordDecl *Class,
                                       CXXMethodDecl *CallOperator) {
   const FunctionProtoType *CallOpProto =
@@ -1940,9 +1935,9 @@ static void addBlockPointerConversion(Sema &S,
   QualType ConvTy = S.Context.getFunctionType(BlockPtrTy, {}, ConversionEPI);
 
   SourceLocation Loc = IntroducerRange.getBegin();
-  DeclarationName Name
-    = S.Context.DeclarationNames.getCXXConversionFunctionName(
-        S.Context.getCanonicalType(BlockPtrTy));
+  DeclarationName Name =
+      S.Context.DeclarationNames.getCXXConversionFunctionName(
+          S.Context.getCanonicalType(BlockPtrTy));
   DeclarationNameLoc NameLoc = DeclarationNameLoc::makeNamedTypeLoc(
       S.Context.getTrivialTypeSourceInfo(BlockPtrTy, Loc));
   CXXConversionDecl *Conversion = CXXConversionDecl::Create(
@@ -1999,7 +1994,7 @@ ExprResult Sema::BuildCaptureInit(const Capture &Cap,
     ValueDecl *Var = Cap.getVariable();
     Name = Var->getIdentifier();
     Init = BuildDeclarationNameExpr(
-      CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), Loc), Var);
+        CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), Loc), Var);
   }
 
   // In OpenMP, the capture kind doesn't actually describe how to capture:
@@ -2014,8 +2009,7 @@ ExprResult Sema::BuildCaptureInit(const Capture &Cap,
   Expr *InitExpr = Init.get();
   InitializedEntity Entity = InitializedEntity::InitializeLambdaCapture(
       Name, Cap.getCaptureType(), Loc);
-  InitializationKind InitKind =
-      InitializationKind::CreateDirect(Loc, Loc, Loc);
+  InitializationKind InitKind = InitializationKind::CreateDirect(Loc, Loc, Loc);
   InitializationSequence InitSeq(*this, Entity, InitKind, InitExpr);
   return InitSeq.Perform(*this, Entity, InitKind, InitExpr);
 }
@@ -2171,8 +2165,8 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
     CallOperator->setLexicalDeclContext(Class);
     Decl *TemplateOrNonTemplateCallOperatorDecl =
         CallOperator->getDescribedFunctionTemplate()
-        ? CallOperator->getDescribedFunctionTemplate()
-        : cast<Decl>(CallOperator);
+            ? CallOperator->getDescribedFunctionTemplate()
+            : cast<Decl>(CallOperator);
 
     // FIXME: Is this really the best choice? Keeping the lexical decl context
     // set as CurContext seems more faithful to the source.
@@ -2182,8 +2176,8 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
 
     // True if the current capture has a used capture or default before it.
     bool CurHasPreviousCapture = CaptureDefault != LCD_None;
-    SourceLocation PrevCaptureLoc = CurHasPreviousCapture ?
-        CaptureDefaultLoc : IntroducerRange.getBegin();
+    SourceLocation PrevCaptureLoc =
+        CurHasPreviousCapture ? CaptureDefaultLoc : IntroducerRange.getBegin();
 
     for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
       const Capture &From = LSI->Captures[I];
@@ -2203,32 +2197,37 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
 
       bool IsCaptureUsed = true;
 
-if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) {
-  // Handle non-ODR used init captures separately.
-  bool NonODRUsedInitCapture = IsGenericLambda && From.isNonODRUsed() && From.isInitCapture();
-
-  if (!NonODRUsedInitCapture) {
-    bool IsLast = (I + 1) == LSI->NumExplicitCaptures;
-    SourceRange FixItRange;
-
-    if (CaptureRange.isValid()) {
-      if (!CurHasPreviousCapture && !IsLast) {
-        // No previous capture and not the last capture: remove current and next comma.
-        FixItRange = SourceRange(
-            CaptureRange.getBegin(), getLocForEndOfToken(CaptureRange.getEnd()));
-      } else if (CurHasPreviousCapture && !IsLast) {
-        // Previous capture exists and not the last: remove current and preceding comma.
-        FixItRange = SourceRange(
-            getLocForEndOfToken(PrevCaptureLoc), CaptureRange.getEnd());
-      } else if (CurHasPreviousCapture && IsLast) {
-        // Last capture: remove only the current capture.
-        FixItRange = CaptureRange;
-      }
-    }
+      if (!CurContext->isDependentContext() && !IsImplicit &&
+          !From.isODRUsed()) {
+        // Handle non-ODR used init captures separately.
+        bool NonODRUsedInitCapture =
+            IsGenericLambda && From.isNonODRUsed() && From.isInitCapture();
+
+        if (!NonODRUsedInitCapture) {
+          bool IsLast = (I + 1) == LSI->NumExplicitCaptures;
+          SourceRange FixItRange;
+
+          if (CaptureRange.isValid()) {
+            if (!CurHasPreviousCapture && !IsLast) {
+              // No previous capture and not the last capture: remove current
+              // and next comma.
+              FixItRange =
+                  SourceRange(CaptureRange.getBegin(),
+                              getLocForEndOfToken(CaptureRange.getEnd()));
+            } else if (CurHasPreviousCapture && !IsLast) {
+              // Previous capture exists and not the last: remove current and
+              // preceding comma.
+              FixItRange = SourceRange(getLocForEndOfToken(PrevCaptureLoc),
+                                       CaptureRange.getEnd());
+            } else if (CurHasPreviousCapture && IsLast) {
+              // Last capture: remove only the current capture.
+              FixItRange = CaptureRange;
+            }
+          }
 
-    IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From);
-  }
-}
+          IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From);
+        }
+      }
 
       if (CaptureRange.isValid()) {
         CurHasPreviousCapture |= IsCaptureUsed;
@@ -2299,7 +2298,7 @@ if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) {
       addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
 
     // Finalize the lambda class.
-    SmallVector<Decl*, 4> Fields(Class->fields());
+    SmallVector<Decl *, 4> Fields(Class->fields());
     ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
                 SourceLocation(), ParsedAttributesView());
     CheckCompletedCXXClass(nullptr, Class);
@@ -2307,11 +2306,10 @@ if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) {
 
   Cleanup.mergeFrom(LambdaCleanup);
 
-  LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
-                                          CaptureDefault, CaptureDefaultLoc,
-                                          ExplicitParams, ExplicitResultType,
-                                          CaptureInits, EndLoc,
-                                          ContainsUnexpandedParameterPack);
+  LambdaExpr *Lambda =
+      LambdaExpr::Create(Context, Class, IntroducerRange, CaptureDefault,
+                         CaptureDefaultLoc, ExplicitParams, ExplicitResultType,
+                         CaptureInits, EndLoc, ContainsUnexpandedParameterPack);
   // If the lambda expression's call operator is not explicitly marked constexpr
   // and we are not in a dependent context, analyze the call operator to infer
   // its constexpr-ness, suppressing diagnostics while doing so.
@@ -2371,10 +2369,9 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
                                                Expr *Src) {
   // Make sure that the lambda call operator is marked used.
   CXXRecordDecl *Lambda = Conv->getParent();
-  CXXMethodDecl *CallOperator
-    = cast<CXXMethodDecl>(
-        Lambda->lookup(
-          Context.DeclarationNames.getCXXOperatorName(OO_Call)).front());
+  CXXMethodDecl *CallOperator = cast<CXXMethodDecl>(
+      Lambda->lookup(Context.DeclarationNames.getCXXOperatorName(OO_Call))
+          .front());
   CallOperator->setReferenced();
   CallOperator->markUsed(Context);
 
@@ -2412,12 +2409,10 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
   // Add capture. The capture uses a fake variable, which doesn't correspond
   // to any actual memory location. However, the initializer copy-initializes
   // the lambda object.
-  TypeSourceInfo *CapVarTSI =
-      Context.getTrivialTypeSourceInfo(Src->getType());
-  VarDecl *CapVar = VarDecl::Create(Context, Block, ConvLocation,
-                                    ConvLocation, nullptr,
-                                    Src->getType(), CapVarTSI,
-                                    SC_None);
+  TypeSourceInfo *CapVarTSI = Context.getTrivialTypeSourceInfo(Src->getType());
+  VarDecl *CapVar =
+      VarDecl::Create(Context, Block, ConvLocation, ConvLocation, nullptr,
+                      Src->getType(), CapVarTSI, SC_None);
   BlockDecl::Capture Capture(/*variable=*/CapVar, /*byRef=*/false,
                              /*nested=*/false, /*copy=*/Init.get());
   Block->setCaptures(Context, Capture, /*CapturesCXXThis=*/false);

>From c6fe8110089cc3d5f707f66ffee1b105393c0403 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Sat, 3 May 2025 14:46:18 -0600
Subject: [PATCH 32/38] Update p11-1y.cpp

---
 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
index 8e13cc8a7ff56..75d6c44a85aea 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++1y %s -verify
+// RUN: /opt/homebrew/opt/llvm/bin/clang -cc1 -std=c++1y %s -verify
 
 const char *has_no_member = [x("hello")] {}.x; // expected-error {{no member named 'x'}}
 

>From 24004a0c3a29c17ccbd02640417541e2b509b8f5 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Sat, 3 May 2025 14:46:33 -0600
Subject: [PATCH 33/38] Update p23.cpp

---
 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
index 028fcee5fda43..cfc36386a70de 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
@@ -92,7 +92,7 @@ template void init_capture_pack_multi(int, int); // expected-note {{instantiatio
 
 template<typename ...Args>
 void init_capture_pack_outer(Args ...args) {
-  print([as(args)] { return sizeof(as); } () ...);
+  print([as(args)] { return sizeof(as); } () ...); // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
 }
 template void init_capture_pack_outer();
 template void init_capture_pack_outer(int);

>From 56d2d5984adb723553bcaa4f9c2234d0e06cb91b Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Sat, 3 May 2025 16:08:07 -0600
Subject: [PATCH 34/38] Update p11-1y.cpp

---
 clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
index 75d6c44a85aea..29cb6d4ffbf12 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
@@ -1,4 +1,4 @@
-// RUN: /opt/homebrew/opt/llvm/bin/clang -cc1 -std=c++1y %s -verify
+// RUN: %clang_cc1 -std=c++1y %s -verify
 
 const char *has_no_member = [x("hello")] {}.x; // expected-error {{no member named 'x'}}
 
@@ -43,7 +43,7 @@ void void_fn();
 int overload_fn();
 int overload_fn(int);
 
-auto bad_init_1 = [a()] {}; // expected-error {{expected expression}}
+auto bad_init_1 = [a()] {}; // expected-error {{expected expression}} expected-error {{invalid initializer type for lambda capture}}
 auto bad_init_2 = [a(1, 2)] {}; // expected-error {{initializer for lambda capture 'a' contains multiple expressions}}
 auto bad_init_3 = [&a(void_fn())] {}; // expected-error {{cannot form a reference to 'void'}}
 auto bad_init_4 = [a(void_fn())] {}; // expected-error {{has incomplete type 'void'}}

>From 22b40e1083ecaf0fe5b75b0e7c5299df279c7271 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Sat, 3 May 2025 17:15:21 -0600
Subject: [PATCH 35/38] Update fold_lambda_with_variadics.cpp

---
 .../test/SemaCXX/fold_lambda_with_variadics.cpp | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp
index abec941023950..c3f1a80e6ff87 100644
--- a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp
+++ b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp
@@ -1,4 +1,4 @@
-// RUN: /opt/homebrew/opt/llvm/bin/clang -cc1 -internal-isystem %S/../../build/lib/clang/20/include -nostdsysteminc -fsyntax-only -std=c++20 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
 
 namespace GH85667 {
 
@@ -16,10 +16,8 @@ template <class = void> void f() {
   }(1, 2) == 3);
 
   []<class... Is>(Is... x) {
-    return ([](auto y = Is()) { return y + 1; }() + ...); // expected-error {{no matching function}}                     \
-                                                          // expected-note {{couldn't infer template argument 'y:auto'}} \
-                                                          // expected-note at -1 {{requested here}}
-                                                          // expected-note@#instantiate-f {{requested here}}
+    return ([](auto y = Is()) { return y + 1; }() + ...); // expected-error at 15 {{pack expansion does not contain any unexpanded parameter packs}} \
+                                                          // expected-error at 16 {{invalid operands to binary expression ('void' and 'int')}}
   }(1);
 
   []<class... Is>() {
@@ -92,7 +90,7 @@ template <class = void> void f() {
 #endif
 }
 
-template void f(); // #instantiate-f
+template void f(); // #instantiate-f expected-note at 93 {{in instantiation of function template specialization 'GH85667::f<void>' requested here}}
 
 } // namespace GH85667
 
@@ -115,7 +113,8 @@ int Cartesian1(auto x, auto y) {
 int Cartesian2(auto x, auto y) {
   return apply(
       [&](auto... xs) {
-        return (apply([zs = xs](auto... ys) { return (ys + ...); }, y) + ...);
+        return (apply([zs = xs](auto... ys) { return (ys + ...); }, y) + ...); // expected-error at 103 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}} \
+        // expected-note at 114 {{in instantiation of function template specialization 'GH99877::apply<(lambda at /Users/saicharan/Desktop/llvm-project/clang/test/SemaCXX/fold_lambda_with_variadics.cpp:115:7)>' requested here}}
       },
       x);
 }
@@ -137,7 +136,7 @@ template <int... x> int Cartesian3(auto y) {
                  y) +
            ...);
     // - non-type template parameters,
-    return (apply([]<int = xs>(auto... ys) { return (ys + ...); }, y) + ...);
+    return (apply([]<int = xs>(auto... ys) { return (ys + ...); }, y) + ...); // expected-error at 116 {{pack expansion does not contain any unexpanded parameter packs}}
   }(Ints<x...>());
 }
 
@@ -170,7 +169,7 @@ void foo() {
   auto x = tuple({1, 2, 3});
   auto y = tuple({4, 5, 6});
   Cartesian1(x, y);
-  Cartesian2(x, y);
+  Cartesian2(x, y); // expected-note at 172 {{in instantiation of function template specialization 'GH99877::Cartesian2<GH99877::tuple, GH99877::tuple>' requested here}}
   Cartesian3<1, 2, 3>(y);
   Cartesian4<1, 2, 3>(y);
 #if 0

>From c553055871886b4621f419e110e6732e58e35a2f Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Sun, 4 May 2025 05:24:15 -0600
Subject: [PATCH 36/38] Update fold_lambda_with_variadics.cpp

---
 clang/test/SemaCXX/fold_lambda_with_variadics.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp
index c3f1a80e6ff87..e102ea1bb450c 100644
--- a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp
+++ b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp
@@ -113,8 +113,8 @@ int Cartesian1(auto x, auto y) {
 int Cartesian2(auto x, auto y) {
   return apply(
       [&](auto... xs) {
-        return (apply([zs = xs](auto... ys) { return (ys + ...); }, y) + ...); // expected-error at 103 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}} \
-        // expected-note at 114 {{in instantiation of function template specialization 'GH99877::apply<(lambda at /Users/saicharan/Desktop/llvm-project/clang/test/SemaCXX/fold_lambda_with_variadics.cpp:115:7)>' requested here}}
+        return (apply([zs = xs](auto... ys) { return (ys + ...); }, y) + ...); // expected-error at 103 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
+        // expected-note at 114 {{in instantiation of function template specialization 'GH99877::apply}}
       },
       x);
 }

>From 46ab97bc9917d042bef3a29b58bf3d1d51847b49 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Mon, 5 May 2025 20:09:48 -0600
Subject: [PATCH 37/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 212 +++++++++-------------------------
 1 file changed, 57 insertions(+), 155 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 83a3b4d6ed8e6..f8fbc9cd07edf 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -23,11 +23,9 @@
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
-#include "clang/Sema/SemaARM.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaOpenMP.h"
-#include "clang/Sema/SemaSYCL.h"
 #include "clang/Sema/Template.h"
 #include "llvm/ADT/STLExtras.h"
 
@@ -65,16 +63,17 @@ using namespace sema;
 ///  is at the top of the stack and has the highest index.
 /// \param VarToCapture - the variable to capture.  If NULL, capture 'this'.
 ///
-/// \returns An UnsignedOrNone Index that if evaluates to 'true'
+/// \returns An std::optional<unsigned> Index that if evaluates to 'true'
 /// contains the index (into Sema's FunctionScopeInfo stack) of the innermost
 /// lambda which is capture-ready.  If the return value evaluates to 'false'
 /// then no lambda is capture-ready for \p VarToCapture.
 
-static inline UnsignedOrNone getStackIndexOfNearestEnclosingCaptureReadyLambda(
+static inline std::optional<unsigned>
+getStackIndexOfNearestEnclosingCaptureReadyLambda(
     ArrayRef<const clang::sema::FunctionScopeInfo *> FunctionScopes,
     ValueDecl *VarToCapture) {
   // Label failure to capture.
-  const UnsignedOrNone NoLambdaIsCaptureReady = std::nullopt;
+  const std::optional<unsigned> NoLambdaIsCaptureReady;
 
   // Ignore all inner captured regions.
   unsigned CurScopeIndex = FunctionScopes.size() - 1;
@@ -175,18 +174,19 @@ static inline UnsignedOrNone getStackIndexOfNearestEnclosingCaptureReadyLambda(
 /// \param VarToCapture - the variable to capture.  If NULL, capture 'this'.
 ///
 ///
-/// \returns An UnsignedOrNone Index that if evaluates to 'true'
+/// \returns An std::optional<unsigned> Index that if evaluates to 'true'
 /// contains the index (into Sema's FunctionScopeInfo stack) of the innermost
 /// lambda which is capture-capable.  If the return value evaluates to 'false'
 /// then no lambda is capture-capable for \p VarToCapture.
 
-UnsignedOrNone clang::getStackIndexOfNearestEnclosingCaptureCapableLambda(
+std::optional<unsigned>
+clang::getStackIndexOfNearestEnclosingCaptureCapableLambda(
     ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes,
     ValueDecl *VarToCapture, Sema &S) {
 
-  const UnsignedOrNone NoLambdaIsCaptureCapable = std::nullopt;
+  const std::optional<unsigned> NoLambdaIsCaptureCapable;
 
-  const UnsignedOrNone OptionalStackIndex =
+  const std::optional<unsigned> OptionalStackIndex =
       getStackIndexOfNearestEnclosingCaptureReadyLambda(FunctionScopes,
                                                         VarToCapture);
   if (!OptionalStackIndex)
@@ -210,12 +210,13 @@ UnsignedOrNone clang::getStackIndexOfNearestEnclosingCaptureCapableLambda(
     // checking whether all enclosing lambdas of the capture-ready lambda allow
     // the capture - i.e. make sure it is capture-capable.
     QualType CaptureType, DeclRefType;
-    const bool CanCaptureVariable = !S.tryCaptureVariable(
-        VarToCapture,
-        /*ExprVarIsUsedInLoc*/ SourceLocation(), TryCaptureKind::Implicit,
-        /*EllipsisLoc*/ SourceLocation(),
-        /*BuildAndDiagnose*/ false, CaptureType, DeclRefType,
-        &IndexOfCaptureReadyLambda);
+    const bool CanCaptureVariable =
+        !S.tryCaptureVariable(VarToCapture,
+                              /*ExprVarIsUsedInLoc*/ SourceLocation(),
+                              clang::Sema::TryCapture_Implicit,
+                              /*EllipsisLoc*/ SourceLocation(),
+                              /*BuildAndDiagnose*/ false, CaptureType,
+                              DeclRefType, &IndexOfCaptureReadyLambda);
     if (!CanCaptureVariable)
       return NoLambdaIsCaptureCapable;
   } else {
@@ -291,8 +292,7 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
     DataMember,
     InlineVariable,
     TemplatedVariable,
-    Concept,
-    NonInlineInModulePurview
+    Concept
   } Kind = Normal;
 
   bool IsInNonspecializedTemplate =
@@ -301,50 +301,29 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
   // Default arguments of member function parameters that appear in a class
   // definition, as well as the initializers of data members, receive special
   // treatment. Identify them.
-  Kind = [&]() {
-    if (!ManglingContextDecl)
-      return Normal;
-
-    if (auto *ND = dyn_cast<NamedDecl>(ManglingContextDecl)) {
-      // See discussion in https://github.com/itanium-cxx-abi/cxx-abi/issues/186
-      //
-      // zygoloid:
-      //    Yeah, I think the only cases left where lambdas don't need a
-      //    mangling are when they have (effectively) internal linkage or appear
-      //    in a non-inline function in a non-module translation unit.
-      Module *M = ManglingContextDecl->getOwningModule();
-      if (M && M->getTopLevelModule()->isNamedModuleUnit() &&
-          ND->isExternallyVisible())
-        return NonInlineInModulePurview;
-    }
-
+  if (ManglingContextDecl) {
     if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) {
       if (const DeclContext *LexicalDC =
               Param->getDeclContext()->getLexicalParent())
         if (LexicalDC->isRecord())
-          return DefaultArgument;
+          Kind = DefaultArgument;
     } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {
       if (Var->getMostRecentDecl()->isInline())
-        return InlineVariable;
-
-      if (Var->getDeclContext()->isRecord() && IsInNonspecializedTemplate)
-        return TemplatedVariable;
-
-      if (Var->getDescribedVarTemplate())
-        return TemplatedVariable;
-
-      if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+        Kind = InlineVariable;
+      else if (Var->getDeclContext()->isRecord() && IsInNonspecializedTemplate)
+        Kind = TemplatedVariable;
+      else if (Var->getDescribedVarTemplate())
+        Kind = TemplatedVariable;
+      else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
         if (!VTS->isExplicitSpecialization())
-          return TemplatedVariable;
+          Kind = TemplatedVariable;
       }
     } else if (isa<FieldDecl>(ManglingContextDecl)) {
-      return DataMember;
+      Kind = DataMember;
     } else if (isa<ImplicitConceptSpecializationDecl>(ManglingContextDecl)) {
-      return Concept;
+      Kind = Concept;
     }
-
-    return Normal;
-  }();
+  }
 
   // Itanium ABI [5.1.7]:
   //   In the following contexts [...] the one-definition rule requires closure
@@ -363,7 +342,6 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
     return std::make_tuple(nullptr, nullptr);
   }
 
-  case NonInlineInModulePurview:
   case Concept:
     // Concept definitions aren't code generated and thus aren't mangled,
     // however the ManglingContextDecl is important for the purposes of
@@ -807,8 +785,8 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
 
 QualType Sema::buildLambdaInitCaptureInitialization(
     SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc,
-    UnsignedOrNone NumExpansions, IdentifierInfo *Id, bool IsDirectInit,
-    Expr *&Init) {
+    std::optional<unsigned> NumExpansions, IdentifierInfo *Id,
+    bool IsDirectInit, Expr *&Init) {
   // Create an 'auto' or 'auto&' TypeSourceInfo that we can use to
   // deduce against.
   QualType DeductType = Context.getAutoDeductType();
@@ -1014,7 +992,7 @@ CXXMethodDecl *Sema::CreateLambdaCallOperator(SourceRange IntroducerRange,
       QualType(), /*Tinfo=*/nullptr, SC_None,
       getCurFPFeatures().isFPConstrained(),
       /*isInline=*/true, ConstexprSpecKind::Unspecified, SourceLocation(),
-      /*TrailingRequiresClause=*/{});
+      /*TrailingRequiresClause=*/nullptr);
   Method->setAccess(AS_public);
   return Method;
 }
@@ -1032,8 +1010,7 @@ void Sema::AddTemplateParametersToLambdaCallOperator(
 
 void Sema::CompleteLambdaCallOperator(
     CXXMethodDecl *Method, SourceLocation LambdaLoc,
-    SourceLocation CallOperatorLoc,
-    const AssociatedConstraint &TrailingRequiresClause,
+    SourceLocation CallOperatorLoc, Expr *TrailingRequiresClause,
     TypeSourceInfo *MethodTyInfo, ConstexprSpecKind ConstexprKind,
     StorageClass SC, ArrayRef<ParmVarDecl *> Params,
     bool HasExplicitResultType) {
@@ -1411,9 +1388,8 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
     if (C->Init.isUsable()) {
       addInitCapture(LSI, cast<VarDecl>(Var), C->Kind == LCK_ByRef);
     } else {
-      TryCaptureKind Kind = C->Kind == LCK_ByRef
-                                ? TryCaptureKind::ExplicitByRef
-                                : TryCaptureKind::ExplicitByVal;
+      TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef
+                                                 : TryCapture_ExplicitByVal;
       tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc);
     }
     if (!LSI->Captures.empty()) {
@@ -1532,7 +1508,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
 
   CompleteLambdaCallOperator(
       Method, Intro.Range.getBegin(), CallOperatorLoc,
-      AssociatedConstraint(ParamInfo.getTrailingRequiresClause()), MethodTyInfo,
+      ParamInfo.getTrailingRequiresClause(), MethodTyInfo,
       ParamInfo.getDeclSpec().getConstexprSpecifier(),
       IsLambdaStatic ? SC_Static : SC_None, Params, ExplicitResultType);
 
@@ -1550,9 +1526,6 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
   // Attributes on the lambda apply to the method.
   ProcessDeclAttributes(CurScope, Method, ParamInfo);
 
-  if (Context.getTargetInfo().getTriple().isAArch64())
-    ARM().CheckSMEFunctionDefAttributes(Method);
-
   // CUDA lambdas get implicit host and device attributes.
   if (getLangOpts().CUDA)
     CUDA().SetLambdaAttrs(Method);
@@ -1616,7 +1589,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
   // The optional requires-clause ([temp.pre]) in an init-declarator or
   // member-declarator shall be present only if the declarator declares a
   // templated function ([dcl.fct]).
-  if (const AssociatedConstraint &TRC = Method->getTrailingRequiresClause()) {
+  if (Expr *TRC = Method->getTrailingRequiresClause()) {
     // [temp.pre]/8:
     // An entity is templated if it is
     // - a template,
@@ -1639,8 +1612,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
     // applies to the call operator, which we already know is a member function,
     // AND defined.
     if (!Method->getDescribedFunctionTemplate() && !Method->isTemplated()) {
-      Diag(TRC.ConstraintExpr->getBeginLoc(),
-           diag::err_constrained_non_templated_function);
+      Diag(TRC->getBeginLoc(), diag::err_constrained_non_templated_function);
     }
   }
 
@@ -1863,8 +1835,7 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
 
   // A non-generic lambda may still be a templated entity. We need to preserve
   // constraints when converting the lambda to a function pointer. See GH63181.
-  if (const AssociatedConstraint &Requires =
-          CallOperator->getTrailingRequiresClause())
+  if (Expr *Requires = CallOperator->getTrailingRequiresClause())
     Conversion->setTrailingRequiresClause(Requires);
 
   if (Class->isGenericLambda()) {
@@ -2045,10 +2016,6 @@ ExprResult Sema::BuildCaptureInit(const Capture &Cap,
 
 ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body) {
   LambdaScopeInfo LSI = *cast<LambdaScopeInfo>(FunctionScopes.back());
-
-  if (LSI.CallOperator->hasAttr<SYCLKernelEntryPointAttr>())
-    SYCL().CheckSYCLEntryPointFunctionDecl(LSI.CallOperator);
-
   ActOnFinishFunctionBody(LSI.CallOperator, Body);
 
   return BuildLambdaExpr(StartLoc, Body->getEndLoc(), &LSI);
@@ -2343,14 +2310,13 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
       LambdaExpr::Create(Context, Class, IntroducerRange, CaptureDefault,
                          CaptureDefaultLoc, ExplicitParams, ExplicitResultType,
                          CaptureInits, EndLoc, ContainsUnexpandedParameterPack);
-
   // If the lambda expression's call operator is not explicitly marked constexpr
-  // and is not dependent, analyze the call operator to infer
+  // and we are not in a dependent context, analyze the call operator to infer
   // its constexpr-ness, suppressing diagnostics while doing so.
   if (getLangOpts().CPlusPlus17 && !CallOperator->isInvalidDecl() &&
       !CallOperator->isConstexpr() &&
       !isa<CoroutineBodyStmt>(CallOperator->getBody()) &&
-      !Class->isDependentContext()) {
+      !Class->getDeclContext()->isDependentContext()) {
     CallOperator->setConstexprKind(
         CheckConstexprFunctionDefinition(CallOperator,
                                          CheckConstexprKind::CheckValid)
@@ -2486,74 +2452,6 @@ static FunctionDecl *getPatternFunctionDecl(FunctionDecl *FD) {
   return FTD->getTemplatedDecl();
 }
 
-bool Sema::addInstantiatedCapturesToScope(
-    FunctionDecl *Function, const FunctionDecl *PatternDecl,
-    LocalInstantiationScope &Scope,
-    const MultiLevelTemplateArgumentList &TemplateArgs) {
-  const auto *LambdaClass = cast<CXXMethodDecl>(Function)->getParent();
-  const auto *LambdaPattern = cast<CXXMethodDecl>(PatternDecl)->getParent();
-
-  unsigned Instantiated = 0;
-
-  // FIXME: This is a workaround for not having deferred lambda body
-  // instantiation.
-  // When transforming a lambda's body, if we encounter another call to a
-  // nested lambda that contains a constraint expression, we add all of the
-  // outer lambda's instantiated captures to the current instantiation scope to
-  // facilitate constraint evaluation. However, these captures don't appear in
-  // the CXXRecordDecl until after the lambda expression is rebuilt, so we
-  // pull them out from the corresponding LSI.
-  LambdaScopeInfo *InstantiatingScope = nullptr;
-  if (LambdaPattern->capture_size() && !LambdaClass->capture_size()) {
-    for (FunctionScopeInfo *Scope : llvm::reverse(FunctionScopes)) {
-      auto *LSI = dyn_cast<LambdaScopeInfo>(Scope);
-      if (!LSI || getPatternFunctionDecl(LSI->CallOperator) != PatternDecl)
-        continue;
-      InstantiatingScope = LSI;
-      break;
-    }
-    assert(InstantiatingScope);
-  }
-
-  auto AddSingleCapture = [&](const ValueDecl *CapturedPattern,
-                              unsigned Index) {
-    ValueDecl *CapturedVar =
-        InstantiatingScope ? InstantiatingScope->Captures[Index].getVariable()
-                           : LambdaClass->getCapture(Index)->getCapturedVar();
-    assert(CapturedVar->isInitCapture());
-    Scope.InstantiatedLocal(CapturedPattern, CapturedVar);
-  };
-
-  for (const LambdaCapture &CapturePattern : LambdaPattern->captures()) {
-    if (!CapturePattern.capturesVariable()) {
-      Instantiated++;
-      continue;
-    }
-    ValueDecl *CapturedPattern = CapturePattern.getCapturedVar();
-
-    if (!CapturedPattern->isInitCapture()) {
-      Instantiated++;
-      continue;
-    }
-
-    if (!CapturedPattern->isParameterPack()) {
-      AddSingleCapture(CapturedPattern, Instantiated++);
-    } else {
-      Scope.MakeInstantiatedLocalArgPack(CapturedPattern);
-      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-      SemaRef.collectUnexpandedParameterPacks(
-          dyn_cast<VarDecl>(CapturedPattern)->getInit(), Unexpanded);
-      auto NumArgumentsInExpansion =
-          getNumArgumentsInExpansionFromUnexpanded(Unexpanded, TemplateArgs);
-      if (!NumArgumentsInExpansion)
-        continue;
-      for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg)
-        AddSingleCapture(CapturedPattern, Instantiated++);
-    }
-  }
-  return false;
-}
-
 Sema::LambdaScopeForCallOperatorInstantiationRAII::
     LambdaScopeForCallOperatorInstantiationRAII(
         Sema &SemaRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
@@ -2573,31 +2471,35 @@ Sema::LambdaScopeForCallOperatorInstantiationRAII::
   if (!ShouldAddDeclsFromParentScope)
     return;
 
+  FunctionDecl *InnermostFD = FD, *InnermostFDPattern = FDPattern;
   llvm::SmallVector<std::pair<FunctionDecl *, FunctionDecl *>, 4>
-      InstantiationAndPatterns;
-  while (FDPattern && FD) {
-    InstantiationAndPatterns.emplace_back(FDPattern, FD);
-
+      ParentInstantiations;
+  while (true) {
     FDPattern =
         dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(FDPattern));
     FD = dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(FD));
+
+    if (!FDPattern || !FD)
+      break;
+
+    ParentInstantiations.emplace_back(FDPattern, FD);
   }
 
   // Add instantiated parameters and local vars to scopes, starting from the
   // outermost lambda to the innermost lambda. This ordering ensures that
-  // the outer instantiations can be found when referenced from within inner
-  // lambdas.
-  //
-  //   auto L = [](auto... x) {
-  //     return [](decltype(x)... y) { }; // Instantiating y needs x
-  //   };
-  //
+  // parameters in inner lambdas can correctly depend on those defined
+  // in outer lambdas, e.g. auto L = [](auto... x) {
+  //   return [](decltype(x)... y) { }; // `y` depends on `x`
+  // };
 
-  for (auto [FDPattern, FD] : llvm::reverse(InstantiationAndPatterns)) {
+  for (const auto &[FDPattern, FD] : llvm::reverse(ParentInstantiations)) {
     SemaRef.addInstantiatedParametersToScope(FD, FDPattern, Scope, MLTAL);
     SemaRef.addInstantiatedLocalVarsToScope(FD, FDPattern, Scope);
 
     if (isLambdaCallOperator(FD))
       SemaRef.addInstantiatedCapturesToScope(FD, FDPattern, Scope, MLTAL);
   }
+
+  SemaRef.addInstantiatedCapturesToScope(InnermostFD, InnermostFDPattern, Scope,
+                                         MLTAL);
 }

>From 0fa8171d4487f64828ec596909c29864cf6c9fba Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-003 at users.noreply.github.com>
Date: Mon, 5 May 2025 20:47:39 -0600
Subject: [PATCH 38/38] Update SemaLambda.cpp

---
 clang/lib/Sema/SemaLambda.cpp | 305 +++++++++++++++++-----------------
 1 file changed, 155 insertions(+), 150 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index f8fbc9cd07edf..e2ab44d761e51 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -15,9 +15,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/MangleNumberingContext.h"
-#include "clang/AST/Type.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/Lexer.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
@@ -28,6 +26,8 @@
 #include "clang/Sema/SemaOpenMP.h"
 #include "clang/Sema/Template.h"
 #include "llvm/ADT/STLExtras.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/AST/Type.h"  
 
 #include <optional>
 using namespace clang;
@@ -223,10 +223,11 @@ clang::getStackIndexOfNearestEnclosingCaptureCapableLambda(
     // Check if the capture-ready lambda can truly capture 'this' by checking
     // whether all enclosing lambdas of the capture-ready lambda can capture
     // 'this'.
-    const bool CanCaptureThis = !S.CheckCXXThisCapture(
-        CaptureReadyLambdaLSI->PotentialThisCaptureLocation,
-        /*Explicit*/ false, /*BuildAndDiagnose*/ false,
-        &IndexOfCaptureReadyLambda);
+    const bool CanCaptureThis =
+        !S.CheckCXXThisCapture(
+             CaptureReadyLambdaLSI->PotentialThisCaptureLocation,
+             /*Explicit*/ false, /*BuildAndDiagnose*/ false,
+             &IndexOfCaptureReadyLambda);
     if (!CanCaptureThis)
       return NoLambdaIsCaptureCapable;
   }
@@ -241,7 +242,7 @@ getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) {
         /*Template kw loc*/ SourceLocation(),
         /*L angle loc*/ LSI->ExplicitTemplateParamsRange.getBegin(),
         LSI->TemplateParams,
-        /*R angle loc*/ LSI->ExplicitTemplateParamsRange.getEnd(),
+        /*R angle loc*/LSI->ExplicitTemplateParamsRange.getEnd(),
         LSI->RequiresClause.get());
   }
   return LSI->GLTemplateParameterList;
@@ -303,8 +304,8 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
   // treatment. Identify them.
   if (ManglingContextDecl) {
     if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) {
-      if (const DeclContext *LexicalDC =
-              Param->getDeclContext()->getLexicalParent())
+      if (const DeclContext *LexicalDC
+          = Param->getDeclContext()->getLexicalParent())
         if (LexicalDC->isRecord())
           Kind = DefaultArgument;
     } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {
@@ -555,7 +556,8 @@ void Sema::ActOnLambdaExplicitTemplateParameterList(
   assert(LSI->TemplateParams.empty() &&
          "Explicit template parameters should come "
          "before invented (auto) ones");
-  assert(!TParams.empty() && "No template parameters to act on");
+  assert(!TParams.empty() &&
+         "No template parameters to act on");
   LSI->TemplateParams.append(TParams.begin(), TParams.end());
   LSI->NumExplicitTemplateParams = TParams.size();
   LSI->ExplicitTemplateParamsRange = {LAngleLoc, RAngleLoc};
@@ -576,7 +578,8 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) {
 
   //  - it is an enumerator whose enum type is T or
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
-    if (EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
+    if (EnumConstantDecl *D
+          = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
       return cast<EnumDecl>(D->getDeclContext());
     }
     return nullptr;
@@ -640,13 +643,12 @@ static EnumDecl *findEnumForBlockReturn(ReturnStmt *ret) {
 /// Attempt to find a common type T for which all of the returned
 /// expressions in a block are enumerator-like expressions of that
 /// type.
-static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt *> returns) {
-  ArrayRef<ReturnStmt *>::iterator i = returns.begin(), e = returns.end();
+static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt*> returns) {
+  ArrayRef<ReturnStmt*>::iterator i = returns.begin(), e = returns.end();
 
   // Try to find one for the first return.
   EnumDecl *ED = findEnumForBlockReturn(*i);
-  if (!ED)
-    return nullptr;
+  if (!ED) return nullptr;
 
   // Check that the rest of the returns have the same enum.
   for (++i; i != e; ++i) {
@@ -655,18 +657,17 @@ static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt *> returns) {
   }
 
   // Never infer an anonymous enum type.
-  if (!ED->hasNameForLinkage())
-    return nullptr;
+  if (!ED->hasNameForLinkage()) return nullptr;
 
   return ED;
 }
 
 /// Adjust the given return statements so that they formally return
 /// the given type.  It should require, at most, an IntegralCast.
-static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt *> returns,
+static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns,
                                      QualType returnType) {
-  for (ArrayRef<ReturnStmt *>::iterator i = returns.begin(), e = returns.end();
-       i != e; ++i) {
+  for (ArrayRef<ReturnStmt*>::iterator
+         i = returns.begin(), e = returns.end(); i != e; ++i) {
     ReturnStmt *ret = *i;
     Expr *retValue = ret->getRetValue();
     if (S.Context.hasSameType(retValue->getType(), returnType))
@@ -763,7 +764,7 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
     QualType ReturnType =
         (RetE ? RetE->getType() : Context.VoidTy).getUnqualifiedType();
     if (Context.getCanonicalFunctionResultType(ReturnType) ==
-        Context.getCanonicalFunctionResultType(CSI.ReturnType)) {
+          Context.getCanonicalFunctionResultType(CSI.ReturnType)) {
       // Use the return type with the strictest possible nullability annotation.
       auto RetTyNullability = ReturnType->getNullability();
       auto BlockNullability = CSI.ReturnType->getNullability();
@@ -815,7 +816,7 @@ QualType Sema::buildLambdaInitCaptureInitialization(
 
   // Deduce the type of the init capture.
   QualType DeducedType = deduceVarTypeFromInitializer(
-      /*VarDecl*/ nullptr, DeclarationName(Id), DeductType, TSI,
+      /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI,
       SourceRange(Loc, Loc), IsDirectInit, Init);
   if (DeducedType.isNull())
     return QualType();
@@ -1165,27 +1166,25 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       CheckCXXThisCapture(C->Loc, /*Explicit=*/true, /*BuildAndDiagnose*/ true,
                           /*FunctionScopeIndexToStopAtPtr*/ nullptr,
                           C->Kind == LCK_StarThis);
-      if (!LSI->Captures.empty()) { //
+      if (!LSI->Captures.empty()) { // 
         SourceManager &SourceMgr = Context.getSourceManager();
         const LangOptions &LangOpts = Context.getLangOpts();
-        SourceRange TrimmedRange =
-            Lexer::makeFileCharRange(
-                CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr,
-                LangOpts)
-                .getAsRange();
+        SourceRange TrimmedRange = Lexer::makeFileCharRange(
+            CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts)
+            .getAsRange();
         LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
       }
       continue; // // skip further processing for `this` and `*this` captures.
     }
 
-    if (!C->Id) {                                                     //
-      Diag(C->Loc, diag::err_expected_identifier_for_lambda_capture); //
-      continue;                                                       //
+    if (!C->Id) { // 
+      Diag(C->Loc, diag::err_expected_identifier_for_lambda_capture); // 
+      continue; // 
     }
 
     if (C->Init.isInvalid()) {
-      Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); //
-      continue;                                                        //
+      Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);  // 
+      continue; // 
     }
 
     ValueDecl *Var = nullptr;
@@ -1199,61 +1198,66 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
       // FIXME: we should create the init capture variable and mark it invalid
       // in this case.
-      // Ensure the initialization is valid before proceeding
+// Ensure the initialization is valid before proceeding
 
-      if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) {
-        if (!C->Init.isUsable()) {
-          Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
-          continue;
-        }
 
-        if (!C->Init.get()) {
-          continue;
-        }
+if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) {
+  if (!C->Init.isUsable()) {
+      Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
+      continue;
+  }
 
-        ASTContext &Ctx = this->Context;
-        QualType DeducedType = C->Init.get()->getType();
+  if (!C->Init.get()) {
+      continue;
+  }
 
-        if (DeducedType.isNull()) {
-          continue;
-        }
+  ASTContext &Ctx = this->Context;
+  QualType DeducedType = C->Init.get()->getType();
 
-        if (DeducedType->isVoidType()) {
-          if (!DeducedType->isDependentType()) {
-            C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
-          } else {
-            Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
-          }
-          continue;
-        }
+  if (DeducedType.isNull()) {
+      continue;
+  }
 
-        if (isa<InitListExpr>(C->Init.get())) {
-          IdentifierInfo *DummyID = &Ctx.Idents.get("lambda_tmp_var");
-          QualType DummyType = Ctx.UnknownAnyTy;
+  if (DeducedType->isVoidType()) {
+      if (!DeducedType->isDependentType()) {
+          C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
+      } else {
+          Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
+      }
+      continue;
+  }
 
-          auto *TempVarDecl =
-              VarDecl::Create(Ctx, nullptr, C->Loc, C->Loc, DummyID, DummyType,
-                              nullptr, SC_None);
+  if (isa<InitListExpr>(C->Init.get())) {
+      IdentifierInfo *DummyID = &Ctx.Idents.get("lambda_tmp_var");
+      QualType DummyType = Ctx.UnknownAnyTy;
 
-          if (!TempVarDecl) {
-            continue;
-          }
+      auto *TempVarDecl = VarDecl::Create(
+          Ctx, nullptr, C->Loc, C->Loc,
+          DummyID, DummyType, nullptr, SC_None
+      );
 
-          DeducedType = deduceVarTypeFromInitializer(
-              TempVarDecl, TempVarDecl->getDeclName(), TempVarDecl->getType(),
-              nullptr, TempVarDecl->getSourceRange(), false, C->Init.get());
+      if (!TempVarDecl) {
+          continue;
+      }
 
-          if (DeducedType.isNull()) {
-            Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
-            C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
-            continue;
-          }
-        }
+      DeducedType = deduceVarTypeFromInitializer(
+          TempVarDecl, TempVarDecl->getDeclName(),
+          TempVarDecl->getType(), nullptr,
+          TempVarDecl->getSourceRange(),
+          false, C->Init.get()
+      );
 
-        if (!DeducedType.isNull()) {
-          C->InitCaptureType = ParsedType::make(DeducedType);
-        }
+      if (DeducedType.isNull()) {
+          Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type);
+          C->InitCaptureType = ParsedType::make(Ctx.DependentTy);
+          continue;
       }
+  }
+
+  if (!DeducedType.isNull()) {
+      C->InitCaptureType = ParsedType::make(DeducedType);
+  }
+}
 
       unsigned InitStyle;
       switch (C->InitKind) {
@@ -1288,12 +1292,12 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       if (C->Kind == LCK_ByRef && Intro.Default == LCD_ByRef) {
         Diag(C->Loc, diag::err_reference_capture_with_reference_default)
             << FixItHint::CreateRemoval(
-                   SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
+                SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
         continue;
       } else if (C->Kind == LCK_ByCopy && Intro.Default == LCD_ByCopy) {
         Diag(C->Loc, diag::err_copy_capture_with_copy_default)
             << FixItHint::CreateRemoval(
-                   SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
+                SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
         continue;
       }
 
@@ -1392,16 +1396,14 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
                                                  : TryCapture_ExplicitByVal;
       tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc);
     }
-    if (!LSI->Captures.empty()) {
-      SourceManager &SourceMgr = Context.getSourceManager();
-      const LangOptions &LangOpts = Context.getLangOpts();
-      SourceRange TrimmedRange =
-          Lexer::makeFileCharRange(
-              CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr,
-              LangOpts)
-              .getAsRange();
-      LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
-    }
+    if (!LSI->Captures.empty())
+      {
+    SourceManager &SourceMgr = Context.getSourceManager();
+    const LangOptions &LangOpts = Context.getLangOpts();
+    SourceRange TrimmedRange = Lexer::makeFileCharRange(
+        CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange();
+    LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange;
+      }
   }
   finishLambdaExplicitCaptures(LSI);
   LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;
@@ -1643,7 +1645,7 @@ void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope,
   // Finalize the lambda.
   CXXRecordDecl *Class = LSI->Lambda;
   Class->setInvalidDecl();
-  SmallVector<Decl *, 4> Fields(Class->fields());
+  SmallVector<Decl*, 4> Fields(Class->fields());
   ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
               SourceLocation(), ParsedAttributesView());
   CheckCompletedCXXClass(nullptr, Class);
@@ -1748,7 +1750,7 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
   // Create the type of the conversion function.
   FunctionProtoType::ExtProtoInfo ConvExtInfo(
       S.Context.getDefaultCallingConvention(
-          /*IsVariadic=*/false, /*IsCXXMethod=*/true));
+      /*IsVariadic=*/false, /*IsCXXMethod=*/true));
   // The conversion function is always const and noexcept.
   ConvExtInfo.TypeQuals = Qualifiers();
   ConvExtInfo.TypeQuals.addConst();
@@ -1756,9 +1758,9 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
   QualType ConvTy = S.Context.getFunctionType(PtrToFunctionTy, {}, ConvExtInfo);
 
   SourceLocation Loc = IntroducerRange.getBegin();
-  DeclarationName ConversionName =
-      S.Context.DeclarationNames.getCXXConversionFunctionName(
-          S.Context.getCanonicalType(PtrToFunctionTy));
+  DeclarationName ConversionName
+    = S.Context.DeclarationNames.getCXXConversionFunctionName(
+        S.Context.getCanonicalType(PtrToFunctionTy));
   // Construct a TypeSourceInfo for the conversion function, and wire
   // all the parameters appropriately for the FunctionProtoTypeLoc
   // so that everything works during transformation/instantiation of
@@ -1797,7 +1799,7 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
   FunctionProtoTypeLoc CallOpConvTL =
       PtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>();
   FunctionProtoTypeLoc CallOpConvNameTL =
-      ConvNamePtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>();
+    ConvNamePtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>();
 
   // Wire up the FunctionProtoTypeLocs with the call operator's parameters.
   // These parameter's are essentially used to transform the name and
@@ -1842,10 +1844,12 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
     // Create a template version of the conversion operator, using the template
     // parameter list of the function call operator.
     FunctionTemplateDecl *TemplateCallOperator =
-        CallOperator->getDescribedFunctionTemplate();
-    FunctionTemplateDecl *ConversionTemplate = FunctionTemplateDecl::Create(
-        S.Context, Class, Loc, ConversionName,
-        TemplateCallOperator->getTemplateParameters(), Conversion);
+            CallOperator->getDescribedFunctionTemplate();
+    FunctionTemplateDecl *ConversionTemplate =
+                  FunctionTemplateDecl::Create(S.Context, Class,
+                                      Loc, ConversionName,
+                                      TemplateCallOperator->getTemplateParameters(),
+                                      Conversion);
     ConversionTemplate->setAccess(AS_public);
     ConversionTemplate->setImplicit(true);
     Conversion->setDescribedFunctionTemplate(ConversionTemplate);
@@ -1918,7 +1922,8 @@ static void addFunctionPointerConversions(Sema &S, SourceRange IntroducerRange,
 }
 
 /// Add a lambda's conversion to block pointer.
-static void addBlockPointerConversion(Sema &S, SourceRange IntroducerRange,
+static void addBlockPointerConversion(Sema &S,
+                                      SourceRange IntroducerRange,
                                       CXXRecordDecl *Class,
                                       CXXMethodDecl *CallOperator) {
   const FunctionProtoType *CallOpProto =
@@ -1935,9 +1940,9 @@ static void addBlockPointerConversion(Sema &S, SourceRange IntroducerRange,
   QualType ConvTy = S.Context.getFunctionType(BlockPtrTy, {}, ConversionEPI);
 
   SourceLocation Loc = IntroducerRange.getBegin();
-  DeclarationName Name =
-      S.Context.DeclarationNames.getCXXConversionFunctionName(
-          S.Context.getCanonicalType(BlockPtrTy));
+  DeclarationName Name
+    = S.Context.DeclarationNames.getCXXConversionFunctionName(
+        S.Context.getCanonicalType(BlockPtrTy));
   DeclarationNameLoc NameLoc = DeclarationNameLoc::makeNamedTypeLoc(
       S.Context.getTrivialTypeSourceInfo(BlockPtrTy, Loc));
   CXXConversionDecl *Conversion = CXXConversionDecl::Create(
@@ -1994,7 +1999,7 @@ ExprResult Sema::BuildCaptureInit(const Capture &Cap,
     ValueDecl *Var = Cap.getVariable();
     Name = Var->getIdentifier();
     Init = BuildDeclarationNameExpr(
-        CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), Loc), Var);
+      CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), Loc), Var);
   }
 
   // In OpenMP, the capture kind doesn't actually describe how to capture:
@@ -2009,7 +2014,8 @@ ExprResult Sema::BuildCaptureInit(const Capture &Cap,
   Expr *InitExpr = Init.get();
   InitializedEntity Entity = InitializedEntity::InitializeLambdaCapture(
       Name, Cap.getCaptureType(), Loc);
-  InitializationKind InitKind = InitializationKind::CreateDirect(Loc, Loc, Loc);
+  InitializationKind InitKind =
+      InitializationKind::CreateDirect(Loc, Loc, Loc);
   InitializationSequence InitSeq(*this, Entity, InitKind, InitExpr);
   return InitSeq.Perform(*this, Entity, InitKind, InitExpr);
 }
@@ -2165,8 +2171,8 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
     CallOperator->setLexicalDeclContext(Class);
     Decl *TemplateOrNonTemplateCallOperatorDecl =
         CallOperator->getDescribedFunctionTemplate()
-            ? CallOperator->getDescribedFunctionTemplate()
-            : cast<Decl>(CallOperator);
+        ? CallOperator->getDescribedFunctionTemplate()
+        : cast<Decl>(CallOperator);
 
     // FIXME: Is this really the best choice? Keeping the lexical decl context
     // set as CurContext seems more faithful to the source.
@@ -2176,8 +2182,8 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
 
     // True if the current capture has a used capture or default before it.
     bool CurHasPreviousCapture = CaptureDefault != LCD_None;
-    SourceLocation PrevCaptureLoc =
-        CurHasPreviousCapture ? CaptureDefaultLoc : IntroducerRange.getBegin();
+    SourceLocation PrevCaptureLoc = CurHasPreviousCapture ?
+        CaptureDefaultLoc : IntroducerRange.getBegin();
 
     for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
       const Capture &From = LSI->Captures[I];
@@ -2197,37 +2203,32 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
 
       bool IsCaptureUsed = true;
 
-      if (!CurContext->isDependentContext() && !IsImplicit &&
-          !From.isODRUsed()) {
-        // Handle non-ODR used init captures separately.
-        bool NonODRUsedInitCapture =
-            IsGenericLambda && From.isNonODRUsed() && From.isInitCapture();
-
-        if (!NonODRUsedInitCapture) {
-          bool IsLast = (I + 1) == LSI->NumExplicitCaptures;
-          SourceRange FixItRange;
-
-          if (CaptureRange.isValid()) {
-            if (!CurHasPreviousCapture && !IsLast) {
-              // No previous capture and not the last capture: remove current
-              // and next comma.
-              FixItRange =
-                  SourceRange(CaptureRange.getBegin(),
-                              getLocForEndOfToken(CaptureRange.getEnd()));
-            } else if (CurHasPreviousCapture && !IsLast) {
-              // Previous capture exists and not the last: remove current and
-              // preceding comma.
-              FixItRange = SourceRange(getLocForEndOfToken(PrevCaptureLoc),
-                                       CaptureRange.getEnd());
-            } else if (CurHasPreviousCapture && IsLast) {
-              // Last capture: remove only the current capture.
-              FixItRange = CaptureRange;
-            }
-          }
-
-          IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From);
-        }
+if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) {
+  // Handle non-ODR used init captures separately.
+  bool NonODRUsedInitCapture = IsGenericLambda && From.isNonODRUsed() && From.isInitCapture();
+
+  if (!NonODRUsedInitCapture) {
+    bool IsLast = (I + 1) == LSI->NumExplicitCaptures;
+    SourceRange FixItRange;
+
+    if (CaptureRange.isValid()) {
+      if (!CurHasPreviousCapture && !IsLast) {
+        // No previous capture and not the last capture: remove current and next comma.
+        FixItRange = SourceRange(
+            CaptureRange.getBegin(), getLocForEndOfToken(CaptureRange.getEnd()));
+      } else if (CurHasPreviousCapture && !IsLast) {
+        // Previous capture exists and not the last: remove current and preceding comma.
+        FixItRange = SourceRange(
+            getLocForEndOfToken(PrevCaptureLoc), CaptureRange.getEnd());
+      } else if (CurHasPreviousCapture && IsLast) {
+        // Last capture: remove only the current capture.
+        FixItRange = CaptureRange;
       }
+    }
+
+    IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From);
+  }
+}
 
       if (CaptureRange.isValid()) {
         CurHasPreviousCapture |= IsCaptureUsed;
@@ -2298,7 +2299,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
       addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
 
     // Finalize the lambda class.
-    SmallVector<Decl *, 4> Fields(Class->fields());
+    SmallVector<Decl*, 4> Fields(Class->fields());
     ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
                 SourceLocation(), ParsedAttributesView());
     CheckCompletedCXXClass(nullptr, Class);
@@ -2306,10 +2307,11 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
 
   Cleanup.mergeFrom(LambdaCleanup);
 
-  LambdaExpr *Lambda =
-      LambdaExpr::Create(Context, Class, IntroducerRange, CaptureDefault,
-                         CaptureDefaultLoc, ExplicitParams, ExplicitResultType,
-                         CaptureInits, EndLoc, ContainsUnexpandedParameterPack);
+  LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
+                                          CaptureDefault, CaptureDefaultLoc,
+                                          ExplicitParams, ExplicitResultType,
+                                          CaptureInits, EndLoc,
+                                          ContainsUnexpandedParameterPack);
   // If the lambda expression's call operator is not explicitly marked constexpr
   // and we are not in a dependent context, analyze the call operator to infer
   // its constexpr-ness, suppressing diagnostics while doing so.
@@ -2369,9 +2371,10 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
                                                Expr *Src) {
   // Make sure that the lambda call operator is marked used.
   CXXRecordDecl *Lambda = Conv->getParent();
-  CXXMethodDecl *CallOperator = cast<CXXMethodDecl>(
-      Lambda->lookup(Context.DeclarationNames.getCXXOperatorName(OO_Call))
-          .front());
+  CXXMethodDecl *CallOperator
+    = cast<CXXMethodDecl>(
+        Lambda->lookup(
+          Context.DeclarationNames.getCXXOperatorName(OO_Call)).front());
   CallOperator->setReferenced();
   CallOperator->markUsed(Context);
 
@@ -2409,10 +2412,12 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
   // Add capture. The capture uses a fake variable, which doesn't correspond
   // to any actual memory location. However, the initializer copy-initializes
   // the lambda object.
-  TypeSourceInfo *CapVarTSI = Context.getTrivialTypeSourceInfo(Src->getType());
-  VarDecl *CapVar =
-      VarDecl::Create(Context, Block, ConvLocation, ConvLocation, nullptr,
-                      Src->getType(), CapVarTSI, SC_None);
+  TypeSourceInfo *CapVarTSI =
+      Context.getTrivialTypeSourceInfo(Src->getType());
+  VarDecl *CapVar = VarDecl::Create(Context, Block, ConvLocation,
+                                    ConvLocation, nullptr,
+                                    Src->getType(), CapVarTSI,
+                                    SC_None);
   BlockDecl::Capture Capture(/*variable=*/CapVar, /*byRef=*/false,
                              /*nested=*/false, /*copy=*/Init.get());
   Block->setCaptures(Context, Capture, /*CapturesCXXThis=*/false);



More information about the cfe-commits mailing list