Support looking through decl-only classes and update diff reports

accordingly

	* include/abg-comparison.h (class diff_context): New class.
	(class diff::{ctxt_, reported_once_, currently_reporting_}): New
	data members.
	(diff::diff): Initialize the new data members above.
	(diff::{context, currently_reporting, reported_once}): New
	accessors.
	(compute_diff, var_diff::var_diff, pointer_diff::pointer_diff)
	(reference_diff::reference_diff, qualified_type_diff)
	(enum_diff:enum_diff, class_diff::class_diff)
	(scope_diff::scope_diff, function_decl_diff::function_decl_diff)
	(type_decl_diff::type_decl_diff, typedef_diff::typedef_diff)
	(translation_unit_diff::translation_unit_diff, corpus_diff::corpus_diff):
	Take an additional pointer to diff_context.
	* abg-comparison.cc (diff_context::{has_diff_for,
	has_diff_for_types, add_diff}): New methods.
	(try_to_diff, compute_diff_for_types, compute_diff_for_decls)
	(represent): Take an additional pointer to
	diff_context in argument.  In the later function, do not re-report
	a diff if it has already been reported, or if it's being reported
	already.
	(var_diff::var_diff, pointer_diff::pointer_diff)
	(reference_diff::reference_diff)
	(qualified_type_diff::qualified_type_diff, enum_diff::enum_diff)
	(class_diff::class_diff, scope_diff::scope_diff)
	(function_decl_diff::function_decl_diff, type_decl::type_decl)
	(typedef_diff::typedef_diff)
	(translation_unit_diff::translation_unit_diff)
	(corpus_diff::corpus_diff): Take an additional pointer to
	diff_context in argument.
	({pointer_diff, qualified_type_diff,
	reference_type_diff}::report): do not re-report a diff about the
	underlying type if it has already been reported, or if it's being
	reported already.
	(enum_diff::report): Fix this to properly use the populated lookup
	tables.
	(compute_diff): take an additional pointer to diff_context in
	argument. For the var_decl, pointer_diff reference_type_diff,
	qualified_type_diff enum_diff, scope_diff, function_decl_diff,
	type_decl_diff and typedef_diff overloads, do not re-build a diff
	object, if one exits already.  Otherwise, record the new diff
	object created so that it can be re-used later.
	(enum_diff::ensure_lookup_tables_populated): Fix logic to avoid
	one loop.
	(class_decl::priv::{deleted_member_functions_,
	inserted_member_functions_, changed_member_function_}): New
	members to support reporting about member functions changes.
	(class_decl::{lookup_tables_empty, clear_lookup_tables, length):
	Update for the new additions above.
	(class_decl::ensure_lookup_tables_populated): Likewise.  Fix to
	properly use the lookup tables and also avoid a going through
	several loops to compute the changed members.
	(class_decl::report): Flip a switch to make the beginning and end
	of the reporting, in the context.  Also, do not try to report
	again, if we were already reporting this diff.  Fix quite some
	spots to properly use the lookup tables.
	(scope_diff::ensure_lookup_tables_populated): Skip decl-only
	classes during comparison. Fix some thinkos.  Fix logic to avoid a
	loop.
	(scope_diff::report): Adjust to pass a context to
	compute_diff_for_types.
	(function_decl_diff::ensure_lookup_tables_populated): Fix logic to
	avoid a loop.
	(function_decl_diff::report): Adjust call to
	compute_diff_for_types to pass the context.
	(typedef::report): Avoid re-reporting the diff of the underlying
	types, if we are already reporting it.
	(corpus_diff::priv::ensure_lookup_tables_populated): Use the
	pretty representation of the function rather than its name to key
	the maps of deleted and added functions. Fix logic to avoid going
	through an additional loop for the changed functions.
	(corpus_diff::report): Add a title for removed/added/changed
	functions.  Fix indentation for added/removed/changed functions.
	* include/abg-ir.h (class_decl::comparison_started_): New member
	* src/abg-dwarf-reader.cc (is_public_decl): Style fix.
	(is_declaration_only_): New static function.
	(build_class_type_and_add_to_ir): Create decl-only classes (IR) for
	classes flagged as declaration-only in the DWARF.
	* src/abg-hash.cc (class_decl:#️⃣:operator()): Do not forget to
	include the "is_declaration_only" flag into the hashing.
	* src/abg-ir.cc (class_decl::operator==): Look through decl-only
	classes to get their definitions and compare the definitions
	instead.  Avoid comparing member types and fns if the comparison
	of this type has already started.
	* src/abg-reader.cc (build_class_decl): Set the definition of a
	declaration, when we see it.
	* tests/data/test-bidiff/test-qual-type0-report.txt: Update.
	* tests/data/test-bidiff/test-struct0-report.txt: Likewise.
	* tests/data/test-bidiff/test-struct1-report.txt: Likewise.

signed-off-by: Dodji Seketeli <dodji@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2014-02-07 18:52:45 +01:00
parent a2cd6d7e04
commit 9905d847d2
10 changed files with 1364 additions and 609 deletions

View File

@ -106,6 +106,23 @@ typedef std::pair<function_decl*, function_decl*> changed_function_ptr;
typedef unordered_map<string,
changed_function_ptr> string_changed_function_ptr_map;
/// Convenience typedef for a pair of class_decl::member_function_sptr
/// representing a changed member function. The first element of the
/// pair is the initial member function and the second element is the
/// changed one.
typedef pair<class_decl::member_function_sptr,
class_decl::member_function_sptr> changed_member_function_sptr;
/// Convenience typedef for a hash map of strings and changed member functions.
typedef unordered_map<string,
changed_member_function_sptr>
string_changed_member_function_sptr_map;
/// Convenience typedef for a hash map of strings and member functions.
typedef unordered_map<string,
class_decl::member_function_sptr>
string_member_function_sptr_map;
/// Convenience typedef for a map which key is a string and which
/// value is a point to @ref var_decl.
typedef unordered_map<string, var_decl*> string_var_ptr_map;
@ -120,6 +137,39 @@ typedef std::pair<var_decl*, var_decl*> changed_var_ptr;
/// value is a @ref changed_var_ptr.
typedef unordered_map<string, changed_var_ptr> string_changed_var_ptr_map;
class diff_context;
/// Convenience typedef for a shared pointer of @ref diff_context.
typedef shared_ptr<diff_context> diff_context_sptr;
/// The context of the diff. This type holds various bits of
/// information that is going to be used throughout the diffing of two
/// entities and the reporting that follows.
class diff_context
{
struct priv;
shared_ptr<priv> priv_;
public:
diff_context();
diff_sptr
has_diff_for(const decl_base_sptr first,
const decl_base_sptr second) const;
diff_sptr
has_diff_for_types(const type_base_sptr first,
const type_base_sptr second) const;
diff_sptr
has_diff_for(const diff_sptr d) const;
void
add_diff(const decl_base_sptr first,
const decl_base_sptr second,
diff_sptr d);
};//end struct diff_context.
/// This type encapsulates an edit script (a set of insertions and
/// deletions) for two constructs that are to be diff'ed. The two
/// constructs are called the "subjects" of the diff.
@ -127,12 +177,27 @@ class diff
{
decl_base_sptr first_subject_;
decl_base_sptr second_subject_;
diff_context_sptr ctxt_;
mutable bool reported_once_;
mutable bool currently_reporting_;
protected:
diff(decl_base_sptr first_subject,
decl_base_sptr second_subject)
: first_subject_(first_subject),
second_subject_(second_subject)
second_subject_(second_subject),
reported_once_(false),
currently_reporting_(false)
{}
diff(decl_base_sptr first_subject,
decl_base_sptr second_subject,
diff_context_sptr ctxt)
: first_subject_(first_subject),
second_subject_(second_subject),
ctxt_(ctxt),
reported_once_(false),
currently_reporting_(false)
{}
public:
@ -151,6 +216,55 @@ public:
second_subject() const
{return second_subject_;}
/// Getter of the context of the current diff.
///
/// @return the context of the current diff.
const diff_context_sptr
context() const
{return ctxt_;}
/// Setter of the context of the current diff.
///
/// @param c the new context to set.
void
context(diff_context_sptr c)
{ctxt_ = c;}
/// Tests if we are currently in the middle of emitting a report for
/// this diff.
///
/// @return true if we are currently emitting a report for the
/// current diff, false otherwise.
bool
currently_reporting() const
{return currently_reporting_;}
/// Sets a flag saying if we are currently in the middle of emitting
/// a report for this diff.
///
/// @param f true if we are currently emitting a report for the
/// current diff, false otherwise.
void
currently_reporting(bool f) const
{currently_reporting_ = f;}
/// Tests if a report has already been emitted for the current diff.
///
/// @return true if a report has already been emitted for the
/// current diff, false otherwise.
bool
reported_once() const
{return reported_once_;}
/// Sets a flag saying if a report has already been emitted for the
/// current diff.
///
/// @param f true if a repot has already been emitted for the
/// current diff, false otherwise.
void
reported_once(bool f) const
{reported_once_ = f;}
/// Pure interface to get the length of the changes
/// encapsulated by this diff. This is to be implemented by all
/// descendants of this class.
@ -171,10 +285,14 @@ public:
};// end class diff
diff_sptr
compute_diff(decl_base_sptr, decl_base_sptr);
compute_diff(const decl_base_sptr,
const decl_base_sptr,
diff_context_sptr ctxt);
diff_sptr
compute_diff(type_base_sptr, type_base_sptr);
compute_diff(const type_base_sptr,
const type_base_sptr,
diff_context_sptr ctxt);
class var_diff;
@ -189,7 +307,10 @@ class var_diff : public diff
priv_sptr priv_;
protected:
var_diff(var_decl_sptr, var_decl_sptr, diff_sptr);
var_diff(var_decl_sptr first,
var_decl_sptr second,
diff_sptr type_diff,
diff_context_sptr ctxt = diff_context_sptr());
public:
var_decl_sptr
@ -208,11 +329,13 @@ public:
report(ostream& out, const string& indent = "") const;
friend var_diff_sptr
compute_diff(const var_decl_sptr first, const var_decl_sptr second);
}; // end class var_diff
compute_diff(const var_decl_sptr first,
const var_decl_sptr second,
diff_context_sptr ctxt);
};// end class var_diff
var_diff_sptr
compute_diff(const var_decl_sptr, const var_decl_sptr);
compute_diff(const var_decl_sptr, const var_decl_sptr, diff_context_sptr);
class pointer_diff;
/// Convenience typedef for a shared pointer on a @ref
@ -226,8 +349,9 @@ class pointer_diff : public diff
shared_ptr<priv> priv_;
protected:
pointer_diff(pointer_type_def_sptr first,
pointer_type_def_sptr second);
pointer_diff(pointer_type_def_sptr first,
pointer_type_def_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
public:
const pointer_type_def_sptr
@ -249,13 +373,15 @@ public:
report(ostream&, const string& indent = "") const;
friend pointer_diff_sptr
compute_diff(pointer_type_def_sptr first,
pointer_type_def_sptr second);
compute_diff(pointer_type_def_sptr first,
pointer_type_def_sptr second,
diff_context_sptr ctxt);
};// end class pointer_diff
pointer_diff_sptr
compute_diff(pointer_type_def_sptr first,
pointer_type_def_sptr second);
pointer_type_def_sptr second,
diff_context_sptr ctxt);
class reference_diff;
@ -270,8 +396,9 @@ class reference_diff : public diff
shared_ptr<priv> priv_;
protected:
reference_diff(const reference_type_def_sptr first,
const reference_type_def_sptr second);
reference_diff(const reference_type_def_sptr first,
const reference_type_def_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
public:
reference_type_def_sptr
@ -294,12 +421,14 @@ public:
friend reference_diff_sptr
compute_diff(reference_type_def_sptr first,
reference_type_def_sptr second);
reference_type_def_sptr second,
diff_context_sptr ctxt);
};// end class reference_diff
reference_diff_sptr
compute_diff(reference_type_def_sptr first,
reference_type_def_sptr second);
reference_type_def_sptr second,
diff_context_sptr ctxt);
class qualified_type_diff;
typedef class shared_ptr<qualified_type_diff> qualified_type_diff_sptr;
@ -312,8 +441,9 @@ class qualified_type_diff : public diff
priv_sptr priv_;
protected:
qualified_type_diff(qualified_type_def_sptr first,
qualified_type_def_sptr second);
qualified_type_diff(qualified_type_def_sptr first,
qualified_type_def_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
public:
const qualified_type_def_sptr
@ -336,12 +466,14 @@ public:
friend qualified_type_diff_sptr
compute_diff(const qualified_type_def_sptr first,
const qualified_type_def_sptr second);
const qualified_type_def_sptr second,
diff_context_sptr ctxt);
};// end class qualified_type_diff.
qualified_type_diff_sptr
compute_diff(const qualified_type_def_sptr first,
const qualified_type_def_sptr second);
const qualified_type_def_sptr second,
diff_context_sptr ctxt);
class enum_diff;
typedef shared_ptr<enum_diff> enum_diff_sptr;
@ -365,7 +497,8 @@ class enum_diff : public diff
protected:
enum_diff(const enum_type_decl_sptr,
const enum_type_decl_sptr,
const diff_sptr);
const diff_sptr,
diff_context_sptr ctxt = diff_context_sptr());
public:
const enum_type_decl_sptr
@ -394,12 +527,14 @@ public:
friend enum_diff_sptr
compute_diff(const enum_type_decl_sptr first,
const enum_type_decl_sptr second);
const enum_type_decl_sptr second,
diff_context_sptr ctxt);
};//end class enum_diff;
enum_diff_sptr
compute_diff(const enum_type_decl_sptr,
const enum_type_decl_sptr);
const enum_type_decl_sptr,
diff_context_sptr ctxt);
class class_diff;
@ -422,7 +557,9 @@ class class_diff : public diff
ensure_lookup_tables_populated(void) const;
protected:
class_diff(class_decl_sptr first_scope, class_decl_sptr second_scope);
class_diff(class_decl_sptr first_scope,
class_decl_sptr second_scope,
diff_context_sptr ctxt = diff_context_sptr());
public:
//TODO: add change of the name of the type.
@ -477,12 +614,14 @@ public:
friend class_diff_sptr
compute_diff(const class_decl_sptr first,
const class_decl_sptr second);
const class_decl_sptr second,
diff_context_sptr ctxt);
};// end class_diff
class_diff_sptr
compute_diff(const class_decl_sptr first,
const class_decl_sptr second);
compute_diff(const class_decl_sptr first,
const class_decl_sptr second,
diff_context_sptr ctxt);
class scope_diff;
@ -506,18 +645,21 @@ class scope_diff : public diff
protected:
scope_diff(scope_decl_sptr first_scope,
scope_decl_sptr second_scope);
scope_decl_sptr second_scope,
diff_context_sptr ctxt = diff_context_sptr());
public:
friend scope_diff_sptr
compute_diff(const scope_decl_sptr first,
const scope_decl_sptr second,
scope_diff_sptr d);
compute_diff(const scope_decl_sptr first,
const scope_decl_sptr second,
scope_diff_sptr d,
diff_context_sptr ctxt);
friend scope_diff_sptr
compute_diff(const scope_decl_sptr first_scope,
const scope_decl_sptr second_scope);
compute_diff(const scope_decl_sptr first_scope,
const scope_decl_sptr second_scope,
diff_context_sptr ctxt);
const scope_decl_sptr
first_scope() const;
@ -571,11 +713,13 @@ public:
scope_diff_sptr
compute_diff(const scope_decl_sptr first,
const scope_decl_sptr second,
scope_diff_sptr d);
scope_diff_sptr d,
diff_context_sptr ctxt);
scope_diff_sptr
compute_diff(const scope_decl_sptr first_scope,
const scope_decl_sptr second_scope);
const scope_decl_sptr second_scope,
diff_context_sptr ctxt);
class function_decl_diff;
@ -598,13 +742,15 @@ class function_decl_diff : public diff
inserted_parameter_at(int i) const;
protected:
function_decl_diff(const function_decl_sptr first,
const function_decl_sptr second);
function_decl_diff(const function_decl_sptr first,
const function_decl_sptr second,
diff_context_sptr ctxt);
public:
friend function_decl_diff_sptr
compute_diff(const function_decl_sptr first,
const function_decl_sptr second);
compute_diff(const function_decl_sptr first,
const function_decl_sptr second,
diff_context_sptr ctxt);
const function_decl_sptr
first_function_decl() const;
@ -632,8 +778,9 @@ compute_diff(const function_decl_sptr first,
}; // end class function_decl_diff
function_decl_diff_sptr
compute_diff(const function_decl_sptr first,
const function_decl_sptr second);
compute_diff(const function_decl_sptr first,
const function_decl_sptr second,
diff_context_sptr ctxt);
class type_decl_diff;
@ -646,11 +793,15 @@ class type_decl_diff : public diff
type_decl_diff();
protected:
type_decl_diff(const type_decl_sptr, const type_decl_sptr);
type_decl_diff(const type_decl_sptr first,
const type_decl_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
public:
friend type_decl_diff_sptr
compute_diff(const type_decl_sptr first, const type_decl_sptr second);
compute_diff(const type_decl_sptr first,
const type_decl_sptr second,
diff_context_sptr ctxt);
const type_decl_sptr
first_type_decl() const;
@ -666,7 +817,9 @@ public:
};// end type_decl_diff
type_decl_diff_sptr
compute_diff(const type_decl_sptr, const type_decl_sptr);
compute_diff(const type_decl_sptr,
const type_decl_sptr,
diff_context_sptr);
class typedef_diff;
@ -682,13 +835,15 @@ class typedef_diff : public diff
typedef_diff();
protected:
typedef_diff(const typedef_decl_sptr first,
const typedef_decl_sptr second);
typedef_diff(const typedef_decl_sptr first,
const typedef_decl_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
public:
friend typedef_diff_sptr
compute_diff(const typedef_decl_sptr first, const typedef_decl_sptr second);
compute_diff(const typedef_decl_sptr first,
const typedef_decl_sptr second,
diff_context_sptr ctxt);
const typedef_decl_sptr
first_typedef_decl() const;
@ -710,7 +865,9 @@ public:
};// end class typedef_diff
typedef_diff_sptr
compute_diff(const typedef_decl_sptr, const typedef_decl_sptr);
compute_diff(const typedef_decl_sptr,
const typedef_decl_sptr,
diff_context_sptr ctxt);
class translation_unit_diff;
@ -722,13 +879,15 @@ typedef shared_ptr<translation_unit_diff> translation_unit_diff_sptr;
class translation_unit_diff : public scope_diff
{
protected:
translation_unit_diff(translation_unit_sptr first,
translation_unit_sptr second);
translation_unit_diff(translation_unit_sptr first,
translation_unit_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
public:
friend translation_unit_diff_sptr
compute_diff(const translation_unit_sptr first,
const translation_unit_sptr second);
compute_diff(const translation_unit_sptr first,
const translation_unit_sptr second,
diff_context_sptr ctxt);
virtual unsigned
length() const;
@ -739,7 +898,8 @@ public:
translation_unit_diff_sptr
compute_diff(const translation_unit_sptr first,
const translation_unit_sptr second);
const translation_unit_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
class corpus_diff;
@ -754,8 +914,9 @@ class corpus_diff
priv_sptr priv_;
protected:
corpus_diff(corpus_sptr first,
corpus_sptr second);
corpus_diff(corpus_sptr first,
corpus_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
public:
@ -778,11 +939,15 @@ public:
report(ostream& out, const string& indent = "") const;
friend corpus_diff_sptr
compute_diff(const corpus_sptr f, const corpus_sptr s);
compute_diff(const corpus_sptr f,
const corpus_sptr s,
diff_context_sptr ctxt = diff_context_sptr());
}; // end class corpus_diff
corpus_diff_sptr
compute_diff(const corpus_sptr, const corpus_sptr);
compute_diff(const corpus_sptr,
const corpus_sptr,
diff_context_sptr);
}// end namespace comparison
}// end namespace abigail

