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-...@users.noreply.github.com>
Date: Wed, 27 Nov 2024 18:43:38 -0700
Subject: [PATCH 01/31] 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-...@users.noreply.github.com>
Date: Wed, 27 Nov 2024 18:48:37 -0700
Subject: [PATCH 02/31] 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-...@users.noreply.github.com>
Date: Wed, 27 Nov 2024 21:52:22 -0700
Subject: [PATCH 03/31] 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-...@users.noreply.github.com>
Date: Wed, 27 Nov 2024 21:58:20 -0700
Subject: [PATCH 04/31] 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-...@users.noreply.github.com>
Date: Wed, 27 Nov 2024 22:07:07 -0700
Subject: [PATCH 05/31] 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-...@users.noreply.github.com>
Date: Wed, 27 Nov 2024 22:15:07 -0700
Subject: [PATCH 06/31] 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-...@users.noreply.github.com>
Date: Fri, 29 Nov 2024 02:59:55 -0700
Subject: [PATCH 07/31] 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-...@users.noreply.github.com>
Date: Fri, 29 Nov 2024 03:01:12 -0700
Subject: [PATCH 08/31] 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-...@users.noreply.github.com>
Date: Fri, 29 Nov 2024 03:02:10 -0700
Subject: [PATCH 09/31] 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-...@users.noreply.github.com>
Date: Fri, 20 Dec 2024 15:07:49 -0700
Subject: [PATCH 10/31] 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-...@users.noreply.github.com>
Date: Fri, 20 Dec 2024 15:08:14 -0700
Subject: [PATCH 11/31] 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-...@users.noreply.github.com>
Date: Fri, 20 Dec 2024 15:08:48 -0700
Subject: [PATCH 12/31] Update ParseExprCXX.cpp


>From 0326d6e9dc3eb75606c5b463945dbd6bd005cdd3 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-...@users.noreply.github.com>
Date: Fri, 20 Dec 2024 15:09:30 -0700
Subject: [PATCH 13/31] 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-...@users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:57:51 -0700
Subject: [PATCH 14/31] 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-...@users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:58:52 -0700
Subject: [PATCH 15/31] Update ParseExprCXX.cpp


>From cbda68a9a539c8f27f1783061c0e63fe7c3cae76 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-...@users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:59:08 -0700
Subject: [PATCH 16/31] 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-...@users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:59:39 -0700
Subject: [PATCH 17/31] Update fixit-unused-lambda-capture.cpp


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


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


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


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


>From cd72b630cc77a67c16e415cf2b7c783528dfa524 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-...@users.noreply.github.com>
Date: Thu, 26 Dec 2024 16:48:01 -0700
Subject: [PATCH 22/31] 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@-1 {{initialized 
lambda captures are a C++14 extension}}
 }

>From 0f9b9f86ecd54e6d86003a4d605658c112acd274 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-...@users.noreply.github.com>
Date: Thu, 13 Feb 2025 00:30:42 -0700
Subject: [PATCH 23/31] 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-...@users.noreply.github.com>
Date: Thu, 13 Feb 2025 16:28:16 -0700
Subject: [PATCH 24/31] 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-...@users.noreply.github.com>
Date: Fri, 2 May 2025 05:13:16 -0600
Subject: [PATCH 25/31] 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@-1 {{initialized 
lambda captures are a C++14 extension}}
 }

>From 9a57bafa514fc48adb52adaa35bb35c09af26609 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-...@users.noreply.github.com>
Date: Fri, 2 May 2025 12:19:08 -0600
Subject: [PATCH 26/31] 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-...@users.noreply.github.com>
Date: Fri, 2 May 2025 15:13:25 -0600
Subject: [PATCH 27/31] 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-...@users.noreply.github.com>
Date: Fri, 2 May 2025 15:16:50 -0600
Subject: [PATCH 28/31] 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-...@users.noreply.github.com>
Date: Sat, 3 May 2025 14:45:51 -0600
Subject: [PATCH 29/31] 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@-1 {{initialized 
lambda captures are a C++14 extension}}
 }

>From f5ef37c6fc7fe68238e51d3a79d0e282b7f5b603 Mon Sep 17 00:00:00 2001
From: charan-003 <85248228+charan-...@users.noreply.github.com>
Date: Sat, 3 May 2025 14:45:58 -0600
Subject: [PATCH 30/31] 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-...@users.noreply.github.com>
Date: Sat, 3 May 2025 14:46:12 -0600
Subject: [PATCH 31/31] 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);

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

Reply via email to