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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits