forked from OSchip/llvm-project
Fixed an issue where we are asking to get the decl context for a function
that is in a class from the expression parser, and it was causing an assertion. There is now a function that will correctly resolve a type even if it is in a class. llvm-svn: 146141
This commit is contained in:
parent
18c7920d6b
commit
cab36a3a59
|
@ -1614,27 +1614,46 @@ SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
|
|||
{
|
||||
DWARFCompileUnitSP cu_sp;
|
||||
const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
|
||||
if (type_die != NULL)
|
||||
{
|
||||
// We might be coming in in the middle of a type tree (a class
|
||||
// withing a class, an enum within a class), so parse any needed
|
||||
// parent DIEs before we get to this one...
|
||||
const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu_sp.get(), type_die);
|
||||
switch (decl_ctx_die->Tag())
|
||||
{
|
||||
case DW_TAG_structure_type:
|
||||
case DW_TAG_union_type:
|
||||
case DW_TAG_class_type:
|
||||
ResolveType(cu_sp.get(), decl_ctx_die);
|
||||
break;
|
||||
}
|
||||
return ResolveType (cu_sp.get(), type_die);
|
||||
}
|
||||
const bool assert_not_being_parsed = true;
|
||||
return ResolveTypeUID (cu_sp.get(), type_die, assert_not_being_parsed);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Type*
|
||||
SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed)
|
||||
{
|
||||
if (die != NULL)
|
||||
{
|
||||
// We might be coming in in the middle of a type tree (a class
|
||||
// withing a class, an enum within a class), so parse any needed
|
||||
// parent DIEs before we get to this one...
|
||||
const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
|
||||
switch (decl_ctx_die->Tag())
|
||||
{
|
||||
case DW_TAG_structure_type:
|
||||
case DW_TAG_union_type:
|
||||
case DW_TAG_class_type:
|
||||
{
|
||||
// Get the type, which could be a forward declaration
|
||||
Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
|
||||
// Now ask the type to complete itself if it already hasn't.
|
||||
// This will make the call to ResolveType below just use the
|
||||
// cached value that is already parsed for "die"
|
||||
if (parent_type)
|
||||
parent_type->GetClangFullType();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ResolveType (cu, die);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This function is used when SymbolFileDWARFDebugMap owns a bunch of
|
||||
// SymbolFileDWARF objects to detect if this DWARF file is the one that
|
||||
// can resolve a clang_type.
|
||||
|
@ -1858,8 +1877,10 @@ SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEnt
|
|||
if (type_die != NULL)
|
||||
{
|
||||
Type *type = m_die_to_type.lookup (type_die);
|
||||
|
||||
if (type == NULL)
|
||||
type = GetTypeForDIE (curr_cu, type_die).get();
|
||||
|
||||
if (assert_not_being_parsed)
|
||||
assert (type != DIE_IS_BEING_PARSED);
|
||||
return type;
|
||||
|
@ -3650,25 +3671,25 @@ SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebu
|
|||
}
|
||||
|
||||
clang::DeclContext *
|
||||
SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
|
||||
SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
|
||||
{
|
||||
clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
|
||||
if (clang_decl_ctx)
|
||||
return clang_decl_ctx;
|
||||
// If this DIE has a specification, or an abstract origin, then trace to those.
|
||||
|
||||
dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
|
||||
dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
|
||||
if (die_offset != DW_INVALID_OFFSET)
|
||||
return GetClangDeclContextForDIEOffset (sc, die_offset);
|
||||
|
||||
die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
|
||||
die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
|
||||
if (die_offset != DW_INVALID_OFFSET)
|
||||
return GetClangDeclContextForDIEOffset (sc, die_offset);
|
||||
|
||||
// This is the DIE we want. Parse it, then query our map.
|
||||
|
||||
ParseType(sc, curr_cu, die, NULL);
|
||||
|
||||
bool assert_not_being_parsed = true;
|
||||
ResolveTypeUID (cu, die, assert_not_being_parsed);
|
||||
|
||||
clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
|
||||
|
||||
return clang_decl_ctx;
|
||||
|
@ -4544,6 +4565,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
|
|||
m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
|
||||
ClangASTContext::SetHasExternalStorage (clang_type, true);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -279,6 +279,7 @@ protected:
|
|||
uint32_t depth);
|
||||
size_t ParseTypes (const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children);
|
||||
lldb::TypeSP ParseType (const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new);
|
||||
lldb_private::Type* ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed);
|
||||
|
||||
lldb::VariableSP ParseVariableDIE(
|
||||
const lldb_private::SymbolContext& sc,
|
||||
|
|
Loading…
Reference in New Issue