mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-21 00:06:58 +00:00
Fix hashing of member types
* include/abg-ir.h (class_decl::{member_function_template,
member_class_template}): Make these inherit from decl_base, to
comply with class_decl::member_type.
(class_decl_base_spec::{base_spec, member_type, member_function,
member_function_template, member_class_template}::hash): Declare
these hashing functors in the header here.
(class_decl::{member_base, member_type, data_member,
member_function, member_function_template,
member_class_template}:#️⃣:operator()): define these out of
line here.
(type_base::dynamic_hash::operator()): Update this to hash member
things.
* src/abg-writer.cc (write_qualified_type_def)
(write_pointer_type_def, write_class_decl)
(write_reference_type_def, write_enum_type_decl): Add an overload
that takes the type ID to use in the serialization.
(write_member_type): New implementation.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
fbe972012a
commit
be14ac2ab2
@ -2164,7 +2164,7 @@ operator==(class_decl::member_function_sptr l,
|
||||
|
||||
/// Abstract a member function template.
|
||||
class class_decl::member_function_template
|
||||
: public member_base, public virtual traversable_base
|
||||
: public member_base, public virtual decl_base
|
||||
{
|
||||
bool is_constructor_;
|
||||
bool is_const_;
|
||||
@ -2180,8 +2180,9 @@ public:
|
||||
member_function_template(function_tdecl_sptr f,
|
||||
access_specifier access, bool is_static,
|
||||
bool is_constructor, bool is_const)
|
||||
: member_base(access, is_static), is_constructor_(is_constructor),
|
||||
is_const_(is_const), fn_tmpl_(f)
|
||||
: decl_base(f->get_name(), location()),
|
||||
member_base(access, is_static), is_constructor_(is_constructor),
|
||||
is_const_(is_const), fn_tmpl_(f)
|
||||
{}
|
||||
|
||||
bool
|
||||
@ -2212,7 +2213,8 @@ operator==(class_decl::member_function_template_sptr l,
|
||||
|
||||
/// Abstracts a member class template template
|
||||
class class_decl::member_class_template
|
||||
: public member_base, public virtual traversable_base
|
||||
: public member_base,
|
||||
public virtual decl_base
|
||||
{
|
||||
shared_ptr<class_tdecl> class_tmpl_;
|
||||
|
||||
@ -2226,7 +2228,9 @@ public:
|
||||
|
||||
member_class_template(shared_ptr<class_tdecl> c,
|
||||
access_specifier access, bool is_static)
|
||||
: member_base(access, is_static), class_tmpl_(c)
|
||||
: decl_base(c->get_name(), location()),
|
||||
member_base(access, is_static),
|
||||
class_tmpl_(c)
|
||||
{}
|
||||
|
||||
operator const class_tdecl& () const
|
||||
@ -2274,6 +2278,55 @@ struct type_base::cached_hash
|
||||
operator() (const type_base_sptr t) const;
|
||||
};
|
||||
|
||||
/// The hashing functor for class_decl::base_spec.
|
||||
struct class_decl::base_spec::hash
|
||||
{
|
||||
size_t
|
||||
operator()(const base_spec& t) const;
|
||||
};
|
||||
|
||||
/// The hashing functor for class_decl::member_base.
|
||||
struct class_decl::member_base::hash
|
||||
{
|
||||
size_t
|
||||
operator()(const member_base& m) const;
|
||||
};
|
||||
|
||||
/// The hashing functor for class_decl::member_type.
|
||||
struct class_decl::member_type::hash
|
||||
{
|
||||
size_t
|
||||
operator()(const member_type& t) const ;
|
||||
};
|
||||
|
||||
/// The hashing functor for class_decl::data_member.
|
||||
struct class_decl::data_member::hash
|
||||
{
|
||||
size_t
|
||||
operator()(const data_member& t) const;
|
||||
};
|
||||
|
||||
/// The hashing functor for class_decl::member_function.
|
||||
struct class_decl::member_function::hash
|
||||
{
|
||||
size_t
|
||||
operator()(const member_function& t) const;
|
||||
};
|
||||
|
||||
/// The hashing functor for class_decl::member_function_template.
|
||||
struct class_decl::member_function_template::hash
|
||||
{
|
||||
size_t
|
||||
operator()(const member_function_template& t) const;
|
||||
};
|
||||
|
||||
/// The hashing functor for class_decl::member_class_template
|
||||
struct class_decl::member_class_template::hash
|
||||
{
|
||||
size_t
|
||||
operator()(const member_class_template& t) const;
|
||||
};
|
||||
|
||||
struct function_tdecl::hash
|
||||
{
|
||||
size_t
|
||||
|
201
src/abg-hash.cc
201
src/abg-hash.cc
@ -360,121 +360,117 @@ struct method_type::hash
|
||||
}
|
||||
};
|
||||
|
||||
struct class_decl::member_base::hash
|
||||
size_t
|
||||
class_decl::member_base::hash::operator()(const member_base& m) const
|
||||
{
|
||||
size_t
|
||||
operator()(const member_base& m) const
|
||||
{
|
||||
std::tr1::hash<int> hash_int;
|
||||
return hash_int(m.get_access_specifier());
|
||||
}
|
||||
};
|
||||
std::tr1::hash<int> hash_int;
|
||||
return hash_int(m.get_access_specifier());
|
||||
}
|
||||
|
||||
struct class_decl::member_type::hash
|
||||
size_t
|
||||
class_decl::member_type::hash::operator()(const member_type& t)const
|
||||
{
|
||||
size_t
|
||||
operator()(const member_type& t)const
|
||||
{
|
||||
member_base::hash hash_member;
|
||||
type_base::type_base::dynamic_hash hash_type;
|
||||
member_base::hash hash_member;
|
||||
type_base::type_base::dynamic_hash hash_type;
|
||||
std::tr1::hash<string> hash_string;
|
||||
|
||||
size_t v = hash_member(t);
|
||||
v = hashing::combine_hashes(v, hash_type(&t));
|
||||
return v;
|
||||
}
|
||||
};
|
||||
size_t v = hash_member(t);
|
||||
string n = t.get_qualified_name();
|
||||
v = hashing::combine_hashes(v, hash_string(n));
|
||||
v = hashing::combine_hashes(v, hash_type(t.get_underlying_type().get()));
|
||||
return v;
|
||||
}
|
||||
|
||||
struct class_decl::base_spec::hash
|
||||
size_t
|
||||
class_decl::base_spec::hash::operator()(const base_spec& t) const
|
||||
{
|
||||
size_t
|
||||
operator()(const base_spec& t) const
|
||||
{
|
||||
member_base::hash hash_member;
|
||||
type_base::shared_ptr_hash hash_type_ptr;
|
||||
member_base::hash hash_member;
|
||||
type_base::shared_ptr_hash hash_type_ptr;
|
||||
|
||||
size_t v = hash_member(t);
|
||||
v = hashing::combine_hashes(v, hash_type_ptr(t.get_base_class()));
|
||||
return v;
|
||||
}
|
||||
};
|
||||
size_t v = hash_member(t);
|
||||
v = hashing::combine_hashes(v, hash_type_ptr(t.get_base_class()));
|
||||
return v;
|
||||
}
|
||||
|
||||
struct class_decl::data_member::hash
|
||||
size_t
|
||||
class_decl::data_member::hash::operator()(const data_member& t) const
|
||||
{
|
||||
size_t
|
||||
operator()(data_member& t)
|
||||
{
|
||||
if (t.hash_ == 0)
|
||||
{
|
||||
std::tr1::hash<size_t> hash_size_t;
|
||||
var_decl::hash hash_var_decl;
|
||||
member_base::hash hash_member;
|
||||
if (t.hash_ == 0)
|
||||
{
|
||||
std::tr1::hash<size_t> hash_size_t;
|
||||
var_decl::hash hash_var_decl;
|
||||
member_base::hash hash_member;
|
||||
std::tr1::hash<string> hash_string;
|
||||
|
||||
size_t v = hash_member(t);
|
||||
v = hashing::combine_hashes(v, hash_var_decl(t));
|
||||
if (t.is_laid_out())
|
||||
v = hashing::combine_hashes(v, hash_size_t(t.get_offset_in_bits()));
|
||||
t.hash_ = v;
|
||||
}
|
||||
return t.hash_;
|
||||
}
|
||||
};
|
||||
size_t v = hash_member(t);
|
||||
string n = t.get_qualified_name();
|
||||
v = hashing::combine_hashes(v, hash_string(n));
|
||||
v = hashing::combine_hashes(v, hash_var_decl(t));
|
||||
if (t.is_laid_out())
|
||||
v = hashing::combine_hashes(v, hash_size_t(t.get_offset_in_bits()));
|
||||
t.hash_ = v;
|
||||
}
|
||||
return t.hash_;
|
||||
}
|
||||
|
||||
struct class_decl::member_function::hash
|
||||
size_t
|
||||
class_decl::member_function::hash::operator()(const member_function& t) const
|
||||
{
|
||||
size_t
|
||||
operator()(const member_function& t) const
|
||||
{
|
||||
if (t.hash_ == 0)
|
||||
{
|
||||
std::tr1::hash<bool> hash_bool;
|
||||
std::tr1::hash<size_t> hash_size_t;
|
||||
member_base::hash hash_member;
|
||||
function_decl::hash hash_fn;
|
||||
if (t.hash_ == 0)
|
||||
{
|
||||
std::tr1::hash<bool> hash_bool;
|
||||
std::tr1::hash<size_t> hash_size_t;
|
||||
member_base::hash hash_member;
|
||||
function_decl::hash hash_fn;
|
||||
std::tr1::hash<string> hash_string;
|
||||
|
||||
size_t v = hash_member(t);
|
||||
v = hashing::combine_hashes(v, hash_fn(t));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.is_constructor()));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.is_const()));
|
||||
size_t v = hash_member(t);
|
||||
string n = t.get_qualified_name();
|
||||
v = hashing::combine_hashes(v, hash_string(n));
|
||||
v = hashing::combine_hashes(v, hash_fn(t));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.is_constructor()));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.is_const()));
|
||||
|
||||
if (!t.is_static() && !t.is_constructor())
|
||||
v = hashing::combine_hashes(v,
|
||||
hash_size_t(t.get_vtable_offset()));
|
||||
t.hash_ = v;
|
||||
}
|
||||
return t.hash_;
|
||||
}
|
||||
};
|
||||
if (!t.is_static() && !t.is_constructor())
|
||||
v = hashing::combine_hashes(v,
|
||||
hash_size_t(t.get_vtable_offset()));
|
||||
t.hash_ = v;
|
||||
}
|
||||
return t.hash_;
|
||||
}
|
||||
|
||||
struct class_decl::member_function_template::hash
|
||||
size_t
|
||||
class_decl::member_function_template::hash::operator()
|
||||
(const member_function_template& t) const
|
||||
{
|
||||
size_t
|
||||
operator()(const member_function_template& t) const
|
||||
{
|
||||
std::tr1::hash<bool> hash_bool;
|
||||
function_tdecl::hash hash_function_tdecl;
|
||||
member_base::hash hash_member;
|
||||
std::tr1::hash<bool> hash_bool;
|
||||
function_tdecl::hash hash_function_tdecl;
|
||||
member_base::hash hash_member;
|
||||
std::tr1::hash<string> hash_string;
|
||||
|
||||
size_t v = hash_member(t);
|
||||
v = hashing::combine_hashes(v, hash_function_tdecl(t));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.is_constructor()));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.is_const()));
|
||||
return v;
|
||||
}
|
||||
};
|
||||
size_t v = hash_member(t);
|
||||
string n = t.get_qualified_name();
|
||||
v = hashing::combine_hashes(v, hash_string(n));
|
||||
v = hashing::combine_hashes(v, hash_function_tdecl(t));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.is_constructor()));
|
||||
v = hashing::combine_hashes(v, hash_bool(t.is_const()));
|
||||
return v;
|
||||
}
|
||||
|
||||
struct class_decl::member_class_template::hash
|
||||
size_t
|
||||
class_decl::member_class_template::hash::operator()
|
||||
(const member_class_template& t) const
|
||||
{
|
||||
size_t
|
||||
operator()(member_class_template& t) const
|
||||
{
|
||||
member_base::hash hash_member;
|
||||
class_tdecl::hash hash_class_tdecl;
|
||||
member_base::hash hash_member;
|
||||
class_tdecl::hash hash_class_tdecl;
|
||||
std::tr1::hash<string> hash_string;
|
||||
|
||||
size_t v = hash_member(t);
|
||||
v = hashing::combine_hashes(v, hash_class_tdecl(t));
|
||||
return v;
|
||||
}
|
||||
};
|
||||
size_t v = hash_member(t);
|
||||
string n = t.get_qualified_name();
|
||||
v = hashing::combine_hashes(v, hash_string(n));
|
||||
v = hashing::combine_hashes(v, hash_class_tdecl(t));
|
||||
return v;
|
||||
}
|
||||
|
||||
struct class_decl::hash
|
||||
{
|
||||
@ -746,6 +742,21 @@ type_base::dynamic_hash::operator()(const type_base* t) const
|
||||
{
|
||||
if (t == 0)
|
||||
return 0;
|
||||
if (const class_decl::member_type* d =
|
||||
dynamic_cast<const class_decl::member_type*>(t))
|
||||
return class_decl::member_type::hash()(*d);
|
||||
if (const class_decl::data_member* d =
|
||||
dynamic_cast<const class_decl::data_member*>(t))
|
||||
return class_decl::data_member::hash()(*d);
|
||||
if (const class_decl::member_function* d =
|
||||
dynamic_cast<const class_decl::member_function*>(t))
|
||||
return class_decl::member_function::hash()(*d);
|
||||
if (const class_decl::member_function_template* d =
|
||||
dynamic_cast<const class_decl::member_function_template*>(t))
|
||||
return class_decl::member_function_template::hash()(*d);
|
||||
if (const class_decl::member_class_template* d =
|
||||
dynamic_cast<const class_decl::member_class_template*>(t))
|
||||
return class_decl::member_class_template::hash()(*d);
|
||||
if (const template_tparameter* d =
|
||||
dynamic_cast<const template_tparameter*>(t))
|
||||
return template_tparameter::hash()(*d);
|
||||
|
@ -235,6 +235,8 @@ static bool write_var_decl(const shared_ptr<var_decl>,
|
||||
write_context&, bool, unsigned);
|
||||
static bool write_function_decl(const shared_ptr<function_decl>,
|
||||
write_context&, bool, unsigned);
|
||||
static bool write_member_type(const class_decl::member_type_sptr,
|
||||
write_context&, unsigned);
|
||||
static bool write_class_decl(const shared_ptr<class_decl>,
|
||||
write_context&, unsigned);
|
||||
static bool write_type_tparameter
|
||||
@ -833,6 +835,14 @@ write_namespace_decl(const shared_ptr<namespace_decl> decl,
|
||||
///
|
||||
/// @param decl the qualfied type declaration to write.
|
||||
///
|
||||
/// @param id the type id identitifier to use in the serialized
|
||||
/// output. If this is empty, the function will compute an
|
||||
/// appropriate one. This is useful when this function is called to
|
||||
/// serialize the underlying type of a member type; in that case, the
|
||||
/// caller has already computed the id of the *member type*, and that
|
||||
/// id is the one to be written as the value of the 'id' attribute of
|
||||
/// the XML element of the underlying type.
|
||||
///
|
||||
/// @param ctxt the write context.
|
||||
///
|
||||
/// @param indent the number of space to indent to during the
|
||||
@ -840,8 +850,10 @@ write_namespace_decl(const shared_ptr<namespace_decl> decl,
|
||||
///
|
||||
/// @return true upon successful completion, false otherwise.
|
||||
static bool
|
||||
write_qualified_type_def(const shared_ptr<qualified_type_def> decl,
|
||||
write_context& ctxt, unsigned indent)
|
||||
write_qualified_type_def(const shared_ptr<qualified_type_def> decl,
|
||||
const string& id,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
@ -861,10 +873,74 @@ write_qualified_type_def(const shared_ptr<qualified_type_def> decl,
|
||||
|
||||
write_location(static_pointer_cast<decl_base>(decl), o);
|
||||
|
||||
o<< " id='"
|
||||
<< ctxt.get_id_for_type(decl)
|
||||
string i = id;
|
||||
if (i.empty())
|
||||
i = ctxt.get_id_for_type(decl);
|
||||
|
||||
o<< " id='" << i << "'/>";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize a qualified type declaration to an output stream.
|
||||
///
|
||||
/// @param decl the qualfied type declaration to write.
|
||||
///
|
||||
/// @param ctxt the write context.
|
||||
///
|
||||
/// @param indent the number of space to indent to during the
|
||||
/// serialization.
|
||||
///
|
||||
/// @return true upon successful completion, false otherwise.
|
||||
static bool
|
||||
write_qualified_type_def(const shared_ptr<qualified_type_def> decl,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{return write_qualified_type_def(decl, "", ctxt, indent);}
|
||||
|
||||
/// Serialize a pointer to an instance of pointer_type_def.
|
||||
///
|
||||
/// @param decl the pointer_type_def to serialize.
|
||||
///
|
||||
/// @param id the type id identitifier to use in the serialized
|
||||
/// output. If this is empty, the function will compute an
|
||||
/// appropriate one. This is useful when this function is called to
|
||||
/// serialize the underlying type of a member type; in that case, the
|
||||
/// caller has already computed the id of the *member type*, and that
|
||||
/// id is the one to be written as the value of the 'id' attribute of
|
||||
/// the XML element of the underlying type.
|
||||
///
|
||||
/// @param ctxt the context of the serialization.
|
||||
///
|
||||
/// @param indent the number of indentation white spaces to use.
|
||||
///
|
||||
/// @return true upon succesful completion, false otherwise.
|
||||
static bool
|
||||
write_pointer_type_def(const shared_ptr<pointer_type_def> decl,
|
||||
const string& id,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
|
||||
ostream& o = ctxt.get_ostream();
|
||||
|
||||
do_indent(o, indent);
|
||||
|
||||
o << "<pointer-type-def type-id='"
|
||||
<< ctxt.get_id_for_type(decl->get_pointed_to_type())
|
||||
<< "'";
|
||||
|
||||
write_size_and_alignment(decl, o);
|
||||
|
||||
string i = id;
|
||||
if (i.empty())
|
||||
i = ctxt.get_id_for_type(decl);
|
||||
|
||||
o << " id='" << i << "'";
|
||||
|
||||
write_location(static_pointer_cast<decl_base>(decl), o);
|
||||
o << "/>";
|
||||
|
||||
return true;
|
||||
@ -881,41 +957,32 @@ write_qualified_type_def(const shared_ptr<qualified_type_def> decl,
|
||||
/// @return true upon succesful completion, false otherwise.
|
||||
static bool
|
||||
write_pointer_type_def(const shared_ptr<pointer_type_def> decl,
|
||||
write_context& ctxt, unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
|
||||
ostream& o = ctxt.get_ostream();
|
||||
|
||||
do_indent(o, indent);
|
||||
|
||||
o << "<pointer-type-def type-id='"
|
||||
<< ctxt.get_id_for_type(decl->get_pointed_to_type())
|
||||
<< "'";
|
||||
|
||||
write_size_and_alignment(decl, o);
|
||||
|
||||
o << " id='" << ctxt.get_id_for_type(decl) << "'";
|
||||
|
||||
write_location(static_pointer_cast<decl_base>(decl), o);
|
||||
o << "/>";
|
||||
|
||||
return true;
|
||||
}
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{return write_pointer_type_def(decl, "", ctxt, indent);}
|
||||
|
||||
/// Serialize a pointer to an instance of reference_type_def.
|
||||
///
|
||||
/// @param decl the reference_type_def to serialize.
|
||||
///
|
||||
/// @param id the type id identitifier to use in the serialized
|
||||
/// output. If this is empty, the function will compute an
|
||||
/// appropriate one. This is useful when this function is called to
|
||||
/// serialize the underlying type of a member type; in that case, the
|
||||
/// caller has already computed the id of the *member type*, and that
|
||||
/// id is the one to be written as the value of the 'id' attribute of
|
||||
/// the XML element of the underlying type.
|
||||
///
|
||||
/// @param ctxt the context of the serialization.
|
||||
///
|
||||
/// @param indent the number of indentation white spaces to use.
|
||||
///
|
||||
/// @return true upon succesful completion, false otherwise.
|
||||
static bool
|
||||
write_reference_type_def(const shared_ptr<reference_type_def> decl,
|
||||
write_context& ctxt, unsigned indent)
|
||||
write_reference_type_def(const shared_ptr<reference_type_def> decl,
|
||||
const string& id,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
@ -935,7 +1002,10 @@ write_reference_type_def(const shared_ptr<reference_type_def> decl,
|
||||
|
||||
write_size_and_alignment(decl, o);
|
||||
|
||||
o << " id='" << ctxt.get_id_for_type(decl) << "'";
|
||||
string i = id;
|
||||
if (i.empty())
|
||||
i = ctxt.get_id_for_type(decl);
|
||||
o << " id='" << i << "'";
|
||||
|
||||
write_location(static_pointer_cast<decl_base>(decl), o);
|
||||
|
||||
@ -943,9 +1013,9 @@ write_reference_type_def(const shared_ptr<reference_type_def> decl,
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize a pointer to an instance of enum_type_decl.
|
||||
/// Serialize a pointer to an instance of reference_type_def.
|
||||
///
|
||||
/// @param decl the enum_type_decl to serialize.
|
||||
/// @param decl the reference_type_def to serialize.
|
||||
///
|
||||
/// @param ctxt the context of the serialization.
|
||||
///
|
||||
@ -953,8 +1023,33 @@ write_reference_type_def(const shared_ptr<reference_type_def> decl,
|
||||
///
|
||||
/// @return true upon succesful completion, false otherwise.
|
||||
static bool
|
||||
write_enum_type_decl(const shared_ptr<enum_type_decl> decl,
|
||||
write_context& ctxt, unsigned indent)
|
||||
write_reference_type_def(const shared_ptr<reference_type_def> decl,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{return write_reference_type_def(decl, "", ctxt, indent);}
|
||||
|
||||
/// Serialize a pointer to an instance of enum_type_decl.
|
||||
///
|
||||
/// @param decl the enum_type_decl to serialize.
|
||||
///
|
||||
/// @param id the type id identitifier to use in the serialized
|
||||
/// output. If this is empty, the function will compute an
|
||||
/// appropriate one. This is useful when this function is called to
|
||||
/// serialize the underlying type of a member type; in that case, the
|
||||
/// caller has already computed the id of the *member type*, and that
|
||||
/// id is the one to be written as the value of the 'id' attribute of
|
||||
/// the XML element of the underlying type.
|
||||
///
|
||||
/// @param ctxt the context of the serialization.
|
||||
///
|
||||
/// @param indent the number of indentation white spaces to use.
|
||||
///
|
||||
/// @return true upon succesful completion, false otherwise.
|
||||
static bool
|
||||
write_enum_type_decl(const shared_ptr<enum_type_decl> decl,
|
||||
const string& id,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
@ -966,7 +1061,10 @@ write_enum_type_decl(const shared_ptr<enum_type_decl> decl,
|
||||
|
||||
write_location(decl, o);
|
||||
|
||||
o << " id='" << ctxt.get_id_for_type(decl) << "'>\n";
|
||||
string i = id;
|
||||
if (i.empty())
|
||||
i = ctxt.get_id_for_type(decl);
|
||||
o << " id='" << i << "'>\n";
|
||||
|
||||
do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
|
||||
o << "<underlying-type type-id='"
|
||||
@ -992,9 +1090,9 @@ write_enum_type_decl(const shared_ptr<enum_type_decl> decl,
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize a pointer to an instance of typedef_decl.
|
||||
/// Serialize a pointer to an instance of enum_type_decl.
|
||||
///
|
||||
/// @param decl the typedef_decl to serialize.
|
||||
/// @param decl the enum_type_decl to serialize.
|
||||
///
|
||||
/// @param ctxt the context of the serialization.
|
||||
///
|
||||
@ -1002,8 +1100,33 @@ write_enum_type_decl(const shared_ptr<enum_type_decl> decl,
|
||||
///
|
||||
/// @return true upon succesful completion, false otherwise.
|
||||
static bool
|
||||
write_typedef_decl(const shared_ptr<typedef_decl> decl,
|
||||
write_context& ctxt, unsigned indent)
|
||||
write_enum_type_decl(const shared_ptr<enum_type_decl> decl,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{return write_enum_type_decl(decl, "", ctxt, indent);}
|
||||
|
||||
/// Serialize a pointer to an instance of typedef_decl.
|
||||
///
|
||||
/// @param decl the typedef_decl to serialize.
|
||||
///
|
||||
/// @param id the type id identitifier to use in the serialized
|
||||
/// output. If this is empty, the function will compute an
|
||||
/// appropriate one. This is useful when this function is called to
|
||||
/// serialize the underlying type of a member type; in that case, the
|
||||
/// caller has already computed the id of the *member type*, and that
|
||||
/// id is the one to be written as the value of the 'id' attribute of
|
||||
/// the XML element of the underlying type.
|
||||
///
|
||||
/// @param ctxt the context of the serialization.
|
||||
///
|
||||
/// @param indent the number of indentation white spaces to use.
|
||||
///
|
||||
/// @return true upon succesful completion, false otherwise.
|
||||
static bool
|
||||
write_typedef_decl(const shared_ptr<typedef_decl> decl,
|
||||
const string& id,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
@ -1018,13 +1141,30 @@ write_typedef_decl(const shared_ptr<typedef_decl> decl,
|
||||
|
||||
write_location(decl, o);
|
||||
|
||||
o << " id='"
|
||||
<< ctxt.get_id_for_type(decl)
|
||||
<< "'/>";
|
||||
string i = id;
|
||||
if (i.empty())
|
||||
i = ctxt.get_id_for_type(decl);
|
||||
|
||||
o << " id='" << i << "'/>";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize a pointer to an instance of typedef_decl.
|
||||
///
|
||||
/// @param decl the typedef_decl to serialize.
|
||||
///
|
||||
/// @param ctxt the context of the serialization.
|
||||
///
|
||||
/// @param indent the number of indentation white spaces to use.
|
||||
///
|
||||
/// @return true upon succesful completion, false otherwise.
|
||||
static bool
|
||||
write_typedef_decl(const shared_ptr<typedef_decl> decl,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{return write_typedef_decl(decl, "", ctxt, indent);}
|
||||
|
||||
/// Serialize a pointer to an instances of var_decl.
|
||||
///
|
||||
/// @param decl the var_decl to serialize.
|
||||
@ -1153,17 +1293,27 @@ write_function_decl(const shared_ptr<function_decl> decl, write_context& ctxt,
|
||||
///
|
||||
/// @param decl the pointer to class_decl to serialize.
|
||||
///
|
||||
/// @param id the type id identitifier to use in the serialized
|
||||
/// output. If this is empty, the function will compute an
|
||||
/// appropriate one. This is useful when this function is called to
|
||||
/// serialize the underlying type of a member type; in that case, the
|
||||
/// caller has already computed the id of the *member type*, and that
|
||||
/// id is the one to be written as the value of the 'id' attribute of
|
||||
/// the XML element of the underlying type.
|
||||
///
|
||||
/// @param ctxt the context of the serialization.
|
||||
///
|
||||
/// @param indent the initial indentation to use.
|
||||
static bool
|
||||
write_class_decl(const shared_ptr<class_decl> decl,
|
||||
write_context& ctxt, unsigned indent)
|
||||
write_class_decl(const shared_ptr<class_decl> decl,
|
||||
const string& id,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
|
||||
ostream &o = ctxt.get_ostream();
|
||||
ostream& o = ctxt.get_ostream();
|
||||
|
||||
do_indent_to_level(ctxt, indent, 0);
|
||||
|
||||
@ -1181,11 +1331,14 @@ write_class_decl(const shared_ptr<class_decl> decl,
|
||||
{
|
||||
// This instance is the definition of an earlier declaration.
|
||||
o << " def-of-decl-id='"
|
||||
<< ctxt.get_id_for_type(decl->get_earlier_declaration())
|
||||
<< ctxt.get_id_for_type(is_type(decl->get_earlier_declaration()))
|
||||
<< "'";
|
||||
}
|
||||
|
||||
o << " id='" << ctxt.get_id_for_type(decl) << "'";
|
||||
string i = id;
|
||||
if (i.empty())
|
||||
i = ctxt.get_id_for_type(decl);
|
||||
o << " id='" << i << "'";
|
||||
if (decl->is_declaration_only() || decl->has_no_base_nor_member())
|
||||
o << "/>";
|
||||
else
|
||||
@ -1217,20 +1370,7 @@ write_class_decl(const shared_ptr<class_decl> decl,
|
||||
decl->get_member_types().begin();
|
||||
ti != decl->get_member_types().end();
|
||||
++ti)
|
||||
{
|
||||
do_indent(o, nb_ws);
|
||||
o << "<member-type";
|
||||
write_access(*ti, o);
|
||||
o << ">\n";
|
||||
|
||||
write_decl(dynamic_pointer_cast<decl_base>
|
||||
((*ti)->get_underlying_type()), ctxt,
|
||||
get_indent_to_level(ctxt, indent, 2));
|
||||
o << "\n";
|
||||
|
||||
do_indent_to_level(ctxt, indent, 1);
|
||||
o << "</member-type>\n";
|
||||
}
|
||||
write_member_type(*ti, ctxt, nb_ws);
|
||||
|
||||
for (class_decl::data_members::const_iterator data =
|
||||
decl->get_data_members().begin();
|
||||
@ -1329,6 +1469,72 @@ write_class_decl(const shared_ptr<class_decl> decl,
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize a class_decl type.
|
||||
///
|
||||
/// @param decl the pointer to class_decl to serialize.
|
||||
///
|
||||
/// @param ctxt the context of the serialization.
|
||||
///
|
||||
/// @param indent the initial indentation to use.
|
||||
static bool
|
||||
write_class_decl(const shared_ptr<class_decl> decl,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{return write_class_decl(decl, "", ctxt, indent);}
|
||||
|
||||
/// Serialize a member type.
|
||||
///
|
||||
/// Note that the id written as the value of the 'id' attribute of the
|
||||
/// underlying type is actually the id of the member type, not the one
|
||||
/// for the underying type. That id takes in account, the access
|
||||
/// specifier and the qualified name of the member type.
|
||||
///
|
||||
/// @param decl the declaration of the member type to serialize.
|
||||
///
|
||||
/// @param ctxt the write context to use.
|
||||
///
|
||||
/// @param indent the number of levels to use for indentation
|
||||
static bool
|
||||
write_member_type(const class_decl::member_type_sptr decl,
|
||||
write_context& ctxt, unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
|
||||
ostream& o = ctxt.get_ostream();
|
||||
|
||||
do_indent_to_level(ctxt, indent, 0);
|
||||
|
||||
o << "<member-type";
|
||||
write_access(decl, o);
|
||||
o << ">\n";
|
||||
|
||||
string id = ctxt.get_id_for_type(decl);
|
||||
|
||||
type_base_sptr ut = decl->get_underlying_type();
|
||||
assert(ut);
|
||||
|
||||
unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
|
||||
assert(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(ut),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(ut),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_reference_type_def(dynamic_pointer_cast<reference_type_def>(ut),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(ut),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_typedef_decl(dynamic_pointer_cast<typedef_decl>(ut),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_class_decl(dynamic_pointer_cast<class_decl>(ut),
|
||||
id, ctxt, nb_ws));
|
||||
o << "\n";
|
||||
|
||||
do_indent_to_level(ctxt, indent, 0);
|
||||
o << "</member-type>\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize an instance of type_tparameter.
|
||||
///
|
||||
/// @param decl the instance to serialize.
|
||||
|
Loading…
Reference in New Issue
Block a user