diff options
| author | Michael Buch <michaelbuch12@gmail.com> | 2023-11-30 10:41:24 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-30 10:41:24 +0000 |
| commit | 53a24c33f09b81b8f009afbabd05f7086db3f288 (patch) | |
| tree | d27e1de9b0416efefc74fa9cc66644924a9fe726 /clang/lib/CodeGen/CGDebugInfo.cpp | |
| parent | e620035a28d5d957623aa7b4aeda35ab5130e2c9 (diff) | |
| download | llvm-53a24c33f09b81b8f009afbabd05f7086db3f288.zip llvm-53a24c33f09b81b8f009afbabd05f7086db3f288.tar.gz llvm-53a24c33f09b81b8f009afbabd05f7086db3f288.tar.bz2 | |
[clang][DebugInfo] Improve heuristic to determine whether to evaluate a static variable's initializer (#72974)
This patch extracts the logic to evaluate a C++ static data-member's
constant initializer. This logic will be re-used in an upcoming patch.
It also makes the check for whether we are dealing with a constant
initializer more robust/idiomatic, which revealed a bug in the
`debug-info-static-inline-member` test (which existed since its
introduction in https://github.com/llvm/llvm-project/pull/71780)
**Test changes**
* `debug-info-static-member.cpp`:
* We added the check for `const_b` as part of the
patch series in `638a8393615e911b729d5662096f60ef49f1c65e`.
The check for `isUsableAsConstantExpression` added in the current patch
doesn't support constant inline floats (since they are neither constexpr
nor
integrals). This isn't a regression since before said patch series
we wouldn't ever emit the definition for `const_b` anyway. Now
we just don't do it for `inline const float`s. This is consistent with
GCC's behaviour starting with C++11.
* `debug-info-static-inline-member`:
* This was just a bug which is now fixed. We shouldn't emit
a `DW_AT_const_value` for a non-const static.
Diffstat (limited to 'clang/lib/CodeGen/CGDebugInfo.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index f1f4a1b..602e325 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -69,6 +69,29 @@ static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx) { return D->hasAttr<AlignedAttr>() ? D->getMaxAlignment() : 0; } +/// Given a VarDecl corresponding to either the definition or +/// declaration of a C++ static data member, if it has a constant +/// initializer and is evaluatable, return the evaluated value. +/// Returns std::nullopt otherwise. +static std::optional<APValue> +evaluateConstantInitializer(const clang::VarDecl *VD, + const clang::ASTContext &Ctx) { + assert(VD != nullptr); + + if (!VD->isStaticDataMember()) + return std::nullopt; + + if (!VD->isUsableInConstantExpressions(Ctx)) + return std::nullopt; + + auto const *InitExpr = VD->getAnyInitializer(); + Expr::EvalResult Result; + if (!InitExpr->EvaluateAsConstantExpr(Result, Ctx)) + return std::nullopt; + + return Result.Val; +} + CGDebugInfo::CGDebugInfo(CodeGenModule &CGM) : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()), DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs), @@ -5610,14 +5633,11 @@ void CGDebugInfo::EmitGlobalVariable(const VarDecl *VD) { if (VD->hasAttr<NoDebugAttr>()) return; - if (!VD->hasInit()) - return; - const auto CacheIt = DeclCache.find(VD); if (CacheIt != DeclCache.end()) return; - auto const *InitVal = VD->evaluateValue(); + const auto InitVal = evaluateConstantInitializer(VD, CGM.getContext()); if (!InitVal) return; |
