mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-21 00:06:58 +00:00
Use the same representation for member and non-member types
* include/abg-fwd.h (is_at_class_scope): Add new oveloads.
(as_non_member_type, as_non_member_class_decl): Remove.
(has_scope, is_member_decl, is_member_type): New function
declarations. (get_member_is_static, set_member_is_static):
Likewise. * include/abg-ir.h (enum access_specifier): Move to
the abigail:: namespace, from ...
(class_decl::access_specifier): ... here. (class
context_rel): New type. (decl_base::hash_as_member): New
hasher. (decl_base::context_): Change the type of this to
context_rel_sptr. (decl_base::get_context_rel): New protected
getter. (decl_base::get_scope): Move this out-of-line.
(class_decl::member_type): Remove.
(class_decl::member_types): Adjust this typedef.
(class_decl::{insert,add}_member_type): Make these take a
type_base_sptr now. (class_decl::add_member_type): Change the
overload that returned a member_type to return a
type_base_sptr. (get_member_access_specifier,
set_member_access_specifier): New function declarations. *
include/abg-comparison.h (class member_type_diff): Remove.
(compute_diff): Remove the overload for member_type_diff. *
src/abg-comparison.cc (compute_diff_for_types): Adjust for the
removal of class_decl::member_type.
(maybe_report_diff_for_class_members): New static function.
(report_name_size_and_alignment_changes): Do not report a name
change just because of a struct -> class change. ({var_diff,
enum_diff, function_decl_diff}::report): Use the new
maybe_report_diff_for_class_members. (class_diff::report):
Adjust for the removal of class_decl::member_type. Use the
new maybe_report_diff_for_class_members. (class member_diff):
Remove. * src/abg-dwarf-reader.cc (die_access_specifier)
(get_scope_for_die, build_translation_unit_and_add_to_ir)
(build_class_type_and_add_to_ir, build_function_decl)
(build_ir_node_from_die): Adjust. * abg-hash.cc (struct
decl_base::hash_as_member): Define. ({scope_type_decl,
enum_type_decl, typedef_decl}:#️⃣:operator()): Use the
decl_base::hash_as_member.
* src/abg-ir.cc (decl_base::decl_base): Adjust.
(decl_base::get_scope): New out-of-line getter.
(decl_base::{operator==, set_scope): Adjust.
(has_scope, is_member_decl, is_member_type)
(get_member_access_specifier, set_member_access_specifier)
(get_member_is_static, set_member_is_static, is_at_class_scope):
New function definitions.
(as_non_member_type, as_non_member_class_decl): Remove.
(get_node_name): Adjust.
(class_decl::{class_decl, set_earlier_declaration,
insert_member_decl, insert_member_type, add_member_type):
Likewise.
(class_decl::member_type::*) Remove.
* src/abg-reader.cc (read_access, build_qualified_type_decl)
(build_reference_type_def, build_typedef_decl)
(build_class_decl): Adjust.
* src/abg-writer.cc (write_access, write_member_type)
(write_class_decl): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
a58f60c08f
commit
ca53b99c5a
@ -809,53 +809,6 @@ compute_diff(const scope_decl_sptr first_scope,
|
||||
const scope_decl_sptr second_scope,
|
||||
diff_context_sptr ctxt);
|
||||
|
||||
class member_type_diff;
|
||||
/// A convenience typedef for a shared pointer to a @ref member_type_diff
|
||||
typedef shared_ptr<member_type_diff> member_type_diff_sptr;
|
||||
|
||||
/// An abstraction of a diff between two member types.
|
||||
class member_type_diff : public diff
|
||||
{
|
||||
struct priv;
|
||||
typedef shared_ptr<priv> priv_sptr;
|
||||
priv_sptr priv_;
|
||||
|
||||
|
||||
protected:
|
||||
member_type_diff(class_decl::member_type_sptr first,
|
||||
class_decl::member_type_sptr second,
|
||||
diff_context_sptr ctxt = diff_context_sptr());
|
||||
|
||||
public:
|
||||
const class_decl::member_type_sptr
|
||||
first_member_type() const;
|
||||
|
||||
const class_decl::member_type_sptr
|
||||
second_member_type() const;
|
||||
|
||||
diff_sptr
|
||||
underlying_type_diff() const;
|
||||
|
||||
void
|
||||
underlying_type_diff(const diff_sptr);
|
||||
|
||||
virtual unsigned
|
||||
length() const;
|
||||
|
||||
virtual void
|
||||
report(ostream&, const string& indent = "") const;
|
||||
|
||||
friend member_type_diff_sptr
|
||||
compute_diff(const class_decl::member_type_sptr first,
|
||||
const class_decl::member_type_sptr second,
|
||||
diff_context_sptr ctxt);
|
||||
};// end class member_type_diff.
|
||||
|
||||
member_type_diff_sptr
|
||||
compute_diff(const class_decl::member_type_sptr first,
|
||||
const class_decl::member_type_sptr second,
|
||||
diff_context_sptr ctxt);
|
||||
|
||||
class function_decl_diff;
|
||||
|
||||
/// Convenience typedef for a shared pointer on a @ref function_decl type.
|
||||
|
@ -134,6 +134,12 @@ is_at_global_scope(const shared_ptr<decl_base>);
|
||||
bool
|
||||
is_at_class_scope(const shared_ptr<decl_base>);
|
||||
|
||||
bool
|
||||
is_at_class_scope(const decl_base*);
|
||||
|
||||
bool
|
||||
is_at_class_scope(const decl_base&);
|
||||
|
||||
bool
|
||||
is_at_template_scope(const shared_ptr<decl_base>);
|
||||
|
||||
@ -146,18 +152,6 @@ is_type(const decl_base&);
|
||||
shared_ptr<type_base>
|
||||
is_type(const shared_ptr<decl_base>);
|
||||
|
||||
shared_ptr<type_base>
|
||||
as_non_member_type(const shared_ptr<type_base>);
|
||||
|
||||
shared_ptr<type_base>
|
||||
as_non_member_type(const shared_ptr<decl_base>);
|
||||
|
||||
shared_ptr<class_decl>
|
||||
as_non_member_class_decl(const shared_ptr<decl_base>);
|
||||
|
||||
const class_decl*
|
||||
as_non_member_class_decl(const decl_base* t);
|
||||
|
||||
shared_ptr<class_decl>
|
||||
look_through_decl_only_class(shared_ptr<class_decl>);
|
||||
|
||||
@ -189,9 +183,50 @@ insert_decl_into_scope(shared_ptr<decl_base>,
|
||||
vector<shared_ptr<decl_base> >::iterator,
|
||||
shared_ptr<scope_decl>);
|
||||
|
||||
bool
|
||||
has_scope(const decl_base&);
|
||||
|
||||
bool
|
||||
has_scope(const shared_ptr<decl_base>);
|
||||
|
||||
bool
|
||||
has_scope(const type_base&);
|
||||
|
||||
bool
|
||||
has_scope(const shared_ptr<type_base>);
|
||||
|
||||
bool
|
||||
is_member_decl(const shared_ptr<decl_base>);
|
||||
|
||||
bool
|
||||
is_member_decl(const decl_base*);
|
||||
|
||||
bool
|
||||
is_member_decl(const decl_base&);
|
||||
|
||||
bool
|
||||
is_member_type(const shared_ptr<type_base>);
|
||||
|
||||
bool
|
||||
is_member_type(const shared_ptr<decl_base>);
|
||||
|
||||
void
|
||||
remove_decl_from_scope(shared_ptr<decl_base>);
|
||||
|
||||
bool
|
||||
get_member_is_static(const decl_base&);
|
||||
|
||||
bool
|
||||
get_member_is_static(const shared_ptr<decl_base>);
|
||||
|
||||
void
|
||||
set_member_is_static(decl_base&,
|
||||
bool);
|
||||
|
||||
void
|
||||
set_member_is_static(shared_ptr<decl_base>,
|
||||
bool);
|
||||
|
||||
const global_scope*
|
||||
get_global_scope(const decl_base* decl);
|
||||
|
||||
|
222
include/abg-ir.h
222
include/abg-ir.h
@ -178,6 +178,19 @@ public:
|
||||
bool
|
||||
operator==(translation_unit_sptr, translation_unit_sptr);
|
||||
|
||||
/// Access specifier for class members.
|
||||
enum access_specifier
|
||||
{
|
||||
no_access,
|
||||
public_access,
|
||||
protected_access,
|
||||
private_access,
|
||||
};
|
||||
|
||||
class context_rel;
|
||||
/// A convenience typedef for shared pointers to @ref context_rel
|
||||
typedef shared_ptr<context_rel> context_rel_sptr;
|
||||
|
||||
/// The base type of all declarations.
|
||||
class decl_base : public ir_traversable_base
|
||||
{
|
||||
@ -185,6 +198,9 @@ public:
|
||||
/// Facility to hash instances of decl_base.
|
||||
struct hash;
|
||||
|
||||
/// Facility to hash instances of decl_base as class members
|
||||
struct hash_as_member;
|
||||
|
||||
/// ELF visibility
|
||||
enum visibility
|
||||
{
|
||||
@ -207,13 +223,13 @@ public:
|
||||
protected:
|
||||
mutable size_t hash_;
|
||||
location location_;
|
||||
context_rel_sptr context_;
|
||||
mutable std::string name_;
|
||||
mutable std::string qualified_parent_name_;
|
||||
mutable std::string qualified_name_;
|
||||
|
||||
private:
|
||||
std::string mangled_name_;
|
||||
scope_decl* context_;
|
||||
visibility visibility_;
|
||||
|
||||
// Forbidden
|
||||
@ -222,6 +238,22 @@ private:
|
||||
virtual void
|
||||
set_scope(scope_decl*);
|
||||
|
||||
protected:
|
||||
|
||||
///Getter for the context relationship.
|
||||
///
|
||||
///@return the context relationship for the current decl_base.
|
||||
const context_rel_sptr
|
||||
get_context_rel() const
|
||||
{return context_;}
|
||||
|
||||
///Getter for the context relationship.
|
||||
///
|
||||
///@return the context relationship for the current decl_base.
|
||||
context_rel_sptr
|
||||
get_context_rel()
|
||||
{return context_;}
|
||||
|
||||
public:
|
||||
|
||||
decl_base(const std::string& name, location locus,
|
||||
@ -309,11 +341,10 @@ public:
|
||||
|
||||
void
|
||||
set_mangled_name(const std::string& m)
|
||||
{ mangled_name_ = m; }
|
||||
{mangled_name_ = m;}
|
||||
|
||||
scope_decl*
|
||||
get_scope() const
|
||||
{return context_;}
|
||||
get_scope() const;
|
||||
|
||||
visibility
|
||||
get_visibility() const
|
||||
@ -334,6 +365,24 @@ public:
|
||||
vector<shared_ptr<decl_base> >::iterator,
|
||||
scope_decl*);
|
||||
|
||||
friend enum access_specifier
|
||||
get_member_access_specifier(const decl_base& d);
|
||||
|
||||
friend enum access_specifier
|
||||
get_member_access_specifier(const decl_base_sptr d);
|
||||
|
||||
friend void
|
||||
set_member_access_specifier(const decl_base_sptr d,
|
||||
access_specifier a);
|
||||
|
||||
friend bool
|
||||
get_member_is_static(const decl_base& d);
|
||||
|
||||
friend bool
|
||||
get_member_is_static(const decl_base_sptr d);
|
||||
|
||||
friend void
|
||||
set_member_is_static(decl_base_sptr d, bool s);
|
||||
|
||||
friend class class_decl;
|
||||
};// end class decl_base
|
||||
@ -1675,18 +1724,8 @@ public:
|
||||
/// Hasher.
|
||||
struct hash;
|
||||
|
||||
/// Language access specifier.
|
||||
enum access_specifier
|
||||
{
|
||||
no_access,
|
||||
public_access,
|
||||
protected_access,
|
||||
private_access,
|
||||
};
|
||||
|
||||
/// Forward declarations.
|
||||
class member_base;
|
||||
class member_type;
|
||||
class base_spec;
|
||||
class data_member;
|
||||
class method_decl;
|
||||
@ -1698,8 +1737,7 @@ public:
|
||||
/// @{
|
||||
typedef shared_ptr<base_spec> base_spec_sptr;
|
||||
typedef std::vector<base_spec_sptr> base_specs;
|
||||
typedef shared_ptr<member_type> member_type_sptr;
|
||||
typedef std::vector<member_type_sptr> member_types;
|
||||
typedef std::vector<type_base_sptr> member_types;
|
||||
typedef shared_ptr<data_member> data_member_sptr;
|
||||
typedef std::vector<data_member_sptr> data_members;
|
||||
typedef shared_ptr<member_function> member_function_sptr;
|
||||
@ -1795,13 +1833,13 @@ public:
|
||||
{return bases_;}
|
||||
|
||||
void
|
||||
insert_member_type(member_type_sptr t,
|
||||
insert_member_type(type_base_sptr t,
|
||||
declarations::iterator before);
|
||||
|
||||
void
|
||||
add_member_type(member_type_sptr t);
|
||||
add_member_type(type_base_sptr t);
|
||||
|
||||
member_type_sptr
|
||||
type_base_sptr
|
||||
add_member_type(type_base_sptr t, access_specifier a);
|
||||
|
||||
void
|
||||
@ -1873,8 +1911,85 @@ public:
|
||||
virtual ~class_decl();
|
||||
};// end class class_decl
|
||||
|
||||
enum access_specifier
|
||||
get_member_access_specifier(const decl_base&);
|
||||
|
||||
enum access_specifier
|
||||
get_member_access_specifier(const decl_base_sptr);
|
||||
|
||||
void
|
||||
set_member_access_specifier(decl_base_sptr,
|
||||
access_specifier);
|
||||
|
||||
/// The abstraction of the relationship between an entity and its
|
||||
/// containing scope (its context). That relationship can carry
|
||||
/// properties like access rights (if the parent is a class_decl),
|
||||
/// etc.
|
||||
///
|
||||
/// But importantly, this relationship carries a pointer to the
|
||||
/// actualy parent.
|
||||
class context_rel
|
||||
{
|
||||
private:
|
||||
scope_decl* scope_;
|
||||
enum access_specifier access_;
|
||||
bool is_static_;
|
||||
|
||||
public:
|
||||
context_rel()
|
||||
: scope_(0),
|
||||
access_(no_access),
|
||||
is_static_(false)
|
||||
{}
|
||||
|
||||
context_rel(scope_decl* s)
|
||||
: scope_(s),
|
||||
access_(no_access),
|
||||
is_static_(false)
|
||||
{}
|
||||
|
||||
context_rel(scope_decl* s,
|
||||
access_specifier a,
|
||||
bool f)
|
||||
: scope_(s),
|
||||
access_(a),
|
||||
is_static_(f)
|
||||
{}
|
||||
|
||||
scope_decl*
|
||||
get_scope() const
|
||||
{return scope_;}
|
||||
|
||||
access_specifier
|
||||
get_access_specifier() const
|
||||
{return access_;}
|
||||
|
||||
void
|
||||
set_access_specifier(access_specifier a)
|
||||
{access_ = a;}
|
||||
|
||||
bool
|
||||
get_is_static() const
|
||||
{return is_static_;}
|
||||
|
||||
void
|
||||
set_is_static(bool s)
|
||||
{is_static_ = s;}
|
||||
|
||||
void
|
||||
set_scope(scope_decl* s)
|
||||
{scope_ = s;}
|
||||
|
||||
bool
|
||||
operator==(const context_rel& o)const
|
||||
{
|
||||
return (access_ == o.access_
|
||||
&& is_static_ == o.is_static_);
|
||||
}
|
||||
};// end class context_rel
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream&, class_decl::access_specifier);
|
||||
operator<<(std::ostream&, access_specifier);
|
||||
|
||||
bool
|
||||
operator==(class_decl_sptr l, class_decl_sptr r);
|
||||
@ -1931,65 +2046,6 @@ public:
|
||||
operator==(const member_base& o) const;
|
||||
};// end class class_decl::member_base
|
||||
|
||||
/// Abstracts a member type declaration.
|
||||
///
|
||||
/// It's important to understand the interactions between this type
|
||||
/// and the other types. When a type T appears in the scope of a
|
||||
/// class, it becomes a member type MT. T is said to be the
|
||||
/// underlying type of MT. MT and T are different types. In
|
||||
/// practice, when the function class_decl::add_member_type is given a
|
||||
/// type T, it adds it to the class scope and returns MT, which is the
|
||||
/// resulting member type that is created. T can be retrieved from MT
|
||||
/// by invoking either MT::get_underlying_type(), or by invoking
|
||||
/// as_non_member_type(MT).
|
||||
class class_decl::member_type : public member_base,
|
||||
public virtual decl_base,
|
||||
public virtual type_base
|
||||
{
|
||||
type_base_sptr type_;
|
||||
|
||||
//Forbidden
|
||||
member_type();
|
||||
|
||||
public:
|
||||
// Hasher.
|
||||
struct hash;
|
||||
|
||||
member_type(shared_ptr<type_base> t, access_specifier access);
|
||||
|
||||
virtual void
|
||||
set_scope(scope_decl*);
|
||||
|
||||
virtual bool
|
||||
operator==(const decl_base&) const;
|
||||
|
||||
virtual bool
|
||||
operator==(const member_base&) const;
|
||||
|
||||
virtual bool
|
||||
operator==(const type_base&) const;
|
||||
|
||||
virtual void
|
||||
get_qualified_name(string& qualified_name) const;
|
||||
|
||||
string
|
||||
get_qualified_name() const;
|
||||
|
||||
virtual string
|
||||
get_pretty_representation() const;
|
||||
|
||||
virtual void
|
||||
traverse(ir_node_visitor& v);
|
||||
|
||||
const type_base_sptr&
|
||||
get_underlying_type() const;
|
||||
|
||||
bool
|
||||
operator==(const member_type&) const;
|
||||
};// end class member_type
|
||||
|
||||
bool
|
||||
operator==(class_decl::member_type_sptr l, class_decl::member_type_sptr r);
|
||||
|
||||
/// Abstraction of a base specifier in a class declaration.
|
||||
class class_decl::base_spec : public member_base
|
||||
@ -2494,13 +2550,6 @@ struct class_decl::member_base::hash
|
||||
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
|
||||
{
|
||||
@ -2579,7 +2628,6 @@ struct ir_node_visitor : public node_visitor_base
|
||||
virtual void visit(class_tdecl*);
|
||||
virtual void visit(class_decl*);
|
||||
virtual void visit(class_decl::data_member*);
|
||||
virtual void visit(class_decl::member_type*);
|
||||
virtual void visit(class_decl::member_function*);
|
||||
virtual void visit(class_decl::member_function_template*);
|
||||
virtual void visit(class_decl::member_class_template*);
|
||||
|
@ -495,7 +495,6 @@ compute_diff_for_types(const decl_base_sptr first,
|
||||
const decl_base_sptr s = second;
|
||||
|
||||
((d = try_to_diff_distinct_kinds(f, s, ctxt))
|
||||
||(d = try_to_diff<class_decl::member_type>(f, s, ctxt))
|
||||
||(d = try_to_diff<type_decl>(f, s, ctxt))
|
||||
||(d = try_to_diff<enum_type_decl>(f, s, ctxt))
|
||||
||(d = try_to_diff<class_decl>(f, s,ctxt))
|
||||
@ -668,6 +667,12 @@ diff_length_of_type_bases(type_base_sptr first, type_base_sptr second)
|
||||
return l;
|
||||
}
|
||||
|
||||
static bool
|
||||
maybe_report_diff_for_class_members(decl_base_sptr decl1,
|
||||
decl_base_sptr decl2,
|
||||
ostream& out,
|
||||
const string& indent);
|
||||
|
||||
/// Stream a string representation for a member function.
|
||||
///
|
||||
/// @param mem_fn the member function to stream
|
||||
@ -848,8 +853,8 @@ report_name_size_and_alignment_changes(decl_base_sptr first,
|
||||
return false;
|
||||
|
||||
bool n = false;
|
||||
string fn = first->get_pretty_representation(),
|
||||
sn = second->get_pretty_representation();
|
||||
string fn = first->get_qualified_name(),
|
||||
sn = second->get_qualified_name();
|
||||
if (fn != sn)
|
||||
{
|
||||
if (nl)
|
||||
@ -1033,6 +1038,8 @@ var_diff::report(ostream& out, const string& indent) const
|
||||
/*start_with_new_line=*/false))
|
||||
out << "\n";
|
||||
|
||||
maybe_report_diff_for_class_members(first, second, out, indent);
|
||||
|
||||
if (diff_sptr d = type_diff())
|
||||
{
|
||||
if (d->length())
|
||||
@ -1075,6 +1082,55 @@ compute_diff(const var_decl_sptr first,
|
||||
|
||||
// </var_diff stuff>
|
||||
|
||||
/// Report the differences in access specifiers and static-ness for
|
||||
/// class members.
|
||||
///
|
||||
/// @param decl1 the first class member to consider.
|
||||
///
|
||||
/// @param decl2 the second class member to consider.
|
||||
///
|
||||
/// @param out the output stream to send the report to.
|
||||
///
|
||||
/// @param indent the indentation string to use for the report.
|
||||
///
|
||||
/// @return true if something was reported, false otherwise.
|
||||
static bool
|
||||
maybe_report_diff_for_class_members(decl_base_sptr decl1,
|
||||
decl_base_sptr decl2,
|
||||
ostream& out,
|
||||
const string& indent)
|
||||
|
||||
{
|
||||
bool reported = false;
|
||||
if (!is_member_decl(decl1) || !is_member_decl(decl2))
|
||||
return reported;
|
||||
|
||||
string decl1_repr = decl1->get_pretty_representation(),
|
||||
decl2_repr = decl2->get_pretty_representation();
|
||||
|
||||
if (get_member_is_static(decl1) != get_member_is_static(decl2))
|
||||
{
|
||||
bool lost = get_member_is_static(decl1);
|
||||
out << indent << "'" << decl1_repr << "' ";
|
||||
if (lost)
|
||||
out << "became non-static";
|
||||
else
|
||||
out << "became static";
|
||||
out << "\n";
|
||||
reported = true;
|
||||
}
|
||||
if (get_member_access_specifier(decl1) != get_member_access_specifier(decl2))
|
||||
{
|
||||
out << indent << "'" << decl1_repr << "' access changed from '"
|
||||
<< get_member_access_specifier(decl1)
|
||||
<< "' to '"
|
||||
<< get_member_access_specifier(decl2)
|
||||
<< "'\n";
|
||||
reported = true;
|
||||
}
|
||||
return reported;
|
||||
}
|
||||
|
||||
/// Constructor for a pointer_diff.
|
||||
///
|
||||
/// @param first the first pointer to consider for the diff.
|
||||
@ -1706,6 +1762,7 @@ enum_diff::report(ostream& out, const string& indent) const
|
||||
if (report_name_size_and_alignment_changes(first, second, out, indent,
|
||||
/*start_with_num_line=*/false))
|
||||
out << "\n";
|
||||
maybe_report_diff_for_class_members(first, second, out, indent);
|
||||
|
||||
// name
|
||||
if (first->get_name() != second->get_name())
|
||||
@ -1977,8 +2034,9 @@ class_diff::ensure_lookup_tables_populated(void) const
|
||||
++it)
|
||||
{
|
||||
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);
|
||||
decl_base_sptr d =
|
||||
get_type_declaration(first_class_decl()->get_member_types()[i]);
|
||||
class_decl_sptr klass_decl = dynamic_pointer_cast<class_decl>(d);
|
||||
if (klass_decl && klass_decl->get_is_declaration_only())
|
||||
continue;
|
||||
string qname = d->get_qualified_name();
|
||||
@ -1995,8 +2053,9 @@ class_diff::ensure_lookup_tables_populated(void) const
|
||||
++iit)
|
||||
{
|
||||
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);
|
||||
decl_base_sptr d =
|
||||
get_type_declaration(second_class_decl()->get_member_types()[i]);
|
||||
class_decl_sptr klass_decl = dynamic_pointer_cast<class_decl>(d);
|
||||
if (klass_decl && klass_decl->get_is_declaration_only())
|
||||
continue;
|
||||
string qname = d->get_qualified_name();
|
||||
@ -2375,6 +2434,8 @@ class_diff::report(ostream& out, const string& indent) const
|
||||
/*start_with_new_line=*/false))
|
||||
out << "\n";
|
||||
|
||||
maybe_report_diff_for_class_members(first, second, out, indent);
|
||||
|
||||
// bases classes
|
||||
if (base_changes())
|
||||
{
|
||||
@ -2513,7 +2574,7 @@ class_diff::report(ostream& out, const string& indent) const
|
||||
i != e.insertions().end();
|
||||
++i)
|
||||
{
|
||||
class_decl::member_type_sptr mem_type;
|
||||
type_base_sptr mem_type;
|
||||
for (vector<unsigned>::const_iterator j =
|
||||
i->inserted_indexes().begin();
|
||||
j != i->inserted_indexes().end();
|
||||
@ -2522,10 +2583,12 @@ class_diff::report(ostream& out, const string& indent) const
|
||||
if (emitted)
|
||||
out << "\n";
|
||||
mem_type = second->get_member_types()[*j];
|
||||
if (!priv_->member_type_has_changed(mem_type))
|
||||
if (!priv_->
|
||||
member_type_has_changed(get_type_declaration(mem_type)))
|
||||
{
|
||||
out << indent << " '"
|
||||
<< mem_type->get_pretty_representation()
|
||||
<< get_type_declaration(mem_type)->
|
||||
get_pretty_representation()
|
||||
<< "'";
|
||||
emitted = true;
|
||||
}
|
||||
@ -3423,147 +3486,6 @@ compute_diff(const scope_decl_sptr first_scope,
|
||||
|
||||
//</scope_diff stuff>
|
||||
|
||||
// <member_type_diff stuff>
|
||||
|
||||
/// The type of the private data for @ref member_type_diff.
|
||||
struct member_type_diff::priv
|
||||
{
|
||||
diff_sptr underlying_type_diff_;
|
||||
};//end struct member_type_diff
|
||||
|
||||
/// Constructor for member_type_diff.
|
||||
///
|
||||
/// @param first the first subject of the diff.
|
||||
///
|
||||
/// @param second the second subject of the diff.
|
||||
///
|
||||
/// @param ctxt the context of the diff.
|
||||
member_type_diff::member_type_diff(class_decl::member_type_sptr first,
|
||||
class_decl::member_type_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
: diff(first, second, ctxt),
|
||||
priv_(new priv)
|
||||
{}
|
||||
|
||||
/// Getter for the first subject of the diff.
|
||||
///
|
||||
/// @return the first member type of the diff.
|
||||
const class_decl::member_type_sptr
|
||||
member_type_diff::first_member_type() const
|
||||
{return dynamic_pointer_cast<class_decl::member_type>(first_subject());}
|
||||
|
||||
/// Getter for the second subject of the diff.
|
||||
///
|
||||
/// @return the second member type of the diff.
|
||||
const class_decl::member_type_sptr
|
||||
member_type_diff::second_member_type() const
|
||||
{return dynamic_pointer_cast<class_decl::member_type>(second_subject());}
|
||||
|
||||
/// Getter for the diff of the underlying types of the member types.
|
||||
///
|
||||
/// @return the diff of the underlying type of the member type.
|
||||
diff_sptr
|
||||
member_type_diff::underlying_type_diff() const
|
||||
{return priv_->underlying_type_diff_;}
|
||||
|
||||
/// Setter for the diff of the underlying types of the member types
|
||||
///
|
||||
/// @param d the new diff for the underlying types of the member types
|
||||
/// to set.
|
||||
void
|
||||
member_type_diff::underlying_type_diff(const diff_sptr d)
|
||||
{priv_->underlying_type_diff_ = d;}
|
||||
|
||||
/// Getter for the length of the diff.
|
||||
///
|
||||
/// @return return 1 if the two member types are different, 0
|
||||
/// otherwise.
|
||||
unsigned
|
||||
member_type_diff::length() const
|
||||
{return (*first_member_type() != *second_member_type());}
|
||||
|
||||
/// Report the details of the differences abstracted by the current
|
||||
/// instance of @ref member_type_diff.
|
||||
///
|
||||
/// @param out the output stream to stick the report into.
|
||||
///
|
||||
/// @param indent the string to use as indentation.
|
||||
void
|
||||
member_type_diff::report(ostream& out, const string& indent) const
|
||||
{
|
||||
if (!length())
|
||||
return;
|
||||
|
||||
if (diff_sptr d = context()->has_diff_for(first_subject(),
|
||||
second_subject()))
|
||||
{
|
||||
if (d->currently_reporting())
|
||||
{
|
||||
out << indent << "details are being reported\n";
|
||||
return;
|
||||
}
|
||||
else if (d->reported_once())
|
||||
{
|
||||
out << indent << "details were reported earlier\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
class_decl::member_type_sptr f = first_member_type(),
|
||||
s = second_member_type();
|
||||
string fn = f->get_pretty_representation(),
|
||||
sn = s->get_pretty_representation();
|
||||
|
||||
if (f->get_is_static() != s->get_is_static())
|
||||
{
|
||||
bool lost = f->get_is_static();
|
||||
out << indent << "'" << sn << "' ";
|
||||
if (lost)
|
||||
out << "became non-static";
|
||||
else
|
||||
out << "became static";
|
||||
out << "\n";
|
||||
}
|
||||
if (f->get_access_specifier() != s->get_access_specifier())
|
||||
{
|
||||
out << indent << "'" << fn << "' access changed from '"
|
||||
<< f->get_access_specifier()
|
||||
<< "' to '"
|
||||
<< s->get_access_specifier() << "'\n";
|
||||
}
|
||||
|
||||
if (underlying_type_diff()->length())
|
||||
underlying_type_diff()->report(out, indent);
|
||||
}
|
||||
|
||||
/// Compute the diff of two member types.
|
||||
///
|
||||
/// @return the member type diff object
|
||||
member_type_diff_sptr
|
||||
compute_diff(const class_decl::member_type_sptr first,
|
||||
const class_decl::member_type_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (diff_sptr dif = ctxt->has_diff_for(first, second))
|
||||
{
|
||||
member_type_diff_sptr d = dynamic_pointer_cast<member_type_diff>(dif);
|
||||
assert(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
|
||||
second->get_underlying_type(),
|
||||
ctxt);
|
||||
member_type_diff_sptr result(new member_type_diff(first, second, ctxt));
|
||||
result->underlying_type_diff(d);
|
||||
ctxt->add_diff(first, second, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// </member_type_diff stuff>
|
||||
|
||||
// <function_decl_diff stuff>
|
||||
struct function_decl_diff::priv
|
||||
{
|
||||
@ -3762,6 +3684,10 @@ function_decl_diff::report(ostream& out, const string& indent) const
|
||||
if (length() == 0)
|
||||
return;
|
||||
|
||||
maybe_report_diff_for_class_members(first_function_decl(),
|
||||
second_function_decl(),
|
||||
out, indent);
|
||||
|
||||
string qn1 = first_function_decl()->get_qualified_name(),
|
||||
qn2 = second_function_decl()->get_qualified_name();
|
||||
|
||||
@ -4101,6 +4027,8 @@ typedef_diff::report(ostream& out, const string& indent) const
|
||||
}
|
||||
}
|
||||
|
||||
maybe_report_diff_for_class_members(f, s, out, indent);
|
||||
|
||||
if (f->get_name() != s->get_name())
|
||||
{
|
||||
out << indent << "typedef name changed from "
|
||||
|
@ -586,7 +586,7 @@ die_size_in_bits(Dwarf_Die* die, size_t& size)
|
||||
///
|
||||
/// @return bool if the DIE contains the DW_AT_accessibility die.
|
||||
static bool
|
||||
die_access_specifier(Dwarf_Die * die, class_decl::access_specifier& access)
|
||||
die_access_specifier(Dwarf_Die * die, access_specifier& access)
|
||||
{
|
||||
if (!die)
|
||||
return false;
|
||||
@ -595,20 +595,20 @@ die_access_specifier(Dwarf_Die * die, class_decl::access_specifier& access)
|
||||
if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
|
||||
return false;
|
||||
|
||||
class_decl::access_specifier result = class_decl::private_access;
|
||||
access_specifier result = private_access;
|
||||
|
||||
switch (a)
|
||||
{
|
||||
case class_decl::private_access:
|
||||
result = class_decl::private_access;
|
||||
case private_access:
|
||||
result = private_access;
|
||||
break;
|
||||
|
||||
case class_decl::protected_access:
|
||||
result = class_decl::protected_access;
|
||||
case protected_access:
|
||||
result = protected_access;
|
||||
break;
|
||||
|
||||
case class_decl::public_access:
|
||||
result = class_decl::public_access;
|
||||
case public_access:
|
||||
result = public_access;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1919,13 +1919,10 @@ get_scope_for_die(read_context& ctxt,
|
||||
|
||||
decl_base_sptr d = build_ir_node_from_die(ctxt, &parent_die,
|
||||
called_for_public_decl);
|
||||
scope_decl_sptr s =
|
||||
as_non_member_class_decl(d)
|
||||
? dynamic_pointer_cast<scope_decl>(as_non_member_class_decl(d))
|
||||
: dynamic_pointer_cast<scope_decl>(d);
|
||||
scope_decl_sptr s = dynamic_pointer_cast<scope_decl>(d);
|
||||
assert(s);
|
||||
|
||||
class_decl_sptr cl = as_non_member_class_decl(d);
|
||||
class_decl_sptr cl = dynamic_pointer_cast<class_decl>(d);
|
||||
if (cl && cl->get_is_declaration_only())
|
||||
{
|
||||
scope_decl_sptr scop (cl->get_definition_of_declaration());
|
||||
@ -1982,7 +1979,7 @@ build_translation_unit_and_add_to_ir(read_context& ctxt,
|
||||
v != ctxt.var_decls_to_re_add_to_tree().end();
|
||||
++v)
|
||||
{
|
||||
if (as_non_member_class_decl((*v)->get_scope()))
|
||||
if (is_member_decl(*v))
|
||||
continue;
|
||||
|
||||
assert((*v)->get_scope());
|
||||
@ -1997,7 +1994,7 @@ build_translation_unit_and_add_to_ir(read_context& ctxt,
|
||||
if (!fqn_comps.empty())
|
||||
ty_decl = lookup_type_in_translation_unit(fqn_comps,
|
||||
*ctxt.cur_tu());
|
||||
if (class_decl_sptr cl = as_non_member_class_decl(ty_decl))
|
||||
if (class_decl_sptr cl = dynamic_pointer_cast<class_decl>(ty_decl))
|
||||
{
|
||||
// so this is a static member variable then.
|
||||
// So remove it from its current non-class scope and
|
||||
@ -2244,7 +2241,7 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
result->set_is_declaration_only(true);
|
||||
|
||||
res = add_decl_to_scope(result, scope);
|
||||
result = dynamic_pointer_cast<class_decl>(as_non_member_type(res));
|
||||
result = dynamic_pointer_cast<class_decl>(res);
|
||||
assert(result);
|
||||
}
|
||||
|
||||
@ -2256,8 +2253,7 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
ctxt.die_wip_classes_map()[dwarf_dieoffset(die)] = res;
|
||||
|
||||
scope_decl_sptr scop =
|
||||
dynamic_pointer_cast<scope_decl>
|
||||
(get_type_declaration(as_non_member_type(res)));
|
||||
dynamic_pointer_cast<scope_decl>(res);
|
||||
assert(scop);
|
||||
ctxt.scope_stack().push(scop.get());
|
||||
|
||||
@ -2285,10 +2281,10 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
if (lookup_type_in_scope(base_type->get_name(), result))
|
||||
continue;
|
||||
|
||||
class_decl::access_specifier access =
|
||||
access_specifier access =
|
||||
is_struct
|
||||
? class_decl::public_access
|
||||
: class_decl::private_access;
|
||||
? public_access
|
||||
: private_access;
|
||||
|
||||
die_access_specifier(&child, access);
|
||||
|
||||
@ -2333,10 +2329,10 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
is_laid_out = die_member_offset(&child, offset_in_bits);
|
||||
offset_in_bits *= 8;
|
||||
|
||||
class_decl::access_specifier access =
|
||||
access_specifier access =
|
||||
is_struct
|
||||
? class_decl::public_access
|
||||
: class_decl::private_access;
|
||||
? public_access
|
||||
: private_access;
|
||||
|
||||
die_access_specifier(&child, access);
|
||||
|
||||
@ -2374,10 +2370,10 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
size_t vindex = 0;
|
||||
if (is_virtual)
|
||||
die_virtual_function_index(&child, vindex);
|
||||
class_decl::access_specifier access =
|
||||
access_specifier access =
|
||||
is_struct
|
||||
? class_decl::public_access
|
||||
: class_decl::private_access;
|
||||
? public_access
|
||||
: private_access;
|
||||
die_access_specifier(&child, access);
|
||||
bool is_static = false;
|
||||
{
|
||||
@ -2429,16 +2425,14 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
called_from_public_decl);
|
||||
if (td)
|
||||
{
|
||||
class_decl::access_specifier access =
|
||||
access_specifier access =
|
||||
is_struct
|
||||
? class_decl::public_access
|
||||
: class_decl::private_access;
|
||||
? public_access
|
||||
: private_access;
|
||||
die_access_specifier(&child, access);
|
||||
|
||||
class_decl::member_type_sptr m =
|
||||
dynamic_pointer_cast<class_decl::member_type>(td);
|
||||
m->set_access_specifier(access);
|
||||
ctxt.die_decl_map()[dwarf_dieoffset(&child)] = m;
|
||||
set_member_access_specifier(td, access);
|
||||
ctxt.die_decl_map()[dwarf_dieoffset(&child)] = td;
|
||||
}
|
||||
}
|
||||
} while (dwarf_siblingof(&child, &child) == 0);
|
||||
@ -2451,15 +2445,9 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
ctxt.die_wip_classes_map().find(dwarf_dieoffset(die));
|
||||
if (i != ctxt.die_wip_classes_map().end())
|
||||
{
|
||||
class_decl::member_type_sptr m =
|
||||
dynamic_pointer_cast<class_decl::member_type>(i->second);
|
||||
if (m)
|
||||
{
|
||||
class_decl::member_type_sptr m2 =
|
||||
dynamic_pointer_cast<class_decl::member_type>(res);
|
||||
if (m2)
|
||||
m2->set_access_specifier(m->get_access_specifier());
|
||||
}
|
||||
if (is_member_type(i->second))
|
||||
set_member_access_specifier(res,
|
||||
get_member_access_specifier(i->second));
|
||||
ctxt.die_wip_classes_map().erase(i);
|
||||
}
|
||||
}
|
||||
@ -2761,7 +2749,7 @@ build_function_decl(read_context& ctxt,
|
||||
/*called_from_public_decl=*/true);
|
||||
|
||||
class_decl_sptr is_method =
|
||||
as_non_member_class_decl(get_scope_for_die(ctxt, die));
|
||||
dynamic_pointer_cast<class_decl>(get_scope_for_die(ctxt, die));
|
||||
|
||||
Dwarf_Die child;
|
||||
function_decl::parameters function_parms;
|
||||
@ -2992,7 +2980,7 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
skope.get(),
|
||||
called_from_public_decl);
|
||||
assert(cl);
|
||||
class_decl_sptr klass = as_non_member_class_decl(cl);
|
||||
class_decl_sptr klass = dynamic_pointer_cast<class_decl>(cl);
|
||||
assert(klass);
|
||||
|
||||
result =
|
||||
@ -3126,7 +3114,7 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
}
|
||||
|
||||
{
|
||||
const class_decl* cl = as_non_member_class_decl(scope);
|
||||
const class_decl* cl = dynamic_cast<class_decl*>(scope);
|
||||
// we shouldn't be in this class b/c, if this DIE is for a
|
||||
// member function, get_scope_for_die on it (prior to
|
||||
// calling this function) should have built the member
|
||||
|
@ -95,8 +95,24 @@ struct decl_base::hash
|
||||
}
|
||||
return d.hash_;
|
||||
}
|
||||
};
|
||||
}; // end struct decl_base::hash
|
||||
|
||||
struct decl_base::hash_as_member
|
||||
{
|
||||
size_t
|
||||
operator()(const decl_base& d) const
|
||||
{
|
||||
decl_base::hash decl_base_hash;
|
||||
|
||||
size_t v = decl_base_hash(d);
|
||||
if (is_member_decl(d))
|
||||
{
|
||||
v = hashing::combine_hashes(v, get_member_access_specifier(d));
|
||||
v = hashing::combine_hashes(v, get_member_is_static(d));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
};// end struct decl_base::hash_as_member
|
||||
struct type_decl::hash
|
||||
{
|
||||
size_t
|
||||
@ -124,7 +140,7 @@ struct scope_type_decl::hash
|
||||
{
|
||||
if (t.hash_ == 0)
|
||||
{
|
||||
decl_base::hash decl_hash;
|
||||
decl_base::hash_as_member decl_hash;
|
||||
type_base::hash type_hash;
|
||||
std::tr1::hash<string> str_hash;
|
||||
|
||||
@ -216,10 +232,12 @@ struct enum_type_decl::hash
|
||||
if (t.hash_ == 0)
|
||||
{
|
||||
std::tr1::hash<string> str_hash;
|
||||
decl_base::hash_as_member member_hash;
|
||||
type_base::shared_ptr_hash type_ptr_hash;
|
||||
std::tr1::hash<size_t> size_t_hash;
|
||||
|
||||
size_t v = str_hash(typeid(t).name());
|
||||
v = hashing::combine_hashes(v, member_hash(t));
|
||||
v = hashing::combine_hashes(v, type_ptr_hash(t.get_underlying_type()));
|
||||
for (enum_type_decl::enumerators::const_iterator i =
|
||||
t.get_enumerators().begin();
|
||||
@ -244,7 +262,7 @@ struct typedef_decl::hash
|
||||
{
|
||||
std::tr1::hash<string> str_hash;
|
||||
type_base::hash hash_type;
|
||||
decl_base::hash decl_hash;
|
||||
decl_base::hash_as_member decl_hash;
|
||||
type_base::shared_ptr_hash type_ptr_hash;
|
||||
|
||||
size_t v = str_hash(typeid(t).name());
|
||||
@ -397,20 +415,6 @@ class_decl::member_base::hash::operator()(const member_base& m) const
|
||||
return hash_int(m.get_access_specifier());
|
||||
}
|
||||
|
||||
size_t
|
||||
class_decl::member_type::hash::operator()(const member_type& t)const
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
size_t
|
||||
class_decl::base_spec::hash::operator()(const base_spec& t) const
|
||||
{
|
||||
@ -514,9 +518,10 @@ struct class_decl::hash
|
||||
{
|
||||
std::tr1::hash<string> hash_string;
|
||||
std::tr1::hash<bool> hash_bool;
|
||||
type_base::dynamic_hash hash_type;
|
||||
decl_base::hash_as_member hash_as_member;
|
||||
scope_type_decl::hash hash_scope_type;
|
||||
class_decl::base_spec::hash hash_base;
|
||||
class_decl::member_type::hash hash_member_type;
|
||||
class_decl::data_member::hash hash_data_member;
|
||||
class_decl::member_function::hash hash_member_fn;
|
||||
class_decl::member_function_template::hash hash_member_fn_tmpl;
|
||||
@ -540,7 +545,11 @@ struct class_decl::hash
|
||||
t.get_member_types().begin();
|
||||
ti != t.get_member_types().end();
|
||||
++ti)
|
||||
v = hashing::combine_hashes(v, hash_member_type(**ti));
|
||||
{
|
||||
decl_base_sptr decl = get_type_declaration(*ti);
|
||||
v = hashing::combine_hashes(v, hash_as_member(*decl));
|
||||
v = hashing::combine_hashes(v, hash_type((*ti).get()));
|
||||
}
|
||||
|
||||
// Hash data members.
|
||||
for (class_decl::data_members::const_iterator d =
|
||||
@ -774,9 +783,6 @@ 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);
|
||||
|
540
src/abg-ir.cc
540
src/abg-ir.cc
@ -60,7 +60,7 @@ public:
|
||||
|
||||
expanded_location(const string& path, unsigned line, unsigned column)
|
||||
: path_(path), line_(line), column_(column)
|
||||
{ }
|
||||
{}
|
||||
|
||||
bool
|
||||
operator==(const expanded_location& l) const
|
||||
@ -301,14 +301,12 @@ decl_base::decl_base(const std::string& name, location locus,
|
||||
location_(locus),
|
||||
name_(name),
|
||||
mangled_name_(mangled_name),
|
||||
context_(0),
|
||||
visibility_(vis)
|
||||
{ }
|
||||
|
||||
decl_base::decl_base(location l)
|
||||
: hash_(0),
|
||||
location_(l),
|
||||
context_(0),
|
||||
visibility_(VISIBILITY_DEFAULT)
|
||||
{ }
|
||||
|
||||
@ -348,6 +346,18 @@ void
|
||||
decl_base::set_hash(size_t h) const
|
||||
{hash_ = h;}
|
||||
|
||||
/// Return the type containing the current decl, if any.
|
||||
///
|
||||
/// @return the type that contains the current decl, or NULL if there
|
||||
/// is none.
|
||||
scope_decl*
|
||||
decl_base::get_scope() const
|
||||
{
|
||||
if (context_)
|
||||
return context_->get_scope();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Return a copy of the qualified name of the parent of the current
|
||||
/// decl.
|
||||
///
|
||||
@ -435,7 +445,18 @@ decl_base::operator==(const decl_base& other) const
|
||||
if (hash_ && other.hash_
|
||||
&& hash_ != other.hash_)
|
||||
return false;
|
||||
return get_name() == other.get_name();
|
||||
|
||||
if (get_name() != other.get_name())
|
||||
return false;
|
||||
|
||||
if (is_member_decl(this) && is_member_decl(other))
|
||||
{
|
||||
context_rel_sptr r1 = get_context_rel(), r2 = other.get_context_rel();
|
||||
if (*r1 != *r2)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
decl_base::~decl_base()
|
||||
@ -458,7 +479,12 @@ decl_base::traverse(ir_node_visitor&)
|
||||
/// rather the scope that holds a reference on its members.
|
||||
void
|
||||
decl_base::set_scope(scope_decl* scope)
|
||||
{context_ = scope;}
|
||||
{
|
||||
if (!context_)
|
||||
context_.reset(new context_rel(scope));
|
||||
else
|
||||
context_->set_scope(scope);
|
||||
}
|
||||
|
||||
/// Streaming operator for the decl_base::visibility.
|
||||
///
|
||||
@ -544,6 +570,204 @@ operator==(decl_base_sptr l, decl_base_sptr r)
|
||||
return *l == *r;
|
||||
}
|
||||
|
||||
/// Tests if a declaration has got a scope.
|
||||
///
|
||||
/// @param d the decalaration to consider.
|
||||
///
|
||||
/// @return true if the declaration has got a scope, false otherwise.
|
||||
bool
|
||||
has_scope(const decl_base& d)
|
||||
{return (d.get_scope());}
|
||||
|
||||
/// Tests if a declaration has got a scope.
|
||||
///
|
||||
/// @param d the decalaration to consider.
|
||||
///
|
||||
/// @return true if the declaration has got a scope, false otherwise.
|
||||
bool
|
||||
has_scope(const decl_base_sptr d)
|
||||
{return has_scope(*d.get());}
|
||||
|
||||
/// Tests if a type has got a scope.
|
||||
///
|
||||
/// @param t the type to consider.
|
||||
///
|
||||
/// @return true if the type has got a scope, false otherwise.
|
||||
bool
|
||||
has_scope(const type_base& t)
|
||||
{
|
||||
try
|
||||
{
|
||||
const decl_base& d = dynamic_cast<const decl_base&>(t);
|
||||
return has_scope(d);
|
||||
}
|
||||
catch(...)
|
||||
{}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Tests if a type has got a scope.
|
||||
///
|
||||
/// @param t the type to consider.
|
||||
///
|
||||
/// @return true if the type has got a scope, false otherwise.
|
||||
bool
|
||||
has_scope(const type_base_sptr t)
|
||||
{
|
||||
const decl_base_sptr d = dynamic_pointer_cast<decl_base>(t);
|
||||
if (d)
|
||||
return has_scope(d);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Tests if a declaration is a class member.
|
||||
///
|
||||
/// @param d the declaration to consider.
|
||||
///
|
||||
/// @return true if @p d is a class member, false otherwise.
|
||||
bool
|
||||
is_member_decl(const decl_base_sptr d)
|
||||
{return is_at_class_scope(d);}
|
||||
|
||||
/// Tests if a declaration is a class member.
|
||||
///
|
||||
/// @param d the declaration to consider.
|
||||
///
|
||||
/// @return true if @p d is a class member, false otherwise.
|
||||
bool
|
||||
is_member_decl(const decl_base* d)
|
||||
{return is_at_class_scope(d);}
|
||||
|
||||
/// Tests if a declaration is a class member.
|
||||
///
|
||||
/// @param d the declaration to consider.
|
||||
///
|
||||
/// @return true if @p d is a class member, false otherwise.
|
||||
bool
|
||||
is_member_decl(const decl_base& d)
|
||||
{return is_at_class_scope(d);}
|
||||
|
||||
/// Tests if a type is a class member.
|
||||
///
|
||||
/// @param t the type to consider.
|
||||
///
|
||||
/// @return true if @p t is a class member type, false otherwise.
|
||||
bool
|
||||
is_member_type(const type_base_sptr t)
|
||||
{
|
||||
decl_base_sptr d = get_type_declaration(t);
|
||||
return is_member_decl(d);
|
||||
}
|
||||
|
||||
/// Tests if a type is a class member.
|
||||
///
|
||||
/// @param t the type to consider.
|
||||
///
|
||||
/// @return true if @p t is a class member type, false otherwise.
|
||||
bool
|
||||
is_member_type(const decl_base_sptr d)
|
||||
{
|
||||
if (type_base_sptr t = is_type(d))
|
||||
return is_member_type(t);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Gets the access specifier for a class member.
|
||||
///
|
||||
/// @param d the declaration of the class member to consider. Note
|
||||
/// that this must be a class member otherwise the function aborts the
|
||||
/// current process.
|
||||
///
|
||||
/// @return the access specifier for the class member @p d.
|
||||
access_specifier
|
||||
get_member_access_specifier(const decl_base& d)
|
||||
{
|
||||
assert(is_member_decl(d));
|
||||
|
||||
context_rel_sptr c = d.get_context_rel();
|
||||
assert(c);
|
||||
|
||||
return c->get_access_specifier();
|
||||
}
|
||||
|
||||
/// Gets the access specifier for a class member.
|
||||
///
|
||||
/// @param d the declaration of the class member to consider. Note
|
||||
/// that this must be a class member otherwise the function aborts the
|
||||
/// current process.
|
||||
///
|
||||
/// @return the access specifier for the class member @p d.
|
||||
access_specifier
|
||||
get_member_access_specifier(const decl_base_sptr d)
|
||||
{return get_member_access_specifier(*d);}
|
||||
|
||||
/// Sets the access specifier for a class member.
|
||||
///
|
||||
/// @param d the class member to set the access specifier for. Note
|
||||
/// that this must be a class member otherwise the function aborts the
|
||||
/// current process.
|
||||
///
|
||||
/// @param a the new access specifier to set the class member to.
|
||||
void
|
||||
set_member_access_specifier(decl_base_sptr d,
|
||||
access_specifier a)
|
||||
{
|
||||
assert(is_member_decl(d));
|
||||
|
||||
context_rel_sptr c = d->get_context_rel();
|
||||
assert(c);
|
||||
|
||||
c->set_access_specifier(a);
|
||||
}
|
||||
|
||||
/// Gets a flag saying if a class member is static or not.
|
||||
///
|
||||
/// @param d the declaration for the class member to consider. Note
|
||||
/// that this must be a class member otherwise the function aborts the
|
||||
/// current process.
|
||||
///
|
||||
/// @return true if the class member @p d is static, false otherwise.
|
||||
bool
|
||||
get_member_is_static(const decl_base&d)
|
||||
{
|
||||
assert(is_member_decl(d));
|
||||
|
||||
context_rel_sptr c = d.get_context_rel();
|
||||
assert(c);
|
||||
|
||||
return c->get_is_static();
|
||||
}
|
||||
|
||||
/// Gets a flag saying if a class member is static or not.
|
||||
///
|
||||
/// @param d the declaration for the class member to consider. Note
|
||||
/// that this must be a class member otherwise the function aborts the
|
||||
/// current process.
|
||||
///
|
||||
/// @return true if the class member @p d is static, false otherwise.
|
||||
bool
|
||||
get_member_is_static(const decl_base_sptr d)
|
||||
{return get_member_is_static(*d);}
|
||||
|
||||
/// Sets the static-ness property of a class member.
|
||||
///
|
||||
/// @param d the class member to set the static-ness property for.
|
||||
/// Note that this must be a class member otherwise the function
|
||||
/// aborts the current process.
|
||||
///
|
||||
/// @param s this must be true if the member is to be static, false
|
||||
/// otherwise.
|
||||
void
|
||||
set_member_is_static(decl_base_sptr d, bool s)
|
||||
{
|
||||
assert(is_member_decl(d));
|
||||
|
||||
context_rel_sptr c = d->get_context_rel();
|
||||
assert(c);
|
||||
|
||||
c->set_is_static(s);
|
||||
}
|
||||
|
||||
// </decl_base definition>
|
||||
|
||||
/// Add a member decl to this scope. Note that user code should not
|
||||
@ -1010,6 +1234,24 @@ bool
|
||||
is_at_class_scope(const shared_ptr<decl_base> decl)
|
||||
{return (decl && dynamic_cast<class_decl*>(decl->get_scope()));}
|
||||
|
||||
/// Tests whether a given decl is at class scope.
|
||||
///
|
||||
/// @param decl the decl to consider.
|
||||
///
|
||||
/// @return true iff decl is at class scope.
|
||||
bool
|
||||
is_at_class_scope(const decl_base* decl)
|
||||
{return (decl && dynamic_cast<class_decl*>(decl->get_scope()));}
|
||||
|
||||
/// Tests whether a given decl is at class scope.
|
||||
///
|
||||
/// @param decl the decl to consider.
|
||||
///
|
||||
/// @return true iff decl is at class scope.
|
||||
bool
|
||||
is_at_class_scope(const decl_base& decl)
|
||||
{return (dynamic_cast<class_decl*>(decl.get_scope()));}
|
||||
|
||||
/// Tests whether a given decl is at template scope.
|
||||
///
|
||||
/// Note that only template parameters , types that are compositions,
|
||||
@ -1059,82 +1301,6 @@ type_base_sptr
|
||||
is_type(const decl_base_sptr decl)
|
||||
{return dynamic_pointer_cast<type_base>(decl);}
|
||||
|
||||
/// If a type is a member type, return its underying type.
|
||||
///
|
||||
///@param t the type to consider.
|
||||
///
|
||||
/// @return return the underlying type of a member type, or return the
|
||||
/// type itself.
|
||||
type_base_sptr
|
||||
as_non_member_type(const type_base_sptr t)
|
||||
{
|
||||
class_decl::member_type_sptr m =
|
||||
dynamic_pointer_cast<class_decl::member_type>(t);
|
||||
if (m)
|
||||
return m->get_underlying_type();
|
||||
else
|
||||
return t;
|
||||
}
|
||||
|
||||
/// If a type is a member type, return its underying type.
|
||||
///
|
||||
///@param t the type to consider.
|
||||
///
|
||||
/// @return return the underlying type of a member type, or return the
|
||||
/// type itself.
|
||||
type_base_sptr
|
||||
as_non_member_type(const decl_base_sptr t)
|
||||
{
|
||||
class_decl::member_type_sptr m =
|
||||
dynamic_pointer_cast<class_decl::member_type>(t);
|
||||
if (m)
|
||||
return m->get_underlying_type();
|
||||
else
|
||||
return dynamic_pointer_cast<type_base>(t);
|
||||
}
|
||||
|
||||
/// Return the underlying class decl of a member class decl type.
|
||||
///
|
||||
/// If a given type is a member class decl, return its underlying
|
||||
/// class type.
|
||||
///
|
||||
/// @param t the member type to consider.
|
||||
///
|
||||
/// @return the underlying class decl of the member type given in
|
||||
/// parameter, if it's a member class decl. If the parameter was a
|
||||
/// non-member class decl, just return that class decl. Otherwise, it
|
||||
/// the parameter was not a class decl at all, return nil.
|
||||
class_decl_sptr
|
||||
as_non_member_class_decl(const decl_base_sptr t)
|
||||
{
|
||||
class_decl::member_type_sptr m =
|
||||
dynamic_pointer_cast<class_decl::member_type>(t);
|
||||
if (m)
|
||||
return dynamic_pointer_cast<class_decl>(m->get_underlying_type());
|
||||
return dynamic_pointer_cast<class_decl>(t);
|
||||
}
|
||||
|
||||
/// Return the underlying class decl of a member class decl type.
|
||||
///
|
||||
/// If a given type is a member class decl, return its underlying
|
||||
/// class type.
|
||||
///
|
||||
/// @param t the member type to consider.
|
||||
///
|
||||
/// @return the underlying class decl of the member type given in
|
||||
/// parameter, if it's a member class decl. If the parameter was a
|
||||
/// non-member class decl, just return that class decl. Otherwise, it
|
||||
/// the parameter was not a class decl at all, return nil.
|
||||
const class_decl*
|
||||
as_non_member_class_decl(const decl_base* t)
|
||||
{
|
||||
const class_decl::member_type* m =
|
||||
dynamic_cast<const class_decl::member_type*>(t);
|
||||
if (m)
|
||||
return dynamic_cast<const class_decl*>(m->get_underlying_type().get());
|
||||
return dynamic_cast<const class_decl*>(t);
|
||||
}
|
||||
|
||||
/// If a class is a decl-only class, get its definition. Otherwise,
|
||||
/// just return the initial class.
|
||||
///
|
||||
@ -1337,7 +1503,7 @@ get_node_name(decl_base_sptr node)
|
||||
template<>
|
||||
const string&
|
||||
get_node_name(type_base_sptr node)
|
||||
{return get_type_declaration(as_non_member_type(node))->get_name();}
|
||||
{return get_type_declaration(node)->get_name();}
|
||||
|
||||
/// Gets the name of a var_decl node.
|
||||
///
|
||||
@ -2792,17 +2958,17 @@ class_decl::class_decl(const std::string& name, size_t size_in_bits,
|
||||
member_functions_(mbr_fns)
|
||||
{
|
||||
for (member_types::iterator i = mbrs.begin(); i != mbrs.end(); ++i)
|
||||
if (!(*i)->get_scope())
|
||||
add_decl_to_scope(*i, this);
|
||||
if (!has_scope(*i))
|
||||
add_decl_to_scope(get_type_declaration(*i), this);
|
||||
|
||||
for (data_members::iterator i = data_mbrs.begin(); i != data_mbrs.end();
|
||||
++i)
|
||||
if (!(*i)->get_scope())
|
||||
if (!has_scope(static_pointer_cast<decl_base>(*i)))
|
||||
add_decl_to_scope(*i, this);
|
||||
|
||||
for (member_functions::iterator i = mbr_fns.begin(); i != mbr_fns.end();
|
||||
++i)
|
||||
if (!(*i)->get_scope())
|
||||
if (!has_scope(static_pointer_cast<decl_base>(*i)))
|
||||
add_decl_to_scope(*i, this);
|
||||
|
||||
}
|
||||
@ -2872,7 +3038,7 @@ class_decl::set_definition_of_declaration(class_decl_sptr d)
|
||||
void
|
||||
class_decl::set_earlier_declaration(decl_base_sptr declaration)
|
||||
{
|
||||
class_decl_sptr cl = as_non_member_class_decl(declaration);
|
||||
class_decl_sptr cl = dynamic_pointer_cast<class_decl>(declaration);
|
||||
if (cl && cl->get_is_declaration_only())
|
||||
declaration_ = declaration;
|
||||
}
|
||||
@ -2881,24 +3047,14 @@ decl_base_sptr
|
||||
class_decl::insert_member_decl(decl_base_sptr d,
|
||||
declarations::iterator before)
|
||||
{
|
||||
if (member_type_sptr t = dynamic_pointer_cast<member_type>(d))
|
||||
{
|
||||
insert_member_type(t, before);
|
||||
d = t;
|
||||
}
|
||||
else if (type_base_sptr t = dynamic_pointer_cast<type_base>(d))
|
||||
{
|
||||
class_decl::member_type_sptr m
|
||||
(new class_decl::member_type(t, class_decl::public_access));
|
||||
add_member_type(m);
|
||||
d = m;
|
||||
}
|
||||
if (type_base_sptr t = dynamic_pointer_cast<type_base>(d))
|
||||
insert_member_type(t, before);
|
||||
else if (data_member_sptr m = dynamic_pointer_cast<data_member>(d))
|
||||
add_data_member(m);
|
||||
else if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
|
||||
{
|
||||
class_decl::data_member_sptr dm
|
||||
(new class_decl::data_member(v, class_decl::public_access,
|
||||
(new class_decl::data_member(v, public_access,
|
||||
/*is_laid_out=*/false,
|
||||
/*is_static=*/false,
|
||||
/*offset_in_bits=*/0));
|
||||
@ -2927,9 +3083,7 @@ class_decl::insert_member_decl(decl_base_sptr d,
|
||||
/// @param d the member declaration to add.
|
||||
decl_base_sptr
|
||||
class_decl::add_member_decl(decl_base_sptr d)
|
||||
{
|
||||
return insert_member_decl(d, get_member_decls().end());
|
||||
}
|
||||
{return insert_member_decl(d, get_member_decls().end());}
|
||||
|
||||
/// Remove a given decl from the current class scope.
|
||||
///
|
||||
@ -2951,29 +3105,16 @@ class_decl::remove_member_decl(decl_base_sptr decl)
|
||||
}
|
||||
|
||||
void
|
||||
class_decl::insert_member_type(member_type_sptr t,
|
||||
class_decl::insert_member_type(type_base_sptr t,
|
||||
declarations::iterator before)
|
||||
{
|
||||
scope_decl* c = t->get_scope();
|
||||
/// TODO: use our own assertion facility that adds a meaningful
|
||||
/// error message or something like a structured error.
|
||||
//assert(!c || c == this);
|
||||
assert(!c);
|
||||
decl_base_sptr d = get_type_declaration(t);
|
||||
assert(d);
|
||||
assert(!has_scope(d));
|
||||
|
||||
if (decl_base_sptr d = dynamic_pointer_cast<decl_base>(t))
|
||||
{
|
||||
scope_decl* s = d->get_scope();
|
||||
if (s)
|
||||
{
|
||||
scope_decl* o = this;
|
||||
assert(*s == *o);
|
||||
}
|
||||
}
|
||||
t->set_scope(this);
|
||||
d->set_scope(this);
|
||||
member_types_.push_back(t);
|
||||
decl_base_sptr td = get_type_declaration(t->get_underlying_type());
|
||||
td->set_scope(this);
|
||||
scope_decl::insert_member_decl(td, before);
|
||||
scope_decl::insert_member_decl(d, before);
|
||||
}
|
||||
|
||||
/// Add a member type to the current instance of class_decl.
|
||||
@ -2981,7 +3122,7 @@ class_decl::insert_member_type(member_type_sptr t,
|
||||
/// @param t the member type to add. It must not have been added to a
|
||||
/// scope, otherwise this will violate an assertion.
|
||||
void
|
||||
class_decl::add_member_type(member_type_sptr t)
|
||||
class_decl::add_member_type(type_base_sptr t)
|
||||
{insert_member_type(t, get_member_decls().end());}
|
||||
|
||||
/// Add a member type to the current instance of class_decl.
|
||||
@ -2991,14 +3132,15 @@ class_decl::add_member_type(member_type_sptr t)
|
||||
/// will be created out of @p t and and added to the the class.
|
||||
///
|
||||
/// @param a the access specifier for the member type to be created.
|
||||
class_decl::member_type_sptr
|
||||
type_base_sptr
|
||||
class_decl::add_member_type(type_base_sptr t, access_specifier a)
|
||||
{
|
||||
decl_base_sptr d = get_type_declaration(t);
|
||||
assert(!d->get_scope());
|
||||
shared_ptr<class_decl::member_type> m(new class_decl::member_type(t, a));
|
||||
add_member_type(m);
|
||||
return m;
|
||||
assert(d);
|
||||
assert(!is_member_decl(d));
|
||||
add_member_type(t);
|
||||
set_member_access_specifier(d, a);
|
||||
return t;
|
||||
}
|
||||
|
||||
/// Remove a member type from the current class scope.
|
||||
@ -3753,92 +3895,6 @@ class_decl::member_base::operator==(const member_base& o) const
|
||||
&& get_is_static() == o.get_is_static());
|
||||
}
|
||||
|
||||
/// Constructor of a class_decl::member_type
|
||||
///
|
||||
/// @param t the type to be member of the class
|
||||
///
|
||||
/// @param access the access specifier for the member type.
|
||||
class_decl::member_type::member_type(shared_ptr<type_base> t,
|
||||
access_specifier access)
|
||||
: decl_base(*dynamic_pointer_cast<decl_base>(t)), type_base(*t),
|
||||
member_base(access), type_(t)
|
||||
{set_scope(0);}
|
||||
|
||||
/// Get the underlying type of a member type.
|
||||
///
|
||||
/// @return the new underlying type.
|
||||
const type_base_sptr&
|
||||
class_decl::member_type::get_underlying_type() const
|
||||
{return type_;}
|
||||
|
||||
/// Traverse a class_decl::member_type IR Node all the way to its
|
||||
/// underlying type.
|
||||
///
|
||||
/// @param v the visitor to use to visit the current node and its
|
||||
/// underlying nodes.
|
||||
void
|
||||
class_decl::member_type::traverse(ir_node_visitor& v)
|
||||
{
|
||||
v.visit(this);
|
||||
type_base_sptr t = get_underlying_type();
|
||||
decl_base_sptr decl = get_type_declaration(t);
|
||||
assert(decl);
|
||||
decl->traverse(v);
|
||||
}
|
||||
|
||||
/// Set the scope of a member type.
|
||||
///
|
||||
/// @param scope the new scope to set.
|
||||
void
|
||||
class_decl::member_type::set_scope(scope_decl* scope)
|
||||
{
|
||||
decl_base::context_ = scope;
|
||||
decl_base_sptr td = get_type_declaration(get_underlying_type());
|
||||
td->set_scope(scope);
|
||||
}
|
||||
|
||||
bool
|
||||
class_decl::member_type::operator==(const decl_base& other) const
|
||||
{
|
||||
try
|
||||
{
|
||||
const class_decl::member_type& o =
|
||||
dynamic_cast<const class_decl::member_type&>(other);
|
||||
return (member_base::operator==(o)
|
||||
&& (*get_underlying_type() == *o.get_underlying_type()));
|
||||
}
|
||||
catch(...)
|
||||
{return false;}
|
||||
}
|
||||
|
||||
bool
|
||||
class_decl::member_type::operator==(const member_base& other) const
|
||||
{
|
||||
try
|
||||
{
|
||||
const decl_base& o = dynamic_cast<const decl_base&>(other);;
|
||||
return *this == o;
|
||||
}
|
||||
catch(...)
|
||||
{return false;}
|
||||
}
|
||||
|
||||
bool
|
||||
class_decl::member_type::operator==(const type_base& other) const
|
||||
{
|
||||
const decl_base* o = dynamic_cast<const class_decl::member_type*>(&other);
|
||||
if (!o)
|
||||
return false;
|
||||
return *this == *o;
|
||||
}
|
||||
|
||||
bool
|
||||
class_decl::member_type::operator==(const member_type& other) const
|
||||
{
|
||||
const decl_base& o = other;
|
||||
return *this == o;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(class_decl::base_spec_sptr l, class_decl::base_spec_sptr r)
|
||||
{
|
||||
@ -3850,17 +3906,6 @@ operator==(class_decl::base_spec_sptr l, class_decl::base_spec_sptr r)
|
||||
return *l == *r;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(class_decl::member_type_sptr l, class_decl::member_type_sptr r)
|
||||
{
|
||||
if (l.get() == r.get())
|
||||
return true;
|
||||
if (!!l != !!r)
|
||||
return false;
|
||||
|
||||
return *l == *r;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(class_decl::data_member_sptr l, class_decl::data_member_sptr r)
|
||||
{
|
||||
@ -3888,37 +3933,6 @@ class_decl::data_member::operator==(const decl_base& o) const
|
||||
{return false;}
|
||||
}
|
||||
|
||||
/// Build the qualified name of the current instance of @ref
|
||||
/// class_decl::member_type.
|
||||
///
|
||||
/// @param qualified_name output parameter. Is set to the qualified
|
||||
/// name name that is newly built.
|
||||
void
|
||||
class_decl::member_type::get_qualified_name(string& qualified_name) const
|
||||
{
|
||||
decl_base_sptr td = get_type_declaration(get_underlying_type());
|
||||
td->get_qualified_name(qualified_name);
|
||||
}
|
||||
|
||||
/// Build the qualified name for the current instance of
|
||||
/// class_decl::member_type.
|
||||
///
|
||||
/// @return a copy of the newly-built qualified name.
|
||||
string
|
||||
class_decl::member_type::get_qualified_name() const
|
||||
{
|
||||
string result;
|
||||
get_qualified_name(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
string
|
||||
class_decl::member_type::get_pretty_representation() const
|
||||
{
|
||||
decl_base_sptr td = get_type_declaration(get_underlying_type());
|
||||
return td->get_pretty_representation();
|
||||
}
|
||||
|
||||
void
|
||||
class_decl::data_member::traverse(ir_node_visitor& v)
|
||||
{v.visit(this);}
|
||||
@ -4079,22 +4093,22 @@ class_decl::member_class_template::traverse(ir_node_visitor& v)
|
||||
///
|
||||
/// @return the output stream.
|
||||
std::ostream&
|
||||
operator<<(std::ostream& o, class_decl::access_specifier a)
|
||||
operator<<(std::ostream& o, access_specifier a)
|
||||
{
|
||||
string r;
|
||||
|
||||
switch (a)
|
||||
{
|
||||
case class_decl::no_access:
|
||||
case no_access:
|
||||
r = "none";
|
||||
break;
|
||||
case class_decl::private_access:
|
||||
case private_access:
|
||||
r = "private";
|
||||
break;
|
||||
case class_decl::protected_access:
|
||||
case protected_access:
|
||||
r = "protected";
|
||||
break;
|
||||
case class_decl::public_access:
|
||||
case public_access:
|
||||
r= "public";
|
||||
break;
|
||||
};
|
||||
@ -4459,10 +4473,6 @@ void
|
||||
ir_node_visitor::visit(class_decl::data_member*)
|
||||
{}
|
||||
|
||||
void
|
||||
ir_node_visitor::visit(class_decl::member_type*)
|
||||
{}
|
||||
|
||||
void
|
||||
ir_node_visitor::visit(class_decl::member_function*)
|
||||
{}
|
||||
|
@ -505,7 +505,7 @@ static bool read_translation_unit_from_input(read_context&,
|
||||
static bool read_location(read_context&, xmlNodePtr, location&);
|
||||
static bool read_visibility(xmlNodePtr, decl_base::visibility&);
|
||||
static bool read_binding(xmlNodePtr, decl_base::binding&);
|
||||
static bool read_access(xmlNodePtr, class_decl::access_specifier&);
|
||||
static bool read_access(xmlNodePtr, access_specifier&);
|
||||
static bool read_size_and_alignment(xmlNodePtr, size_t&, size_t&);
|
||||
static bool read_static(xmlNodePtr, bool&);
|
||||
static bool read_offset_in_bits(xmlNodePtr, size_t&);
|
||||
@ -1026,20 +1026,20 @@ read_binding(xmlNodePtr node, decl_base::binding& bind)
|
||||
///
|
||||
/// @return true upon sucessful completion, false otherwise.
|
||||
static bool
|
||||
read_access(xmlNodePtr node, class_decl::access_specifier& access)
|
||||
read_access(xmlNodePtr node, access_specifier& access)
|
||||
{
|
||||
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "access"))
|
||||
{
|
||||
string a = CHAR_STR(s);
|
||||
|
||||
if (a == "private")
|
||||
access = class_decl::private_access;
|
||||
access = private_access;
|
||||
else if (a == "protected")
|
||||
access = class_decl::protected_access;
|
||||
access = protected_access;
|
||||
else if (a == "public")
|
||||
access = class_decl::public_access;
|
||||
access = public_access;
|
||||
else
|
||||
access = class_decl::private_access;
|
||||
access = private_access;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1660,8 +1660,7 @@ build_qualified_type_decl(read_context& ctxt,
|
||||
|
||||
if (type_base_sptr d = ctxt.get_type_decl(id))
|
||||
{
|
||||
qualified_type_def_sptr ty =
|
||||
dynamic_pointer_cast<qualified_type_def>(as_non_member_type(d));
|
||||
qualified_type_def_sptr ty = dynamic_pointer_cast<qualified_type_def>(d);
|
||||
assert(ty);
|
||||
assert(*ty->get_underlying_type() == *underlying_type);
|
||||
assert(ty->get_cv_quals() == cv);
|
||||
@ -1738,8 +1737,7 @@ build_pointer_type_def(read_context& ctxt,
|
||||
assert(!id.empty());
|
||||
if (type_base_sptr d = ctxt.get_type_decl(id))
|
||||
{
|
||||
pointer_type_def_sptr ty =
|
||||
dynamic_pointer_cast<pointer_type_def>(as_non_member_type(d));
|
||||
pointer_type_def_sptr ty = dynamic_pointer_cast<pointer_type_def>(d);
|
||||
assert(ty);
|
||||
assert(*pointed_to_type == *ty->get_pointed_to_type());
|
||||
return ty;
|
||||
@ -1827,8 +1825,7 @@ build_reference_type_def(read_context& ctxt,
|
||||
|
||||
if (type_base_sptr d = ctxt.get_type_decl(id))
|
||||
{
|
||||
reference_type_def_sptr ty =
|
||||
dynamic_pointer_cast<reference_type_def>(as_non_member_type(d));
|
||||
reference_type_def_sptr ty = dynamic_pointer_cast<reference_type_def>(d);
|
||||
assert(ty);
|
||||
assert(*pointed_to_type == *ty->get_pointed_to_type());
|
||||
return ty;
|
||||
@ -1996,8 +1993,7 @@ build_typedef_decl(read_context& ctxt,
|
||||
|
||||
if (type_base_sptr d = ctxt.get_type_decl(id))
|
||||
{
|
||||
typedef_decl_sptr ty =
|
||||
dynamic_pointer_cast<typedef_decl>(as_non_member_type((d)));
|
||||
typedef_decl_sptr ty = dynamic_pointer_cast<typedef_decl>(d);
|
||||
assert(ty);
|
||||
assert(name == ty->get_name());
|
||||
assert(underlying_type == ty->get_underlying_type());
|
||||
@ -2038,7 +2034,7 @@ build_class_decl(read_context& ctxt,
|
||||
|
||||
if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
|
||||
{
|
||||
class_decl_sptr result = as_non_member_class_decl(d);
|
||||
class_decl_sptr result = dynamic_pointer_cast<class_decl>(d);
|
||||
assert(result);
|
||||
return result;
|
||||
}
|
||||
@ -2129,7 +2125,7 @@ build_class_decl(read_context& ctxt,
|
||||
|
||||
if (xmlStrEqual(n->name, BAD_CAST("base-class")))
|
||||
{
|
||||
class_decl::access_specifier access = class_decl::private_access;
|
||||
access_specifier access = private_access;
|
||||
read_access(n, access);
|
||||
|
||||
string type_id;
|
||||
@ -2156,7 +2152,7 @@ build_class_decl(read_context& ctxt,
|
||||
}
|
||||
else if (xmlStrEqual(n->name, BAD_CAST("member-type")))
|
||||
{
|
||||
class_decl::access_specifier access = class_decl::private_access;
|
||||
access_specifier access = private_access;
|
||||
read_access(n, access);
|
||||
|
||||
ctxt.map_xml_node_to_decl(n, decl);
|
||||
@ -2171,14 +2167,14 @@ build_class_decl(read_context& ctxt,
|
||||
{
|
||||
if (!get_type_declaration(t)->get_scope())
|
||||
{
|
||||
class_decl::member_type_sptr m =
|
||||
type_base_sptr m =
|
||||
decl->add_member_type(t, access);
|
||||
|
||||
xml_char_sptr i= XML_NODE_GET_ATTRIBUTE(p, "id");
|
||||
string id = CHAR_STR(i);
|
||||
assert(!id.empty());
|
||||
ctxt.key_type_decl(m, id, /*force=*/true);
|
||||
ctxt.map_xml_node_to_decl(p, m);
|
||||
ctxt.map_xml_node_to_decl(p, get_type_declaration(m));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2187,7 +2183,7 @@ build_class_decl(read_context& ctxt,
|
||||
{
|
||||
ctxt.map_xml_node_to_decl(n, decl);
|
||||
|
||||
class_decl::access_specifier access = class_decl::private_access;
|
||||
access_specifier access = private_access;
|
||||
read_access(n, access);
|
||||
|
||||
bool is_laid_out = false;
|
||||
@ -2213,7 +2209,7 @@ build_class_decl(read_context& ctxt,
|
||||
{
|
||||
ctxt.map_xml_node_to_decl(n, decl);
|
||||
|
||||
class_decl::access_specifier access = class_decl::private_access;
|
||||
access_specifier access = private_access;
|
||||
read_access(n, access);
|
||||
|
||||
size_t vtable_offset = 0;
|
||||
@ -2246,7 +2242,7 @@ build_class_decl(read_context& ctxt,
|
||||
{
|
||||
ctxt.map_xml_node_to_decl(n, decl);
|
||||
|
||||
class_decl::access_specifier access = class_decl::private_access;
|
||||
access_specifier access = private_access;
|
||||
read_access(n, access);
|
||||
|
||||
bool is_static = false;
|
||||
|
@ -206,8 +206,7 @@ static void write_location(const shared_ptr<decl_base>&, ostream&);
|
||||
static bool write_visibility(const shared_ptr<decl_base>&, ostream&);
|
||||
static bool write_binding(const shared_ptr<decl_base>&, ostream&);
|
||||
static void write_size_and_alignment(const shared_ptr<type_base>, ostream&);
|
||||
static void write_access(class_decl::access_specifier, ostream&);
|
||||
static void write_access(shared_ptr<class_decl::member_base>, ostream&);
|
||||
static void write_access(access_specifier, ostream&);
|
||||
static void write_layout_offset(shared_ptr<class_decl::data_member>, ostream&);
|
||||
static void write_layout_offset(shared_ptr<class_decl::base_spec>, ostream&);
|
||||
static void write_cdtor_const_static(bool, bool, bool, bool, ostream&);
|
||||
@ -235,7 +234,7 @@ 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,
|
||||
static bool write_member_type(const type_base_sptr,
|
||||
write_context&, unsigned);
|
||||
static bool write_class_decl(const shared_ptr<class_decl>,
|
||||
write_context&, unsigned);
|
||||
@ -469,21 +468,21 @@ write_size_and_alignment(const shared_ptr<type_base> decl, ostream& o)
|
||||
///
|
||||
/// @param o the output stream to serialize it to.
|
||||
static void
|
||||
write_access(class_decl::access_specifier a, ostream& o)
|
||||
write_access(access_specifier a, ostream& o)
|
||||
{
|
||||
string access_str = "private";
|
||||
|
||||
switch (a)
|
||||
{
|
||||
case class_decl::private_access:
|
||||
case private_access:
|
||||
access_str = "private";
|
||||
break;
|
||||
|
||||
case class_decl::protected_access:
|
||||
case protected_access:
|
||||
access_str = "protected";
|
||||
break;
|
||||
|
||||
case class_decl::public_access:
|
||||
case public_access:
|
||||
access_str = "public";
|
||||
break;
|
||||
|
||||
@ -522,10 +521,8 @@ write_layout_offset(shared_ptr<class_decl::base_spec> base, ostream& o)
|
||||
///
|
||||
/// @param o the ostream to serialize the member to.
|
||||
static void
|
||||
write_access(shared_ptr<class_decl::member_base> member, ostream& o)
|
||||
{
|
||||
write_access(member->get_access_specifier(), o);
|
||||
}
|
||||
write_access(decl_base_sptr member, ostream& o)
|
||||
{write_access(get_member_access_specifier(member), o);}
|
||||
|
||||
/// Write the voffset of a member function if it's non-zero
|
||||
///
|
||||
@ -1369,7 +1366,7 @@ write_class_decl(const shared_ptr<class_decl> decl,
|
||||
do_indent(o, nb_ws);
|
||||
o << "<base-class";
|
||||
|
||||
write_access(*base, o);
|
||||
write_access((*base)->get_access_specifier(), o);
|
||||
|
||||
write_layout_offset (*base, o);
|
||||
|
||||
@ -1394,7 +1391,7 @@ write_class_decl(const shared_ptr<class_decl> decl,
|
||||
{
|
||||
do_indent(o, nb_ws);
|
||||
o << "<data-member";
|
||||
write_access(*data, o);
|
||||
write_access((*data)->get_access_specifier(), o);
|
||||
|
||||
bool is_static = (*data)->get_is_static();
|
||||
write_cdtor_const_static(/*is_ctor=*/false,
|
||||
@ -1421,7 +1418,7 @@ write_class_decl(const shared_ptr<class_decl> decl,
|
||||
class_decl::member_function_sptr fn = *f;
|
||||
do_indent(o, nb_ws);
|
||||
o << "<member-function";
|
||||
write_access(fn, o);
|
||||
write_access(fn->get_access_specifier(), o);
|
||||
write_cdtor_const_static( fn->is_constructor(),
|
||||
fn->is_destructor(),
|
||||
fn->is_const(),
|
||||
@ -1446,7 +1443,7 @@ write_class_decl(const shared_ptr<class_decl> decl,
|
||||
{
|
||||
do_indent(o, nb_ws);
|
||||
o << "<member-template";
|
||||
write_access(*fn, o);
|
||||
write_access((*fn)->get_access_specifier(), o);
|
||||
write_cdtor_const_static((*fn)->is_constructor(),
|
||||
/*is_dtor=*/false,
|
||||
(*fn)->is_const(),
|
||||
@ -1466,7 +1463,7 @@ write_class_decl(const shared_ptr<class_decl> decl,
|
||||
{
|
||||
do_indent(o, nb_ws);
|
||||
o << "<member-template";
|
||||
write_access(*cl, o);
|
||||
write_access((*cl)->get_access_specifier(), o);
|
||||
write_cdtor_const_static(false, false, false,
|
||||
(*cl)->get_is_static(), o);
|
||||
o << ">\n";
|
||||
@ -1511,37 +1508,37 @@ write_class_decl(const shared_ptr<class_decl> decl,
|
||||
///
|
||||
/// @param indent the number of levels to use for indentation
|
||||
static bool
|
||||
write_member_type(const class_decl::member_type_sptr decl,
|
||||
write_member_type(const type_base_sptr t,
|
||||
write_context& ctxt, unsigned indent)
|
||||
{
|
||||
if (!decl)
|
||||
if (!t)
|
||||
return false;
|
||||
|
||||
ostream& o = ctxt.get_ostream();
|
||||
|
||||
do_indent_to_level(ctxt, indent, 0);
|
||||
|
||||
decl_base_sptr decl = get_type_declaration(t);
|
||||
assert(decl);
|
||||
|
||||
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);
|
||||
string id = ctxt.get_id_for_type(t);
|
||||
|
||||
unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
|
||||
assert(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(ut),
|
||||
assert(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(t),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(ut),
|
||||
|| write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(t),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_reference_type_def(dynamic_pointer_cast<reference_type_def>(ut),
|
||||
|| write_reference_type_def(dynamic_pointer_cast<reference_type_def>(t),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(ut),
|
||||
|| write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(t),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_typedef_decl(dynamic_pointer_cast<typedef_decl>(ut),
|
||||
|| write_typedef_decl(dynamic_pointer_cast<typedef_decl>(t),
|
||||
id, ctxt, nb_ws)
|
||||
|| write_class_decl(dynamic_pointer_cast<class_decl>(ut),
|
||||
|| write_class_decl(dynamic_pointer_cast<class_decl>(t),
|
||||
id, ctxt, nb_ws));
|
||||
o << "\n";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user