Fixed the Objective C method prototypes to be correct (the selectors weren't

being chopped up correctly). The DWARF plug-in also keeps a map of the ObjC
class names to selectors for easy parsing of all class selectors when we parse
the class type.

llvm-svn: 116290
This commit is contained in:
Greg Clayton 2010-10-12 02:24:53 +00:00
parent 01cbf2de0f
commit 450e3f3c77
10 changed files with 124 additions and 26 deletions

View File

@ -2438,6 +2438,7 @@
isa = PBXProject;
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,

View File

@ -225,13 +225,13 @@ ObjectFileELF::ParseDependentModules()
// Locate the dynamic table.
user_id_t dynsym_id = 0;
user_id_t dynstr_id = 0;
for (SectionHeaderCollIter I = m_section_headers.begin();
I != m_section_headers.end(); ++I)
for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
sh_pos != m_section_headers.end(); ++sh_pos)
{
if (I->sh_type == SHT_DYNAMIC)
if (sh_pos->sh_type == SHT_DYNAMIC)
{
dynsym_id = SectionIndex(I);
dynstr_id = I->sh_link + 1; // Section ID's are 1 based.
dynsym_id = SectionIndex(sh_pos);
dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
break;
}
}

View File

@ -568,6 +568,7 @@ DWARFCompileUnit::Index
NameToDIE& full_name_to_function_die,
NameToDIE& method_name_to_function_die,
NameToDIE& selector_name_to_function_die,
NameToDIE& objc_class_selector_dies,
NameToDIE& name_to_global_die,
NameToDIE& name_to_type_die,
const DWARFDebugRanges *debug_ranges,
@ -786,6 +787,12 @@ DWARFCompileUnit::Index
const char *method_name = strchr (name, ' ');
if (method_name)
{
ConstString class_name (name + 2, method_name - name - 2);
// Keep a map of the objective C class name to all selector
// DIEs
objc_class_selector_dies.Insert(class_name, die_info);
// Skip the space
++method_name;
// Extract the objective C basename and add it to the

View File

@ -138,6 +138,7 @@ public:
NameToDIE& full_name_to_function_die,
NameToDIE& method_name_to_function_die,
NameToDIE& selector_name_to_function_die,
NameToDIE& objc_class_selector_dies,
NameToDIE& name_to_global_die,
NameToDIE& name_to_type_die,
const DWARFDebugRanges* debug_ranges,

View File

@ -49,6 +49,7 @@
#include "DWARFFormValue.h"
#include "DWARFLocationList.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
#include <map>
@ -141,8 +142,9 @@ GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
}
SymbolFileDWARF::SymbolFileDWARF(ObjectFile* ofile) :
SymbolFile(ofile),
SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
SymbolFile (objfile),
m_debug_map_symfile (NULL),
m_flags(),
m_data_debug_abbrev(),
m_data_debug_frame(),
@ -159,6 +161,7 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* ofile) :
m_function_fullname_index(),
m_function_method_index(),
m_function_selector_index(),
m_objc_class_selectors_index(),
m_global_index(),
m_types_index(),
m_indexed(false),
@ -906,7 +909,7 @@ SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
if (line_table_ap.get())
{
ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_flags.IsSet (flagsDWARFIsOSOForDebugMap), false};
ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
uint32_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
sc.comp_unit->SetLineTable(line_table_ap.release());
@ -1257,7 +1260,9 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
if (die == NULL)
return NULL;
DWARFCompileUnit *cu = DebugInfo()->GetCompileUnitContainingDIE (die->GetOffset()).get();
DWARFDebugInfo* debug_info = DebugInfo();
DWARFCompileUnit *cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Type *type = m_die_to_type.lookup (die);
const dw_tag_t tag = die->Tag();
@ -1277,7 +1282,8 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
if (die->HasChildren())
{
LanguageType class_language = eLanguageTypeUnknown;
if (ClangASTContext::IsObjCClassType (clang_type))
bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
if (is_objc_class)
class_language = eLanguageTypeObjC;
int tag_decl_kind = -1;
@ -1326,6 +1332,34 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
}
}
if (class_language == eLanguageTypeObjC)
{
std::string class_str (ClangASTContext::GetTypeName (clang_type));
if (!class_str.empty())
{
ConstString class_name (class_str.c_str());
std::vector<NameToDIE::Info> method_die_infos;
if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
{
DWARFCompileUnit* method_cu = NULL;
DWARFCompileUnit* prev_method_cu = NULL;
const size_t num_objc_methods = method_die_infos.size();
for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
{
method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
if (method_cu != prev_method_cu)
method_cu->ExtractDIEsIfNeeded (false);
DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
ResolveType (method_cu, method_die);
}
}
}
}
// If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
// need to tell the clang type it is actually a class.
if (class_language != eLanguageTypeObjC)
@ -1412,6 +1446,9 @@ SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* cu, uint32_t cu_
DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
if (m_debug_map_symfile)
m_debug_map_symfile->SetCompileUnit(this, dc_cu);
}
}
return (CompileUnit*)cu->GetUserData();
@ -1673,6 +1710,7 @@ SymbolFileDWARF::Index ()
m_function_fullname_index,
m_function_method_index,
m_function_selector_index,
m_objc_class_selectors_index,
m_global_index,
m_types_index,
DebugRanges(),
@ -1686,13 +1724,14 @@ SymbolFileDWARF::Index ()
m_aranges->Sort();
#if 0
#if 0
StreamFile s(stdout);
s.Printf("DWARF index for '%s':", GetObjectFile()->GetFileSpec().GetFilename().AsCString());
s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
s.Printf("\nTypes:\n"); m_types_index.Dump (&s);
#endif
@ -2975,9 +3014,10 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
for (uint32_t i=0; i<match_count; ++i)
{
Type *type = types.GetTypeAtIndex (i).get();
if (ClangASTContext::IsObjCClassType (type->GetClangType()))
clang_type_t type_clang_forward_type = type->GetClangForwardType();
if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
{
class_opaque_type = type->GetClangType();
class_opaque_type = type_clang_forward_type;
break;
}
}
@ -3216,6 +3256,10 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
{
// We are ready to put this type into the uniqued list up at the module level
TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
if (m_debug_map_symfile)
m_debug_map_symfile->GetObjectFile()->GetModule()->GetTypeList()->InsertUnique (uniqued_type_sp);
type_sp = uniqued_type_sp;
m_die_to_type[die] = type_sp.get();
}

View File

@ -49,6 +49,7 @@ class DWARFDebugPubnames;
class DWARFDebugRanges;
class DWARFDIECollection;
class DWARFFormValue;
class SymbolFileDWARFDebugMap;
class SymbolFileDWARF : public lldb_private::SymbolFile
{
@ -196,9 +197,6 @@ protected:
flagsGotDebugPubTypesData = (1 << 8),
flagsGotDebugRangesData = (1 << 9),
flagsGotDebugStrData = (1 << 10),
// True if this is a .o file used when resolving a N_OSO entry with
// debug maps.
flagsDWARFIsOSOForDebugMap = (1 << 16)
};
DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF);
@ -288,6 +286,12 @@ protected:
void Index();
void SetDebugMapSymfile (SymbolFileDWARFDebugMap *debug_map_symfile)
{
m_debug_map_symfile = debug_map_symfile;
}
SymbolFileDWARFDebugMap* m_debug_map_symfile;
lldb_private::Flags m_flags;
lldb_private::DataExtractor m_dwarf_data;
lldb_private::DataExtractor m_data_debug_abbrev;
@ -308,6 +312,7 @@ protected:
NameToDIE m_function_fullname_index; // All concrete functions
NameToDIE m_function_method_index; // All inlined functions
NameToDIE m_function_selector_index; // All method names for functions of classes
NameToDIE m_objc_class_selectors_index; // Given a class name, find all selectors for the class
NameToDIE m_global_index; // Global and static variables
NameToDIE m_types_index; // All type DIE offsets
bool m_indexed;

View File

@ -227,10 +227,10 @@ SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit
// comp_unit_info->oso_dwarf_sp.reset (oso_dwarf);
if (comp_unit_info->oso_symbol_vendor)
{
// Set a bit that lets this DWARF file know that it is being
// used along with a debug map and that it will have the
// remapped sections that we do below.
((SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile())->GetFlags().Set(SymbolFileDWARF::flagsDWARFIsOSOForDebugMap);
// Set a a pointer to this class to set our OSO DWARF file know
// that the DWARF is being used along with a debug map and that
// it will have the remapped sections that we do below.
((SymbolFileDWARF *)comp_unit_info->oso_symbol_vendor->GetSymbolFile())->SetDebugMapSymfile(this);
comp_unit_info->debug_map_sections_sp.reset(new SectionList);
Symtab *exe_symtab = m_obj_file->GetSymtab();
@ -506,6 +506,10 @@ SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
so_symbol->GetMangled().GetName().AsCString(),
cu_idx,
eLanguageTypeUnknown));
// Let our symbol vendor know about this compile unit
m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (m_compile_unit_infos[cu_idx].oso_compile_unit_sp,
cu_idx);
}
}
}
@ -966,3 +970,24 @@ SymbolFileDWARFDebugMap::EnablePluginLogging (Stream *strm, Args &command)
}
void
SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
{
const uint32_t cu_count = GetNumCompileUnits();
for (uint32_t i=0; i<cu_count; ++i)
{
if (m_compile_unit_infos[i].oso_symbol_vendor &&
m_compile_unit_infos[i].oso_symbol_vendor->GetSymbolFile() == oso_dwarf)
{
if (m_compile_unit_infos[i].oso_compile_unit_sp)
{
assert (m_compile_unit_infos[i].oso_compile_unit_sp.get() == cu_sp.get());
}
else
{
m_compile_unit_infos[i].oso_compile_unit_sp = cu_sp;
}
}
}
}

View File

@ -98,6 +98,8 @@ protected:
kNumFlags
};
friend class SymbolFileDWARF;
//------------------------------------------------------------------
// Class specific types
//------------------------------------------------------------------
@ -184,6 +186,10 @@ protected:
uint32_t max_matches,
lldb_private::VariableList& variables);
void
SetCompileUnit (SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp);
//------------------------------------------------------------------
// Member Variables
//------------------------------------------------------------------

View File

@ -1559,12 +1559,22 @@ ClangASTContext::AddMethodToObjCObjectType
return NULL;
llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
size_t len;
size_t len = 0;
const char *start;
for (start = selector_start, len = ::strcspn(start, ":]");
//printf ("name = '%s'\n", name);
unsigned num_selectors_with_args = 0;
for (start = selector_start;
start && *start != '\0' && *start != ']';
start += len + 1)
start += len)
{
len = ::strcspn(start, ":]");
if (start[len] == ':')
{
++num_selectors_with_args;
len += 1;
}
//printf ("@selector[%zu] = '%.*s'\n", selector_idents.size(), (int)len, start);
selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
}
@ -1572,7 +1582,7 @@ ClangASTContext::AddMethodToObjCObjectType
if (selector_idents.size() == 0)
return 0;
clang::Selector method_selector = ast_context->Selectors.getSelector (selector_idents.size(),
clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0,
selector_idents.data());
QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));

View File

@ -96,8 +96,7 @@ SymbolVendor::AddSymbolFileRepresendation(ObjectFile *obj_file)
}
bool
SymbolVendor::SetCompileUnitAtIndex
(CompUnitSP& cu, uint32_t idx)
SymbolVendor::SetCompileUnitAtIndex (CompUnitSP& cu, uint32_t idx)
{
Mutex::Locker locker(m_mutex);
const uint32_t num_compile_units = GetNumCompileUnits();