mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-23 01:06:56 +00:00
Support pointer types & Fix IR types equality
* src/abg-ir.h (location::{operator==, operator<}) (decl_base::operator==, scope_decl::operator==) (type_base::operator==, struct type_shared_ptr_equal) (type_decl::operator==, scope_type::operator==) (qualified_type_def::operator==, class pointer_type_def): New declarations.. * src/abg-ir.cc (decl_base::operator==, scope_decl::operator==) (type_base::operator==, type_decl::operator==) (scope_type_decl::operator==, namespace_decl::operator==) (qualified_type_def::operator==) (pointer_type_def::pointer_type_def, pointer_type_def::operator==) (pointer_type_def::get_pointed_to_type) (pointer_type_def::~pointer_type_def): New definitions. * src/abg-reader.cc (handle_pointer_type_def): New definition. (read_input): Handle pointer-type-def elements. * src/abg-writer.cc (type_shared_ptr_map): Make this map use the use type_shared_ptr_equal predicate. (write_pointer_type_def): New definition. (write_decl): Improve logic. Support serializing a pointer to pointer_type_def. * tests/data/test-read-write/test4.xml: New test input file. * tests/Makefile.am: Add tests/data/test-read-write/test4.xml to the build system. * tests/test-read-write.cc: (De)serialize the new test file.
This commit is contained in:
parent
57d8b7da41
commit
d418d5198f
157
src/abg-ir.cc
157
src/abg-ir.cc
@ -4,7 +4,6 @@
|
||||
#include <iterator>
|
||||
#include <typeinfo>
|
||||
#include <tr1/memory>
|
||||
|
||||
#include "abg-ir.h"
|
||||
|
||||
using std::string;
|
||||
@ -159,6 +158,20 @@ decl_base::decl_base(const decl_base& d)
|
||||
m_context = d.m_context;
|
||||
}
|
||||
|
||||
/// Return true iff the two decls have the same name.
|
||||
///
|
||||
/// This function doesn't test if the scopes of the the two decls are
|
||||
/// equal.
|
||||
bool
|
||||
decl_base::operator==(const decl_base& other) const
|
||||
{
|
||||
// Runtime types must be equal.
|
||||
if (typeid(*this) != typeid(other))
|
||||
return false;
|
||||
|
||||
return get_name() == other.get_name();
|
||||
}
|
||||
|
||||
decl_base::~decl_base()
|
||||
{
|
||||
}
|
||||
@ -184,6 +197,34 @@ scope_decl::scope_decl(location l)
|
||||
{
|
||||
}
|
||||
|
||||
/// Return true iff both scopes have the same names and have the same
|
||||
/// member decls.
|
||||
///
|
||||
/// This function doesn't check for equality of the scopes of its
|
||||
/// arguments.
|
||||
bool
|
||||
scope_decl::operator==(const scope_decl& other) const
|
||||
{
|
||||
// Runtime types must be equal.
|
||||
if (typeid(*this) != typeid(other))
|
||||
return false;
|
||||
|
||||
if (static_cast<decl_base>(*this) != static_cast<decl_base>(other))
|
||||
return false;
|
||||
|
||||
std::list<shared_ptr<decl_base> >::const_iterator i, j;
|
||||
for (i = get_member_decls().begin(), j = other.get_member_decls().begin();
|
||||
i != get_member_decls().end() && j != other.get_member_decls().end();
|
||||
++i, ++j)
|
||||
if (**i != **j)
|
||||
return false;
|
||||
|
||||
if (i != get_member_decls().end() || j != other.get_member_decls().end())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Add a member decl to this scope. Note that user code should not
|
||||
/// use this, but rather use #add_decl_to_scope.
|
||||
///
|
||||
@ -229,6 +270,20 @@ type_base::type_base(size_t s = 8, size_t a = 8)
|
||||
{
|
||||
}
|
||||
|
||||
/// Return true iff both type declarations are equal.
|
||||
///
|
||||
/// Note that this doesn't test if the scopes of both types are equal.
|
||||
bool
|
||||
type_base::operator==(const type_base& other) const
|
||||
{
|
||||
// Runtime types must be equal.
|
||||
if (typeid(*this) != typeid(other))
|
||||
return false;
|
||||
|
||||
return (get_size_in_bits() == other.get_size_in_bits()
|
||||
&& get_alignment_in_bits() == other.get_alignment_in_bits());
|
||||
}
|
||||
|
||||
void
|
||||
type_base::set_size_in_bits(size_t s)
|
||||
{
|
||||
@ -270,6 +325,20 @@ type_decl::type_decl(const std::string& name,
|
||||
{
|
||||
}
|
||||
|
||||
/// Return true if both types equals.
|
||||
///
|
||||
/// Note that this does not check the scopes of any of the types.
|
||||
bool
|
||||
type_decl::operator==(const type_decl& other) const
|
||||
{
|
||||
// Runtime types must be equal.
|
||||
if (typeid(*this) != typeid(other))
|
||||
return false;
|
||||
|
||||
return (static_cast<decl_base>(*this) == other
|
||||
&& static_cast<type_base>(*this) == other);
|
||||
}
|
||||
|
||||
type_decl::~type_decl()
|
||||
{
|
||||
}
|
||||
@ -287,6 +356,21 @@ scope_type_decl::scope_type_decl(const std::string& name,
|
||||
{
|
||||
}
|
||||
|
||||
/// Return true iff both scope types are equal.
|
||||
///
|
||||
/// Note that this function does not consider the scope of the scope
|
||||
/// types themselves.
|
||||
bool
|
||||
scope_type_decl::operator==(const scope_type_decl& other) const
|
||||
{
|
||||
// Runtime types must be equal.
|
||||
if (typeid(*this) != typeid(other))
|
||||
return false;
|
||||
|
||||
return (static_cast<scope_decl>(*this) == other
|
||||
&& static_cast<type_base>(*this) == other);
|
||||
}
|
||||
|
||||
scope_type_decl::~scope_type_decl()
|
||||
{
|
||||
}
|
||||
@ -300,6 +384,20 @@ namespace_decl::namespace_decl(const std::string& name,
|
||||
{
|
||||
}
|
||||
|
||||
/// Return true iff both namespaces and their members are equal.
|
||||
///
|
||||
/// Note that this function does not check if the scope of these
|
||||
/// namespaces are equal.
|
||||
bool
|
||||
namespace_decl::operator==(const namespace_decl& other) const
|
||||
{
|
||||
// Runtime types must be equal.
|
||||
if (typeid(*this) != typeid(other))
|
||||
return false;
|
||||
|
||||
return (static_cast<scope_decl>(*this) == other);
|
||||
}
|
||||
|
||||
namespace_decl::~namespace_decl()
|
||||
{
|
||||
}
|
||||
@ -331,6 +429,24 @@ qualified_type_def::qualified_type_def(shared_ptr<type_base> type,
|
||||
set_name(get_name() + dynamic_pointer_cast<decl_base>(type)->get_name());
|
||||
}
|
||||
|
||||
/// Return true iff both qualified types are equal.
|
||||
///
|
||||
/// Note that this function does not check for equality of the scopes.
|
||||
bool
|
||||
qualified_type_def::operator==(const qualified_type_def& other) const
|
||||
{
|
||||
// Runtime types must be equal.
|
||||
if (typeid(*this) != typeid(other)
|
||||
|| get_cv_quals() != other.get_cv_quals()
|
||||
|| get_underlying_type() != other.get_underlying_type())
|
||||
return false;
|
||||
|
||||
if (shared_ptr<type_base> u = get_underlying_type())
|
||||
return (*u == *other.get_underlying_type());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// The destructor of the qualified type
|
||||
qualified_type_def::~qualified_type_def()
|
||||
{
|
||||
@ -383,4 +499,43 @@ dynamic_type_hash::operator()(const type_base* t) const
|
||||
// Poor man's fallback case.
|
||||
return type_base_hash()(*t);
|
||||
}
|
||||
|
||||
pointer_type_def::pointer_type_def(shared_ptr<type_base>& pointed_to,
|
||||
size_t size_in_bits,
|
||||
size_t align_in_bits,
|
||||
location locus)
|
||||
: type_base(size_in_bits, align_in_bits),
|
||||
decl_base("", locus),
|
||||
m_pointed_to_type(pointed_to)
|
||||
{
|
||||
}
|
||||
|
||||
/// Return true iff both instances of pointer_type_def are equal.
|
||||
///
|
||||
/// Note that this function does not check for the scopes of the this
|
||||
/// types.
|
||||
bool
|
||||
pointer_type_def::operator==(const pointer_type_def& other) const
|
||||
{
|
||||
// Runtime types must be equal.
|
||||
if (typeid(*this) != typeid(other)
|
||||
|| get_pointed_to_type() != other.get_pointed_to_type())
|
||||
return false;
|
||||
|
||||
if (shared_ptr<type_base> c = get_pointed_to_type())
|
||||
return *c == *other.get_pointed_to_type();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
shared_ptr<type_base>
|
||||
pointer_type_def::get_pointed_to_type() const
|
||||
{
|
||||
return m_pointed_to_type;
|
||||
}
|
||||
|
||||
pointer_type_def::~pointer_type_def()
|
||||
{
|
||||
}
|
||||
|
||||
}//end namespace abigail
|
||||
|
85
src/abg-ir.h
85
src/abg-ir.h
@ -9,7 +9,7 @@
|
||||
#include <string>
|
||||
#include <tr1/functional>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <utility> // for std::rel_ops, at least.
|
||||
#include "abg-hash.h"
|
||||
|
||||
using std::tr1::shared_ptr;
|
||||
@ -19,6 +19,10 @@ using std::string;
|
||||
// Our real stuff
|
||||
namespace abigail
|
||||
{
|
||||
|
||||
using namespace std::rel_ops; // Pull in relational operators so that
|
||||
// we don't have to define them all here.
|
||||
|
||||
/// \brief The source location of a token.
|
||||
///
|
||||
/// This represents the location of a token coming from a given ABI
|
||||
@ -50,6 +54,14 @@ public:
|
||||
return !!m_value;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const location other) const
|
||||
{return m_value == other.m_value;}
|
||||
|
||||
bool
|
||||
operator<(const location other) const
|
||||
{return m_value < other.m_value;}
|
||||
|
||||
friend class location_manager;
|
||||
|
||||
private:
|
||||
@ -99,8 +111,14 @@ public:
|
||||
|
||||
decl_base(const std::string& name,
|
||||
location locus);
|
||||
|
||||
decl_base(location);
|
||||
|
||||
decl_base(const decl_base&);
|
||||
|
||||
virtual bool
|
||||
operator==(const decl_base&) const;
|
||||
|
||||
virtual ~decl_base();
|
||||
|
||||
location
|
||||
@ -153,8 +171,12 @@ class scope_decl : public decl_base
|
||||
public:
|
||||
scope_decl(const std::string& name,
|
||||
location locus);
|
||||
|
||||
scope_decl(location);
|
||||
|
||||
virtual bool
|
||||
operator==(const scope_decl&) const;
|
||||
|
||||
const std::list<shared_ptr<decl_base> >&
|
||||
get_member_decls() const;
|
||||
|
||||
@ -198,6 +220,10 @@ class type_base
|
||||
public:
|
||||
|
||||
type_base(size_t s, size_t a);
|
||||
|
||||
virtual bool
|
||||
operator==(const type_base&) const;
|
||||
|
||||
virtual ~type_base();
|
||||
|
||||
void
|
||||
@ -253,6 +279,24 @@ struct type_shared_ptr_hash
|
||||
}
|
||||
};//end struct type_shared_ptr_hash
|
||||
|
||||
/// A predicate for deep equality of instances of
|
||||
/// shared_ptr<type_base>
|
||||
struct type_shared_ptr_equal
|
||||
{
|
||||
bool
|
||||
operator()(const shared_ptr<type_base>l,
|
||||
const shared_ptr<type_base>r) const
|
||||
{
|
||||
if (l != r)
|
||||
return false;
|
||||
|
||||
if (l)
|
||||
return *l == *r;
|
||||
|
||||
return true;
|
||||
}
|
||||
};//end struct type_shared_ptr_equal
|
||||
|
||||
/// A basic type declaration that introduces no scope.
|
||||
class type_decl : public decl_base, public type_base
|
||||
{
|
||||
@ -266,6 +310,9 @@ public:
|
||||
size_t alignment_in_bits,
|
||||
location locus);
|
||||
|
||||
virtual bool
|
||||
operator==(const type_decl&) const;
|
||||
|
||||
virtual ~type_decl();
|
||||
};// class type_decl
|
||||
|
||||
@ -297,6 +344,9 @@ public:
|
||||
size_t alignment_in_bits,
|
||||
location locus);
|
||||
|
||||
virtual bool
|
||||
operator==(const scope_type_decl&) const;
|
||||
|
||||
virtual ~scope_type_decl();
|
||||
};
|
||||
|
||||
@ -324,6 +374,9 @@ public:
|
||||
namespace_decl(const std::string& name,
|
||||
location locus);
|
||||
|
||||
virtual bool
|
||||
operator==(const namespace_decl&) const;
|
||||
|
||||
virtual ~namespace_decl();
|
||||
};//end class namespace_decl
|
||||
|
||||
@ -331,6 +384,8 @@ public:
|
||||
class qualified_type_def : public type_base, public decl_base
|
||||
{
|
||||
|
||||
// Forbidden.
|
||||
qualified_type_def();
|
||||
public:
|
||||
/// Bit field values representing the cv qualifiers of the
|
||||
/// underlying type.
|
||||
@ -345,6 +400,9 @@ public:
|
||||
CV quals,
|
||||
location locus);
|
||||
|
||||
virtual bool
|
||||
operator==(const qualified_type_def&) const;
|
||||
|
||||
char
|
||||
get_cv_quals() const;
|
||||
|
||||
@ -378,5 +436,30 @@ struct qualified_type_def_hash
|
||||
}
|
||||
};//end struct qualified_type_def_hash
|
||||
|
||||
/// The abstraction of a pointer type.
|
||||
class pointer_type_def : public type_base, public decl_base
|
||||
{
|
||||
// Forbidden.
|
||||
pointer_type_def();
|
||||
|
||||
public:
|
||||
|
||||
pointer_type_def(shared_ptr<type_base>& pointed_to_type,
|
||||
size_t size_in_bits,
|
||||
size_t alignment_in_bits,
|
||||
location locus);
|
||||
|
||||
virtual bool
|
||||
operator==(const pointer_type_def&) const;
|
||||
|
||||
shared_ptr<type_base>
|
||||
get_pointed_to_type() const;
|
||||
|
||||
virtual ~pointer_type_def();
|
||||
|
||||
private:
|
||||
shared_ptr<type_base> m_pointed_to_type;
|
||||
};//end class pointer_type_def
|
||||
|
||||
} // end namespace abigail
|
||||
#endif // __ABL_IR_H__
|
||||
|
@ -140,14 +140,15 @@ private:
|
||||
stack<shared_ptr<decl_base> > m_decls_stack;
|
||||
};//end class read_context
|
||||
|
||||
static void update_read_context(read_context&);
|
||||
static int advance_cursor(read_context&);
|
||||
static bool read_input(read_context&, abi_corpus&);
|
||||
static bool read_location(read_context&, abi_corpus& , location&);
|
||||
static bool handle_element(read_context&, abi_corpus&);
|
||||
static bool handle_type_decl(read_context&, abi_corpus&);
|
||||
static bool handle_namespace_decl(read_context&, abi_corpus&);
|
||||
static bool handle_qualified_type_decl(read_context&, abi_corpus&);
|
||||
static void update_read_context(read_context&);
|
||||
static int advance_cursor(read_context&);
|
||||
static bool read_input(read_context&, abi_corpus&);
|
||||
static bool read_location(read_context&, abi_corpus& , location&);
|
||||
static bool handle_element(read_context&, abi_corpus&);
|
||||
static bool handle_type_decl(read_context&, abi_corpus&);
|
||||
static bool handle_namespace_decl(read_context&, abi_corpus&);
|
||||
static bool handle_qualified_type_decl(read_context&, abi_corpus&);
|
||||
static bool handle_pointer_type_def(read_context&, abi_corpus&);
|
||||
|
||||
bool
|
||||
read_file(const string& file_path,
|
||||
@ -212,7 +213,7 @@ advance_cursor(read_context& ctxt)
|
||||
///
|
||||
/// \param corpus the result of the parsing.
|
||||
///
|
||||
/// \return true upon successufl parsing, false otherwise.
|
||||
/// \return true upon successful parsing, false otherwise.
|
||||
static bool
|
||||
read_input(read_context& ctxt,
|
||||
abi_corpus& corpus)
|
||||
@ -276,6 +277,9 @@ handle_element(read_context& ctxt,
|
||||
if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
|
||||
BAD_CAST("qualified-type-def")))
|
||||
return handle_qualified_type_decl(ctxt, corpus);
|
||||
if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
|
||||
BAD_CAST("pointer-type-def")))
|
||||
return handle_pointer_type_def(ctxt, corpus);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -411,7 +415,7 @@ handle_namespace_decl(read_context& ctxt, abi_corpus& corpus)
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Parse qualified-type-def xml element
|
||||
/// Parse a qualified-type-def xml element.
|
||||
///
|
||||
/// \param ctxt the parsing context.
|
||||
///
|
||||
@ -480,5 +484,61 @@ handle_qualified_type_decl(read_context& ctxt, abi_corpus& corpus)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Parse a pointer-type-decl element.
|
||||
///
|
||||
/// \param ctxt the context of the parsing.
|
||||
///
|
||||
/// \param corpus the ABI Corpus to augment with the result of the
|
||||
/// parsing.
|
||||
///
|
||||
/// \return true upon successful completion, false otherwise.
|
||||
static bool
|
||||
handle_pointer_type_def(read_context& ctxt, abi_corpus& corpus)
|
||||
{
|
||||
xml::reader_sptr r = ctxt.get_reader();
|
||||
if (!r)
|
||||
return false;
|
||||
|
||||
string type_id;
|
||||
if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(r, "type-id"))
|
||||
type_id = CHAR_STR(s);
|
||||
|
||||
shared_ptr<type_base> pointed_to_type = ctxt.get_type_decl(type_id);
|
||||
if (!pointed_to_type)
|
||||
return false;
|
||||
|
||||
size_t size_in_bits = 0, alignment_in_bits = 0;
|
||||
if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(r, "size-in-bits"))
|
||||
size_in_bits = atoi(CHAR_STR(s));
|
||||
if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(r, "alignment-in-bits"))
|
||||
alignment_in_bits = atoi(CHAR_STR(s));
|
||||
|
||||
string id;
|
||||
if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(r, "id"))
|
||||
id = CHAR_STR(s);
|
||||
if (id.empty() || ctxt.get_type_decl(id))
|
||||
return false;
|
||||
|
||||
location loc;
|
||||
read_location(ctxt, corpus, loc);
|
||||
|
||||
shared_ptr<decl_base> decl =
|
||||
shared_ptr<decl_base> (new pointer_type_def(pointed_to_type,
|
||||
size_in_bits,
|
||||
alignment_in_bits,
|
||||
loc));
|
||||
add_decl_to_scope(decl, ctxt.get_cur_scope());
|
||||
|
||||
if (!decl->get_scope())
|
||||
corpus.add(decl);
|
||||
|
||||
ctxt.push_decl(decl);
|
||||
|
||||
ctxt.add_type_decl(id, dynamic_pointer_cast<type_base>(decl));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}//end namespace reader
|
||||
}//end namespace abigail
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
using std::tr1::shared_ptr;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::list;
|
||||
@ -61,7 +62,8 @@ private:
|
||||
|
||||
typedef unordered_map<shared_ptr<type_base>,
|
||||
string,
|
||||
type_shared_ptr_hash> type_shared_ptr_map;
|
||||
type_shared_ptr_hash,
|
||||
type_shared_ptr_equal> type_shared_ptr_map;
|
||||
class write_context
|
||||
{
|
||||
write_context();
|
||||
@ -138,7 +140,11 @@ static bool write_qualified_type_def(const shared_ptr<qualified_type_def>,
|
||||
const abi_corpus&,
|
||||
write_context&,
|
||||
unsigned);
|
||||
void do_indent(ostream&, unsigned);
|
||||
static bool write_pointer_type_def(const shared_ptr<pointer_type_def>,
|
||||
const abi_corpus&,
|
||||
write_context&,
|
||||
unsigned);
|
||||
static void do_indent(ostream&, unsigned);
|
||||
|
||||
/// Emit #nb_whitespaces white spaces into the output stream #o.
|
||||
void
|
||||
@ -215,13 +221,14 @@ write_decl(const shared_ptr<decl_base> decl,
|
||||
unsigned indent)
|
||||
{
|
||||
if (write_type_decl(dynamic_pointer_cast<type_decl> (decl),
|
||||
corpus, ctxt, indent))
|
||||
return true;
|
||||
if (write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
|
||||
corpus, ctxt, indent))
|
||||
return true;
|
||||
if (write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(decl),
|
||||
corpus, ctxt, indent))
|
||||
corpus, ctxt, indent)
|
||||
|| write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
|
||||
corpus, ctxt, indent)
|
||||
|| write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
|
||||
(decl),
|
||||
corpus, ctxt, indent)
|
||||
|| write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(decl),
|
||||
corpus, ctxt, indent))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -400,7 +407,7 @@ write_qualified_type_def(const shared_ptr<qualified_type_def> decl,
|
||||
if (decl->get_cv_quals() & qualified_type_def::CV_VOLATILE)
|
||||
o << " volatile='yes'";
|
||||
|
||||
write_decl_location(dynamic_pointer_cast<decl_base>(decl), corpus, o);
|
||||
write_decl_location(static_pointer_cast<decl_base>(decl), corpus, o);
|
||||
|
||||
o<< " id='"
|
||||
<< ctxt.get_id_for_type(decl)
|
||||
@ -411,5 +418,45 @@ write_qualified_type_def(const shared_ptr<qualified_type_def> decl,
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize a pointer to an instance of pointer_type_def.
|
||||
///
|
||||
/// \param decl the pointer_type_def to serialize.
|
||||
///
|
||||
/// \param corpus the ABI corpus it belongs to.
|
||||
///
|
||||
/// \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 abi_corpus& corpus,
|
||||
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())
|
||||
<< "'";
|
||||
|
||||
if (size_t s = decl->get_size_in_bits())
|
||||
o << " size-in-bits='" << s << "'";
|
||||
if (size_t s = decl->get_alignment_in_bits())
|
||||
o << " alignment-in-bits='" << s << "'";
|
||||
|
||||
o << " id='" << ctxt.get_id_for_type(decl) << "'";
|
||||
|
||||
write_decl_location(static_pointer_cast<decl_base>(decl), corpus, o);
|
||||
o << "/>";
|
||||
|
||||
return true;
|
||||
}
|
||||
}//end namespace writer
|
||||
}//end namespace abigail
|
||||
|
@ -23,4 +23,5 @@ EXTRA_DIST= \
|
||||
$(h)/data/test-read-write/test0.xml \
|
||||
$(h)/data/test-read-write/test1.xml \
|
||||
$(h)/data/test-read-write/test2.xml \
|
||||
$(h)/data/test-read-write/test3.xml
|
||||
$(h)/data/test-read-write/test3.xml \
|
||||
$(h)/data/test-read-write/test4.xml
|
||||
|
4
tests/data/test-read-write/test4.xml
Normal file
4
tests/data/test-read-write/test4.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<abi-instr version='1.0'>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
|
||||
<pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
|
||||
</abi-instr>
|
@ -40,6 +40,10 @@ InOutSpec in_out_specs[] =
|
||||
"data/test-read-write/test3.xml",
|
||||
"output/test-read-write/test3.xml"
|
||||
},
|
||||
{
|
||||
"data/test-read-write/test4.xml",
|
||||
"output/test-read-write/test4.xml"
|
||||
},
|
||||
|
||||
// This should be the last entry.
|
||||
{NULL, NULL}
|
||||
|
Loading…
Reference in New Issue
Block a user