teemperor created this revision.
teemperor added a reviewer: davide.
teemperor added a project: Upstreaming LLDB's downstream patches.
Herald added subscribers: lldb-commits, JDevlieghere.
Herald added a project: LLDB.

In Swift there is a check if the compiled module actually fits to our Swift 
version in LLDB. We don't really do this
kind of version checking so far in LLDB as we only have one Clang-based 
TypeSystem for C languages.
C languages don't have this precise version semantic but different standards 
which are expressed as different language types,
so there is no precise version checking needed for them.

This adds the relevant compatibility check to SBModule and adds the relevant 
tests for it. The actual Swift version check is
implemented in Swift's TypeSystem class which is downstream, so we test this 
here with the Clang type system which is
always treating modules as compatible.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D69704

Files:
  lldb/include/lldb/API/SBError.h
  lldb/include/lldb/API/SBModule.h
  lldb/include/lldb/Symbol/TypeSystem.h
  lldb/packages/Python/lldbsuite/test/python_api/module_compability/Makefile
  
lldb/packages/Python/lldbsuite/test/python_api/module_compability/TestModuleTypeSystemCompatible.py
  lldb/packages/Python/lldbsuite/test/python_api/module_compability/main.cpp
  lldb/scripts/interface/SBModule.i
  lldb/source/API/SBModule.cpp
  lldb/source/Symbol/TypeSystem.cpp

Index: lldb/source/Symbol/TypeSystem.cpp
===================================================================
--- lldb/source/Symbol/TypeSystem.cpp
+++ lldb/source/Symbol/TypeSystem.cpp
@@ -147,6 +147,12 @@
   return false;
 }
 
+Status TypeSystem::IsCompatible() {
+  // Assume a language is compatible. Override this virtual function
+  // in your TypeSystem plug-in if version checking is desired.
+  return Status();
+}
+
 ConstString TypeSystem::DeclGetMangledName(void *opaque_decl) {
   return ConstString();
 }
Index: lldb/source/API/SBModule.cpp
===================================================================
--- lldb/source/API/SBModule.cpp
+++ lldb/source/API/SBModule.cpp
@@ -23,6 +23,7 @@
 #include "lldb/Symbol/Symtab.h"
 #include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/StreamString.h"
 
@@ -687,6 +688,27 @@
   return LLDB_RECORD_RESULT(sb_addr);
 }
 
