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 <michaelbuc...@gmail.com> Date: Sat, 18 Nov 2023 00:20:05 +0000 Subject: [PATCH 1/8] [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 <michaelbuc...@gmail.com> Date: Sat, 18 Nov 2023 00:52:24 +0000 Subject: [PATCH 2/8] 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 <michaelbuc...@gmail.com> Date: Sat, 18 Nov 2023 00:22:06 +0000 Subject: [PATCH 3/8] [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@s@@2IB", scope: ![[SCOPE:[0-9]+]], // CHECK: ![[SCOPE]] = distinct !DICompileUnit( >From d654d67012fa3370904c440a7045885d237b2389 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Sat, 18 Nov 2023 00:55:01 +0000 Subject: [PATCH 4/8] 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 <michaelbuc...@gmail.com> Date: Sat, 18 Nov 2023 14:15:24 +0000 Subject: [PATCH 5/8] 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 <michaelbuc...@gmail.com> Date: Mon, 20 Nov 2023 10:38:19 +0000 Subject: [PATCH 6/8] 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; >From 6677a50749f717b8c8ef6f56bc1fb771da8a4cd0 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Mon, 20 Nov 2023 12:43:19 +0000 Subject: [PATCH 7/8] fixup! fix tests * `debug-info-static-member.cpp`: * We added the check for `const_b` as part of the patch series in `638a8393615e911b729d5662096f60ef49f1c65e`. The new check `isUsableAsConstantExpression` 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 `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. --- .../CodeGenCXX/debug-info-static-inline-member.cpp | 9 --------- clang/test/CodeGenCXX/debug-info-static-member.cpp | 14 +++++++------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp index 950ea9b302b290c..b7683f9dc8825d2 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: diff --git a/clang/test/CodeGenCXX/debug-info-static-member.cpp b/clang/test/CodeGenCXX/debug-info-static-member.cpp index a2d25e98ed1cb62..519c971e1fbf1b9 100644 --- a/clang/test/CodeGenCXX/debug-info-static-member.cpp +++ b/clang/test/CodeGenCXX/debug-info-static-member.cpp @@ -1,8 +1,8 @@ -// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-4 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4,NOT-MS %s +// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-4 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4,CPP11,NOT-MS %s // RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-4 -std=c++98 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4,NOT-MS %s -// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-4 -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4,NOT-MS %s -// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-5 -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF5 %s -// RUN: %clangxx -target x86_64-windows-msvc -g -gdwarf-4 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4 %s +// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-4 -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4,CPP11,NOT-MS %s +// RUN: %clangxx -target x86_64-unknown-unknown -g -gdwarf-5 -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF5,CPP11 %s +// RUN: %clangxx -target x86_64-windows-msvc -g -gdwarf-4 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,DWARF4,CPP11 %s // PR14471 // CHECK: @{{.*}}a{{.*}} = dso_local global i32 4, align 4, !dbg [[A:![0-9]+]] @@ -171,9 +171,9 @@ int y::z; // CHECK: ![[CONST_A_VAR]] = distinct !DIGlobalVariable(name: "const_a" // CHECK-SAME: isLocal: true, isDefinition: true, declaration: ![[CONST_A_DECL]]) -// CHECK: !DIGlobalVariableExpression(var: ![[CONST_B_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, {{.*}}, DW_OP_stack_value)) -// CHECK: ![[CONST_B_VAR]] = distinct !DIGlobalVariable(name: "const_b" -// CHECK-SAME: isLocal: true, isDefinition: true, declaration: ![[CONST_B_DECL]]) +// CPP11: !DIGlobalVariableExpression(var: ![[CONST_B_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, {{.*}}, DW_OP_stack_value)) +// CPP11: ![[CONST_B_VAR]] = distinct !DIGlobalVariable(name: "const_b" +// CPP11-SAME: isLocal: true, isDefinition: true, declaration: ![[CONST_B_DECL]]) // CHECK: !DIGlobalVariableExpression(var: ![[CONST_C_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, 18, DW_OP_stack_value)) // CHECK: ![[CONST_C_VAR]] = distinct !DIGlobalVariable(name: "const_c" >From 3e5ed7b53661f93907d255b56f7e2d5ee602e011 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Mon, 20 Nov 2023 16:17:06 +0000 Subject: [PATCH 8/8] fixup! clarify function comment --- 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 54a368db7f77d16..7b79612fc7ad50e 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -72,7 +72,7 @@ static uint32_t getDeclAlignIfRequired(const Decl *D, const ASTContext &Ctx) { /// 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. +/// Returns std::nullopt otherwise. static std::optional<APValue> evaluateConstantInitializer(const clang::VarDecl *VD, const clang::ASTContext &Ctx) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits