forked from OSchip/llvm-project
Moved byte-size computation out of a
startDefinition() ... endDefinition() block, preventing crashes where the byte size of a not-yet-complete type was being computed. llvm-svn: 151546
This commit is contained in:
parent
5e8636f36e
commit
77a1fd3f45
|
@ -1919,152 +1919,155 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
|
||||||
case DW_TAG_structure_type:
|
case DW_TAG_structure_type:
|
||||||
case DW_TAG_union_type:
|
case DW_TAG_union_type:
|
||||||
case DW_TAG_class_type:
|
case DW_TAG_class_type:
|
||||||
ast.StartTagDeclarationDefinition (clang_type);
|
|
||||||
{
|
{
|
||||||
LayoutInfo layout_info;
|
LayoutInfo layout_info;
|
||||||
if (die->HasChildren())
|
|
||||||
|
ast.StartTagDeclarationDefinition (clang_type);
|
||||||
{
|
{
|
||||||
|
if (die->HasChildren())
|
||||||
LanguageType class_language = eLanguageTypeUnknown;
|
|
||||||
bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
|
|
||||||
if (is_objc_class)
|
|
||||||
class_language = eLanguageTypeObjC;
|
|
||||||
|
|
||||||
int tag_decl_kind = -1;
|
|
||||||
AccessType default_accessibility = eAccessNone;
|
|
||||||
if (tag == DW_TAG_structure_type)
|
|
||||||
{
|
{
|
||||||
tag_decl_kind = clang::TTK_Struct;
|
|
||||||
default_accessibility = eAccessPublic;
|
|
||||||
}
|
|
||||||
else if (tag == DW_TAG_union_type)
|
|
||||||
{
|
|
||||||
tag_decl_kind = clang::TTK_Union;
|
|
||||||
default_accessibility = eAccessPublic;
|
|
||||||
}
|
|
||||||
else if (tag == DW_TAG_class_type)
|
|
||||||
{
|
|
||||||
tag_decl_kind = clang::TTK_Class;
|
|
||||||
default_accessibility = eAccessPrivate;
|
|
||||||
}
|
|
||||||
|
|
||||||
SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
|
|
||||||
std::vector<clang::CXXBaseSpecifier *> base_classes;
|
|
||||||
std::vector<int> member_accessibilities;
|
|
||||||
bool is_a_class = false;
|
|
||||||
// Parse members and base classes first
|
|
||||||
DWARFDIECollection member_function_dies;
|
|
||||||
|
|
||||||
ParseChildMembers (sc,
|
|
||||||
curr_cu,
|
|
||||||
die,
|
|
||||||
clang_type,
|
|
||||||
class_language,
|
|
||||||
base_classes,
|
|
||||||
member_accessibilities,
|
|
||||||
member_function_dies,
|
|
||||||
default_accessibility,
|
|
||||||
is_a_class,
|
|
||||||
layout_info);
|
|
||||||
|
|
||||||
// Now parse any methods if there were any...
|
|
||||||
size_t num_functions = member_function_dies.Size();
|
|
||||||
if (num_functions > 0)
|
|
||||||
{
|
|
||||||
for (size_t i=0; i<num_functions; ++i)
|
|
||||||
{
|
|
||||||
ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (class_language == eLanguageTypeObjC)
|
|
||||||
{
|
|
||||||
std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
|
|
||||||
if (!class_str.empty())
|
|
||||||
{
|
|
||||||
|
|
||||||
DIEArray method_die_offsets;
|
LanguageType class_language = eLanguageTypeUnknown;
|
||||||
if (m_using_apple_tables)
|
bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
|
||||||
|
if (is_objc_class)
|
||||||
|
class_language = eLanguageTypeObjC;
|
||||||
|
|
||||||
|
int tag_decl_kind = -1;
|
||||||
|
AccessType default_accessibility = eAccessNone;
|
||||||
|
if (tag == DW_TAG_structure_type)
|
||||||
|
{
|
||||||
|
tag_decl_kind = clang::TTK_Struct;
|
||||||
|
default_accessibility = eAccessPublic;
|
||||||
|
}
|
||||||
|
else if (tag == DW_TAG_union_type)
|
||||||
|
{
|
||||||
|
tag_decl_kind = clang::TTK_Union;
|
||||||
|
default_accessibility = eAccessPublic;
|
||||||
|
}
|
||||||
|
else if (tag == DW_TAG_class_type)
|
||||||
|
{
|
||||||
|
tag_decl_kind = clang::TTK_Class;
|
||||||
|
default_accessibility = eAccessPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
|
||||||
|
std::vector<clang::CXXBaseSpecifier *> base_classes;
|
||||||
|
std::vector<int> member_accessibilities;
|
||||||
|
bool is_a_class = false;
|
||||||
|
// Parse members and base classes first
|
||||||
|
DWARFDIECollection member_function_dies;
|
||||||
|
|
||||||
|
ParseChildMembers (sc,
|
||||||
|
curr_cu,
|
||||||
|
die,
|
||||||
|
clang_type,
|
||||||
|
class_language,
|
||||||
|
base_classes,
|
||||||
|
member_accessibilities,
|
||||||
|
member_function_dies,
|
||||||
|
default_accessibility,
|
||||||
|
is_a_class,
|
||||||
|
layout_info);
|
||||||
|
|
||||||
|
// Now parse any methods if there were any...
|
||||||
|
size_t num_functions = member_function_dies.Size();
|
||||||
|
if (num_functions > 0)
|
||||||
|
{
|
||||||
|
for (size_t i=0; i<num_functions; ++i)
|
||||||
{
|
{
|
||||||
if (m_apple_objc_ap.get())
|
ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
|
||||||
m_apple_objc_ap->FindByName(class_str.c_str(), method_die_offsets);
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (class_language == eLanguageTypeObjC)
|
||||||
|
{
|
||||||
|
std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
|
||||||
|
if (!class_str.empty())
|
||||||
{
|
{
|
||||||
if (!m_indexed)
|
|
||||||
Index ();
|
|
||||||
|
|
||||||
ConstString class_name (class_str.c_str());
|
DIEArray method_die_offsets;
|
||||||
m_objc_class_selectors_index.Find (class_name, method_die_offsets);
|
if (m_using_apple_tables)
|
||||||
}
|
|
||||||
|
|
||||||
if (!method_die_offsets.empty())
|
|
||||||
{
|
|
||||||
DWARFDebugInfo* debug_info = DebugInfo();
|
|
||||||
|
|
||||||
DWARFCompileUnit* method_cu = NULL;
|
|
||||||
const size_t num_matches = method_die_offsets.size();
|
|
||||||
for (size_t i=0; i<num_matches; ++i)
|
|
||||||
{
|
{
|
||||||
const dw_offset_t die_offset = method_die_offsets[i];
|
if (m_apple_objc_ap.get())
|
||||||
DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
|
m_apple_objc_ap->FindByName(class_str.c_str(), method_die_offsets);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!m_indexed)
|
||||||
|
Index ();
|
||||||
|
|
||||||
if (method_die)
|
ConstString class_name (class_str.c_str());
|
||||||
ResolveType (method_cu, method_die);
|
m_objc_class_selectors_index.Find (class_name, method_die_offsets);
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (!method_die_offsets.empty())
|
||||||
|
{
|
||||||
|
DWARFDebugInfo* debug_info = DebugInfo();
|
||||||
|
|
||||||
|
DWARFCompileUnit* method_cu = NULL;
|
||||||
|
const size_t num_matches = method_die_offsets.size();
|
||||||
|
for (size_t i=0; i<num_matches; ++i)
|
||||||
{
|
{
|
||||||
if (m_using_apple_tables)
|
const dw_offset_t die_offset = method_die_offsets[i];
|
||||||
|
DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
|
||||||
|
|
||||||
|
if (method_die)
|
||||||
|
ResolveType (method_cu, method_die);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_objc accelerator table had bad die 0x%8.8x for '%s')\n",
|
if (m_using_apple_tables)
|
||||||
die_offset, class_str.c_str());
|
{
|
||||||
}
|
GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_objc accelerator table had bad die 0x%8.8x for '%s')\n",
|
||||||
}
|
die_offset, class_str.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
if (is_a_class && tag_decl_kind != clang::TTK_Class)
|
||||||
|
ast.SetTagTypeKind (clang_type, clang::TTK_Class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since DW_TAG_structure_type gets used for both classes
|
||||||
|
// and structures, we may need to set any DW_TAG_member
|
||||||
|
// fields to have a "private" access if none was specified.
|
||||||
|
// When we parsed the child members we tracked that actual
|
||||||
|
// accessibility value for each DW_TAG_member in the
|
||||||
|
// "member_accessibilities" array. If the value for the
|
||||||
|
// member is zero, then it was set to the "default_accessibility"
|
||||||
|
// which for structs was "public". Below we correct this
|
||||||
|
// by setting any fields to "private" that weren't correctly
|
||||||
|
// set.
|
||||||
|
if (is_a_class && !member_accessibilities.empty())
|
||||||
|
{
|
||||||
|
// This is a class and all members that didn't have
|
||||||
|
// their access specified are private.
|
||||||
|
ast.SetDefaultAccessForRecordFields (clang_type,
|
||||||
|
eAccessPrivate,
|
||||||
|
&member_accessibilities.front(),
|
||||||
|
member_accessibilities.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!base_classes.empty())
|
||||||
|
{
|
||||||
|
ast.SetBaseClassesForClassType (clang_type,
|
||||||
|
&base_classes.front(),
|
||||||
|
base_classes.size());
|
||||||
|
|
||||||
|
// Clang will copy each CXXBaseSpecifier in "base_classes"
|
||||||
|
// so we have to free them all.
|
||||||
|
ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
|
||||||
|
base_classes.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
if (is_a_class && tag_decl_kind != clang::TTK_Class)
|
|
||||||
ast.SetTagTypeKind (clang_type, clang::TTK_Class);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since DW_TAG_structure_type gets used for both classes
|
|
||||||
// and structures, we may need to set any DW_TAG_member
|
|
||||||
// fields to have a "private" access if none was specified.
|
|
||||||
// When we parsed the child members we tracked that actual
|
|
||||||
// accessibility value for each DW_TAG_member in the
|
|
||||||
// "member_accessibilities" array. If the value for the
|
|
||||||
// member is zero, then it was set to the "default_accessibility"
|
|
||||||
// which for structs was "public". Below we correct this
|
|
||||||
// by setting any fields to "private" that weren't correctly
|
|
||||||
// set.
|
|
||||||
if (is_a_class && !member_accessibilities.empty())
|
|
||||||
{
|
|
||||||
// This is a class and all members that didn't have
|
|
||||||
// their access specified are private.
|
|
||||||
ast.SetDefaultAccessForRecordFields (clang_type,
|
|
||||||
eAccessPrivate,
|
|
||||||
&member_accessibilities.front(),
|
|
||||||
member_accessibilities.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!base_classes.empty())
|
|
||||||
{
|
|
||||||
ast.SetBaseClassesForClassType (clang_type,
|
|
||||||
&base_classes.front(),
|
|
||||||
base_classes.size());
|
|
||||||
|
|
||||||
// Clang will copy each CXXBaseSpecifier in "base_classes"
|
|
||||||
// so we have to free them all.
|
|
||||||
ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
|
|
||||||
base_classes.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
ast.CompleteTagDeclarationDefinition (clang_type);
|
||||||
|
|
||||||
if (!layout_info.field_offsets.empty())
|
if (!layout_info.field_offsets.empty())
|
||||||
{
|
{
|
||||||
|
@ -2087,7 +2090,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
|
||||||
layout_info.bit_size,
|
layout_info.bit_size,
|
||||||
layout_info.alignment,
|
layout_info.alignment,
|
||||||
(uint32_t)layout_info.field_offsets.size());
|
(uint32_t)layout_info.field_offsets.size());
|
||||||
|
|
||||||
llvm::DenseMap <const clang::FieldDecl *, uint64_t>::const_iterator pos, end = layout_info.field_offsets.end();
|
llvm::DenseMap <const clang::FieldDecl *, uint64_t>::const_iterator pos, end = layout_info.field_offsets.end();
|
||||||
for (pos = layout_info.field_offsets.begin(); pos != end; ++pos)
|
for (pos = layout_info.field_offsets.begin(); pos != end; ++pos)
|
||||||
{
|
{
|
||||||
|
@ -2102,7 +2105,7 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.CompleteTagDeclarationDefinition (clang_type);
|
|
||||||
return clang_type;
|
return clang_type;
|
||||||
|
|
||||||
case DW_TAG_enumeration_type:
|
case DW_TAG_enumeration_type:
|
||||||
|
|
Loading…
Reference in New Issue