From 84c398d375d9f3b0c2ce2a755dbaa57500e3f8ec Mon Sep 17 00:00:00 2001 From: Aleksandr Urakov Date: Fri, 24 Apr 2020 16:09:06 +0300 Subject: [PATCH] [lldb][TypeSystemClang] Desugar an elaborated type before checking if it's a typedef or getting a typedefed type Summary: 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. Reviewers: aprantl, teemperor, labath, leonid.mashinskiy Reviewed By: teemperor Subscribers: labath, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D78697 --- .../Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 7 +-- lldb/test/API/lang/cpp/typedef/Makefile | 2 + lldb/test/API/lang/cpp/typedef/TestCppTypedef.py | 55 ++++++++++++++++++++++ lldb/test/API/lang/cpp/typedef/main.cpp | 13 +++++ 4 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 lldb/test/API/lang/cpp/typedef/Makefile create mode 100644 lldb/test/API/lang/cpp/typedef/TestCppTypedef.py create mode 100644 lldb/test/API/lang/cpp/typedef/main.cpp diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 4f35d8a..7acdad2 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -3541,7 +3541,8 @@ bool TypeSystemClang::IsScalarType(lldb::opaque_compiler_type_t type) { bool TypeSystemClang::IsTypedefType(lldb::opaque_compiler_type_t type) { if (!type) return false; - return GetQualType(type)->getTypeClass() == clang::Type::Typedef; + return RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef}) + ->getTypeClass() == clang::Type::Typedef; } bool TypeSystemClang::IsVoidType(lldb::opaque_compiler_type_t type) { @@ -4525,8 +4526,8 @@ CompilerType TypeSystemClang::CreateTypedef( CompilerType TypeSystemClang::GetTypedefedType(lldb::opaque_compiler_type_t type) { if (type) { - const clang::TypedefType *typedef_type = - llvm::dyn_cast(GetQualType(type)); + const clang::TypedefType *typedef_type = llvm::dyn_cast( + RemoveWrappingTypes(GetQualType(type), {clang::Type::Typedef})); if (typedef_type) return GetType(typedef_type->getDecl()->getUnderlyingType()); } diff --git a/lldb/test/API/lang/cpp/typedef/Makefile b/lldb/test/API/lang/cpp/typedef/Makefile new file mode 100644 index 0000000..3d0b98f --- /dev/null +++ b/lldb/test/API/lang/cpp/typedef/Makefile @@ -0,0 +1,2 @@ +CXX_SOURCES := main.cpp +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/typedef/TestCppTypedef.py b/lldb/test/API/lang/cpp/typedef/TestCppTypedef.py new file mode 100644 index 0000000..2aa2bcf --- /dev/null +++ b/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(), "Expression failed with: " + str(expr_result.GetError())) + + 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", "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(), "Expression failed with: " + str(expr_result.GetError())) + + 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") diff --git a/lldb/test/API/lang/cpp/typedef/main.cpp b/lldb/test/API/lang/cpp/typedef/main.cpp new file mode 100644 index 0000000..f1407b63 --- /dev/null +++ b/lldb/test/API/lang/cpp/typedef/main.cpp @@ -0,0 +1,13 @@ +template +struct S { + typedef T V; + + V value; +}; + +typedef S SF; + +int main (int argc, char const *argv[]) { + SF s{ .5 }; + return 0; // Set a breakpoint here +} -- 2.7.4