mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-21 00:06:58 +00:00
Allow adding members to decl-only classes making them defined classes
* include/abg-fwd.h (lookup_type_in_scope)
(lookup_var_decl_in_scope): New declarations.
* include/abg-ir.h (class_decl::get_is_declaration_only): Rename
is_declaration_only on this.
(class_decl::set_is_declaration_only):
* src/abg-comparison.cc (try_to_diff<class_decl>)
(class_diff::ensure_lookup_tables_populated)
(scope_diff::ensure_lookup_tables_populated): Update for the
get_is_declaration_only renaming.
* src/abg-dwarf-reader.cc (get_scope_for_die): Likewize.
(build_class_type_and_add_to_ir): Make sure that a member type or
data member is not already present in the class before adding it.
Also, if a decl-only class gets a data member, it's not a
decl-only class anymore.
* src/abg-hash.cc (class_decl:#️⃣:operator()): Update for the
get_is_declaration_only renaming.
* src/abg-ir.cc (scope_decl::find_iterator_for_member)
(look_through_decl_only_class): Likewise.
(lookup_type_in_scope, lookup_var_decl_in_scope, get_node_name)
(convert_node_to_decl, lookup_node_in_scope)
(lookup_type_in_scope): New definitions.
(class_decl::{set_definition_of_declaration,
set_earlier_declaration, operator==}): Update for the
get_is_declaration_only renaming.
* src/abg-reader.cc (build_class_decl): Likewise.
* src/abg-writer.cc (write_class_is_declaration_only): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
9fcd72ca39
commit
df7c672219
@ -237,6 +237,22 @@ const shared_ptr<decl_base>
|
||||
lookup_type_in_translation_unit(const std::list<string>&,
|
||||
const translation_unit&);
|
||||
|
||||
const shared_ptr<decl_base>
|
||||
lookup_type_in_scope(const string&,
|
||||
const shared_ptr<scope_decl>);
|
||||
|
||||
const shared_ptr<decl_base>
|
||||
lookup_type_in_scope(const std::list<string>&,
|
||||
const shared_ptr<scope_decl>);
|
||||
|
||||
const shared_ptr<decl_base>
|
||||
lookup_var_decl_in_scope(const string&,
|
||||
const shared_ptr<scope_decl>);
|
||||
|
||||
const shared_ptr<decl_base>
|
||||
lookup_var_decl_in_scope(const std::list<string>&,
|
||||
const shared_ptr<scope_decl>);
|
||||
|
||||
string
|
||||
demangle_cplus_mangled_name(const string&);
|
||||
|
||||
|
@ -1761,9 +1761,13 @@ public:
|
||||
get_pretty_representation() const;
|
||||
|
||||
bool
|
||||
is_declaration_only() const
|
||||
get_is_declaration_only() const
|
||||
{return is_declaration_only_;}
|
||||
|
||||
void
|
||||
set_is_declaration_only(bool f)
|
||||
{is_declaration_only_ = f;}
|
||||
|
||||
bool
|
||||
is_struct() const
|
||||
{return is_struct_;}
|
||||
|
@ -434,13 +434,13 @@ try_to_diff<class_decl>(const decl_base_sptr first,
|
||||
dynamic_pointer_cast<class_decl>(first))
|
||||
{
|
||||
class_decl_sptr s = dynamic_pointer_cast<class_decl>(second);
|
||||
if (f->is_declaration_only())
|
||||
if (f->get_is_declaration_only())
|
||||
{
|
||||
class_decl_sptr f2 = f->get_definition_of_declaration();
|
||||
if (f2)
|
||||
f = f2;
|
||||
}
|
||||
if (s->is_declaration_only())
|
||||
if (s->get_is_declaration_only())
|
||||
{
|
||||
class_decl_sptr s2 = s->get_definition_of_declaration();
|
||||
if (s2)
|
||||
@ -1979,7 +1979,7 @@ class_diff::ensure_lookup_tables_populated(void) const
|
||||
unsigned i = it->index();
|
||||
decl_base_sptr d = first_class_decl()->get_member_types()[i];
|
||||
class_decl_sptr klass_decl = as_non_member_class_decl(d);
|
||||
if (klass_decl && klass_decl->is_declaration_only())
|
||||
if (klass_decl && klass_decl->get_is_declaration_only())
|
||||
continue;
|
||||
string qname = d->get_qualified_name();
|
||||
priv_->deleted_member_types_[qname] = d;
|
||||
@ -1997,7 +1997,7 @@ class_diff::ensure_lookup_tables_populated(void) const
|
||||
unsigned i = *iit;
|
||||
decl_base_sptr d = second_class_decl()->get_member_types()[i];
|
||||
class_decl_sptr klass_decl = as_non_member_class_decl(d);
|
||||
if (klass_decl && klass_decl->is_declaration_only())
|
||||
if (klass_decl && klass_decl->get_is_declaration_only())
|
||||
continue;
|
||||
string qname = d->get_qualified_name();
|
||||
string_decl_base_sptr_map::const_iterator j =
|
||||
@ -2954,7 +2954,7 @@ scope_diff::ensure_lookup_tables_populated()
|
||||
if (is_type(decl))
|
||||
{
|
||||
class_decl_sptr klass_decl = dynamic_pointer_cast<class_decl>(decl);
|
||||
if (klass_decl && klass_decl->is_declaration_only())
|
||||
if (klass_decl && klass_decl->get_is_declaration_only())
|
||||
continue;
|
||||
|
||||
assert(priv_->deleted_types_.find(qname)
|
||||
@ -2984,7 +2984,7 @@ scope_diff::ensure_lookup_tables_populated()
|
||||
{
|
||||
class_decl_sptr klass_decl =
|
||||
dynamic_pointer_cast<class_decl>(decl);
|
||||
if (klass_decl && klass_decl->is_declaration_only())
|
||||
if (klass_decl && klass_decl->get_is_declaration_only())
|
||||
continue;
|
||||
|
||||
assert(priv_->inserted_types_.find(qname)
|
||||
|
@ -1926,7 +1926,7 @@ get_scope_for_die(read_context& ctxt,
|
||||
assert(s);
|
||||
|
||||
class_decl_sptr cl = as_non_member_class_decl(d);
|
||||
if (cl && cl->is_declaration_only())
|
||||
if (cl && cl->get_is_declaration_only())
|
||||
{
|
||||
scope_decl_sptr scop (cl->get_definition_of_declaration());
|
||||
if (scop)
|
||||
@ -2234,14 +2234,15 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
|
||||
decl_base_sptr res;
|
||||
if (klass)
|
||||
result = klass;
|
||||
res = result = klass;
|
||||
else
|
||||
{
|
||||
result.reset(new class_decl(name, size, 0, is_struct, loc,
|
||||
decl_base::VISIBILITY_DEFAULT));
|
||||
|
||||
if (is_declaration_only)
|
||||
result.reset(new class_decl(name, is_struct));
|
||||
else
|
||||
result.reset(new class_decl(name, size, 0, is_struct, loc,
|
||||
decl_base::VISIBILITY_DEFAULT));
|
||||
result->set_is_declaration_only(true);
|
||||
|
||||
res = add_decl_to_scope(result, scope);
|
||||
result = dynamic_pointer_cast<class_decl>(as_non_member_type(res));
|
||||
assert(result);
|
||||
@ -2269,7 +2270,7 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
// Handle base classes.
|
||||
if (tag == DW_TAG_inheritance)
|
||||
{
|
||||
assert(!result->is_declaration_only());
|
||||
result->set_is_declaration_only(false);
|
||||
|
||||
Dwarf_Die type_die;
|
||||
if (!die_die_attribute(&child, DW_AT_type, type_die))
|
||||
@ -2281,6 +2282,8 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
class_decl_sptr b = dynamic_pointer_cast<class_decl>(base_type);
|
||||
if (!b)
|
||||
continue;
|
||||
if (lookup_type_in_scope(base_type->get_name(), result))
|
||||
continue;
|
||||
|
||||
class_decl::access_specifier access =
|
||||
is_struct
|
||||
@ -2306,7 +2309,7 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
else if (tag == DW_TAG_member
|
||||
|| tag == DW_TAG_variable)
|
||||
{
|
||||
assert(!result->is_declaration_only());
|
||||
result->set_is_declaration_only(false);
|
||||
|
||||
Dwarf_Die type_die;
|
||||
if (!die_die_attribute(&child, DW_AT_type, type_die))
|
||||
@ -2322,6 +2325,8 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
string n, m;
|
||||
location loc;
|
||||
die_loc_and_name(ctxt, &child, loc, n, m);
|
||||
if (lookup_var_decl_in_scope(n, result))
|
||||
continue;
|
||||
|
||||
ssize_t offset_in_bits = 0;
|
||||
bool is_laid_out = false;
|
||||
|
@ -524,7 +524,7 @@ struct class_decl::hash
|
||||
|
||||
size_t v = hash_string(typeid(t).name());
|
||||
v = hashing::combine_hashes(v, hash_scope_type(t));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.is_declaration_only()));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.get_is_declaration_only()));
|
||||
|
||||
t.hashing_started(true);
|
||||
|
||||
|
215
src/abg-ir.cc
215
src/abg-ir.cc
@ -657,7 +657,7 @@ scope_decl::find_iterator_for_member(const decl_base* decl,
|
||||
declarations::iterator& i)
|
||||
{
|
||||
if (class_decl* klass = dynamic_cast<class_decl*>(this))
|
||||
assert(!klass->is_declaration_only());
|
||||
assert(!klass->get_is_declaration_only());
|
||||
|
||||
if (!decl)
|
||||
return false;
|
||||
@ -670,7 +670,7 @@ scope_decl::find_iterator_for_member(const decl_base* decl,
|
||||
|
||||
const class_decl* is_class = dynamic_cast<const class_decl*>(decl);
|
||||
if (is_class)
|
||||
assert(!is_class->is_declaration_only());
|
||||
assert(!is_class->get_is_declaration_only());
|
||||
|
||||
string qual_name1 = decl->get_qualified_name();
|
||||
for (declarations::iterator it = get_member_decls().begin();
|
||||
@ -685,7 +685,7 @@ scope_decl::find_iterator_for_member(const decl_base* decl,
|
||||
class_decl_sptr cur_class =
|
||||
dynamic_pointer_cast<class_decl>(*it);
|
||||
assert(cur_class);
|
||||
if (cur_class->is_declaration_only())
|
||||
if (cur_class->get_is_declaration_only())
|
||||
continue;
|
||||
}
|
||||
i = it;
|
||||
@ -1149,7 +1149,7 @@ look_through_decl_only_class(class_decl_sptr klass)
|
||||
return klass;
|
||||
|
||||
while (klass
|
||||
&& klass->is_declaration_only()
|
||||
&& klass->get_is_declaration_only()
|
||||
&& klass->get_definition_of_declaration())
|
||||
klass = klass->get_definition_of_declaration();
|
||||
|
||||
@ -1274,27 +1274,142 @@ lookup_type_in_translation_unit(const string& fqn,
|
||||
return lookup_type_in_translation_unit(comps, tu);
|
||||
}
|
||||
|
||||
/// Lookup an IR node from a translation unit.
|
||||
/// Lookup a type in a scope.
|
||||
///
|
||||
/// @tparam NodeKind the type of the IR node to lookup from the
|
||||
/// translation unit.
|
||||
/// @param fqn the fully qualified name of the type to lookup.
|
||||
///
|
||||
/// @param fqn the components of the fully qualified name of the node
|
||||
/// to look up.
|
||||
/// @param skope the scope to look into.
|
||||
///
|
||||
/// @param tu the translation unit to perform lookup from.
|
||||
/// @return the declaration of the type if found, NULL otherwise.
|
||||
const decl_base_sptr
|
||||
lookup_type_in_scope(const string& fqn,
|
||||
const scope_decl_sptr skope)
|
||||
{
|
||||
list<string> comps;
|
||||
fqn_to_components(fqn, comps);
|
||||
return lookup_type_in_scope(comps, skope);
|
||||
}
|
||||
|
||||
/// Lookup a @ref var_decl in a scope.
|
||||
///
|
||||
/// @return the declaration of the IR node found, NULL otherwise.
|
||||
/// @param fqn the fuly qualified name of the @var_decl to lookup.
|
||||
///
|
||||
/// @param skope the scope to look into.
|
||||
///
|
||||
/// @return the declaration of the @ref var_decl if found, NULL
|
||||
/// otherwise.
|
||||
const decl_base_sptr
|
||||
lookup_var_decl_in_scope(const string& fqn,
|
||||
const scope_decl_sptr skope)
|
||||
{
|
||||
list<string> comps;
|
||||
fqn_to_components(fqn, comps);
|
||||
return lookup_var_decl_in_scope(comps, skope);
|
||||
}
|
||||
|
||||
/// A generic function (template) to get the name of a node, whatever
|
||||
/// node it is. This has to specialized for the kind of node we want
|
||||
///
|
||||
/// @tparam NodeKind the kind of node to consider.
|
||||
///
|
||||
/// @param node the node to get the name from.
|
||||
///
|
||||
/// @return the name of the node.
|
||||
template<typename NodeKind>
|
||||
static const string&
|
||||
get_node_name(shared_ptr<NodeKind> node);
|
||||
|
||||
/// Gets the name of a decl_base node.
|
||||
///
|
||||
/// @param node the decl_base node to get the name from.
|
||||
///
|
||||
/// @return the name of the node.
|
||||
template<>
|
||||
const string&
|
||||
get_node_name(decl_base_sptr node)
|
||||
{return node->get_name();}
|
||||
|
||||
/// Gets the name of a type_base node.
|
||||
///
|
||||
/// @param node the type_base node to get the name from.
|
||||
///
|
||||
/// @return the name of the node.
|
||||
template<>
|
||||
const string&
|
||||
get_node_name(type_base_sptr node)
|
||||
{return get_type_declaration(as_non_member_type(node))->get_name();}
|
||||
|
||||
/// Gets the name of a var_decl node.
|
||||
///
|
||||
/// @param node the var_decl node to get the name from.
|
||||
///
|
||||
/// @return the name of the node.
|
||||
template<>
|
||||
const string&
|
||||
get_node_name(var_decl_sptr node)
|
||||
{return node->get_name();}
|
||||
|
||||
/// Generic function to get the declaration of a given node, whatever
|
||||
/// it is. There has to be specializations for the kind of the nodes
|
||||
/// we want to support.
|
||||
///
|
||||
/// @tparam NodeKind the type of the node we are looking at.
|
||||
///
|
||||
/// @return the declaration.
|
||||
template<typename NodeKind>
|
||||
static decl_base_sptr
|
||||
convert_node_to_decl(shared_ptr<NodeKind> node);
|
||||
|
||||
/// Get the declaration of a given decl_base node
|
||||
///
|
||||
/// @param node the decl_base node to consider.
|
||||
///
|
||||
/// @return the declaration of the node.
|
||||
template<>
|
||||
decl_base_sptr
|
||||
convert_node_to_decl(decl_base_sptr node)
|
||||
{return node;}
|
||||
|
||||
/// Get the declaration of a type_base node.
|
||||
///
|
||||
/// @param node the type node to consider.
|
||||
///
|
||||
/// @return the declaration of the type_base.
|
||||
template<>
|
||||
decl_base_sptr
|
||||
convert_node_to_decl(type_base_sptr node)
|
||||
{return get_type_declaration(node);}
|
||||
|
||||
/// Get the declaration of a var_decl.
|
||||
///
|
||||
/// @param node the var_decl to consider.
|
||||
///
|
||||
/// @return the declaration of the var_decl.
|
||||
template<>
|
||||
decl_base_sptr
|
||||
convert_node_to_decl(var_decl_sptr node)
|
||||
{return node;}
|
||||
|
||||
/// Lookup a node in a given scope.
|
||||
///
|
||||
/// @tparam the type of the node to lookup.
|
||||
///
|
||||
/// @param fqn the components of the fully qualified name of the the
|
||||
/// node to lookup.
|
||||
///
|
||||
/// @param skope the scope to look into.
|
||||
///
|
||||
/// @return the declaration of the lookuped node, or NULL if it wasn't
|
||||
/// found.
|
||||
template<typename NodeKind>
|
||||
static const decl_base_sptr
|
||||
lookup_node_in_translation_unit(const list<string>& fqn,
|
||||
const translation_unit& tu)
|
||||
lookup_node_in_scope(const list<string>& fqn,
|
||||
const scope_decl_sptr skope)
|
||||
{
|
||||
global_scope_sptr global_scope = tu.get_global_scope();
|
||||
scope_decl_sptr cur_scope = global_scope, new_scope, scope;
|
||||
decl_base_sptr resulting_type_decl;
|
||||
type_base_sptr type;
|
||||
decl_base_sptr resulting_decl;
|
||||
shared_ptr<NodeKind> node;
|
||||
bool it_is_last = false;
|
||||
scope_decl_sptr cur_scope = skope, new_scope, scope;
|
||||
|
||||
for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
|
||||
{
|
||||
@ -1318,22 +1433,60 @@ lookup_node_in_translation_unit(const list<string>& fqn,
|
||||
else
|
||||
{
|
||||
//looking for a final type.
|
||||
type = dynamic_pointer_cast<type_base>(*m);
|
||||
if (type && get_type_declaration(type)->get_name() == *c)
|
||||
if (node && get_node_name(node) == *c)
|
||||
{
|
||||
resulting_type_decl = get_type_declaration(type);
|
||||
resulting_decl = convert_node_to_decl(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!new_scope && !resulting_type_decl)
|
||||
if (!new_scope && !resulting_decl)
|
||||
return decl_base_sptr();
|
||||
cur_scope = new_scope;
|
||||
}
|
||||
assert(resulting_type_decl);
|
||||
return resulting_type_decl;
|
||||
assert(resulting_decl);
|
||||
return resulting_decl;
|
||||
}
|
||||
|
||||
/// lookup a type in a scope.
|
||||
///
|
||||
/// @param comps the components of the fully qualified name of the
|
||||
/// type to lookup.
|
||||
///
|
||||
/// @param skope the scope to look into.
|
||||
const decl_base_sptr
|
||||
lookup_type_in_scope(const list<string>& comps,
|
||||
const scope_decl_sptr skope)
|
||||
{return lookup_node_in_scope<type_base>(comps, skope);}
|
||||
|
||||
/// lookup a var_decl in a scope.
|
||||
///
|
||||
/// @param comps the components of the fully qualified name of the
|
||||
/// var_decl to lookup.
|
||||
///
|
||||
/// @param skope the scope to look into.
|
||||
const decl_base_sptr
|
||||
lookup_var_decl_in_scope(const std::list<string>& comps,
|
||||
const scope_decl_sptr skope)
|
||||
{return lookup_node_in_scope<var_decl>(comps, skope);}
|
||||
|
||||
/// Lookup an IR node from a translation unit.
|
||||
///
|
||||
/// @tparam NodeKind the type of the IR node to lookup from the
|
||||
/// translation unit.
|
||||
///
|
||||
/// @param fqn the components of the fully qualified name of the node
|
||||
/// to look up.
|
||||
///
|
||||
/// @param tu the translation unit to perform lookup from.
|
||||
///
|
||||
/// @return the declaration of the IR node found, NULL otherwise.
|
||||
template<typename NodeKind>
|
||||
static const decl_base_sptr
|
||||
lookup_node_in_translation_unit(const list<string>& fqn,
|
||||
const translation_unit& tu)
|
||||
{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
|
||||
|
||||
/// Lookup a type from a translation unit.
|
||||
///
|
||||
/// @param fqn the components of the fully qualified name of the node
|
||||
@ -2708,7 +2861,7 @@ class_decl::get_pretty_representation() const
|
||||
void
|
||||
class_decl::set_definition_of_declaration(class_decl_sptr d)
|
||||
{
|
||||
assert(is_declaration_only());
|
||||
assert(get_is_declaration_only());
|
||||
definition_of_declaration_ = d;
|
||||
}
|
||||
|
||||
@ -2720,7 +2873,7 @@ void
|
||||
class_decl::set_earlier_declaration(decl_base_sptr declaration)
|
||||
{
|
||||
class_decl_sptr cl = as_non_member_class_decl(declaration);
|
||||
if (cl && cl->is_declaration_only())
|
||||
if (cl && cl->get_is_declaration_only())
|
||||
declaration_ = declaration;
|
||||
}
|
||||
|
||||
@ -3317,20 +3470,20 @@ class_decl::operator==(const decl_base& other) const
|
||||
|
||||
// if one of the classes is declaration-only, look through it to
|
||||
// get its definition.
|
||||
if (is_declaration_only()
|
||||
|| o.is_declaration_only())
|
||||
if (get_is_declaration_only()
|
||||
|| o.get_is_declaration_only())
|
||||
{
|
||||
const class_decl* def1 = is_declaration_only()
|
||||
const class_decl* def1 = get_is_declaration_only()
|
||||
? get_definition_of_declaration().get()
|
||||
: this;
|
||||
|
||||
const class_decl* def2 = o.is_declaration_only()
|
||||
const class_decl* def2 = o.get_is_declaration_only()
|
||||
? o.get_definition_of_declaration().get()
|
||||
: op;
|
||||
|
||||
if (!def1 || !def2
|
||||
|| def1->is_declaration_only()
|
||||
|| def2->is_declaration_only())
|
||||
|| def1->get_is_declaration_only()
|
||||
|| def2->get_is_declaration_only())
|
||||
{
|
||||
string q1 = get_qualified_name();
|
||||
string q2 = o.get_qualified_name();
|
||||
|
@ -2105,7 +2105,7 @@ build_class_decl(read_context& ctxt,
|
||||
{
|
||||
shared_ptr<class_decl> d =
|
||||
dynamic_pointer_cast<class_decl>(ctxt.get_type_decl(def_id));
|
||||
if (d && d->is_declaration_only())
|
||||
if (d && d->get_is_declaration_only())
|
||||
{
|
||||
is_def_of_decl = true;
|
||||
decl->set_earlier_declaration(d);
|
||||
|
@ -581,7 +581,7 @@ write_cdtor_const_static(bool is_ctor,
|
||||
static void
|
||||
write_class_is_declaration_only(const shared_ptr<class_decl> klass, ostream& o)
|
||||
{
|
||||
if (klass->is_declaration_only())
|
||||
if (klass->get_is_declaration_only())
|
||||
o << " is-declaration-only='yes'";
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user