werat updated this revision to Diff 314558.
werat added a comment.
Herald added a subscriber: JDevlieghere.

Fix formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D94077/new/

https://reviews.llvm.org/D94077

Files:
  lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
  lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
  lldb/test/API/lang/cpp/enum_types/main.cpp
  lldb/test/API/python_api/target/globals/Makefile
  lldb/test/API/python_api/target/globals/TestTargetGlobals.py
  lldb/test/API/python_api/target/globals/main.cpp

Index: lldb/test/API/python_api/target/globals/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/python_api/target/globals/main.cpp
@@ -0,0 +1,14 @@
+enum MyEnum {
+  eFirst,
+};
+MyEnum my_enum;
+
+enum class MyScopedEnum {
+  eFoo = 1,
+  eBar,
+};
+MyScopedEnum my_scoped_enum;
+
+int eFoo = 2;
+
+int main() {}
Index: lldb/test/API/python_api/target/globals/TestTargetGlobals.py
===================================================================
--- /dev/null
+++ lldb/test/API/python_api/target/globals/TestTargetGlobals.py
@@ -0,0 +1,39 @@
+"""
+Test SBTarget::FindGlobalVariables API.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+class TargetAPITestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @add_test_categories(['pyapi'])
+    def test_find_global_variables(self):
+        """Exercise SBTarget.FindGlobalVariables() API."""
+        self.build()
+
+        # Don't need to launch a process, since we're only interested in
+        # looking up global variables.
+        target = self.dbg.CreateTarget(self.getBuildArtifact())
+
+        def test_global_var(query, name, type_name, value):
+            value_list = target.FindGlobalVariables(query, 1)
+            self.assertEqual(value_list.GetSize(), 1)
+            var = value_list.GetValueAtIndex(0)
+            self.DebugSBValue(var)
+            self.assertTrue(var)
+            self.assertEqual(var.GetName(), name)
+            self.assertEqual(var.GetTypeName(), type_name)
+            self.assertEqual(var.GetValue(), value)
+
+        test_global_var("eFirst", "eFirst", "MyEnum", "eFirst")
+
+        # Global variable eFoo is looked up fine, since scoped enumeration
+        # members are not available as constants in the surrounding scope.
+        test_global_var("eFoo", "::eFoo", "int", "2")
+
+        # eBar is not available since it's a member of a scoped enumeration.
+        value_list = target.FindGlobalVariables("eBar", 1)
+        self.assertEqual(value_list.GetSize(), 0)
Index: lldb/test/API/python_api/target/globals/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/python_api/target/globals/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
Index: lldb/test/API/lang/cpp/enum_types/main.cpp
===================================================================
--- lldb/test/API/lang/cpp/enum_types/main.cpp
+++ lldb/test/API/lang/cpp/enum_types/main.cpp
@@ -25,4 +25,14 @@
 DEFINE_UNSIGNED_ENUM(ull, unsigned long long)
 DEFINE_SIGNED_ENUM(ll, signed long long)
 
+enum MyEnum {
+  eFoo = 1,
+};
+MyEnum my_enum = eFoo;
+
+enum class MyScopedEnum {
+  eBar = 1,
+};
+MyScopedEnum my_scoped_enum = MyScopedEnum::eBar;
+
 int main(int argc, char const *argv[]) { return 0; }
Index: lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
===================================================================
--- lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
+++ lldb/test/API/lang/cpp/enum_types/TestCPP11EnumTypes.py
@@ -1,9 +1,7 @@
 """Look up enum type information and check for correct display."""
 
-import lldb
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
-import lldbsuite.test.lldbutil as lldbutil
 
 
 class CPP11EnumTypesTestCase(TestBase):
@@ -51,3 +49,10 @@
         self.check_enum("l")
         self.check_enum("ull")
         self.check_enum("ll")
+
+        self.expect_expr("eFoo", result_type="MyEnum", result_value="eFoo")
+        self.expect_expr("MyEnum::eFoo", result_type="MyEnum", result_value="eFoo")
+        self.expect_expr("my_enum + eFoo + MyEnum::eFoo", result_value="3")
+
+        self.expect("p eBar", error=True,
+                    substrs=["use of undeclared identifier 'eBar'"])
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2115,7 +2115,7 @@
       sc.module_sp = m_objfile_sp->GetModule();
     assert(sc.module_sp);
 
-    if (die.Tag() != DW_TAG_variable)
+    if (die.Tag() != DW_TAG_variable && die.Tag() != DW_TAG_enumerator)
       return true;
 
     auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
@@ -3096,6 +3096,7 @@
   ModuleSP module = GetObjectFile()->GetModule();
 
   if (tag != DW_TAG_variable && tag != DW_TAG_constant &&
+      tag != DW_TAG_enumerator &&
       (tag != DW_TAG_formal_parameter || !sc.function))
     return nullptr;
 
@@ -3106,7 +3107,7 @@
   const char *name = nullptr;
   const char *mangled = nullptr;
   Declaration decl;
-  DWARFFormValue type_die_form;
+  DWARFDIE type_die;
   DWARFExpression location;
   bool is_external = false;
   bool is_artificial = false;
@@ -3138,7 +3139,7 @@
       mangled = form_value.AsCString();
       break;
     case DW_AT_type:
-      type_die_form = form_value;
+      type_die = form_value.Reference();
       break;
     case DW_AT_external:
       is_external = form_value.Boolean();
@@ -3170,6 +3171,11 @@
     }
   }
 
+  // For enumerators the type is their parent (DW_TAG_enumeration_type).
+  if (tag == DW_TAG_enumerator) {
+    type_die = die.GetParent();
+  }
+
   // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
   // for static constexpr member variables -- DW_AT_const_value will be
   // present in the class declaration and DW_AT_location in the DIE defining
@@ -3260,6 +3266,8 @@
 
   if (tag == DW_TAG_formal_parameter)
     scope = eValueTypeVariableArgument;
+  else if (tag == DW_TAG_enumerator)
+    scope = eValueTypeVariableGlobal;
   else {
     // DWARF doesn't specify if a DW_TAG_variable is a local, global
     // or static variable, so we have to do a little digging:
@@ -3401,8 +3409,7 @@
   }
 
   if (symbol_context_scope) {
-    auto type_sp = std::make_shared<SymbolFileType>(
-        *this, GetUID(type_die_form.Reference()));
+    auto type_sp = std::make_shared<SymbolFileType>(*this, GetUID(type_die));
 
     if (use_type_size_for_value && type_sp->GetType())
       location.UpdateValue(
@@ -3499,6 +3506,7 @@
     } else {
       // We haven't already parsed it, lets do that now.
       if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
+          (tag == DW_TAG_enumerator) ||
           (tag == DW_TAG_formal_parameter && sc.function)) {
         if (variable_list_sp.get() == nullptr) {
           DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die);
Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -172,6 +172,7 @@
     bool is_declaration = false;
     // bool is_artificial = false;
     bool has_address = false;
+    bool is_enum_class = false;
     bool has_location_or_const_value = false;
     bool is_global_or_static_variable = false;
 
@@ -192,6 +193,11 @@
             is_declaration = form_value.Unsigned() != 0;
           break;
 
+        case DW_AT_enum_class:
+          if (attributes.ExtractFormValueAtIndex(i, form_value))
+            is_enum_class = form_value.Boolean();
+          break;
+
         case DW_AT_MIPS_linkage_name:
         case DW_AT_linkage_name:
           if (attributes.ExtractFormValueAtIndex(i, form_value))
@@ -295,6 +301,16 @@
         set.types.Insert(ConstString(name), ref);
       if (mangled_cstr && !is_declaration)
         set.types.Insert(ConstString(mangled_cstr), ref);
+      // Unscoped enumerators are basically constants in the surrounding scope.
+      if (tag == DW_TAG_enumeration_type && !is_enum_class) {
+        for (const DWARFDebugInfoEntry *value = die.GetFirstChild();
+             value != nullptr; value = value->GetSibling()) {
+          if (value->Tag() == DW_TAG_enumerator) {
+            DIERef value_ref = DWARFDIE(&unit, value).GetDIERef().getValue();
+            set.globals.Insert(ConstString(value->GetName(&unit)), value_ref);
+          }
+        }
+      }
       break;
 
     case DW_TAG_namespace:
Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
===================================================================
--- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1567,6 +1567,27 @@
       CompleteType(objc_object_ptr_type->getInterfaceDecl());
   }
 
+  // Check if this variable actually represents an unscoped enumeration
+  // constant. They're stored in the index with global variables and thus can be
+  // looked up as a global variable. But the declarations for the enumeration
+  // members (enumerators) are generated during the enumeration type completion,
+  // so adding a declaration for the variable will created a duplicate, leading
+  // to an error like "reference to 'VARNAME' is ambiguous".
+  bool ignore;
+  if (pt.IsEnumerationType(ignore) && !pt.IsScopedEnumerationType()) {
+    bool is_enum_constant = false;
+    pt.ForEachEnumerator([&](const CompilerType &integer_type, ConstString name,
+                             const llvm::APSInt &value) {
+      if (name == var->GetName())
+        is_enum_constant = true;
+      return !is_enum_constant;
+    });
+
+    // Do not create declarations for the variables representing enum constants.
+    if (is_enum_constant)
+      return;
+  }
+
   bool is_reference = pt.IsReferenceType();
 
   NamedDecl *var_decl = nullptr;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to