[Lldb-commits] [lldb] [llvm] [lldb][dwarf] Compute fully qualified names on simplified template names with DWARFTypePrinter (PR #112811)

Zequan Wu via lldb-commits lldb-commits at lists.llvm.org
Thu Nov 7 15:04:05 PST 2024


https://github.com/ZequanWu updated https://github.com/llvm/llvm-project/pull/112811

>From 3fc0675398547617731d0501e3d4b98e2ffc480e Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Wed, 9 Oct 2024 22:35:46 -0700
Subject: [PATCH 1/4] [lldb][dwarf] Compute fully qualified names on simplified
 template names with DWARFTypePrinter

---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 21 +++++++----
 .../Plugins/SymbolFile/DWARF/DWARFBaseDIE.h   |  7 ++++
 .../Plugins/SymbolFile/DWARF/DWARFDIE.cpp     | 35 ++++++++++++++++++
 .../Plugins/SymbolFile/DWARF/DWARFDIE.h       | 15 ++++++++
 .../SymbolFile/DWARF/DWARFFormValue.cpp       | 25 +++++++++++++
 .../Plugins/SymbolFile/DWARF/DWARFFormValue.h |  3 ++
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      | 36 +++++--------------
 .../TypeSystem/Clang/TypeSystemClang.cpp      | 20 -----------
 .../TypeSystem/Clang/TypeSystemClang.h        |  4 ---
 .../DWARF/x86/simplified-template-names.cpp   | 31 ++++++++++++++++
 llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h  |  2 ++
 .../llvm/DebugInfo/DWARF/DWARFTypePrinter.h   | 31 ++++++++++------
 llvm/lib/DebugInfo/DWARF/DWARFDie.cpp         |  9 +++++
 13 files changed, 170 insertions(+), 69 deletions(-)
 create mode 100644 lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a30d898a93cc4d..41cb11f94a45e8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -44,6 +44,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
 #include "llvm/Demangle/Demangle.h"
 
 #include <map>
@@ -825,11 +826,11 @@ std::string DWARFASTParserClang::GetDIEClassTemplateParams(DWARFDIE die) {
   if (llvm::StringRef(die.GetName()).contains("<"))
     return {};
 
-  TypeSystemClang::TemplateParameterInfos template_param_infos;
-  if (ParseTemplateParameterInfos(die, template_param_infos))
-    return m_ast.PrintTemplateParams(template_param_infos);
-
-  return {};
+  std::string name;
+  llvm::raw_string_ostream os(name);
+  llvm::DWARFTypePrinter<DWARFDIE> type_printer(os);
+  type_printer.appendAndTerminateTemplateParameters(die);
+  return name;
 }
 
 void DWARFASTParserClang::MapDeclDIEToDefDIE(
@@ -1617,9 +1618,9 @@ void DWARFASTParserClang::GetUniqueTypeNameAndDeclaration(
     case DW_TAG_structure_type:
     case DW_TAG_union_type: {
       if (const char *class_union_struct_name = parent_decl_ctx_die.GetName()) {
-        qualified_name.insert(
-            0, GetDIEClassTemplateParams(parent_decl_ctx_die));
         qualified_name.insert(0, "::");
+        qualified_name.insert(0,
+                              GetDIEClassTemplateParams(parent_decl_ctx_die));
         qualified_name.insert(0, class_union_struct_name);
       }
       parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
@@ -1672,6 +1673,12 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
   if (attrs.name) {
     GetUniqueTypeNameAndDeclaration(die, cu_language, unique_typename,
                                     unique_decl);
+    if (log) {
+      dwarf->GetObjectFile()->GetModule()->LogMessage(
+          log, "SymbolFileDWARF({0:p}) - {1:x16}: {2} has unique name: {3} ",
+          static_cast<void *>(this), die.GetID(), DW_TAG_value_to_name(tag),
+          unique_typename.AsCString());
+    }
     if (UniqueDWARFASTType *unique_ast_entry_type =
             dwarf->GetUniqueDWARFASTTypeMap().Find(
                 unique_typename, die, unique_decl, byte_size,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 235343d2271223..ca25801137be38 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -24,9 +24,11 @@ class DWARFUnit;
 class DWARFDebugInfoEntry;
 class DWARFDeclContext;
 class SymbolFileDWARF;
+class DWARFFormValue;
 
 class DWARFBaseDIE {
 public:
+  using DWARFFormValue = dwarf::DWARFFormValue;
   DWARFBaseDIE() = default;
 
   DWARFBaseDIE(DWARFUnit *cu, DWARFDebugInfoEntry *die)
@@ -46,6 +48,7 @@ class DWARFBaseDIE {
   explicit operator bool() const { return IsValid(); }
 
   bool IsValid() const { return m_cu && m_die; }
+  bool isValid() const { return IsValid(); }
 
   bool HasChildren() const;
 
@@ -85,6 +88,8 @@ class DWARFBaseDIE {
   // Accessing information about a DIE
   dw_tag_t Tag() const;
 
+  dw_tag_t getTag() const { return Tag(); }
+
   dw_offset_t GetOffset() const;
 
   // Get the LLDB user ID for this DIE. This is often just the DIE offset,
@@ -95,6 +100,8 @@ class DWARFBaseDIE {
 
   const char *GetName() const;
 
+  const char *getShortName() const { return GetName(); }
+
   lldb::ModuleSP GetModule() const;
 
   // Getting attribute values from the DIE.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index d83740f8e2113b..3b4330c6de31d3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -86,6 +86,12 @@ elaborating_dies(const DWARFDIE &die) {
 }
 } // namespace
 
+std::optional<uint64_t> DWARFDIE::getLanguage() const {
+  if (IsValid())
+    return m_cu->GetDWARFLanguageType();
+  return std::nullopt;
+}
+
 DWARFDIE
 DWARFDIE::GetParent() const {
   if (IsValid())
@@ -118,6 +124,22 @@ DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const {
     return {};
 }
 
+DWARFDIE DWARFDIE::resolveReferencedType(dw_attr_t attr) const {
+  return GetReferencedDIE(attr);
+}
+
+DWARFDIE DWARFDIE::resolveReferencedType(DWARFFormValue v) const {
+  if (IsValid())
+    return v.Reference();
+  return {};
+}
+
+DWARFDIE DWARFDIE::resolveTypeUnitReference() const {
+  if (DWARFDIE reference = GetReferencedDIE(DW_AT_signature))
+    return reference;
+  return *this;
+}
+
 DWARFDIE
 DWARFDIE::GetDIE(dw_offset_t die_offset) const {
   if (IsValid())
@@ -575,3 +597,16 @@ bool DWARFDIE::GetDIENamesAndRanges(
 llvm::iterator_range<DWARFDIE::child_iterator> DWARFDIE::children() const {
   return llvm::make_range(child_iterator(*this), child_iterator());
 }
+
+DWARFDIE::child_iterator DWARFDIE::begin() const {
+  return child_iterator(*this);
+}
+
+DWARFDIE::child_iterator DWARFDIE::end() const { return child_iterator(); }
+
+std::optional<DWARFFormValue> DWARFDIE::find(const dw_attr_t attr) const {
+  DWARFFormValue form_value;
+  if (m_die->GetAttributeValue(m_cu, attr, form_value, nullptr, false))
+    return form_value;
+  return std::nullopt;
+}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index e1318953a384cd..273ac79e453703 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -44,9 +44,13 @@ class DWARFDIE : public DWARFBaseDIE {
 
   // Functions for obtaining DIE relations and references
 
+  std::optional<uint64_t> getLanguage() const;
+
   DWARFDIE
   GetParent() const;
 
+  DWARFDIE getParent() const { return GetParent(); }
+
   DWARFDIE
   GetFirstChild() const;
 
@@ -56,6 +60,12 @@ class DWARFDIE : public DWARFBaseDIE {
   DWARFDIE
   GetReferencedDIE(const dw_attr_t attr) const;
 
+  DWARFDIE resolveReferencedType(dw_attr_t attr) const;
+
+  DWARFDIE resolveReferencedType(DWARFFormValue v) const;
+
+  DWARFDIE resolveTypeUnitReference() const;
+
   // Get a another DIE from the same DWARF file as this DIE. This will
   // check the current DIE's compile unit first to see if "die_offset" is
   // in the same compile unit, and fall back to checking the DWARF file.
@@ -96,6 +106,8 @@ class DWARFDIE : public DWARFBaseDIE {
   DWARFDIE
   GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
 
+  std::optional<DWARFFormValue> find(const dw_attr_t attr) const;
+
   bool GetDIENamesAndRanges(
       const char *&name, const char *&mangled, DWARFRangeList &ranges,
       std::optional<int> &decl_file, std::optional<int> &decl_line,
@@ -105,6 +117,9 @@ class DWARFDIE : public DWARFBaseDIE {
 
   /// The range of all the children of this DIE.
   llvm::iterator_range<child_iterator> children() const;
+
+  child_iterator begin() const;
+  child_iterator end() const;
 };
 
 class DWARFDIE::child_iterator
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index f58c6262349c6f..bc5d0a9555ebd4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -569,6 +569,31 @@ uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
   }
 }
 
+std::optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
+  if ((!IsDataForm(m_form)) || m_form == lldb_private::dwarf::DW_FORM_sdata)
+    return std::nullopt;
+  return m_value.uval;
+}
+
+std::optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
+  if ((!IsDataForm(m_form)) ||
+      (m_form == lldb_private::dwarf::DW_FORM_udata &&
+       uint64_t(std::numeric_limits<int64_t>::max()) < m_value.uval))
+    return std::nullopt;
+  switch (m_form) {
+  case lldb_private::dwarf::DW_FORM_data4:
+    return int32_t(m_value.uval);
+  case lldb_private::dwarf::DW_FORM_data2:
+    return int16_t(m_value.uval);
+  case lldb_private::dwarf::DW_FORM_data1:
+    return int8_t(m_value.uval);
+  case lldb_private::dwarf::DW_FORM_sdata:
+  case lldb_private::dwarf::DW_FORM_data8:
+  default:
+    return m_value.sval;
+  }
+}
+
 const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
 
 bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index 8ab9163e645fea..66fb6e855f29f8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -58,11 +58,14 @@ class DWARFFormValue {
 
   uint64_t Reference(dw_offset_t offset) const;
   bool Boolean() const { return m_value.uval != 0; }
+  std::optional<uint64_t> getAsUnsignedConstant() const;
+  std::optional<int64_t> getAsSignedConstant() const;
   uint64_t Unsigned() const { return m_value.uval; }
   void SetUnsigned(uint64_t uval) { m_value.uval = uval; }
   int64_t Signed() const { return m_value.sval; }
   void SetSigned(int64_t sval) { m_value.sval = sval; }
   const char *AsCString() const;
+  const char *getAsCString() const { return AsCString(); }
   dw_addr_t Address() const;
   bool IsValid() const { return m_form != 0; }
   bool SkipValue(const DWARFDataExtractor &debug_info_data,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 9287d4baf19e9c..40c145c8ff1550 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -9,6 +9,7 @@
 #include "SymbolFileDWARF.h"
 
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Format.h"
@@ -2821,33 +2822,14 @@ void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {
             return true; // Keep iterating over index types, language mismatch.
         }
 
-        // Check the context matches
-        std::vector<lldb_private::CompilerContext> die_context;
-        if (query.GetModuleSearch())
-          die_context = die.GetDeclContext();
-        else
-          die_context = die.GetTypeLookupContext();
-        assert(!die_context.empty());
-        if (!query_simple.ContextMatches(die_context))
-          return true; // Keep iterating over index types, context mismatch.
-
-        // Try to resolve the type.
-        if (Type *matching_type = ResolveType(die, true, true)) {
-          ConstString name = matching_type->GetQualifiedName();
-          // We have found a type that still might not match due to template
-          // parameters. If we create a new TypeQuery that uses the new type's
-          // fully qualified name, we can find out if this type matches at all
-          // context levels. We can't use just the "match_simple" context
-          // because all template parameters were stripped off. The fully
-          // qualified name of the type will have the template parameters and
-          // will allow us to make sure it matches correctly.
-          TypeQuery die_query(name.GetStringRef(),
-                              TypeQueryOptions::e_exact_match);
-          if (!query.ContextMatches(die_query.GetContextRef()))
-            return true; // Keep iterating over index types, context mismatch.
-
-          results.InsertUnique(matching_type->shared_from_this());
-        }
+        std::string qualified_name;
+        llvm::raw_string_ostream os(qualified_name);
+        llvm::DWARFTypePrinter<DWARFDIE> type_printer(os);
+        type_printer.appendQualifiedName(die);
+        TypeQuery die_query(qualified_name, e_exact_match);
+        if (query.ContextMatches(die_query.GetContextRef()))
+          if (Type *matching_type = ResolveType(die, true, true))
+            results.InsertUnique(matching_type->shared_from_this());
         return !results.Done(query); // Keep iterating if we aren't done.
       });
       if (results.Done(query)) {
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 50115a638b9589..798535a4c390d6 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -1403,26 +1403,6 @@ static TemplateParameterList *CreateTemplateParameterList(
   return template_param_list;
 }
 
-std::string TypeSystemClang::PrintTemplateParams(
-    const TemplateParameterInfos &template_param_infos) {
-  llvm::SmallVector<NamedDecl *, 8> ignore;
-  clang::TemplateParameterList *template_param_list =
-      CreateTemplateParameterList(getASTContext(), template_param_infos,
-                                  ignore);
-  llvm::SmallVector<clang::TemplateArgument, 2> args(
-      template_param_infos.GetArgs());
-  if (template_param_infos.hasParameterPack()) {
-    llvm::ArrayRef<TemplateArgument> pack_args =
-        template_param_infos.GetParameterPackArgs();
-    args.append(pack_args.begin(), pack_args.end());
-  }
-  std::string str;
-  llvm::raw_string_ostream os(str);
-  clang::printTemplateArgumentList(os, args, GetTypePrintingPolicy(),
-                                   template_param_list);
-  return str;
-}
-
 clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
     clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
     clang::FunctionDecl *func_decl,
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index e39aedec7e3902..678eaed381fd49 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -1148,10 +1148,6 @@ class TypeSystemClang : public TypeSystem {
 
   bool SetDeclIsForcefullyCompleted(const clang::TagDecl *td);
 
-  /// Return the template parameters (including surrounding <>) in string form.
-  std::string
-  PrintTemplateParams(const TemplateParameterInfos &template_param_infos);
-
 private:
   /// Returns the PrintingPolicy used when generating the internal type names.
   /// These type names are mostly used for the formatter selection.
diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp
new file mode 100644
index 00000000000000..b1563c5b2ba443
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp
@@ -0,0 +1,31 @@
+// Test lldb is able to compute the fully qualified names on templates with
+// -gsimple-template-names and -fdebug-types-section.
+
+// REQUIRES: lld
+
+// Test against logging to see if we print the fully qualified names correctly.
+// RUN: %clangxx --target=x86_64-pc-linux -g -gsimple-template-names %s -o %t
+// RUN: %lldb %t -o "log enable dwarf comp" -o "target variable v1 v2" -o exit | FileCheck %s --check-prefix=LOG
+
+// Test that we following DW_AT_signature correctly. If not, lldb might confuse the types of v1 and v2.
+// RUN: %clangxx --target=x86_64-pc-linux -g -gsimple-template-names -fdebug-types-section %s -o %t
+// RUN: %lldb %t -o "target variable v1 v2" -o exit | FileCheck %s --check-prefix=TYPE
+
+// LOG: unique name: ::t2<outer_struct1::t1<int> >
+// LOG: unique name: ::t2<outer_struct2::t1<int> >
+
+// TYPE:      (t2<outer_struct1::t1<int> >) v1 = {}
+// TYPE-NEXT: (t2<outer_struct2::t1<int> >) v2 = {}
+
+struct outer_struct1 {
+  template <typename> struct t1 {};
+};
+
+struct outer_struct2 {
+  template <typename> struct t1 {};
+};
+
+template <typename> struct t2 {};
+t2<outer_struct1::t1<int>> v1;
+t2<outer_struct2::t1<int>> v2;
+int main() {}
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
index 69c91835a4d9a1..2e98a4a397147b 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
@@ -226,6 +226,8 @@ class DWARFDie {
 
   bool addressRangeContainsAddress(const uint64_t Address) const;
 
+  std::optional<uint64_t> getLanguage() const;
+
   Expected<DWARFLocationExpressionsVector>
   getLocations(dwarf::Attribute Attr) const;
 
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
index 87e876273c4b97..b6d42f686cd266 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
@@ -11,6 +11,7 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/Support/Error.h"
 
 #include <string>
 
@@ -107,13 +108,11 @@ void DWARFTypePrinter<DieType>::appendArrayType(const DieType &D) {
     if (std::optional<typename DieType::DWARFFormValue> UpperV =
             C.find(dwarf::DW_AT_upper_bound))
       UB = UpperV->getAsUnsignedConstant();
-    if (std::optional<typename DieType::DWARFFormValue> LV =
-            D.getDwarfUnit()->getUnitDIE().find(dwarf::DW_AT_language))
-      if (std::optional<uint64_t> LC = LV->getAsUnsignedConstant())
-        if ((DefaultLB =
-                 LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
-          if (LB && *LB == *DefaultLB)
-            LB = std::nullopt;
+    if (std::optional<uint64_t> LV = D.getLanguage())
+      if ((DefaultLB =
+               LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LV))))
+        if (LB && *LB == *DefaultLB)
+          LB = std::nullopt;
     if (!LB && !Count && !UB)
       OS << "[]";
     else if (!LB && (Count || UB) && DefaultLB)
@@ -150,6 +149,16 @@ template <typename DieType>
 DieType resolveReferencedType(DieType D, typename DieType::DWARFFormValue F) {
   return D.resolveReferencedType(F);
 }
+template <typename DWARFFormValueType>
+const char *toString(std::optional<DWARFFormValueType> F) {
+  if (F) {
+    llvm::Expected<const char *> E = F->getAsCString();
+    if (E)
+      return *E;
+    llvm::consumeError(E.takeError());
+  }
+  return nullptr;
+}
 } // namespace detail
 
 template <typename DieType>
@@ -239,7 +248,7 @@ DieType DWARFTypePrinter<DieType>::appendUnqualifiedNameBefore(
     appendConstVolatileQualifierBefore(D);
     break;
   case dwarf::DW_TAG_namespace: {
-    if (const char *Name = dwarf::toString(D.find(dwarf::DW_AT_name), nullptr))
+    if (const char *Name = detail::toString(D.find(dwarf::DW_AT_name)))
       OS << Name;
     else
       OS << "(anonymous namespace)";
@@ -261,7 +270,7 @@ DieType DWARFTypePrinter<DieType>::appendUnqualifiedNameBefore(
   case DW_TAG_base_type:
   */
   default: {
-    const char *NamePtr = dwarf::toString(D.find(dwarf::DW_AT_name), nullptr);
+    const char *NamePtr = detail::toString(D.find(dwarf::DW_AT_name));
     if (!NamePtr) {
       appendTypeTagName(D.getTag());
       return DieType();
@@ -440,7 +449,7 @@ bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D,
       if (T.getTag() == dwarf::DW_TAG_pointer_type ||
           T.getTag() == dwarf::DW_TAG_reference_type)
         continue;
-      const char *RawName = dwarf::toString(T.find(dwarf::DW_AT_name), nullptr);
+      const char *RawName = detail::toString(T.find(dwarf::DW_AT_name));
       assert(RawName);
       StringRef Name = RawName;
       auto V = C.find(dwarf::DW_AT_const_value);
@@ -533,7 +542,7 @@ bool DWARFTypePrinter<DieType>::appendTemplateParameters(DieType D,
     }
     if (C.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
       const char *RawName =
-          dwarf::toString(C.find(dwarf::DW_AT_GNU_template_name), nullptr);
+          detail::toString(C.find(dwarf::DW_AT_GNU_template_name));
       assert(RawName);
       StringRef Name = RawName;
       Sep();
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 6e7b5870dfa29f..f62526d08e54e8 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -414,6 +414,15 @@ bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
   return false;
 }
 
+std::optional<uint64_t> DWARFDie::getLanguage() const {
+  if (isValid()) {
+    if (std::optional<DWARFFormValue> LV =
+            U->getUnitDIE().find(dwarf::DW_AT_language))
+      return LV->getAsUnsignedConstant();
+  }
+  return std::nullopt;
+}
+
 Expected<DWARFLocationExpressionsVector>
 DWARFDie::getLocations(dwarf::Attribute Attr) const {
   std::optional<DWARFFormValue> Location = find(Attr);

>From 38a459bf14d68041a974e38d91cd054ef27b3276 Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Wed, 6 Nov 2024 16:59:41 -0800
Subject: [PATCH 2/4] Address comments.

---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 22 +++---
 .../Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp | 20 +++---
 .../Plugins/SymbolFile/DWARF/DWARFBaseDIE.h   | 16 ++---
 .../Plugins/SymbolFile/DWARF/DWARFDIE.cpp     | 72 ++++++++++---------
 .../Plugins/SymbolFile/DWARF/DWARFDIE.h       | 34 ++++-----
 .../Plugins/SymbolFile/DWARF/DWARFFormValue.h |  9 ++-
 .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp    |  2 +-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      |  8 +--
 .../llvm/DebugInfo/DWARF/DWARFTypePrinter.h   |  2 +-
 9 files changed, 94 insertions(+), 91 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 41cb11f94a45e8..e6504fb26c42cf 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -96,7 +96,7 @@ static bool IsClangModuleFwdDecl(const DWARFDIE &Die) {
   if (!Die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))
     return false;
   auto Parent = Die.GetParent();
-  while (Parent.IsValid()) {
+  while (Parent) {
     if (Parent.Tag() == DW_TAG_module)
       return true;
     Parent = Parent.GetParent();
@@ -105,11 +105,11 @@ static bool IsClangModuleFwdDecl(const DWARFDIE &Die) {
 }
 
 static DWARFDIE GetContainingClangModuleDIE(const DWARFDIE &die) {
-  if (die.IsValid()) {
+  if (die) {
     DWARFDIE top_module_die;
     // Now make sure this DIE is scoped in a DW_TAG_module tag and return true
     // if so
-    for (DWARFDIE parent = die.GetParent(); parent.IsValid();
+    for (DWARFDIE parent = die.GetParent(); parent;
          parent = parent.GetParent()) {
       const dw_tag_t tag = parent.Tag();
       if (tag == DW_TAG_module)
@@ -124,7 +124,7 @@ static DWARFDIE GetContainingClangModuleDIE(const DWARFDIE &die) {
 }
 
 static lldb::ModuleSP GetContainingClangModule(const DWARFDIE &die) {
-  if (die.IsValid()) {
+  if (die) {
     DWARFDIE clang_module_die = GetContainingClangModuleDIE(die);
 
     if (clang_module_die) {
@@ -1590,7 +1590,7 @@ void DWARFASTParserClang::GetUniqueTypeNameAndDeclaration(
   // For C++, we rely solely upon the one definition rule that says
   // only one thing can exist at a given decl context. We ignore the
   // file and line that things are declared on.
-  if (!die.IsValid() || !Language::LanguageIsCPlusPlus(language) ||
+  if (!die || !Language::LanguageIsCPlusPlus(language) ||
       unique_typename.IsEmpty())
     return;
   decl_declaration.Clear();
@@ -3211,8 +3211,7 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
     // This means 'die' is a C++ static data member.
     // We don't want to create decls for such members
     // here.
-    if (auto parent = die.GetParent();
-        parent.IsValid() && TagIsRecordType(parent.Tag()))
+    if (auto parent = die.GetParent(); parent && TagIsRecordType(parent.Tag()))
       return nullptr;
     break;
   default:
@@ -3351,11 +3350,10 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
 
 OptionalClangModuleID
 DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) {
-  if (!die.IsValid())
+  if (!die)
     return {};
 
-  for (DWARFDIE parent = die.GetParent(); parent.IsValid();
-       parent = parent.GetParent()) {
+  for (DWARFDIE parent = die.GetParent(); parent; parent = parent.GetParent()) {
     const dw_tag_t tag = parent.Tag();
     if (tag == DW_TAG_module) {
       DWARFDIE module_die = parent;
@@ -3596,11 +3594,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
   UniqueCStringMap<DWARFDIE> dst_name_to_die;
   UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
   UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
-  for (DWARFDIE src_die = src_class_die.GetFirstChild(); src_die.IsValid();
+  for (DWARFDIE src_die = src_class_die.GetFirstChild(); src_die;
        src_die = src_die.GetSibling()) {
     gather(src_die, src_name_to_die, src_name_to_die_artificial);
   }
-  for (DWARFDIE dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid();
+  for (DWARFDIE dst_die = dst_class_die.GetFirstChild(); dst_die;
        dst_die = dst_die.GetSibling()) {
     gather(dst_die, dst_name_to_die, dst_name_to_die_artificial);
   }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
index c2ebeed4c860d4..2785c1ea80d919 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -21,7 +21,7 @@ using namespace lldb_private;
 using namespace lldb_private::plugin::dwarf;
 
 std::optional<DIERef> DWARFBaseDIE::GetDIERef() const {
-  if (!IsValid())
+  if (!*this)
     return std::nullopt;
 
   return DIERef(m_cu->GetSymbolFileDWARF().GetFileIndex(),
@@ -37,7 +37,7 @@ dw_tag_t DWARFBaseDIE::Tag() const {
 
 const char *DWARFBaseDIE::GetAttributeValueAsString(const dw_attr_t attr,
                                                 const char *fail_value) const {
-  if (IsValid())
+  if (*this)
     return m_die->GetAttributeValueAsString(GetCU(), attr, fail_value);
   else
     return fail_value;
@@ -45,7 +45,7 @@ const char *DWARFBaseDIE::GetAttributeValueAsString(const dw_attr_t attr,
 
 uint64_t DWARFBaseDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr,
                                                uint64_t fail_value) const {
-  if (IsValid())
+  if (*this)
     return m_die->GetAttributeValueAsUnsigned(GetCU(), attr, fail_value);
   else
     return fail_value;
@@ -53,14 +53,14 @@ uint64_t DWARFBaseDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr,
 
 std::optional<uint64_t>
 DWARFBaseDIE::GetAttributeValueAsOptionalUnsigned(const dw_attr_t attr) const {
-  if (IsValid())
+  if (*this)
     return m_die->GetAttributeValueAsOptionalUnsigned(GetCU(), attr);
   return std::nullopt;
 }
 
 uint64_t DWARFBaseDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
                                               uint64_t fail_value) const {
-  if (IsValid())
+  if (*this)
     return m_die->GetAttributeValueAsAddress(GetCU(), attr, fail_value);
   else
     return fail_value;
@@ -75,7 +75,7 @@ lldb::user_id_t DWARFBaseDIE::GetID() const {
 }
 
 const char *DWARFBaseDIE::GetName() const {
-  if (IsValid())
+  if (*this)
     return m_die->GetName(m_cu);
   else
     return nullptr;
@@ -90,7 +90,7 @@ lldb::ModuleSP DWARFBaseDIE::GetModule() const {
 }
 
 dw_offset_t DWARFBaseDIE::GetOffset() const {
-  if (IsValid())
+  if (*this)
     return m_die->GetOffset();
   else
     return DW_INVALID_OFFSET;
@@ -108,11 +108,11 @@ bool DWARFBaseDIE::HasChildren() const {
 }
 
 bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
-  return IsValid() && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
+  return *this && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
 }
 
 DWARFAttributes DWARFBaseDIE::GetAttributes(Recurse recurse) const {
-  if (IsValid())
+  if (*this)
     return m_die->GetAttributes(m_cu, recurse);
   return DWARFAttributes();
 }
@@ -131,6 +131,6 @@ bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
 
 const DWARFDataExtractor &DWARFBaseDIE::GetData() const {
   // Clients must check if this DIE is valid before calling this function.
-  assert(IsValid());
+  assert(*this);
   return m_cu->GetData();
 }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index ca25801137be38..57bdf22b6a681e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -44,11 +44,7 @@ class DWARFBaseDIE {
       : m_cu(const_cast<DWARFUnit *>(cu)),
         m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
 
-  // Tests
-  explicit operator bool() const { return IsValid(); }
-
-  bool IsValid() const { return m_cu && m_die; }
-  bool isValid() const { return IsValid(); }
+  explicit operator bool() const { return m_cu && m_die; }
 
   bool HasChildren() const;
 
@@ -88,8 +84,6 @@ class DWARFBaseDIE {
   // Accessing information about a DIE
   dw_tag_t Tag() const;
 
-  dw_tag_t getTag() const { return Tag(); }
-
   dw_offset_t GetOffset() const;
 
   // Get the LLDB user ID for this DIE. This is often just the DIE offset,
@@ -100,8 +94,6 @@ class DWARFBaseDIE {
 
   const char *GetName() const;
 
-  const char *getShortName() const { return GetName(); }
-
   lldb::ModuleSP GetModule() const;
 
   // Getting attribute values from the DIE.
@@ -124,6 +116,12 @@ class DWARFBaseDIE {
   enum class Recurse : bool { no, yes };
   DWARFAttributes GetAttributes(Recurse recurse = Recurse::yes) const;
 
+  // The following methods use LLVM naming convension in order to be are used by
+  // LLVM libraries.
+  dw_tag_t getTag() const { return Tag(); }
+
+  const char *getShortName() const { return GetName(); }
+
 protected:
   DWARFUnit *m_cu = nullptr;
   DWARFDebugInfoEntry *m_die = nullptr;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 3b4330c6de31d3..7bcb616a312f51 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -86,15 +86,9 @@ elaborating_dies(const DWARFDIE &die) {
 }
 } // namespace
 
-std::optional<uint64_t> DWARFDIE::getLanguage() const {
-  if (IsValid())
-    return m_cu->GetDWARFLanguageType();
-  return std::nullopt;
-}
-
 DWARFDIE
 DWARFDIE::GetParent() const {
-  if (IsValid())
+  if (*this)
     return DWARFDIE(m_cu, m_die->GetParent());
   else
     return DWARFDIE();
@@ -102,7 +96,7 @@ DWARFDIE::GetParent() const {
 
 DWARFDIE
 DWARFDIE::GetFirstChild() const {
-  if (IsValid())
+  if (*this)
     return DWARFDIE(m_cu, m_die->GetFirstChild());
   else
     return DWARFDIE();
@@ -110,7 +104,7 @@ DWARFDIE::GetFirstChild() const {
 
 DWARFDIE
 DWARFDIE::GetSibling() const {
-  if (IsValid())
+  if (*this)
     return DWARFDIE(m_cu, m_die->GetSibling());
   else
     return DWARFDIE();
@@ -118,31 +112,15 @@ DWARFDIE::GetSibling() const {
 
 DWARFDIE
 DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const {
-  if (IsValid())
+  if (*this)
     return m_die->GetAttributeValueAsReference(GetCU(), attr);
   else
     return {};
 }
 
-DWARFDIE DWARFDIE::resolveReferencedType(dw_attr_t attr) const {
-  return GetReferencedDIE(attr);
-}
-
-DWARFDIE DWARFDIE::resolveReferencedType(DWARFFormValue v) const {
-  if (IsValid())
-    return v.Reference();
-  return {};
-}
-
-DWARFDIE DWARFDIE::resolveTypeUnitReference() const {
-  if (DWARFDIE reference = GetReferencedDIE(DW_AT_signature))
-    return reference;
-  return *this;
-}
-
 DWARFDIE
 DWARFDIE::GetDIE(dw_offset_t die_offset) const {
-  if (IsValid())
+  if (*this)
     return m_cu->GetDIE(die_offset);
   else
     return DWARFDIE();
@@ -150,7 +128,7 @@ DWARFDIE::GetDIE(dw_offset_t die_offset) const {
 
 DWARFDIE
 DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
-  if (IsValid()) {
+  if (*this) {
     DWARFUnit *cu = GetCU();
     const bool check_elaborating_dies = true;
     DWARFFormValue form_value;
@@ -163,7 +141,7 @@ DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
 
 DWARFDIE
 DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
-  if (!IsValid())
+  if (!*this)
     return DWARFDIE();
 
   DWARFDIE result;
@@ -222,14 +200,14 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
 }
 
 const char *DWARFDIE::GetMangledName() const {
-  if (IsValid())
+  if (*this)
     return m_die->GetMangledName(m_cu);
   else
     return nullptr;
 }
 
 const char *DWARFDIE::GetPubname() const {
-  if (IsValid())
+  if (*this)
     return m_die->GetPubname(m_cu);
   else
     return nullptr;
@@ -241,7 +219,7 @@ const char *DWARFDIE::GetPubname() const {
 // stream object. If the DIE is a NULL object "NULL" is placed into the stream,
 // and if no DW_AT_name attribute exists for the DIE then nothing is printed.
 void DWARFDIE::GetName(Stream &s) const {
-  if (!IsValid())
+  if (!*this)
     return;
   if (GetDIE()->IsNULL()) {
     s.PutCString("NULL");
@@ -259,7 +237,7 @@ void DWARFDIE::GetName(Stream &s) const {
 // a fully qualified type name and dump the results to the supplied stream.
 // This is used to show the name of types given a type identifier.
 void DWARFDIE::AppendTypeName(Stream &s) const {
-  if (!IsValid())
+  if (!*this)
     return;
   if (GetDIE()->IsNULL()) {
     s.PutCString("NULL");
@@ -378,7 +356,7 @@ void DWARFDIE::AppendTypeName(Stream &s) const {
 }
 
 lldb_private::Type *DWARFDIE::ResolveType() const {
-  if (IsValid())
+  if (*this)
     return GetDWARF()->ResolveType(*this, true);
   else
     return nullptr;
@@ -586,7 +564,7 @@ bool DWARFDIE::GetDIENamesAndRanges(
     std::optional<int> &decl_column, std::optional<int> &call_file,
     std::optional<int> &call_line, std::optional<int> &call_column,
     lldb_private::DWARFExpressionList *frame_base) const {
-  if (IsValid()) {
+  if (*this) {
     return m_die->GetDIENamesAndRanges(
         GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column,
         call_file, call_line, call_column, frame_base);
@@ -594,6 +572,8 @@ bool DWARFDIE::GetDIENamesAndRanges(
     return false;
 }
 
+// The following methods use LLVM naming convension in order to be are used by
+// LLVM libraries.
 llvm::iterator_range<DWARFDIE::child_iterator> DWARFDIE::children() const {
   return llvm::make_range(child_iterator(*this), child_iterator());
 }
@@ -610,3 +590,25 @@ std::optional<DWARFFormValue> DWARFDIE::find(const dw_attr_t attr) const {
     return form_value;
   return std::nullopt;
 }
+
+std::optional<uint64_t> DWARFDIE::getLanguage() const {
+  if (*this)
+    return m_cu->GetDWARFLanguageType();
+  return std::nullopt;
+}
+
+DWARFDIE DWARFDIE::resolveReferencedType(dw_attr_t attr) const {
+  return GetReferencedDIE(attr);
+}
+
+DWARFDIE DWARFDIE::resolveReferencedType(DWARFFormValue v) const {
+  if (*this)
+    return v.Reference();
+  return {};
+}
+
+DWARFDIE DWARFDIE::resolveTypeUnitReference() const {
+  if (DWARFDIE reference = GetReferencedDIE(DW_AT_signature))
+    return reference;
+  return *this;
+}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 273ac79e453703..a933a89ec993e9 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -44,13 +44,9 @@ class DWARFDIE : public DWARFBaseDIE {
 
   // Functions for obtaining DIE relations and references
 
-  std::optional<uint64_t> getLanguage() const;
-
   DWARFDIE
   GetParent() const;
 
-  DWARFDIE getParent() const { return GetParent(); }
-
   DWARFDIE
   GetFirstChild() const;
 
@@ -60,12 +56,6 @@ class DWARFDIE : public DWARFBaseDIE {
   DWARFDIE
   GetReferencedDIE(const dw_attr_t attr) const;
 
-  DWARFDIE resolveReferencedType(dw_attr_t attr) const;
-
-  DWARFDIE resolveReferencedType(DWARFFormValue v) const;
-
-  DWARFDIE resolveTypeUnitReference() const;
-
   // Get a another DIE from the same DWARF file as this DIE. This will
   // check the current DIE's compile unit first to see if "die_offset" is
   // in the same compile unit, and fall back to checking the DWARF file.
@@ -106,8 +96,6 @@ class DWARFDIE : public DWARFBaseDIE {
   DWARFDIE
   GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
 
-  std::optional<DWARFFormValue> find(const dw_attr_t attr) const;
-
   bool GetDIENamesAndRanges(
       const char *&name, const char *&mangled, DWARFRangeList &ranges,
       std::optional<int> &decl_file, std::optional<int> &decl_line,
@@ -115,6 +103,20 @@ class DWARFDIE : public DWARFBaseDIE {
       std::optional<int> &call_line, std::optional<int> &call_column,
       DWARFExpressionList *frame_base) const;
 
+  // The following methods use LLVM naming convension in order to be are used by
+  // LLVM libraries.
+  std::optional<uint64_t> getLanguage() const;
+
+  DWARFDIE getParent() const { return GetParent(); }
+
+  DWARFDIE resolveReferencedType(dw_attr_t attr) const;
+
+  DWARFDIE resolveReferencedType(DWARFFormValue v) const;
+
+  DWARFDIE resolveTypeUnitReference() const;
+
+  std::optional<DWARFFormValue> find(const dw_attr_t attr) const;
+
   /// The range of all the children of this DIE.
   llvm::iterator_range<child_iterator> children() const;
 
@@ -136,20 +138,20 @@ class DWARFDIE::child_iterator
     // has a CU but no DIE and one that has neither CU nor DIE. The 'end'
     // iterator could be default constructed, so explicitly allow
     // (CU, (DIE)nullptr) == (nullptr, nullptr) -> true
-    if (!m_die.IsValid() && !it.m_die.IsValid())
+    if (!m_die && !it.m_die)
       return true;
     return m_die == it.m_die;
   }
   const DWARFDIE &operator*() const {
-    assert(m_die.IsValid() && "Derefencing invalid iterator?");
+    assert(m_die && "Derefencing invalid iterator?");
     return m_die;
   }
   DWARFDIE &operator*() {
-    assert(m_die.IsValid() && "Derefencing invalid iterator?");
+    assert(m_die && "Derefencing invalid iterator?");
     return m_die;
   }
   child_iterator &operator++() {
-    assert(m_die.IsValid() && "Incrementing invalid iterator?");
+    assert(m_die && "Incrementing invalid iterator?");
     m_die = m_die.GetSibling();
     return *this;
   }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index 66fb6e855f29f8..613948f2f3c9b7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -58,14 +58,11 @@ class DWARFFormValue {
 
   uint64_t Reference(dw_offset_t offset) const;
   bool Boolean() const { return m_value.uval != 0; }
-  std::optional<uint64_t> getAsUnsignedConstant() const;
-  std::optional<int64_t> getAsSignedConstant() const;
   uint64_t Unsigned() const { return m_value.uval; }
   void SetUnsigned(uint64_t uval) { m_value.uval = uval; }
   int64_t Signed() const { return m_value.sval; }
   void SetSigned(int64_t sval) { m_value.sval = sval; }
   const char *AsCString() const;
-  const char *getAsCString() const { return AsCString(); }
   dw_addr_t Address() const;
   bool IsValid() const { return m_form != 0; }
   bool SkipValue(const DWARFDataExtractor &debug_info_data,
@@ -79,6 +76,12 @@ class DWARFFormValue {
   void Clear();
   static bool FormIsSupported(dw_form_t form);
 
+  // The following methods use LLVM naming convension in order to be are used by
+  // LLVM libraries.
+  std::optional<uint64_t> getAsUnsignedConstant() const;
+  std::optional<int64_t> getAsSignedConstant() const;
+  const char *getAsCString() const { return AsCString(); }
+
 protected:
   // Compile unit where m_value was located.
   // It may be different from compile unit where m_value refers to.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 0eb882b0e7d4f5..b8cde0ba44122f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -107,7 +107,7 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() {
   }
 
   DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
-  if (!dwo_cu_die.IsValid()) {
+  if (!dwo_cu_die) {
     // Can't fetch the compile unit DIE from the dwo file.
     SetDwoError(Status::FromErrorStringWithFormatv(
         "unable to extract compile unit DIE from .dwo file for skeleton "
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 40c145c8ff1550..33219d86975960 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -903,7 +903,7 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
 Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
                                          const DWARFDIE &die) {
   ASSERT_MODULE_LOCK(this);
-  if (!die.IsValid())
+  if (!die)
     return nullptr;
 
   auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
@@ -950,7 +950,7 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
 ConstString
 SymbolFileDWARF::ConstructFunctionDemangledName(const DWARFDIE &die) {
   ASSERT_MODULE_LOCK(this);
-  if (!die.IsValid()) {
+  if (!die) {
     return ConstString();
   }
 
@@ -4097,7 +4097,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
       // Extract DW_AT_call_origin (the call target's DIE).
       if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) {
         call_origin = form_value.Reference();
-        if (!call_origin->IsValid()) {
+        if (!*call_origin) {
           LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}",
                    function_die.GetPubname());
           break;
@@ -4212,7 +4212,7 @@ SymbolFileDWARF::ParseCallEdgesInFunction(lldb_private::UserID func_id) {
   // late, because the act of storing results from ParseCallEdgesInFunction
   // would be racy.
   DWARFDIE func_die = GetDIE(func_id.GetID());
-  if (func_die.IsValid())
+  if (func_die)
     return CollectCallEdges(GetObjectFile()->GetModule(), func_die);
   return {};
 }
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
index b6d42f686cd266..962462b8278259 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
@@ -602,7 +602,7 @@ void DWARFTypePrinter<DieType>::appendConstVolatileQualifierAfter(DieType N) {
   decomposeConstVolatile(N, T, C, V);
   if (T && T.getTag() == dwarf::DW_TAG_subroutine_type)
     appendSubroutineNameAfter(T, detail::resolveReferencedType(T), false,
-                              C.isValid(), V.isValid());
+                              static_cast<bool>(C), static_cast<bool>(V));
   else
     appendUnqualifiedNameAfter(T, detail::resolveReferencedType(T));
 }

>From 769c4fb1b9eff2fa1861832872b30877d043d86d Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Thu, 7 Nov 2024 11:56:58 -0800
Subject: [PATCH 3/4] revert removal of DWARFBaseDIE::IsValid() api

---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 22 +++++++-------
 .../Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp | 20 ++++++-------
 .../Plugins/SymbolFile/DWARF/DWARFBaseDIE.h   |  5 +++-
 .../Plugins/SymbolFile/DWARF/DWARFDIE.cpp     | 30 +++++++++----------
 .../Plugins/SymbolFile/DWARF/DWARFDIE.h       |  8 ++---
 .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp    |  2 +-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      |  8 ++---
 7 files changed, 50 insertions(+), 45 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index e6504fb26c42cf..41cb11f94a45e8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -96,7 +96,7 @@ static bool IsClangModuleFwdDecl(const DWARFDIE &Die) {
   if (!Die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))
     return false;
   auto Parent = Die.GetParent();
-  while (Parent) {
+  while (Parent.IsValid()) {
     if (Parent.Tag() == DW_TAG_module)
       return true;
     Parent = Parent.GetParent();
@@ -105,11 +105,11 @@ static bool IsClangModuleFwdDecl(const DWARFDIE &Die) {
 }
 
 static DWARFDIE GetContainingClangModuleDIE(const DWARFDIE &die) {
-  if (die) {
+  if (die.IsValid()) {
     DWARFDIE top_module_die;
     // Now make sure this DIE is scoped in a DW_TAG_module tag and return true
     // if so
-    for (DWARFDIE parent = die.GetParent(); parent;
+    for (DWARFDIE parent = die.GetParent(); parent.IsValid();
          parent = parent.GetParent()) {
       const dw_tag_t tag = parent.Tag();
       if (tag == DW_TAG_module)
@@ -124,7 +124,7 @@ static DWARFDIE GetContainingClangModuleDIE(const DWARFDIE &die) {
 }
 
 static lldb::ModuleSP GetContainingClangModule(const DWARFDIE &die) {
-  if (die) {
+  if (die.IsValid()) {
     DWARFDIE clang_module_die = GetContainingClangModuleDIE(die);
 
     if (clang_module_die) {
@@ -1590,7 +1590,7 @@ void DWARFASTParserClang::GetUniqueTypeNameAndDeclaration(
   // For C++, we rely solely upon the one definition rule that says
   // only one thing can exist at a given decl context. We ignore the
   // file and line that things are declared on.
-  if (!die || !Language::LanguageIsCPlusPlus(language) ||
+  if (!die.IsValid() || !Language::LanguageIsCPlusPlus(language) ||
       unique_typename.IsEmpty())
     return;
   decl_declaration.Clear();
@@ -3211,7 +3211,8 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
     // This means 'die' is a C++ static data member.
     // We don't want to create decls for such members
     // here.
-    if (auto parent = die.GetParent(); parent && TagIsRecordType(parent.Tag()))
+    if (auto parent = die.GetParent();
+        parent.IsValid() && TagIsRecordType(parent.Tag()))
       return nullptr;
     break;
   default:
@@ -3350,10 +3351,11 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
 
 OptionalClangModuleID
 DWARFASTParserClang::GetOwningClangModule(const DWARFDIE &die) {
-  if (!die)
+  if (!die.IsValid())
     return {};
 
-  for (DWARFDIE parent = die.GetParent(); parent; parent = parent.GetParent()) {
+  for (DWARFDIE parent = die.GetParent(); parent.IsValid();
+       parent = parent.GetParent()) {
     const dw_tag_t tag = parent.Tag();
     if (tag == DW_TAG_module) {
       DWARFDIE module_die = parent;
@@ -3594,11 +3596,11 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
   UniqueCStringMap<DWARFDIE> dst_name_to_die;
   UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
   UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
-  for (DWARFDIE src_die = src_class_die.GetFirstChild(); src_die;
+  for (DWARFDIE src_die = src_class_die.GetFirstChild(); src_die.IsValid();
        src_die = src_die.GetSibling()) {
     gather(src_die, src_name_to_die, src_name_to_die_artificial);
   }
-  for (DWARFDIE dst_die = dst_class_die.GetFirstChild(); dst_die;
+  for (DWARFDIE dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid();
        dst_die = dst_die.GetSibling()) {
     gather(dst_die, dst_name_to_die, dst_name_to_die_artificial);
   }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
index 2785c1ea80d919..c2ebeed4c860d4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -21,7 +21,7 @@ using namespace lldb_private;
 using namespace lldb_private::plugin::dwarf;
 
 std::optional<DIERef> DWARFBaseDIE::GetDIERef() const {
-  if (!*this)
+  if (!IsValid())
     return std::nullopt;
 
   return DIERef(m_cu->GetSymbolFileDWARF().GetFileIndex(),
@@ -37,7 +37,7 @@ dw_tag_t DWARFBaseDIE::Tag() const {
 
 const char *DWARFBaseDIE::GetAttributeValueAsString(const dw_attr_t attr,
                                                 const char *fail_value) const {
-  if (*this)
+  if (IsValid())
     return m_die->GetAttributeValueAsString(GetCU(), attr, fail_value);
   else
     return fail_value;
@@ -45,7 +45,7 @@ const char *DWARFBaseDIE::GetAttributeValueAsString(const dw_attr_t attr,
 
 uint64_t DWARFBaseDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr,
                                                uint64_t fail_value) const {
-  if (*this)
+  if (IsValid())
     return m_die->GetAttributeValueAsUnsigned(GetCU(), attr, fail_value);
   else
     return fail_value;
@@ -53,14 +53,14 @@ uint64_t DWARFBaseDIE::GetAttributeValueAsUnsigned(const dw_attr_t attr,
 
 std::optional<uint64_t>
 DWARFBaseDIE::GetAttributeValueAsOptionalUnsigned(const dw_attr_t attr) const {
-  if (*this)
+  if (IsValid())
     return m_die->GetAttributeValueAsOptionalUnsigned(GetCU(), attr);
   return std::nullopt;
 }
 
 uint64_t DWARFBaseDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
                                               uint64_t fail_value) const {
-  if (*this)
+  if (IsValid())
     return m_die->GetAttributeValueAsAddress(GetCU(), attr, fail_value);
   else
     return fail_value;
@@ -75,7 +75,7 @@ lldb::user_id_t DWARFBaseDIE::GetID() const {
 }
 
 const char *DWARFBaseDIE::GetName() const {
-  if (*this)
+  if (IsValid())
     return m_die->GetName(m_cu);
   else
     return nullptr;
@@ -90,7 +90,7 @@ lldb::ModuleSP DWARFBaseDIE::GetModule() const {
 }
 
 dw_offset_t DWARFBaseDIE::GetOffset() const {
-  if (*this)
+  if (IsValid())
     return m_die->GetOffset();
   else
     return DW_INVALID_OFFSET;
@@ -108,11 +108,11 @@ bool DWARFBaseDIE::HasChildren() const {
 }
 
 bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
-  return *this && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
+  return IsValid() && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
 }
 
 DWARFAttributes DWARFBaseDIE::GetAttributes(Recurse recurse) const {
-  if (*this)
+  if (IsValid())
     return m_die->GetAttributes(m_cu, recurse);
   return DWARFAttributes();
 }
@@ -131,6 +131,6 @@ bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
 
 const DWARFDataExtractor &DWARFBaseDIE::GetData() const {
   // Clients must check if this DIE is valid before calling this function.
-  assert(*this);
+  assert(IsValid());
   return m_cu->GetData();
 }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 57bdf22b6a681e..d92de658a49e89 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -44,7 +44,10 @@ class DWARFBaseDIE {
       : m_cu(const_cast<DWARFUnit *>(cu)),
         m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
 
-  explicit operator bool() const { return m_cu && m_die; }
+  // Tests
+  explicit operator bool() const { return IsValid(); }
+
+  bool IsValid() const { return m_cu && m_die; }
 
   bool HasChildren() const;
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 7bcb616a312f51..281876cb429611 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -88,7 +88,7 @@ elaborating_dies(const DWARFDIE &die) {
 
 DWARFDIE
 DWARFDIE::GetParent() const {
-  if (*this)
+  if (IsValid())
     return DWARFDIE(m_cu, m_die->GetParent());
   else
     return DWARFDIE();
@@ -96,7 +96,7 @@ DWARFDIE::GetParent() const {
 
 DWARFDIE
 DWARFDIE::GetFirstChild() const {
-  if (*this)
+  if (IsValid())
     return DWARFDIE(m_cu, m_die->GetFirstChild());
   else
     return DWARFDIE();
@@ -104,7 +104,7 @@ DWARFDIE::GetFirstChild() const {
 
 DWARFDIE
 DWARFDIE::GetSibling() const {
-  if (*this)
+  if (IsValid())
     return DWARFDIE(m_cu, m_die->GetSibling());
   else
     return DWARFDIE();
@@ -112,7 +112,7 @@ DWARFDIE::GetSibling() const {
 
 DWARFDIE
 DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const {
-  if (*this)
+  if (IsValid())
     return m_die->GetAttributeValueAsReference(GetCU(), attr);
   else
     return {};
@@ -120,7 +120,7 @@ DWARFDIE::GetReferencedDIE(const dw_attr_t attr) const {
 
 DWARFDIE
 DWARFDIE::GetDIE(dw_offset_t die_offset) const {
-  if (*this)
+  if (IsValid())
     return m_cu->GetDIE(die_offset);
   else
     return DWARFDIE();
@@ -128,7 +128,7 @@ DWARFDIE::GetDIE(dw_offset_t die_offset) const {
 
 DWARFDIE
 DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
-  if (*this) {
+  if (IsValid()) {
     DWARFUnit *cu = GetCU();
     const bool check_elaborating_dies = true;
     DWARFFormValue form_value;
@@ -141,7 +141,7 @@ DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
 
 DWARFDIE
 DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
-  if (!*this)
+  if (!IsValid())
     return DWARFDIE();
 
   DWARFDIE result;
@@ -200,14 +200,14 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
 }
 
 const char *DWARFDIE::GetMangledName() const {
-  if (*this)
+  if (IsValid())
     return m_die->GetMangledName(m_cu);
   else
     return nullptr;
 }
 
 const char *DWARFDIE::GetPubname() const {
-  if (*this)
+  if (IsValid())
     return m_die->GetPubname(m_cu);
   else
     return nullptr;
@@ -219,7 +219,7 @@ const char *DWARFDIE::GetPubname() const {
 // stream object. If the DIE is a NULL object "NULL" is placed into the stream,
 // and if no DW_AT_name attribute exists for the DIE then nothing is printed.
 void DWARFDIE::GetName(Stream &s) const {
-  if (!*this)
+  if (!IsValid())
     return;
   if (GetDIE()->IsNULL()) {
     s.PutCString("NULL");
@@ -237,7 +237,7 @@ void DWARFDIE::GetName(Stream &s) const {
 // a fully qualified type name and dump the results to the supplied stream.
 // This is used to show the name of types given a type identifier.
 void DWARFDIE::AppendTypeName(Stream &s) const {
-  if (!*this)
+  if (!IsValid())
     return;
   if (GetDIE()->IsNULL()) {
     s.PutCString("NULL");
@@ -356,7 +356,7 @@ void DWARFDIE::AppendTypeName(Stream &s) const {
 }
 
 lldb_private::Type *DWARFDIE::ResolveType() const {
-  if (*this)
+  if (IsValid())
     return GetDWARF()->ResolveType(*this, true);
   else
     return nullptr;
@@ -564,7 +564,7 @@ bool DWARFDIE::GetDIENamesAndRanges(
     std::optional<int> &decl_column, std::optional<int> &call_file,
     std::optional<int> &call_line, std::optional<int> &call_column,
     lldb_private::DWARFExpressionList *frame_base) const {
-  if (*this) {
+  if (IsValid()) {
     return m_die->GetDIENamesAndRanges(
         GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column,
         call_file, call_line, call_column, frame_base);
@@ -592,7 +592,7 @@ std::optional<DWARFFormValue> DWARFDIE::find(const dw_attr_t attr) const {
 }
 
 std::optional<uint64_t> DWARFDIE::getLanguage() const {
-  if (*this)
+  if (IsValid())
     return m_cu->GetDWARFLanguageType();
   return std::nullopt;
 }
@@ -602,7 +602,7 @@ DWARFDIE DWARFDIE::resolveReferencedType(dw_attr_t attr) const {
 }
 
 DWARFDIE DWARFDIE::resolveReferencedType(DWARFFormValue v) const {
-  if (*this)
+  if (IsValid())
     return v.Reference();
   return {};
 }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index a933a89ec993e9..3956450a0c4fd6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -138,20 +138,20 @@ class DWARFDIE::child_iterator
     // has a CU but no DIE and one that has neither CU nor DIE. The 'end'
     // iterator could be default constructed, so explicitly allow
     // (CU, (DIE)nullptr) == (nullptr, nullptr) -> true
-    if (!m_die && !it.m_die)
+    if (!m_die.IsValid() && !it.m_die.IsValid())
       return true;
     return m_die == it.m_die;
   }
   const DWARFDIE &operator*() const {
-    assert(m_die && "Derefencing invalid iterator?");
+    assert(m_die.IsValid() && "Derefencing invalid iterator?");
     return m_die;
   }
   DWARFDIE &operator*() {
-    assert(m_die && "Derefencing invalid iterator?");
+    assert(m_die.IsValid() && "Derefencing invalid iterator?");
     return m_die;
   }
   child_iterator &operator++() {
-    assert(m_die && "Incrementing invalid iterator?");
+    assert(m_die.IsValid() && "Incrementing invalid iterator?");
     m_die = m_die.GetSibling();
     return *this;
   }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index b8cde0ba44122f..0eb882b0e7d4f5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -107,7 +107,7 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() {
   }
 
   DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
-  if (!dwo_cu_die) {
+  if (!dwo_cu_die.IsValid()) {
     // Can't fetch the compile unit DIE from the dwo file.
     SetDwoError(Status::FromErrorStringWithFormatv(
         "unable to extract compile unit DIE from .dwo file for skeleton "
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 33219d86975960..40c145c8ff1550 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -903,7 +903,7 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
 Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
                                          const DWARFDIE &die) {
   ASSERT_MODULE_LOCK(this);
-  if (!die)
+  if (!die.IsValid())
     return nullptr;
 
   auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
@@ -950,7 +950,7 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
 ConstString
 SymbolFileDWARF::ConstructFunctionDemangledName(const DWARFDIE &die) {
   ASSERT_MODULE_LOCK(this);
-  if (!die) {
+  if (!die.IsValid()) {
     return ConstString();
   }
 
@@ -4097,7 +4097,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
       // Extract DW_AT_call_origin (the call target's DIE).
       if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) {
         call_origin = form_value.Reference();
-        if (!*call_origin) {
+        if (!call_origin->IsValid()) {
           LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}",
                    function_die.GetPubname());
           break;
@@ -4212,7 +4212,7 @@ SymbolFileDWARF::ParseCallEdgesInFunction(lldb_private::UserID func_id) {
   // late, because the act of storing results from ParseCallEdgesInFunction
   // would be racy.
   DWARFDIE func_die = GetDIE(func_id.GetID());
-  if (func_die)
+  if (func_die.IsValid())
     return CollectCallEdges(GetObjectFile()->GetModule(), func_die);
   return {};
 }

>From 58605dc5756d885a21c7033821cd9a1b43bf120f Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Thu, 7 Nov 2024 15:03:49 -0800
Subject: [PATCH 4/4] Add a unittest for DWARFTypePrinter and update shell
 test.

---
 .../DWARF/x86/simplified-template-names.cpp   |  11 +-
 .../SymbolFile/DWARF/DWARFDIETest.cpp         | 125 ++++++++++++++++++
 2 files changed, 133 insertions(+), 3 deletions(-)

diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp
index b1563c5b2ba443..bc34b16607cf93 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/simplified-template-names.cpp
@@ -5,14 +5,13 @@
 
 // Test against logging to see if we print the fully qualified names correctly.
 // RUN: %clangxx --target=x86_64-pc-linux -g -gsimple-template-names %s -o %t
-// RUN: %lldb %t -o "log enable dwarf comp" -o "target variable v1 v2" -o exit | FileCheck %s --check-prefix=LOG
+// RUN: %lldb %t -o "log enable dwarf comp" -o "target variable v3" -o exit | FileCheck %s --check-prefix=LOG
 
 // Test that we following DW_AT_signature correctly. If not, lldb might confuse the types of v1 and v2.
 // RUN: %clangxx --target=x86_64-pc-linux -g -gsimple-template-names -fdebug-types-section %s -o %t
 // RUN: %lldb %t -o "target variable v1 v2" -o exit | FileCheck %s --check-prefix=TYPE
 
-// LOG: unique name: ::t2<outer_struct1::t1<int> >
-// LOG: unique name: ::t2<outer_struct2::t1<int> >
+// LOG: unique name: t3<t2<int> >::t4
 
 // TYPE:      (t2<outer_struct1::t1<int> >) v1 = {}
 // TYPE-NEXT: (t2<outer_struct2::t1<int> >) v2 = {}
@@ -28,4 +27,10 @@ struct outer_struct2 {
 template <typename> struct t2 {};
 t2<outer_struct1::t1<int>> v1;
 t2<outer_struct2::t1<int>> v2;
+
+template <typename> struct t3 {
+  struct t4 {};
+};
+t3<t2<int>>::t4 v3;
+
 int main() {}
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
index 1e4c8f3ba07787..ae63e286cc1551 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Symbol/Type.h"
 #include "lldb/lldb-private-enumerations.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -394,3 +395,127 @@ TEST(DWARFDIETest, GetContextInFunction) {
   EXPECT_THAT(foo_struct_die.GetTypeLookupContext(),
               testing::ElementsAre(make_struct("struct_t")));
 }
+
+TEST(DWARFDIETest, TestDWARFTypePrinter) {
+  // Make sure we can get template parameters and qualified names correctly with
+  // DWARFTypePrinter when using -gsimple-template-names.
+
+  // 0x0000000b: DW_TAG_compile_unit
+  // 0x0000000c:   DW_TAG_base_type
+  //                 DW_AT_name      ("int")
+  // 0x00000011:   DW_TAG_structure_type
+  //                 DW_AT_name      ("t1")
+  // 0x00000015:     DW_TAG_template_type_parameter
+  //                   DW_AT_type    (0x0000001f "t3<int>")
+  // 0x0000001a:     DW_TAG_structure_type
+  //                   DW_AT_name    ("t2")
+  // 0x0000001e:     NULL
+  // 0x0000001f:   DW_TAG_structure_type
+  //                 DW_AT_name      ("t3")
+  // 0x00000023:     DW_TAG_template_type_parameter
+  //                   DW_AT_type    (0x0000000c "int")
+  // 0x00000028:     NULL
+  // 0x00000029:   NULL
+  const char *yamldata = R"(
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_386
+DWARF:
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+        - Code:            0x2
+          Tag:             DW_TAG_base_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+        - Code:            0x3
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+        - Code:            0x4
+          Tag:             DW_TAG_template_type_parameter
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+        - Code:            0x5
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+        - Code:            0x6
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+        - Code:            0x7
+          Tag:             DW_TAG_template_type_parameter
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+  debug_info:
+    - Version:         4
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x1
+        - AbbrCode:        0x2
+          Values:
+            - Value:           0xDEADBEEFDEADBEEF
+              CStr:            int
+        - AbbrCode:        0x3
+          Values:
+            - Value:           0xDEADBEEFDEADBEEF
+              CStr:            t1
+        - AbbrCode:        0x4
+          Values:
+            - Value:            0x0000001f # update
+        - AbbrCode:        0x5
+          Values:
+            - Value:           0xDEADBEEFDEADBEEF
+              CStr:            t2
+        - AbbrCode:        0x0
+        - AbbrCode:        0x6
+          Values:
+            - Value:           0xDEADBEEFDEADBEEF
+              CStr:            t3
+        - AbbrCode:        0x7
+          Values:
+            - Value:            0x0000000c # update
+        - AbbrCode:        0x0
+        - AbbrCode:        0x0)";
+  YAMLModuleTester t(yamldata);
+  auto *symbol_file =
+      llvm::cast<SymbolFileDWARF>(t.GetModule()->GetSymbolFile());
+  DWARFUnit *unit = symbol_file->DebugInfo().GetUnitAtIndex(0);
+  std::string debug_str;
+  StreamString debug_os;
+  unit->Dump(&debug_os);
+  ASSERT_TRUE(unit);
+
+  DWARFDIE t1_die = unit->GetDIE(0x11);
+  std::string template_name;
+  llvm::raw_string_ostream template_name_os(template_name);
+  llvm::DWARFTypePrinter<DWARFDIE> template_name_printer(template_name_os);
+  template_name_printer.appendAndTerminateTemplateParameters(t1_die);
+  EXPECT_THAT(template_name, "<t3<int> >");
+
+  DWARFDIE t2_die = unit->GetDIE(0x1a);
+  std::string qualified_name;
+  llvm::raw_string_ostream qualified_name_os(qualified_name);
+  llvm::DWARFTypePrinter<DWARFDIE> qualified_name_printer(qualified_name_os);
+  qualified_name_printer.appendQualifiedName(t2_die);
+  EXPECT_THAT(qualified_name, "t1<t3<int> >::t2");
+}



More information about the lldb-commits mailing list