summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2012-03-29 19:07:06 +0000
committerSean Callanan <scallanan@apple.com>2012-03-29 19:07:06 +0000
commit751aac610a7c6213e7f5720944f94df0b973af38 (patch)
tree465083b6298d6e5bfb2f8554707700ea2efc08cd
parent064b5386f09bf669c4fd7abcd2e3926ff3f0c4ad (diff)
downloadbcm5719-llvm-751aac610a7c6213e7f5720944f94df0b973af38.tar.gz
bcm5719-llvm-751aac610a7c6213e7f5720944f94df0b973af38.zip
Added support for the DW_AT_APPLE_Property tag
for unbacked properties. We support two variants: one in which the getter/setter are provided by selector ("mySetter:") and one in which the getter/setter are provided by signature ("-[MyClass mySetter:]"). llvm-svn: 153675
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp149
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp1
2 files changed, 90 insertions, 60 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 683bc81243d..7ccd6f24d86 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1462,6 +1462,7 @@ SymbolFileDWARF::ParseChildMembers
switch (tag)
{
case DW_TAG_member:
+ case DW_TAG_APPLE_Property:
{
DWARFDebugInfoEntry::Attributes attributes;
const size_t num_attributes = die->GetAttributes (this,
@@ -1547,7 +1548,30 @@ SymbolFileDWARF::ParseChildMembers
}
}
- // Clang has a DWARF generation bug where sometimes it
+ ConstString fixed_getter;
+ ConstString fixed_setter;
+
+ if (prop_getter_name && prop_getter_name[0] == '-')
+ {
+ ObjCLanguageRuntime::ParseMethodName (prop_getter_name,
+ NULL,
+ &fixed_getter,
+ NULL,
+ NULL);
+ prop_getter_name = fixed_getter.GetCString();
+ }
+
+ if (prop_setter_name && prop_setter_name[0] == '-')
+ {
+ ObjCLanguageRuntime::ParseMethodName (prop_setter_name,
+ NULL,
+ &fixed_setter,
+ NULL,
+ NULL);
+ prop_setter_name = fixed_setter.GetCString();
+ }
+
+ // Clang has a DWARF generation bug where sometimes it
// represents fields that are references with bad byte size
// and bit size/offset information such as:
//
@@ -1587,77 +1611,84 @@ SymbolFileDWARF::ParseChildMembers
{
Type *member_type = ResolveTypeUID(encoding_uid);
clang::FieldDecl *field_decl = NULL;
- if (member_type)
- {
- if (accessibility == eAccessNone)
- accessibility = default_accessibility;
- member_accessibilities.push_back(accessibility);
-
- field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
- name,
- member_type->GetClangLayoutType(),
- accessibility,
- bit_size);
- }
- else
+ if (tag == DW_TAG_member)
{
- if (name)
- GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member '%s' refers to type 0x%8.8llx which was unable to be parsed",
- MakeUserID(die->GetOffset()),
- name,
- encoding_uid);
- else
- GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member refers to type 0x%8.8llx which was unable to be parsed",
- MakeUserID(die->GetOffset()),
- encoding_uid);
- }
-
- if (member_byte_offset != UINT32_MAX || bit_size != 0)
- {
- /////////////////////////////////////////////////////////////
- // How to locate a field given the DWARF debug information
- //
- // AT_byte_size indicates the size of the word in which the
- // bit offset must be interpreted.
- //
- // AT_data_member_location indicates the byte offset of the
- // word from the base address of the structure.
- //
- // AT_bit_offset indicates how many bits into the word
- // (according to the host endianness) the low-order bit of
- // the field starts. AT_bit_offset can be negative.
- //
- // AT_bit_size indicates the size of the field in bits.
- /////////////////////////////////////////////////////////////
-
- ByteOrder object_endian = GetObjectFile()->GetModule()->GetArchitecture().GetDefaultEndian();
-
- uint64_t total_bit_offset = 0;
-
- total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
-
- if (object_endian == eByteOrderLittle)
- {
- total_bit_offset += byte_size * 8;
- total_bit_offset -= (bit_offset + bit_size);
+ if (member_type)
+ {
+ if (accessibility == eAccessNone)
+ accessibility = default_accessibility;
+ member_accessibilities.push_back(accessibility);
+
+ field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
+ name,
+ member_type->GetClangLayoutType(),
+ accessibility,
+ bit_size);
}
else
{
- total_bit_offset += bit_offset;
+ if (name)
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member '%s' refers to type 0x%8.8llx which was unable to be parsed",
+ MakeUserID(die->GetOffset()),
+ name,
+ encoding_uid);
+ else
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member refers to type 0x%8.8llx which was unable to be parsed",
+ MakeUserID(die->GetOffset()),
+ encoding_uid);
}
+
+ if (member_byte_offset != UINT32_MAX || bit_size != 0)
+ {
+ /////////////////////////////////////////////////////////////
+ // How to locate a field given the DWARF debug information
+ //
+ // AT_byte_size indicates the size of the word in which the
+ // bit offset must be interpreted.
+ //
+ // AT_data_member_location indicates the byte offset of the
+ // word from the base address of the structure.
+ //
+ // AT_bit_offset indicates how many bits into the word
+ // (according to the host endianness) the low-order bit of
+ // the field starts. AT_bit_offset can be negative.
+ //
+ // AT_bit_size indicates the size of the field in bits.
+ /////////////////////////////////////////////////////////////
- layout_info.field_offsets.insert(std::make_pair(field_decl, total_bit_offset));
+ ByteOrder object_endian = GetObjectFile()->GetModule()->GetArchitecture().GetDefaultEndian();
+
+ uint64_t total_bit_offset = 0;
+
+ total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
+
+ if (object_endian == eByteOrderLittle)
+ {
+ total_bit_offset += byte_size * 8;
+ total_bit_offset -= (bit_offset + bit_size);
+ }
+ else
+ {
+ total_bit_offset += bit_offset;
+ }
+
+ layout_info.field_offsets.insert(std::make_pair(field_decl, total_bit_offset));
+ }
}
+
if (prop_name != NULL)
{
+ clang::ObjCIvarDecl *ivar_decl = NULL;
- clang::ObjCIvarDecl *ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
- assert (ivar_decl != NULL);
+ if (field_decl)
+ {
+ ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
+ assert (ivar_decl != NULL);
+ }
-
GetClangASTContext().AddObjCClassProperty (class_clang_type,
prop_name,
- 0,
+ member_type->GetClangLayoutType(),
ivar_decl,
prop_setter_name,
prop_getter_name,
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 4f1d77a9603..45831f72b9b 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -2407,7 +2407,6 @@ ClangASTContext::AddObjCClassProperty
else if (ivar_decl)
property_opaque_type_to_access = ivar_decl->getType().getAsOpaquePtr();
- // FIXME: For now, we don't know how to add properties if we don't have their associated ivar.
if (class_interface_decl && property_opaque_type_to_access)
{
clang::TypeSourceInfo *prop_type_source;
OpenPOWER on IntegriCloud