1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 // -*- Mode: C++ -*- 3 // 4 // Copyright (C) 2013-2023 Red Hat, Inc. 5 // 6 // Author: Dodji Seketeli 7 8 #ifndef __ABG_COMPARISON_H__ 9 #define __ABG_COMPARISON_H__ 10 11 /// @file 12 13 #include <memory> 14 #include <ostream> 15 #include <unordered_map> 16 #include <unordered_set> 17 #include "abg-corpus.h" 18 #include "abg-diff-utils.h" 19 #include "abg-reporter.h" 20 #include "abg-suppression.h" 21 22 namespace abigail 23 { 24 25 /// @brief utilities to compare abi artifacts 26 /// 27 /// The main entry points of the namespace are the compute_diff() 28 /// overloads used to compute the difference between two abi artifacts. 29 namespace comparison 30 { 31 32 namespace filtering 33 { 34 struct filter_base; 35 typedef shared_ptr<filter_base> filter_base_sptr; 36 typedef std::vector<filter_base_sptr> filters; 37 } 38 39 // Inject types we need into this namespace. 40 using std::ostream; 41 using std::vector; 42 using std::unordered_map; 43 using std::unordered_set; 44 using std::pair; 45 46 using diff_utils::insertion; 47 using diff_utils::deletion; 48 using diff_utils::edit_script; 49 50 /// Hasher for @ref diff_sptr. 51 struct diff_sptr_hasher 52 { 53 /// The actual hashing functor. 54 size_t operatordiff_sptr_hasher55 operator()(const diff_sptr& t) const 56 {return reinterpret_cast<size_t>(t.get());} 57 }; // end struct diff_sptr_hasher 58 59 /// Convenience typedef for a vector of @ref diff_sptr. 60 typedef vector<diff_sptr> diff_sptrs_type; 61 62 /// Convenience typedef for a vector of @ref diff*. 63 typedef vector<diff*> diff_ptrs_type; 64 65 /// Convenience typedef for an unoredered set of @ref diff_sptr 66 typedef unordered_set<diff_sptr, diff_sptr_hasher> unordered_diff_sptr_set; 67 68 class decl_diff_base; 69 70 /// Convenience typedef for a shared_ptr of @ref decl_diff_base. 71 typedef shared_ptr<decl_diff_base> decl_diff_base_sptr; 72 73 /// Convenience typedef for a vector of @ref decl_diff_base_sptr. 74 typedef vector<decl_diff_base_sptr> decl_diff_base_sptrs_type; 75 76 class type_diff_base; 77 /// Convenience pointer for a shared pointer to a type_diff_base 78 typedef shared_ptr<type_diff_base> type_diff_base_sptr; 79 80 /// Convenience typedef for a vector of @ref type_diff_base_sptr 81 typedef vector<type_diff_base_sptr> type_diff_base_sptrs_type; 82 83 class function_decl_diff; 84 85 /// Convenience typedef for a shared pointer to a @ref function_decl type. 86 typedef shared_ptr<function_decl_diff> function_decl_diff_sptr; 87 88 /// Convenience typedef for a vector of @ref function_decl_diff_sptr 89 typedef vector<function_decl_diff_sptr> function_decl_diff_sptrs_type; 90 91 class fn_parm_diff; 92 93 /// Convenience typedef for a shared pointer to a @ref fn_parm_diff 94 /// type. 95 typedef shared_ptr<fn_parm_diff> fn_parm_diff_sptr; 96 97 class var_diff; 98 99 /// Convenience typedef for a shared pointer to a @ref var_diff type. 100 typedef shared_ptr<var_diff> var_diff_sptr; 101 102 /// Convenience typedef for a vector of @ref var_diff_sptr. 103 typedef vector<var_diff_sptr> var_diff_sptrs_type; 104 105 class base_diff; 106 107 /// Convenience typedef for a shared pointer to a @ref base_diff type. 108 typedef shared_ptr<base_diff> base_diff_sptr; 109 110 /// Convenience typedef for a vector of @ref base_diff_sptr. 111 typedef vector<base_diff_sptr> base_diff_sptrs_type; 112 113 class class_diff; 114 115 /// Convenience typedef for a shared pointer on a @ref class_diff type. 116 typedef shared_ptr<class_diff> class_diff_sptr; 117 118 /// Convenience typedef for a map of pointer values. The Key is a 119 /// pointer value and the value is potentially another pointer value 120 /// associated to the first one. 121 typedef unordered_map<size_t, size_t> pointer_map; 122 123 /// Convenience typedef for a map which key is a string and which 124 /// value is a @ref decl_base_sptr. 125 typedef unordered_map<string, decl_base_sptr> string_decl_base_sptr_map; 126 127 /// Convenience typedef for a map which key is a string and which 128 /// value is a @ref type_base_sptr. 129 typedef unordered_map<string, type_base_sptr> string_type_base_sptr_map; 130 131 /// Convenience typedef for a map which key is an unsigned integer and 132 /// which value is a @ref decl_base_sptr 133 typedef unordered_map<unsigned, decl_base_sptr> unsigned_decl_base_sptr_map; 134 135 /// Convenience typedef for a map of string and class_decl::basse_spec_sptr. 136 typedef unordered_map<string, class_decl::base_spec_sptr> string_base_sptr_map; 137 138 /// Convenience typedef for a map of string and @ref base_diff_sptr. 139 typedef unordered_map<string, base_diff_sptr> string_base_diff_sptr_map; 140 141 /// Convenience typedef for a map which value is a changed function 142 /// parameter and which key is the name of the function parameter. 143 typedef unordered_map<string, fn_parm_diff_sptr> string_fn_parm_diff_sptr_map; 144 145 /// Convenience typedef for a map which key is an integer and which 146 /// value is a changed parameter. 147 typedef unordered_map<unsigned, fn_parm_diff_sptr> 148 unsigned_fn_parm_diff_sptr_map; 149 150 /// Convenience typedef for a map which key is an integer and which 151 /// value is a parameter. 152 typedef unordered_map<unsigned, 153 function_decl::parameter_sptr> unsigned_parm_map; 154 155 /// Convenience typedef for a map which value is a 156 /// type_diff_base_sptr. The key of the map is the qualified name of 157 /// the changed type. 158 typedef unordered_map<string, 159 type_diff_base_sptr> string_type_diff_base_sptr_map; 160 161 /// Convenience typedef for a map which value is a 162 /// decl_diff_base_sptr. The key of the map is the qualified name of 163 /// the changed type. 164 typedef unordered_map<string, 165 decl_diff_base_sptr> string_decl_diff_base_sptr_map; 166 167 /// Convenience typedef for a map which value is a diff_sptr. The key 168 /// of the map is the qualified name of the changed type. 169 typedef unordered_map<string, diff_sptr> string_diff_sptr_map; 170 171 /// Convenience typedef for a map which value is a diff*. The key of 172 /// the map is the qualified name of the changed type. 173 typedef unordered_map<string, diff*> string_diff_ptr_map; 174 175 /// Convenience typedef for a map whose key is a string and whose 176 /// value is a changed variable of type @ref var_diff_sptr. 177 typedef unordered_map<string, 178 var_diff_sptr> string_var_diff_sptr_map; 179 180 181 /// Convenience typedef for a map whose key is an unsigned int and 182 /// whose value is a changed variable of type @ref var_diff_sptr. 183 typedef unordered_map<unsigned, var_diff_sptr> unsigned_var_diff_sptr_map; 184 185 /// Convenience typedef for a map which value is a function 186 /// parameter. The key is the name of the function parm. 187 typedef unordered_map<string, function_decl::parameter_sptr> string_parm_map; 188 189 /// Convenience typedef for a map which value is an enumerator. The 190 /// key is the name of the enumerator. 191 typedef unordered_map<string, enum_type_decl::enumerator> string_enumerator_map; 192 193 /// Convenience typedef for a changed enumerator. The first element 194 /// of the pair is the old enumerator and the second one is the new enumerator. 195 typedef std::pair<enum_type_decl::enumerator, 196 enum_type_decl::enumerator> changed_enumerator; 197 198 /// Convenience typedef for a vector of changed enumerators. 199 typedef vector<changed_enumerator> changed_enumerators_type; 200 201 /// Convenience typedef for a map which value is a changed enumerator. 202 /// The key is the name of the changed enumerator. 203 typedef unordered_map<string, changed_enumerator> string_changed_enumerator_map; 204 205 /// Convenience typedef for a map which key is a string and which 206 /// value is a pointer to @ref decl_base. 207 typedef unordered_map<string, function_decl*> string_function_ptr_map; 208 209 /// Convenience typedef for a map which key is a string and which 210 /// value is a @ref function_decl_diff_sptr. 211 typedef unordered_map<string, 212 function_decl_diff_sptr> 213 string_function_decl_diff_sptr_map; 214 215 /// Convenience typedef for a pair of class_decl::member_function_sptr 216 /// representing a changed member function. The first element of the 217 /// pair is the initial member function and the second element is the 218 /// changed one. 219 typedef pair<method_decl_sptr, 220 method_decl_sptr> changed_member_function_sptr; 221 222 /// Convenience typedef for a hash map of strings and changed member functions. 223 typedef unordered_map<string, 224 changed_member_function_sptr> 225 string_changed_member_function_sptr_map; 226 227 /// Convenience typedef for a hash map of strings and member functions. 228 typedef unordered_map<string, method_decl_sptr> string_member_function_sptr_map; 229 230 /// Convenience typedef for a map which key is a string and which 231 /// value is a point to @ref var_decl. 232 typedef unordered_map<string, var_decl*> string_var_ptr_map; 233 234 /// Convenience typedef for a pair of pointer to @ref var_decl 235 /// representing a @ref var_decl change. The first member of the pair 236 /// represents the initial variable and the second member represents 237 /// the changed variable. 238 typedef std::pair<var_decl*, var_decl*> changed_var_ptr; 239 240 /// Convenience typedef for a pair of @ref var_decl_sptr representing 241 /// a @ref var_decl change. The first member of the pair represents 242 /// the initial variable and the second member represents the changed 243 /// variable. 244 typedef std::pair<var_decl_sptr, var_decl_sptr> changed_var_sptr; 245 246 /// Convenience typedef for a vector of @changed_var_sptr.gg381 247 typedef vector<changed_var_sptr> changed_var_sptrs_type; 248 249 /// Convenience typedef for a map whose key is a string and whose 250 /// value is an @ref elf_symbol_sptr. 251 typedef unordered_map<string, elf_symbol_sptr> string_elf_symbol_map; 252 253 /// Convenience typedef for a map which key is a string and which 254 /// value is a @ref var_diff_sptr. 255 typedef unordered_map<string, var_diff_sptr> string_var_diff_ptr_map; 256 257 class diff_node_visitor; 258 259 class diff_traversable_base; 260 261 /// Convenience typedef for shared_ptr on diff_traversable_base. 262 typedef shared_ptr<diff_traversable_base> diff_traversable_base_sptr; 263 264 /// An enum for the different ways to visit a diff tree node. 265 /// 266 /// This is used by the node traversing code, to know when to avoid 267 /// visiting children nodes, for instance. 268 enum visiting_kind 269 { 270 /// The default enumerator value of this enum. It doesn't have any 271 /// particular meaning yet. 272 DEFAULT_VISITING_KIND = 0, 273 274 /// This says that the traversing code should avoid visiting the 275 /// children nodes of the current node being visited. 276 SKIP_CHILDREN_VISITING_KIND = 1, 277 278 /// This says that the traversing code should not mark visited nodes 279 /// as having been traversed. This is useful, for instance, for 280 /// visitors which have debugging purposes. 281 DO_NOT_MARK_VISITED_NODES_AS_VISITED = 1 << 1 282 }; 283 284 visiting_kind 285 operator|(visiting_kind l, visiting_kind r); 286 287 visiting_kind 288 operator&(visiting_kind l, visiting_kind r); 289 290 visiting_kind 291 operator~(visiting_kind l); 292 293 /// The base class for the diff classes that are to be traversed. 294 class diff_traversable_base : public traversable_base 295 { 296 public: 297 virtual bool 298 traverse(diff_node_visitor& v); 299 }; // end struct diff_traversable_base 300 301 /// An enum for the different categories that a diff tree node falls 302 /// into, regarding the kind of changes it represents. 303 /// 304 /// Note that if you add an enumerator to this enum, you need to 305 /// update a few spots accordingly: 306 /// 307 /// * update the ACCESS_CHANGE_CATEGORY enumerator (which is the 308 /// last enumerator of this enum by OR-ing its initializer with 309 /// the new enumerator. 310 /// 311 /// * update the categorize_harmless_diff_node or 312 /// categorize_harmful_diff_node function depending on if the new 313 /// enumerator classifies diff nodes as harmless or harmful. 314 /// 315 /// * update the get_default_harmless_categories_bitmap or 316 /// get_default_harmful_categories_bitmap function as well, just 317 /// like above. 318 /// 319 /// * update the "operator<<(ostream& o, diff_category c)" streaming 320 /// operator so that it can stream the new enumerator to a textual 321 /// output stream. 322 enum diff_category 323 { 324 /// This means the diff node does not carry any (meaningful) change, 325 /// or that it carries changes that have not yet been categorized. 326 NO_CHANGE_CATEGORY = 0, 327 328 /// This means the diff node (or at least one of its descendant 329 /// nodes) carries access related changes, e.g, a private member 330 /// that becomes public. 331 ACCESS_CHANGE_CATEGORY = 1, 332 333 /// This means the diff node (or at least one of its descendant 334 /// nodes) carries a change involving two compatible types. For 335 /// instance a type and its typedefs. 336 COMPATIBLE_TYPE_CHANGE_CATEGORY = 1 << 1, 337 338 /// This means that a diff node in the sub-tree carries a harmless 339 /// declaration name change. This is set only for name changes for 340 /// data members and typedefs. 341 HARMLESS_DECL_NAME_CHANGE_CATEGORY = 1 << 2, 342 343 /// This means that a diff node in the sub-tree carries an addition 344 /// or removal of a non-virtual member function. 345 NON_VIRT_MEM_FUN_CHANGE_CATEGORY = 1 << 3, 346 347 /// This means that a diff node in the sub-tree carries an addition 348 /// or removal of a static data member. 349 STATIC_DATA_MEMBER_CHANGE_CATEGORY = 1 << 4, 350 351 /// This means that a diff node in the sub-tree carries an addition 352 /// of enumerator to an enum type. 353 HARMLESS_ENUM_CHANGE_CATEGORY = 1 << 5, 354 355 /// This means that a diff node in the sub-tree carries an a symbol 356 /// alias change that is harmless. 357 HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY = 1 << 6, 358 359 /// This means that a diff node in the sub-tree carries a harmless 360 /// union change. 361 HARMLESS_UNION_CHANGE_CATEGORY = 1 << 7, 362 363 /// This means that a diff node in the sub-tree carries a harmless 364 /// data member change. An example of harmless data member change 365 /// is an anonymous data member that replaces a given data member 366 /// without locally changing the layout. 367 HARMLESS_DATA_MEMBER_CHANGE_CATEGORY = 1 << 8, 368 369 /// This means that a diff node was marked as suppressed by a 370 /// user-provided suppression specification. 371 SUPPRESSED_CATEGORY = 1 << 9, 372 373 /// This means that a diff node was warked as being for a private 374 /// type. That is, the diff node is meant to be suppressed by a 375 /// suppression specification that was auto-generated to filter out 376 /// changes to private types. 377 PRIVATE_TYPE_CATEGORY = 1 << 10, 378 379 /// This means the diff node (or at least one of its descendant 380 /// nodes) carries a change that modifies the size of a type or an 381 /// offset of a type member. Removal or changes of enumerators in a 382 /// enum fall in this category too. 383 SIZE_OR_OFFSET_CHANGE_CATEGORY = 1 << 11, 384 385 /// This means that a diff node in the sub-tree carries an 386 /// incompatible change to a vtable. 387 VIRTUAL_MEMBER_CHANGE_CATEGORY = 1 << 12, 388 389 /// A diff node in this category is redundant. That means it's 390 /// present as a child of a other nodes in the diff tree. 391 REDUNDANT_CATEGORY = 1 << 13, 392 393 /// This means that a diff node in the sub-tree carries a type that 394 /// was declaration-only and that is now defined, or vice versa. 395 TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY = 1 << 14, 396 397 /// A diff node in this category is a function parameter type which 398 /// top cv-qualifiers change. 399 FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY = 1 << 15, 400 401 /// A diff node in this category has a function parameter type with a 402 /// cv-qualifiers change. 403 FN_PARM_TYPE_CV_CHANGE_CATEGORY = 1 << 16, 404 405 /// A diff node in this category is a function return type with a 406 /// cv-qualifier change. 407 FN_RETURN_TYPE_CV_CHANGE_CATEGORY = 1 << 17, 408 409 /// A diff node in this category is a function (or function type) 410 /// with at least one parameter added or removed. 411 FN_PARM_ADD_REMOVE_CHANGE_CATEGORY = 1 << 18, 412 413 /// A diff node in this category is for a variable which type holds 414 /// a cv-qualifier change. 415 VAR_TYPE_CV_CHANGE_CATEGORY = 1 << 19, 416 417 /// A diff node in this category carries a change from void pointer 418 /// to non-void pointer. 419 VOID_PTR_TO_PTR_CHANGE_CATEGORY = 1 << 20, 420 421 /// A diff node in this category carries a change in the size of the 422 /// array type of a global variable, but the ELF size of the 423 /// variable didn't change. 424 BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY = 1 << 21, 425 426 /// A diff node in this category carries a change that must be 427 /// reported, even if the diff node is also in the 428 /// SUPPRESSED_CATEGORY or PRIVATE_TYPE_CATEGORY categories. 429 /// Typically, this node matches a suppression specification like 430 /// the [allow_type] directive. 431 HAS_ALLOWED_CHANGE_CATEGORY = 1 << 22, 432 433 /// A diff node in this category has a descendant node that is in 434 /// the HAS_ALLOWED_CHANGE_CATEGORY category. Nodes in this 435 /// category must be reported, even if they are also in the 436 /// SUPPRESSED_CATEGORY or PRIVATE_TYPE_CATEGORY categories. 437 HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY = 1 << 23, 438 439 /// A diff node in this category has a parent node that is in the 440 /// HAS_ALLOWED_CHANGE_CATEGORY category. Nodes in this category 441 /// must be reported, even if they are also in the 442 /// SUPPRESSED_CATEGORY or PRIVATE_TYPE_CATEGORY categories. 443 HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY = 1 << 24, 444 445 /// A special enumerator that is the logical 'or' all the 446 /// enumerators above. 447 /// 448 /// This one must stay the last enumerator. Please update it each 449 /// time you add a new enumerator above. 450 EVERYTHING_CATEGORY = 451 ACCESS_CHANGE_CATEGORY 452 | COMPATIBLE_TYPE_CHANGE_CATEGORY 453 | HARMLESS_DECL_NAME_CHANGE_CATEGORY 454 | NON_VIRT_MEM_FUN_CHANGE_CATEGORY 455 | STATIC_DATA_MEMBER_CHANGE_CATEGORY 456 | HARMLESS_ENUM_CHANGE_CATEGORY 457 | HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY 458 | HARMLESS_UNION_CHANGE_CATEGORY 459 | HARMLESS_DATA_MEMBER_CHANGE_CATEGORY 460 | SUPPRESSED_CATEGORY 461 | PRIVATE_TYPE_CATEGORY 462 | SIZE_OR_OFFSET_CHANGE_CATEGORY 463 | VIRTUAL_MEMBER_CHANGE_CATEGORY 464 | REDUNDANT_CATEGORY 465 | TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY 466 | FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY 467 | FN_PARM_TYPE_CV_CHANGE_CATEGORY 468 | FN_RETURN_TYPE_CV_CHANGE_CATEGORY 469 | FN_PARM_ADD_REMOVE_CHANGE_CATEGORY 470 | VAR_TYPE_CV_CHANGE_CATEGORY 471 | VOID_PTR_TO_PTR_CHANGE_CATEGORY 472 | BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY 473 | HAS_ALLOWED_CHANGE_CATEGORY 474 | HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY 475 | HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY 476 }; // enum diff_category 477 478 diff_category 479 operator|(diff_category c1, diff_category c2); 480 481 diff_category& 482 operator|=(diff_category& c1, diff_category c2); 483 484 diff_category& 485 operator&=(diff_category& c1, diff_category c2); 486 487 diff_category 488 operator^(diff_category c1, diff_category c2); 489 490 diff_category 491 operator&(diff_category c1, diff_category c2); 492 493 diff_category 494 operator~(diff_category c); 495 496 diff_category 497 get_default_harmless_categories_bitmap(); 498 499 diff_category 500 get_default_harmful_categories_bitmap(); 501 502 ostream& 503 operator<<(ostream& o, diff_category); 504 505 class corpus_diff; 506 507 /// This type contains maps. Each map associates a type name to a 508 /// diff of that type. Not all kinds of diffs are present; only those 509 /// that carry leaf changes are, for now. 510 class diff_maps 511 { 512 struct priv; 513 std::unique_ptr<priv> priv_; 514 515 public: 516 517 diff_maps(); 518 519 ~diff_maps(); 520 521 const string_diff_ptr_map& 522 get_type_decl_diff_map() const; 523 524 string_diff_ptr_map& 525 get_type_decl_diff_map(); 526 527 const string_diff_ptr_map& 528 get_enum_diff_map() const; 529 530 string_diff_ptr_map& 531 get_enum_diff_map(); 532 533 const string_diff_ptr_map& 534 get_class_diff_map() const; 535 536 string_diff_ptr_map& 537 get_class_diff_map(); 538 539 const string_diff_ptr_map& 540 get_union_diff_map() const; 541 542 string_diff_ptr_map& 543 get_union_diff_map(); 544 545 const string_diff_ptr_map& 546 get_typedef_diff_map() const; 547 548 string_diff_ptr_map& 549 get_typedef_diff_map(); 550 551 const string_diff_ptr_map& 552 get_subrange_diff_map() const; 553 554 string_diff_ptr_map& 555 get_subrange_diff_map(); 556 557 const string_diff_ptr_map& 558 get_array_diff_map() const; 559 560 string_diff_ptr_map& 561 get_array_diff_map(); 562 563 const string_diff_ptr_map& 564 get_reference_diff_map() const; 565 566 string_diff_ptr_map& 567 get_reference_diff_map(); 568 569 const string_diff_ptr_map& 570 get_fn_parm_diff_map() const; 571 572 string_diff_ptr_map& 573 get_fn_parm_diff_map(); 574 575 const string_diff_ptr_map& 576 get_function_type_diff_map() const; 577 578 string_diff_ptr_map& 579 get_function_type_diff_map(); 580 581 const string_diff_ptr_map& 582 get_function_decl_diff_map() const; 583 584 string_diff_ptr_map& 585 get_function_decl_diff_map(); 586 587 const string_diff_ptr_map& 588 get_var_decl_diff_map() const; 589 590 string_diff_ptr_map& 591 get_var_decl_diff_map(); 592 593 const string_diff_ptr_map& 594 get_distinct_diff_map() const; 595 596 string_diff_ptr_map& 597 get_distinct_diff_map(); 598 599 bool 600 insert_diff_node(const diff *d, 601 const type_or_decl_base_sptr& impacted_iface); 602 603 artifact_sptr_set_type* 604 lookup_impacted_interfaces(const diff *d) const; 605 }; // end class diff_maps 606 607 /// A convenience typedef for a shared pointer to @ref corpus_diff. 608 typedef shared_ptr<corpus_diff> corpus_diff_sptr; 609 610 /// The context of the diff. This type holds various bits of 611 /// information that is going to be used throughout the diffing of two 612 /// entities and the reporting that follows. 613 class diff_context 614 { 615 struct priv; 616 std::unique_ptr<priv> priv_; 617 618 diff_sptr 619 has_diff_for(const type_or_decl_base_sptr first, 620 const type_or_decl_base_sptr second) const; 621 622 diff_sptr 623 has_diff_for_types(const type_base_sptr first, 624 const type_base_sptr second) const; 625 626 const diff* 627 has_diff_for(const diff* d) const; 628 629 diff_sptr 630 has_diff_for(const diff_sptr d) const; 631 632 void 633 add_diff(const type_or_decl_base_sptr first, 634 const type_or_decl_base_sptr second, 635 const diff_sptr d); 636 637 void 638 add_diff(const diff_sptr d); 639 640 void 641 add_diff(const diff* d); 642 643 void 644 set_canonical_diff_for(const type_or_decl_base_sptr first, 645 const type_or_decl_base_sptr second, 646 const diff_sptr); 647 648 diff_sptr 649 set_or_get_canonical_diff_for(const type_or_decl_base_sptr first, 650 const type_or_decl_base_sptr second, 651 const diff_sptr canonical_diff); 652 653 public: 654 diff_context(); 655 656 ~diff_context(); 657 658 bool 659 do_log() const; 660 661 void 662 do_log(bool); 663 664 void 665 set_corpus_diff(const corpus_diff_sptr&); 666 667 const corpus_diff_sptr& 668 get_corpus_diff() const; 669 670 corpus_sptr 671 get_first_corpus() const; 672 673 corpus_sptr 674 get_second_corpus() const; 675 676 reporter_base_sptr 677 get_reporter() const; 678 679 void 680 set_reporter(reporter_base_sptr&); 681 682 diff_sptr 683 get_canonical_diff_for(const type_or_decl_base_sptr first, 684 const type_or_decl_base_sptr second) const; 685 686 diff_sptr 687 get_canonical_diff_for(const diff_sptr d) const; 688 689 void 690 initialize_canonical_diff(const diff_sptr diff); 691 692 void 693 keep_diff_alive(diff_sptr&); 694 695 diff* 696 diff_has_been_visited(const diff*) const; 697 698 diff_sptr 699 diff_has_been_visited(const diff_sptr) const; 700 701 void 702 mark_diff_as_visited(const diff*); 703 704 void 705 forget_visited_diffs(); 706 707 void 708 mark_last_diff_visited_per_class_of_equivalence(const diff*); 709 710 void 711 clear_last_diffs_visited_per_class_of_equivalence(); 712 713 const diff* 714 get_last_visited_diff_of_class_of_equivalence(const diff*); 715 716 void 717 forbid_visiting_a_node_twice(bool f); 718 719 bool 720 visiting_a_node_twice_is_forbidden() const; 721 722 void 723 forbid_visiting_a_node_twice_per_interface(bool); 724 725 bool 726 visiting_a_node_twice_is_forbidden_per_interface() const; 727 728 diff_category 729 get_allowed_category() const; 730 731 void 732 set_allowed_category(diff_category c); 733 734 void 735 switch_categories_on(diff_category c); 736 737 void 738 switch_categories_off(diff_category c); 739 740 const filtering::filters& 741 diff_filters() const; 742 743 void 744 add_diff_filter(filtering::filter_base_sptr); 745 746 void 747 maybe_apply_filters(diff_sptr diff); 748 749 void 750 maybe_apply_filters(corpus_diff_sptr diff); 751 752 const suppr::suppressions_type& 753 suppressions() const; 754 755 suppr::suppressions_type& 756 suppressions(); 757 758 const suppr::suppressions_type& 759 negated_suppressions() const; 760 761 const suppr::suppressions_type& 762 direct_suppressions() const; 763 764 void 765 add_suppression(const suppr::suppression_sptr suppr); 766 767 void 768 add_suppressions(const suppr::suppressions_type& supprs); 769 770 bool 771 perform_change_categorization() const; 772 773 void 774 perform_change_categorization(bool); 775 776 void 777 show_leaf_changes_only(bool f); 778 779 bool 780 show_leaf_changes_only() const; 781 782 bool 783 show_hex_values() const; 784 785 void 786 show_hex_values(bool f); 787 788 bool 789 show_offsets_sizes_in_bits() const; 790 791 void 792 show_offsets_sizes_in_bits(bool f); 793 794 void 795 show_relative_offset_changes(bool f); 796 797 bool 798 show_relative_offset_changes(void); 799 800 void 801 show_stats_only(bool f); 802 803 bool 804 show_stats_only() const; 805 806 void 807 show_soname_change(bool f); 808 809 bool 810 show_soname_change() const; 811 812 void 813 show_architecture_change(bool f); 814 815 bool 816 show_architecture_change() const; 817 818 void 819 show_deleted_fns(bool f); 820 821 bool 822 show_deleted_fns() const; 823 824 void 825 show_changed_fns(bool f); 826 827 bool 828 show_changed_fns() const; 829 830 void 831 show_added_fns(bool f); 832 833 bool 834 show_added_fns() const; 835 836 void 837 show_deleted_vars(bool f); 838 839 bool 840 show_deleted_vars() const; 841 842 void 843 show_changed_vars(bool f); 844 845 bool 846 show_changed_vars() const; 847 848 void 849 show_added_vars(bool f); 850 851 bool 852 show_added_vars() const; 853 854 bool 855 show_linkage_names() const; 856 857 void 858 show_linkage_names(bool f); 859 860 bool 861 show_locs() const; 862 863 void 864 show_locs(bool f); 865 866 bool 867 show_redundant_changes() const; 868 869 void 870 show_redundant_changes(bool f); 871 872 bool 873 show_symbols_unreferenced_by_debug_info() const; 874 875 void 876 show_symbols_unreferenced_by_debug_info(bool f); 877 878 bool 879 show_added_symbols_unreferenced_by_debug_info() const; 880 881 void 882 show_added_symbols_unreferenced_by_debug_info(bool f); 883 884 void show_unreachable_types(bool f); 885 886 bool show_unreachable_types(); 887 888 bool 889 show_impacted_interfaces() const; 890 891 void 892 show_impacted_interfaces(bool f); 893 894 void 895 default_output_stream(ostream*); 896 897 ostream* 898 default_output_stream(); 899 900 void 901 error_output_stream(ostream*); 902 903 ostream* 904 error_output_stream() const; 905 906 bool 907 dump_diff_tree() const; 908 909 void 910 dump_diff_tree(bool f); 911 912 void 913 do_dump_diff_tree(const diff_sptr) const; 914 915 void 916 do_dump_diff_tree(const corpus_diff_sptr) const; 917 918 friend class_diff_sptr 919 compute_diff(const class_decl_sptr first, 920 const class_decl_sptr second, 921 diff_context_sptr ctxt); 922 };//end struct diff_context. 923 924 /// The abstraction of a change between two ABI artifacts, a.k.a an 925 /// artifact change. 926 /// 927 /// In the grand scheme of things, a diff is strongly typed; for 928 /// instance, a change between two enums is represented by an 929 /// enum_diff type. A change between two function_type is represented 930 /// by a function_type_diff type and a change between two class_decl 931 /// is represented by a class_diff type. All of these types derive 932 /// from the @ref diff parent class. 933 /// 934 /// An artifact change D can have one (or more) details named D'. A 935 /// detail is an artifact change that "belongs" to another one. Here, 936 /// D' belongs to D. Or said otherwise, D' is a child change of D. 937 /// Said otherwise, D and D' are related, and the relation is a 938 /// "child relation". 939 /// 940 /// For instance, if we consider a change carried by a class_diff, the 941 /// detail change might be a change on one data member of the class. 942 /// In other word, the class_diff change might have a child diff node 943 /// that would be a var_diff node. 944 /// 945 /// There are two ways to get the child var_diff node (for the data 946 /// member change detail) of the class_diff. 947 /// 948 /// The first way is through the typed API, that is, through the 949 /// class_diff::sorted_changed_data_members() member function which 950 /// returns var_diff nodes. 951 /// 952 /// The second way is through the generic API, that is, through the 953 /// diff::children_nodes() member function which returns generic diff 954 /// nodes. This second way enables us to walk the diff nodes graph in 955 /// a generic way, regardless of the types of the diff nodes. 956 /// 957 /// Said otherwise, there are two views for a given diff node. There 958 /// is typed view, and there is the generic view. In the typed view, 959 /// the details are accessed through the typed API. In the generic 960 /// view, the details are gathered through the generic view. 961 /// 962 /// 963 /// Please read more about the @ref DiffNode "IR" of the comparison 964 /// engine to learn more about this. 965 /// 966 /// This type encapsulates an edit script (a set of insertions and 967 /// deletions) for two constructs that are to be diff'ed. The two 968 /// constructs are called the "subjects" of the diff. 969 class diff : public diff_traversable_base 970 { 971 friend class diff_context; 972 973 // Forbidden 974 diff(); 975 976 protected: 977 struct priv; 978 std::unique_ptr<priv> priv_; 979 980 diff(type_or_decl_base_sptr first_subject, 981 type_or_decl_base_sptr second_subject); 982 983 diff(type_or_decl_base_sptr first_subject, 984 type_or_decl_base_sptr second_subject, 985 diff_context_sptr ctxt); 986 987 bool 988 do_log() const; 989 990 void 991 do_log(bool); 992 993 void 994 begin_traversing(); 995 996 void 997 end_traversing(); 998 999 virtual void 1000 finish_diff_type(); 1001 1002 void 1003 set_canonical_diff(diff *); 1004 1005 public: 1006 type_or_decl_base_sptr 1007 first_subject() const; 1008 1009 type_or_decl_base_sptr 1010 second_subject() const; 1011 1012 const vector<diff*>& 1013 children_nodes() const; 1014 1015 const diff* 1016 parent_node() const; 1017 1018 diff* get_canonical_diff() const; 1019 1020 bool 1021 is_traversing() const; 1022 1023 void 1024 append_child_node(diff_sptr); 1025 1026 const diff_context_sptr 1027 context() const; 1028 1029 void 1030 context(diff_context_sptr c); 1031 1032 bool 1033 currently_reporting() const; 1034 1035 void 1036 currently_reporting(bool f) const; 1037 1038 bool 1039 reported_once() const; 1040 1041 void 1042 reported_once(bool f) const; 1043 1044 diff_category 1045 get_category() const; 1046 1047 diff_category 1048 get_local_category() const; 1049 1050 diff_category 1051 get_class_of_equiv_category() const; 1052 1053 diff_category 1054 add_to_category(diff_category c); 1055 1056 diff_category 1057 add_to_local_category(diff_category c); 1058 1059 void 1060 add_to_local_and_inherited_categories(diff_category c); 1061 1062 diff_category 1063 remove_from_category(diff_category c); 1064 1065 diff_category 1066 remove_from_local_category(diff_category c); 1067 1068 void 1069 set_category(diff_category c); 1070 1071 void 1072 set_local_category(diff_category c); 1073 1074 bool 1075 is_filtered_out() const; 1076 1077 bool 1078 is_filtered_out_wrt_non_inherited_categories() const; 1079 1080 bool 1081 is_filtered_out_without_looking_at_allowed_changes() const; 1082 1083 bool 1084 is_suppressed() const; 1085 1086 bool 1087 is_suppressed(bool &is_private_type) const; 1088 1089 bool 1090 to_be_reported() const; 1091 1092 bool 1093 has_local_changes_to_be_reported() const; 1094 1095 bool 1096 is_allowed_by_specific_negated_suppression() const; 1097 1098 bool 1099 has_descendant_allowed_by_specific_negated_suppression() const; 1100 1101 bool 1102 has_parent_allowed_by_specific_negated_suppression() const; 1103 1104 virtual const string& 1105 get_pretty_representation() const; 1106 1107 /// This constructs the relation between this diff node and its 1108 /// detail diff nodes, in the generic view of the diff node. 1109 /// 1110 /// Each specific typed diff node should implement how the typed 1111 /// view "links" itself to its detail nodes in the generic sense. 1112 virtual void 1113 chain_into_hierarchy(); 1114 1115 /// Pure interface to get the length of the changes encapsulated by 1116 /// this diff. A length of zero means that the current instance of 1117 /// @ref diff doesn't carry any change. 1118 /// 1119 /// This is to be implemented by all descendants of this type. 1120 virtual bool 1121 has_changes() const = 0; 1122 1123 /// Pure interface to know if the current instance of @diff carries 1124 /// a local change. A local change is a change that is on the @ref 1125 /// diff object itself, as opposed to a change that is carried by 1126 /// some of its children nodes. 1127 /// 1128 /// This is to be implemented by all descendants of this type. 1129 virtual enum change_kind 1130 has_local_changes() const = 0; 1131 1132 /// Pure interface to report the diff in a serialized form that is 1133 /// legible for the user. 1134 /// 1135 /// Note that the serializd report has to leave one empty line at 1136 /// the end of its content. 1137 /// 1138 /// @param out the output stream to serialize the report to. 1139 /// 1140 /// @param indent the indentation string to use. 1141 virtual void 1142 report(ostream& out, const string& indent = "") const = 0; 1143 1144 virtual bool 1145 traverse(diff_node_visitor& v); 1146 };// end class diff 1147 1148 diff_sptr 1149 compute_diff(const decl_base_sptr, 1150 const decl_base_sptr, 1151 diff_context_sptr ctxt); 1152 1153 diff_sptr 1154 compute_diff(const type_base_sptr, 1155 const type_base_sptr, 1156 diff_context_sptr ctxt); 1157 1158 /// The base class of diff between types. 1159 class type_diff_base : public diff 1160 { 1161 struct priv; 1162 std::unique_ptr<priv> priv_; 1163 1164 type_diff_base(); 1165 1166 protected: 1167 type_diff_base(type_base_sptr first_subject, 1168 type_base_sptr second_subject, 1169 diff_context_sptr ctxt); 1170 1171 public: 1172 1173 virtual enum change_kind 1174 has_local_changes() const = 0; 1175 1176 virtual ~type_diff_base(); 1177 };// end class type_diff_base 1178 1179 /// The base class of diff between decls. 1180 class decl_diff_base : public diff 1181 { 1182 struct priv; 1183 std::unique_ptr<priv> priv_; 1184 1185 protected: 1186 decl_diff_base(decl_base_sptr first_subject, 1187 decl_base_sptr second_subject, 1188 diff_context_sptr ctxt); 1189 1190 public: 1191 1192 virtual enum change_kind 1193 has_local_changes() const = 0; 1194 1195 virtual ~decl_diff_base(); 1196 };// end class decl_diff_base 1197 1198 string 1199 get_pretty_representation(diff*); 1200 1201 class distinct_diff; 1202 1203 /// Convenience typedef for a shared pointer to distinct_types_diff 1204 typedef shared_ptr<distinct_diff> distinct_diff_sptr; 1205 1206 /// An abstraction of a diff between entities that are of a different 1207 /// kind (disctinct). 1208 class distinct_diff : public diff 1209 { 1210 struct priv; 1211 std::unique_ptr<priv> priv_; 1212 1213 protected: 1214 distinct_diff(type_or_decl_base_sptr first, 1215 type_or_decl_base_sptr second, 1216 diff_context_sptr ctxt = diff_context_sptr()); 1217 1218 public: 1219 1220 const type_or_decl_base_sptr 1221 first() const; 1222 1223 const type_or_decl_base_sptr 1224 second() const; 1225 1226 const diff_sptr 1227 compatible_child_diff() const; 1228 1229 virtual const string& 1230 get_pretty_representation() const; 1231 1232 virtual bool 1233 has_changes() const; 1234 1235 virtual enum change_kind 1236 has_local_changes() const; 1237 1238 virtual void 1239 report(ostream& out, const string& indent = "") const; 1240 1241 virtual void 1242 chain_into_hierarchy(); 1243 1244 static bool 1245 entities_are_of_distinct_kinds(type_or_decl_base_sptr first, 1246 type_or_decl_base_sptr second); 1247 1248 friend distinct_diff_sptr 1249 compute_diff_for_distinct_kinds(const type_or_decl_base_sptr first, 1250 const type_or_decl_base_sptr second, 1251 diff_context_sptr ctxt); 1252 };// end class distinct_types_diff 1253 1254 distinct_diff_sptr 1255 compute_diff_for_distinct_kinds(const type_or_decl_base_sptr, 1256 const type_or_decl_base_sptr, 1257 diff_context_sptr ctxt); 1258 1259 /// Abstracts a diff between two instances of @ref var_decl 1260 class var_diff : public decl_diff_base 1261 { 1262 struct priv; 1263 std::unique_ptr<priv> priv_; 1264 1265 protected: 1266 var_diff(var_decl_sptr first, 1267 var_decl_sptr second, 1268 diff_sptr type_diff, 1269 diff_context_sptr ctxt = diff_context_sptr()); 1270 1271 public: 1272 var_decl_sptr 1273 first_var() const; 1274 1275 var_decl_sptr 1276 second_var() const; 1277 1278 diff_sptr 1279 type_diff() const; 1280 1281 virtual void 1282 chain_into_hierarchy(); 1283 1284 virtual bool 1285 has_changes() const; 1286 1287 virtual enum change_kind 1288 has_local_changes() const; 1289 1290 virtual void 1291 report(ostream& out, const string& indent = "") const; 1292 1293 virtual const string& 1294 get_pretty_representation() const; 1295 1296 friend var_diff_sptr 1297 compute_diff(const var_decl_sptr first, 1298 const var_decl_sptr second, 1299 diff_context_sptr ctxt); 1300 };// end class var_diff 1301 1302 var_diff_sptr 1303 compute_diff(const var_decl_sptr, const var_decl_sptr, diff_context_sptr); 1304 1305 class pointer_diff; 1306 /// Convenience typedef for a shared pointer on a @ref 1307 /// pointer_diff type. 1308 typedef shared_ptr<pointer_diff> pointer_diff_sptr; 1309 1310 /// The abstraction of a diff between two pointers. 1311 class pointer_diff : public type_diff_base 1312 { 1313 struct priv; 1314 std::unique_ptr<priv> priv_; 1315 1316 protected: 1317 pointer_diff(pointer_type_def_sptr first, 1318 pointer_type_def_sptr second, 1319 diff_sptr underlying_type_diff, 1320 diff_context_sptr ctxt = diff_context_sptr()); 1321 1322 public: 1323 const pointer_type_def_sptr 1324 first_pointer() const; 1325 1326 const pointer_type_def_sptr 1327 second_pointer() const; 1328 1329 diff_sptr 1330 underlying_type_diff() const; 1331 1332 void 1333 underlying_type_diff(const diff_sptr); 1334 1335 virtual const string& 1336 get_pretty_representation() const; 1337 1338 virtual bool 1339 has_changes() const; 1340 1341 virtual enum change_kind 1342 has_local_changes() const; 1343 1344 virtual void 1345 report(ostream&, const string& indent = "") const; 1346 1347 virtual void 1348 chain_into_hierarchy(); 1349 1350 friend pointer_diff_sptr 1351 compute_diff(pointer_type_def_sptr first, 1352 pointer_type_def_sptr second, 1353 diff_context_sptr ctxt); 1354 };// end class pointer_diff 1355 1356 pointer_diff_sptr 1357 compute_diff(pointer_type_def_sptr first, 1358 pointer_type_def_sptr second, 1359 diff_context_sptr ctxt); 1360 1361 class reference_diff; 1362 1363 /// Convenience typedef for a shared pointer on a @ref 1364 /// reference_diff type. 1365 typedef shared_ptr<reference_diff> reference_diff_sptr; 1366 1367 /// The abstraction of a diff between two references. 1368 class reference_diff : public type_diff_base 1369 { 1370 struct priv; 1371 std::unique_ptr<priv> priv_; 1372 1373 protected: 1374 reference_diff(const reference_type_def_sptr first, 1375 const reference_type_def_sptr second, 1376 diff_sptr underlying, 1377 diff_context_sptr ctxt = diff_context_sptr()); 1378 1379 public: 1380 reference_type_def_sptr 1381 first_reference() const; 1382 1383 reference_type_def_sptr 1384 second_reference() const; 1385 1386 const diff_sptr& 1387 underlying_type_diff() const; 1388 1389 diff_sptr& 1390 underlying_type_diff(diff_sptr); 1391 1392 virtual const string& 1393 get_pretty_representation() const; 1394 1395 virtual bool 1396 has_changes() const; 1397 1398 virtual enum change_kind 1399 has_local_changes() const; 1400 1401 virtual void 1402 report(ostream&, const string& indent = "") const; 1403 1404 virtual void 1405 chain_into_hierarchy(); 1406 1407 friend reference_diff_sptr 1408 compute_diff(reference_type_def_sptr first, 1409 reference_type_def_sptr second, 1410 diff_context_sptr ctxt); 1411 };// end class reference_diff 1412 1413 reference_diff_sptr 1414 compute_diff(reference_type_def_sptr first, 1415 reference_type_def_sptr second, 1416 diff_context_sptr ctxt); 1417 1418 1419 class subrange_diff; 1420 1421 /// A convenience typedef for a shared pointer to subrange_diff type. 1422 typedef shared_ptr<subrange_diff> subrange_diff_sptr; 1423 1424 /// The abstraction of the diff between two subrange types. 1425 class subrange_diff : public type_diff_base 1426 { 1427 struct priv; 1428 std::unique_ptr<priv> priv_; 1429 1430 protected: 1431 subrange_diff(const array_type_def::subrange_sptr& first, 1432 const array_type_def::subrange_sptr& second, 1433 const diff_sptr& underlying_type_diff, 1434 const diff_context_sptr ctxt = diff_context_sptr()); 1435 1436 public: 1437 const array_type_def::subrange_sptr 1438 first_subrange() const; 1439 1440 const array_type_def::subrange_sptr 1441 second_subrange() const; 1442 1443 const diff_sptr 1444 underlying_type_diff() const; 1445 1446 virtual const string& 1447 get_pretty_representation() const; 1448 1449 virtual bool 1450 has_changes() const; 1451 1452 virtual enum change_kind 1453 has_local_changes() const; 1454 1455 virtual void 1456 report(ostream&, const string& indent = "") const; 1457 1458 virtual void 1459 chain_into_hierarchy(); 1460 1461 friend subrange_diff_sptr 1462 compute_diff(array_type_def::subrange_sptr first, 1463 array_type_def::subrange_sptr second, 1464 diff_context_sptr ctxt); 1465 }; // end subrange_diff 1466 1467 subrange_diff_sptr 1468 compute_diff(array_type_def::subrange_sptr first, 1469 array_type_def::subrange_sptr second, 1470 diff_context_sptr ctxt); 1471 1472 1473 class array_diff; 1474 1475 /// Convenience typedef for a shared pointer on a @ref 1476 /// array_diff type. 1477 typedef shared_ptr<array_diff> array_diff_sptr; 1478 1479 /// The abstraction of a diff between two arrays. 1480 class array_diff : public type_diff_base 1481 { 1482 struct priv; 1483 std::unique_ptr<priv> priv_; 1484 1485 protected: 1486 array_diff(const array_type_def_sptr first, 1487 const array_type_def_sptr second, 1488 diff_sptr element_type_diff, 1489 diff_context_sptr ctxt = diff_context_sptr()); 1490 1491 public: 1492 const array_type_def_sptr 1493 first_array() const; 1494 1495 const array_type_def_sptr 1496 second_array() const; 1497 1498 const diff_sptr& 1499 element_type_diff() const; 1500 1501 void 1502 element_type_diff(diff_sptr); 1503 1504 virtual const string& 1505 get_pretty_representation() const; 1506 1507 virtual bool 1508 has_changes() const; 1509 1510 virtual enum change_kind 1511 has_local_changes() const; 1512 1513 virtual void 1514 report(ostream&, const string& indent = "") const; 1515 1516 virtual void 1517 chain_into_hierarchy(); 1518 1519 friend array_diff_sptr 1520 compute_diff(array_type_def_sptr first, 1521 array_type_def_sptr second, 1522 diff_context_sptr ctxt); 1523 };// end class array_diff 1524 1525 array_diff_sptr 1526 compute_diff(array_type_def_sptr first, 1527 array_type_def_sptr second, 1528 diff_context_sptr ctxt); 1529 1530 class qualified_type_diff; 1531 typedef class shared_ptr<qualified_type_diff> qualified_type_diff_sptr; 1532 1533 /// Abstraction of a diff between two qualified types. 1534 class qualified_type_diff : public type_diff_base 1535 { 1536 struct priv; 1537 std::unique_ptr<priv> priv_; 1538 1539 protected: 1540 qualified_type_diff(qualified_type_def_sptr first, 1541 qualified_type_def_sptr second, 1542 diff_sptr underling, 1543 diff_context_sptr ctxt = diff_context_sptr()); 1544 1545 public: 1546 const qualified_type_def_sptr 1547 first_qualified_type() const; 1548 1549 const qualified_type_def_sptr 1550 second_qualified_type() const; 1551 1552 diff_sptr 1553 underlying_type_diff() const; 1554 1555 void 1556 underlying_type_diff(const diff_sptr); 1557 1558 diff_sptr 1559 leaf_underlying_type_diff() const; 1560 1561 virtual const string& 1562 get_pretty_representation() const; 1563 1564 virtual bool 1565 has_changes() const; 1566 1567 virtual enum change_kind 1568 has_local_changes() const; 1569 1570 virtual void 1571 report(ostream&, const string& indent = "") const; 1572 1573 virtual void 1574 chain_into_hierarchy(); 1575 1576 friend qualified_type_diff_sptr 1577 compute_diff(const qualified_type_def_sptr first, 1578 const qualified_type_def_sptr second, 1579 diff_context_sptr ctxt); 1580 };// end class qualified_type_diff. 1581 1582 qualified_type_diff_sptr 1583 compute_diff(const qualified_type_def_sptr first, 1584 const qualified_type_def_sptr second, 1585 diff_context_sptr ctxt); 1586 1587 class enum_diff; 1588 typedef shared_ptr<enum_diff> enum_diff_sptr; 1589 1590 /// Abstraction of a diff between two enums. 1591 class enum_diff : public type_diff_base 1592 { 1593 struct priv; 1594 std::unique_ptr<priv> priv_; 1595 1596 void 1597 clear_lookup_tables(); 1598 1599 bool 1600 lookup_tables_empty() const; 1601 1602 void 1603 ensure_lookup_tables_populated(); 1604 1605 protected: 1606 enum_diff(const enum_type_decl_sptr, 1607 const enum_type_decl_sptr, 1608 const diff_sptr, 1609 diff_context_sptr ctxt = diff_context_sptr()); 1610 1611 public: 1612 const enum_type_decl_sptr 1613 first_enum() const; 1614 1615 const enum_type_decl_sptr 1616 second_enum() const; 1617 1618 diff_sptr 1619 underlying_type_diff() const; 1620 1621 const string_enumerator_map& 1622 deleted_enumerators() const; 1623 1624 const string_enumerator_map& 1625 inserted_enumerators() const; 1626 1627 const string_changed_enumerator_map& 1628 changed_enumerators() const; 1629 1630 virtual const string& 1631 get_pretty_representation() const; 1632 1633 virtual bool 1634 has_changes() const; 1635 1636 virtual enum change_kind 1637 has_local_changes() const; 1638 1639 virtual void 1640 report(ostream&, const string& indent = "") const; 1641 1642 virtual void 1643 chain_into_hierarchy(); 1644 1645 friend enum_diff_sptr 1646 compute_diff(const enum_type_decl_sptr first, 1647 const enum_type_decl_sptr second, 1648 diff_context_sptr ctxt); 1649 };//end class enum_diff; 1650 1651 enum_diff_sptr 1652 compute_diff(const enum_type_decl_sptr, 1653 const enum_type_decl_sptr, 1654 diff_context_sptr); 1655 1656 /// This is the base class of @ref class_diff and @ref union_diff. 1657 class class_or_union_diff : public type_diff_base 1658 { 1659 protected: 1660 struct priv; 1661 typedef std::unique_ptr<priv> priv_ptr; 1662 priv_ptr priv_; 1663 1664 void 1665 clear_lookup_tables(void); 1666 1667 bool 1668 lookup_tables_empty(void) const; 1669 1670 void 1671 ensure_lookup_tables_populated(void) const; 1672 1673 void 1674 allocate_priv_data(); 1675 1676 protected: 1677 class_or_union_diff(class_or_union_sptr first_scope, 1678 class_or_union_sptr second_scope, 1679 diff_context_sptr ctxt = diff_context_sptr()); 1680 1681 public: 1682 1683 const class_or_union_diff::priv_ptr& 1684 get_priv() const; 1685 1686 //TODO: add change of the name of the type. 1687 1688 virtual ~class_or_union_diff(); 1689 1690 class_or_union_sptr 1691 first_class_or_union() const; 1692 1693 class_or_union_sptr 1694 second_class_or_union() const; 1695 1696 const edit_script& 1697 member_types_changes() const; 1698 1699 edit_script& 1700 member_types_changes(); 1701 1702 const edit_script& 1703 data_members_changes() const; 1704 1705 edit_script& 1706 data_members_changes(); 1707 1708 const string_decl_base_sptr_map& 1709 inserted_data_members() const; 1710 1711 const string_decl_base_sptr_map& 1712 deleted_data_members() const; 1713 1714 const unsigned_var_diff_sptr_map& 1715 changed_data_members() const; 1716 1717 const var_diff_sptrs_type& 1718 sorted_changed_data_members() const; 1719 1720 const edit_script& 1721 member_fns_changes() const; 1722 1723 edit_script& 1724 member_fns_changes(); 1725 1726 const function_decl_diff_sptrs_type& 1727 changed_member_fns() const; 1728 1729 const string_member_function_sptr_map& 1730 deleted_member_fns() const; 1731 1732 const string_member_function_sptr_map& 1733 inserted_member_fns() const; 1734 1735 size_t 1736 count_filtered_changed_data_members(bool local_only = false) const; 1737 1738 const var_diff_sptrs_type& 1739 sorted_subtype_changed_data_members() const; 1740 1741 size_t 1742 count_filtered_subtype_changed_data_members(bool local_only = false) const; 1743 1744 const string_decl_base_sptr_map& 1745 data_members_replaced_by_adms() const; 1746 1747 const changed_var_sptrs_type& 1748 ordered_data_members_replaced_by_adms() const; 1749 1750 const edit_script& 1751 member_fn_tmpls_changes() const; 1752 1753 edit_script& 1754 member_fn_tmpls_changes(); 1755 1756 const edit_script& 1757 member_class_tmpls_changes() const; 1758 1759 edit_script& 1760 member_class_tmpls_changes(); 1761 1762 virtual bool 1763 has_changes() const; 1764 1765 virtual enum change_kind 1766 has_local_changes() const; 1767 1768 virtual void 1769 report(ostream&, const string& indent = "") const; 1770 1771 virtual void 1772 chain_into_hierarchy(); 1773 1774 friend class default_reporter; 1775 }; // end class_or_union_diff; 1776 1777 /// This type abstracts changes for a class_decl. 1778 class class_diff : public class_or_union_diff 1779 { 1780 struct priv; 1781 typedef std::unique_ptr<priv> priv_ptr; 1782 priv_ptr priv_; 1783 1784 const priv_ptr& get_priv()const; 1785 1786 void 1787 clear_lookup_tables(void); 1788 1789 bool 1790 lookup_tables_empty(void) const; 1791 1792 void 1793 ensure_lookup_tables_populated(void) const; 1794 1795 void 1796 allocate_priv_data(); 1797 1798 protected: 1799 class_diff(class_decl_sptr first_scope, 1800 class_decl_sptr second_scope, 1801 diff_context_sptr ctxt = diff_context_sptr()); 1802 1803 public: 1804 //TODO: add change of the name of the type. 1805 1806 virtual ~class_diff(); 1807 1808 class_decl_sptr 1809 first_class_decl() const; 1810 1811 class_decl_sptr 1812 second_class_decl() const; 1813 1814 const edit_script& 1815 base_changes() const; 1816 1817 edit_script& 1818 base_changes(); 1819 1820 const string_base_sptr_map& 1821 deleted_bases() const; 1822 1823 const string_base_sptr_map& 1824 inserted_bases() const; 1825 1826 const base_diff_sptrs_type& 1827 changed_bases(); 1828 1829 const vector<class_decl::base_spec_sptr>& 1830 moved_bases() const; 1831 1832 virtual bool 1833 has_changes() const; 1834 1835 virtual enum change_kind 1836 has_local_changes() const; 1837 1838 virtual const string& 1839 get_pretty_representation() const; 1840 1841 virtual void 1842 report(ostream&, const string& indent = "") const; 1843 1844 virtual void 1845 chain_into_hierarchy(); 1846 1847 friend class_diff_sptr 1848 compute_diff(const class_decl_sptr first, 1849 const class_decl_sptr second, 1850 diff_context_sptr ctxt); 1851 1852 friend class default_reporter; 1853 };// end class_diff 1854 1855 class_diff_sptr 1856 compute_diff(const class_decl_sptr first, 1857 const class_decl_sptr second, 1858 diff_context_sptr ctxt); 1859 1860 class union_diff; 1861 typedef shared_ptr<union_diff> union_diff_sptr; 1862 1863 class union_diff : public class_or_union_diff 1864 { 1865 void 1866 clear_lookup_tables(void); 1867 1868 bool 1869 lookup_tables_empty(void) const; 1870 1871 void 1872 ensure_lookup_tables_populated(void) const; 1873 1874 void 1875 allocate_priv_data(); 1876 1877 protected: 1878 union_diff(union_decl_sptr first_union, 1879 union_decl_sptr second_union, 1880 diff_context_sptr ctxt = diff_context_sptr()); 1881 1882 public: 1883 1884 virtual ~union_diff(); 1885 1886 union_decl_sptr 1887 first_union_decl() const; 1888 1889 union_decl_sptr 1890 second_union_decl() const; 1891 1892 virtual const string& 1893 get_pretty_representation() const; 1894 1895 virtual void 1896 report(ostream&, const string& indent = "") const; 1897 1898 friend union_diff_sptr 1899 compute_diff(const union_decl_sptr first, 1900 const union_decl_sptr second, 1901 diff_context_sptr ctxt); 1902 }; // end class union_diff 1903 1904 union_diff_sptr 1905 compute_diff(const union_decl_sptr first, 1906 const union_decl_sptr second, 1907 diff_context_sptr ctxt); 1908 1909 /// An abstraction of a diff between two instances of class_decl::base_spec. 1910 class base_diff : public diff 1911 { 1912 struct priv; 1913 std::unique_ptr<priv> priv_; 1914 1915 protected: 1916 base_diff(class_decl::base_spec_sptr first, 1917 class_decl::base_spec_sptr second, 1918 class_diff_sptr underlying, 1919 diff_context_sptr ctxt = diff_context_sptr()); 1920 1921 public: 1922 class_decl::base_spec_sptr 1923 first_base() const; 1924 1925 class_decl::base_spec_sptr 1926 second_base() const; 1927 1928 const class_diff_sptr 1929 get_underlying_class_diff() const; 1930 1931 void 1932 set_underlying_class_diff(class_diff_sptr d); 1933 1934 virtual const string& 1935 get_pretty_representation() const; 1936 1937 virtual bool 1938 has_changes() const; 1939 1940 virtual enum change_kind 1941 has_local_changes() const; 1942 1943 virtual void 1944 report(ostream&, const string& indent = "") const; 1945 1946 virtual void 1947 chain_into_hierarchy(); 1948 1949 friend base_diff_sptr 1950 compute_diff(const class_decl::base_spec_sptr first, 1951 const class_decl::base_spec_sptr second, 1952 diff_context_sptr ctxt); 1953 };// end class base_diff 1954 1955 base_diff_sptr 1956 compute_diff(const class_decl::base_spec_sptr first, 1957 const class_decl::base_spec_sptr second, 1958 diff_context_sptr ctxt); 1959 1960 class scope_diff; 1961 1962 /// Convenience typedef for a shared pointer on a @ref scope_diff. 1963 typedef shared_ptr<scope_diff> scope_diff_sptr; 1964 1965 /// An abstractions of the changes between two scopes. 1966 class scope_diff : public diff 1967 { 1968 struct priv; 1969 std::unique_ptr<priv> priv_; 1970 1971 bool 1972 lookup_tables_empty() const; 1973 1974 void 1975 clear_lookup_tables(); 1976 1977 void 1978 ensure_lookup_tables_populated(); 1979 1980 protected: 1981 scope_diff(scope_decl_sptr first_scope, 1982 scope_decl_sptr second_scope, 1983 diff_context_sptr ctxt = diff_context_sptr()); 1984 1985 public: 1986 1987 friend scope_diff_sptr 1988 compute_diff(const scope_decl_sptr first, 1989 const scope_decl_sptr second, 1990 scope_diff_sptr d, 1991 diff_context_sptr ctxt); 1992 1993 friend scope_diff_sptr 1994 compute_diff(const scope_decl_sptr first_scope, 1995 const scope_decl_sptr second_scope, 1996 diff_context_sptr ctxt); 1997 1998 const scope_decl_sptr 1999 first_scope() const; 2000 2001 const scope_decl_sptr 2002 second_scope() const; 2003 2004 const edit_script& 2005 member_changes() const; 2006 2007 edit_script& 2008 member_changes(); 2009 2010 const decl_base_sptr 2011 deleted_member_at(unsigned index) const; 2012 2013 const decl_base_sptr 2014 deleted_member_at(vector<deletion>::const_iterator) const; 2015 2016 const decl_base_sptr 2017 inserted_member_at(unsigned i); 2018 2019 const decl_base_sptr 2020 inserted_member_at(vector<unsigned>::const_iterator i); 2021 2022 const diff_sptrs_type& 2023 changed_types() const; 2024 2025 const diff_sptrs_type& 2026 changed_decls() const; 2027 2028 const string_decl_base_sptr_map& 2029 removed_types() const; 2030 2031 const string_decl_base_sptr_map& 2032 removed_decls() const; 2033 2034 const string_decl_base_sptr_map& 2035 added_types() const; 2036 2037 const string_decl_base_sptr_map& 2038 added_decls() const; 2039 2040 virtual const string& 2041 get_pretty_representation() const; 2042 2043 virtual bool 2044 has_changes() const; 2045 2046 virtual enum change_kind 2047 has_local_changes() const; 2048 2049 virtual void 2050 report(ostream& out, const string& indent = "") const; 2051 2052 virtual void 2053 chain_into_hierarchy(); 2054 2055 friend class default_reporter; 2056 friend class leaf_reporter; 2057 };// end class scope_diff 2058 2059 scope_diff_sptr 2060 compute_diff(const scope_decl_sptr first, 2061 const scope_decl_sptr second, 2062 scope_diff_sptr d, 2063 diff_context_sptr ctxt); 2064 2065 scope_diff_sptr 2066 compute_diff(const scope_decl_sptr first_scope, 2067 const scope_decl_sptr second_scope, 2068 diff_context_sptr ctxt); 2069 2070 /// Abstraction of a diff between two function parameters. 2071 class fn_parm_diff : public decl_diff_base 2072 { 2073 struct priv; 2074 std::unique_ptr<priv> priv_; 2075 2076 fn_parm_diff(const function_decl::parameter_sptr first, 2077 const function_decl::parameter_sptr second, 2078 diff_context_sptr ctxt); 2079 2080 public: 2081 friend fn_parm_diff_sptr 2082 compute_diff(const function_decl::parameter_sptr first, 2083 const function_decl::parameter_sptr second, 2084 diff_context_sptr ctxt); 2085 2086 const function_decl::parameter_sptr 2087 first_parameter() const; 2088 2089 const function_decl::parameter_sptr 2090 second_parameter() const; 2091 2092 diff_sptr 2093 type_diff() const; 2094 2095 virtual const string& 2096 get_pretty_representation() const; 2097 2098 virtual bool 2099 has_changes() const; 2100 2101 virtual enum change_kind 2102 has_local_changes() const; 2103 2104 virtual void 2105 report(ostream&, const string& indent = "") const; 2106 2107 virtual void 2108 chain_into_hierarchy(); 2109 }; // end class fn_parm_diff 2110 2111 fn_parm_diff_sptr 2112 compute_diff(const function_decl::parameter_sptr first, 2113 const function_decl::parameter_sptr second, 2114 diff_context_sptr ctxt); 2115 2116 class function_type_diff; 2117 2118 /// A convenience typedef for a shared pointer to @ref 2119 /// function_type_type_diff 2120 typedef shared_ptr<function_type_diff> function_type_diff_sptr; 2121 2122 /// Abstraction of a diff between two function types. 2123 class function_type_diff: public type_diff_base 2124 { 2125 struct priv; 2126 std::unique_ptr<priv> priv_; 2127 2128 void 2129 ensure_lookup_tables_populated(); 2130 2131 const function_decl::parameter_sptr 2132 deleted_parameter_at(int i) const; 2133 2134 const function_decl::parameter_sptr 2135 inserted_parameter_at(int i) const; 2136 2137 protected: 2138 function_type_diff(const function_type_sptr first, 2139 const function_type_sptr second, 2140 diff_context_sptr ctxt); 2141 2142 public: 2143 friend function_type_diff_sptr 2144 compute_diff(const function_type_sptr first, 2145 const function_type_sptr second, 2146 diff_context_sptr ctxt); 2147 2148 const function_type_sptr 2149 first_function_type() const; 2150 2151 const function_type_sptr 2152 second_function_type() const; 2153 2154 const diff_sptr 2155 return_type_diff() const; 2156 2157 const string_fn_parm_diff_sptr_map& 2158 subtype_changed_parms() const; 2159 2160 const string_parm_map& 2161 removed_parms() const; 2162 2163 const string_parm_map& 2164 added_parms() const; 2165 2166 const vector<function_decl::parameter_sptr>& 2167 sorted_deleted_parms() const; 2168 2169 const vector<function_decl::parameter_sptr>& 2170 sorted_added_parms() const; 2171 2172 virtual const string& 2173 get_pretty_representation() const; 2174 2175 virtual bool 2176 has_changes() const; 2177 2178 virtual enum change_kind 2179 has_local_changes() const; 2180 2181 virtual void 2182 report(ostream&, const string& indent = "") const; 2183 2184 virtual void 2185 chain_into_hierarchy(); 2186 2187 friend class default_reporter; 2188 friend class leaf_reporter; 2189 };// end class function_type_diff 2190 2191 function_type_diff_sptr 2192 compute_diff(const function_type_sptr first, 2193 const function_type_sptr second, 2194 diff_context_sptr ctxt); 2195 2196 /// Abstraction of a diff between two function_decl. 2197 class function_decl_diff : public decl_diff_base 2198 { 2199 struct priv; 2200 std::unique_ptr<priv> priv_; 2201 2202 void 2203 ensure_lookup_tables_populated(); 2204 2205 2206 protected: 2207 function_decl_diff(const function_decl_sptr first, 2208 const function_decl_sptr second, 2209 diff_context_sptr ctxt); 2210 2211 public: 2212 2213 friend function_decl_diff_sptr 2214 compute_diff(const function_decl_sptr first, 2215 const function_decl_sptr second, 2216 diff_context_sptr ctxt); 2217 2218 const function_decl_sptr 2219 first_function_decl() const; 2220 2221 const function_decl_sptr 2222 second_function_decl() const; 2223 2224 const function_type_diff_sptr 2225 type_diff() const; 2226 2227 virtual const string& 2228 get_pretty_representation() const; 2229 2230 virtual bool 2231 has_changes() const; 2232 2233 virtual enum change_kind 2234 has_local_changes() const; 2235 2236 virtual void 2237 report(ostream&, const string& indent = "") const; 2238 2239 virtual void 2240 chain_into_hierarchy(); 2241 }; // end class function_decl_diff 2242 2243 function_decl_diff_sptr 2244 compute_diff(const function_decl_sptr first, 2245 const function_decl_sptr second, 2246 diff_context_sptr ctxt); 2247 2248 class type_decl_diff; 2249 2250 /// Convenience typedef for a shared pointer on a @ref type_decl_diff type. 2251 typedef shared_ptr<type_decl_diff> type_decl_diff_sptr; 2252 2253 /// Abstraction of a diff between two basic type declarations. 2254 class type_decl_diff : public type_diff_base 2255 { 2256 type_decl_diff(); 2257 2258 protected: 2259 type_decl_diff(const type_decl_sptr first, 2260 const type_decl_sptr second, 2261 diff_context_sptr ctxt = diff_context_sptr()); 2262 2263 public: 2264 friend type_decl_diff_sptr 2265 compute_diff(const type_decl_sptr first, 2266 const type_decl_sptr second, 2267 diff_context_sptr ctxt); 2268 2269 const type_decl_sptr 2270 first_type_decl() const; 2271 2272 const type_decl_sptr 2273 second_type_decl() const; 2274 2275 virtual const string& 2276 get_pretty_representation() const; 2277 2278 virtual bool 2279 has_changes() const; 2280 2281 virtual enum change_kind 2282 has_local_changes() const; 2283 2284 virtual void 2285 report(ostream& out, const string& indent = "") const; 2286 };// end type_decl_diff 2287 2288 type_decl_diff_sptr 2289 compute_diff(const type_decl_sptr, 2290 const type_decl_sptr, 2291 diff_context_sptr); 2292 2293 class typedef_diff; 2294 2295 /// Convenience typedef for a shared pointer on a typedef_diff type. 2296 typedef shared_ptr<typedef_diff> typedef_diff_sptr; 2297 2298 /// Abstraction of a diff between two typedef_decl. 2299 class typedef_diff : public type_diff_base 2300 { 2301 struct priv; 2302 std::unique_ptr<priv> priv_; 2303 2304 typedef_diff(); 2305 2306 protected: 2307 typedef_diff(const typedef_decl_sptr first, 2308 const typedef_decl_sptr second, 2309 const diff_sptr underlying_type_diff, 2310 diff_context_sptr ctxt = diff_context_sptr()); 2311 2312 public: 2313 friend typedef_diff_sptr 2314 compute_diff(const typedef_decl_sptr first, 2315 const typedef_decl_sptr second, 2316 diff_context_sptr ctxt); 2317 2318 const typedef_decl_sptr 2319 first_typedef_decl() const; 2320 2321 const typedef_decl_sptr 2322 second_typedef_decl() const; 2323 2324 const diff_sptr 2325 underlying_type_diff() const; 2326 2327 void 2328 underlying_type_diff(const diff_sptr); 2329 2330 virtual const string& 2331 get_pretty_representation() const; 2332 2333 virtual bool 2334 has_changes() const; 2335 2336 virtual enum change_kind 2337 has_local_changes() const; 2338 2339 virtual void 2340 report(ostream&, const string& indent = "") const; 2341 2342 virtual void 2343 chain_into_hierarchy(); 2344 };// end class typedef_diff 2345 2346 typedef_diff_sptr 2347 compute_diff(const typedef_decl_sptr, 2348 const typedef_decl_sptr, 2349 diff_context_sptr ctxt); 2350 2351 const diff* 2352 get_typedef_diff_underlying_type_diff(const diff* diff); 2353 2354 class translation_unit_diff; 2355 2356 /// Convenience typedef for a shared pointer on a 2357 /// @ref translation_unit_diff type. 2358 typedef shared_ptr<translation_unit_diff> translation_unit_diff_sptr; 2359 2360 /// An abstraction of a diff between two translation units. 2361 class translation_unit_diff : public scope_diff 2362 { 2363 struct priv; 2364 std::unique_ptr<priv> priv_; 2365 2366 protected: 2367 translation_unit_diff(translation_unit_sptr first, 2368 translation_unit_sptr second, 2369 diff_context_sptr ctxt = diff_context_sptr()); 2370 2371 public: 2372 2373 const translation_unit_sptr 2374 first_translation_unit() const; 2375 2376 const translation_unit_sptr 2377 second_translation_unit() const; 2378 2379 friend translation_unit_diff_sptr 2380 compute_diff(const translation_unit_sptr first, 2381 const translation_unit_sptr second, 2382 diff_context_sptr ctxt); 2383 2384 virtual bool 2385 has_changes() const; 2386 2387 virtual enum change_kind 2388 has_local_changes() const; 2389 2390 virtual void 2391 report(ostream& out, const string& indent = "") const; 2392 };//end class translation_unit_diff 2393 2394 translation_unit_diff_sptr 2395 compute_diff(const translation_unit_sptr first, 2396 const translation_unit_sptr second, 2397 diff_context_sptr ctxt = diff_context_sptr()); 2398 2399 /// An abstraction of a diff between between two abi corpus. 2400 class corpus_diff 2401 { 2402 struct priv; 2403 std::unique_ptr<priv> priv_; 2404 2405 protected: 2406 corpus_diff(corpus_sptr first, 2407 corpus_sptr second, 2408 diff_context_sptr ctxt = diff_context_sptr()); 2409 2410 void 2411 finish_diff_type(); 2412 2413 public: 2414 2415 class diff_stats; 2416 2417 virtual ~corpus_diff(); 2418 2419 /// A convenience typedef for a shared pointer to @ref diff_stats 2420 typedef shared_ptr<diff_stats> diff_stats_sptr; 2421 2422 bool 2423 do_log() const; 2424 2425 void 2426 do_log(bool); 2427 2428 corpus_sptr 2429 first_corpus() const; 2430 2431 corpus_sptr 2432 second_corpus() const; 2433 2434 const vector<diff*>& 2435 children_nodes() const; 2436 2437 void 2438 append_child_node(diff_sptr); 2439 2440 edit_script& 2441 function_changes() const; 2442 2443 edit_script& 2444 variable_changes() const; 2445 2446 bool 2447 soname_changed() const; 2448 2449 bool 2450 architecture_changed() const; 2451 2452 const string_function_ptr_map& 2453 deleted_functions() const; 2454 2455 const string_function_ptr_map& 2456 added_functions(); 2457 2458 const string_function_decl_diff_sptr_map& 2459 changed_functions(); 2460 2461 const function_decl_diff_sptrs_type& 2462 changed_functions_sorted(); 2463 2464 const string_var_ptr_map& 2465 deleted_variables() const; 2466 2467 const string_var_ptr_map& 2468 added_variables() const; 2469 2470 const string_var_diff_sptr_map& 2471 changed_variables(); 2472 2473 const var_diff_sptrs_type& 2474 changed_variables_sorted(); 2475 2476 const string_elf_symbol_map& 2477 deleted_unrefed_function_symbols() const; 2478 2479 const string_elf_symbol_map& 2480 added_unrefed_function_symbols() const; 2481 2482 const string_elf_symbol_map& 2483 deleted_unrefed_variable_symbols() const; 2484 2485 const string_elf_symbol_map& 2486 added_unrefed_variable_symbols() const; 2487 2488 const string_type_base_sptr_map& 2489 deleted_unreachable_types() const; 2490 2491 const vector<type_base_sptr>& 2492 deleted_unreachable_types_sorted() const; 2493 2494 const string_type_base_sptr_map& 2495 added_unreachable_types() const; 2496 2497 const vector<type_base_sptr>& 2498 added_unreachable_types_sorted() const; 2499 2500 const string_diff_sptr_map& 2501 changed_unreachable_types() const; 2502 2503 const vector<diff_sptr>& 2504 changed_unreachable_types_sorted() const; 2505 2506 const diff_context_sptr 2507 context() const; 2508 2509 const string& 2510 get_pretty_representation() const; 2511 2512 bool 2513 has_changes() const; 2514 2515 bool 2516 has_incompatible_changes() const; 2517 2518 bool 2519 has_net_subtype_changes() const; 2520 2521 bool 2522 has_net_changes() const; 2523 2524 const diff_stats& 2525 apply_filters_and_suppressions_before_reporting(); 2526 2527 void 2528 mark_leaf_diff_nodes(); 2529 2530 diff_maps& 2531 get_leaf_diffs(); 2532 2533 const diff_maps& 2534 get_leaf_diffs() const; 2535 2536 virtual void 2537 report(ostream& out, const string& indent = "") const; 2538 2539 virtual bool 2540 traverse(diff_node_visitor& v); 2541 2542 virtual void 2543 chain_into_hierarchy(); 2544 2545 friend corpus_diff_sptr 2546 compute_diff(const corpus_sptr f, 2547 const corpus_sptr s, 2548 diff_context_sptr ctxt); 2549 2550 friend void 2551 apply_suppressions(const corpus_diff* diff_tree); 2552 2553 friend void 2554 maybe_report_unreachable_type_changes(const corpus_diff& d, 2555 const corpus_diff::diff_stats &s, 2556 const string& indent, 2557 ostream& out); 2558 2559 friend class default_reporter; 2560 friend class leaf_reporter; 2561 }; // end class corpus_diff 2562 2563 corpus_diff_sptr 2564 compute_diff(const corpus_sptr, 2565 const corpus_sptr, 2566 diff_context_sptr = diff_context_sptr()); 2567 2568 corpus_diff_sptr 2569 compute_diff(const corpus_group_sptr&, 2570 const corpus_group_sptr&, 2571 diff_context_sptr ctxt); 2572 2573 /// This is a document class that aims to capture statistics about the 2574 /// changes carried by a @ref corpus_diff type. 2575 /// 2576 /// Its values are populated by the member function 2577 /// corpus_diff::apply_filters_and_suppressions_before_reporting() 2578 class corpus_diff::diff_stats 2579 { 2580 struct priv; 2581 std::unique_ptr<priv> priv_; 2582 2583 diff_stats(); 2584 2585 public: 2586 2587 diff_stats(diff_context_sptr); 2588 2589 size_t num_func_removed() const; 2590 void num_func_removed(size_t); 2591 2592 size_t num_removed_func_filtered_out() const; 2593 void num_removed_func_filtered_out(size_t); 2594 2595 size_t net_num_func_removed() const; 2596 2597 size_t num_func_added() const; 2598 void num_func_added(size_t); 2599 2600 size_t num_added_func_filtered_out() const; 2601 void num_added_func_filtered_out(size_t); 2602 2603 size_t net_num_func_added() const; 2604 2605 size_t num_func_changed() const; 2606 void num_func_changed(size_t); 2607 2608 size_t num_changed_func_filtered_out() const; 2609 void num_changed_func_filtered_out(size_t); 2610 2611 size_t num_func_with_virtual_offset_changes() const; 2612 void num_func_with_virtual_offset_changes(size_t); 2613 2614 size_t net_num_func_changed() const; 2615 2616 size_t num_vars_removed() const; 2617 void num_vars_removed(size_t); 2618 2619 size_t num_removed_vars_filtered_out() const; 2620 void num_removed_vars_filtered_out(size_t) const; 2621 2622 size_t net_num_vars_removed() const; 2623 2624 size_t num_vars_added() const; 2625 void num_vars_added(size_t); 2626 2627 size_t num_added_vars_filtered_out() const; 2628 void num_added_vars_filtered_out(size_t); 2629 2630 size_t net_num_vars_added() const; 2631 2632 size_t num_vars_changed() const; 2633 void num_vars_changed(size_t); 2634 2635 size_t num_changed_vars_filtered_out() const; 2636 void num_changed_vars_filtered_out(size_t); 2637 2638 size_t net_num_vars_changed() const; 2639 2640 size_t num_func_syms_removed() const; 2641 void num_func_syms_removed(size_t); 2642 2643 size_t num_removed_func_syms_filtered_out() const; 2644 void num_removed_func_syms_filtered_out(size_t); 2645 2646 size_t num_func_syms_added() const; 2647 void num_func_syms_added(size_t); 2648 2649 size_t num_added_func_syms_filtered_out() const; 2650 void num_added_func_syms_filtered_out(size_t); 2651 2652 size_t net_num_removed_func_syms() const; 2653 size_t net_num_added_func_syms() const; 2654 2655 size_t num_var_syms_removed() const; 2656 void num_var_syms_removed(size_t); 2657 2658 size_t num_removed_var_syms_filtered_out() const; 2659 void num_removed_var_syms_filtered_out(size_t); 2660 2661 size_t num_var_syms_added() const; 2662 void num_var_syms_added(size_t); 2663 2664 size_t num_added_var_syms_filtered_out() const; 2665 void num_added_var_syms_filtered_out(size_t); 2666 2667 size_t net_num_removed_var_syms() const; 2668 size_t net_num_added_var_syms() const; 2669 2670 size_t num_leaf_changes() const; 2671 void num_leaf_changes(size_t); 2672 2673 size_t num_leaf_changes_filtered_out() const; 2674 void num_leaf_changes_filtered_out(size_t); 2675 2676 size_t net_num_leaf_changes() const; 2677 2678 size_t num_leaf_type_changes() const; 2679 void num_leaf_type_changes(size_t); 2680 2681 size_t num_leaf_type_changes_filtered_out() const; 2682 void num_leaf_type_changes_filtered_out(size_t); 2683 size_t net_num_leaf_type_changes() const; 2684 2685 size_t num_leaf_func_changes() const; 2686 void num_leaf_func_changes(size_t); 2687 2688 size_t num_leaf_func_changes_filtered_out() const; 2689 void num_leaf_func_changes_filtered_out(size_t); 2690 size_t net_num_leaf_func_changes() const; 2691 2692 size_t num_leaf_var_changes() const; 2693 void num_leaf_var_changes(size_t); 2694 2695 size_t num_leaf_var_changes_filtered_out() const; 2696 void num_leaf_var_changes_filtered_out(size_t); 2697 size_t net_num_leaf_var_changes() const; 2698 2699 size_t num_added_unreachable_types() const; 2700 void num_added_unreachable_types(size_t); 2701 2702 size_t num_added_unreachable_types_filtered_out() const; 2703 void num_added_unreachable_types_filtered_out(size_t); 2704 size_t net_num_added_unreachable_types() const; 2705 2706 size_t num_removed_unreachable_types() const; 2707 void num_removed_unreachable_types(size_t); 2708 2709 size_t num_removed_unreachable_types_filtered_out() const; 2710 void num_removed_unreachable_types_filtered_out(size_t); 2711 size_t net_num_removed_unreachable_types() const; 2712 2713 size_t num_changed_unreachable_types() const; 2714 void num_changed_unreachable_types(size_t); 2715 2716 size_t num_changed_unreachable_types_filtered_out() const; 2717 void num_changed_unreachable_types_filtered_out(size_t); 2718 size_t net_num_changed_unreachable_types() const; 2719 2720 }; // end class corpus_diff::diff_stats 2721 2722 /// The base class for the node visitors. These are the types used to 2723 /// visit each node traversed by the diff_traversable_base::traverse() method. 2724 class diff_node_visitor : public node_visitor_base 2725 { 2726 protected: 2727 struct priv; 2728 std::unique_ptr<priv> priv_; 2729 2730 public: 2731 2732 diff_node_visitor(); 2733 2734 virtual ~diff_node_visitor(); 2735 2736 diff_node_visitor(visiting_kind k); 2737 2738 visiting_kind 2739 get_visiting_kind() const; 2740 2741 void 2742 set_visiting_kind(visiting_kind v); 2743 2744 void 2745 or_visiting_kind(visiting_kind v); 2746 2747 void 2748 set_current_topmost_iface_diff(diff*); 2749 2750 diff* 2751 get_current_topmost_iface_diff() const; 2752 2753 virtual void 2754 visit_begin(diff*); 2755 2756 virtual void 2757 visit_begin(corpus_diff*); 2758 2759 virtual void 2760 visit_end(diff*); 2761 2762 virtual void 2763 visit_end(corpus_diff*); 2764 2765 virtual bool 2766 visit(diff*, bool); 2767 2768 virtual bool 2769 visit(distinct_diff*, bool); 2770 2771 virtual bool 2772 visit(var_diff*, bool); 2773 2774 virtual bool 2775 visit(pointer_diff*, bool); 2776 2777 virtual bool 2778 visit(reference_diff*, bool); 2779 2780 virtual bool 2781 visit(qualified_type_diff*, bool); 2782 2783 virtual bool 2784 visit(enum_diff*, bool); 2785 2786 virtual bool 2787 visit(class_diff*, bool); 2788 2789 virtual bool 2790 visit(base_diff*, bool); 2791 2792 virtual bool 2793 visit(scope_diff*, bool); 2794 2795 virtual bool 2796 visit(function_decl_diff*, bool); 2797 2798 virtual bool 2799 visit(type_decl_diff*, bool); 2800 2801 virtual bool 2802 visit(typedef_diff*, bool); 2803 2804 virtual bool 2805 visit(translation_unit_diff*, bool); 2806 2807 virtual bool 2808 visit(corpus_diff*, bool); 2809 }; // end struct diff_node_visitor 2810 2811 void 2812 propagate_categories(diff* diff_tree); 2813 2814 void 2815 propagate_categories(diff_sptr diff_tree); 2816 2817 void 2818 propagate_categories(corpus_diff* diff_tree); 2819 2820 void 2821 propagate_categories(corpus_diff_sptr diff_tree); 2822 2823 void 2824 apply_suppressions(diff* diff_tree); 2825 2826 void 2827 apply_suppressions(const corpus_diff* diff_tree); 2828 2829 void 2830 apply_suppressions(diff_sptr diff_tree); 2831 2832 void 2833 apply_suppressions(corpus_diff_sptr diff_tree); 2834 2835 void 2836 print_diff_tree(diff* diff_tree, std::ostream&); 2837 2838 void 2839 print_diff_tree(corpus_diff* diff_tree, 2840 std::ostream&); 2841 2842 void 2843 print_diff_tree(diff_sptr diff_tree, 2844 std::ostream&); 2845 2846 void 2847 print_diff_tree(corpus_diff_sptr diff_tree, 2848 std::ostream&); 2849 2850 void 2851 categorize_redundancy(diff* diff_tree); 2852 2853 void 2854 categorize_redundancy(diff_sptr diff_tree); 2855 2856 void 2857 categorize_redundancy(corpus_diff* diff_tree); 2858 2859 void 2860 categorize_redundancy(corpus_diff_sptr diff_tree); 2861 2862 void 2863 clear_redundancy_categorization(diff* diff_tree); 2864 2865 void 2866 clear_redundancy_categorization(diff_sptr diff_tree); 2867 2868 void 2869 clear_redundancy_categorization(corpus_diff* diff_tree); 2870 2871 void 2872 clear_redundancy_categorization(corpus_diff_sptr diff_tree); 2873 2874 void 2875 apply_filters(corpus_diff_sptr diff_tree); 2876 2877 bool 2878 is_diff_of_variadic_parameter_type(const diff*); 2879 2880 bool 2881 is_diff_of_variadic_parameter_type(const diff_sptr&); 2882 2883 bool 2884 is_diff_of_variadic_parameter(const diff*); 2885 2886 bool 2887 is_diff_of_variadic_parameter(const diff_sptr&); 2888 2889 const type_diff_base* 2890 is_type_diff(const diff* diff); 2891 2892 const decl_diff_base* 2893 is_decl_diff(const diff* diff); 2894 2895 const type_decl_diff* 2896 is_diff_of_basic_type(const diff* diff); 2897 2898 const type_decl_diff* 2899 is_diff_of_basic_type(const diff* diff, bool); 2900 2901 const class_or_union_diff* 2902 is_diff_of_class_or_union_type(const diff *d); 2903 2904 bool 2905 has_basic_type_change_only(const diff* diff); 2906 2907 const enum_diff* 2908 is_enum_diff(const diff *diff); 2909 2910 const class_diff* 2911 is_class_diff(const diff* diff); 2912 2913 const union_diff* 2914 is_union_diff(const diff* diff); 2915 2916 const class_or_union_diff* 2917 is_class_or_union_diff(const diff* d); 2918 2919 const class_or_union_diff* 2920 is_anonymous_class_or_union_diff(const diff* d); 2921 2922 const subrange_diff* 2923 is_subrange_diff(const diff* diff); 2924 2925 const array_diff* 2926 is_array_diff(const diff* diff); 2927 2928 const function_type_diff* 2929 is_function_type_diff(const diff* diff); 2930 2931 const function_type_diff* 2932 is_function_type_diff_with_local_changes(const diff* diff); 2933 2934 const typedef_diff* 2935 is_typedef_diff(const diff *diff); 2936 2937 const var_diff* 2938 is_var_diff(const diff* diff); 2939 2940 const function_decl_diff* 2941 is_function_decl_diff(const diff* diff); 2942 2943 const pointer_diff* 2944 is_pointer_diff(const diff* diff); 2945 2946 const reference_diff* 2947 is_reference_diff(const diff* diff); 2948 2949 const qualified_type_diff* 2950 is_qualified_type_diff(const diff* diff); 2951 2952 const fn_parm_diff* 2953 is_fn_parm_diff(const diff* diff); 2954 2955 const base_diff* 2956 is_base_diff(const diff* diff); 2957 2958 const distinct_diff* 2959 is_distinct_diff(const diff *diff); 2960 2961 bool 2962 is_child_node_of_function_parm_diff(const diff* diff); 2963 2964 bool 2965 is_child_node_of_base_diff(const diff* diff); 2966 2967 const corpus_diff* 2968 is_corpus_diff(const diff* diff); 2969 2970 const diff* 2971 peel_typedef_diff(const diff* dif); 2972 2973 const diff* 2974 peel_pointer_diff(const diff* dif); 2975 2976 const diff* 2977 peel_reference_diff(const diff* dif); 2978 2979 const diff* 2980 peel_qualified_diff(const diff* dif); 2981 2982 const diff* 2983 peel_fn_parm_diff(const diff* dif); 2984 2985 const diff* 2986 peel_pointer_or_qualified_type_diff(const diff* dif); 2987 2988 const diff* 2989 peel_typedef_or_qualified_type_diff(const diff* dif); 2990 2991 const diff* 2992 peel_typedef_qualified_type_or_parameter_diff(const diff *dif); 2993 }// end namespace comparison 2994 2995 }// end namespace abigail 2996 2997 #endif //__ABG_COMPARISON_H__ 2998