Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4818,19 +4818,6 @@ struct DestroyUnpassedArg final : EHScopeStack::Cleanup {
}
};

struct DisableDebugLocationUpdates {
CodeGenFunction &CGF;
bool disabledDebugInfo;
DisableDebugLocationUpdates(CodeGenFunction &CGF, const Expr *E) : CGF(CGF) {
if ((disabledDebugInfo = isa<CXXDefaultArgExpr>(E) && CGF.getDebugInfo()))
CGF.disableDebugInfo();
}
~DisableDebugLocationUpdates() {
if (disabledDebugInfo)
CGF.enableDebugInfo();
}
};

} // end anonymous namespace

RValue CallArg::getRValue(CodeGenFunction &CGF) const {
Expand Down Expand Up @@ -4867,7 +4854,9 @@ void CodeGenFunction::EmitWritebacks(const CallArgList &args) {

void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
QualType type) {
DisableDebugLocationUpdates Dis(*this, E);
std::optional<DisableDebugLocationUpdates> Dis;
if (isa<CXXDefaultArgExpr>(E))
Dis.emplace(*this);
if (const ObjCIndirectCopyRestoreExpr *CRE =
dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
assert(getLangOpts().ObjCAutoRefCount);
Expand Down Expand Up @@ -6282,3 +6271,12 @@ RValue CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr,
return CGM.getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty, Slot);
return CGM.getABIInfo().EmitVAArg(*this, VAListAddr, Ty, Slot);
}

DisableDebugLocationUpdates::DisableDebugLocationUpdates(CodeGenFunction &CGF)
: CGF(CGF) {
CGF.disableDebugInfo();
}

DisableDebugLocationUpdates::~DisableDebugLocationUpdates() {
CGF.enableDebugInfo();
}
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/CGCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,12 @@ inline FnInfoOpts &operator&=(FnInfoOpts &A, FnInfoOpts B) {
return A;
}

struct DisableDebugLocationUpdates {
CodeGenFunction &CGF;
DisableDebugLocationUpdates(CodeGenFunction &CGF);
~DisableDebugLocationUpdates();
};

} // end namespace CodeGen
} // end namespace clang

Expand Down
9 changes: 8 additions & 1 deletion clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3387,7 +3387,14 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
auto *FD = LambdaCaptureFields.lookup(BD);
return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue);
}
return EmitLValue(BD->getBinding());
// Suppress debug location updates when visiting the binding, since the
// binding may emit instructions that would otherwise be associated with the
// binding itself, rather than the expression referencing the binding. (this
// leads to jumpy debug stepping behavior where the location/debugger jump
// back to the binding declaration, then back to the expression referencing
// the binding)
DisableDebugLocationUpdates D(*this);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

return EmitLValue(BD->getBinding(), NotKnownNonNull);
}

// We can form DeclRefExprs naming GUID declarations when reconstituting
Expand Down
44 changes: 43 additions & 1 deletion clang/test/DebugInfo/CXX/structured-binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
// CHECK: #dbg_declare(ptr %{{[0-9]+}}, ![[VAR_4:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 4),
// CHECK: #dbg_declare(ptr %z1, ![[VAR_5:[0-9]+]], !DIExpression()
// CHECK: #dbg_declare(ptr %z2, ![[VAR_6:[0-9]+]], !DIExpression()
// CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg ![[Y1_DEBUG_LOC:[0-9]+]]
// CHECK: getelementptr inbounds nuw %struct.A, ptr {{.*}}, i32 0, i32 1, !dbg ![[Y2_DEBUG_LOC:[0-9]+]]
// CHECK: load ptr, ptr %z2, {{.*}}!dbg ![[Z2_DEBUG_LOC:[0-9]+]]
// CHECK: getelementptr inbounds [2 x i32], ptr {{.*}}, i64 0, i64 1, !dbg ![[A2_DEBUG_LOC:[0-9]+]]
// CHECK: getelementptr inbounds nuw { i32, i32 }, ptr {{.*}}, i32 0, i32 1, !dbg ![[C2_DEBUG_LOC:[0-9]+]]
// CHECK: extractelement <2 x i32> {{.*}}, i32 1, !dbg ![[V2_DEBUG_LOC:[0-9]+]]
// CHECK: ![[VAR_0]] = !DILocalVariable(name: "a"
// CHECK: ![[VAR_1]] = !DILocalVariable(name: "x1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
// CHECK: ![[VAR_2]] = !DILocalVariable(name: "y1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
Expand Down Expand Up @@ -46,5 +52,41 @@ int f() {
auto [x1, y1] = a;
auto &[x2, y2] = a;
auto [z1, z2] = B{1, 2};
return x1 + y1 + x2 + y2 + z1 + z2;
int array[2] = {3, 4};
auto &[a1, a2] = array;
_Complex int cmplx = {1, 2};
auto &[c1, c2] = cmplx;
int vctr __attribute__ ((vector_size (sizeof(int)*2)))= {1, 2};
auto &[v1, v2] = vctr;
return //
x1 //
+ //
// CHECK: ![[Y1_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]
y1 //
+ //
x2 //
+ //
// CHECK: ![[Y2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]
y2 //
+ //
z1 //
+ //
// CHECK: ![[Z2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]
z2 //
+ //
a1 //
+ //
// CHECK: ![[A2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]
a2 //
+ //
c1 //
+ //
// CHECK: ![[C2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]
c2 //
+ //
v1 //
+ //
// CHECK: ![[V2_DEBUG_LOC]] = !DILocation(line: [[@LINE+1]]
v2 //
;
}
Loading