Skip to content

Commit

Permalink
Fix handling of variant parts
Browse files Browse the repository at this point in the history
This fixes a couple of problems noticed while debugging the rust
compiler change to use DW_TAG_variant_part:

* IterableDIEChildren returned one extra DIE, because it did not
  preserve the CU in end()

* The entire block dealing with DW_TAG_variant_part was erroneously
  inside the DW_TAG_member case.
  • Loading branch information
tromey authored and nikic committed Sep 26, 2019
1 parent c51bafc commit efabcf5
Showing 1 changed file with 34 additions and 30 deletions.
64 changes: 34 additions & 30 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserRust.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class IterableDIEChildren

iterator end() const
{
return iterator(DWARFDIE());
return iterator(DWARFDIE(m_die.GetCU(), (DWARFDebugInfoEntry*) nullptr));
}

private:
Expand Down Expand Up @@ -611,38 +611,42 @@ DWARFASTParserRust::ParseFields(const DWARFDIE &die, std::vector<size_t> &discri
break;
}
}
}

if (child_die == discriminant_die) {
// This field is the discriminant, so don't push it, but instead
// record this for the caller.
saw_discr = true;
discr_offset = new_field.byte_offset;
discr_byte_size = m_ast.GetBitSize(new_field.compiler_type.GetOpaqueQualType(),
nullptr) / 8;
} else if (child_die.Tag() == DW_TAG_variant_part) {
// New-style enum representation -- nothing useful is in the
// enclosing struct, so we can just recurse here.
return ParseFields(child_die, discriminant_path, is_tuple,
discr_offset, discr_byte_size, saw_discr);
} else {
if (new_field.is_discriminant) {
// Don't check this field name, and don't increment field_index.
// When we see a tuple with fields like
// RUST$ENUM$DISR
// __0
// __1
// etc
// ... it means the tuple is a member type of an enum.
} else if (numeric_names) {
char buf[32];
snprintf (buf, sizeof (buf), "__%u", field_index);
if (!new_field.name || strcmp(new_field.name, buf) != 0)
numeric_names = false;
++field_index;
}
if (child_die == discriminant_die) {
// This field is the discriminant, so don't push it, but instead
// record this for the caller.
saw_discr = true;
discr_offset = new_field.byte_offset;

fields.push_back(new_field);
Type *type = die.ResolveTypeUID(DIERef(new_field.type));
if (type) {
lldb_private::CompilerType ctype = type->GetFullCompilerType();
discr_byte_size = m_ast.GetBitSize(ctype.GetOpaqueQualType(), nullptr) / 8;
}
} else if (child_die.Tag() == DW_TAG_variant_part) {
// New-style enum representation -- nothing useful is in the
// enclosing struct, so we can just recurse here.
return ParseFields(child_die, discriminant_path, is_tuple,
discr_offset, discr_byte_size, saw_discr);
} else {
if (new_field.is_discriminant) {
// Don't check this field name, and don't increment field_index.
// When we see a tuple with fields like
// RUST$ENUM$DISR
// __0
// __1
// etc
// ... it means the tuple is a member type of an enum.
} else if (numeric_names) {
char buf[32];
snprintf (buf, sizeof (buf), "__%u", field_index);
if (!new_field.name || strcmp(new_field.name, buf) != 0)
numeric_names = false;
++field_index;
}

fields.push_back(new_field);
}
}

Expand Down

0 comments on commit efabcf5

Please sign in to comment.