[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
Michael Buch via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 20 02:49:13 PST 2023
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/72730
>From 6dcb09dcc50a9b9e92640412242927b3e226929e 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 1/6] [clang][DebugInfo][NFC] Create
evaluateConstantInitializer helper function
---
clang/lib/CodeGen/CGDebugInfo.cpp | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 0b52d99ad07f164..4840581b5d03f89 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -69,6 +69,19 @@ static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx) {
return D->hasAttr<AlignedAttr>() ? D->getMaxAlignment() : 0;
}
+APValue const * evaluateConstantInitializer(clang::VarDecl const * VD) {
+ assert (VD != nullptr);
+
+ VD = VD->getCanonicalDecl();
+ if (!VD)
+ return nullptr;
+
+ if (!VD->hasConstantInitialization() || !VD->hasInit())
+ return nullptr;
+
+ return VD->evaluateValue();
+}
+
CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
: CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
@@ -5596,14 +5609,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();
+ auto const * InitVal = evaluateConstantInitializer(VD);
if (!InitVal)
return;
>From fcc6e19d108798fb18c1973e4d4cc3800da07f9f Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 18 Nov 2023 00:52:24 +0000
Subject: [PATCH 2/6] fixup! clang-format
---
clang/lib/CodeGen/CGDebugInfo.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 4840581b5d03f89..9bba6e6b13e9318 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -69,8 +69,8 @@ static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx) {
return D->hasAttr<AlignedAttr>() ? D->getMaxAlignment() : 0;
}
-APValue const * evaluateConstantInitializer(clang::VarDecl const * VD) {
- assert (VD != nullptr);
+APValue const *evaluateConstantInitializer(clang::VarDecl const *VD) {
+ assert(VD != nullptr);
VD = VD->getCanonicalDecl();
if (!VD)
@@ -5613,7 +5613,7 @@ void CGDebugInfo::EmitGlobalVariable(const VarDecl *VD) {
if (CacheIt != DeclCache.end())
return;
- auto const * InitVal = evaluateConstantInitializer(VD);
+ auto const *InitVal = evaluateConstantInitializer(VD);
if (!InitVal)
return;
>From 148ab1793a866111060f77807ff065040fad92d8 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 18 Nov 2023 00:22:06 +0000
Subject: [PATCH 3/6] [clang][DebugInfo] Attach DW_AT_const_value to static
data-member definitions if available
---
clang/lib/CodeGen/CGDebugInfo.cpp | 10 ++++++++--
.../CodeGenCXX/debug-info-static-inline-member.cpp | 2 +-
clang/test/CodeGenCXX/inline-dllexport-member.cpp | 2 +-
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 9bba6e6b13e9318..e01c57baef19931 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5516,11 +5516,17 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
}
AppendAddressSpaceXDeref(AddressSpace, Expr);
+ llvm::DIExpression *E = nullptr;
+ if (Expr.empty()) {
+ if (auto const *InitVal = evaluateConstantInitializer(D))
+ E = createConstantValueExpression(D, *InitVal);
+ } else
+ E = DBuilder.createExpression(Expr);
+
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
GVE = DBuilder.createGlobalVariableExpression(
DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
- Var->hasLocalLinkage(), true,
- Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
+ Var->hasLocalLinkage(), true, E,
getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
Align, Annotations);
Var->addDebugInfo(GVE);
diff --git a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
index f2d4d9408a8297a..950ea9b302b290c 100644
--- a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
+++ b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
@@ -43,7 +43,7 @@ int main() {
// CHECK: @{{.*}}cexpr_struct_with_addr{{.*}} =
// CHECK-SAME !dbg ![[EMPTY_GLOBAL:[0-9]+]]
-// CHECK: !DIGlobalVariableExpression(var: ![[INT_VAR:[0-9]+]], expr: !DIExpression())
+// CHECK: !DIGlobalVariableExpression(var: ![[INT_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, 25, DW_OP_stack_value))
// CHECK: ![[INT_VAR]] = distinct !DIGlobalVariable(name: "cexpr_int_with_addr", linkageName:
// CHECK-SAME: isLocal: false, isDefinition: true, declaration: ![[INT_DECL:[0-9]+]])
diff --git a/clang/test/CodeGenCXX/inline-dllexport-member.cpp b/clang/test/CodeGenCXX/inline-dllexport-member.cpp
index d6b004d66dc6cbd..6bc01599c466780 100644
--- a/clang/test/CodeGenCXX/inline-dllexport-member.cpp
+++ b/clang/test/CodeGenCXX/inline-dllexport-member.cpp
@@ -7,7 +7,7 @@ struct __declspec(dllexport) s {
static const unsigned int ui = 0;
};
-// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]], expr: !DIExpression())
+// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]], expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value))
// CHECK: [[UIV]] = distinct !DIGlobalVariable(name: "ui", linkageName: "?ui at s@@2IB", scope: ![[SCOPE:[0-9]+]],
// CHECK: ![[SCOPE]] = distinct !DICompileUnit(
>From d654d67012fa3370904c440a7045885d237b2389 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 18 Nov 2023 00:55:01 +0000
Subject: [PATCH 4/6] fixup! make helper static
---
clang/lib/CodeGen/CGDebugInfo.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index e01c57baef19931..b0460c93acb4f67 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -69,7 +69,7 @@ static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx) {
return D->hasAttr<AlignedAttr>() ? D->getMaxAlignment() : 0;
}
-APValue const *evaluateConstantInitializer(clang::VarDecl const *VD) {
+static APValue const *evaluateConstantInitializer(clang::VarDecl const *VD) {
assert(VD != nullptr);
VD = VD->getCanonicalDecl();
>From e21fb80c09d66ff036b65425ff29f69f95eba226 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 18 Nov 2023 14:15:24 +0000
Subject: [PATCH 5/6] fixup! add braces to adhere to llvm-code style
---
clang/lib/CodeGen/CGDebugInfo.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index b0460c93acb4f67..0db72ad33cdd1d2 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5520,8 +5520,9 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
if (Expr.empty()) {
if (auto const *InitVal = evaluateConstantInitializer(D))
E = createConstantValueExpression(D, *InitVal);
- } else
+ } else {
E = DBuilder.createExpression(Expr);
+ }
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
GVE = DBuilder.createGlobalVariableExpression(
>From c5a6f0e4b6eea316f3d9a9ef32fb787cb4836354 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 20 Nov 2023 10:38:19 +0000
Subject: [PATCH 6/6] fixup! use getAnyInitializer instead of canonical decl
This is more idiomatic
---
clang/lib/CodeGen/CGDebugInfo.cpp | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 0db72ad33cdd1d2..54a368db7f77d16 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -69,17 +69,27 @@ static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx) {
return D->hasAttr<AlignedAttr>() ? D->getMaxAlignment() : 0;
}
-static APValue const *evaluateConstantInitializer(clang::VarDecl const *VD) {
+/// 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 on failure.
+static std::optional<APValue>
+evaluateConstantInitializer(const clang::VarDecl *VD,
+ const clang::ASTContext &Ctx) {
assert(VD != nullptr);
- VD = VD->getCanonicalDecl();
- if (!VD)
- return nullptr;
+ if (!VD->isStaticDataMember())
+ return std::nullopt;
- if (!VD->hasConstantInitialization() || !VD->hasInit())
- return nullptr;
+ if (!VD->isUsableInConstantExpressions(Ctx))
+ return std::nullopt;
+
+ auto const *InitExpr = VD->getAnyInitializer();
+ Expr::EvalResult Result;
+ if (!InitExpr->EvaluateAsConstantExpr(Result, Ctx))
+ return std::nullopt;
- return VD->evaluateValue();
+ return Result.Val;
}
CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
@@ -5518,7 +5528,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
llvm::DIExpression *E = nullptr;
if (Expr.empty()) {
- if (auto const *InitVal = evaluateConstantInitializer(D))
+ if (const auto InitVal = evaluateConstantInitializer(D, CGM.getContext()))
E = createConstantValueExpression(D, *InitVal);
} else {
E = DBuilder.createExpression(Expr);
@@ -5620,7 +5630,7 @@ void CGDebugInfo::EmitGlobalVariable(const VarDecl *VD) {
if (CacheIt != DeclCache.end())
return;
- auto const *InitVal = evaluateConstantInitializer(VD);
+ const auto InitVal = evaluateConstantInitializer(VD, CGM.getContext());
if (!InitVal)
return;
More information about the cfe-commits
mailing list