aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGDebugInfo.cpp
diff options
context:
space:
mode:
authorMichael Buch <michaelbuch12@gmail.com>2023-11-30 10:41:24 +0000
committerGitHub <noreply@github.com>2023-11-30 10:41:24 +0000
commit53a24c33f09b81b8f009afbabd05f7086db3f288 (patch)
treed27e1de9b0416efefc74fa9cc66644924a9fe726 /clang/lib/CodeGen/CGDebugInfo.cpp
parente620035a28d5d957623aa7b4aeda35ab5130e2c9 (diff)
downloadllvm-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.cpp28
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;