vsk updated this revision to Diff 162764.
vsk added a comment.

- Partially address some of @rsmith's feedback. Instead of using the capture 
default location, I used the beginning location of the capture list. This 
results in smoother single-stepping when those two locations are on different 
lines.


https://reviews.llvm.org/D50927

Files:
  clang/lib/Sema/SemaLambda.cpp
  clang/test/CodeGenCXX/debug-info-lambda.cpp
  clang/test/SemaCXX/uninitialized.cpp
  clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp

Index: clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
===================================================================
--- clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
+++ clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
@@ -75,11 +75,15 @@
 TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) {
   DeclRefExprVisitor Visitor;
   Visitor.setShouldVisitImplicitCode(true);
-  // We're expecting the "i" in the lambda to be visited twice:
-  // - Once for the DeclRefExpr in the lambda capture initialization (whose
-  //   source code location is set to the first use of the variable).
-  // - Once for the DeclRefExpr for the use of "i" inside the lambda.
-  Visitor.ExpectMatch("i", 1, 24, /*Times=*/2);
+  // We're expecting the "i" in the lambda to be visited just once (for the
+  // DeclRefExpr for the use of "i" inside the lambda).
+  //
+  // Previously, the DeclRefExpr in the implicit lambda capture initialization
+  // (whose source code location was set to the first use of the variable) was
+  // also matched. This location was changed to the starting site of the
+  // capture list to improve stepping behavior.
+  Visitor.ExpectMatch("i", 1, 19, /*Times=*/1);
+  Visitor.ExpectMatch("i", 1, 24, /*Times=*/1);
   EXPECT_TRUE(Visitor.runOver(
     "void f() { int i; [=]{ i; }; }",
     DeclRefExprVisitor::Lang_CXX11));
Index: clang/test/SemaCXX/uninitialized.cpp
===================================================================
--- clang/test/SemaCXX/uninitialized.cpp
+++ clang/test/SemaCXX/uninitialized.cpp
@@ -884,8 +884,10 @@
     int x;
   };
   A a0([] { return a0.x; }); // ok
-  void f() { 
-    A a1([=] { return a1.x; }); // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
+  void f() {
+    A a1([=] { // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
+      return a1.x;
+    });
     A a2([&] { return a2.x; }); // ok
   }
 }
Index: clang/test/CodeGenCXX/debug-info-lambda.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/debug-info-lambda.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm \
+// RUN:   -debug-info-kind=line-tables-only -dwarf-column-info -std=c++11 %s -o - | FileCheck %s
+
+// CHECK-LABEL: define{{.*}}lambda_in_func
+void lambda_in_func(int &ref) {
+  // CHECK: [[ref_slot:%.*]] = getelementptr inbounds %class.anon, %class.anon* {{.*}}, i32 0, i32 0, !dbg [[lambda_decl_loc:![0-9]+]]
+  // CHECK-NEXT: %1 = load i32*, i32** %ref.addr, align 8, !dbg [[lambda_decl_loc]]
+  // CHECK-NEXT: store i32* %1, i32** %0, align 8, !dbg [[lambda_decl_loc]]
+  // CHECK-NEXT: call void {{.*}}, !dbg [[lambda_call_loc:![0-9]+]]
+
+  auto helper = [       // CHECK: [[lambda_decl_loc]] = !DILocation(line: [[@LINE]], column: 17
+                 &]() { 
+    ++ref;
+  };
+  helper();             // CHECK: [[lambda_call_loc]] = !DILocation(line: [[@LINE]]
+}
Index: clang/lib/Sema/SemaLambda.cpp
===================================================================
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -1392,13 +1392,14 @@
   Class->addDecl(Conversion);
 }
 
-static ExprResult performLambdaVarCaptureInitialization(Sema &S,
-                                                        const Capture &Capture,
-                                                        FieldDecl *Field) {
+static ExprResult performLambdaVarCaptureInitialization(
+    Sema &S, const Capture &Capture, FieldDecl *Field,
+    SourceLocation ImplicitCaptureLoc, bool IsImplicitCapture) {
   assert(Capture.isVariableCapture() && "not a variable capture");
 
   auto *Var = Capture.getVariable();
   SourceLocation Loc = Capture.getLocation();
+  SourceLocation InitLoc = IsImplicitCapture ? ImplicitCaptureLoc : Loc;
 
   // C++11 [expr.prim.lambda]p21:
   //   When the lambda-expression is evaluated, the entities that
@@ -1413,7 +1414,7 @@
   //   An entity captured by a lambda-expression is odr-used (3.2) in
   //   the scope containing the lambda-expression.
   ExprResult RefResult = S.BuildDeclarationNameExpr(
-      CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), Loc), Var);
+      CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), InitLoc), Var);
   if (RefResult.isInvalid())
     return ExprError();
   Expr *Ref = RefResult.get();
@@ -1607,8 +1608,8 @@
                                        Var, From.getEllipsisLoc()));
       Expr *Init = From.getInitExpr();
       if (!Init) {
-        auto InitResult =
-            performLambdaVarCaptureInitialization(*this, From, *CurField);
+        auto InitResult = performLambdaVarCaptureInitialization(
+            *this, From, *CurField, IntroducerRange.getBegin(), IsImplicit);
         if (InitResult.isInvalid())
           return ExprError();
         Init = InitResult.get();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to