diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index f1f4a1b79b7bc..602e325e560f9 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() ? 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 +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()) 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 d3b6a363c5bd8..1a1547a687f91 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-SAME: extraData: i32 -1 - // CHECK: ![[EMPTY_TEMPLATED_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "empty_templated", // CHECK-SAME: flags: DIFlagStaticMember // CHECK-SAME: extraData: i32 1 @@ -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 096bfa0271e0e..a111dc84b6e66 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"