[clang] 066eea7 - Revert "Reland "clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (#70639)""

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 7 06:52:53 PST 2023


Author: Hans Wennborg
Date: 2023-11-07T15:52:19+01:00
New Revision: 066eea75d38957353824b46474413ef2632d01a7

URL: https://github.com/llvm/llvm-project/commit/066eea75d38957353824b46474413ef2632d01a7
DIFF: https://github.com/llvm/llvm-project/commit/066eea75d38957353824b46474413ef2632d01a7.diff

LOG: Revert "Reland "clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (#70639)""

This casued asserts:

  llvm/lib/IR/Metadata.cpp:689:
  void llvm::MDNode::resolve(): Assertion `isUniqued() && "Expected this to be uniqued"' failed.

See comments on the PR.

This also reverts the dependent follow-up commits, see below.

> When an LLDB user asks for the value of a static data member, LLDB
> starts by searching the Names accelerator table for the corresponding
> variable definition DIE. For static data members with out-of-class
> definitions that works fine, because those get represented as global
> variables with a location and making them eligible to be added to the
> Names table. However, in-class definitions won<E2><80><99>t get indexed because
> we usually don't emit global variables for them. So in DWARF we end
> up with a single `DW_TAG_member` that usually holds the constant
> initializer.  But we don't get a corresponding CU-level
> `DW_TAG_variable` like we do for out-of-class definitions.
>
> To make it more convenient for debuggers to get to the value of
> inline static data members, this patch makes sure we emit definitions
> for static variables with constant initializers the same way we do
> for other static variables. This also aligns Clang closer to GCC,
> which produces CU-level definitions for inline statics and also
> emits these into `.debug_pubnames`.
>
> The implementation keeps track of newly created static data members.
> Then in `CGDebugInfo::finalize`, we emit a global `DW_TAG_variable`
> with a `DW_AT_const_value` for any of those declarations that didn't
> end up with a definition in the `DeclCache`.
>
> The newly emitted `DW_TAG_variable` will look as follows:
> ```
> 0x0000007b:   DW_TAG_structure_type
>                 DW_AT_calling_convention        (DW_CC_pass_by_value)
>                 DW_AT_name      ("Foo")
>                 ...
>
> 0x0000008d:     DW_TAG_member
>                   DW_AT_name    ("i")
>                   DW_AT_type    (0x00000062 "const int")
>                   DW_AT_external        (true)
>                   DW_AT_declaration     (true)
>                   DW_AT_const_value     (4)
>
> Newly added
> vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
>
> 0x0000009a:   DW_TAG_variable
>                 DW_AT_specification     (0x0000008d "i")
>                 DW_AT_const_value       (4)
>                 DW_AT_linkage_name      ("_ZN2t2IiE1iIfEE")
> ```
>
> This patch also drops the `DW_AT_const_value` off of the declaration
> since we now always have it on the definition. This ensures that the
> `DWARFParallelLinker` can type-merge class with static members where
> we couldn't attach the constant on the declaration in some CUs.

This reverts commit 7c3707aea8a6f1fc245ad2862982b8a51b6c0fea.
This reverts commit cab0a19467ac2e6e1e022087f4b6cb90d55da040.
This reverts commit 317481b3c8b34b0c3f106c514e6aa39b70886110.
This reverts commit 15fc809404d4715822e5349b76dcca50eb100eec.
This reverts commit 470de2bbec7f5fdd199775aa99c68ac76f4d5c74.

Added: 
    

Modified: 
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/lib/CodeGen/CGDebugInfo.h
    clang/test/CodeGenCXX/debug-info-class.cpp
    clang/test/CodeGenCXX/debug-info-static-member.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
    lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
    lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
    lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py

Removed: 
    clang/test/CodeGenCXX/debug-info-static-inline-member.cpp


################################################################################
diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 410c8f522b1017f..84a166d3ac3659c 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1677,13 +1677,22 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy,
 
   unsigned LineNumber = getLineNumber(Var->getLocation());
   StringRef VName = Var->getName();
+  llvm::Constant *C = nullptr;
+  if (Var->getInit()) {
+    const APValue *Value = Var->evaluateValue();
+    if (Value) {
+      if (Value->isInt())
+        C = llvm::ConstantInt::get(CGM.getLLVMContext(), Value->getInt());
+      if (Value->isFloat())
+        C = llvm::ConstantFP::get(CGM.getLLVMContext(), Value->getFloat());
+    }
+  }
 
   llvm::DINode::DIFlags Flags = getAccessFlag(Var->getAccess(), RD);
   auto Align = getDeclAlignIfRequired(Var, CGM.getContext());
   llvm::DIDerivedType *GV = DBuilder.createStaticMemberType(
-      RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align);
+      RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Align);
   StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV);
-  StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl());
   return GV;
 }
 
@@ -5587,39 +5596,6 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
       TemplateParameters, Align));
 }
 
-void CGDebugInfo::EmitGlobalVariable(const VarDecl *VD) {
-  assert(VD->hasInit());
-  assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
-  if (VD->hasAttr<NoDebugAttr>())
-    return;
-
-  auto &GV = DeclCache[VD];
-  if (GV)
-    return;
-
-  auto const *InitVal = VD->evaluateValue();
-  if (!InitVal)
-    return;
-
-  llvm::DIFile *Unit = nullptr;
-  llvm::DIScope *DContext = nullptr;
-  unsigned LineNo;
-  StringRef DeclName, LinkageName;
-  QualType T;
-  llvm::MDTuple *TemplateParameters = nullptr;
-  collectVarDeclProps(VD, Unit, LineNo, T, DeclName, LinkageName,
-                      TemplateParameters, DContext);
-
-  auto Align = getDeclAlignIfRequired(VD, CGM.getContext());
-  llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
-  llvm::DIExpression *InitExpr = createConstantValueExpression(VD, *InitVal);
-
-  GV.reset(DBuilder.createGlobalVariableExpression(
-      TheCU, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
-      true, true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VD),
-      TemplateParameters, Align, Annotations));
-}
-
 void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var,
                                        const VarDecl *D) {
   assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
@@ -5890,18 +5866,6 @@ void CGDebugInfo::finalize() {
     DBuilder.replaceTemporary(std::move(FwdDecl), cast<llvm::MDNode>(Repl));
   }
 
-  for (auto const *VD : StaticDataMemberDefinitionsToEmit) {
-    assert(VD->isStaticDataMember());
-
-    if (DeclCache.contains(VD))
-      continue;
-
-    if (!VD->hasInit())
-      continue;
-
-    EmitGlobalVariable(VD);
-  }
-
   // We keep our own list of retained types, because we need to look
   // up the final type in the type cache.
   for (auto &RT : RetainedTypes)

diff  --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 3e4c133b7f2b9f1..7b60e94555d0608 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -161,9 +161,6 @@ class CGDebugInfo {
   llvm::DenseMap<const Decl *, llvm::TypedTrackingMDRef<llvm::DIDerivedType>>
       StaticDataMemberCache;
 
-  /// Keeps track of static data members for which we should emit a definition.
-  std::vector<const VarDecl *> StaticDataMemberDefinitionsToEmit;
-
   using ParamDecl2StmtTy = llvm::DenseMap<const ParmVarDecl *, const Stmt *>;
   using Param2DILocTy =
       llvm::DenseMap<const ParmVarDecl *, llvm::DILocalVariable *>;
@@ -529,9 +526,6 @@ class CGDebugInfo {
   /// Emit a constant global variable's debug info.
   void EmitGlobalVariable(const ValueDecl *VD, const APValue &Init);
 
-  /// Emit debug-info for a variable with a constant initializer.
-  void EmitGlobalVariable(const VarDecl *VD);
-
   /// Emit information about an external variable.
   void EmitExternalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
 

diff  --git a/clang/test/CodeGenCXX/debug-info-class.cpp b/clang/test/CodeGenCXX/debug-info-class.cpp
index a3111cd7c3640a0..ef84b91b67821a9 100644
--- a/clang/test/CodeGenCXX/debug-info-class.cpp
+++ b/clang/test/CodeGenCXX/debug-info-class.cpp
@@ -116,19 +116,11 @@ int main(int argc, char **argv) {
 // CHECK-SAME:                             DIFlagFwdDecl
 // CHECK-NOT:                             identifier:
 // CHECK-SAME:                            ){{$}}
-
-// CHECK:      !DIGlobalVariableExpression(var: ![[HDR_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, 52, DW_OP_stack_value))
-// CHECK:      ![[HDR_VAR]] = distinct !DIGlobalVariable(name: "HdrSize",
-// CHECK-SAME:                isLocal: true, isDefinition: true, declaration: ![[HDR_VAR_DECL:[0-9]+]])
-// CHECK:      ![[INT:[0-9]+]] = !DIBasicType(name: "int"
-// CHECK:      ![[HDR_VAR_DECL]] = !DIDerivedType(tag: DW_TAG_member, name: "HdrSize"
-
-// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A"
-
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "I"
 // CHECK-NOT:              DIFlagFwdDecl
 // CHECK-SAME:             ){{$}}
 
+// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
 // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "bar"
 // CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "baz"
@@ -194,5 +186,8 @@ int main(int argc, char **argv) {
 // CHECK: [[G_INNER_I]] = !DIDerivedType(tag: DW_TAG_member, name: "j"
 // CHECK-SAME:                           baseType: ![[INT]]
 
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A"
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "HdrSize"
+//
 // CHECK: ![[EXCEPTLOC]] = !DILocation(line: 100,
 // CHECK: ![[RETLOC]] = !DILocation(line: 99,

diff  --git a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
deleted file mode 100644
index 16872b752167ad9..000000000000000
--- a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s
-
-enum class Enum : int {
-  VAL = -1
-};
-
-struct Empty {};
-
-constexpr auto func() { return 25; }
-
-struct Foo {
-    static constexpr int cexpr_int_with_addr = func();
-    static constexpr int cexpr_int2 = func() + 1;
-    static constexpr float cexpr_float = 2.0 + 1.0;
-    static constexpr Enum cexpr_enum = Enum::VAL;
-    static constexpr Empty cexpr_struct_with_addr{};
-    static inline    Enum inline_enum = Enum::VAL;
-
-    template<typename T>
-    static constexpr T cexpr_template{};
-};
-
-int main() {
-    Foo f;
-
-    // Force global variable definitions to be emitted.
-    (void)&Foo::cexpr_int_with_addr;
-    (void)&Foo::cexpr_struct_with_addr;
-
-    return Foo::cexpr_int_with_addr + Foo::cexpr_float
-           + (int)Foo::cexpr_enum + Foo::cexpr_template<short>;
-}
-
-// CHECK:      @{{.*}}cexpr_int_with_addr{{.*}} =
-// CHECK-SAME:   !dbg ![[INT_GLOBAL:[0-9]+]]
-
-// CHECK:      @{{.*}}cexpr_struct_with_addr{{.*}} = 
-// CHECK-SAME    !dbg ![[EMPTY_GLOBAL:[0-9]+]]
-
-// CHECK:      !DIGlobalVariableExpression(var: ![[INT_VAR:[0-9]+]], expr: !DIExpression())
-// CHECK:      ![[INT_VAR]] = distinct !DIGlobalVariable(name: "cexpr_int_with_addr", linkageName:
-// CHECK-SAME:                isLocal: false, isDefinition: true, declaration: ![[INT_DECL:[0-9]+]])
-
-// CHECK:      ![[INT_DECL]] = !DIDerivedType(tag: DW_TAG_member, name: "cexpr_int_with_addr",
-// CHECK-SAME:                 flags: DIFlagStaticMember
-// CHECK-NOT:                  extraData:
-
-// CHECK:      ![[INT_DECL2:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "cexpr_int2",
-// CHECK-SAME:                         flags: DIFlagStaticMember
-// CHECK-NOT:                          extraData:
-
-// CHECK:      ![[FLOAT_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "cexpr_float",
-// CHECK-SAME:                          flags: DIFlagStaticMember
-// CHECK-NOT:                           extraData:
-
-// CHECK:      ![[ENUM_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "cexpr_enum",
-// CHECK-SAME:                         flags: DIFlagStaticMember
-// CHECK-NOT:                          extraData:
-
-// CHECK:      ![[EMPTY_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "cexpr_struct_with_addr",
-// 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:      ![[TEMPLATE_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "cexpr_template",
-// CHECK-SAME:                             flags: DIFlagStaticMember
-// CHECK-NOT:                              extraData:
-
-// CHECK:      !DIGlobalVariableExpression(var: ![[EMPTY_VAR:[0-9]+]], expr: !DIExpression())
-// CHECK:      ![[EMPTY_VAR]] = distinct !DIGlobalVariable(name: "cexpr_struct_with_addr", linkageName:
-// CHECK-SAME:                  isLocal: false, isDefinition: true, declaration: ![[EMPTY_DECL]])
-
-// CHECK:      !DIGlobalVariableExpression(var: ![[INT_VAR2:[0-9]+]], expr: !DIExpression(DW_OP_constu, 26, DW_OP_stack_value))
-// CHECK:      ![[INT_VAR2]] = distinct !DIGlobalVariable(name: "cexpr_int2", linkageName:
-// CHECK-SAME:                 isLocal: true, isDefinition: true, declaration: ![[INT_DECL2]])
-
-// CHECK:      !DIGlobalVariableExpression(var: ![[FLOAT_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, {{.*}}, DW_OP_stack_value))
-// CHECK:      ![[FLOAT_VAR]] = distinct !DIGlobalVariable(name: "cexpr_float", linkageName:
-// CHECK-SAME:                  isLocal: true, isDefinition: true, declaration: ![[FLOAT_DECL]])
-
-// CHECK:      !DIGlobalVariableExpression(var: ![[ENUM_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, {{.*}}, DW_OP_stack_value))
-// CHECK:      ![[ENUM_VAR]] = distinct !DIGlobalVariable(name: "cexpr_enum", 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", linkageName:
-// CHECK-SAME:                  isLocal: true, isDefinition: true, declaration: ![[IENUM_DECL]])
-
-// CHECK:      !DIGlobalVariableExpression(var: ![[TEMPLATE_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value))
-// CHECK:      ![[TEMPLATE_VAR]] = distinct !DIGlobalVariable(name: "cexpr_template", linkageName:
-// CHECK-SAME:                     isLocal: true, isDefinition: true, declaration: ![[TEMPLATE_DECL]], templateParams: ![[TEMPLATE_PARMS:[0-9]+]])

diff  --git a/clang/test/CodeGenCXX/debug-info-static-member.cpp b/clang/test/CodeGenCXX/debug-info-static-member.cpp
index 578995801c6400b..260a3afdd6524f3 100644
--- a/clang/test/CodeGenCXX/debug-info-static-member.cpp
+++ b/clang/test/CodeGenCXX/debug-info-static-member.cpp
@@ -63,19 +63,19 @@ int C::a = 4;
 // CHECK-NOT:                                 offset:
 // CHECK-SAME:                                flags: DIFlagStaticMember)
 //
-// CHECK:    ![[CONST_A_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "const_a"
-// CHECK-NOT:                           size:
-// CHECK-NOT:                           align:
-// CHECK-NOT:                           offset:
-// CHECK-SAME:                          flags: DIFlagStaticMember
-// CHECK-NOT:                           extraData:
-
-// CHECK:     ![[CONST_B_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "const_b"
-// CHECK-NOT:                            size:
-// CHECK-NOT:                            align:
-// CHECK-NOT:                            offset:
-// CHECK-SAME:                           flags: DIFlagProtected | DIFlagStaticMember
-// CHECK-NOT:                            extraData:
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_a"
+// CHECK-NOT:            size:
+// CHECK-NOT:            align:
+// CHECK-NOT:            offset:
+// CHECK-SAME:           flags: DIFlagStaticMember,
+// CHECK-SAME:           extraData: i1 true)
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_b"
+// CHECK-NOT:            size:
+// CHECK-NOT:            align:
+// CHECK-NOT:            offset:
+// CHECK-SAME:           flags: DIFlagProtected | DIFlagStaticMember,
+// CHECK-SAME:           extraData: float 0x{{.*}})
 
 // CHECK: ![[DECL_C:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "c"
 // CHECK-NOT:                                 size:
@@ -83,12 +83,12 @@ int C::a = 4;
 // CHECK-NOT:                                 offset:
 // CHECK-SAME:                                flags: DIFlagPublic | DIFlagStaticMember)
 //
-// CHECK:     ![[CONST_C_DECL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "const_c"
-// CHECK-NOT:                            size:
-// CHECK-NOT:                            align:
-// CHECK-NOT:                            offset:
-// CHECK-SAME:                           flags: DIFlagPublic | DIFlagStaticMember
-// CHECK-NOT:                            extraData:
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_c"
+// CHECK-NOT:            size:
+// CHECK-NOT:            align:
+// CHECK-NOT:            offset:
+// CHECK-SAME:           flags: DIFlagPublic | DIFlagStaticMember,
+// CHECK-SAME:           extraData: i32 18)
 //
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x_a"
 // CHECK-SAME:           flags: DIFlagPublic | DIFlagStaticMember)
@@ -144,7 +144,7 @@ struct V {
 // const_va is not emitted for MS targets.
 // NOT-MS: !DIDerivedType(tag: DW_TAG_member, name: "const_va",
 // NOT-MS-SAME:           line: [[@LINE-5]]
-// NOT-MS-NOT:            extraData:
+// NOT-MS-SAME:           extraData: i32 42
 const int V::const_va;
 
 namespace x {
@@ -156,15 +156,3 @@ struct y {
 };
 int y::z;
 }
-
-// CHECK:      !DIGlobalVariableExpression(var: ![[CONST_A_VAR:[0-9]+]], expr: !DIExpression(DW_OP_constu, 1, DW_OP_stack_value))
-// 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]])
-
-// 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"
-// CHECK-SAME:                    isLocal: true, isDefinition: true, declaration: ![[CONST_C_DECL]])

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4e41858674467a3..3174c18c97d888c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -31,7 +31,6 @@
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/TypeMap.h"
-#include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/Language.h"
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/Log.h"
@@ -134,54 +133,6 @@ static lldb::ModuleSP GetContainingClangModule(const DWARFDIE &die) {
   return lldb::ModuleSP();
 }
 
-std::optional<DWARFFormValue>
-DWARFASTParserClang::FindConstantOnVariableDefinition(DWARFDIE die) {
-  assert(die.Tag() == llvm::dwarf::DW_TAG_member);
-
-  auto *dwarf = die.GetDWARF();
-  if (!dwarf)
-    return {};
-
-  ConstString name{die.GetName()};
-  if (!name)
-    return {};
-
-  auto *CU = die.GetCU();
-  if (!CU)
-    return {};
-
-  DWARFASTParser *dwarf_ast = dwarf->GetDWARFParser(*CU);
-  auto parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
-
-  // Make sure we populate the GetDieToVariable cache.
-  VariableList variables;
-  dwarf->FindGlobalVariables(name, parent_decl_ctx, UINT_MAX, variables);
-
-  // The cache contains the variable definition whose DW_AT_specification
-  // points to our declaration DIE. Look up that definition using our
-  // declaration.
-  auto const &die_to_var = dwarf->GetDIEToVariable();
-  auto it = die_to_var.find(die.GetDIE());
-  if (it == die_to_var.end())
-    return {};
-
-  auto var_sp = it->getSecond();
-  assert(var_sp != nullptr);
-
-  if (!var_sp->GetLocationIsConstantValueData())
-    return {};
-
-  auto def = dwarf->GetDIE(var_sp->GetID());
-  auto def_attrs = def.GetAttributes();
-  DWARFFormValue form_value;
-  if (!def_attrs.ExtractFormValueAtIndex(
-          def_attrs.FindAttributeIndex(llvm::dwarf::DW_AT_const_value),
-          form_value))
-    return {};
-
-  return form_value;
-}
-
 TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
                                                      const DWARFDIE &die,
                                                      Log *log) {
@@ -2955,21 +2906,9 @@ void DWARFASTParserClang::ParseSingleMember(
 
       bool unused;
       // TODO: Support float/double static members as well.
-      if (!ct.IsIntegerOrEnumerationType(unused))
+      if (!attrs.const_value_form || !ct.IsIntegerOrEnumerationType(unused))
         return;
 
-      // Newer versions of Clang don't emit the DW_AT_const_value
-      // on the declaration of an inline static data member. Instead
-      // it's attached to the definition DIE. If that's the case,
-      // try and fetch it.
-      if (!attrs.const_value_form) {
-        auto maybe_form_value = FindConstantOnVariableDefinition(die);
-        if (!maybe_form_value)
-          return;
-
-        attrs.const_value_form = *maybe_form_value;
-      }
-
       llvm::Expected<llvm::APInt> const_value_or_err =
           ExtractIntFromFormValue(ct, *attrs.const_value_form);
       if (!const_value_or_err) {

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 21fd6f9d7980efc..c381c58fba74263 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -373,17 +373,6 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
                        lldb_private::CompilerType &class_clang_type,
                        const lldb::AccessType default_accesibility,
                        lldb_private::ClangASTImporter::LayoutInfo &layout_info);
-
-  /// Tries to find the definition DW_TAG_variable DIE of the the specified
-  /// DW_TAG_member 'die'. If such definition exists, returns the
-  /// DW_AT_const_value of that definition if available. Returns std::nullopt
-  /// otherwise.
-  ///
-  /// In newer versions of clang, DW_AT_const_value attributes are not attached
-  /// to the declaration of a inline static data-member anymore, but rather on
-  /// its definition. This function is used to locate said constant.
-  std::optional<lldb_private::plugin::dwarf::DWARFFormValue>
-  FindConstantOnVariableDefinition(lldb_private::plugin::dwarf::DWARFDIE die);
 };
 
 /// Parsed form of all attributes that are relevant for type reconstruction.

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index e6efbba7e24990a..28430ccb87924b5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -343,11 +343,6 @@ class SymbolFileDWARF : public SymbolFileCommon {
     return m_forward_decl_compiler_type_to_die;
   }
 
-  typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP>
-      DIEToVariableSP;
-
-  virtual DIEToVariableSP &GetDIEToVariable() { return m_die_to_variable_sp; }
-
   virtual UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap();
 
   bool ClassOrStructIsVirtual(const DWARFDIE &die);
@@ -367,6 +362,9 @@ class SymbolFileDWARF : public SymbolFileCommon {
   Type *ResolveTypeUID(const DIERef &die_ref);
 
 protected:
+  typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP>
+      DIEToVariableSP;
+
   SymbolFileDWARF(const SymbolFileDWARF &) = delete;
   const SymbolFileDWARF &operator=(const SymbolFileDWARF &) = delete;
 
@@ -490,6 +488,8 @@ class SymbolFileDWARF : public SymbolFileCommon {
 
   void UpdateExternalModuleListIfNeeded();
 
+  virtual DIEToVariableSP &GetDIEToVariable() { return m_die_to_variable_sp; }
+
   void BuildCuTranslationTable();
   std::optional<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx);
 

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index ca698a84a9146da..223af281cd57db7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -142,10 +142,3 @@ SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
     return DebugInfo().GetDIE(die_ref);
   return GetBaseSymbolFile().GetDIE(die_ref);
 }
-
-void SymbolFileDWARFDwo::FindGlobalVariables(
-    ConstString name, const CompilerDeclContext &parent_decl_ctx,
-    uint32_t max_matches, VariableList &variables) {
-  GetBaseSymbolFile().FindGlobalVariables(name, parent_decl_ctx, max_matches,
-                                          variables);
-}

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 9f5950e51b0c180..fa8376507d6a89b 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -51,11 +51,6 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {
                               lldb::offset_t &offset,
                               std::vector<Value> &stack) const override;
 
-  void FindGlobalVariables(ConstString name,
-                           const CompilerDeclContext &parent_decl_ctx,
-                           uint32_t max_matches,
-                           VariableList &variables) override;
-
 protected:
   DIEToTypePtr &GetDIEToType() override;
 

diff  --git a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py b/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
index 8679ac75acc78b7..530191e8a37ba1b 100644
--- a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
+++ b/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
@@ -102,10 +102,9 @@ def test(self):
         # it does not crash.
         self.expect("image lookup -t A")
 
-    # For debug-info produced by older versions of clang, dsymutil strips the
-    # debug info for classes that only have const static data members without
-    # definitions.
-    @expectedFailureAll(compiler=["clang"], compiler_version=["<", "18.0"])
+    # dsymutil strips the debug info for classes that only have const static
+    # data members without a definition namespace scope.
+    @expectedFailureAll(debug_info=["dsym"])
     def test_class_with_only_const_static(self):
         self.build()
         lldbutil.run_to_source_breakpoint(
@@ -114,39 +113,6 @@ def test_class_with_only_const_static(self):
 
         self.expect_expr("ClassWithOnlyConstStatic::member", result_value="3")
 
-    def check_global_var(self, name: str, expect_type, expect_val):
-        var_list = self.target().FindGlobalVariables(name, lldb.UINT32_MAX)
-        self.assertEqual(len(var_list), 1)
-        varobj = var_list[0]
-        self.assertEqual(varobj.type.name, expect_type)
-        self.assertEqual(varobj.value, expect_val)
-
-    # For debug-info produced by older versions of clang, inline static data members
-    # wouldn't get indexed into the Names accelerator table preventing LLDB from finding
-    # them.
-    @expectedFailureAll(compiler=["clang"], compiler_version=["<", "18.0"])
-    @expectedFailureAll(debug_info=no_match(["dsym"]), oslist=no_match(["linux", "windows"]))
-    def test_inline_static_members(self):
-        self.build()
-        lldbutil.run_to_source_breakpoint(
-            self, "// break here", lldb.SBFileSpec("main.cpp")
-        )
-
-        self.check_global_var("A::int_val", "const int", "1")
-        self.check_global_var("A::int_val_with_address", "const int", "2")
-        self.check_global_var("A::bool_val", "const bool", "true")
-        self.check_global_var("A::enum_val", "Enum", "enum_case2")
-        self.check_global_var("A::enum_bool_val", "EnumBool", "enum_bool_case1")
-        self.check_global_var("A::scoped_enum_val", "ScopedEnum", "scoped_enum_case2")
-
-        self.check_global_var("ClassWithOnlyConstStatic::member", "const int", "3")
-
-        self.check_global_var("ClassWithConstexprs::member", "const int", "2")
-        self.check_global_var("ClassWithConstexprs::enum_val", "Enum", "enum_case2")
-        self.check_global_var(
-            "ClassWithConstexprs::scoped_enum_val", "ScopedEnum", "scoped_enum_case2"
-        )
-
     # With older versions of Clang, LLDB fails to evaluate classes with only
     # constexpr members when dsymutil is enabled
     @expectedFailureAll(
@@ -172,24 +138,3 @@ def test_class_with_only_constexpr_static(self):
         self.expect_expr(
             "ClassWithEnumAlias::enum_alias_alias", result_value="scoped_enum_case1"
         )
-
-    def test_shadowed_static_inline_members(self):
-        """Tests that the expression evaluator and SBAPI can both
-        correctly determine the requested inline static variable
-        in the presence of multiple variables of the same name."""
-
-        self.build()
-        lldbutil.run_to_name_breakpoint(self, "bar")
-
-        self.check_global_var("ns::Foo::mem", "const int", "10")
-
-        self.expect_expr("mem", result_value="10")
-        self.expect_expr("Foo::mem", result_value="10")
-        self.expect_expr("ns::Foo::mem", result_value="10")
-        self.expect_expr("::Foo::mem", result_value="-29")
-
-    @expectedFailureAll(bugnumber="target var doesn't honour global namespace")
-    def test_shadowed_static_inline_members_xfail(self):
-        self.build()
-        lldbutil.run_to_name_breakpoint(self, "bar")
-        self.check_global_var("::Foo::mem", "const int", "-29")

diff  --git a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp b/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
index fb0b49e2d7aad7a..4275f471df6aed1 100644
--- a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
+++ b/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
@@ -89,25 +89,6 @@ struct ClassWithEnumAlias {
       ScopedEnum::scoped_enum_case1;
 };
 
-namespace ns {
-struct Foo {
-  constexpr static int mem = 10;
-
-  void bar() { return; }
-};
-} // namespace ns
-
-struct Foo {
-  constexpr static int mem = -29;
-};
-
-int func() {
-  Foo f1;
-  ns::Foo f2;
-  f2.bar();
-  return ns::Foo::mem + Foo::mem;
-}
-
 int main() {
   A a;
 
@@ -143,7 +124,6 @@ int main() {
 
   auto enum_alias_val = ClassWithEnumAlias::enum_alias;
   auto enum_alias_alias_val = ClassWithEnumAlias::enum_alias_alias;
-  auto ret = func();
 
   return 0; // break here
 }

diff  --git a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
index d2a21ad3cd1d44f..11d9bf18db7a6e1 100644
--- a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
+++ b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
@@ -87,11 +87,10 @@ def verify_values(self, verify_dict, actual, varref_dict=None, expression=None):
     def verify_variables(self, verify_dict, variables, varref_dict=None):
         for variable in variables:
             name = variable["name"]
-            if not name.startswith("std::"):
-                self.assertIn(
-                    name, verify_dict, 'variable "%s" in verify dictionary' % (name)
-                )
-                self.verify_values(verify_dict[name], variable, varref_dict)
+            self.assertIn(
+                name, verify_dict, 'variable "%s" in verify dictionary' % (name)
+            )
+            self.verify_values(verify_dict[name], variable, varref_dict)
 
     def darwin_dwarf_missing_obj(self, initCommands):
         self.build(debug_info="dwarf")


        


More information about the cfe-commits mailing list