From 5ff4f881a7774b8ec8d4db40d2a6c95ddd8a5f21 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 5 Feb 2020 11:44:28 +0100 Subject: [PATCH] [lldb] Ignore type sugar in TypeSystemClang::GetPointerType Summary: Currently having a typedef for ObjC types is breaking member access in LLDB: ``` typedef NSString Str; NSString *s; s.length; // OK Str *s; s.length; // Causes: member reference base type 'Str *' (aka 'NSString *') is not a structure or union ``` This works for NSString as there the type building from `NSString` -> `NSString *` will correctly build a ObjCObjectPointerType (which is necessary to make member access with a dot possible), but for the typedef the `Str` -> `Str *` conversion will produce an incorrect PointerType. The reason for this is that our check in TypeSystemClang::GetPointerType is not desugaring the base type, which causes that `Str` is not recognised as a type to a `ObjCInterface` as the check only sees the typedef sugar that was put around it. This causes that we fall back to constructing a PointerType instead which does not allow member access with the dot operator. This patch just changes the check to look at the desugared type instead. Fixes rdar://17525603 Reviewers: shafik, mib Reviewed By: mib Subscribers: mib, JDevlieghere, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D73952 --- .../test/lang/objc/objc-property/TestObjCProperty.py | 5 +++++ .../Python/lldbsuite/test/lang/objc/objc-property/main.m | 3 +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 3 +-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py b/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py index 3092c3f086a9..4eaef1668ccc 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py +++ b/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py @@ -110,6 +110,11 @@ class ObjCPropertyTestCase(TestBase): self.assertTrue(backed_value.GetValueAsUnsigned(12345) == backing_value.GetValueAsUnsigned(23456)) + value_from_typedef = frame.EvaluateExpression("typedefd.backedInt", False) + self.assertTrue(value_from_typedef.GetError().Success()) + self.assertEqual(value_from_typedef.GetValueAsUnsigned(12345), + backing_value.GetValueAsUnsigned(23456)) + unbacked_value = frame.EvaluateExpression("mine.unbackedInt", False) unbacked_error = unbacked_value.GetError() self.assertTrue(unbacked_error.Success()) diff --git a/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m b/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m index 8d14759fb384..8c84440adc43 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m +++ b/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m @@ -87,10 +87,13 @@ static int _class_int = 123; } @end +typedef BaseClass TypedefBaseClass; + int main () { BaseClass *mine = [BaseClass baseClassWithBackedInt: 10 andUnbackedInt: 20]; + TypedefBaseClass *typedefd = mine; // Set a breakpoint here. int nonexistant = mine.nonexistantInt; diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 32a52e8100a2..23e9d2172cc9 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -4259,8 +4259,7 @@ TypeSystemClang::GetPointerType(lldb::opaque_compiler_type_t type) { if (type) { clang::QualType qual_type(GetQualType(type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) { + switch (qual_type.getDesugaredType(getASTContext())->getTypeClass()) { case clang::Type::ObjCObject: case clang::Type::ObjCInterface: return GetType(getASTContext().getObjCObjectPointerType(qual_type));