aleksandr.urakov created this revision. aleksandr.urakov added reviewers: aprantl, teemperor. aleksandr.urakov added a project: LLDB. Herald added a subscriber: lldb-commits.
Sometimes a result variable of some expression can be presented as an elaborated type. In this case the methods `IsTypedefType()` and `GetTypedefedType()` of `SBType` didn't work. This patch fixes that. I didn't find the test for these API methods, so I added a basic test for this too. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D78697 Files: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp lldb/test/API/lang/cpp/typedef/Makefile lldb/test/API/lang/cpp/typedef/TestCppTypedef.py lldb/test/API/lang/cpp/typedef/main.cpp
Index: lldb/test/API/lang/cpp/typedef/main.cpp =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/typedef/main.cpp @@ -0,0 +1,13 @@ +template<typename T> +struct S { + typedef T V; + + V value; +}; + +typedef S<float> SF; + +int main (int argc, char const *argv[]) { + SF s{ .5 }; + return 0; // Set a breakpoint here +} Index: lldb/test/API/lang/cpp/typedef/TestCppTypedef.py =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/typedef/TestCppTypedef.py @@ -0,0 +1,55 @@ +""" +Test that we can retrieve typedefed types correctly +""" + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * +from lldbsuite.test import decorators + +class TestCppTypedef(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_typedef(self): + """ + Test that we retrieve typedefed types correctly + """ + + # Build and run until the breakpoint + self.build() + self.main_source_file = lldb.SBFileSpec("main.cpp") + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "Set a breakpoint here", self.main_source_file) + + # Get the current frame + frame = thread.GetSelectedFrame() + + # First of all, check that we can get a typedefed type correctly in a simple case + + expr_result = frame.EvaluateExpression("(SF)s") + self.assertTrue(expr_result.IsValid(), "Can't evaluate an expression with result type `SF`") + + typedef_type = expr_result.GetType(); + self.assertTrue(typedef_type.IsValid(), "Can't get `SF` type of evaluated expression") + self.assertTrue(typedef_type.IsTypedefType(), "Type `SF` should be a typedef") + + typedefed_type = typedef_type.GetTypedefedType() + self.assertTrue(typedefed_type.IsValid(), "Can't get `SF` typedefed type") + self.assertEqual(typedefed_type.GetName(), "S<float>", "Got invalid `SF` typedefed type") + + # Check that we can get a typedefed type correctly in the case + # when an elaborated type is created during the parsing + + expr_result = frame.EvaluateExpression("(SF::V)s.value") + self.assertTrue(expr_result.IsValid(), "Can't evaluate an expression with result type `SF::V`") + + typedef_type = expr_result.GetType(); + self.assertTrue(typedef_type.IsValid(), "Can't get `SF::V` type of evaluated expression") + self.assertTrue(typedef_type.IsTypedefType(), "Type `SF::V` should be a typedef") + + typedefed_type = typedef_type.GetTypedefedType() + self.assertTrue(typedefed_type.IsValid(), "Can't get `SF::V` typedefed type") + self.assertEqual(typedefed_type.GetName(), "float", "Got invalid `SF::V` typedefed type") Index: lldb/test/API/lang/cpp/typedef/Makefile =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/typedef/Makefile @@ -0,0 +1,2 @@ +CXX_SOURCES := main.cpp +include Makefile.rules Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -537,6 +537,13 @@ Opts.ModulesLocalVisibility = 1; } +static QualType desugarType(QualType type) { + while (const clang::ElaboratedType *elaboratedType = + llvm::dyn_cast<clang::ElaboratedType>(type)) + type = elaboratedType->desugar(); + return type; +} + TypeSystemClang::TypeSystemClang(llvm::StringRef name, llvm::Triple target_triple) { m_display_name = name.str(); @@ -3539,7 +3546,7 @@ bool TypeSystemClang::IsTypedefType(lldb::opaque_compiler_type_t type) { if (!type) return false; - return GetQualType(type)->getTypeClass() == clang::Type::Typedef; + return desugarType(GetQualType(type))->getTypeClass() == clang::Type::Typedef; } bool TypeSystemClang::IsVoidType(lldb::opaque_compiler_type_t type) { @@ -4524,7 +4531,7 @@ TypeSystemClang::GetTypedefedType(lldb::opaque_compiler_type_t type) { if (type) { const clang::TypedefType *typedef_type = - llvm::dyn_cast<clang::TypedefType>(GetQualType(type)); + llvm::dyn_cast<clang::TypedefType>(desugarType(GetQualType(type))); if (typedef_type) return GetType(typedef_type->getDecl()->getUnderlyingType()); }
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits