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:
Dodji Seketeli 2014-03-12 14:59:45 +01:00
parent 9fcd72ca39
commit df7c672219
8 changed files with 227 additions and 49 deletions

View File

@ -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&);

View File

@ -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_;}

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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'";
}