View File

@ -1619,6 +1619,7 @@ public:
private:
mutable bool hashing_started_;
mutable bool comparison_started_;
decl_base_sptr declaration_;
bool is_declaration_only_;
class_decl_sptr definition_of_declaration_;

File diff suppressed because it is too large Load Diff

View File

@ -622,11 +622,26 @@ die_access_specifier(Dwarf_Die * die, class_decl::access_specifier& access)
static bool
is_public_decl(Dwarf_Die* die)
{
bool is_public = 0;
bool is_public = false;
die_flag_attribute(die, DW_AT_external, is_public);
return is_public;
}
/// Test whether a given DIE represents a declaration-only DIE.
///
/// That is, if the DIE has the DW_AT_declaration flag set.
///
/// @param die the DIE to consider.
///
/// @return true if a DW_AT_declaration is present, false otherwise.
static bool
is_declaration_only(Dwarf_Die* die)
{
bool is_declaration_only = false;
die_flag_attribute(die, DW_AT_declaration, is_declaration_only);
return is_declaration_only;
}
///@return true if a tag represents a type, false otherwise.
///
///@param tag the tag to consider.
@ -2147,6 +2162,13 @@ build_class_type_and_add_to_ir(read_context& ctxt,
class_decl_sptr cur_class_decl (new class_decl(name));
decl_base_sptr cur_class =
add_decl_to_scope(cur_class_decl, scope);
Dwarf_Die child;
bool has_child = (dwarf_child(die, &child) == 0);
if (!has_child && is_declaration_only(die))
return cur_class;
ctxt.die_wip_classes_map()[dwarf_dieoffset(die)] = cur_class;
result.reset(new class_decl(name, size, 0, loc,
@ -2163,8 +2185,7 @@ build_class_type_and_add_to_ir(read_context& ctxt,
assert(scop);
ctxt.scope_stack().push(scop.get());
Dwarf_Die child;
if (dwarf_child(die, &child) == 0)
if (has_child)
{
do
{

View File

@ -512,9 +512,8 @@ struct class_decl::hash
if (t.hash_ == 0)
{
t.hashing_started(true);
std::tr1::hash<string> hash_string;
std::tr1::hash<bool> hash_bool;
scope_type_decl::hash hash_scope_type;
class_decl::base_spec::hash hash_base;
class_decl::member_type::hash hash_member_type;
@ -525,6 +524,9 @@ struct class_decl::hash
size_t v = hash_string(typeid(t).name());
v = hashing::combine_hashes(v, hash_scope_type(t));
v = hashing::combine_hashes(v, hash_bool(t.is_declaration_only()));
t.hashing_started(true);
// Hash bases.
for (class_decl::base_specs::const_iterator b =

View File

@ -2266,6 +2266,7 @@ class_decl::class_decl(const std::string& name, size_t size_in_bits,
type_base(size_in_bits, align_in_bits),
scope_type_decl(name, size_in_bits, align_in_bits, locus, vis),
hashing_started_(false),
comparison_started_(false),
is_declaration_only_(false),
bases_(bases),
member_types_(mbrs),
@ -2307,6 +2308,7 @@ class_decl::class_decl(const std::string& name, size_t size_in_bits,
type_base(size_in_bits, align_in_bits),
scope_type_decl(name, size_in_bits, align_in_bits, locus, vis),
hashing_started_(false),
comparison_started_(false),
is_declaration_only_(false)
{}
@ -2322,6 +2324,7 @@ class_decl::class_decl(const std::string& name, bool is_declaration_only)
type_base(0, 0),
scope_type_decl(name, 0, 0, location()),
hashing_started_(false),
comparison_started_(false),
is_declaration_only_(is_declaration_only)
{}
@ -2915,25 +2918,62 @@ class_decl::has_no_base_nor_member() const
bool
class_decl::operator==(const decl_base& other) const
{
const class_decl* op = 0;
try
{
const class_decl* op = dynamic_cast<const class_decl*>(&other);
op = dynamic_cast<const class_decl*>(&other);
if (!op)
return false;
const class_decl& o = *op;
comparison_started_ = true;
o.comparison_started_ = true;
#define RETURN(value) \
{ \
comparison_started_ = false; \
op->comparison_started_ = false; \
return value; \
}
// if one of the classes is declaration-only, look through it to
// get its definition.
if (is_declaration_only()
|| o.is_declaration_only())
{
string q1 = get_qualified_name();
string q2 = o.get_qualified_name();
if (q1 != q2)
RETURN(false);
const class_decl* def1 = is_declaration_only()
? get_definition_of_declaration().get()
: this;
const class_decl* def2 = o.is_declaration_only()
? o.get_definition_of_declaration().get()
: op;
if (!def1 || !def2)
RETURN(true);
bool val = *def1 == *def2;
RETURN(val);
}
// No need to go further if the classes have different names or
// different size / alignment.
if (!(decl_base::operator==(o) && type_base::operator==(o)))
return false;
RETURN(false);
if (hash_ != other.hash_)
return false;
RETURN(false);
// Compare bases.
{
if (get_base_specifiers().size() != o.get_base_specifiers().size())
return false;
RETURN(false);
base_specs::const_iterator b0, b1;
for(b0 = get_base_specifiers().begin(),
@ -2942,101 +2982,116 @@ class_decl::operator==(const decl_base& other) const
&& b1 != o.get_base_specifiers().end());
++b0, ++b1)
if (**b0 != **b1)
return false;
RETURN(false);
if (b0 != get_base_specifiers().end()
|| b1 != o.get_base_specifiers().end())
return false;
RETURN(false);
}
//Compare member types
{
if (get_member_types().size() != o.get_member_types().size())
return false;
RETURN(false);
member_types::const_iterator t0, t1;
for (t0 = get_member_types().begin(), t1 = o.get_member_types().begin();
t0 != get_member_types().end() && t1 != o.get_member_types().end();
++t0, ++t1)
if (!(**t0 == **t1))
return false;
if (t0 != get_member_types().end() || t1 != o.get_member_types().end())
return false;
if (!comparison_started_ && !o.comparison_started_)
{
member_types::const_iterator t0, t1;
for (t0 = get_member_types().begin(),
t1 = o.get_member_types().begin();
(t0 != get_member_types().end()
&& t1 != o.get_member_types().end());
++t0, ++t1)
if (!(**t0 == **t1))
RETURN(false);
if (t0 != get_member_types().end()
|| t1 != o.get_member_types().end())
RETURN(false);
}
}
//compare data_members
{
if (get_data_members().size() != o.get_data_members().size())
return false;
RETURN(false);
data_members::const_iterator d0, d1;
for (d0 = get_data_members().begin(), d1 = o.get_data_members().begin();
d0 != get_data_members().end() && d1 != o.get_data_members().end();
++d0, ++d1)
if (**d0 != **d1)
return false;
RETURN(false);
if (d0 != get_data_members().end() || d1 != o.get_data_members().end())
return false;
RETURN(false);
}
//compare member functions
{
if (get_member_functions().size() != o.get_member_functions().size())
return false;
RETURN(false);
member_functions::const_iterator f0, f1;
for (f0 = get_member_functions().begin(),
f1 = o.get_member_functions().begin();
f0 != get_member_functions().end()
&& f1 != o.get_member_functions().end();
++f0, ++f1)
if (**f0 != **f1)
return false;
if (f0 != get_member_functions().end()
|| f1 != o.get_member_functions().end())
return false;
if (!comparison_started_ && !o.comparison_started_)
{
member_functions::const_iterator f0, f1;
for (f0 = get_member_functions().begin(),
f1 = o.get_member_functions().begin();
f0 != get_member_functions().end()
&& f1 != o.get_member_functions().end();
++f0, ++f1)
if (**f0 != **f1)
RETURN(false);
if (f0 != get_member_functions().end()
|| f1 != o.get_member_functions().end())
RETURN(false);
}
}
// compare member function templates
{
if (get_member_function_templates().size()
!= o.get_member_function_templates().size())
return false;
RETURN(false);
member_function_templates::const_iterator fn_tmpl_it0, fn_tmpl_it1;
for (fn_tmpl_it0 = get_member_function_templates().begin(),
fn_tmpl_it1 = o.get_member_function_templates().begin();
fn_tmpl_it0 != get_member_function_templates().end()
&& fn_tmpl_it1 != o.get_member_function_templates().end();
++fn_tmpl_it0, ++fn_tmpl_it1)
if (**fn_tmpl_it0 != **fn_tmpl_it1)
return false;
if (fn_tmpl_it0 != get_member_function_templates().end()
|| fn_tmpl_it1 != o.get_member_function_templates().end())
return false;
if (!comparison_started_ && !o.comparison_started_)
{
member_function_templates::const_iterator fn_tmpl_it0, fn_tmpl_it1;
for (fn_tmpl_it0 = get_member_function_templates().begin(),
fn_tmpl_it1 = o.get_member_function_templates().begin();
fn_tmpl_it0 != get_member_function_templates().end()
&& fn_tmpl_it1 != o.get_member_function_templates().end();
++fn_tmpl_it0, ++fn_tmpl_it1)
if (**fn_tmpl_it0 != **fn_tmpl_it1)
RETURN(false);
if (fn_tmpl_it0 != get_member_function_templates().end()
|| fn_tmpl_it1 != o.get_member_function_templates().end())
RETURN(false);
}
}
// compare member class templates
{
if (get_member_class_templates().size()
!= o.get_member_class_templates().size())
return false;
RETURN(false);
member_class_templates::const_iterator cl_tmpl_it0, cl_tmpl_it1;
for (cl_tmpl_it0 = get_member_class_templates().begin(),
cl_tmpl_it1 = o.get_member_class_templates().begin();
cl_tmpl_it0 != get_member_class_templates().end()
&& cl_tmpl_it1 != o.get_member_class_templates().end();
++cl_tmpl_it0, ++cl_tmpl_it1)
if (**cl_tmpl_it0 != **cl_tmpl_it1)
return false;
if (cl_tmpl_it0 != get_member_class_templates().end()
|| cl_tmpl_it1 != o.get_member_class_templates().end())
return false;
if (!comparison_started_ && !o.comparison_started_)
{
member_class_templates::const_iterator cl_tmpl_it0, cl_tmpl_it1;
for (cl_tmpl_it0 = get_member_class_templates().begin(),
cl_tmpl_it1 = o.get_member_class_templates().begin();
cl_tmpl_it0 != get_member_class_templates().end()
&& cl_tmpl_it1 != o.get_member_class_templates().end();
++cl_tmpl_it0, ++cl_tmpl_it1)
if (**cl_tmpl_it0 != **cl_tmpl_it1)
RETURN(false);
if (cl_tmpl_it0 != get_member_class_templates().end()
|| cl_tmpl_it1 != o.get_member_class_templates().end())
RETURN(false);
}
}
}
catch (...)
{return false;}
return true;
{RETURN(false);}
RETURN(true);
}
/// Equality operator for class_decl.

View File

@ -2069,6 +2069,7 @@ build_class_decl(read_context& ctxt,
{
is_def_of_decl = true;
decl->set_earlier_declaration(d);
d->set_definition_of_declaration(decl);
}
}

View File

@ -1,28 +1,20 @@
3 changed types:
'class S0' changed:
size changed from 32 to 64 bits
1 member type change:
'typedef S0::S0' changed:
underlying type class S0 changed; details are being reported
1 data member insertion:
'char S0::m1', at offset 32 (in bits)
'const S0' changed:
in unqualified underlying type 'class S0':
size changed from 32 to 64 bits
1 data member insertion:
'char S0::m1', at offset 32 (in bits)
unqualified underlying type class S0 changed, as reported earlier
'const S0&' changed:
in referenced type 'const S0':
in unqualified underlying type 'class S0':
size changed from 32 to 64 bits
1 data member insertion:
'char S0::m1', at offset 32 (in bits)
in refereneced type 'const S0':
unqualified underlying type class S0 changed, as reported earlier
1 changed declaration:
'function void foo(const S0&)' was changed to 'function void foo(const S0&)':
parameter 0 of type 'const S0&' changed:
in referenced type 'const S0':
in unqualified underlying type 'class S0':
size changed from 32 to 64 bits
1 data member insertion:
'char S0::m1', at offset 32 (in bits)
in refereneced type 'const S0':
unqualified underlying type class S0 changed, as reported earlier

View File

@ -1,8 +1,12 @@
2 changed types:
'class s0' changed:
size changed from 64 to 96 bits
1 member type change:
'typedef s0::s0' changed:
underlying type class s0 changed; details are being reported
1 data member change:
's0::m1' type changed:
'char s0::m1' type changed:
name changed from 'char' to 'unsigned int'
size changed from 8 to 32 bits
alignment changed from 8 to 32 bits
@ -11,28 +15,8 @@
'char s0::m2', at offset 64 (in bits)
's0&' changed:
in referenced type 'class s0':
size changed from 64 to 96 bits
1 data member change:
's0::m1' type changed:
name changed from 'char' to 'unsigned int'
size changed from 8 to 32 bits
alignment changed from 8 to 32 bits
1 data member insertion:
'char s0::m2', at offset 64 (in bits)
referenced type 'class s0' changed, as reported earlier
1 changed declaration:
'function int foo(s0&)' was changed to 'function int foo(s0&)':
parameter 0 of type 's0&' changed:
in referenced type 'class s0':
size changed from 64 to 96 bits
1 data member change:
's0::m1' type changed:
name changed from 'char' to 'unsigned int'
size changed from 8 to 32 bits
alignment changed from 8 to 32 bits
1 data member insertion:
'char s0::m2', at offset 64 (in bits)
referenced type 'class s0' changed, as reported earlier

View File

@ -1,42 +1,15 @@
2 changed types:
'class s0' changed:
size changed from 192 to 256 bits
1 member type change:
'typedef s0::number_type' changed:
underlying type changed:
name changed from 'int' to 'char'
size changed from 32 to 8 bits
alignment changed from 32 to 8 bits
1 member type insertion:
'typedef s0::grrr'
1 data member deletion:
'char s0::m1', at offset 96 (in bits)
2 data member changes:
's0::m2' offset changed from 128 to 192
's0::m0' type changed:
name changed from 'int' to 'char'
size changed from 32 to 8 bits
alignment changed from 32 to 8 bits
1 data member insertion:
'double s0::m01', at offset 128 (in bits)
2 member function insertions:
'method int s0::foo()'
'method int s0::foo(int, char) const', virtual at voffset 2/2
's0&' changed:
in referenced type 'class s0':
5 changed types:
'const s0' changed:
in unqualified underlying type 'class s0':
size changed from 192 to 256 bits
1 member type change:
2 member type changes:
'typedef s0::s0' changed:
underlying type class s0 changed; details are being reported
'typedef s0::number_type' changed:
underlying type changed:
name changed from 'int' to 'char'
size changed from 32 to 8 bits
alignment changed from 32 to 8 bits
underlying type changed:
name changed from 'int' to 'char'
size changed from 32 to 8 bits
alignment changed from 32 to 8 bits
1 member type insertion:
'typedef s0::grrr'
@ -46,7 +19,7 @@
2 data member changes:
's0::m2' offset changed from 128 to 192
's0::m0' type changed:
'int s0::m0' type changed:
name changed from 'int' to 'char'
size changed from 32 to 8 bits
alignment changed from 32 to 8 bits
@ -55,9 +28,17 @@
'double s0::m01', at offset 128 (in bits)
2 member function insertions:
'method int s0::foo()'
'method int s0::foo(int, char) const', virtual at voffset 2/2
'method int s0::foo()'
's0*' changed:
pointed to type 'class s0' changed, as reported earlier
'class s0' changed:
details were reported earlier
's0&' changed:
referenced type 'class s0' changed, as reported earlier
'const s0*' changed:
in pointed to type 'const s0':
unqualified underlying type class s0 changed, as reported earlier
'function int bar(s0&)' was removed
'function int baz(s0&)' was added