diff options
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 107 | ||||
-rw-r--r-- | lldb/test/lang/objc/objc-property/TestObjCProperty.py | 5 | ||||
-rw-r--r-- | lldb/test/lang/objc/objc-property/main.m | 9 |
3 files changed, 82 insertions, 39 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index d81fa171e33..122725c7584 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -5511,51 +5511,80 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break; } - if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID)) + if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL) { - if (type_name_cstr != NULL && sc.comp_unit != NULL && - (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus)) + bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus); + + if (translation_unit_is_objc) { - static ConstString g_objc_type_name_id("id"); - static ConstString g_objc_type_name_Class("Class"); - static ConstString g_objc_type_name_selector("SEL"); - - if (type_name_const_str == g_objc_type_name_id) + if (type_name_cstr != NULL) { - if (log) - GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.", - die->GetOffset(), - DW_TAG_value_to_name(die->Tag()), - die->GetName(this, dwarf_cu)); - clang_type = ast.GetBuiltInType_objc_id(); - encoding_data_type = Type::eEncodingIsUID; - encoding_uid = LLDB_INVALID_UID; - resolve_state = Type::eResolveStateFull; + static ConstString g_objc_type_name_id("id"); + static ConstString g_objc_type_name_Class("Class"); + static ConstString g_objc_type_name_selector("SEL"); + + if (type_name_const_str == g_objc_type_name_id) + { + if (log) + GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.", + die->GetOffset(), + DW_TAG_value_to_name(die->Tag()), + die->GetName(this, dwarf_cu)); + clang_type = ast.GetBuiltInType_objc_id(); + encoding_data_type = Type::eEncodingIsUID; + encoding_uid = LLDB_INVALID_UID; + resolve_state = Type::eResolveStateFull; + } + else if (type_name_const_str == g_objc_type_name_Class) + { + if (log) + GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.", + die->GetOffset(), + DW_TAG_value_to_name(die->Tag()), + die->GetName(this, dwarf_cu)); + clang_type = ast.GetBuiltInType_objc_Class(); + encoding_data_type = Type::eEncodingIsUID; + encoding_uid = LLDB_INVALID_UID; + resolve_state = Type::eResolveStateFull; + } + else if (type_name_const_str == g_objc_type_name_selector) + { + if (log) + GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.", + die->GetOffset(), + DW_TAG_value_to_name(die->Tag()), + die->GetName(this, dwarf_cu)); + clang_type = ast.GetBuiltInType_objc_selector(); + encoding_data_type = Type::eEncodingIsUID; + encoding_uid = LLDB_INVALID_UID; + resolve_state = Type::eResolveStateFull; + } } - else if (type_name_const_str == g_objc_type_name_Class) - { - if (log) - GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.", - die->GetOffset(), - DW_TAG_value_to_name(die->Tag()), - die->GetName(this, dwarf_cu)); - clang_type = ast.GetBuiltInType_objc_Class(); - encoding_data_type = Type::eEncodingIsUID; - encoding_uid = LLDB_INVALID_UID; - resolve_state = Type::eResolveStateFull; - } - else if (type_name_const_str == g_objc_type_name_selector) + else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID) { - if (log) - GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.", - die->GetOffset(), - DW_TAG_value_to_name(die->Tag()), - die->GetName(this, dwarf_cu)); - clang_type = ast.GetBuiltInType_objc_selector(); - encoding_data_type = Type::eEncodingIsUID; - encoding_uid = LLDB_INVALID_UID; - resolve_state = Type::eResolveStateFull; + // Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id". + + DWARFDebugInfoEntry* encoding_die = dwarf_cu->GetDIEPtr(encoding_uid); + + if (encoding_die && encoding_die->Tag() == DW_TAG_structure_type) + { + if (const char *struct_name = encoding_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL)) + { + if (!strcmp(struct_name, "objc_object")) + { + if (log) + GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.", + die->GetOffset(), + DW_TAG_value_to_name(die->Tag()), + die->GetName(this, dwarf_cu)); + clang_type = ast.GetBuiltInType_objc_id(); + encoding_data_type = Type::eEncodingIsUID; + encoding_uid = LLDB_INVALID_UID; + resolve_state = Type::eResolveStateFull; + } + } + } } } } diff --git a/lldb/test/lang/objc/objc-property/TestObjCProperty.py b/lldb/test/lang/objc/objc-property/TestObjCProperty.py index 37249d5a9a7..dadb7fa291c 100644 --- a/lldb/test/lang/objc/objc-property/TestObjCProperty.py +++ b/lldb/test/lang/objc/objc-property/TestObjCProperty.py @@ -124,6 +124,11 @@ class ObjCPropertyTestCase(TestBase): unbacked_value = frame.EvaluateExpression("mine.unbackedInt", False) unbacked_error = unbacked_value.GetError() self.assertTrue (unbacked_error.Success()) + + idWithProtocol_value = frame.EvaluateExpression("mine.idWithProtocol", False) + idWithProtocol_error = idWithProtocol_value.GetError() + self.assertTrue (idWithProtocol_error.Success()) + self.assertTrue (idWithProtocol_value.GetTypeName() == "id") if __name__ == '__main__': import atexit diff --git a/lldb/test/lang/objc/objc-property/main.m b/lldb/test/lang/objc/objc-property/main.m index 4ce78eccde5..2ef142be9b0 100644 --- a/lldb/test/lang/objc/objc-property/main.m +++ b/lldb/test/lang/objc/objc-property/main.m @@ -1,5 +1,11 @@ #import <Foundation/Foundation.h> +@protocol MyProtocol + +-(const char *)hello; + +@end + @interface BaseClass : NSObject { int _backedInt; @@ -18,6 +24,7 @@ @property(getter=myGetUnbackedInt,setter=mySetUnbackedInt:) int unbackedInt; @property int backedInt; +@property (nonatomic, assign) id <MyProtocol> idWithProtocol; @end @implementation BaseClass @@ -79,6 +86,8 @@ main () int unbackedInt = mine.unbackedInt; + id idWithProtocol = mine.idWithProtocol; + NSLog (@"Results for %p: nonexistant: %d backed: %d unbacked: %d accessCount: %d.", mine, nonexistant, |