mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-17 07:24:34 +00:00
From DWARD, avoid adding IR nodes for member functions twice
* include/abg-fwd.h (as_non_member_class_decl): Declare new overload. * src/abg-ir.cc (as_non_member_class_decl): Define new overload. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Add member functions to the DIE -> IR Node map. (build_ir_node_from_die): Assert that DW_TAG_subprogram cannot be for a member function here because getting the scope of the member function would have constructed the entire class that contains it, including the member function. Then, calling build_ir_node_from_die for the DIE of the member function would find the already IR Node in the DIE -> IR Node map. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
a5b80d8203
commit
cc5af46601
@ -155,6 +155,9 @@ as_non_member_type(const shared_ptr<decl_base>);
|
||||
shared_ptr<class_decl>
|
||||
as_non_member_class_decl(const shared_ptr<decl_base>);
|
||||
|
||||
const class_decl*
|
||||
as_non_member_class_decl(const decl_base* t);
|
||||
|
||||
bool
|
||||
is_var_decl(const shared_ptr<decl_base>);
|
||||
|
||||
|
@ -2328,6 +2328,7 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
is_dtor,
|
||||
/*is_const*/false));
|
||||
result->add_member_function(mem_fun);
|
||||
ctxt.die_decl_map()[dwarf_dieoffset(&child)] = mem_fun;
|
||||
}
|
||||
// Handle member types
|
||||
else if (is_type_die(&child))
|
||||
@ -2976,9 +2977,21 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const class_decl* cl = as_non_member_class_decl(scope);
|
||||
// we shouldn't be in this class b/c, if this DIE is for a
|
||||
// member function, get_scope_for_die on it (prior to
|
||||
// calling this function) should have built the member
|
||||
// function for this DIE, and thus, this function should
|
||||
// have found the DIE for the member function in its cache.
|
||||
assert(!cl);
|
||||
}
|
||||
ctxt.scope_stack().push(scope);
|
||||
|
||||
if ((result = build_function_decl(ctxt, die, called_from_public_decl)))
|
||||
result = add_decl_to_scope(result, scope);
|
||||
|
||||
ctxt.scope_stack().pop();
|
||||
}
|
||||
break;
|
||||
|
@ -1094,6 +1094,27 @@ as_non_member_class_decl(const decl_base_sptr t)
|
||||
return dynamic_pointer_cast<class_decl>(t);
|
||||
}
|
||||
|
||||
/// Return the underlying class decl of a member class decl type.
|
||||
///
|
||||
/// If a given type is a member class decl, return its underlying
|
||||
/// class type.
|
||||
///
|
||||
/// @param t the member type to consider.
|
||||
///
|
||||
/// @return the underlying class decl of the member type given in
|
||||
/// parameter, if it's a member class decl. If the parameter was a
|
||||
/// non-member class decl, just return that class decl. Otherwise, it
|
||||
/// the parameter was not a class decl at all, return nil.
|
||||
const class_decl*
|
||||
as_non_member_class_decl(const decl_base* t)
|
||||
{
|
||||
const class_decl::member_type* m =
|
||||
dynamic_cast<const class_decl::member_type*>(t);
|
||||
if (m)
|
||||
return dynamic_cast<const class_decl*>(m->get_underlying_type().get());
|
||||
return dynamic_cast<const class_decl*>(t);
|
||||
}
|
||||
|
||||
/// Tests wheter a declaration is a variable declaration.
|
||||
///
|
||||
/// @param decl the decl to test.
|
||||
|
Loading…
Reference in New Issue
Block a user