diff options
author | David Blaikie <dblaikie@gmail.com> | 2025-09-02 14:03:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-02 21:03:58 +0000 |
commit | 665e875f1a86be650e044bb20744bb272d03e11d (patch) | |
tree | 4a28f777685bd58931a11a684e6f89c003832946 /clang/lib/CodeGen/CGCall.cpp | |
parent | 3c7bf3b3c3a4871d13f7b7d5d60bbf190eaf8f3a (diff) | |
download | llvm-665e875f1a86be650e044bb20744bb272d03e11d.zip llvm-665e875f1a86be650e044bb20744bb272d03e11d.tar.gz llvm-665e875f1a86be650e044bb20744bb272d03e11d.tar.bz2 |
[DebugInfo] When referencing structured bindings use the reference's location, not the binding's declaration's location (#153637)
For structured bindings that use custom `get` specializations, the
resulting LLVM IR ascribes the load of the result of `get` to the
binding's declaration, rather than the place where the binding is
referenced - this caused awkward sequencing in the debug info where,
when stepping through the code you'd step back to the binding
declaration every time there was a reference to the binding.
To fix that - when we cross into IRGening a binding - suppress the debug
info location of that subexpression.
I don't represent this as a great bit of API design - certainly open to
ideas, but putting it out here as a place to start.
It's /possible/ this is an incomplete fix, even - if the binding decl
had other subexpressions, those would still get their location applied &
it'd likely be wrong.
So maybe that's a direction to go with to productionize this - add a new
location scoped device that suppresses any overriding - this might be
more robust. How do people feel about that?
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index c024f94..a94a7ed 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -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 { @@ -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); @@ -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(); +} |