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