Don't cache type qualified name before canonicalization

Caching the qualified name of a given type has always been subject to
subtle bugs.  If the qualified name is queried (so it's computed)
before the type is added into its final content, then what is cached
is a non-qualified type name.  Later when the type is finally added to
its context, querying its qualified name will just yield the cached
non-qualified name.  And that has impact on hashing and comparison.

We needed a way to signal that the type is "fully built and added to
its final context".  When the type is fully built then we can cache
its qualified name.

This patch uses the presence of the canonical type as the signal; if
the canonical type is present then the type is fully built and added
to its final context.  And then at that point the cached qualified
name is used.

Note that this patch is the first of a series fixing several things
that influence hashing, comparison, the reading and writing of abixml.
It's only at the end of the series that an update to regression tests
is provided.  In between, some patches of the series are going to
"break" the regression tests.  That is fine.

	* src/abg-ir.cc (decl_base::{get_qualified_parent_name,
	get_qualified_name}): Use the qualified name cache only if the
	type is fully built, i.e, when its canonical type is present.
	(qualified_type_def::get_qualified_name): Likewise.
	(pointer_type_def::get_qualified_name): Likewise.
	(reference_type_def::get_qualified_name): Likewise.
	(array_type_def::get_qualified_name): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2015-08-25 16:07:33 +02:00
parent 72b42c3090
commit 173a2c9939

View File

@ -1897,7 +1897,9 @@ decl_base::get_scope() const
const string&
decl_base::get_qualified_parent_name() const
{
if (priv_->qualified_parent_name_.empty())
if (priv_->qualified_parent_name_.empty()
|| (is_type(this)
&& !is_type(this)->get_canonical_type()))
{
list<string> qn_components;
for (scope_decl* s = get_scope();
@ -1947,7 +1949,9 @@ decl_base::get_pretty_representation() const
const string&
decl_base::get_qualified_name() const
{
if (priv_->qualified_name_.empty())
if (priv_->qualified_name_.empty()
|| (is_type(this)
&& !is_type(this)->get_canonical_type()))
{
priv_->qualified_name_ = get_qualified_parent_name();
if (!get_name().empty())
@ -6114,7 +6118,8 @@ qualified_type_def::get_qualified_name(string& qualified_name) const
const string&
qualified_type_def::get_qualified_name() const
{
if (peek_qualified_name().empty())
if (peek_qualified_name().empty()
|| !get_canonical_type())
set_qualified_name(build_name(true));
return peek_qualified_name();
}
@ -6342,7 +6347,8 @@ pointer_type_def::get_qualified_name(string& qn) const
const string&
pointer_type_def::get_qualified_name() const
{
if (peek_qualified_name().empty())
if (peek_qualified_name().empty()
|| !get_canonical_type())
{
decl_base_sptr td =
get_type_declaration(get_pointed_to_type());
@ -6489,7 +6495,8 @@ reference_type_def::get_qualified_name(string& qn) const
const string&
reference_type_def::get_qualified_name() const
{
if (peek_qualified_name().empty())
if (peek_qualified_name().empty()
|| !get_canonical_type())
{
decl_base_sptr td =
get_type_declaration(type_or_void(get_pointed_to_type()));
@ -6803,7 +6810,8 @@ array_type_def::get_qualified_name(string& qn) const
const string&
array_type_def::get_qualified_name() const
{
if (decl_base::peek_qualified_name().empty())
if (decl_base::peek_qualified_name().empty()
|| !get_canonical_type())
set_qualified_name(get_type_representation(*this));
return decl_base::peek_qualified_name();
}