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:
Dodji Seketeli 2014-03-13 11:13:54 +01:00
parent a58f60c08f
commit ca53b99c5a
9 changed files with 641 additions and 680 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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*);

View File

@ -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 "

View File

@ -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

View File

@ -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);

View File

@ -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*)
{}

View File

@ -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;

View File

@ -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";