jankratochvil updated this revision to Diff 217053.

Repository:
  rLLDB LLDB

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

https://reviews.llvm.org/D66654

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

Index: lldb/source/DataFormatters/TypeCategory.cpp
===================================================================
--- lldb/source/DataFormatters/TypeCategory.cpp
+++ lldb/source/DataFormatters/TypeCategory.cpp
@@ -101,12 +101,22 @@
                            lldb::TypeFormatImplSP &entry, uint32_t *reason) {
   if (!IsEnabled() || !IsApplicable(valobj))
     return false;
-  if (GetTypeFormatsContainer()->Get(candidates, entry, reason))
+  llvm::Expected<bool> plain =
+      GetTypeFormatsContainer()->Get(candidates, entry, reason);
+  if (plain && *plain)
     return true;
-  bool regex = GetRegexTypeFormatsContainer()->Get(candidates, entry, reason);
-  if (regex && reason)
-    *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
-  return regex;
+  llvm::Expected<bool> regex =
+      GetRegexTypeFormatsContainer()->Get(candidates, entry, reason);
+  if (regex && *regex) {
+    FormatDropExpected(std::move(plain));
+    if (reason)
+      *reason |=
+          lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
+    return true;
+  }
+  valobj.TakeError(std::move(plain));
+  valobj.TakeError(std::move(regex));
+  return false;
 }
 
 bool TypeCategoryImpl::Get(ValueObject &valobj,
@@ -114,12 +124,22 @@
                            lldb::TypeSummaryImplSP &entry, uint32_t *reason) {
   if (!IsEnabled() || !IsApplicable(valobj))
     return false;
-  if (GetTypeSummariesContainer()->Get(candidates, entry, reason))
+  llvm::Expected<bool> plain =
+      GetTypeSummariesContainer()->Get(candidates, entry, reason);
+  if (plain && *plain)
+    return true;
+  llvm::Expected<bool> regex =
+      GetRegexTypeSummariesContainer()->Get(candidates, entry, reason);
+  if (regex && *regex) {
+    FormatDropExpected(std::move(plain));
+    if (reason)
+      *reason |=
+          lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
     return true;
-  bool regex = GetRegexTypeSummariesContainer()->Get(candidates, entry, reason);
-  if (regex && reason)
-    *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
-  return regex;
+  }
+  valobj.TakeError(std::move(plain));
+  valobj.TakeError(std::move(regex));
+  return false;
 }
 
 bool TypeCategoryImpl::Get(ValueObject &valobj,
@@ -132,20 +152,38 @@
   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))
-    regex_filter = GetRegexTypeFiltersContainer()->Get(candidates, filter_sp,
-                                                       &reason_filter);
+  llvm::Expected<bool> error_filter_regex(false);
+  llvm::Expected<bool> error_filter_plain =
+      GetTypeFiltersContainer()->Get(candidates, filter_sp, &reason_filter);
+  if (!error_filter_plain || !*error_filter_plain) {
+    FormatDropExpected(std::move(error_filter_regex));
+    error_filter_regex = GetRegexTypeFiltersContainer()->Get(
+        candidates, filter_sp, &reason_filter);
+    if (error_filter_regex && *error_filter_regex)
+      regex_filter = true;
+  }
 
   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 (!filter_sp.get() && !synth.get())
+  llvm::Expected<bool> error_synth_regex(false);
+  llvm::Expected<bool> error_synth_plain =
+      GetTypeSyntheticsContainer()->Get(candidates, synth, &reason_synth);
+  if (!error_synth_plain || !*error_synth_plain) {
+    FormatDropExpected(std::move(error_synth_regex));
+    error_synth_regex = GetRegexTypeSyntheticsContainer()->Get(
+        candidates, synth, &reason_synth);
+    if (error_synth_regex && *error_synth_regex)
+      regex_synth = true;
+  }
+  if (!filter_sp.get() && !synth.get()) {
+    valobj.TakeError(std::move(error_filter_plain));
+    valobj.TakeError(std::move(error_filter_regex));
+    valobj.TakeError(std::move(error_synth_plain));
+    valobj.TakeError(std::move(error_synth_regex));
     return false;
-  else if (!filter_sp.get() && synth.get())
+  } else if (!filter_sp.get() && synth.get())
     pick_synth = true;
 
   else if (filter_sp.get() && !synth.get())
