jankratochvil created this revision.
jankratochvil added reviewers: labath, JDevlieghere, granata.enrico.
jankratochvil added a project: LLDB.
Herald added a subscriber: lldb-commits.

The sanity checking part 
<https://reviews.llvm.org/D66398?id=216585#inline-597273> is improved here to 
use some better error channel than original `llvm::errs()`.
With this patch (and without its `TestDataFormatterAdv.py` fix) one gets:

  runCmd: frame variable int_array
  output: (int [5]) int_array = <Two regexes ("int \[[0-9]+\]" and "int 
\[[0-9]\]") ambiguously match the same string "int [5]".>

I understand one could pass some better abstracted error-reporting interface 
instead of `ValueObject` itself but that would require some more code 
(interface definition, inheritance etc.).
With this alternative patch 
<https://people.redhat.com/jkratoch/regexlistambiguouscheck-module.patch> one 
gets:

  runCmd: frame variable int_array
  output: (int [5]) int_array = ([0] = -1, [1] = 2, [2] = 3, [3] = 4, [4] = 5)
   = no formatter applied
  and on console:
  error: a.out Two regexes ("int \[[0-9]+\]" and "int \[[0-9]\]") ambiguously 
match the same string "int [5]".

But I think the alternative patch is worse than this one - for example maybe 
the variable does not come from a file/module (can it really happen?) and then 
there would be no way to print the error.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D66654

Files:
  lldb/include/lldb/Core/ValueObject.h
  lldb/include/lldb/DataFormatters/FormattersContainer.h
  
lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
  lldb/source/DataFormatters/TypeCategory.cpp

Index: lldb/source/DataFormatters/TypeCategory.cpp
===================================================================
--- lldb/source/DataFormatters/TypeCategory.cpp
+++ lldb/source/DataFormatters/TypeCategory.cpp
@@ -101,9 +101,10 @@
                            lldb::TypeFormatImplSP &entry, uint32_t *reason) {
   if (!IsEnabled() || !IsApplicable(valobj))
     return false;
-  if (GetTypeFormatsContainer()->Get(candidates, entry, reason))
+  if (GetTypeFormatsContainer()->Get(candidates, entry, reason, &valobj))
     return true;
-  bool regex = GetRegexTypeFormatsContainer()->Get(candidates, entry, reason);
+  bool regex =
+      GetRegexTypeFormatsContainer()->Get(candidates, entry, reason, &valobj);
   if (regex && reason)
     *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
   return regex;
@@ -114,9 +115,10 @@
                            lldb::TypeSummaryImplSP &entry, uint32_t *reason) {
   if (!IsEnabled() || !IsApplicable(valobj))
     return false;
-  if (GetTypeSummariesContainer()->Get(candidates, entry, reason))
+  if (GetTypeSummariesContainer()->Get(candidates, entry, reason, &valobj))
     return true;
-  bool regex = GetRegexTypeSummariesContainer()->Get(candidates, entry, reason);
+  bool regex =
+      GetRegexTypeSummariesContainer()->Get(candidates, entry, reason, &valobj);
   if (regex && reason)
     *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
   return regex;
@@ -132,17 +134,19 @@
   bool regex_filter = false;
   // first find both Filter and Synth, and then check which is most recent
 
-  if (!GetTypeFiltersContainer()->Get(candidates, filter_sp, &reason_filter))
+  if (!GetTypeFiltersContainer()->Get(candidates, filter_sp, &reason_filter,
+                                      &valobj))
     regex_filter = GetRegexTypeFiltersContainer()->Get(candidates, filter_sp,
-                                                       &reason_filter);
+                                                       &reason_filter, &valobj);
 
   bool regex_synth = false;
   uint32_t reason_synth = 0;
   bool pick_synth = false;
   ScriptedSyntheticChildren::SharedPointer synth;
