Add helpers for the notion of a type scavenger that is "either this or that" source...
authorEnrico Granata <egranata@apple.com>
Tue, 1 Nov 2016 20:17:14 +0000 (20:17 +0000)
committerEnrico Granata <egranata@apple.com>
Tue, 1 Nov 2016 20:17:14 +0000 (20:17 +0000)
Use the helper to rewrite the ObjC type lookup logic (first modules, then runtime) in terms of an either scavenger

llvm-svn: 285736

lldb/include/lldb/Target/Language.h
lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp

index 12d6572..edc5287 100644 (file)
@@ -95,6 +95,34 @@ public:
                    ResultSet &results) override;
   };
 
+  template <typename TypeScavenger1, typename TypeScavenger2>
+  class EitherTypeScavenger : public TypeScavenger {
+    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+                   ResultSet &results) override {
+      const bool append = false;
+      auto ts1 = TypeScavenger1();
+      if (ts1.Find(exe_scope, key, results, append))
+        return true;
+      auto ts2 = TypeScavenger2();
+      if (ts2.Find(exe_scope, key, results, append))
+        return true;
+      return false;
+    }
+  };
+
+  template <typename TypeScavenger1, typename TypeScavenger2>
+  class BothTypeScavenger : public TypeScavenger {
+    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+                   ResultSet &results) override {
+      const bool append = true;
+      auto ts1 = TypeScavenger1();
+      bool success = ts1.Find(exe_scope, key, results, append);
+      auto ts2 = TypeScavenger2();
+      success = ts2.Find(exe_scope, key, results, append) || success;
+      return success;
+    }
+  };
+
   enum class FunctionNameRepresentation {
     eName,
     eNameWithArgs,
index 1d6522f..76a940b 100644 (file)
@@ -906,35 +906,65 @@ ObjCLanguage::GetPossibleFormattersMatches(ValueObject &valobj,
 }
 
 std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() {
-  class ObjCTypeScavenger : public Language::TypeScavenger {
+  class ObjCScavengerResult : public Language::TypeScavenger::Result {
+  public:
+    ObjCScavengerResult(CompilerType type)
+        : Language::TypeScavenger::Result(), m_compiler_type(type) {}
+
+    bool IsValid() override { return m_compiler_type.IsValid(); }
+
+    bool DumpToStream(Stream &stream, bool print_help_if_available) override {
+      if (IsValid()) {
+        m_compiler_type.DumpTypeDescription(&stream);
+        stream.EOL();
+        return true;
+      }
+      return false;
+    }
+
   private:
-    class ObjCScavengerResult : public Language::TypeScavenger::Result {
-    public:
-      ObjCScavengerResult(CompilerType type)
-          : Language::TypeScavenger::Result(), m_compiler_type(type) {}
-
-      bool IsValid() override { return m_compiler_type.IsValid(); }
-
-      bool DumpToStream(Stream &stream, bool print_help_if_available) override {
-        if (IsValid()) {
-          m_compiler_type.DumpTypeDescription(&stream);
-          stream.EOL();
-          return true;
+    CompilerType m_compiler_type;
+  };
+
+  class ObjCRuntimeScavenger : public Language::TypeScavenger {
+  protected:
+    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
+                   ResultSet &results) override {
+      bool result = false;
+
+      Process *process = exe_scope->CalculateProcess().get();
+      if (process) {
+        const bool create_on_demand = false;
+        auto objc_runtime = process->GetObjCLanguageRuntime(create_on_demand);
+        if (objc_runtime) {
+          auto decl_vendor = objc_runtime->GetDeclVendor();
+          if (decl_vendor) {
+            std::vector<clang::NamedDecl *> decls;
+            ConstString name(key);
+            decl_vendor->FindDecls(name, true, UINT32_MAX, decls);
+            for (auto decl : decls) {
+              if (decl) {
+                if (CompilerType candidate =
+                        ClangASTContext::GetTypeForDecl(decl)) {
+                  result = true;
+                  std::unique_ptr<Language::TypeScavenger::Result> result(
+                      new ObjCScavengerResult(candidate));
+                  results.insert(std::move(result));
+                }
+              }
+            }
+          }
         }
-        return false;
       }
 
-      ~ObjCScavengerResult() override = default;
+      return result;
+    }
 
-    private:
-      CompilerType m_compiler_type;
-    };
+    friend class lldb_private::ObjCLanguage;
+  };
 
+  class ObjCModulesScavenger : public Language::TypeScavenger {
   protected:
-    ObjCTypeScavenger() = default;
-
-    ~ObjCTypeScavenger() override = default;
-
     bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
                    ResultSet &results) override {
       bool result = false;
@@ -959,40 +989,15 @@ std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() {
         }
       }
 
-      if (!result) {
-        Process *process = exe_scope->CalculateProcess().get();
-        if (process) {
-          const bool create_on_demand = false;
-          auto objc_runtime = process->GetObjCLanguageRuntime(create_on_demand);
-          if (objc_runtime) {
-            auto decl_vendor = objc_runtime->GetDeclVendor();
-            if (decl_vendor) {
-              std::vector<clang::NamedDecl *> decls;
-              ConstString name(key);
-              decl_vendor->FindDecls(name, true, UINT32_MAX, decls);
-              for (auto decl : decls) {
-                if (decl) {
-                  if (CompilerType candidate =
-                          ClangASTContext::GetTypeForDecl(decl)) {
-                    result = true;
-                    std::unique_ptr<Language::TypeScavenger::Result> result(
-                        new ObjCScavengerResult(candidate));
-                    results.insert(std::move(result));
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-
       return result;
     }
 
     friend class lldb_private::ObjCLanguage;
   };
 
-  return std::unique_ptr<TypeScavenger>(new ObjCTypeScavenger());
+  return std::unique_ptr<TypeScavenger>(
+      new Language::EitherTypeScavenger<ObjCModulesScavenger,
+                                        ObjCRuntimeScavenger>());
 }
 
 bool ObjCLanguage::GetFormatterPrefixSuffix(ValueObject &valobj,