[lldb] Process formatters in reverse-chronological order
authorJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 20 Sep 2019 20:19:18 +0000 (20:19 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 20 Sep 2019 20:19:18 +0000 (20:19 +0000)
If one reverts D66398 then the TestDataFormatterStdList does fail - as the C++
formatters are initialized in the opposite order. But the current state of
trunk does not mind the order for C++ formatters.

It is using now a single std::vector as suggested by Pavel Labath.

Differential Revision: https://reviews.llvm.org/D66654

llvm-svn: 372424

lldb/include/lldb/DataFormatters/FormattersContainer.h
lldb/include/lldb/Utility/RegularExpression.h
lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py

index 0791028..de2edb1 100644 (file)
@@ -65,7 +65,7 @@ template <typename KeyType, typename ValueType> class FormattersContainer;
 template <typename KeyType, typename ValueType> class FormatMap {
 public:
   typedef typename ValueType::SharedPointer ValueSP;
-  typedef std::map<KeyType, ValueSP> MapType;
+  typedef std::vector<std::pair<KeyType, ValueSP>> MapType;
   typedef typename MapType::iterator MapIterator;
   typedef std::function<bool(const KeyType &, const ValueSP &)> ForEachCallback;
 
@@ -79,20 +79,22 @@ public:
       entry->GetRevision() = 0;
 
     std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
-    m_map[std::move(name)] = entry;
+    Delete(name);
+    m_map.emplace_back(std::move(name), std::move(entry));
     if (listener)
       listener->Changed();
   }
 
   bool Delete(const KeyType &name) {
     std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
-    MapIterator iter = m_map.find(name);
-    if (iter == m_map.end())
-      return false;
-    m_map.erase(iter);
-    if (listener)
-      listener->Changed();
-    return true;
+    for (MapIterator iter = m_map.begin(); iter != m_map.end(); ++iter)
+      if (iter->first == name) {
+        m_map.erase(iter);
+        if (listener)
+          listener->Changed();
+        return true;
+      }
+    return false;
   }
 
   void Clear() {
@@ -104,11 +106,12 @@ public:
 
   bool Get(const KeyType &name, ValueSP &entry) {
     std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
-    MapIterator iter = m_map.find(name);
-    if (iter == m_map.end())
-      return false;
-    entry = iter->second;
-    return true;
+    for (const auto &pos : m_map)
+      if (pos.first == name) {
+        entry = pos.second;
+        return true;
+      }
+    return false;
   }
 
   void ForEach(ForEachCallback callback) {
@@ -126,29 +129,17 @@ public:
 
   ValueSP GetValueAtIndex(size_t index) {
     std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
-    MapIterator iter = m_map.begin();
-    MapIterator end = m_map.end();
-    while (index > 0) {
-      iter++;
-      index--;
-      if (end == iter)
-        return ValueSP();
-    }
-    return iter->second;
+    if (index >= m_map.size())
+      return ValueSP();
+    return m_map[index].second;
   }
 
   // If caller holds the mutex we could return a reference without copy ctor.
   KeyType GetKeyAtIndex(size_t index) {
     std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
-    MapIterator iter = m_map.begin();
-    MapIterator end = m_map.end();
-    while (index > 0) {
-      iter++;
-      index--;
-      if (end == iter)
-        return KeyType();
-    }
-    return iter->first;
+    if (index >= m_map.size())
+      return {};
+    return m_map[index].first;
   }
 
 protected:
@@ -171,8 +162,8 @@ protected:
 public:
   typedef typename BackEndType::MapType MapType;
   typedef typename MapType::iterator MapIterator;
-  typedef typename MapType::key_type MapKeyType;
-  typedef typename MapType::mapped_type MapValueType;
+  typedef KeyType MapKeyType;
+  typedef std::shared_ptr<ValueType> MapValueType;
   typedef typename BackEndType::ForEachCallback ForEachCallback;
   typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType>>
       SharedPointer;
@@ -294,7 +285,8 @@ protected:
                 RegularExpression *dummy) {
     llvm::StringRef key_str = key.GetStringRef();
     std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
-    for (const auto &pos : m_format_map.map()) {
+    // Patterns are matched in reverse-chronological order.
+    for (const auto &pos : llvm::reverse(m_format_map.map())) {
       const RegularExpression &regex = pos.first;
       if (regex.Execute(key_str)) {
         value = pos.second;
index ee2e2f5..6acc203 100644 (file)
@@ -78,10 +78,6 @@ public:
   ///     otherwise.
   llvm::Error GetError() const;
 
-  bool operator<(const RegularExpression &rhs) const {
-    return GetText() < rhs.GetText();
-  }
-
   bool operator==(const RegularExpression &rhs) const {
     return GetText() == rhs.GetText();
   }
index 8615fe6..3390da4 100644 (file)
@@ -136,6 +136,13 @@ class AdvDataFormatterTestCase(TestBase):
         self.expect("frame variable int_array",
                     substrs=['1,2'])
 
+        # Test the patterns are matched in reverse-chronological order.
+        self.runCmd(
+            'type summary add --summary-string \"${var[2-3]}\" "int []"')
+
+        self.expect("frame variable int_array",
+                    substrs=['3,4'])
+
         self.runCmd("type summary clear")
 
         self.runCmd("type summary add -c -x \"i_am_cool \[[0-9]\]\"")