From d4445731bb40412bf02d8f1e4191f8c4e1a8d7bb Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Mon, 13 Oct 2014 16:19:34 +0200 Subject: [PATCH] Gain ability know if a diff node has local changes * include/abg-comparison.h (diff::has_local_changes): Add new pure interface. ({decl_diff_base, type_diff_base, distinct_type_diff, var_diff, pointer_diff, reference_diff, array_diff, qualified_type_diff, enum_diff, class_diff, base_diff, scope_diff, function_decl_diff, type_decl_diff, typedef_diff, translation_unit_diff}::has_local_changes): Declare the implementation of the pure interface above. * src/abg-comparison.cc ({decl_diff_base, type_diff_base, distinct_type_diff, var_diff, pointer_diff, reference_diff, array_diff, qualified_type_diff, enum_diff, class_diff, base_diff, scope_diff, function_decl_diff, type_decl_diff, typedef_diff, translation_unit_diff}::has_local_changes): Define the implementation of the pure interface above. Signed-off-by: Dodji Seketeli --- include/abg-comparison.h | 67 ++++++++++++++++++- src/abg-comparison.cc | 137 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 199 insertions(+), 5 deletions(-) diff --git a/include/abg-comparison.h b/include/abg-comparison.h index 97c6328c..6876ef0c 100644 --- a/include/abg-comparison.h +++ b/include/abg-comparison.h @@ -697,12 +697,23 @@ public: virtual void chain_into_hierarchy(); - /// Pure interface to get the length of the changes - /// encapsulated by this diff. This is to be implemented by all - /// descendants of this class. + /// Pure interface to get the length of the changes encapsulated by + /// this diff. A length of zero means that the current instance of + /// @ref diff doesn't carry any change. + /// + /// This is to be implemented by all descendants of this type. virtual unsigned length() const = 0; + /// Pure interface to know if the current instance of @diff carries + /// a local change. A local change is a change that is on the @ref + /// diff object itself, as opposed to a change that is carried by + /// some of its children nodes. + /// + /// This is to be implemented by all descendants of this type. + virtual bool + has_local_changes() const = 0; + /// Pure interface to report the diff in a serialized form that is /// legible for the user. /// @@ -749,6 +760,10 @@ protected: diff_context_sptr ctxt); public: + + virtual bool + has_local_changes() const = 0; + virtual ~type_diff_base(); };// end class type_diff_base @@ -766,6 +781,10 @@ protected: diff_context_sptr ctxt); public: + + virtual bool + has_local_changes() const = 0; + virtual ~decl_diff_base(); };// end class decl_diff_base @@ -807,6 +826,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream& out, const string& indent = "") const; @@ -865,6 +887,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream& out, const string& indent = "") const; @@ -919,6 +944,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream&, const string& indent = "") const; @@ -976,6 +1004,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream&, const string& indent = "") const; @@ -1033,6 +1064,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream&, const string& indent = "") const; @@ -1088,6 +1122,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream&, const string& indent = "") const; @@ -1158,6 +1195,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream&, const string& indent = "") const; @@ -1279,6 +1319,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream&, const string& indent = "") const; @@ -1335,6 +1378,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream&, const string& indent = "") const; @@ -1441,6 +1487,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream& out, const string& indent = "") const; @@ -1518,6 +1567,9 @@ compute_diff(const function_decl_sptr first, virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream&, const string& indent = "") const; @@ -1566,6 +1618,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream& out, const string& indent = "") const; };// end type_decl_diff @@ -1621,6 +1676,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream&, const string& indent = "") const; @@ -1667,6 +1725,9 @@ public: virtual unsigned length() const; + virtual bool + has_local_changes() const; + virtual void report(ostream& out, const string& indent = "") const; };//end class translation_unit_diff diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc index 71a7ee30..0183a6a9 100644 --- a/src/abg-comparison.cc +++ b/src/abg-comparison.cc @@ -1699,6 +1699,16 @@ distinct_diff::length() const return 1; } +/// @return true iff the current diff node carries local changes. +bool +distinct_diff::has_local_changes() const +{ + // The changes on a distinct_diff are all local. + if (length()) + return true; + return false; +} + /// Emit a report about the current diff instance. /// /// @param out the output stream to send the diff report to. @@ -2689,6 +2699,16 @@ unsigned var_diff::length() const {return *first_var() != *second_var();} +/// @return true iff the current diff node carries local changes. +bool +var_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_var(), *second_var(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} + /// Report the diff in a serialized form. /// /// @param out the stream to serialize the diff to. @@ -2894,6 +2914,16 @@ pointer_diff::length() const : 0; } +/// @return true iff the current diff node carries local changes. +bool +pointer_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_pointer(), *second_pointer(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} + /// Getter for the diff between the pointed-to types of the pointers /// of this diff. /// @@ -3089,6 +3119,16 @@ array_diff::length() const return l; } +/// @return true iff the current diff node carries local changes. +bool +array_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_array(), *second_array(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} + /// Report the diff in a serialized form. /// /// @param out the output stream to serialize the dif to. @@ -3321,6 +3361,16 @@ reference_diff::length() const : 0; } +/// @return true iff the current diff node carries local changes. +bool +reference_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_reference(), *second_reference(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} + /// Report the diff in a serialized form. /// /// @param out the output stream to serialize the dif to. @@ -3496,6 +3546,16 @@ qualified_type_diff::length() const : l); } +/// @return true iff the current diff node carries local changes. +bool +qualified_type_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_qualified_type(), *second_qualified_type(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} + /// Return the first underlying type that is not a qualified type. /// @param t the qualified type to consider. /// @@ -3771,6 +3831,16 @@ enum_diff::length() const return a + b; } +/// @return true iff the current diff node carries local changes. +bool +enum_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_enum(), *second_enum(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} + /// A functor to compare two enumerators based on their value. This /// implements the "less than" operator. struct enumerator_value_comp @@ -4124,7 +4194,7 @@ class_diff::ensure_lookup_tables_populated(void) const priv_->deleted_bases_.find(qname); if (j != priv_->deleted_bases_.end()) { - if (*j->second != *b) + if (j->second != b) priv_->changed_bases_[qname] = std::make_pair(j->second, b); priv_->deleted_bases_.erase(j); @@ -4819,6 +4889,16 @@ unsigned class_diff::length() const {return (*first_class_decl() != *second_class_decl());} +/// @return true iff the current diff node carries local changes. +bool +class_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_class_decl(), *second_class_decl(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} + /// @return the first class invoveld in the diff. shared_ptr class_diff::first_class_decl() const @@ -5722,7 +5802,17 @@ base_diff::get_pretty_representation() const /// @return the length of the diff. unsigned base_diff::length() const -{return *first_base() != *second_base();} +{return first_base() != second_base();} + +/// @return true iff the current diff node carries local changes. +bool +base_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_base(), *second_base(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} /// Generates a report for the current instance of base_diff. /// @@ -6252,6 +6342,16 @@ scope_diff::length() const return changed_types().size() + changed_decls().size(); } +/// @return true iff the current diff node carries local changes. +bool +scope_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_scope(), *second_scope(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} + /// Report the changes of one scope against another. /// /// @param out the out stream to report the changes to. @@ -6718,6 +6818,15 @@ unsigned function_decl_diff::length() const {return *first_function_decl() != *second_function_decl();} +/// @return true iff the current diff node carries local changes. +bool +function_decl_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_function_decl(), *second_function_decl(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} /// A comparison functor to compare two changed function parameters /// based on their indexes. struct changed_parm_comp @@ -7050,6 +7159,15 @@ type_decl_diff::length() const + diff_length_of_type_bases(f, s)); } +/// @return true iff the current diff node carries local changes. +bool +type_decl_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_type_decl(), *second_type_decl(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} /// Ouputs a report of the differences between of the two type_decl /// involved in the type_decl_diff. /// @@ -7241,6 +7359,16 @@ typedef_diff::length() const return !(*first_typedef_decl() == *second); } +/// @return true iff the current diff node carries local changes. +bool +typedef_diff::has_local_changes() const +{ + ir::change_kind k = ir::NO_CHANGE_KIND; + if (!equals(*first_typedef_decl(), *second_typedef_decl(), k)) + return k & LOCAL_CHANGE_KIND; + return false; +} + /// Reports the difference between the two subjects of the diff in a /// serialized form. /// @@ -7364,6 +7492,11 @@ unsigned translation_unit_diff::length() const {return scope_diff::length();} +/// @return true iff the current diff node carries local changes. +bool +translation_unit_diff::has_local_changes() const +{return false;} + /// Report the diff in a serialized form. /// /// @param out the output stream to serialize the report to.