@@ -155,18 +193,22 @@
   {
     pick_synth = filter_sp->GetRevision() <= synth->GetRevision();
   }
+
+  FormatDropExpected(std::move(error_filter_plain));
+  FormatDropExpected(std::move(error_filter_regex));
+  FormatDropExpected(std::move(error_synth_plain));
+  FormatDropExpected(std::move(error_synth_regex));
+
   if (pick_synth) {
     if (regex_synth && reason)
       *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
     entry = synth;
-    return true;
   } else {
     if (regex_filter && reason)
       *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
     entry = filter_sp;
-    return true;
   }
-  return false;
+  return true;
 }
 
 bool TypeCategoryImpl::Get(ValueObject &valobj,
@@ -174,13 +216,22 @@
                            lldb::TypeValidatorImplSP &entry, uint32_t *reason) {
   if (!IsEnabled())
     return false;
-  if (GetTypeValidatorsContainer()->Get(candidates, entry, reason))
+  llvm::Expected<bool> plain =
+      GetTypeValidatorsContainer()->Get(candidates, entry, reason);
+  if (plain && *plain)
     return true;
-  bool regex =
+  llvm::Expected<bool> regex =
       GetRegexTypeValidatorsContainer()->Get(candidates, entry, reason);
-  if (regex && reason)
-    *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
-  return regex;
+  if (regex && *regex) {
+    FormatDropExpected(std::move(plain));
+    if (reason)
+      *reason |=
+          lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
+    return true;
+  }
+  valobj.TakeError(std::move(plain));
+  valobj.TakeError(std::move(regex));
+  return false;
 }
 
 void TypeCategoryImpl::Clear(FormatCategoryItems items) {
@@ -295,7 +346,8 @@
   TypeValidatorImpl::SharedPointer validator_sp;
 
   if ((items & eFormatCategoryItemValue) == eFormatCategoryItemValue) {
-    if (GetTypeFormatsContainer()->Get(type_name, format_sp)) {
+    if (FormatDropExpected(
+            GetTypeFormatsContainer()->Get(type_name, format_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -305,7 +357,8 @@
   }
   if ((items & eFormatCategoryItemRegexValue) ==
       eFormatCategoryItemRegexValue) {
-    if (GetRegexTypeFormatsContainer()->Get(type_name, format_sp)) {
+    if (FormatDropExpected(
+            GetRegexTypeFormatsContainer()->Get(type_name, format_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -315,7 +368,8 @@
   }
 
   if ((items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary) {
-    if (GetTypeSummariesContainer()->Get(type_name, summary_sp)) {
+    if (FormatDropExpected(
+            GetTypeSummariesContainer()->Get(type_name, summary_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -325,7 +379,8 @@
   }
   if ((items & eFormatCategoryItemRegexSummary) ==
       eFormatCategoryItemRegexSummary) {
-    if (GetRegexTypeSummariesContainer()->Get(type_name, summary_sp)) {
+    if (FormatDropExpected(
+            GetRegexTypeSummariesContainer()->Get(type_name, summary_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -335,7 +390,8 @@
   }
 
   if ((items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter) {
-    if (GetTypeFiltersContainer()->Get(type_name, filter_sp)) {
+    if (FormatDropExpected(
+            GetTypeFiltersContainer()->Get(type_name, filter_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -345,7 +401,8 @@
   }
   if ((items & eFormatCategoryItemRegexFilter) ==
       eFormatCategoryItemRegexFilter) {
-    if (GetRegexTypeFiltersContainer()->Get(type_name, filter_sp)) {
+    if (FormatDropExpected(
+            GetRegexTypeFiltersContainer()->Get(type_name, filter_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -355,7 +412,8 @@
   }
 
   if ((items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth) {
-    if (GetTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
+    if (FormatDropExpected(
+            GetTypeSyntheticsContainer()->Get(type_name, synth_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -365,7 +423,8 @@
   }
   if ((items & eFormatCategoryItemRegexSynth) ==
       eFormatCategoryItemRegexSynth) {
-    if (GetRegexTypeSyntheticsContainer()->Get(type_name, synth_sp)) {
+    if (FormatDropExpected(
+            GetRegexTypeSyntheticsContainer()->Get(type_name, synth_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -375,7 +434,8 @@
   }
 
   if ((items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator) {
-    if (GetTypeValidatorsContainer()->Get(type_name, validator_sp)) {
+    if (FormatDropExpected(
+            GetTypeValidatorsContainer()->Get(type_name, validator_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -385,7 +445,8 @@
   }
   if ((items & eFormatCategoryItemRegexValidator) ==
       eFormatCategoryItemRegexValidator) {
-    if (GetRegexTypeValidatorsContainer()->Get(type_name, validator_sp)) {
+    if (FormatDropExpected(
+            GetRegexTypeValidatorsContainer()->Get(type_name, validator_sp))) {
       if (matching_category)
         *matching_category = m_name.GetCString();
       if (matching_type)
@@ -403,11 +464,11 @@
 
   if (type_sp) {
     if (type_sp->IsRegex())
-      GetRegexTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),
-                                               retval);
+      FormatDropExpected(GetRegexTypeFormatsContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
     else
-      GetTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),
-                                          retval);
+      FormatDropExpected(GetTypeFormatsContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
   }
 
   return retval;
@@ -419,11 +480,11 @@
 
   if (type_sp) {
     if (type_sp->IsRegex())
-      GetRegexTypeSummariesContainer()->GetExact(
-          ConstString(type_sp->GetName()), retval);
+      FormatDropExpected(GetRegexTypeSummariesContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
     else
-      GetTypeSummariesContainer()->GetExact(ConstString(type_sp->GetName()),
-                                            retval);
+      FormatDropExpected(GetTypeSummariesContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
   }
 
   return retval;
@@ -435,11 +496,11 @@
 
   if (type_sp) {
     if (type_sp->IsRegex())
-      GetRegexTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),
-                                               retval);
+      FormatDropExpected(GetRegexTypeFiltersContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
     else
-      GetTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),
-                                          retval);
+      FormatDropExpected(GetTypeFiltersContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
   }
 
   return retval;
@@ -451,11 +512,11 @@
 
   if (type_sp) {
     if (type_sp->IsRegex())
-      GetRegexTypeSyntheticsContainer()->GetExact(
-          ConstString(type_sp->GetName()), retval);
+      FormatDropExpected(GetRegexTypeSyntheticsContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
     else
-      GetTypeSyntheticsContainer()->GetExact(ConstString(type_sp->GetName()),
-                                             retval);
+      FormatDropExpected(GetTypeSyntheticsContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
   }
 
   return retval;
@@ -467,11 +528,11 @@
 
   if (type_sp) {
     if (type_sp->IsRegex())
-      GetRegexTypeValidatorsContainer()->GetExact(
-          ConstString(type_sp->GetName()), retval);
+      FormatDropExpected(GetRegexTypeValidatorsContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
     else
-      GetTypeValidatorsContainer()->GetExact(ConstString(type_sp->GetName()),
-                                             retval);
+      FormatDropExpected(GetTypeValidatorsContainer()->GetExact(
+          ConstString(type_sp->GetName()), retval));
   }
 
   return retval;
Index: lldb/source/DataFormatters/FormatClasses.cpp
===================================================================
--- lldb/source/DataFormatters/FormatClasses.cpp
+++ lldb/source/DataFormatters/FormatClasses.cpp
@@ -47,3 +47,34 @@
 lldb::DynamicValueType FormattersMatchData::GetDynamicValueType() {
   return m_dynamic_value_type;
 }
+
+char FormatDupError::ID = 0;
+
+FormatDupError::FormatDupError(RegularExpressionSP regex1,
+                               RegularExpressionSP regex2, ConstString str)
+    : m_regex1(std::move(regex1)), m_regex2(std::move(regex2)), m_str(str) {}
+
+void FormatDupError::log(llvm::raw_ostream &OS) const {
+  OS << llvm::formatv("Two regexes (\"{0}\" and \"{1}\") ambiguously match the "
+                      "same string \"{2}\".",
+                      m_regex1->GetText(), m_regex2->GetText(), m_str);
+}
+std::error_code FormatDupError::convertToErrorCode() const {
+  return llvm::inconvertibleErrorCode();
+}
+
+/// FormatDropExpected returns whether function succeeded, dropping the error
+/// code even if it failed. Call ValueObject::TakeError() if possible.
+///
+/// \param e confusingly evaluates as true even if it is a false return from
+//         function:
+///   |  retval &&  *retval | true return.                                     |
+///   |  retval && !*retval | false return with no error code reported.        |
+///   | !retval             | false return with error code retval.takeError(). |
+bool lldb_private::FormatDropExpected(llvm::Expected<bool> &&e) {
+  if (e)
+    return *e;
+  llvm::handleAllErrors(e.takeError(),
+                        [&](std::unique_ptr<FormatDupError> E) {});
+  return false;
+}
Index: lldb/source/API/SBTypeCategory.cpp
===================================================================
--- lldb/source/API/SBTypeCategory.cpp
+++ lldb/source/API/SBTypeCategory.cpp
@@ -199,11 +199,11 @@
   lldb::TypeFilterImplSP children_sp;
 
   if (spec.IsRegex())
-    m_opaque_sp->GetRegexTypeFiltersContainer()->GetExact(
-        ConstString(spec.GetName()), children_sp);
+    FormatDropExpected(m_opaque_sp->GetRegexTypeFiltersContainer()->GetExact(
+        ConstString(spec.GetName()), children_sp));
   else
-    m_opaque_sp->GetTypeFiltersContainer()->GetExact(
-        ConstString(spec.GetName()), children_sp);
+    FormatDropExpected(m_opaque_sp->GetTypeFiltersContainer()->GetExact(
+        ConstString(spec.GetName()), children_sp));
 
   if (!children_sp)
     return LLDB_RECORD_RESULT(lldb::SBTypeFilter());
@@ -226,11 +226,11 @@
   lldb::TypeFormatImplSP format_sp;
 
   if (spec.IsRegex())
-    m_opaque_sp->GetRegexTypeFormatsContainer()->GetExact(
-        ConstString(spec.GetName()), format_sp);
+    FormatDropExpected(m_opaque_sp->GetRegexTypeFormatsContainer()->GetExact(
+        ConstString(spec.GetName()), format_sp));
   else
-    m_opaque_sp->GetTypeFormatsContainer()->GetExact(
-        ConstString(spec.GetName()), format_sp);
+    FormatDropExpected(m_opaque_sp->GetTypeFormatsContainer()->GetExact(
+        ConstString(spec.GetName()), format_sp));
 
   if (!format_sp)
     return LLDB_RECORD_RESULT(lldb::SBTypeFormat());
@@ -251,11 +251,11 @@
   lldb::TypeSummaryImplSP summary_sp;
 
   if (spec.IsRegex())
-    m_opaque_sp->GetRegexTypeSummariesContainer()->GetExact(
-        ConstString(spec.GetName()), summary_sp);
+    FormatDropExpected(m_opaque_sp->GetRegexTypeSummariesContainer()->GetExact(
+        ConstString(spec.GetName()), summary_sp));
   else
-    m_opaque_sp->GetTypeSummariesContainer()->GetExact(
-        ConstString(spec.GetName()), summary_sp);
+    FormatDropExpected(m_opaque_sp->GetTypeSummariesContainer()->GetExact(
+        ConstString(spec.GetName()), summary_sp));
 
   if (!summary_sp)
     return LLDB_RECORD_RESULT(lldb::SBTypeSummary());
@@ -276,11 +276,11 @@
   lldb::SyntheticChildrenSP children_sp;
 
   if (spec.IsRegex())
-    m_opaque_sp->GetRegexTypeSyntheticsContainer()->GetExact(
-        ConstString(spec.GetName()), children_sp);
+    FormatDropExpected(m_opaque_sp->GetRegexTypeSyntheticsContainer()->GetExact(
+        ConstString(spec.GetName()), children_sp));
   else
-    m_opaque_sp->GetTypeSyntheticsContainer()->GetExact(
-        ConstString(spec.GetName()), children_sp);
+    FormatDropExpected(m_opaque_sp->GetTypeSyntheticsContainer()->GetExact(
+        ConstString(spec.GetName()), children_sp));
 
   if (!children_sp)
     return LLDB_RECORD_RESULT(lldb::SBTypeSynthetic());
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,11 +204,13 @@
     return ret;
   }
 
-  bool Get(ConstString type, MapValueType &entry) {
+  // See FormatDropExpected how to handle the return value.
+  llvm::Expected<bool> Get(ConstString type, MapValueType &entry) {
     return Get_Impl(type, entry, static_cast<KeyType *>(nullptr));
   }
 
-  bool GetExact(ConstString type, MapValueType &entry) {
+  // See FormatDropExpected how to handle the return value.
+  llvm::Expected<bool> GetExact(ConstString type, MapValueType &entry) {
     return GetExact_Impl(type, entry, static_cast<KeyType *>(nullptr));
   }
 
@@ -262,12 +264,15 @@
     return false;
   }
 
-  bool Get_Impl(ConstString type, MapValueType &entry, ConstString *dummy) {
+  // See FormatDropExpected how to handle the return value.
+  llvm::Expected<bool> Get_Impl(ConstString type, MapValueType &entry,
+                                ConstString *dummy) {
     return m_format_map.Get(type, entry);
   }
 
-  bool GetExact_Impl(ConstString type, MapValueType &entry,
-                     ConstString *dummy) {
+  // See FormatDropExpected how to handle the return value.
+  llvm::Expected<bool> GetExact_Impl(ConstString type, MapValueType &entry,
+                                     ConstString *dummy) {
     return Get_Impl(type, entry, static_cast<KeyType *>(nullptr));
   }
 
@@ -291,19 +296,25 @@
         new TypeNameSpecifierImpl(regex->GetText().str().c_str(), true));
   }
 
-  bool Get_Impl(ConstString key, MapValueType &value,
-                lldb::RegularExpressionSP *dummy) {
+  // See FormatDropExpected how to handle the return value.
+  llvm::Expected<bool> Get_Impl(ConstString key, MapValueType &value,
+                                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)
+          return llvm::make_error<FormatDupError>(found->first, regex, key);
+        found = pos;
       }
     }
-    return false;
+    if (found == end)
+      return false;
+    value = found->second;
+    return true;
   }
 
   bool GetExact_Impl(ConstString key, MapValueType &value,
@@ -320,21 +331,28 @@
     return false;
   }
 
-  bool Get(const FormattersMatchVector &candidates, MapValueType &entry,
-           uint32_t *reason) {
+  // See FormatDropExpected how to handle the return value.
+  llvm::Expected<bool> Get(const FormattersMatchVector &candidates,
+                           MapValueType &entry, uint32_t *reason) {
+    llvm::Expected<bool> retval(false);
     for (const FormattersMatchCandidate &candidate : candidates) {
-      if (Get(candidate.GetTypeName(), entry)) {
+      llvm::Expected<bool> got = Get(candidate.GetTypeName(), entry);
+      if (!got) {
+        FormatDropExpected(std::move(retval));
+        retval = std::move(got);
+      } else if (*got) {
         if (candidate.IsMatch(entry) == false) {
           entry.reset();
           continue;
         } else {
           if (reason)
             *reason = candidate.GetReason();
+          FormatDropExpected(std::move(retval));
           return true;
         }
       }
     }
-    return false;
+    return retval;
   }
 };
 
Index: lldb/include/lldb/DataFormatters/FormatClasses.h
===================================================================
--- lldb/include/lldb/DataFormatters/FormatClasses.h
+++ lldb/include/lldb/DataFormatters/FormatClasses.h
@@ -160,6 +160,24 @@
   DISALLOW_COPY_AND_ASSIGN(TypeNameSpecifierImpl);
 };
 
+class FormatDupError : public llvm::ErrorInfo<FormatDupError> {
+public:
+  static char ID;
+
+  FormatDupError(lldb::RegularExpressionSP regex1,
+                 lldb::RegularExpressionSP regex2, ConstString str);
+
+  void log(llvm::raw_ostream &OS) const override;
+
+  std::error_code convertToErrorCode() const override;
+
+private:
+  lldb::RegularExpressionSP m_regex1, m_regex2;
+  ConstString m_str;
+};
+
+bool FormatDropExpected(llvm::Expected<bool> &&e);
+
 } // namespace lldb_private
 
 #endif // lldb_FormatClasses_h_
Index: lldb/include/lldb/Core/ValueObject.h
===================================================================
--- lldb/include/lldb/Core/ValueObject.h
+++ lldb/include/lldb/Core/ValueObject.h
@@ -456,6 +456,12 @@
   // The functions below should NOT be modified by subclasses
   const Status &GetError();
 
+  // Store error from Expected<> parameter unless some error is already stored.
+  template <class T> void TakeError(llvm::Expected<T> &&e) {
+    if (!e && !GetError().Fail())
+      m_error = Status(e.takeError());
+  }
+
   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