[clang] [clang][DebugInfo] Improve heuristic to determine whether to evaluate a static variable's initializer (PR #72974)

Michael Buch via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 21 02:25:09 PST 2023


https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/72974

This patch extracts the logic to evaluate a C++ static data-member's constant initializer such that it can be used by 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)

>From 4bb7f6b708480fbd831614b552560fa1504c1a59 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 18 Nov 2023 00:20:05 +0000
Subject: [PATCH] [clang][DebugInfo] Create evaluateConstantInitializer helper
 function

This patch extracts the logic to evaluate a C++ static
data-member's constant initializer such that it can be
used by 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.
---
 clang/lib/CodeGen/CGDebugInfo.cpp             | 28 ++++++++++++++++---
 .../debug-info-static-inline-member.cpp       |  9 ------
 2 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 0b52d99ad07f164..4c7c7d68b4271e3 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),
@@ -5596,14 +5619,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;
 
diff --git a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
index f2d4d9408a8297a..6ba98373d33ada8 100644
--- a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
+++ b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
@@ -67,10 +67,6 @@ int main() {
 // CHECK-SAME:                          flags: DIFlagStaticMember
 // CHECK-NOT:                           extraData:
 
-// CHECK:      ![[IENUM_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "inline_enum",
-// CHECK-SAME:                          flags: DIFlagStaticMember
-// CHECK-NOT:                           extraData:
-
 // CHECK:      ![[EMPTY_TEMPLATED_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "empty_templated",
 // CHECK-SAME:                                    flags: DIFlagStaticMember
 // CHECK-NOT:                                     extraData:
@@ -98,11 +94,6 @@ int main() {
 // CHECK-NOT:                  linkageName:
 // CHECK-SAME:                 isLocal: true, isDefinition: true, declaration: ![[ENUM_DECL]])
 
-// CHECK:      !DIGlobalVariableExpression(var: ![[IENUM_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, {{.*}}, DW_OP_stack_value))
-// CHECK:      ![[IENUM_VAR]] = distinct !DIGlobalVariable(name: "inline_enum"
-// CHECK-NOT:                   linkageName:
-// CHECK-SAME:                  isLocal: true, isDefinition: true, declaration: ![[IENUM_DECL]])
-
 // CHECK:      !DIGlobalVariableExpression(var: ![[EMPTY_TEMPLATED_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, 1, DW_OP_stack_value))
 // CHECK:      ![[EMPTY_TEMPLATED_VAR]] = distinct !DIGlobalVariable(name: "empty_templated"
 // CHECK-NOT:                             linkageName:



More information about the cfe-commits mailing list