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
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 87806a0..196bec8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1614,27 +1614,46 @@
{
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 @@
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 @@
}
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 @@
m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
ClangASTContext::SetHasExternalStorage (clang_type, true);
}
+
}
break;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index b860ee3..e7b0ff7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -279,6 +279,7 @@
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,