[clang] 7c3707a - Reland "clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (#70639)"
Author: Michael Buch Date: 2023-11-07T04:53:54Z New Revision: 7c3707aea8a6f1fc245ad2862982b8a51b6c0fea URL: https://github.com/llvm/llvm-project/commit/7c3707aea8a6f1fc245ad2862982b8a51b6c0fea DIFF: https://github.com/llvm/llvm-project/commit/7c3707aea8a6f1fc245ad2862982b8a51b6c0fea.diff LOG: Reland "clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (#70639)" 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’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: ``` 0x007b: DW_TAG_structure_type DW_AT_calling_convention(DW_CC_pass_by_value) DW_AT_name ("Foo") ... 0x008d: DW_TAG_member DW_AT_name("i") DW_AT_type(0x0062 "const int") DW_AT_external(true) DW_AT_declaration (true) DW_AT_const_value (4) Newly added v 0x009a: DW_TAG_variable DW_AT_specification (0x008d "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. Added: clang/test/CodeGenCXX/debug-info-static-inline-member.cpp 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/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py Removed: diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 84a166d3ac3659c..410c8f522b1017f 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1677,22 +1677,13 @@ 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, C, Align); + RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5596,6 +5587,39 @@ 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()) +return; + + auto &GV = DeclCache[VD]; + if (GV) +return; + + auto const *InitVal = VD->evaluateValue(); + if (!InitVal) +return; + + llvm::DIFile *Unit = nullptr;
[lldb] [clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: > This causes Clang to assert: > > ``` > llvm/lib/IR/Metadata.cpp:689: > void llvm::MDNode::resolve(): Assertion `isUniqued() && "Expected this > to be uniqued"' failed. > ``` > > See https://bugs.chromium.org/p/chromium/issues/detail?id=1500262#c1 for a > reproducer. > > I'll revert to green. Thanks for the repro. Reduced it to: ``` struct Foo; template using Int = int; class Bar { template static const bool Constant = false; Int> Val; Bar(); }; Bar::Bar() {} ``` when compiling with `-debug-info-kind=limited`. The issue was that `EmitGlobalVariable` can cause creation of `DINodes`, which, if using limited debug-info, will be temporary. But the emission of the global variables is done *after* we've uniqued the temporaries. So the fix is really to just do the `EmitGlobalVariable` at the beginning of `CGDebugInfo::finalize`. Will submit a new PR with that change and a new test-case for this https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/71780 This patch relands https://github.com/llvm/llvm-project/pull/70639 It was reverted because under certain conditions we triggered an assertion in `DIBuilder`. Specifically, in the original patch we called `EmitGlobalVariable` at the end of `CGDebugInfo::finalize`, after all the temporary `DIType`s have been uniqued. With limited debug-info such temporary nodes would be created more frequently, leaving us with non-uniqued nodes by the time we got to `DIBuilder::finalize`; this violated its pre-condition and caused assertions to trigger. To fix this, the latest iteration of the patch moves `EmitGlobalVariable` to the beginning of `CGDebugInfo::finalize`. Now, when we create a temporary `DIType` node as a result of emitting a variable definition, it will get uniqued in time. A test-case was added for this scenario. Original commit message: """ 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’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: ``` 0x007b: DW_TAG_structure_type DW_AT_calling_convention(DW_CC_pass_by_value) DW_AT_name ("Foo") ... 0x008d: DW_TAG_member DW_AT_name("i") DW_AT_type(0x0062 "const int") DW_AT_external(true) DW_AT_declaration (true) DW_AT_const_value (4) Newly added v 0x009a: DW_TAG_variable DW_AT_specification (0x008d "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. """ Dependent changes: * https://github.com/llvm/llvm-project/pull/71004 * https://github.com/llvm/llvm-project/pull/70641 >From e5bc858c35b479d29174c9945c6c67f4d2dc085b Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 9 Nov 2023 01:13:21 + Subject: [PATCH] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" --- clang/lib/CodeGen/CGDebugInfo.cpp | 58 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 +++-- .../CodeGenCXX/debug-info-static-member.cpp | 52 ++--- .../TestConstStaticIntegralMember.py | 7 ++- .../lldb-dap/variables/TestDAP_variables.py | 9 +-- 6 files changed, 103 insertions(+), 42 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 84a166d3ac3659c..245f7516640d098 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1677,22 +1677,13 @@ 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 =
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/71780 >From e5bc858c35b479d29174c9945c6c67f4d2dc085b Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 9 Nov 2023 01:13:21 + Subject: [PATCH 1/2] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" --- clang/lib/CodeGen/CGDebugInfo.cpp | 58 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 +++-- .../CodeGenCXX/debug-info-static-member.cpp | 52 ++--- .../TestConstStaticIntegralMember.py | 7 ++- .../lldb-dap/variables/TestDAP_variables.py | 9 +-- 6 files changed, 103 insertions(+), 42 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 84a166d3ac3659c..245f7516640d098 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1677,22 +1677,13 @@ 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, C, Align); + RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5596,6 +5587,39 @@ 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()) +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()); @@ -5800,6 +5824,18 @@ void CGDebugInfo::setDwoId(uint64_t Signature) { } void CGDebugInfo::finalize() { + for (auto const *VD : StaticDataMemberDefinitionsToEmit) { +assert(VD->isStaticDataMember()); + +if (DeclCache.contains(VD)) + continue; + +if (!VD->hasInit()) + continue; + +EmitGlobalVariable(VD); + } + // Creating types might create further types - invalidating the current // element and the size(), so don't cache/reference them. for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) { diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 7b60e94555d0608..3e4c133b7f2b9f1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -161,6 +161,9 @@ class CGDebugInfo { llvm::DenseMap> StaticDataMemberCache; + /// Keeps track of static data members for which we should emit a definition. + std::vector StaticDataMemberDefinitionsToEmit; + using ParamDecl2StmtTy = llvm::DenseMap; using Param2DILocTy = llvm::DenseMap; @@ -526,6 +529,9 @@ 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/
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/71780 >From e5bc858c35b479d29174c9945c6c67f4d2dc085b Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 9 Nov 2023 01:13:21 + Subject: [PATCH 1/3] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" --- clang/lib/CodeGen/CGDebugInfo.cpp | 58 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 +++-- .../CodeGenCXX/debug-info-static-member.cpp | 52 ++--- .../TestConstStaticIntegralMember.py | 7 ++- .../lldb-dap/variables/TestDAP_variables.py | 9 +-- 6 files changed, 103 insertions(+), 42 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 84a166d3ac3659c..245f7516640d098 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1677,22 +1677,13 @@ 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, C, Align); + RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5596,6 +5587,39 @@ 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()) +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()); @@ -5800,6 +5824,18 @@ void CGDebugInfo::setDwoId(uint64_t Signature) { } void CGDebugInfo::finalize() { + for (auto const *VD : StaticDataMemberDefinitionsToEmit) { +assert(VD->isStaticDataMember()); + +if (DeclCache.contains(VD)) + continue; + +if (!VD->hasInit()) + continue; + +EmitGlobalVariable(VD); + } + // Creating types might create further types - invalidating the current // element and the size(), so don't cache/reference them. for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) { diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 7b60e94555d0608..3e4c133b7f2b9f1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -161,6 +161,9 @@ class CGDebugInfo { llvm::DenseMap> StaticDataMemberCache; + /// Keeps track of static data members for which we should emit a definition. + std::vector StaticDataMemberDefinitionsToEmit; + using ParamDecl2StmtTy = llvm::DenseMap; using Param2DILocTy = llvm::DenseMap; @@ -526,6 +529,9 @@ 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/
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/71780 >From e5bc858c35b479d29174c9945c6c67f4d2dc085b Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 9 Nov 2023 01:13:21 + Subject: [PATCH 1/4] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" --- clang/lib/CodeGen/CGDebugInfo.cpp | 58 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 +++-- .../CodeGenCXX/debug-info-static-member.cpp | 52 ++--- .../TestConstStaticIntegralMember.py | 7 ++- .../lldb-dap/variables/TestDAP_variables.py | 9 +-- 6 files changed, 103 insertions(+), 42 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 84a166d3ac3659c..245f7516640d098 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1677,22 +1677,13 @@ 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, C, Align); + RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5596,6 +5587,39 @@ 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()) +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()); @@ -5800,6 +5824,18 @@ void CGDebugInfo::setDwoId(uint64_t Signature) { } void CGDebugInfo::finalize() { + for (auto const *VD : StaticDataMemberDefinitionsToEmit) { +assert(VD->isStaticDataMember()); + +if (DeclCache.contains(VD)) + continue; + +if (!VD->hasInit()) + continue; + +EmitGlobalVariable(VD); + } + // Creating types might create further types - invalidating the current // element and the size(), so don't cache/reference them. for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) { diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 7b60e94555d0608..3e4c133b7f2b9f1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -161,6 +161,9 @@ class CGDebugInfo { llvm::DenseMap> StaticDataMemberCache; + /// Keeps track of static data members for which we should emit a definition. + std::vector StaticDataMemberDefinitionsToEmit; + using ParamDecl2StmtTy = llvm::DenseMap; using Param2DILocTy = llvm::DenseMap; @@ -526,6 +529,9 @@ 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/
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
@@ -5596,6 +5587,42 @@ 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()) +return; + + auto &GV = DeclCache[VD]; Michael137 wrote: Good catch, I'll err on the side of caution and not do that https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
@@ -5800,6 +5827,18 @@ void CGDebugInfo::setDwoId(uint64_t Signature) { } void CGDebugInfo::finalize() { + for (auto const *VD : StaticDataMemberDefinitionsToEmit) { +assert(VD->isStaticDataMember()); + +if (DeclCache.contains(VD)) + continue; + +if (!VD->hasInit()) Michael137 wrote: I'll update the `EmitGlobalVariable` docs to clarify that we need an initialiser, otherwise behaviour is undefined https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/71780 >From e5bc858c35b479d29174c9945c6c67f4d2dc085b Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 9 Nov 2023 01:13:21 + Subject: [PATCH 1/4] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" --- clang/lib/CodeGen/CGDebugInfo.cpp | 58 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 +++-- .../CodeGenCXX/debug-info-static-member.cpp | 52 ++--- .../TestConstStaticIntegralMember.py | 7 ++- .../lldb-dap/variables/TestDAP_variables.py | 9 +-- 6 files changed, 103 insertions(+), 42 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 84a166d3ac3659c..245f7516640d098 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1677,22 +1677,13 @@ 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, C, Align); + RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5596,6 +5587,39 @@ 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()) +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()); @@ -5800,6 +5824,18 @@ void CGDebugInfo::setDwoId(uint64_t Signature) { } void CGDebugInfo::finalize() { + for (auto const *VD : StaticDataMemberDefinitionsToEmit) { +assert(VD->isStaticDataMember()); + +if (DeclCache.contains(VD)) + continue; + +if (!VD->hasInit()) + continue; + +EmitGlobalVariable(VD); + } + // Creating types might create further types - invalidating the current // element and the size(), so don't cache/reference them. for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) { diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 7b60e94555d0608..3e4c133b7f2b9f1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -161,6 +161,9 @@ class CGDebugInfo { llvm::DenseMap> StaticDataMemberCache; + /// Keeps track of static data members for which we should emit a definition. + std::vector StaticDataMemberDefinitionsToEmit; + using ParamDecl2StmtTy = llvm::DenseMap; using Param2DILocTy = llvm::DenseMap; @@ -526,6 +529,9 @@ 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/
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/71780 >From e5bc858c35b479d29174c9945c6c67f4d2dc085b Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 9 Nov 2023 01:13:21 + Subject: [PATCH 1/5] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" --- clang/lib/CodeGen/CGDebugInfo.cpp | 58 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 +++-- .../CodeGenCXX/debug-info-static-member.cpp | 52 ++--- .../TestConstStaticIntegralMember.py | 7 ++- .../lldb-dap/variables/TestDAP_variables.py | 9 +-- 6 files changed, 103 insertions(+), 42 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 84a166d3ac3659c..245f7516640d098 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1677,22 +1677,13 @@ 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, C, Align); + RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5596,6 +5587,39 @@ 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()) +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()); @@ -5800,6 +5824,18 @@ void CGDebugInfo::setDwoId(uint64_t Signature) { } void CGDebugInfo::finalize() { + for (auto const *VD : StaticDataMemberDefinitionsToEmit) { +assert(VD->isStaticDataMember()); + +if (DeclCache.contains(VD)) + continue; + +if (!VD->hasInit()) + continue; + +EmitGlobalVariable(VD); + } + // Creating types might create further types - invalidating the current // element and the size(), so don't cache/reference them. for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) { diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 7b60e94555d0608..3e4c133b7f2b9f1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -161,6 +161,9 @@ class CGDebugInfo { llvm::DenseMap> StaticDataMemberCache; + /// Keeps track of static data members for which we should emit a definition. + std::vector StaticDataMemberDefinitionsToEmit; + using ParamDecl2StmtTy = llvm::DenseMap; using Param2DILocTy = llvm::DenseMap; @@ -526,6 +529,9 @@ 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/
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/71780 >From e5bc858c35b479d29174c9945c6c67f4d2dc085b Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 9 Nov 2023 01:13:21 + Subject: [PATCH 1/6] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" --- clang/lib/CodeGen/CGDebugInfo.cpp | 58 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 +++-- .../CodeGenCXX/debug-info-static-member.cpp | 52 ++--- .../TestConstStaticIntegralMember.py | 7 ++- .../lldb-dap/variables/TestDAP_variables.py | 9 +-- 6 files changed, 103 insertions(+), 42 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 84a166d3ac3659c..245f7516640d098 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1677,22 +1677,13 @@ 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, C, Align); + RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5596,6 +5587,39 @@ 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()) +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()); @@ -5800,6 +5824,18 @@ void CGDebugInfo::setDwoId(uint64_t Signature) { } void CGDebugInfo::finalize() { + for (auto const *VD : StaticDataMemberDefinitionsToEmit) { +assert(VD->isStaticDataMember()); + +if (DeclCache.contains(VD)) + continue; + +if (!VD->hasInit()) + continue; + +EmitGlobalVariable(VD); + } + // Creating types might create further types - invalidating the current // element and the size(), so don't cache/reference them. for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) { diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 7b60e94555d0608..3e4c133b7f2b9f1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -161,6 +161,9 @@ class CGDebugInfo { llvm::DenseMap> StaticDataMemberCache; + /// Keeps track of static data members for which we should emit a definition. + std::vector StaticDataMemberDefinitionsToEmit; + using ParamDecl2StmtTy = llvm::DenseMap; using Param2DILocTy = llvm::DenseMap; @@ -526,6 +529,9 @@ 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/
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72234)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/72234 This patch adds the LLVM-side infrastructure to implement DWARFv5 issue 161118.1: "DW_TAG for C++ static data members". The clang-side of this patch will simply construct the DIDerivedType with a different DW_TAG. >From af4a49c1f468705f2f7226e4244936363c41155e Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 6 Nov 2023 11:52:47 + Subject: [PATCH] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable This patch adds the LLVM-side infrastructure to implement DWARFv5 issue 161118.1: "DW_TAG for C++ static data members". The clang-side of this patch will simply construct the DIDerivedType with a different DW_TAG. --- clang/lib/CodeGen/CGDebugInfo.cpp | 3 +- llvm/include/llvm-c/DebugInfo.h | 6 +- llvm/include/llvm/IR/DIBuilder.h | 3 +- llvm/lib/IR/DIBuilder.cpp | 9 +- llvm/lib/IR/DebugInfo.cpp | 12 +- llvm/lib/IR/DebugInfoMetadata.cpp | 4 +- llvm/lib/IR/Verifier.cpp | 1 + .../dwarf5-debug-info-static-member.ll| 109 ++ 8 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 llvm/test/DebugInfo/Generic/dwarf5-debug-info-static-member.ll diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 04ca02cfe858579..b8acef67dee4c7c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1681,7 +1681,8 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, 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, /* Val */ nullptr, + DW_TAG_member, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index 5924294708cc354..61659d514b520e5 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -785,14 +785,14 @@ LLVMMetadataRef LLVMDIBuilderCreateMemberType( * \param Type Type of the static member. * \param FlagsFlags to encode member attribute, e.g. private. * \param ConstantVal Const initializer of the member. + * \param Tag DWARF tag of the static member. * \param AlignInBits Member alignment. */ -LLVMMetadataRef -LLVMDIBuilderCreateStaticMemberType( +LLVMMetadataRef LLVMDIBuilderCreateStaticMemberType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal, -uint32_t AlignInBits); +unsigned Tag, uint32_t AlignInBits); /** * Create debugging information entry for a pointer to member. diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index ecd6dd7b0a4f822..2be133e85e8c1e4 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -376,11 +376,12 @@ namespace llvm { /// \param Ty Type of the static member. /// \param Flags Flags to encode member attribute, e.g. private. /// \param ValConst initializer of the member. +/// \param TagDWARF tag of the static member. /// \param AlignInBits Member alignment. DIDerivedType *createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, DINode::DIFlags Flags, - Constant *Val, + Constant *Val, unsigned Tag, uint32_t AlignInBits = 0); /// Create debugging information entry for Objective-C diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 1ce8c17f8a880f6..58a7e07d9b58d86 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -405,12 +405,11 @@ DIDerivedType * DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, DIType *Ty, DINode::DIFlags Flags, llvm::Constant *Val, - uint32_t AlignInBits) { + unsigned Tag, uint32_t AlignInBits) { Flags |= DINode::FlagStaticMember; - return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, -LineNumber, getNonCompileUnitScope(Scope), Ty
[clang] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72235)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/72235 This patch implements the DWARFv5 issue 161118.1: "DW_TAG for C++ static data members". This will simplify LLDB's handling of static data members greatly in the long term since we no longer need to differentiate non-static from static data member declarations using non-portable heuristics. >From c0db61f318f50a1cf219c69af9c6b624b05c9da1 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 13 Nov 2023 09:48:39 + Subject: [PATCH] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable This patch implements the DWARFv5 issue 161118.1: "DW_TAG for C++ static data members". This will simplify LLDB's handling of static data members greatly in the long term since we no longer need to differentiate non-static from static data member declarations using non-portable heuristics. --- clang/lib/CodeGen/CGDebugInfo.cpp | 8 +++-- .../debug-info-static-inline-member.cpp | 4 +-- .../CodeGenCXX/debug-info-static-member.cpp | 36 --- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 04ca02cfe858579..f3de91d4a39ebee 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1679,9 +1679,13 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, StringRef VName = Var->getName(); llvm::DINode::DIFlags Flags = getAccessFlag(Var->getAccess(), RD); + auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5 + ? llvm::dwarf::DW_TAG_variable + : llvm::dwarf::DW_TAG_member; auto Align = getDeclAlignIfRequired(Var, CGM.getContext()); - llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( - RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); + llvm::DIDerivedType *GV = + DBuilder.createStaticMemberType(RecordTy, VName, VUnit, LineNumber, VTy, + Flags, /* Val */ nullptr, Tag, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; diff --git a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp index bfb7ad6b80fabf3..f2d4d9408a8297a 100644 --- a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp +++ b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp @@ -1,5 +1,5 @@ -// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -debug-info-kind=standalone %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s -// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -debug-info-kind=limited %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s +// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -gdwarf-4 -debug-info-kind=standalone %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s +// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -gdwarf-4 -debug-info-kind=limited %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s enum class Enum : int { VAL = -1 diff --git a/clang/test/CodeGenCXX/debug-info-static-member.cpp b/clang/test/CodeGenCXX/debug-info-static-member.cpp index 578995801c6400b..a2d25e98ed1cb62 100644 --- a/clang/test/CodeGenCXX/debug-info-static-member.cpp +++ b/clang/test/CodeGenCXX/debug-info-static-member.cpp @@ -1,7 +1,8 @@ -// RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s -// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++98 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s -// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s -// RUN: %clangxx -target x86_64-windows-msvc -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s +// 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 -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 // PR14471 // CHECK: @{{.*}}a{{.*}} = dso_local global i32 4, align 4, !dbg [[A:![0-9]+]] @@ -39,17 +40,20 @@ class C // // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}) // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct" -// CHE
[clang] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72235)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/72235 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72235)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/72235 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72235)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/72235 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72234)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/72234 >From af4a49c1f468705f2f7226e4244936363c41155e Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 6 Nov 2023 11:52:47 + Subject: [PATCH 1/2] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable This patch adds the LLVM-side infrastructure to implement DWARFv5 issue 161118.1: "DW_TAG for C++ static data members". The clang-side of this patch will simply construct the DIDerivedType with a different DW_TAG. --- clang/lib/CodeGen/CGDebugInfo.cpp | 3 +- llvm/include/llvm-c/DebugInfo.h | 6 +- llvm/include/llvm/IR/DIBuilder.h | 3 +- llvm/lib/IR/DIBuilder.cpp | 9 +- llvm/lib/IR/DebugInfo.cpp | 12 +- llvm/lib/IR/DebugInfoMetadata.cpp | 4 +- llvm/lib/IR/Verifier.cpp | 1 + .../dwarf5-debug-info-static-member.ll| 109 ++ 8 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 llvm/test/DebugInfo/Generic/dwarf5-debug-info-static-member.ll diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 04ca02cfe858579..b8acef67dee4c7c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1681,7 +1681,8 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, 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, /* Val */ nullptr, + DW_TAG_member, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index 5924294708cc354..61659d514b520e5 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -785,14 +785,14 @@ LLVMMetadataRef LLVMDIBuilderCreateMemberType( * \param Type Type of the static member. * \param FlagsFlags to encode member attribute, e.g. private. * \param ConstantVal Const initializer of the member. + * \param Tag DWARF tag of the static member. * \param AlignInBits Member alignment. */ -LLVMMetadataRef -LLVMDIBuilderCreateStaticMemberType( +LLVMMetadataRef LLVMDIBuilderCreateStaticMemberType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal, -uint32_t AlignInBits); +unsigned Tag, uint32_t AlignInBits); /** * Create debugging information entry for a pointer to member. diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index ecd6dd7b0a4f822..2be133e85e8c1e4 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -376,11 +376,12 @@ namespace llvm { /// \param Ty Type of the static member. /// \param Flags Flags to encode member attribute, e.g. private. /// \param ValConst initializer of the member. +/// \param TagDWARF tag of the static member. /// \param AlignInBits Member alignment. DIDerivedType *createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, DINode::DIFlags Flags, - Constant *Val, + Constant *Val, unsigned Tag, uint32_t AlignInBits = 0); /// Create debugging information entry for Objective-C diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 1ce8c17f8a880f6..58a7e07d9b58d86 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -405,12 +405,11 @@ DIDerivedType * DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, DIType *Ty, DINode::DIFlags Flags, llvm::Constant *Val, - uint32_t AlignInBits) { + unsigned Tag, uint32_t AlignInBits) { Flags |= DINode::FlagStaticMember; - return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, -LineNumber, getNonCompileUnitScope(Scope), Ty, 0, -AlignInBits, 0, std::nullopt, Flags, -getConstantOrNull(Val)); + return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber, +
[clang] [lldb] [clang][DebugInfo] Revert "emit variable definitions for constant-initialized static data-members" (PR #74580)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/74580 This commit reverts the changes in https://github.com/llvm/llvm-project/pull/71780 and all of its follow-up patches. We got reports of the `.debug_names/.debug_gnu_pubnames/gdb_index/etc.` sections growing by a non-trivial amount for some large projects. While GCC does index definitions for static data member constants, they do so *only* for explicitly `constexpr` members. We were indexing *all* constant-initialized const-static members, which is likely where the significant size difference comes from. However, only emitting explicitly `constexpr` variables into the index doesn't seem like a good way forward, since from clang's perspective `const`-static integrals are `constexpr` too, and that shouldn't be any different in the debug-info component. Also, as new code moves to `constexpr` instead of `const` static for constants, such solution would just delay the growth of the Names index. To prevent the size regression we revert to not emitting definitions for static data-members that have no location. To support access to such constants from LLDB we'll most likely have to have to make LLDB find the constants by looking at the containing class first. >From fe9624fdf898a2a629bb34f070d0e084f6dc0aa9 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Tue, 5 Dec 2023 14:52:00 + Subject: [PATCH] [clang][DebugInfo] Revert "emit variable definitions for constant-initialized static data-members" This commit reverts the changes in https://github.com/llvm/llvm-project/pull/71780 and all of its follow-up patches. We got reports of the `.debug_names/.debug_gnu_pubnames/gdb_index/etc.` sections growing by a non-trivial amount for some large projects. While GCC does index definitions for static data member constants, they do so *only* for explicitly `constexpr` members. We were indexing *all* constant-initialized const-static members, which is likely where the significant size difference comes from. However, only emitting explicitly `constexpr` variables into the index doesn't seem like a good way forward, since from clang's perspective `const`-static integrals are `constexpr` too, and that shouldn't be any different in the debug-info component. Also, as new code moves to `constexpr` instead of `const` static for constants, such solution would just delay the growth of the Names index. To prevent the size regression we revert to not emitting definitions for static data-members that have no location. To support access to such constants from LLDB we'll most likely have to have to make LLDB find the constants by looking at the containing class first. --- clang/lib/CodeGen/CGDebugInfo.cpp | 73 clang/lib/CodeGen/CGDebugInfo.h | 6 - clang/test/CodeGenCXX/debug-info-class.cpp| 12 +- .../debug-info-static-inline-member.cpp | 104 -- .../CodeGenCXX/debug-info-static-member.cpp | 20 +--- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 64 +-- .../SymbolFile/DWARF/DWARFASTParserClang.h| 11 -- 7 files changed, 10 insertions(+), 280 deletions(-) delete mode 100644 clang/test/CodeGenCXX/debug-info-static-inline-member.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 602e325e560f9..7cf661994a29c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -69,29 +69,6 @@ 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), @@ -1724,7 +1701,6 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Tag, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); - StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5628,41 +5604,6 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const AP
[clang] [lldb] [clang][DebugInfo] Revert "emit definitions for constant-initialized static data-members" (PR #74580)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/74580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] [clang][DebugInfo] Revert "emit definitions for constant-initialized static data-members" (PR #74580)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/74580 >From fe9624fdf898a2a629bb34f070d0e084f6dc0aa9 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Tue, 5 Dec 2023 14:52:00 + Subject: [PATCH 1/2] [clang][DebugInfo] Revert "emit variable definitions for constant-initialized static data-members" This commit reverts the changes in https://github.com/llvm/llvm-project/pull/71780 and all of its follow-up patches. We got reports of the `.debug_names/.debug_gnu_pubnames/gdb_index/etc.` sections growing by a non-trivial amount for some large projects. While GCC does index definitions for static data member constants, they do so *only* for explicitly `constexpr` members. We were indexing *all* constant-initialized const-static members, which is likely where the significant size difference comes from. However, only emitting explicitly `constexpr` variables into the index doesn't seem like a good way forward, since from clang's perspective `const`-static integrals are `constexpr` too, and that shouldn't be any different in the debug-info component. Also, as new code moves to `constexpr` instead of `const` static for constants, such solution would just delay the growth of the Names index. To prevent the size regression we revert to not emitting definitions for static data-members that have no location. To support access to such constants from LLDB we'll most likely have to have to make LLDB find the constants by looking at the containing class first. --- clang/lib/CodeGen/CGDebugInfo.cpp | 73 clang/lib/CodeGen/CGDebugInfo.h | 6 - clang/test/CodeGenCXX/debug-info-class.cpp| 12 +- .../debug-info-static-inline-member.cpp | 104 -- .../CodeGenCXX/debug-info-static-member.cpp | 20 +--- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 64 +-- .../SymbolFile/DWARF/DWARFASTParserClang.h| 11 -- 7 files changed, 10 insertions(+), 280 deletions(-) delete mode 100644 clang/test/CodeGenCXX/debug-info-static-inline-member.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 602e325e560f9..7cf661994a29c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -69,29 +69,6 @@ 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), @@ -1724,7 +1701,6 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Tag, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); - StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5628,41 +5604,6 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { TemplateParameters, Align)); } -void CGDebugInfo::EmitGlobalVariable(const VarDecl *VD) { - assert(CGM.getCodeGenOpts().hasReducedDebugInfo()); - if (VD->hasAttr()) -return; - - const auto CacheIt = DeclCache.find(VD); - if (CacheIt != DeclCache.end()) -return; - - const auto InitVal = evaluateConstantInitializer(VD, CGM.getContext()); - 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); - - // Omit linkage name for variable definitions that represent constants. - // There hasn't been a need from consumers yet to have it attached. - DeclCache[VD].reset(DBuilder.createGlobalVariableExpression( - TheCU, DeclName, /* LinkageName
[clang] [lldb] [clang][DebugInfo] Revert "emit definitions for constant-initialized static data-members" (PR #74580)
Michael137 wrote: > Do you need me to merge that for you? Was going to wait until some more people had the chance to look. But if urgent, I don't think there should be any trouble merging this sooner https://github.com/llvm/llvm-project/pull/74580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] [clang][DebugInfo] Revert "emit definitions for constant-initialized static data-members" (PR #74580)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/74580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] [clang][DebugInfo] Revert "emit definitions for constant-initialized static data-members" (PR #74580)
Michael137 wrote: > > To support access to such constants from LLDB we'll most likely have to > > have to make LLDB find the constants by looking at the containing class > > first. > > Tangentially related to: > https://discourse.llvm.org/t/rfc-improve-dwarf-5-debug-names-type-lookup-parsing-speed/74151/31?u=dblaikie > > Clang/LLVM do know the difference between type-invariant members and type > variant ones (type invariant members are in the `members` list of the > `DICompositeType` and variant members have a `scope` that refers to the type > but don't appear in the `members` list) - would it be reasonable to not > include the invariant members in the accelerator table, but only include the > variant ones? Invariant ones can be found by finding any instance of the type > in the index, then looking at its members - and for variant members it'd be > useful to have them in the index. (though, honestly, I'm not sure how lldb > and gdb handle that situation - last time I tested it with gdb, it just saw > two different copies of the type and didn't try to unify/aggregate all the > variant members... but lldb only creates one copy of the type, so don't know > what it does if you've got, say, two member function template instantiations > for different template parameters in two different translation units/compile > units) I'll merge the PR for now to unblock and address this later https://github.com/llvm/llvm-project/pull/74580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] [clang][DebugInfo] Revert "emit definitions for constant-initialized static data-members" (PR #74580)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/74580 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] fixing issue #64441 (PR #74814)
@@ -56,10 +56,10 @@ namespace Foo = A::B; // namespace alias using Foo::myfunc; // using declaration -using namespace Foo;// using directive +//removing namespace foo; for quality naming Michael137 wrote: The `using` directive was used here to make sure LLDB does the right thing when doing qualified lookup in the presence of various `DW_TAG_imported_module` and name shadowing. I don't think we should change this because it risks subtly changing the test coverage. https://github.com/llvm/llvm-project/pull/74814 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72234)
Michael137 wrote: > I think this is missing a test in clang/test/CodeGenCXX that verifies Clang > generates the expected LLVM IR. I added those tests here: https://github.com/llvm/llvm-project/pull/72235 The IR doesn't change with this patch. It merely adds the necessary parameter to the DIBuilder API to be used from clang in the subsequent patch https://github.com/llvm/llvm-project/pull/72234 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72234)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/72234 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang] [flang] [compiler-rt] [llvm] [libc] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72235)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/72235 >From c0db61f318f50a1cf219c69af9c6b624b05c9da1 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 13 Nov 2023 09:48:39 + Subject: [PATCH] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable This patch implements the DWARFv5 issue 161118.1: "DW_TAG for C++ static data members". This will simplify LLDB's handling of static data members greatly in the long term since we no longer need to differentiate non-static from static data member declarations using non-portable heuristics. --- clang/lib/CodeGen/CGDebugInfo.cpp | 8 +++-- .../debug-info-static-inline-member.cpp | 4 +-- .../CodeGenCXX/debug-info-static-member.cpp | 36 --- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 04ca02cfe858579..f3de91d4a39ebee 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1679,9 +1679,13 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, StringRef VName = Var->getName(); llvm::DINode::DIFlags Flags = getAccessFlag(Var->getAccess(), RD); + auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5 + ? llvm::dwarf::DW_TAG_variable + : llvm::dwarf::DW_TAG_member; auto Align = getDeclAlignIfRequired(Var, CGM.getContext()); - llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( - RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); + llvm::DIDerivedType *GV = + DBuilder.createStaticMemberType(RecordTy, VName, VUnit, LineNumber, VTy, + Flags, /* Val */ nullptr, Tag, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; diff --git a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp index bfb7ad6b80fabf3..f2d4d9408a8297a 100644 --- a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp +++ b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp @@ -1,5 +1,5 @@ -// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -debug-info-kind=standalone %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s -// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -debug-info-kind=limited %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s +// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -gdwarf-4 -debug-info-kind=standalone %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s +// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -gdwarf-4 -debug-info-kind=limited %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s enum class Enum : int { VAL = -1 diff --git a/clang/test/CodeGenCXX/debug-info-static-member.cpp b/clang/test/CodeGenCXX/debug-info-static-member.cpp index 578995801c6400b..a2d25e98ed1cb62 100644 --- a/clang/test/CodeGenCXX/debug-info-static-member.cpp +++ b/clang/test/CodeGenCXX/debug-info-static-member.cpp @@ -1,7 +1,8 @@ -// RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s -// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++98 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s -// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s -// RUN: %clangxx -target x86_64-windows-msvc -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s +// 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 -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 // PR14471 // CHECK: @{{.*}}a{{.*}} = dso_local global i32 4, align 4, !dbg [[A:![0-9]+]] @@ -39,17 +40,20 @@ class C // // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}) // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct" -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var" +// DWARF4: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var" +// DWARF5: !DIDerivedType(tag: DW_TAG_variable, name: "anon_static_decl_var" // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "static_d
[clang] [llvm] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72234)
Michael137 wrote: Looks like the OCaml bindings are using the C-API that was changed in this PR. Will make a follow-up fix for those https://github.com/llvm/llvm-project/pull/72234 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 8e8bad7 - Revert "[llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (#72234)"
Author: Michael Buch Date: 2023-11-15T08:50:16Z New Revision: 8e8bad70e6db0b04198c025bef9acccfd06f36f0 URL: https://github.com/llvm/llvm-project/commit/8e8bad70e6db0b04198c025bef9acccfd06f36f0 DIFF: https://github.com/llvm/llvm-project/commit/8e8bad70e6db0b04198c025bef9acccfd06f36f0.diff LOG: Revert "[llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (#72234)" This reverts commit 9a9933fae23249fbf6cf5b3c090e630f578b7f98. The OCaml bindings were using `LLVMDIBuilderCreateStaticMemberType`, causing the API change in `9a9933fae23249fbf6cf5b3c090e630f578b7f98` to break buildbots that built the bindings. Revert until we figure out whether to fixup the bindings or just not change the C-API Added: Modified: clang/lib/CodeGen/CGDebugInfo.cpp llvm/include/llvm-c/DebugInfo.h llvm/include/llvm/IR/DIBuilder.h llvm/lib/IR/DIBuilder.cpp llvm/lib/IR/DebugInfo.cpp llvm/lib/IR/DebugInfoMetadata.cpp llvm/lib/IR/Verifier.cpp Removed: llvm/test/DebugInfo/Generic/dwarf5-debug-info-static-member.ll diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index a201cf03c22f711..04ca02cfe858579 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1681,8 +1681,7 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, 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, - llvm::dwarf::DW_TAG_member, Align); + RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index 61659d514b520e5..5924294708cc354 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -785,14 +785,14 @@ LLVMMetadataRef LLVMDIBuilderCreateMemberType( * \param Type Type of the static member. * \param FlagsFlags to encode member attribute, e.g. private. * \param ConstantVal Const initializer of the member. - * \param Tag DWARF tag of the static member. * \param AlignInBits Member alignment. */ -LLVMMetadataRef LLVMDIBuilderCreateStaticMemberType( +LLVMMetadataRef +LLVMDIBuilderCreateStaticMemberType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal, -unsigned Tag, uint32_t AlignInBits); +uint32_t AlignInBits); /** * Create debugging information entry for a pointer to member. diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 2be133e85e8c1e4..ecd6dd7b0a4f822 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -376,12 +376,11 @@ namespace llvm { /// \param Ty Type of the static member. /// \param Flags Flags to encode member attribute, e.g. private. /// \param ValConst initializer of the member. -/// \param TagDWARF tag of the static member. /// \param AlignInBits Member alignment. DIDerivedType *createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, DINode::DIFlags Flags, - Constant *Val, unsigned Tag, + Constant *Val, uint32_t AlignInBits = 0); /// Create debugging information entry for Objective-C diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 58a7e07d9b58d86..1ce8c17f8a880f6 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -405,11 +405,12 @@ DIDerivedType * DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, DIType *Ty, DINode::DIFlags Flags, llvm::Constant *Val, - unsigned Tag, uint32_t AlignInBits) { + uint32_t AlignInBits) { Flags |= DINode::FlagStaticMember; - return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber, -getNonCompileUnitScope(Scope), Ty, 0, AlignInBits, -0, std::nullopt, Flags, getConstantOrNull(Val)); + return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, +
[clang] da90fd7 - Reland "[llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (#72234)"
Author: Michael Buch Date: 2023-11-15T10:26:35Z New Revision: da90fd75241d5b149fd307e3eeae84f7317d9d9b URL: https://github.com/llvm/llvm-project/commit/da90fd75241d5b149fd307e3eeae84f7317d9d9b DIFF: https://github.com/llvm/llvm-project/commit/da90fd75241d5b149fd307e3eeae84f7317d9d9b.diff LOG: Reland "[llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (#72234)" This was reverted because it broke the OCaml LLVM bindings. Relanding the original patch but without changing the C-API. They'll continue to work just fine as they do today. If in the future there is a need to pass a new tag to the C-API for creating static members, then we'll make the change to the OCaml bindings at that time. Original commit message: """ This patch adds the LLVM-side infrastructure to implement DWARFv5 issue 161118.1: "DW_TAG for C++ static data members". The clang-side of this patch will simply construct the DIDerivedType with a different DW_TAG. """ Added: llvm/test/DebugInfo/Generic/dwarf5-debug-info-static-member.ll Modified: clang/lib/CodeGen/CGDebugInfo.cpp llvm/include/llvm/IR/DIBuilder.h llvm/lib/IR/DIBuilder.cpp llvm/lib/IR/DebugInfo.cpp llvm/lib/IR/DebugInfoMetadata.cpp llvm/lib/IR/Verifier.cpp Removed: diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 04ca02cfe858579..a201cf03c22f711 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1681,7 +1681,8 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, 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, /* Val */ nullptr, + llvm::dwarf::DW_TAG_member, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index ecd6dd7b0a4f822..2be133e85e8c1e4 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -376,11 +376,12 @@ namespace llvm { /// \param Ty Type of the static member. /// \param Flags Flags to encode member attribute, e.g. private. /// \param ValConst initializer of the member. +/// \param TagDWARF tag of the static member. /// \param AlignInBits Member alignment. DIDerivedType *createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, DINode::DIFlags Flags, - Constant *Val, + Constant *Val, unsigned Tag, uint32_t AlignInBits = 0); /// Create debugging information entry for Objective-C diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 1ce8c17f8a880f6..58a7e07d9b58d86 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -405,12 +405,11 @@ DIDerivedType * DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, DIType *Ty, DINode::DIFlags Flags, llvm::Constant *Val, - uint32_t AlignInBits) { + unsigned Tag, uint32_t AlignInBits) { Flags |= DINode::FlagStaticMember; - return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, -LineNumber, getNonCompileUnitScope(Scope), Ty, 0, -AlignInBits, 0, std::nullopt, Flags, -getConstantOrNull(Val)); + return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber, +getNonCompileUnitScope(Scope), Ty, 0, AlignInBits, +0, std::nullopt, Flags, getConstantOrNull(Val)); } DIDerivedType * diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 390a27c4bc0c4dd..bb6d612638310f9 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1315,17 +1315,15 @@ LLVMDIBuilderCreateUnspecifiedType(LLVMDIBuilderRef Builder, const char *Name, return wrap(unwrap(Builder)->createUnspecifiedType({Name, NameLen})); } -LLVMMetadataRef -LLVMDIBuilderCreateStaticMemberType( +LLVMMetadataRef LLVMDIBuilderCreateStaticMemberType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
[clang] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72235)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/72235 >From a933f170dcbdbaf76f93a15cdb1c1148d78a82e8 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 13 Nov 2023 09:48:39 + Subject: [PATCH] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable This patch implements the DWARFv5 issue 161118.1: "DW_TAG for C++ static data members". This will simplify LLDB's handling of static data members greatly in the long term since we no longer need to differentiate non-static from static data member declarations using non-portable heuristics. --- clang/lib/CodeGen/CGDebugInfo.cpp | 9 +++-- .../debug-info-static-inline-member.cpp | 4 +-- .../CodeGenCXX/debug-info-static-member.cpp | 36 --- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index a201cf03c22f711..f3de91d4a39ebee 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1679,10 +1679,13 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, StringRef VName = Var->getName(); llvm::DINode::DIFlags Flags = getAccessFlag(Var->getAccess(), RD); + auto Tag = CGM.getCodeGenOpts().DwarfVersion >= 5 + ? llvm::dwarf::DW_TAG_variable + : llvm::dwarf::DW_TAG_member; auto Align = getDeclAlignIfRequired(Var, CGM.getContext()); - llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( - RecordTy, VName, VUnit, LineNumber, VTy, Flags, /* Val */ nullptr, - llvm::dwarf::DW_TAG_member, Align); + llvm::DIDerivedType *GV = + DBuilder.createStaticMemberType(RecordTy, VName, VUnit, LineNumber, VTy, + Flags, /* Val */ nullptr, Tag, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; diff --git a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp index bfb7ad6b80fabf3..f2d4d9408a8297a 100644 --- a/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp +++ b/clang/test/CodeGenCXX/debug-info-static-inline-member.cpp @@ -1,5 +1,5 @@ -// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -debug-info-kind=standalone %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s -// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -debug-info-kind=limited %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s +// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -gdwarf-4 -debug-info-kind=standalone %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s +// RUN: %clangxx -target arm64-apple-macosx11.0.0 -g -gdwarf-4 -debug-info-kind=limited %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s enum class Enum : int { VAL = -1 diff --git a/clang/test/CodeGenCXX/debug-info-static-member.cpp b/clang/test/CodeGenCXX/debug-info-static-member.cpp index 578995801c6400b..a2d25e98ed1cb62 100644 --- a/clang/test/CodeGenCXX/debug-info-static-member.cpp +++ b/clang/test/CodeGenCXX/debug-info-static-member.cpp @@ -1,7 +1,8 @@ -// RUN: %clangxx -target x86_64-unknown-unknown -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s -// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++98 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s -// RUN: %clangxx -target x86_64-unknown-unknown -g -std=c++11 %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK,NOT-MS %s -// RUN: %clangxx -target x86_64-windows-msvc -g %s -emit-llvm -S -o - | FileCheck --check-prefixes=CHECK %s +// 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 -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 // PR14471 // CHECK: @{{.*}}a{{.*}} = dso_local global i32 4, align 4, !dbg [[A:![0-9]+]] @@ -39,17 +40,20 @@ class C // // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}) // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct" -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var" +// DWARF4: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var" +// DWARF5: !DIDerivedType(tag: DW_TAG_variable, name: "anon_static_decl_var" // CHECK: !DICompositeType(tag: DW_T
[clang] [clang][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72235)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/72235 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72234)
Michael137 wrote: > @adrian-prantl We do have a pretty strong guarantee of compatibility in the > llvm-c API. A new parameter pretty much means you need to define a new > function. Ended not changing the C-API in the relanded version https://github.com/llvm/llvm-project/pull/72234 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: > We're seeing crashes after this. Here is a reproducer: > https://bugs.chromium.org/p/chromium/issues/detail?id=1502489#c1 > > Please consider reverting if it can't be fixed quickly (I had a look, but it > seems there are some dependent changes on top). Thanks for reporting, will check and revert if not obvious what's wrong https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: > > We're seeing crashes after this. Here is a reproducer: > > https://bugs.chromium.org/p/chromium/issues/detail?id=1502489#c1 > > Please consider reverting if it can't be fixed quickly (I had a look, but > > it seems there are some dependent changes on top). > > Thanks for reporting, will check and revert if not obvious what's wrong Just based on the backtrace the only cause I see would be if we put a nullptr into `StaticDataMemberDefinitionsToEmit`. We unconditionally dereference it. In which case the fix is pretty straightforward. Building a local debug build to confirm this theory. https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: Ok with ASAN I could trigger this quite consistently. Turns out we can't iterate over the `StaticDataMemberDefinitionsToEmit` using a `for each` because during `EmitGlobalVariable` we can end up adding more things to the vector, invalidating the iterators. Will push a fix for this shortly https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Fix iterator invalidation during EmitGlobalVariable (PR #72415)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/72415 This patch fixes an issue introduced in https://github.com/llvm/llvm-project/pull/71780 where, if `EmitGlobalVariable` triggered a call to `CreateRecordStaticField` it would invalidate the `StaticDataMemberDefinitionsToEmit` iterator that is currently in-use. This fixes a crash reported in https://github.com/llvm/llvm-project/pull/71780#issuecomment-1812589911 >From 5aeb017edb3b2b9c4a427b4479fc9498f175c608 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 15 Nov 2023 16:55:24 + Subject: [PATCH] [clang][DebugInfo] Fix iterator invalidation during EmitGlobalVariable This patch fixes an issue introduced in https://github.com/llvm/llvm-project/pull/71780 where, if `EmitGlobalVariable` triggered a call to `CreateRecordStaticField` it would invalidate the `StaticDataMemberDefinitionsToEmit` iterator that is currently in-use. This fixes a crash reported in https://github.com/llvm/llvm-project/pull/71780#issuecomment-1812589911 --- clang/lib/CodeGen/CGDebugInfo.cpp | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index a201cf03c22f711..d19e23e1392f4b4 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5830,8 +5830,13 @@ void CGDebugInfo::setDwoId(uint64_t Signature) { } void CGDebugInfo::finalize() { - for (auto const *VD : StaticDataMemberDefinitionsToEmit) { -assert(VD->isStaticDataMember()); + // We can't use a for-each here because `EmitGlobalVariable` + // may push new decls into `StaticDataMemberDefinitionsToEmit`, + // which would invalidate any iterator. + for (size_t i = 0; i < StaticDataMemberDefinitionsToEmit.size(); ++i) { +auto const *VD = StaticDataMemberDefinitionsToEmit[i]; + +assert(VD && VD->isStaticDataMember()); if (DeclCache.contains(VD)) continue; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Fix iterator invalidation during EmitGlobalVariable (PR #72415)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/72415 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: @zmodem Fix pushed in `14a84510f5d07b05b348188c7dfbe54076fa1485`. Your reproducer works fine for me now. Let me know if you're still seeing issues. https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72234)
Michael137 wrote: > we're seeing debug info verifier issues in Rust with this change, e.g. > > ``` > > invalid tag > > !50 = !DIDerivedType(tag: DW_TAG_imported_declaration, name: "DISCR_EXACT", > scope: !37, file: !2, baseType: !51, flags: DIFlagStaticMember, extraData: > i64 0) > > invalid tag > > !61 = !DIDerivedType(tag: DW_TAG_imported_declaration, name: "DISCR_EXACT", > scope: !54, file: !2, baseType: !51, flags: DIFlagStaticMember, extraData: > i64 1) > > invalid tag > > !86 = !DIDerivedType(tag: DW_TAG_shared_type, name: "DISCR_EXACT", scope: > !79, file: !2, baseType: !87, flags: DIFlagStaticMember, extraData: i64 0) > > invalid tag > > !97 = !DIDerivedType(tag: DW_TAG_shared_type, name: "DISCR_EXACT", scope: > !90, file: !2, baseType: !87, flags: DIFlagStaticMember, extraData: i64 1) > > ``` > > > > is this expected? > > > > (https://logs.chromium.org/logs/chromium/buildbucket/cr-buildbucket/8764364541415601649/+/u/package_rust/stdout?format=raw) > > Hmmm yea that's problematic. Feel free to revert since I'm currently not at my PC. It looks like the Tag parameter wouldve been better off strongly typed since I suspect there are some callers that I missed that now pass alignment to where now the tag is. https://github.com/llvm/llvm-project/pull/72234 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [llvm][DebugInfo] DWARFv5: static data members declarations are DW_TAG_variable (PR #72234)
Michael137 wrote: Is it possible that this is to be fixed at the callsites in the rust frontend? Dont think i missed any callers in LLVM (then again I'm not at a PC to confirm this atm) https://github.com/llvm/llvm-project/pull/72234 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: > Hi @Michael137, we are seeing a failure in one of our internal tests that I > bisected back to this change. Consider the following code: > > ```c++ > struct X > { > static const int constant = 1; > int x; > > X() { x = constant; } > }; > const int X::constant; > > int main() > { > X x; > x.x = X::constant; > x.x = X::constant; > x.x = X::constant; > x.x = X::constant; > x.x = X::constant; > return 0; > } > ``` > > Prior to your change, the compiler would generate the following DWARF for the > constant value: > > ``` > 0x003a: DW_TAG_member > DW_AT_name("constant") > DW_AT_type(0x0057 "const int") > DW_AT_decl_file ("/home/dyung/sandbox/test.cpp") > DW_AT_decl_line (3) > DW_AT_external(true) > DW_AT_declaration (true) > DW_AT_const_value (1) > ``` > > After your change, the DW_AT_const_value is gone from this DW_TAG_member > group, but doesn't appear anywhere else in the DWARF output which seems to > indicate that it was dropped completely which does not seem to be correct. Is > this intended or am I missing something? > Hi @Michael137, we are seeing a failure in one of our internal tests that I > bisected back to this change. Consider the following code: > > ```c++ > struct X > { > static const int constant = 1; > int x; > > X() { x = constant; } > }; > const int X::constant; > > int main() > { > X x; > x.x = X::constant; > x.x = X::constant; > x.x = X::constant; > x.x = X::constant; > x.x = X::constant; > return 0; > } > ``` > > Prior to your change, the compiler would generate the following DWARF for the > constant value: > > ``` > 0x003a: DW_TAG_member > DW_AT_name("constant") > DW_AT_type(0x0057 "const int") > DW_AT_decl_file ("/home/dyung/sandbox/test.cpp") > DW_AT_decl_line (3) > DW_AT_external(true) > DW_AT_declaration (true) > DW_AT_const_value (1) > ``` > > After your change, the DW_AT_const_value is gone from this DW_TAG_member > group, but doesn't appear anywhere else in the DWARF output which seems to > indicate that it was dropped completely which does not seem to be correct. Is > this intended or am I missing something? Right, we stopped putting the `DW_AT_const_value` on the declaration. Instead we put either the location or the constant on the definition, depending on what's available. In your example you define the variable out-of-class which would generate a `DW_TAG_variable` with a location, so we don't emit the constant for it on the definition. What's the nature of the failure? Would you instead be able to read the value out of the definition? CC @dwblaikie https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: > The member is const with an initializer in-class. How is the constant value > not available for the definition? Right, it is available, we just don't attach it if we have a location for it. Don't see why we couldn't put it on the definition if we have the constant on hand https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: > So I guess what you are saying in this case is that it is expected and the > value is at the location indicated by the DW_AT_location value? As long as > the value is still available I suppose that is fine then and the test just > needs updating. Yup that's exactly right. I'll go ahead with @pogo59's suggestion then and make sure we also emit the constant on the definition when we can. If updating your test to accommodate for only having the DW_AT_location is feasible for now that'd be great since I'll only be able to get to it tomorrow https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: > Hi, we're seeing some breakages, similar to the above in our debugger tests > with this patch. > > A failing bot can be found here: > https://luci-milo.appspot.com/ui/p/fuchsia/builders/ci/clang_toolchain.ci.core.x64-debug/b8764552260903625809/overview > > You can find a fuller discussion in our bugtracker: > https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=136182. > > The problem in our test is that the `DW_AT_const_value`, no longer seems to > be in the expected place, similar to @dyung's issue above. Is there an ETA on > when your fix will land? If it won't be soon, would you mind reverting until > you can address this issue? Sorry for not updating the thread. I'm about to open a PR for said change https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: > Fantastic! @ilovepi To clarify the upcoming change, we are planning to attach the `DW_AT_const_value` to the definition, not the declaration like we used to. In case that's what your unit-test is expecting https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/72730 In https://github.com/llvm/llvm-project/pull/71780 we started emitting definitions for all static data-members with constant initialisers, even if they were constants (i.e., didn't have a location). We also dropped the `DW_AT_const_value` from the declaration to help resolve [inconsistencies during type merging in the DWARFParallelLinker](https://github.com/llvm/llvm-project/pull/68721). However, for static data members that do have locations, we wouldn't emit a `DW_AT_const_value` on it, assuming that the consumer knows how to read the value using the location. This broke some consumers that really wanted to find a `DW_AT_const_value`. This patch makes sure we also attach the `DW_AT_const_value` to definitions that have a location. >From 6dcb09dcc50a9b9e92640412242927b3e226929e Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Sat, 18 Nov 2023 00:20:05 + Subject: [PATCH 1/3] [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() ? 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()) 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 Date: Sat, 18 Nov 2023 00:52:24 + Subject: [PATCH 2/3] 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() ? 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 Date: Sat, 18 Nov 2023 00:22:06 + Subject: [PATCH 3/3] [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->hasLoca
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
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 Date: Sat, 18 Nov 2023 00:20:05 + Subject: [PATCH 1/4] [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() ? 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()) 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 Date: Sat, 18 Nov 2023 00:52:24 + Subject: [PATCH 2/4] 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() ? 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 Date: Sat, 18 Nov 2023 00:22:06 + Subject: [PATCH 3/4] [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:[
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
Michael137 wrote: @ilovepi https://github.com/llvm/llvm-project/pull/72730 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
Michael137 wrote: > Overall this looks good, thanks! > > I think we may want to add a test to check that the output DWARF has a const > value in the expected place, since consumers are relying on it. Any suggestions where to put such end-to-end test? This patch makes sure we encode the constant in a `DIExpression` on definitions, which is tested. And we have tests for ensuring that `DW_OP_constu` expressions get turned into `DW_AT_const_value`s (I know of at least `llvm/test/DebugInfo/Generic/dwarf5-debug-info-static-member.ll`) https://github.com/llvm/llvm-project/pull/72730 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
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 Date: Sat, 18 Nov 2023 00:20:05 + Subject: [PATCH 1/5] [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() ? 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()) 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 Date: Sat, 18 Nov 2023 00:52:24 + Subject: [PATCH 2/5] 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() ? 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 Date: Sat, 18 Nov 2023 00:22:06 + Subject: [PATCH 3/5] [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:[
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
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 Date: Sat, 18 Nov 2023 00:20:05 + 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() ? 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()) 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 Date: Sat, 18 Nov 2023 00:52:24 + 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() ? 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 Date: Sat, 18 Nov 2023 00:22:06 + 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:[
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
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 Date: Sat, 18 Nov 2023 00:20:05 + Subject: [PATCH 1/7] [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() ? 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()) 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 Date: Sat, 18 Nov 2023 00:52:24 + Subject: [PATCH 2/7] 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() ? 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 Date: Sat, 18 Nov 2023 00:22:06 + Subject: [PATCH 3/7] [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:[
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/72730 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/72730 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
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 Date: Sat, 18 Nov 2023 00:20:05 + 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() ? 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()) 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 Date: Sat, 18 Nov 2023 00:52:24 + 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() ? 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 Date: Sat, 18 Nov 2023 00:22:06 + 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:[
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
Michael137 wrote: This will need a slight tweak in DwarfCompileUnit because it currently doesn't attach a DW_AT_location to global variable DIEs that already have a DW_AT_const_value https://github.com/llvm/llvm-project/pull/72730 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
Michael137 wrote: > Hmm, I can't quite tell from the test case updates in the patch, at least at > a glance: How does this get encoded at the IR level? Do we end up with two > DIGlobalVariableExpressions? One with the constant value expresison, and one > that references the actual global variable? Or somehow encode both in one? My understanding was that the DIExpression parameter to DIGlobalVariableExpression was empty for global variables with locations. So the patch just encodes the constant into that expression if it's otherwise empty. My plan was to make [DwarfCompileUnit](https://llvm.org/doxygen/DwarfCompileUnit_8cpp_source.html#l00203) support global variables with locations *and* constants, which it currently assumes doesn't happen. Let me know if I missed something here https://github.com/llvm/llvm-project/pull/72730 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] Reland "[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers" (PR #71780)
Michael137 wrote: > I'm unclear on the specifics of the check, but it's probably something we can > adjust if that is the long-term solution. > > CC @petrhosek Since he was interested in getting this resolved soon. There's a few things left to iron out with https://github.com/llvm/llvm-project/pull/72730, which I hope to resolve by Friday. If this is blocking you urgently then we could add back the constant to the declaration until I land https://github.com/llvm/llvm-project/pull/72730 (instead of reverting the entire patch). https://github.com/llvm/llvm-project/pull/71780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Improve heuristic to determine whether to evaluate a static variable's initializer (PR #72974)
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 Date: Sat, 18 Nov 2023 00:20:05 + 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() ? 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), @@ -5596,14 +5619,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 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: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Improve heuristic to determine whether to evaluate a static variable's initializer (PR #72974)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/72974 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
Michael137 wrote: I extracted the parts that are clean-ups/bugfixes into a new PR: https://github.com/llvm/llvm-project/pull/72974 https://github.com/llvm/llvm-project/pull/72730 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Improve heuristic to determine whether to evaluate a static variable's initializer (PR #72974)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/72974 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Improve heuristic to determine whether to evaluate a static variable's initializer (PR #72974)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/72974 >From 012096290352438668d8f4bb7a97179952a87a3a Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Sat, 18 Nov 2023 00:20:05 + 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 -- .../CodeGenCXX/debug-info-static-member.cpp | 14 +- 3 files changed, 31 insertions(+), 20 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() ? 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), @@ -5596,14 +5619,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 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: 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=CHEC
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
Michael137 wrote: > > My understanding was that the DIExpression parameter to > > DIGlobalVariableExpression was empty for global variables with locations. > > So the patch just encodes the constant into that expression if it's > > otherwise empty. > > I think in theory it can be non-empty (see what happens under a merge globals > optimization... I'm not sure of an example of when this optimization fires, > or what the debug info we emit looks like - in theory it should look like a > global with a non-empty expression that describes offsetting the pointer > forward to reach the global inside the merged global) & so then you'd have a > hard time telling whether the expression is meant to be used in addition to > the location, or as part of evaluating the location. > > We don't really have a mechanism for encoding a variable in two locations (or > a constant and a location) at the same time, I think. We could invent a > special opcode to use in the expression to communicate this, or define some > special handling if there's two separate expressions providing a location (or > a location and a constant in this case) for the same variable (say that > they're both valid, and emit them both if we can). > > @adrian-prantl thoughts? Thanks for the pointers. The closest I could get to triggering a GlobalMerge of const static data-members was for following code: ``` struct Foo { static const int a; static const int b; }; const int Foo::a = 100; const int Foo::b = 200; ``` But only if I mark the constants as `internal` in the IR as follows (I attached the whole file): ``` %struct.Foo = type { i8 } @a = internal constant i32 100, align 4, !dbg !0 @b = internal constant i32 200, align 4, !dbg !5 define void @use1() { %x = load i32, ptr @a, align 4 %y = load i32, ptr @b, align 4 ret void } ... ``` Then run `opt` as: ``` ./bin/opt -global-merge -global-merge-max-offset=100 -global-merge-on-const -S merge.ll ``` That changes the IR into: ``` ... @_MergedGlobals = private constant <{ i32, i32 }> <{ i32 100, i32 200 }>, align 4, !dbg !0, !dbg !13 @a = internal alias i32, ptr @_MergedGlobals @b = internal alias i32, getelementptr inbounds (<{ i32, i32 }>, ptr @_MergedGlobals, i32 0, i32 1) ... !1 = distinct !DIGlobalVariable(name: "a", linkageName: "_ZN3Foo1aE", scope: !2, file: !3, line: 6, type: !7, isLocal: false, isDefinition: true, declaration: !12) ... !5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) !6 = distinct !DIGlobalVariable(name: "b", linkageName: "_ZN3Foo1bE", scope: !2, file: !3, line: 7, type: !7, isLocal: false, isDefinition: true, declaration: !9) ... !13 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression(DW_OP_plus_uconst, 4)) ``` https://github.com/llvm/llvm-project/pull/72730 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Attach DW_AT_const_value to static data-member definitions if available (PR #72730)
Michael137 wrote: > Do we end up with two DIGlobalVariableExpressions? Just checked. With this patch, MergeGlobals would produce following IR: ``` ... !10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression(DW_OP_plus_uconst, 4, DW_OP_constu, 200, DW_OP_stack_value)) !11 = distinct !DIGlobalVariable(name: "b", linkageName: "_ZN12_GLOBAL__N_13Foo1bE", scope: !2, file: !3, line: 8, type: !4, isLocal: true, isDefinition: true, declaration: !9) ... !14 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression(DW_OP_constu, 200, DW_OP_stack_value)) ... ``` I.e., two `DIGlobalVariableExpression`s for the same `DIGlobalVariable`, which AFAICT would confuse `DwarfDebug` at the moment, which expects there to be a 1-to-1 mapping. https://github.com/llvm/llvm-project/pull/72730 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70551)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/70551 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’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: ``` 0x007b: DW_TAG_structure_type DW_AT_calling_convention(DW_CC_pass_by_value) DW_AT_name ("Foo") ... 0x008d: DW_TAG_member DW_AT_name("i") DW_AT_type(0x0062 "const int") DW_AT_external(true) DW_AT_declaration (true) DW_AT_const_value (4) Newly added v 0x009a: DW_TAG_variable DW_AT_specification (0x008d "i") DW_AT_const_value (4) DW_AT_linkage_name ("_ZN2t2IiE1iIfEE") ``` >From e02939572877cdc839894454a6fab36ab143d924 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/2] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c430713b0d77d79..a109f140cca80c8 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5574,25 +5574,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5929,3 +5912,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); +
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70551)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70551 >From e02939572877cdc839894454a6fab36ab143d924 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/3] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c430713b0d77d79..a109f140cca80c8 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5574,25 +5574,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5929,3 +5912,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); + if (ValIntOpt) +ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); +} else if (Val.isFloat()) + ValExpr = DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + } + + return ValExpr; +} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ae12485850ca775..7b60e94555d0608 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -800,6 +800,11 @@ class CGDebugInfo { llvm::MDTuple *&TemplateParameters, llvm::DIScope *&VDContext); + /// Create a DIExpression representing the constant corresponding + /// to the specified 'Val'. Returns nullptr on failure. + llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD, +const APValue &Val); + /// Allocate a copy of \p A using the DebugInfoNames allocator /// and return a reference to it. If multiple arguments are given the strings /// are concatenated. >From 119276638095f48d8d2a5dd8fc7e042059e66378 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:19:47 +0100 Subject: [PATCH 2/3] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’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_
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70551)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70551 >From e02939572877cdc839894454a6fab36ab143d924 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/4] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c430713b0d77d79..a109f140cca80c8 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5574,25 +5574,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5929,3 +5912,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); + if (ValIntOpt) +ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); +} else if (Val.isFloat()) + ValExpr = DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + } + + return ValExpr; +} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ae12485850ca775..7b60e94555d0608 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -800,6 +800,11 @@ class CGDebugInfo { llvm::MDTuple *&TemplateParameters, llvm::DIScope *&VDContext); + /// Create a DIExpression representing the constant corresponding + /// to the specified 'Val'. Returns nullptr on failure. + llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD, +const APValue &Val); + /// Allocate a copy of \p A using the DebugInfoNames allocator /// and return a reference to it. If multiple arguments are given the strings /// are concatenated. >From 119276638095f48d8d2a5dd8fc7e042059e66378 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:19:47 +0100 Subject: [PATCH 2/4] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’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_
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/70639 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’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: ``` 0x007b: DW_TAG_structure_type DW_AT_calling_convention(DW_CC_pass_by_value) DW_AT_name ("Foo") ... 0x008d: DW_TAG_member DW_AT_name("i") DW_AT_type(0x0062 "const int") DW_AT_external(true) DW_AT_declaration (true) DW_AT_const_value (4) Newly added v 0x009a: DW_TAG_variable DW_AT_specification (0x008d "i") DW_AT_const_value (4) DW_AT_linkage_name ("_ZN2t2IiE1iIfEE") ``` >From cbae5425ac00e3cb597827e4b6c402446cc40d9d Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/2] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..9de55e41f885d26 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5580,25 +5580,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5935,3 +5918,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); +
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: Summing the size of all *.o files in my local debug Clang build increased by `0.7%` with this patch https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
https://github.com/Michael137 ready_for_review https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70551)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70551 >From e02939572877cdc839894454a6fab36ab143d924 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/4] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c430713b0d77d79..a109f140cca80c8 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5574,25 +5574,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5929,3 +5912,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); + if (ValIntOpt) +ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); +} else if (Val.isFloat()) + ValExpr = DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + } + + return ValExpr; +} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ae12485850ca775..7b60e94555d0608 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -800,6 +800,11 @@ class CGDebugInfo { llvm::MDTuple *&TemplateParameters, llvm::DIScope *&VDContext); + /// Create a DIExpression representing the constant corresponding + /// to the specified 'Val'. Returns nullptr on failure. + llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD, +const APValue &Val); + /// Allocate a copy of \p A using the DebugInfoNames allocator /// and return a reference to it. If multiple arguments are given the strings /// are concatenated. >From 8060e632025f0c480feff434822df40c3e82810b Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:19:47 +0100 Subject: [PATCH 2/4] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’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_
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70639 >From cbae5425ac00e3cb597827e4b6c402446cc40d9d Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/3] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..9de55e41f885d26 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5580,25 +5580,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5935,3 +5918,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); + if (ValIntOpt) +ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); +} else if (Val.isFloat()) + ValExpr = DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + } + + return ValExpr; +} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ae12485850ca775..7b60e94555d0608 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -800,6 +800,11 @@ class CGDebugInfo { llvm::MDTuple *&TemplateParameters, llvm::DIScope *&VDContext); + /// Create a DIExpression representing the constant corresponding + /// to the specified 'Val'. Returns nullptr on failure. + llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD, +const APValue &Val); + /// Allocate a copy of \p A using the DebugInfoNames allocator /// and return a reference to it. If multiple arguments are given the strings /// are concatenated. >From e3ae0862dd834ca54a096b3154bbbcc5a627014f Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:19:47 +0100 Subject: [PATCH 2/3] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’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_
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70639 >From cbae5425ac00e3cb597827e4b6c402446cc40d9d Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/4] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..9de55e41f885d26 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5580,25 +5580,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5935,3 +5918,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); + if (ValIntOpt) +ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); +} else if (Val.isFloat()) + ValExpr = DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + } + + return ValExpr; +} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ae12485850ca775..7b60e94555d0608 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -800,6 +800,11 @@ class CGDebugInfo { llvm::MDTuple *&TemplateParameters, llvm::DIScope *&VDContext); + /// Create a DIExpression representing the constant corresponding + /// to the specified 'Val'. Returns nullptr on failure. + llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD, +const APValue &Val); + /// Allocate a copy of \p A using the DebugInfoNames allocator /// and return a reference to it. If multiple arguments are given the strings /// are concatenated. >From e3ae0862dd834ca54a096b3154bbbcc5a627014f Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:19:47 +0100 Subject: [PATCH 2/4] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’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_
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70551)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/70551 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: This could also help with the type merging issues discussed in https://github.com/llvm/llvm-project/pull/68721#issuecomment-1764685418 https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70639 >From 18db082fc5008283f77cc98d9c733a47c63b7096 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:19:47 +0100 Subject: [PATCH 1/3] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’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: ``` 0x007b: DW_TAG_structure_type DW_AT_calling_convention(DW_CC_pass_by_value) DW_AT_name ("Foo") ... 0x008d: DW_TAG_member DW_AT_name("i") DW_AT_type(0x0062 "const int") DW_AT_external(true) DW_AT_declaration (true) DW_AT_const_value (4) Newly added v 0x009a: DW_TAG_variable DW_AT_specification (0x008d "i") DW_AT_const_value (4) DW_AT_linkage_name ("_ZN2t2IiE1iIfEE") ``` --- clang/lib/CodeGen/CGDebugInfo.cpp | 46 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 ++- .../debug-info-static-inline-member.cpp | 79 +++ .../TestConstStaticIntegralMember.py | 7 +- 5 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 clang/test/CodeGenCXX/debug-info-static-inline-member.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..7529f114996d2ec 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1693,6 +1693,7 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5613,6 +5614,39 @@ 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()) +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()); @@ -5883,6 +5917,18 @@ void CGDebugInfo::finalize() {
[clang] [clang][DebugInfo][NFC] Add createConstantValueExpression helper (PR #70674)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/70674 This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. Pre-requisite for https://github.com/llvm/llvm-project/pull/70639 >From 82795f2e8b06c8ae866c2f58e463d21958105108 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..9de55e41f885d26 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5580,25 +5580,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5935,3 +5918,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); + if (ValIntOpt) +ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); +} else if (Val.isFloat()) + ValExpr = DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + } + + return ValExpr; +} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ae12485850ca775..7b60e94555d0608 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -800,6 +800,11 @@ class CGDebugInfo { llvm::MDTuple *&TemplateParameters, llvm::DIScope *&VDContext); + /// Create a DIExpression representing the constant corresponding + /// to the specified 'Val'. Returns nullptr on failure. + llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD, +const APValue &Val); + /// Allocate a copy of \p A using the DebugInfoNames allocator /// and return a reference to it. If multiple arguments are given the strings /// are concatenated. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo][NFC] Add createConstantValueExpression helper (PR #70674)
@@ -5935,3 +5918,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; Michael137 wrote: will do https://github.com/llvm/llvm-project/pull/70674 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo][NFC] Add createConstantValueExpression helper (PR #70674)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70674 >From 82795f2e8b06c8ae866c2f58e463d21958105108 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/2] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..9de55e41f885d26 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5580,25 +5580,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5935,3 +5918,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); + if (ValIntOpt) +ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); +} else if (Val.isFloat()) + ValExpr = DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + } + + return ValExpr; +} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ae12485850ca775..7b60e94555d0608 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -800,6 +800,11 @@ class CGDebugInfo { llvm::MDTuple *&TemplateParameters, llvm::DIScope *&VDContext); + /// Create a DIExpression representing the constant corresponding + /// to the specified 'Val'. Returns nullptr on failure. + llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD, +const APValue &Val); + /// Allocate a copy of \p A using the DebugInfoNames allocator /// and return a reference to it. If multiple arguments are given the strings /// are concatenated. >From 96a433349a0db8c096bb8a7aeeaccd914392e592 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 30 Oct 2023 17:57:01 + Subject: [PATCH 2/2] fixup! refactor function to use llvm code-style --- clang/lib/CodeGen/CGDebugInfo.cpp | 43 --- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 9de55e41f885d26..76ce1572cdfc69c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5920,26 +5920,27 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { } llvm::DIExpression * -CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, +CGDebugInfo::createConstantValueExpression(const clang::ValueDecl *VD, const APValue &Val) { - llvm::DIExpression *ValExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getTy
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: > > Should not we remove constant initializer from the type definition if we > > have a DW_TAG_variable with a DW_AT_const_value now? > > Yep, +1 to this. This is where the type normalization benefit would come from > - no longer having this const value on the member declaration, but only on > the definition. Makes sense. I'll create a separate PR for that, unless people are fine with doing that as part of this change https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
@@ -0,0 +1,87 @@ +// 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 = 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_empty{}; +static inlineEnum inline_enum = Enum::VAL; + +template +static constexpr T cexpr_template{}; +}; + +int main() { +Foo f; + +// Force global variable definitions to be emitted. +(void)&Foo::cexpr_int; +(void)&Foo::cexpr_empty; + +return Foo::cexpr_int + Foo::cexpr_float + + (int)Foo::cexpr_enum + Foo::cexpr_template; +} + +// CHECK: @{{.*}}cexpr_int{{.*}} = +// CHECK-SAME: !dbg ![[INT_GLOBAL:[0-9]+]] + +// CHECK: @{{.*}}cexpr_empty{{.*}} = +// CHECK-SAME!dbg ![[EMPTY_GLOBAL:[0-9]+]] + +// CHECK: !DIGlobalVariableExpression(var: ![[INT_VAR:[0-9]+]], expr: !DIExpression()) Michael137 wrote: Because this one has a corresponding `llvm::GlobalVariable` which doesn't go down the code-path I added. We emit a `DW_AT_location` only for this. Should we be emitting both a location and constant in this case? https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: > I use `bloaty` for this ( https://github.com/google/bloaty ) - though it's a > bit involved to do this to sum over all the object files - summing up the > results from per-object file, etc... ``` bloaty `find ./patched-build/lib -name *.o` │ bloaty `find ./no-patch-build/lib -name *.o ` FILE SIZEVM SIZE│FILE SIZEVM SIZE - -- │ -- -- 54.6% 2.02Gi 60.3% 2.02Gi,__debug_str │ 54.5% 2.01Gi 60.1% 2.01Gi,__debug_str 22.0% 835Mi 24.3% 835Mi,__debug_info │ 22.1% 831Mi 24.3% 831Mi,__debug_info 6.2% 236Mi 0.0% 0String Table │ 6.1% 228Mi 0.0% 0String Table 4.5% 170Mi 5.0% 170Mi,__text │ 4.5% 169Mi 5.0% 169Mi,__text 2.6% 97.6Mi 2.8% 97.6Mi,__debug_line │ 2.8% 104Mi 3.1% 104Mi,__debug_line 2.3% 88.0Mi 2.6% 88.0Mi,__apple_types│ 2.3% 87.8Mi 2.6% 87.8Mi,__apple_types 2.2% 83.1Mi 2.4% 83.1Mi,__apple_names│ 2.1% 81.0Mi 0.0% 0[Unmapped] 2.2% 81.8Mi 0.0% 0[Unmapped]│ 2.1% 78.5Mi 2.3% 78.5Mi,__apple_names 1.7% 65.6Mi 1.9% 65.6Mi,__compact_unwind │ 1.7% 65.4Mi 1.9% 65.4Mi,__compact_unwind 1.0% 39.2Mi 0.0% 0Symbol Table │ 1.0% 39.0Mi 0.0% 0Symbol Table 0.2% 8.05Mi 0.2% 8.05Mi,__const │ 0.2% 7.55Mi 0.2% 7.55Mi,__const 0.2% 7.91Mi 0.2% 7.91Mi,__cstring│ 0.2% 7.54Mi 0.2% 7.54Mi,__cstring 0.1% 5.24Mi 0.2% 5.24Mi,__debug_abbrev │ 0.1% 5.27Mi 0.2% 5.27Mi,__debug_abbrev 0.1% 2.31Mi 0.0% 0[Mach-O Headers] │ 0.1% 2.30Mi 0.0% 0[Mach-O Headers] 0.0% 1.38Mi 0.0% 1.38Mi,__debug_ranges │ 0.0% 1.38Mi 0.0% 1.38Mi,__debug_ranges 0.0% 994Ki 0.0% 994Ki,__apple_namespac │ 0.0% 949Ki 0.0% 949Ki,__apple_namespac 0.0% 0 0.0% 354Ki,__bss│ 0.0% 0 0.0% 354Ki,__bss 0.0% 324Ki 0.0% 324Ki,__data │ 0.0% 324Ki 0.0% 324Ki,__data 0.0% 283Ki 0.0% 283Ki,__StaticInit │ 0.0% 283Ki 0.0% 283Ki,__StaticInit 0.0% 31.3Ki 0.0% 61.4Ki[10 Others] │ 0.0% 31.9Ki 0.0% 62.0Ki[11 Others] 0.0% 58.6Ki 0.0% 58.6Ki,__apple_objc │ 0.0% 58.6Ki 0.0% 58.6Ki,__apple_objc 00.0% 3.71Gi 100.0% 3.35GiTOTAL │ 100.0% 3.68Gi 100.0% 3.33GiTOTAL ``` Probably the linkage names that contribute most? > That's a bit significant. Any chance you could get a per-section > breakdown/growth on that? (& exact flags - is this with compressed debug > info, for instance? Or not?) This is an example command line invocation (with some paths redacted) for one of the object files: ``` ./patched-build/bin/clang++ -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_LIBCPP_ENABLE_HARDENED_MODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__ STDC_LIMIT_MACROS -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissin g-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstr ing-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -g -std=c++17 -arch arm64 -fno-exceptions -funwind-tables -fno-rtti" ``` https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][DebugInfo][NFC] Add createConstantValueExpression helper (PR #70674)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70674 >From 82795f2e8b06c8ae866c2f58e463d21958105108 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:33:07 +0100 Subject: [PATCH 1/3] [clang][DebugInfo][NFC] Add createConstantValueExpression helper This patch factors out the code to create a DIExpression from an APValue into a separate helper function. This will be useful in a follow-up patch where we re-use this logic elsewhere. --- clang/lib/CodeGen/CGDebugInfo.cpp | 44 ++- clang/lib/CodeGen/CGDebugInfo.h | 5 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..9de55e41f885d26 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5580,25 +5580,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { auto &GV = DeclCache[VD]; if (GV) return; - llvm::DIExpression *InitExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { -// FIXME: Add a representation for integer constants wider than 64 bits. -if (Init.isInt()) { - const llvm::APSInt &InitInt = Init.getInt(); - std::optional InitIntOpt; - if (InitInt.isUnsigned()) -InitIntOpt = InitInt.tryZExtValue(); - else if (auto tmp = InitInt.trySExtValue(); tmp.has_value()) -// Transform a signed optional to unsigned optional. When cpp 23 comes, -// use std::optional::transform -InitIntOpt = (uint64_t)tmp.value(); - if (InitIntOpt) -InitExpr = DBuilder.createConstantValueExpression(InitIntOpt.value()); -} else if (Init.isFloat()) - InitExpr = DBuilder.createConstantValueExpression( - Init.getFloat().bitcastToAPInt().getZExtValue()); - } + llvm::DIExpression *InitExpr = createConstantValueExpression(VD, Init); llvm::MDTuple *TemplateParameters = nullptr; if (isa(VD)) @@ -5935,3 +5918,28 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { return llvm::DINode::FlagAllCallsDescribed; } + +llvm::DIExpression * +CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, + const APValue &Val) { + llvm::DIExpression *ValExpr = nullptr; + if (CGM.getContext().getTypeSize(VD->getType()) <= 64) { +// FIXME: Add a representation for integer constants wider than 64 bits. +if (Val.isInt()) { + const llvm::APSInt &ValInt = Val.getInt(); + std::optional ValIntOpt; + if (ValInt.isUnsigned()) +ValIntOpt = ValInt.tryZExtValue(); + else if (auto tmp = ValInt.trySExtValue(); tmp.has_value()) +// Transform a signed optional to unsigned optional. When cpp 23 comes, +// use std::optional::transform +ValIntOpt = (uint64_t)tmp.value(); + if (ValIntOpt) +ValExpr = DBuilder.createConstantValueExpression(ValIntOpt.value()); +} else if (Val.isFloat()) + ValExpr = DBuilder.createConstantValueExpression( + Val.getFloat().bitcastToAPInt().getZExtValue()); + } + + return ValExpr; +} diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index ae12485850ca775..7b60e94555d0608 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -800,6 +800,11 @@ class CGDebugInfo { llvm::MDTuple *&TemplateParameters, llvm::DIScope *&VDContext); + /// Create a DIExpression representing the constant corresponding + /// to the specified 'Val'. Returns nullptr on failure. + llvm::DIExpression *createConstantValueExpression(const clang::ValueDecl *VD, +const APValue &Val); + /// Allocate a copy of \p A using the DebugInfoNames allocator /// and return a reference to it. If multiple arguments are given the strings /// are concatenated. >From 96a433349a0db8c096bb8a7aeeaccd914392e592 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 30 Oct 2023 17:57:01 + Subject: [PATCH 2/3] fixup! refactor function to use llvm code-style --- clang/lib/CodeGen/CGDebugInfo.cpp | 43 --- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 9de55e41f885d26..76ce1572cdfc69c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -5920,26 +5920,27 @@ llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const { } llvm::DIExpression * -CGDebugInfo::createConstantValueExpression(clang::ValueDecl const *VD, +CGDebugInfo::createConstantValueExpression(const clang::ValueDecl *VD, const APValue &Val) { - llvm::DIExpression *ValExpr = nullptr; - if (CGM.getContext().getTypeSize(VD->getTy
[clang] [lldb] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70639 >From 18db082fc5008283f77cc98d9c733a47c63b7096 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:19:47 +0100 Subject: [PATCH 1/4] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’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: ``` 0x007b: DW_TAG_structure_type DW_AT_calling_convention(DW_CC_pass_by_value) DW_AT_name ("Foo") ... 0x008d: DW_TAG_member DW_AT_name("i") DW_AT_type(0x0062 "const int") DW_AT_external(true) DW_AT_declaration (true) DW_AT_const_value (4) Newly added v 0x009a: DW_TAG_variable DW_AT_specification (0x008d "i") DW_AT_const_value (4) DW_AT_linkage_name ("_ZN2t2IiE1iIfEE") ``` --- clang/lib/CodeGen/CGDebugInfo.cpp | 46 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 ++- .../debug-info-static-inline-member.cpp | 79 +++ .../TestConstStaticIntegralMember.py | 7 +- 5 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 clang/test/CodeGenCXX/debug-info-static-inline-member.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..7529f114996d2ec 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1693,6 +1693,7 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5613,6 +5614,39 @@ 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()) +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()); @@ -5883,6 +5917,18 @@ void CGDebugInfo::finalize() {
[lldb] [clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
@@ -67,15 +67,15 @@ int C::a = 4; // CHECK-NOT:size: // CHECK-NOT:align: // CHECK-NOT:offset: -// CHECK-SAME: flags: DIFlagStaticMember, -// CHECK-SAME: extraData: i1 true) +// CHECK-SAME: flags: DIFlagStaticMember +// CHECK-NOT:extraData: Michael137 wrote: Merging the two makes sense. I tried that initially but the C++98 FileCheck was tedious to work around. But with the latest iteration of the patch that shouldn't be a problem https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: > size report sounds generally OK - but there's a bunch of what look like > unrelated or strange results in there, perhaps they weren't compared at > exactly the same version? (like why did the apple_names size go down? How did > the .text and .debuG_line size change at all? ) Yea I was confused about that too. Might've mixed up commits of the control build. Did measurements again and here's what I got: ``` $ bloaty `find ./patched-build/lib -name *.o ` │ $ bloaty `find ./no-patch-build/lib -name *.o ` FILE SIZEVM SIZE│FILE SIZEVM SIZE -- -- │ -- -- 54.6% 2.02Gi 60.3% 2.02Gi,__debug_str │ 54.5% 2.01Gi 60.3% 2.01Gi,__debug_str 22.0% 834Mi 24.3% 834Mi,__debug_info │ 22.1% 833Mi 24.4% 833Mi,__debug_info 6.2% 236Mi 0.0% 0String Table │ 6.2% 236Mi 0.0% 0String Table 4.5% 170Mi 5.0% 170Mi,__text │ 4.5% 170Mi 5.0% 170Mi,__text 2.6% 97.6Mi 2.8% 97.6Mi,__debug_line │ 2.6% 98.6Mi 2.9% 98.6Mi,__debug_line 2.3% 88.0Mi 2.6% 88.0Mi,__apple_types│ 2.3% 88.0Mi 2.6% 88.0Mi,__apple_types 2.2% 83.1Mi 2.4% 83.1Mi,__apple_names│ 2.2% 81.8Mi 0.0% 0[Unmapped] 2.2% 81.8Mi 0.0% 0[Unmapped]│ 2.1% 77.8Mi 2.3% 77.8Mi,__apple_names 1.7% 65.6Mi 1.9% 65.6Mi,__compact_unwind │ 1.7% 65.6Mi 1.9% 65.6Mi,__compact_unwind 1.0% 39.2Mi 0.0% 0Symbol Table │ 1.0% 39.2Mi 0.0% 0Symbol Table 0.2% 8.05Mi 0.2% 8.05Mi,__const │ 0.2% 8.05Mi 0.2% 8.05Mi,__const 0.2% 7.91Mi 0.2% 7.91Mi,__cstring│ 0.2% 7.92Mi 0.2% 7.92Mi,__cstring 0.1% 5.05Mi 0.1% 5.05Mi,__debug_abbrev │ 0.1% 5.22Mi 0.2% 5.22Mi,__debug_abbrev 0.1% 2.31Mi 0.0% 0[Mach-O Headers] │ 0.1% 2.31Mi 0.0% 0[Mach-O Headers] 0.0% 1.38Mi 0.0% 1.38Mi,__debug_ranges │ 0.0% 1.38Mi 0.0% 1.38Mi,__debug_ranges 0.0% 994Ki 0.0% 994Ki,__apple_namespac │ 0.0% 994Ki 0.0% 994Ki,__apple_namespac 0.0% 0 0.0% 354Ki,__bss│ 0.0% 0 0.0% 354Ki,__bss 0.0% 324Ki 0.0% 324Ki,__data │ 0.0% 324Ki 0.0% 324Ki,__data 0.0% 283Ki 0.0% 283Ki,__StaticInit │ 0.0% 283Ki 0.0% 283Ki,__StaticInit 0.0% 31.3Ki 0.0% 61.4Ki[10 Others] │ 0.0% 31.3Ki 0.0% 61.4Ki[10 Others] 0.0% 58.6Ki 0.0% 58.6Ki,__apple_objc │ 0.0% 58.6Ki 0.0% 58.6Ki,__apple_objc 100.0% 3.70Gi 100.0% 3.35GiTOTAL │ 100.0% 3.69Gi 100.0% 3.34GiTOTAL ``` Section breakdown is still similar https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: > > Few minor issues, but looks good to me. (you metnioned somewhere an lldb > > issue I think with this patch when the value is removed from the static > > member declaration inside the class? If that's a problem - probably hold > > off on committing this until lldb's been fixed so this doesn't regress > > things? And document the dependence clearly in the commit message) > > I saw the patch to lldb to test that we can find global variables that are > `constexpr`. In upstream, we can't use find global variables, but the > expression parser does work for these. We should make sure that both > `FindGlobalVariables(...)` and expression parsing work for all `constexpr` > globals. Yup, the expression evaluator finds them by looking at the `DW_AT_const_value` on the declaration. But since we're moving that constant onto the definition with this patch, that will break that codepath. Looking into how best to address that now https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70639 >From 18db082fc5008283f77cc98d9c733a47c63b7096 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:19:47 +0100 Subject: [PATCH 1/7] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’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: ``` 0x007b: DW_TAG_structure_type DW_AT_calling_convention(DW_CC_pass_by_value) DW_AT_name ("Foo") ... 0x008d: DW_TAG_member DW_AT_name("i") DW_AT_type(0x0062 "const int") DW_AT_external(true) DW_AT_declaration (true) DW_AT_const_value (4) Newly added v 0x009a: DW_TAG_variable DW_AT_specification (0x008d "i") DW_AT_const_value (4) DW_AT_linkage_name ("_ZN2t2IiE1iIfEE") ``` --- clang/lib/CodeGen/CGDebugInfo.cpp | 46 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 ++- .../debug-info-static-inline-member.cpp | 79 +++ .../TestConstStaticIntegralMember.py | 7 +- 5 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 clang/test/CodeGenCXX/debug-info-static-inline-member.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..7529f114996d2ec 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1693,6 +1693,7 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5613,6 +5614,39 @@ 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()) +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()); @@ -5883,6 +5917,18 @@ void CGDebugInfo::finalize() {
[clang] [lldb] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: > The DWARFASTParserClang.cpp will try to create the class from the DWARF for > the class definition. You will need to find the DW_TAG_variable when we are > creating the static field if there is no DW_AT_const_value in the > DW_TAG_member. But we also need to support the DW_AT_const_value being in the > DW_TAG_member since older DWARF will be emitted like this. That's 100% correct. I was thinking, before [this block](https://github.com/llvm/llvm-project/blob/8b91de5d6a3f98dcc00bbd286e339e512f7e3682/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp#L2909-L2919) where we check for the existence of a `const_value_form`. With this patch such constant won't exist on the declaration. So I was thinking we would try to look for the definition. What's interesting is that with this patch, the expression evaluator successfully finds the DW_TAG_variable which have a location attribute but not if they have a constant instead of a location. It's probably some logic that assumes statics always have a location > Are we going to emit a DW_AT_const_expr now in the DW_TAG_member? If so, then > we will know that we need to look for the DW_TAG_variable. I don't think > clang emitted the DW_AT_const_expr attribute before. That wasn't part of this patch. But would make sense to add (i've noticed GCC adds that attribute) https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: Hmmm it seems like for `constexpr static` data members we don't get a symbol in the MachO the same way we do for out-of-line `const static`s that have a location: ``` struct Foo { static const int val1; static constexpr int val2 = 5; }; const int Foo::val1 = 10; $ nm a.out 00013fa4 S __ZN3Foo4val1E 0001 T __mh_execute_header 00013f90 T _main ``` LLDB can fish out the value out of `val1` by doing a `FindSymbol` on the mangled name. But that doesn't work with `val2` because it's not in the symbol table. @clayborg or @jasonmolenda probably know more about this. Seems to me like if we want to drop the constant off of the declaration entirely, we need to lookup the variable definition in the accelerator table in DWARFASTParserClang when we're constructing the VarDecls. https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: > One question I have here: where will the DW_TAG_variable get emitted for > these `constexpr`? For actual static member variables we emit a single > DW_TAG_variable in the file that declares the global variable, but for > `constexpr` we won't be able to do this will we? Will we end up emitting a > new copy each time someone include the header file? In that case we might end > up with many global variables being defined in a linked executable that > includes this header file more than once? That's true, if defined in a header, we'll emit a `DW_TAG_variable` for the constant in each compile unit the header is included in. GCC does do the right thing and only emit the definition DIE in a single CU. We should probably do the same. Though not sure at which level. Possibly the DWARF linker? https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/70639 >From 18db082fc5008283f77cc98d9c733a47c63b7096 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 27 Oct 2023 16:19:47 +0100 Subject: [PATCH 1/8] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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’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: ``` 0x007b: DW_TAG_structure_type DW_AT_calling_convention(DW_CC_pass_by_value) DW_AT_name ("Foo") ... 0x008d: DW_TAG_member DW_AT_name("i") DW_AT_type(0x0062 "const int") DW_AT_external(true) DW_AT_declaration (true) DW_AT_const_value (4) Newly added v 0x009a: DW_TAG_variable DW_AT_specification (0x008d "i") DW_AT_const_value (4) DW_AT_linkage_name ("_ZN2t2IiE1iIfEE") ``` --- clang/lib/CodeGen/CGDebugInfo.cpp | 46 +++ clang/lib/CodeGen/CGDebugInfo.h | 6 ++ clang/test/CodeGenCXX/debug-info-class.cpp| 13 ++- .../debug-info-static-inline-member.cpp | 79 +++ .../TestConstStaticIntegralMember.py | 7 +- 5 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 clang/test/CodeGenCXX/debug-info-static-inline-member.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0aaf678bf287c6e..7529f114996d2ec 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1693,6 +1693,7 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( RecordTy, VName, VUnit, LineNumber, VTy, Flags, C, Align); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); + StaticDataMemberDefinitionsToEmit.push_back(Var->getCanonicalDecl()); return GV; } @@ -5613,6 +5614,39 @@ 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()) +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()); @@ -5883,6 +5917,18 @@ void CGDebugInfo::finalize() {
[clang] [lldb] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: > > That's true, if defined in a header, we'll emit a DW_TAG_variable for the > > constant in each compile unit the header is included in. GCC does do the > > right thing and only emit the definition DIE in a single CU. We should > > probably do the same. Though not sure at which level we want to catch that. > > Which variable are you discussing here, `val1` or `val2`? > > For `val1`, we could not emit the constant value and only emit the real > definition (there's /some/ risk here - non-ODR uses (or otherwise optimized > away uses) of the variable may mean that the object file that defines the > variable won't be linked in - so we'd miss the constant value) For `val2` the > variable is effectively `inline` and doesn't have a home, so there's no one > place that we can emit the `DW_TAG_variable` out-of-line definition... Sorry for the confusion. I wasn't referring to that code snippet. Also, I must've not looked at the GCC dwarfdump output carefully enough. Compiling two CUs that include a class with a `static constexpr` member will produce two separate definitions and two entries in `.debug_pubnames`: ``` .debug_pubnames global die-in-sect 0x0070, cu-in-sect 0x000c, die-in-cu 0x0070, cu-header-in-sect 0x 'Foo::val2' global die-in-sect 0x007b, cu-in-sect 0x000c, die-in-cu 0x007b, cu-header-in-sect 0x 'main' global die-in-sect 0x0118, cu-in-sect 0x00b4, die-in-cu 0x0070, cu-header-in-sect 0x00a8 'Foo::val2' global die-in-sect 0x0128, cu-in-sect 0x00b4, die-in-cu 0x0080, cu-header-in-sect 0x00a8 'Foo::func' ``` So to answer Greg's question, yes we will potentially produce multiple variable definition DIEs. One for each CU that the header was included in https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lldb] [clang] [clang][DebugInfo] Emit global variable definitions for static data members with constant initializers (PR #70639)
Michael137 wrote: > The DWARFASTParserClang, with the current state of things, will automatically > add the const value initializer to the clang AST field. See > `DWARFASTParserClang::ParseSingleMember(...)` around the `// Handle static > members` around > lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp:2882. The code > extracts the `llvm::Expected const_value_or_err` and then calls > `TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err);` > to set the constant value of the static member. > > > > I think the expression parser knows how to grab this value if it is in a > static member variable. If this isn't there, it assumes there is a global > variable that backs it and that we will be able to find the location of this > variable in memory. The expression parser will ask for the address of this > value during expression evaluation when it resolves the symbols. Yup, what i was trying to explain is that with the current patch this will break because the expression evaluator neither finds the constant on the declaration (since we removed it) nor via symbol resolution (since they just won't exist for constants). My point was just that if we are to drop the constant from the declaration, we'll have to amend that DWARFASTParserClang logic that you linked so it finds the correct variable definition and take the constant off of that. > It would be nice to add this as a way to indicate this is a constexpr and > that we need to do something special with it. I agree, though i think that can be done in isolation as a follow-up PR. > Is there anyway we can just leave the `DW_AT_const_value` in the > `DW_TAG_member` and then have the `DW_TAG_variable` point to the > `DW_TAG_member` using a `DW_AT_specification` or `DW_AT_abstract_origin`? My > guess this isn't great DWARF where we have a `DW_TAG_variable` have a > specification or abstract origin that points to a different DWARF tag. The variable definition *will* have a specification back to the declaration. > Or maybe we can include the DW_AT_const_value in both places? The ask to drop the constant off of the declaration comes from the DWARFParallelLinker work where it was causing non-deterministic output. But @dwblaikie @avl-llvm will know more about that https://github.com/llvm/llvm-project/pull/70639 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits