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:
parent
01cbf2de0f
commit
450e3f3c77
|
@ -2438,6 +2438,7 @@
|
|||
isa = PBXProject;
|
||||
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
|
||||
compatibilityVersion = "Xcode 3.1";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
en,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue