Author: Serafean
Date: 2026-07-27T09:38:01-04:00
New Revision: 0a75f1f77fe54e9e366e48f78c9865aee8839809

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

LOG: [libclang]Visit lambda init-capture as VarDeclaration (#174116)

```
int foo(){
    int i = 42;
    int j = 43;

    auto l1 = [x = i, &j ](){};
}
```

in the lambda capture:
- `x` is visited as VariableRef (referencing an unvisited VarDecl at the
same location)
- `i` is visited as DelcRefExpr (fair enough, same as in an assignment)
- `j` is visited as VariableRef

Visit `x` as a `VarDecl`, and stop visiting it as a `VariableRef`, as it
makes no sense (referencing itself at an unvisited cursor).

---------

Co-authored-by: Serafean <[email protected]>

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.md
    clang/test/Index/cxx14-lambdas.cpp
    clang/tools/libclang/CIndex.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 74df9c88d1185..7b829db478088 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -456,6 +456,8 @@ features cannot lower the translation-unit ABI level;
 
 ### libclang
 
+- visit identifier initializers in lambda capture as VarDecl instead of 
VariableRef. Warning: this changes behaviour.
+
 ### Code Completion
 
 ### Static Analyzer

diff  --git a/clang/test/Index/cxx14-lambdas.cpp 
b/clang/test/Index/cxx14-lambdas.cpp
index 0c9aaec6c88e5..dfcf812ae3016 100644
--- a/clang/test/Index/cxx14-lambdas.cpp
+++ b/clang/test/Index/cxx14-lambdas.cpp
@@ -17,9 +17,9 @@ struct X {
 // CHECK-LOAD: cxx14-lambdas.cpp:7:19: CallExpr= Extent=[7:19 - 9:6]
 // CHECK-LOAD: cxx14-lambdas.cpp:7:19: UnexposedExpr= Extent=[7:19 - 9:6]
 // CHECK-LOAD: cxx14-lambdas.cpp:7:19: LambdaExpr= Extent=[7:19 - 9:6]
-// CHECK-LOAD: cxx14-lambdas.cpp:7:20: VariableRef=ptr:7:20 Extent=[7:20 - 
7:23]
-// CHECK-LOAD: cxx14-lambdas.cpp:7:35: VariableRef=copy:7:35 Extent=[7:35 - 
7:39]
+// CHECK-LOAD: cxx14-lambdas.cpp:7:20: VarDecl=ptr:7:20 (Definition) 
Extent=[7:20 - 7:33]
 // CHECK-LOAD: cxx14-lambdas.cpp:7:27: DeclRefExpr=localA:6:9 Extent=[7:27 - 
7:33]
+// CHECK-LOAD: cxx14-lambdas.cpp:7:35: VarDecl=copy:7:35 (Definition) 
Extent=[7:35 - 7:48]
 // CHECK-LOAD: cxx14-lambdas.cpp:7:42: DeclRefExpr=localB:6:17 Extent=[7:42 - 
7:48]
 // CHECK-LOAD: cxx14-lambdas.cpp:7:59: ParmDecl=x:7:59 (Definition) 
Extent=[7:51 - 7:60]
 // CHECK-LOAD: cxx14-lambdas.cpp:7:51: TypeRef=Integer:3:13 Extent=[7:51 - 
7:58]

diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 56eb3ad9050ef..7c9da867909f5 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -3928,19 +3928,20 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList 
&WL) {
       for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
                                         CEnd = E->explicit_capture_end();
            C != CEnd; ++C) {
+
         if (!C->capturesVariable())
           continue;
-        // TODO: handle structured bindings here ?
-        if (!isa<VarDecl>(C->getCapturedVar()))
-          continue;
-        if (Visit(MakeCursorVariableRef(cast<VarDecl>(C->getCapturedVar()),
-                                        C->getLocation(), TU)))
-          return true;
-      }
-      // Visit init captures
-      for (auto InitExpr : E->capture_inits()) {
-        if (InitExpr && Visit(InitExpr))
-          return true;
+
+        if (const auto *CV = dyn_cast_or_null<VarDecl>(C->getCapturedVar())) {
+          if (CV->isInitCapture()) {
+            // Init capture is a declaration, create VarDecl cursor
+            if (Visit(MakeCXCursor(CV, TU, RegionOfInterest)))
+              return true;
+          } else
+            // Non init capture is a VariableRef
+            if (Visit(MakeCursorVariableRef(CV, C->getLocation(), TU)))
+              return true;
+        }
       }
 
       TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to