+lldb::SBError SBModule::IsTypeSystemCompatible(lldb::LanguageType language) {
+  SBError sb_error;
+  ModuleSP module_sp(GetSP());
+  if (!module_sp) {
+    sb_error.SetErrorString("invalid module");
+    return sb_error;
+  }
+
+  auto type_system_or_err = module_sp->GetTypeSystemForLanguage(language);
+  if (!type_system_or_err) {
+    sb_error.SetErrorStringWithFormat(
+        "no type system for language %s",
+        Language::GetNameForLanguageType(language));
+    llvm::consumeError(type_system_or_err.takeError());
+    return sb_error;
+  }
+
+  sb_error.SetError(type_system_or_err->IsCompatible());
+  return sb_error;
+}
+
 namespace lldb_private {
 namespace repro {
 
Index: lldb/scripts/interface/SBModule.i
===================================================================
--- lldb/scripts/interface/SBModule.i
+++ lldb/scripts/interface/SBModule.i
@@ -342,6 +342,9 @@
     lldb::SBAddress
     GetObjectFileEntryPointAddress() const;
 
+    lldb::SBError
+    IsTypeSystemCompatible(lldb::LanguageType language);
+
     %pythoncode %{
         def __len__(self):
             '''Return the number of symbols in a lldb.SBModule object.'''
Index: lldb/packages/Python/lldbsuite/test/python_api/module_compability/main.cpp
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/python_api/module_compability/main.cpp
@@ -0,0 +1 @@
+int main() {}
Index: lldb/packages/Python/lldbsuite/test/python_api/module_compability/TestModuleTypeSystemCompatible.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/python_api/module_compability/TestModuleTypeSystemCompatible.py
@@ -0,0 +1,64 @@
+"""
+Test SBModule's IsTypeSystemCompatible.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class ModuleTypeSystemCheckTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def assert_invalid_module_err(self, error):
+        self.assertEquals("invalid module", error.GetCString())
+        self.assertFalse(error.Success())
+
+    # Py3 asserts due to a bug in SWIG.  A fix for this was upstreamed into
+    # SWIG 3.0.8.
+    @skipIf(py_version=['>=', (3, 0)], swig_version=['<', (3, 0, 8)])
+    @add_test_categories(['pyapi'])
+    @no_debug_info_test
+    def test_default_module(self):
+        exe_module = lldb.SBModule()
+        self.assert_invalid_module_err(exe_module.IsTypeSystemCompatible(lldb.eLanguageTypeUnknown))
+        self.assert_invalid_module_err(error = exe_module.IsTypeSystemCompatible(lldb.eLanguageTypeC))
+
+    def assert_compatible(self, exe_module, lang):
+        error = exe_module.IsTypeSystemCompatible(lang)
+        self.assertTrue(error.Success())
+
+    # Py3 asserts due to a bug in SWIG.  A fix for this was upstreamed into
+    # SWIG 3.0.8.
+    @skipIf(py_version=['>=', (3, 0)], swig_version=['<', (3, 0, 8)])
+    @add_test_categories(['pyapi'])
+    @no_debug_info_test
+    def test_c_languages(self):
+        self.build()
+        exe = self.getBuildArtifact("a.out")
+
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+        self.assertTrue(target.GetNumModules() > 0)
+
+        exe_module = target.GetModuleAtIndex(0)
+
+        # Check that we get an error if LLDB doesn't implement the language
+        error = exe_module.IsTypeSystemCompatible(lldb.eLanguageTypeModula2)
+        self.assertEquals("no type system for language modula2", error.GetCString())
+        self.assertFalse(error.Success())
+
+        # Check that C languages are compatible with the module.
+        self.assert_compatible(exe_module, lldb.eLanguageTypeC)
+        self.assert_compatible(exe_module, lldb.eLanguageTypeC89)
+        self.assert_compatible(exe_module, lldb.eLanguageTypeC99)
+        self.assert_compatible(exe_module, lldb.eLanguageTypeC11)
+        self.assert_compatible(exe_module, lldb.eLanguageTypeC_plus_plus)
+        self.assert_compatible(exe_module, lldb.eLanguageTypeC_plus_plus_03)
+        self.assert_compatible(exe_module, lldb.eLanguageTypeC_plus_plus_11)
+        self.assert_compatible(exe_module, lldb.eLanguageTypeC_plus_plus_14)
+
+        # 'Unknown' language gets mapped to a generic C language right now.
+        self.assert_compatible(exe_module, lldb.eLanguageTypeUnknown)
Index: lldb/packages/Python/lldbsuite/test/python_api/module_compability/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/python_api/module_compability/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
Index: lldb/include/lldb/Symbol/TypeSystem.h
===================================================================
--- lldb/include/lldb/Symbol/TypeSystem.h
+++ lldb/include/lldb/Symbol/TypeSystem.h
@@ -208,6 +208,14 @@
   // TypeSystems can support more than one language
   virtual bool SupportsLanguage(lldb::LanguageType language) = 0;
 
+  /// Check if the current module or target that was used to create this
+  /// type system is compatible with the TypeSystem plug-in.
+  ///
+  /// \return A Status object that is either describing any potential errors
+  ///         that make the module/target incompatible or contains no errors
+  ///         when the module/target is compatible.
+  virtual Status IsCompatible();
+
   // Type Completion
 
   virtual bool GetCompleteType(lldb::opaque_compiler_type_t type) = 0;
Index: lldb/include/lldb/API/SBModule.h
===================================================================
--- lldb/include/lldb/API/SBModule.h
+++ lldb/include/lldb/API/SBModule.h
@@ -288,6 +288,22 @@
   lldb::SBAddress GetObjectFileHeaderAddress() const;
   lldb::SBAddress GetObjectFileEntryPointAddress() const;
 
+  /// Checks if the module is compatible with the type system that LLDB
+  /// implements for the given language.
+  ///
+  /// A module may be incompatible with LLDB's type system if the language
+  /// version that is used in the module isn't supported by LLDB even though
+  /// the language itself is supported. This can happen if the language itself
+  /// evolved but LLDB's only supports a newer/older version of the language.
+  ///
+  /// \param[in] language
+  ///     The language that should be checked for compability with this module.
+  ///
+  /// \return
+  ///     An error object that describes the errors that were encounterd when
+  ///     checking if LLDB's type system is compatible.
+  lldb::SBError IsTypeSystemCompatible(lldb::LanguageType language);
+
 private:
   friend class SBAddress;
   friend class SBFrame;
Index: lldb/include/lldb/API/SBError.h
===================================================================
--- lldb/include/lldb/API/SBError.h
+++ lldb/include/lldb/API/SBError.h
@@ -61,6 +61,7 @@
   friend class SBData;
   friend class SBDebugger;
   friend class SBHostOS;
+  friend class SBModule;
   friend class SBPlatform;
   friend class SBProcess;
   friend class SBReproducer;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to