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