-  if (!GetTypeSyntheticsContainer()->Get(candidates, synth, &reason_synth))
-    regex_synth = GetRegexTypeSyntheticsContainer()->Get(candidates, synth,
-                                                         &reason_synth);
+  if (!GetTypeSyntheticsContainer()->Get(candidates, synth, &reason_synth,
+                                         &valobj))
+    regex_synth = GetRegexTypeSyntheticsContainer()->Get(
+        candidates, synth, &reason_synth, &valobj);
   if (!filter_sp.get() && !synth.get())
     return false;
   else if (!filter_sp.get() && synth.get())
@@ -174,10 +178,10 @@
                            lldb::TypeValidatorImplSP &entry, uint32_t *reason) {
   if (!IsEnabled())
     return false;
-  if (GetTypeValidatorsContainer()->Get(candidates, entry, reason))
+  if (GetTypeValidatorsContainer()->Get(candidates, entry, reason, &valobj))
     return true;
-  bool regex =
-      GetRegexTypeValidatorsContainer()->Get(candidates, entry, reason);
+  bool regex = GetRegexTypeValidatorsContainer()->Get(candidates, entry, reason,
+                                                      &valobj);
   if (regex && reason)
     *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
   return regex;
@@ -295,7 +299,8 @@
   TypeValidatorImpl::SharedPointer validator_sp;
 
   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue) {
-    if (GetTypeFormatsContainer()->Get(type_name, format_sp)) {
+    if (GetTypeFormatsContainer()->Get(type_name, format_sp,
+                                       nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -305,7 +310,8 @@
   }
   if ((items & eFormatCategoryItemRegexValue) ==
       eFormatCategoryItemRegexValue) {
-    if (GetRegexTypeFormatsContainer()->Get(type_name, format_sp)) {
+    if (GetRegexTypeFormatsContainer()->Get(type_name, format_sp,
+                                            nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -315,7 +321,8 @@
   }
 
   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary) {
-    if (GetTypeSummariesContainer()->Get(type_name, summary_sp)) {
+    if (GetTypeSummariesContainer()->Get(type_name, summary_sp,
+                                         nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -325,7 +332,8 @@
   }
   if ((items & eFormatCategoryItemRegexSummary) ==
       eFormatCategoryItemRegexSummary) {
-    if (GetRegexTypeSummariesContainer()->Get(type_name, summary_sp)) {
+    if (GetRegexTypeSummariesContainer()->Get(type_name, summary_sp,
+                                              nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -335,7 +343,8 @@
   }
 
   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter) {
-    if (GetTypeFiltersContainer()->Get(type_name, filter_sp)) {
+    if (GetTypeFiltersContainer()->Get(type_name, filter_sp,
+                                       nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -345,7 +354,8 @@
   }
   if ((items & eFormatCategoryItemRegexFilter) ==
       eFormatCategoryItemRegexFilter) {
-    if (GetRegexTypeFiltersContainer()->Get(type_name, filter_sp)) {
+    if (GetRegexTypeFiltersContainer()->Get(type_name, filter_sp,
+                                            nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -355,7 +365,8 @@
   }
 
   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth) {
-    if (GetTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
+    if (GetTypeSyntheticsContainer()->Get(type_name, synth_sp,
+                                          nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -365,7 +376,8 @@
   }
   if ((items & eFormatCategoryItemRegexSynth) ==
       eFormatCategoryItemRegexSynth) {
-    if (GetRegexTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
+    if (GetRegexTypeSyntheticsContainer()->Get(type_name, synth_sp,
+                                               nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -375,7 +387,8 @@
   }
 
   if ((items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator) {
-    if (GetTypeValidatorsContainer()->Get(type_name, validator_sp)) {
+    if (GetTypeValidatorsContainer()->Get(type_name, validator_sp,
+                                          nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -385,7 +398,8 @@
   }
   if ((items & eFormatCategoryItemRegexValidator) ==
       eFormatCategoryItemRegexValidator) {
-    if (GetRegexTypeValidatorsContainer()->Get(type_name, validator_sp)) {
+    if (GetRegexTypeValidatorsContainer()->Get(type_name, validator_sp,
+                                               nullptr /*valobj*/)) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
Index: lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
+++ lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
@@ -130,6 +130,10 @@
         self.expect("frame variable int_array",
                     substrs=['1,2'])
 
+        # "int []" gets converted by FixArrayTypeNameWithRegex into "int \[[0-9]+\]"
+        # which becomes ambiguous for some string against "int \[[0-9]\]".
+        self.runCmd("type summary clear")
+
         self.runCmd(
             'type summary add --summary-string \"${var[0-1]}\" "int []"')
 
Index: lldb/include/lldb/DataFormatters/FormattersContainer.h
===================================================================
--- lldb/include/lldb/DataFormatters/FormattersContainer.h
+++ lldb/include/lldb/DataFormatters/FormattersContainer.h
@@ -204,8 +204,8 @@
     return ret;
   }
 
-  bool Get(ConstString type, MapValueType &entry) {
-    return Get_Impl(type, entry, static_cast<KeyType *>(nullptr));
+  bool Get(ConstString type, MapValueType &entry, ValueObject *valobj) {
+    return Get_Impl(type, entry, valobj, static_cast<KeyType *>(nullptr));
   }
 
   bool GetExact(ConstString type, MapValueType &entry) {
@@ -262,13 +262,15 @@
     return false;
   }
 
-  bool Get_Impl(ConstString type, MapValueType &entry, ConstString *dummy) {
+  bool Get_Impl(ConstString type, MapValueType &entry, ValueObject *valobj,
+                ConstString *dummy) {
     return m_format_map.Get(type, entry);
   }
 
   bool GetExact_Impl(ConstString type, MapValueType &entry,
                      ConstString *dummy) {
-    return Get_Impl(type, entry, static_cast<KeyType *>(nullptr));
+    return Get_Impl(type, entry, nullptr /*valobj*/,
+                    static_cast<KeyType *>(nullptr));
   }
 
   lldb::TypeNameSpecifierImplSP
@@ -291,19 +293,31 @@
         new TypeNameSpecifierImpl(regex->GetText().str().c_str(), true));
   }
 
-  bool Get_Impl(ConstString key, MapValueType &value,
+  bool Get_Impl(ConstString key, MapValueType &value, ValueObject *valobj,
                 lldb::RegularExpressionSP *dummy) {
     llvm::StringRef key_str = key.GetStringRef();
     std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
     MapIterator pos, end = m_format_map.map().end();
+    MapIterator found = end;
     for (pos = m_format_map.map().begin(); pos != end; pos++) {
       lldb::RegularExpressionSP regex = pos->first;
       if (regex->Execute(key_str)) {
-        value = pos->second;
-        return true;
+        if (found != end) {
+          if (valobj)
+            valobj->SetError(Status("Two regexes (\"%s\" and \"%s\") "
+                                    "ambiguously match the same string \"%s\".",
+                                    found->first->GetText().str().c_str(),
+                                    regex->GetText().str().c_str(),
+                                    key.GetCString()));
+          return false;
+        }
+        found = pos;
       }
     }
-    return false;
+    if (found == end)
+      return false;
+    value = found->second;
+    return true;
   }
 
   bool GetExact_Impl(ConstString key, MapValueType &value,
@@ -321,9 +335,9 @@
   }
 
   bool Get(const FormattersMatchVector &candidates, MapValueType &entry,
-           uint32_t *reason) {
+           uint32_t *reason, ValueObject *valobj) {
     for (const FormattersMatchCandidate &candidate : candidates) {
-      if (Get(candidate.GetTypeName(), entry)) {
+      if (Get(candidate.GetTypeName(), entry, valobj)) {
         if (candidate.IsMatch(entry) == false) {
           entry.reset();
           continue;
Index: lldb/include/lldb/Core/ValueObject.h
===================================================================
--- lldb/include/lldb/Core/ValueObject.h
+++ lldb/include/lldb/Core/ValueObject.h
@@ -456,6 +456,8 @@
   // The functions below should NOT be modified by subclasses
   const Status &GetError();
 
+  void SetError(Status &&error) { m_error = std::move(error); }
+
   ConstString GetName() const;
 
   virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to