mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-21 16:26:57 +00:00
Support typedef declarations
* src/abg-ir.cc (dynamic_type_hash::operator()): Handle hashing of a pointer to an instance of typedef_decl. (typedef_decl::typedef_decl, typedef_decl::operator==) (typedef_decl::operator==, typedef_decl::get_underlying_type) (typedef_decl::~typedef_decl): New definitions. * src/abg-ir.h (class typedef_decl, struct typedef_decl_hash): New declarations. * src/abg-reader.cc (handle_typedef_decl): New definition. (handle_element): Handle de-serialization of typedef-decl element. * src/abg-writer.cc (write_typedef_decl): New definition. (write_decl): Handle serialization of an instance of typedef_decl. * tests/data/test-read-write/test7.xml: New test. * tests/Makefile.am: Add it to the distribution. * tests/test-read-write.cc: De-serialize the content of the new test, serialize it back and diff both.
This commit is contained in:
parent
77ade2bde1
commit
a5a6fd8fce
@ -497,6 +497,8 @@ dynamic_type_hash::operator()(const type_base* t) const
|
||||
return reference_type_def_hash()(*d);
|
||||
if (const enum_type_decl* d = dynamic_cast<const enum_type_decl*>(t))
|
||||
return enum_type_decl_hash()(*d);
|
||||
if (const typedef_decl* d = dynamic_cast<const typedef_decl*>(t))
|
||||
return typedef_decl_hash()(*d);
|
||||
|
||||
// Poor man's fallback case.
|
||||
return type_base_hash()(*t);
|
||||
@ -650,4 +652,49 @@ enum_type_decl::operator==(const enum_type_decl& other) const
|
||||
return true;
|
||||
}
|
||||
|
||||
// <typedef_decl definitions>
|
||||
|
||||
/// Constructor of the typedef_decl type.
|
||||
///
|
||||
/// \param name the name of the typedef.
|
||||
///
|
||||
/// \param underlying_type the underlying type of the typedef.
|
||||
///
|
||||
/// \param locus the source location of the typedef declaration.
|
||||
typedef_decl::typedef_decl(const string& name,
|
||||
const shared_ptr<type_base> underlying_type,
|
||||
location locus)
|
||||
: type_base(underlying_type->get_size_in_bits(),
|
||||
underlying_type->get_alignment_in_bits()),
|
||||
decl_base(name, locus),
|
||||
m_underlying_type(underlying_type)
|
||||
{
|
||||
}
|
||||
|
||||
/// Equality operator
|
||||
///
|
||||
/// \param other the other typedef_decl to test against.
|
||||
bool
|
||||
typedef_decl::operator==(const typedef_decl& other) const
|
||||
{
|
||||
return (typeid(*this) == typeid(other)
|
||||
&& get_name() == other.get_name()
|
||||
&& *get_underlying_type() == *other.get_underlying_type());
|
||||
}
|
||||
|
||||
/// Getter of the underlying type of the typedef.
|
||||
///
|
||||
/// \return the underlying_type.
|
||||
shared_ptr<type_base>
|
||||
typedef_decl::get_underlying_type() const
|
||||
{
|
||||
return m_underlying_type;
|
||||
}
|
||||
|
||||
/// Destructor of the typedef_decl.
|
||||
typedef_decl::~typedef_decl()
|
||||
{
|
||||
}
|
||||
|
||||
// </typedef_decl definitions>
|
||||
}//end namespace abigail
|
||||
|
43
src/abg-ir.h
43
src/abg-ir.h
@ -628,5 +628,48 @@ struct enum_type_decl_hash
|
||||
}
|
||||
};//end struct enum_type_decl_hash
|
||||
|
||||
/// The abstraction of a typedef declaration.
|
||||
class typedef_decl: public type_base, public decl_base
|
||||
{
|
||||
// Forbidden
|
||||
typedef_decl();
|
||||
|
||||
public:
|
||||
|
||||
typedef_decl(const string& name,
|
||||
const shared_ptr<type_base> underlying_type,
|
||||
location locus);
|
||||
|
||||
bool
|
||||
operator==(const typedef_decl&) const;
|
||||
|
||||
shared_ptr<type_base>
|
||||
get_underlying_type() const;
|
||||
|
||||
virtual ~typedef_decl();
|
||||
|
||||
private:
|
||||
shared_ptr<type_base> m_underlying_type;
|
||||
};//end class typedef_decl
|
||||
|
||||
/// Hasher for the typedef_decl type.
|
||||
struct typedef_decl_hash
|
||||
{
|
||||
size_t
|
||||
operator()(const typedef_decl& t) const
|
||||
{
|
||||
hash<string> str_hash;
|
||||
type_base_hash type_hash;
|
||||
decl_base_hash decl_hash;
|
||||
type_shared_ptr_hash type_ptr_hash;
|
||||
|
||||
size_t v = str_hash(typeid(t).name());
|
||||
v = hashing::combine_hashes(v, type_hash(t));
|
||||
v = hashing::combine_hashes(v, decl_hash(t));
|
||||
v = hashing::combine_hashes(v, type_ptr_hash(t.get_underlying_type()));
|
||||
|
||||
return v;
|
||||
}
|
||||
};// end struct typedef_decl_hash
|
||||
} // end namespace abigail
|
||||
#endif // __ABG_IR_H__
|
||||
|
@ -191,6 +191,7 @@ static bool handle_qualified_type_decl(read_context&, abi_corpus&);
|
||||
static bool handle_pointer_type_def(read_context&, abi_corpus&);
|
||||
static bool handle_reference_type_def(read_context&, abi_corpus&);
|
||||
static bool handle_enum_type_decl(read_context&, abi_corpus&);
|
||||
static bool handle_typedef_decl(read_context&, abi_corpus&);
|
||||
|
||||
bool
|
||||
read_file(const string& file_path,
|
||||
@ -328,6 +329,9 @@ handle_element(read_context& ctxt,
|
||||
if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
|
||||
BAD_CAST("enum-decl")))
|
||||
return handle_enum_type_decl(ctxt, corpus);
|
||||
if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
|
||||
BAD_CAST("typedef-decl")))
|
||||
return handle_typedef_decl(ctxt, corpus);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -667,5 +671,43 @@ handle_enum_type_decl(read_context& ctxt, abi_corpus& corpus)
|
||||
return ctxt.finish_type_decl_creation(t, id, corpus);
|
||||
}
|
||||
|
||||
/// Parse a typedef-decl element.
|
||||
///
|
||||
/// \param ctxt the context of the parsing.
|
||||
///
|
||||
/// \param corpus the corpus the resulting pointer to
|
||||
/// typedef_decl is added to.
|
||||
static bool
|
||||
handle_typedef_decl(read_context& ctxt, abi_corpus& corpus)
|
||||
{
|
||||
xml::reader_sptr r = ctxt.get_reader();
|
||||
if (!r)
|
||||
return false;
|
||||
|
||||
string name;
|
||||
if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(r, "name"))
|
||||
name = CHAR_STR(s);
|
||||
|
||||
string type_id;
|
||||
if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(r, "type-id"))
|
||||
type_id = CHAR_STR(s);
|
||||
shared_ptr<type_base> underlying_type(ctxt.get_type_decl(type_id));
|
||||
if (!underlying_type)
|
||||
return false;
|
||||
|
||||
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<type_base> t(new typedef_decl(name, underlying_type, loc));
|
||||
|
||||
return ctxt.finish_type_decl_creation(t, id, corpus);
|
||||
}
|
||||
|
||||
}//end namespace reader
|
||||
}//end namespace abigail
|
||||
|
@ -152,6 +152,10 @@ static bool write_enum_type_decl(const shared_ptr<enum_type_decl>,
|
||||
const abi_corpus&,
|
||||
write_context&,
|
||||
unsigned);
|
||||
static bool write_typedef_decl(const shared_ptr<typedef_decl>,
|
||||
const abi_corpus&,
|
||||
write_context&,
|
||||
unsigned);
|
||||
static void do_indent(ostream&, unsigned);
|
||||
|
||||
/// Emit #nb_whitespaces white spaces into the output stream #o.
|
||||
@ -241,7 +245,9 @@ write_decl(const shared_ptr<decl_base> decl,
|
||||
<reference_type_def>(decl),
|
||||
corpus, ctxt, indent)
|
||||
|| write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(decl),
|
||||
corpus, ctxt, indent))
|
||||
corpus, ctxt, indent)
|
||||
|| write_typedef_decl(dynamic_pointer_cast<typedef_decl>(decl),
|
||||
corpus, ctxt, indent))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -570,5 +576,42 @@ write_enum_type_decl(const shared_ptr<enum_type_decl> decl,
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize a pointer to an instance of typedef_decl.
|
||||
///
|
||||
/// \param decl the typedef_decl 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_typedef_decl(const shared_ptr<typedef_decl> decl,
|
||||
const abi_corpus& corpus,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
|
||||
ostream &o = ctxt.get_ostream();
|
||||
|
||||
do_indent(o, indent);
|
||||
|
||||
o << "<typedef-decl name='" << decl->get_name() << "'";
|
||||
|
||||
o << " type-id='" << ctxt.get_id_for_type(decl->get_underlying_type()) << "'";
|
||||
|
||||
write_decl_location(decl, corpus, o);
|
||||
|
||||
o << " id='"
|
||||
<< ctxt.get_id_for_type(decl)
|
||||
<< "'/>";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}//end namespace writer
|
||||
}//end namespace abigail
|
||||
|
@ -26,4 +26,5 @@ $(h)/data/test-read-write/test2.xml \
|
||||
$(h)/data/test-read-write/test3.xml \
|
||||
$(h)/data/test-read-write/test4.xml \
|
||||
$(h)/data/test-read-write/test5.xml \
|
||||
$(h)/data/test-read-write/test6.xml
|
||||
$(h)/data/test-read-write/test6.xml \
|
||||
$(h)/data/test-read-write/test7.xml
|
||||
|
4
tests/data/test-read-write/test7.xml
Normal file
4
tests/data/test-read-write/test7.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<abi-instr version='1.0'>
|
||||
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-1'/>
|
||||
<typedef-decl name='tchar' type-id='type-id-1' id='type-id-2'/>
|
||||
</abi-instr>
|
@ -48,10 +48,14 @@ InOutSpec in_out_specs[] =
|
||||
"data/test-read-write/test5.xml",
|
||||
"output/test-read-write/test5.xml"
|
||||
},
|
||||
{
|
||||
{
|
||||
"data/test-read-write/test6.xml",
|
||||
"output/test-read-write/test6.xml"
|
||||
},
|
||||
{
|
||||
"data/test-read-write/test7.xml",
|
||||
"output/test-read-write/test7.xml"
|
||||
},
|
||||
|
||||
// This should be the last entry.
|
||||
{NULL, NULL}
|
||||
|
Loading…
Reference in New Issue
Block a user