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 /// @file 9 /// 10 /// Types of the main internal representation of libabigail. 11 /// 12 /// This internal representation abstracts the artifacts that make up 13 /// an application binary interface. 14 15 #ifndef __ABG_IR_H__ 16 #define __ABG_IR_H__ 17 18 #include <assert.h> 19 #include <stdint.h> 20 #include <cstdlib> 21 #include <functional> 22 #include <set> 23 #include <unordered_map> 24 #include "abg-cxx-compat.h" 25 #include "abg-fwd.h" 26 #include "abg-hash.h" 27 #include "abg-traverse.h" 28 #include "abg-config.h" 29 30 /// @file 31 /// 32 /// This file contains the declarations of the Internal Representation 33 /// of libabigail. 34 35 /// @defgroup Memory Memory management 36 /// @{ 37 /// 38 /// How objects' lifetime is handled in libabigail. 39 /// 40 /// For memory management and garbage collection of libabigail's IR 41 /// artifacts, we use std::shared_ptr and std::weak_ptr. 42 /// 43 /// When manipulating these IR artifacts, there are a few rules to keep in 44 /// mind. 45 /// 46 /// <b>The declaration for a type is owned by only one scope </b> 47 /// 48 /// This means that for each instance of abigail::type_base (a type) there 49 /// is an instance of abigail::scope_decl that owns a @ref 50 /// abigail::decl_base_sptr (a shared pointer to an abigail::decl_base) 51 /// that points to the declaration of that type. The 52 /// abigail::type_base_sptr is added to the scope using the function 53 /// abigail::add_decl_to_scope(). 54 /// 55 /// There is a kind of type that is usually not syntactically owned by 56 /// a scope: it's function type. In libabigail, function types are 57 /// represented by abigail::function_type and abigail::method_type. 58 /// These types must be owned by the translation unit they originate 59 /// from. Adding them to the translation unit must be done by a call 60 /// to the method function 61 /// abigail::translation::bind_function_type_life_time(). 62 /// 63 /// <b> A declaration that has a type does NOT own the type </b> 64 /// 65 /// This means that, for instance, in an abigail::var_decl (a variable 66 /// declaration), the type of the declaration is not owned by the 67 /// declaration. In other (concrete) words, the variable declaration 68 /// doesn't have a shared pointer to the type. Rather, it has a *weak* 69 /// pointer to its type. That means that it has a data member of type 70 /// abigail::type_base_wptr that contains the type of the declaration. 71 /// 72 /// But then abigail::var_decl::get_type() returns a shared pointer that 73 /// is constructed from the internal weak pointer to the type. That way, 74 /// users of the type of the var can own a temporary reference on it and 75 /// be assured that the type's life time is long enough for their need. 76 /// 77 /// Likewise, data members, function and template parameters similarly 78 /// have weak pointers on their type. 79 /// 80 /// If, for a reason, you really need to keep a type alive for the 81 /// entire lifetime of the type system, then you can bind the life 82 /// time of that type to the life time of the @ref environment that is 83 /// supposed to outlive the type system. You do that by passing the 84 /// type to the function environment::keep_type_alive(). 85 /// 86 /// @} 87 88 namespace abigail 89 { 90 91 /// The namespace of the internal representation of ABI artifacts like 92 /// types and decls. 93 namespace ir 94 { 95 96 // Inject some std types in here. 97 using std::unordered_map; 98 99 /// A convenience typedef for an unordered set of pointer values 100 typedef unordered_set<uintptr_t> pointer_set; 101 102 /// Functor to hash a canonical type by using its pointer value. 103 struct canonical_type_hash 104 { 105 size_t operator()(const type_base_sptr& l) const; 106 size_t operator()(const type_base *l) const; 107 }; //end struct canonical_type_hash 108 109 /// Helper typedef for an unordered set of type_base_sptr which uses 110 /// pointer value to tell its members appart, because the members are 111 /// canonical types. 112 typedef unordered_set<type_base_sptr, 113 canonical_type_hash> canonical_type_sptr_set_type; 114 115 /// Helper typedef for a vector of pointer to type_base. 116 typedef vector<type_base*> type_base_ptrs_type; 117 118 /// Helper typedef for a vector of shared pointer to a type_base. 119 typedef vector<type_base_sptr> type_base_sptrs_type; 120 121 void 122 sort_types(const canonical_type_sptr_set_type& types, 123 vector<type_base_sptr>& result); 124 125 /// This is an abstraction of the set of resources necessary to manage 126 /// several aspects of the internal representations of the Abigail 127 /// library. 128 /// 129 /// An environment can be seen as the boundaries in which all related 130 /// Abigail artifacts live. So before doing anything using this 131 /// library, the first thing to create is, well, you know it now, an 132 /// environment. 133 /// 134 /// Note that the lifetime of environment objects must be longer than 135 /// the lifetime of any other type in the Abigail system. So a given 136 /// instance of @ref environment must stay around as long as you are 137 /// using libabigail. It's only when you are done using the library 138 /// that you can de-allocate the environment instance. 139 class environment 140 { 141 public: 142 struct priv; 143 std::unique_ptr<priv> priv_; 144 145 /// A convenience typedef for a map of canonical types. The key is 146 /// the pretty representation string of a particular type and the 147 /// value is the vector of canonical types that have the same pretty 148 /// representation string. 149 typedef std::unordered_map<string, std::vector<type_base_sptr> > 150 canonical_types_map_type; 151 152 environment(); 153 154 virtual ~environment(); 155 156 canonical_types_map_type& 157 get_canonical_types_map(); 158 159 const canonical_types_map_type& 160 get_canonical_types_map() const; 161 162 const type_base_sptr& 163 get_void_type() const; 164 165 const type_base_sptr& 166 get_void_pointer_type() const; 167 168 const type_base_sptr& 169 get_variadic_parameter_type() const; 170 171 static string& 172 get_variadic_parameter_type_name(); 173 174 bool 175 canonicalization_is_done() const; 176 177 void 178 canonicalization_is_done(bool); 179 180 bool 181 do_on_the_fly_canonicalization() const; 182 183 void 184 do_on_the_fly_canonicalization(bool f); 185 186 bool 187 decl_only_class_equals_definition() const; 188 189 void 190 decl_only_class_equals_definition(bool f) const; 191 192 bool 193 is_void_type(const type_base_sptr&) const; 194 195 bool 196 is_void_type(const type_base*) const; 197 198 bool 199 is_void_pointer_type(const type_base_sptr&) const; 200 201 bool 202 is_void_pointer_type(const type_base*) const; 203 204 bool 205 is_variadic_parameter_type(const type_base*) const; 206 207 bool 208 is_variadic_parameter_type(const type_base_sptr&) const; 209 210 interned_string 211 intern(const string&) const; 212 213 const config& 214 get_config() const; 215 216 bool 217 user_set_analyze_exported_interfaces_only() const; 218 219 void 220 analyze_exported_interfaces_only(bool f); 221 222 bool 223 analyze_exported_interfaces_only() const; 224 225 #ifdef WITH_DEBUG_SELF_COMPARISON 226 void 227 set_self_comparison_debug_input(const corpus_sptr& corpus); 228 229 void 230 get_self_comparison_debug_inputs(corpus_sptr& first_corpus, 231 corpus_sptr& second_corpus); 232 233 void 234 self_comparison_debug_is_on(bool); 235 236 bool 237 self_comparison_debug_is_on() const; 238 #endif 239 240 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION 241 void 242 debug_type_canonicalization_is_on(bool flag); 243 244 bool 245 debug_type_canonicalization_is_on() const; 246 247 void 248 debug_die_canonicalization_is_on(bool flag); 249 250 bool 251 debug_die_canonicalization_is_on() const; 252 #endif 253 254 vector<type_base_sptr>* get_canonical_types(const char* name); 255 256 type_base* get_canonical_type(const char* name, unsigned index); 257 258 #ifdef WITH_DEBUG_SELF_COMPARISON 259 const unordered_map<string, uintptr_t>& 260 get_type_id_canonical_type_map() const; 261 262 unordered_map<string, uintptr_t>& 263 get_type_id_canonical_type_map(); 264 265 const unordered_map<uintptr_t, string>& 266 get_pointer_type_id_map() const; 267 268 unordered_map<uintptr_t, string>& 269 get_pointer_type_id_map(); 270 271 string 272 get_type_id_from_pointer(uintptr_t ptr) const; 273 274 string 275 get_type_id_from_type(const type_base *ptr) const; 276 277 uintptr_t 278 get_canonical_type_from_type_id(const char*) const; 279 #endif 280 281 friend class class_or_union; 282 friend class class_decl; 283 friend class function_type; 284 285 friend void keep_type_alive(type_base_sptr); 286 }; // end class environment 287 288 class location_manager; 289 /// @brief The source location of a token. 290 /// 291 /// This represents the location of a token coming from a given 292 /// translation unit. This location is actually an abstraction of 293 /// cursor in the table of all the locations of all the tokens of the 294 /// translation unit. That table is managed by the @ref location_manager 295 /// type. To get the file path, line and column numbers associated to 296 /// a given instance of @ref location, you need to use the 297 /// location_manager::expand_location method. 298 class location 299 { 300 unsigned value_; 301 // The location manager to use to decode the value above. There is 302 // one location manager per translation unit, and the location 303 // manager's life time is managed by its translation unit. 304 location_manager* loc_manager_; 305 // Whether the location is artificial. Being artificial means that 306 // the location wasn't generated by the original emitter of the 307 // metadata (i.e, the compiler if the metadata is debug info). For 308 // instance, implicit location derived from the position of XML 309 // elements in the abixml file is represented as artificial 310 // locations. 311 bool is_artificial_; 312 location(unsigned v,location_manager * m)313 location(unsigned v, location_manager* m) 314 : value_(v), loc_manager_(m), is_artificial_(false) 315 {} 316 317 /// Get the location manager to use to decode the value of this 318 /// location. 319 /// 320 /// @return the location manager for the current location value. 321 location_manager* get_location_manager()322 get_location_manager() const 323 {return loc_manager_;} 324 325 public: 326 327 /// Test if the location is artificial. 328 /// 329 /// Being artificial means that the location wasn't generated by the 330 /// original emitter of the metadata (i.e, the compiler if the 331 /// metadata is debug info). For instance, the implicit location 332 /// derived from the position of a given XML element in the abixml 333 /// file is represented as artificial locations. The same XML 334 /// element might carry a non-artificial (natural?) location that was 335 /// originally emitted by the compiler that generated the original 336 /// debug info the abixml file is derived from. 337 /// 338 /// @return true iff the location is artificial. 339 bool get_is_artificial()340 get_is_artificial() const 341 {return is_artificial_;} 342 343 /// Set the artificial-ness of the location. 344 /// 345 /// Being artificial means that the location wasn't generated by the 346 /// original emitter of the metadata (i.e, the compiler if the 347 /// metadata is debug info). For instance, the implicit location 348 /// derived from the position of a given XML element in the abixml 349 /// file is represented as artificial locations. The same XML 350 /// element might carry a non-artificial (natural?) location that 351 /// was originally emitted by the compiler that generated the 352 /// original debug info the abixml file is derived from. 353 /// 354 /// @param f the new artificial-ness state. 355 void set_is_artificial(bool f)356 set_is_artificial(bool f) 357 {is_artificial_ = f;} 358 359 /// Copy constructor of the location. 360 /// 361 /// @param l the location to copy from. location(const location & l)362 location(const location& l) 363 : value_(l.value_), 364 loc_manager_(l.loc_manager_), 365 is_artificial_(l.is_artificial_) 366 {} 367 368 /// Assignment operator of the location. 369 /// 370 /// @param l the location to assign to the current one. 371 location& 372 operator=(const location& l) 373 { 374 value_ = l.value_; 375 loc_manager_ = l.loc_manager_; 376 is_artificial_ = l.is_artificial_; 377 return *this; 378 } 379 380 /// Default constructor for the @ref location type. location()381 location() 382 : value_(), loc_manager_(), is_artificial_() 383 {} 384 385 /// Get the value of the location. 386 unsigned get_value()387 get_value() const 388 {return value_;} 389 390 /// Convert the location into a boolean. 391 /// 392 /// @return true iff the value of the location is different from 393 /// zero. 394 operator bool() const 395 {return !!value_;} 396 397 /// Equality operator of the @ref location type. 398 /// 399 /// @param other the other location to compare against. 400 /// 401 /// @return true iff both locations are equal. 402 bool 403 operator==(const location &other) const 404 {return value_ == other.value_;} 405 406 /// "Less than" operator of the @ref location type. 407 /// 408 /// @parm other the other location type to compare against. 409 /// 410 /// @return true iff the current instance is less than the @p other 411 /// one. 412 bool 413 operator<(const location &other) const 414 {return value_ < other.value_;} 415 416 /// Expand the current location into a tripplet file path, line and 417 /// column number. 418 /// 419 /// @param path the output parameter this function sets the expanded 420 /// path to. 421 /// 422 /// @param line the output parameter this function sets the expanded 423 /// line number to. 424 /// 425 /// @param column the output parameter this function sets the 426 /// expanded column number to. 427 void 428 expand(std::string& path, unsigned& line, unsigned& column) const; 429 430 string 431 expand(void) const; 432 433 friend class location_manager; 434 }; // end class location 435 436 /// @brief The entry point to manage locations. 437 /// 438 /// This type keeps a table of all the locations for tokens of a 439 /// given translation unit. 440 class location_manager 441 { 442 struct priv; 443 std::unique_ptr<priv> priv_; 444 445 public: 446 447 location_manager(); 448 449 ~location_manager(); 450 451 location 452 create_new_location(const std::string& fle, size_t lne, size_t col); 453 454 void 455 expand_location(const location& location, std::string& path, 456 unsigned& line, unsigned& column) const; 457 }; 458 459 /// The base of an entity of the intermediate representation that is 460 /// to be traversed. 461 struct ir_traversable_base : public traversable_base 462 { 463 /// Traverse a given IR node and its children, calling an visitor on 464 /// each node. 465 /// 466 /// @param v the visitor to call on each traversed node. 467 /// 468 /// @return true if the all the IR node tree was traversed. 469 virtual bool 470 traverse(ir_node_visitor& v); 471 }; // end class ir_traversable_base 472 473 /// The hashing functor for using instances of @ref type_or_decl_base 474 /// as values in a hash map or set. 475 struct type_or_decl_hash 476 { 477 478 /// Function-call Operator to hash the string representation of an 479 /// ABI artifact. 480 /// 481 /// @param artifact the ABI artifact to hash. 482 /// 483 /// @return the hash value of the string representation of @p 484 /// artifact. 485 size_t operatortype_or_decl_hash486 operator()(const type_or_decl_base *artifact) const 487 { 488 string repr = get_pretty_representation(artifact); 489 std::hash<string> do_hash; 490 return do_hash(repr); 491 } 492 493 /// Function-call Operator to hash the string representation of an 494 /// ABI artifact. 495 /// 496 /// @param artifact the ABI artifact to hash. 497 /// 498 /// @return the hash value of the string representation of @p 499 /// artifact. 500 size_t operatortype_or_decl_hash501 operator()(const type_or_decl_base_sptr& artifact) const 502 {return operator()(artifact.get());} 503 }; // end struct type_or_decl_hash 504 505 /// The comparison functor for using instances of @ref 506 /// type_or_decl_base as values in a hash map or set. 507 struct type_or_decl_equal 508 { 509 510 /// The function-call operator to compare the string representations 511 /// of two ABI artifacts. 512 /// 513 /// @param l the left hand side ABI artifact operand of the 514 /// comparison. 515 /// 516 /// @param r the right hand side ABI artifact operand of the 517 /// comparison. 518 /// 519 /// @return true iff the string representation of @p l equals the one 520 /// of @p r. 521 bool operatortype_or_decl_equal522 operator()(const type_or_decl_base *l, const type_or_decl_base *r) const 523 { 524 string repr1 = get_pretty_representation(l); 525 string repr2 = get_pretty_representation(r); 526 527 return repr1 == repr2; 528 } 529 530 /// The function-call operator to compare the string representations 531 /// of two ABI artifacts. 532 /// 533 /// @param l the left hand side ABI artifact operand of the 534 /// comparison. 535 /// 536 /// @param r the right hand side ABI artifact operand of the 537 /// comparison. 538 /// 539 /// @return true iff the string representation of @p l equals the one 540 /// of @p r. 541 bool operatortype_or_decl_equal542 operator()(const type_or_decl_base_sptr &l, 543 const type_or_decl_base_sptr &r) const 544 {return operator()(l.get(), r.get());} 545 }; // end type_or_decl_equal 546 547 /// A convenience typedef for a hash set of type_or_decl_base_sptr 548 typedef unordered_set<type_or_decl_base_sptr, 549 type_or_decl_hash, 550 type_or_decl_equal> artifact_sptr_set_type; 551 552 /// A convenience typedef for a hash set of const type_or_decl_base* 553 typedef unordered_set<const type_or_decl_base*, 554 type_or_decl_hash, 555 type_or_decl_equal> artifact_ptr_set_type; 556 557 /// A convenience typedef for a map which key is a string and which 558 /// value is a @ref type_base_wptr. 559 typedef unordered_map<string, type_base_wptr> string_type_base_wptr_map_type; 560 561 /// A convenience typedef for a map which key is a string and which 562 /// value is a @ref type_base_sptr. 563 typedef unordered_map<string, type_base_sptr> string_type_base_sptr_map_type; 564 565 /// A convenience typedef for a map which key is an @ref 566 /// interned_string and which value is a @ref type_base_wptr. 567 typedef unordered_map<interned_string, type_base_wptr, hash_interned_string> 568 istring_type_base_wptr_map_type; 569 570 /// A convenience typedef for a map which key is an @ref 571 /// interned_string and which value is a @ref type_base_wptr. 572 typedef unordered_map<interned_string, 573 type_or_decl_base_sptr, 574 hash_interned_string> 575 istring_type_or_decl_base_sptr_map_type; 576 577 /// This is a type that aggregates maps of all the kinds of types that 578 /// are supported by libabigail. 579 /// 580 /// For instance, the type_maps contains a map of string to basic 581 /// type, a map of string to class type, a map of string to union 582 /// types, etc. The key of a map entry is the pretty representation 583 /// of the type, and the value of the map entry is the type. 584 class type_maps 585 { 586 struct priv; 587 std::unique_ptr<priv> priv_; 588 589 public: 590 591 type_maps(); 592 593 ~type_maps(); 594 595 bool 596 empty() const; 597 598 const istring_type_base_wptrs_map_type& 599 basic_types() const; 600 601 istring_type_base_wptrs_map_type& 602 basic_types(); 603 604 const istring_type_base_wptrs_map_type& 605 class_types() const; 606 607 istring_type_base_wptrs_map_type& 608 class_types(); 609 610 istring_type_base_wptrs_map_type& 611 union_types(); 612 613 const istring_type_base_wptrs_map_type& 614 union_types() const; 615 616 istring_type_base_wptrs_map_type& 617 enum_types(); 618 619 const istring_type_base_wptrs_map_type& 620 enum_types() const; 621 622 istring_type_base_wptrs_map_type& 623 typedef_types(); 624 625 const istring_type_base_wptrs_map_type& 626 typedef_types() const; 627 628 istring_type_base_wptrs_map_type& 629 qualified_types(); 630 631 const istring_type_base_wptrs_map_type& 632 qualified_types() const; 633 634 istring_type_base_wptrs_map_type& 635 pointer_types(); 636 637 const istring_type_base_wptrs_map_type& 638 pointer_types() const; 639 640 istring_type_base_wptrs_map_type& 641 reference_types(); 642 643 const istring_type_base_wptrs_map_type& 644 reference_types() const; 645 646 istring_type_base_wptrs_map_type& 647 array_types(); 648 649 const istring_type_base_wptrs_map_type& 650 array_types() const; 651 652 const istring_type_base_wptrs_map_type& 653 subrange_types() const; 654 655 istring_type_base_wptrs_map_type& 656 subrange_types(); 657 658 istring_type_base_wptrs_map_type& 659 function_types(); 660 661 const istring_type_base_wptrs_map_type& 662 function_types() const; 663 664 const vector<type_base_wptr>& 665 get_types_sorted_by_name() const; 666 }; // end class type_maps; 667 668 /// This is the abstraction of the set of relevant artefacts (types, 669 /// variable declarations, functions, templates, etc) bundled together 670 /// into a translation unit. 671 class translation_unit : public traversable_base 672 { 673 struct priv; 674 std::unique_ptr<priv> priv_; 675 676 // Forbidden 677 translation_unit() = delete; 678 679 public: 680 /// Convenience typedef for a shared pointer on a @ref global_scope. 681 typedef shared_ptr<scope_decl> global_scope_sptr; 682 683 /// The language of the translation unit. 684 enum language 685 { 686 LANG_UNKNOWN = 0, 687 LANG_Cobol74, 688 LANG_Cobol85, 689 LANG_C89, 690 LANG_C99, 691 LANG_C11, 692 LANG_C, 693 LANG_C_plus_plus_03, 694 LANG_C_plus_plus_11, 695 LANG_C_plus_plus_14, 696 LANG_C_plus_plus, 697 LANG_ObjC, 698 LANG_ObjC_plus_plus, 699 LANG_Fortran77, 700 LANG_Fortran90, 701 LANG_Fortran95, 702 LANG_Ada83, 703 LANG_Ada95, 704 LANG_Pascal83, 705 LANG_Modula2, 706 LANG_Java, 707 LANG_PLI, 708 LANG_UPC, 709 LANG_D, 710 LANG_Python, 711 LANG_Go, 712 LANG_Rust, 713 LANG_Mips_Assembler 714 }; 715 716 public: 717 translation_unit(const ir::environment& env, 718 const std::string& path, 719 char address_size = 0); 720 721 virtual ~translation_unit(); 722 723 const environment& 724 get_environment() const; 725 726 language 727 get_language() const; 728 729 void 730 set_language(language l); 731 732 const std::string& 733 get_path() const; 734 735 void 736 set_path(const string&); 737 738 const std::string& 739 get_compilation_dir_path() const; 740 741 void 742 set_compilation_dir_path(const std::string&); 743 744 const std::string& 745 get_absolute_path() const; 746 747 void 748 set_corpus(corpus*); 749 750 const corpus* 751 get_corpus() const; 752 753 corpus* 754 get_corpus(); 755 756 const scope_decl_sptr& 757 get_global_scope() const; 758 759 scope_decl_sptr& 760 get_global_scope(); 761 762 const type_maps& 763 get_types() const; 764 765 type_maps& 766 get_types(); 767 768 const vector<function_type_sptr>& 769 get_live_fn_types() const; 770 771 location_manager& 772 get_loc_mgr(); 773 774 const location_manager& 775 get_loc_mgr() const; 776 777 bool 778 is_empty() const; 779 780 char 781 get_address_size() const; 782 783 void 784 set_address_size(char); 785 786 bool 787 is_constructed() const; 788 789 void 790 set_is_constructed(bool); 791 792 bool 793 operator==(const translation_unit&) const; 794 795 bool 796 operator!=(const translation_unit&) const; 797 798 void 799 bind_function_type_life_time(function_type_sptr) const; 800 801 virtual bool 802 traverse(ir_node_visitor& v); 803 804 friend function_type_sptr 805 lookup_function_type_in_translation_unit(const function_type& t, 806 const translation_unit& tu); 807 808 friend function_type_sptr 809 synthesize_function_type_from_translation_unit(const function_type& fn_type, 810 translation_unit& tu); 811 812 friend type_base_sptr 813 synthesize_type_from_translation_unit(const type_base_sptr& type, 814 translation_unit& tu); 815 };//end class translation_unit 816 817 /// A comparison functor to compare translation units based on their 818 /// absolute paths. 819 struct shared_translation_unit_comp 820 { 821 /// Compare two translations units based on their absolute paths. 822 /// 823 /// @param lhs the first translation unit to consider for the 824 /// comparison. 825 /// 826 /// @param rhs the second translatin unit to consider for the 827 /// comparison. 828 bool operatorshared_translation_unit_comp829 operator()(const translation_unit_sptr& lhs, 830 const translation_unit_sptr& rhs) const 831 {return lhs->get_absolute_path() < rhs->get_absolute_path();} 832 }; // end struct shared_translation_unit_comp 833 834 /// Convenience typedef for an ordered set of @ref 835 /// translation_unit_sptr. 836 typedef std::set<translation_unit_sptr, 837 shared_translation_unit_comp> translation_units; 838 839 string 840 translation_unit_language_to_string(translation_unit::language); 841 842 translation_unit::language 843 string_to_translation_unit_language(const string&); 844 845 bool 846 is_c_language(translation_unit::language l); 847 848 bool 849 is_cplus_plus_language(translation_unit::language l); 850 851 bool 852 is_java_language(translation_unit::language l); 853 854 bool 855 is_ada_language(translation_unit::language l); 856 857 bool 858 operator==(const translation_unit_sptr&, const translation_unit_sptr&); 859 860 bool 861 operator!=(const translation_unit_sptr&, const translation_unit_sptr&); 862 863 /// Access specifier for class members. 864 enum access_specifier 865 { 866 no_access, 867 public_access, 868 protected_access, 869 private_access, 870 }; 871 872 class elf_symbol; 873 /// A convenience typedef for a shared pointer to elf_symbol. 874 typedef shared_ptr<elf_symbol> elf_symbol_sptr; 875 876 /// A convenience typedef for a weak pointer to elf_symbol. 877 typedef weak_ptr<elf_symbol> elf_symbol_wptr; 878 879 /// Convenience typedef for a map which key is a string and which 880 /// value if the elf symbol of the same name. 881 typedef std::unordered_map<string, elf_symbol_sptr> 882 string_elf_symbol_sptr_map_type; 883 884 /// Convenience typedef for a shared pointer to an 885 /// string_elf_symbol_sptr_map_type. 886 typedef shared_ptr<string_elf_symbol_sptr_map_type> 887 string_elf_symbol_sptr_map_sptr; 888 889 /// Convenience typedef for a vector of elf_symbol 890 typedef std::vector<elf_symbol_sptr> elf_symbols; 891 892 /// Convenience typedef for a map which key is a string and which 893 /// value is a vector of elf_symbol. 894 typedef std::unordered_map<string, elf_symbols> 895 string_elf_symbols_map_type; 896 897 /// Convenience typedef for a shared pointer to 898 /// string_elf_symbols_map_type. 899 typedef shared_ptr<string_elf_symbols_map_type> string_elf_symbols_map_sptr; 900 901 /// Abstraction of an elf symbol. 902 /// 903 /// This is useful when a given corpus has been read from an ELF file. 904 /// In that case, a given decl might be associated to its underlying 905 /// ELF symbol, if that decl is publicly exported in the ELF file. In 906 /// that case, comparing decls might involve comparing their 907 /// underlying symbols as well. 908 class elf_symbol 909 { 910 public: 911 /// The type of a symbol. 912 enum type 913 { 914 NOTYPE_TYPE = 0, 915 OBJECT_TYPE, 916 FUNC_TYPE, 917 SECTION_TYPE, 918 FILE_TYPE, 919 COMMON_TYPE, 920 TLS_TYPE, 921 GNU_IFUNC_TYPE 922 }; 923 924 /// The binding of a symbol. 925 enum binding 926 { 927 LOCAL_BINDING = 0, 928 GLOBAL_BINDING, 929 WEAK_BINDING, 930 GNU_UNIQUE_BINDING 931 }; 932 933 /// The visibility of the symbol. 934 enum visibility 935 { 936 DEFAULT_VISIBILITY, 937 PROTECTED_VISIBILITY, 938 HIDDEN_VISIBILITY, 939 INTERNAL_VISIBILITY, 940 }; 941 942 /// Inject the elf_symbol::version here. 943 class version; 944 945 private: 946 struct priv; 947 std::unique_ptr<priv> priv_; 948 949 elf_symbol(); 950 951 elf_symbol(const environment& e, 952 size_t i, 953 size_t s, 954 const string& n, 955 type t, 956 binding b, 957 bool d, 958 bool c, 959 const version& ve, 960 visibility vi, 961 bool is_in_ksymtab = false, 962 const abg_compat::optional<uint32_t>& crc = {}, 963 const abg_compat::optional<std::string>& ns = {}, 964 bool is_suppressed = false); 965 966 elf_symbol(const elf_symbol&); 967 968 elf_symbol& 969 operator=(const elf_symbol& s); 970 971 public: 972 973 static elf_symbol_sptr 974 create(const environment& e, 975 size_t i, 976 size_t s, 977 const string& n, 978 type t, 979 binding b, 980 bool d, 981 bool c, 982 const version& ve, 983 visibility vi, 984 bool is_in_ksymtab = false, 985 const abg_compat::optional<uint32_t>& crc = {}, 986 const abg_compat::optional<std::string>& ns = {}, 987 bool is_suppressed = false); 988 989 const environment& 990 get_environment() const; 991 992 size_t 993 get_index() const; 994 995 void 996 set_index(size_t); 997 998 const string& 999 get_name() const; 1000 1001 void 1002 set_name(const string& n); 1003 1004 type 1005 get_type() const; 1006 1007 void 1008 set_type(type t); 1009 1010 size_t 1011 get_size() const; 1012 1013 void 1014 set_size(size_t); 1015 1016 binding 1017 get_binding() const; 1018 1019 void 1020 set_binding(binding b); 1021 1022 version& 1023 get_version() const; 1024 1025 void 1026 set_version(const version& v); 1027 1028 void 1029 set_visibility(visibility v); 1030 1031 visibility 1032 get_visibility() const; 1033 1034 bool 1035 is_defined() const; 1036 1037 void 1038 is_defined(bool d); 1039 1040 bool 1041 is_public() const; 1042 1043 bool 1044 is_function() const; 1045 1046 bool 1047 is_variable() const; 1048 1049 bool 1050 is_in_ksymtab() const; 1051 1052 void 1053 set_is_in_ksymtab(bool is_in_ksymtab); 1054 1055 const abg_compat::optional<uint32_t>& 1056 get_crc() const; 1057 1058 void 1059 set_crc(const abg_compat::optional<uint32_t>& crc); 1060 1061 const abg_compat::optional<std::string>& 1062 get_namespace() const; 1063 1064 void 1065 set_namespace(const abg_compat::optional<std::string>& ns); 1066 1067 bool 1068 is_suppressed() const; 1069 1070 void 1071 set_is_suppressed(bool is_suppressed); 1072 1073 const elf_symbol_sptr 1074 get_main_symbol() const; 1075 1076 elf_symbol_sptr 1077 get_main_symbol(); 1078 1079 bool 1080 is_main_symbol() const; 1081 1082 elf_symbol_sptr 1083 update_main_symbol(const std::string&); 1084 1085 elf_symbol_sptr 1086 get_next_alias() const; 1087 1088 bool 1089 has_aliases() const; 1090 1091 int 1092 get_number_of_aliases() const; 1093 1094 void 1095 add_alias(const elf_symbol_sptr&); 1096 1097 bool 1098 is_common_symbol() const; 1099 1100 bool 1101 has_other_common_instances() const; 1102 1103 elf_symbol_sptr 1104 get_next_common_instance() const; 1105 1106 void 1107 add_common_instance(const elf_symbol_sptr&); 1108 1109 const string& 1110 get_id_string() const; 1111 1112 elf_symbol_sptr 1113 get_alias_from_name(const string& name) const; 1114 1115 elf_symbol_sptr 1116 get_alias_which_equals(const elf_symbol& other) const; 1117 1118 elf_symbol_sptr 1119 get_alias_with_default_symbol_version() const; 1120 1121 string 1122 get_aliases_id_string(const string_elf_symbols_map_type& symtab, 1123 bool include_symbol_itself = true) const; 1124 1125 string 1126 get_aliases_id_string(bool include_symbol_itself = true) const; 1127 1128 static bool 1129 get_name_and_version_from_id(const string& id, 1130 string& name, 1131 string& ver); 1132 1133 bool 1134 operator==(const elf_symbol&) const; 1135 1136 bool 1137 does_alias(const elf_symbol&) const; 1138 }; // end class elf_symbol. 1139 1140 std::ostream& 1141 operator<<(std::ostream& o, elf_symbol::type t); 1142 1143 std::ostream& 1144 operator<<(std::ostream& o, elf_symbol::binding t); 1145 1146 std::ostream& 1147 operator<<(std::ostream& o, elf_symbol::visibility t); 1148 1149 bool 1150 string_to_elf_symbol_type(const string&, elf_symbol::type&); 1151 1152 bool 1153 string_to_elf_symbol_binding(const string&, elf_symbol::binding&); 1154 1155 bool 1156 string_to_elf_symbol_visibility(const string&, elf_symbol::visibility&); 1157 1158 bool 1159 elf_symbol_is_function(elf_symbol::type); 1160 1161 bool 1162 elf_symbol_is_variable(elf_symbol::type); 1163 1164 bool 1165 operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs); 1166 1167 bool 1168 operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs); 1169 1170 bool 1171 elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2); 1172 1173 void 1174 compute_aliases_for_elf_symbol(const elf_symbol& symbol, 1175 const string_elf_symbols_map_type& symtab, 1176 vector<elf_symbol_sptr>& alias_set); 1177 1178 /// The abstraction of the version of an ELF symbol. 1179 class elf_symbol::version 1180 { 1181 struct priv; 1182 std::unique_ptr<priv> priv_; 1183 1184 public: 1185 version(); 1186 1187 version(const string& v, 1188 bool is_default); 1189 1190 version(const version& v); 1191 1192 ~version(); 1193 1194 operator const string&() const; 1195 1196 const string& 1197 str() const; 1198 1199 void 1200 str(const string& s); 1201 1202 bool 1203 is_default() const; 1204 1205 void 1206 is_default(bool f); 1207 1208 bool 1209 is_empty() const; 1210 1211 bool 1212 operator==(const version& o) const; 1213 1214 bool 1215 operator!=(const version& o) const; 1216 1217 version& 1218 operator=(const version& o); 1219 };// end class elf_symbol::version 1220 1221 class context_rel; 1222 /// A convenience typedef for shared pointers to @ref context_rel 1223 typedef shared_ptr<context_rel> context_rel_sptr; 1224 1225 /// The abstraction of the relationship between an entity and its 1226 /// containing scope (its context). That relationship can carry 1227 /// properties like access rights (if the parent is a class_decl), 1228 /// etc. 1229 /// 1230 /// But importantly, this relationship carries a pointer to the 1231 /// actualy parent. 1232 class context_rel 1233 { 1234 protected: 1235 scope_decl* scope_; 1236 enum access_specifier access_; 1237 bool is_static_; 1238 1239 public: context_rel()1240 context_rel() 1241 : scope_(0), 1242 access_(no_access), 1243 is_static_(false) 1244 {} 1245 context_rel(scope_decl * s)1246 context_rel(scope_decl* s) 1247 : scope_(s), 1248 access_(no_access), 1249 is_static_(false) 1250 {} 1251 context_rel(scope_decl * s,access_specifier a,bool f)1252 context_rel(scope_decl* s, 1253 access_specifier a, 1254 bool f) 1255 : scope_(s), 1256 access_(a), 1257 is_static_(f) 1258 {} 1259 1260 scope_decl* get_scope()1261 get_scope() const 1262 {return scope_;} 1263 1264 access_specifier get_access_specifier()1265 get_access_specifier() const 1266 {return access_;} 1267 1268 void set_access_specifier(access_specifier a)1269 set_access_specifier(access_specifier a) 1270 {access_ = a;} 1271 1272 bool get_is_static()1273 get_is_static() const 1274 {return is_static_;} 1275 1276 void set_is_static(bool s)1277 set_is_static(bool s) 1278 {is_static_ = s;} 1279 1280 void set_scope(scope_decl * s)1281 set_scope(scope_decl* s) 1282 {scope_ = s;} 1283 1284 bool 1285 operator==(const context_rel& o)const 1286 { 1287 return (access_ == o.access_ 1288 && is_static_ == o.is_static_); 1289 } 1290 1291 /// Inequality operator. 1292 /// 1293 /// @param o the other instance of @ref context_rel to compare the 1294 /// current instance against. 1295 /// 1296 /// @return true iff the current instance of @ref context_rel is 1297 /// different from @p o. 1298 bool 1299 operator!=(const context_rel& o) const 1300 {return !operator==(o);} 1301 1302 virtual ~context_rel(); 1303 };// end class context_rel 1304 1305 /// A bitfield that gives callers of abigail::ir::equals() some 1306 /// insight about how different two internal representation artifacts 1307 /// are. 1308 enum change_kind 1309 { 1310 NO_CHANGE_KIND = 0, 1311 1312 /// This means that a given IR artifact has a local type change. 1313 LOCAL_TYPE_CHANGE_KIND = 1 << 0, 1314 1315 /// This means that a given IR artifact has a local non-type change. 1316 /// That is a change that is carried by the artifact itself, not by 1317 /// its type. 1318 LOCAL_NON_TYPE_CHANGE_KIND = 1 << 1, 1319 1320 /// Testing (anding) against this mask means that a given IR artifact has 1321 /// local differences, with respect to the other artifact it was compared 1322 /// against. A local change is a change that is carried by the artifact 1323 /// itself (or its type), rather than by one off its sub-types. 1324 ALL_LOCAL_CHANGES_MASK = LOCAL_TYPE_CHANGE_KIND | LOCAL_NON_TYPE_CHANGE_KIND, 1325 1326 /// This means that a given IR artifact has changes in some of its 1327 /// sub-types, with respect to the other artifact it was compared 1328 /// against. 1329 SUBTYPE_CHANGE_KIND = 1 << 2, 1330 };// end enum change_kind 1331 1332 change_kind 1333 operator|(change_kind, change_kind); 1334 1335 change_kind 1336 operator&(change_kind, change_kind); 1337 1338 change_kind& 1339 operator|=(change_kind&, change_kind); 1340 1341 change_kind& 1342 operator&=(change_kind&, change_kind); 1343 1344 bool 1345 maybe_compare_as_member_decls(const decl_base& l, 1346 const decl_base& r, 1347 change_kind* k); 1348 1349 bool 1350 equals(const decl_base&, const decl_base&, change_kind*); 1351 1352 /// The base class of both types and declarations. 1353 class type_or_decl_base : public ir_traversable_base 1354 { 1355 struct priv; 1356 mutable std::unique_ptr<priv> priv_; 1357 1358 type_or_decl_base(); 1359 type_or_decl_base(const type_or_decl_base&); 1360 1361 protected: 1362 1363 /// This is a bitmap type which instance is meant to contain the 1364 /// runtime type of a given ABI artifact. Bits of the identifiers 1365 /// of the type of a given artifact as well as the types it inherits 1366 /// from are to be set to 1. 1367 enum type_or_decl_kind 1368 { 1369 ABSTRACT_TYPE_OR_DECL, 1370 ABSTRACT_DECL_BASE = 1, 1371 ABSTRACT_SCOPE_DECL = 1 << 1, 1372 GLOBAL_SCOPE_DECL = 1 << 2, 1373 NAMESPACE_DECL = 1 << 3, 1374 VAR_DECL = 1 << 4, 1375 FUNCTION_DECL = 1 << 5, 1376 FUNCTION_PARAMETER_DECL = 1 << 6, 1377 METHOD_DECL = 1 << 7, 1378 TEMPLATE_DECL = 1 << 8, 1379 ABSTRACT_TYPE_BASE = 1 << 9, 1380 ABSTRACT_SCOPE_TYPE_DECL = 1 << 10, 1381 BASIC_TYPE = 1 << 11, 1382 QUALIFIED_TYPE = 1 << 12, 1383 POINTER_TYPE = 1 << 13, 1384 REFERENCE_TYPE = 1 << 14, 1385 ARRAY_TYPE = 1 << 15, 1386 ENUM_TYPE = 1 << 16, 1387 TYPEDEF_TYPE = 1 << 17, 1388 CLASS_TYPE = 1 << 18, 1389 UNION_TYPE = 1 << 19, 1390 FUNCTION_TYPE = 1 << 20, 1391 METHOD_TYPE = 1 << 21, 1392 }; // end enum type_or_decl_kind 1393 1394 enum type_or_decl_kind 1395 kind() const; 1396 1397 void 1398 kind(enum type_or_decl_kind); 1399 1400 const void* 1401 runtime_type_instance() const; 1402 1403 void* 1404 runtime_type_instance(); 1405 1406 void 1407 runtime_type_instance(void*); 1408 1409 const void* 1410 type_or_decl_base_pointer() const; 1411 1412 void* 1413 type_or_decl_base_pointer(); 1414 1415 bool hashing_started() const; 1416 1417 void hashing_started(bool) const; 1418 1419 type_or_decl_base& 1420 operator=(const type_or_decl_base&); 1421 1422 public: 1423 1424 type_or_decl_base(const environment&, 1425 enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL); 1426 1427 virtual ~type_or_decl_base(); 1428 1429 bool 1430 get_is_artificial() const; 1431 1432 void 1433 set_is_artificial(bool); 1434 1435 const environment& 1436 get_environment() const; 1437 1438 void 1439 set_artificial_location(const location &); 1440 1441 location& 1442 get_artificial_location() const; 1443 1444 bool 1445 has_artificial_location() const; 1446 1447 const corpus* 1448 get_corpus() const; 1449 1450 corpus* 1451 get_corpus(); 1452 1453 void 1454 set_translation_unit(translation_unit*); 1455 1456 const translation_unit* 1457 get_translation_unit() const; 1458 1459 translation_unit* 1460 get_translation_unit(); 1461 1462 virtual bool 1463 traverse(ir_node_visitor&); 1464 1465 virtual string 1466 get_pretty_representation(bool internal = false, 1467 bool qualified_name = true) const = 0; 1468 1469 friend type_or_decl_base::type_or_decl_kind 1470 operator|(type_or_decl_base::type_or_decl_kind, 1471 type_or_decl_base::type_or_decl_kind); 1472 1473 friend type_or_decl_base::type_or_decl_kind& 1474 operator|=(type_or_decl_base::type_or_decl_kind&, 1475 type_or_decl_base::type_or_decl_kind); 1476 1477 friend type_or_decl_base::type_or_decl_kind 1478 operator&(type_or_decl_base::type_or_decl_kind, 1479 type_or_decl_base::type_or_decl_kind); 1480 1481 friend type_or_decl_base::type_or_decl_kind& 1482 operator&=(type_or_decl_base::type_or_decl_kind&, 1483 type_or_decl_base::type_or_decl_kind); 1484 1485 friend class_decl* 1486 is_class_type(const type_or_decl_base*); 1487 1488 friend pointer_type_def* 1489 is_pointer_type(type_or_decl_base*); 1490 1491 friend type_base* 1492 is_type(const type_or_decl_base*); 1493 1494 friend decl_base* 1495 is_decl(const type_or_decl_base* d); 1496 }; // end class type_or_decl_base 1497 1498 type_or_decl_base::type_or_decl_kind 1499 operator|(type_or_decl_base::type_or_decl_kind, 1500 type_or_decl_base::type_or_decl_kind); 1501 1502 type_or_decl_base::type_or_decl_kind& 1503 operator|=(type_or_decl_base::type_or_decl_kind&, 1504 type_or_decl_base::type_or_decl_kind); 1505 1506 type_or_decl_base::type_or_decl_kind 1507 operator&(type_or_decl_base::type_or_decl_kind, 1508 type_or_decl_base::type_or_decl_kind); 1509 1510 type_or_decl_base::type_or_decl_kind& 1511 operator&=(type_or_decl_base::type_or_decl_kind&, 1512 type_or_decl_base::type_or_decl_kind); 1513 1514 bool 1515 operator==(const type_or_decl_base&, const type_or_decl_base&); 1516 1517 bool 1518 operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&); 1519 1520 bool 1521 operator!=(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&); 1522 1523 /// The base type of all declarations. 1524 class decl_base : public virtual type_or_decl_base 1525 { 1526 // Forbidden 1527 decl_base(); 1528 1529 struct priv; 1530 1531 protected: 1532 1533 const interned_string& 1534 peek_qualified_name() const; 1535 1536 void 1537 clear_qualified_name(); 1538 1539 void 1540 set_qualified_name(const interned_string&) const; 1541 1542 const interned_string& 1543 peek_temporary_qualified_name() const; 1544 1545 void 1546 set_temporary_qualified_name(const interned_string&) const; 1547 1548 public: 1549 // This is public because some internals of the library need to 1550 // update it. But it's opaque to client code anyway, so no big 1551 // deal. Also, it's not handled by a shared_ptr because accessing 1552 // the data members of the priv struct for this decl_base shows up 1553 // on performance profiles when dealing with big binaries with a lot 1554 // of types; dereferencing the shared_ptr involves locking of some 1555 // sort and that is slower than just dereferencing a pointer likere 1556 // here. There are other types for which the priv pointer is 1557 // managed using shared_ptr just fine, because those didn't show up 1558 // during our performance profiling. 1559 priv* priv_; 1560 1561 /// Facility to hash instances of decl_base. 1562 struct hash; 1563 1564 /// ELF visibility 1565 enum visibility 1566 { 1567 VISIBILITY_NONE, 1568 VISIBILITY_DEFAULT, 1569 VISIBILITY_PROTECTED, 1570 VISIBILITY_HIDDEN, 1571 VISIBILITY_INTERNAL 1572 }; 1573 1574 /// ELF binding 1575 enum binding 1576 { 1577 BINDING_NONE, 1578 BINDING_LOCAL, 1579 BINDING_GLOBAL, 1580 BINDING_WEAK 1581 }; 1582 1583 virtual void 1584 set_scope(scope_decl*); 1585 1586 protected: 1587 const context_rel* 1588 get_context_rel() const; 1589 1590 context_rel* 1591 get_context_rel(); 1592 1593 void 1594 set_context_rel(context_rel *c); 1595 decl_base(const decl_base&); 1596 1597 public: 1598 decl_base(const environment& e, 1599 const string& name, 1600 const location& locus, 1601 const string& mangled_name = "", 1602 visibility vis = VISIBILITY_DEFAULT); 1603 1604 decl_base(const environment& e, 1605 const interned_string& name, 1606 const location& locus, 1607 const interned_string& mangled_name = interned_string(), 1608 visibility vis = VISIBILITY_DEFAULT); 1609 1610 decl_base(const environment&, const location&); 1611 1612 virtual bool 1613 operator==(const decl_base&) const; 1614 1615 virtual bool 1616 operator!=(const decl_base&) const; 1617 1618 virtual bool 1619 traverse(ir_node_visitor& v); 1620 1621 virtual ~decl_base(); 1622 1623 virtual size_t 1624 get_hash() const; 1625 1626 virtual string 1627 get_pretty_representation(bool internal = false, 1628 bool qualified_name = true) const; 1629 1630 virtual void 1631 get_qualified_name(interned_string& qualified_name, 1632 bool internal = false) const; 1633 1634 virtual const interned_string& 1635 get_qualified_name(bool internal = false) const; 1636 1637 virtual const interned_string& 1638 get_scoped_name() const; 1639 1640 bool 1641 get_is_in_public_symbol_table() const; 1642 1643 void 1644 set_is_in_public_symbol_table(bool); 1645 1646 const location& 1647 get_location() const; 1648 1649 void 1650 set_location(const location& l); 1651 1652 const interned_string& 1653 get_name() const; 1654 1655 const interned_string& 1656 get_qualified_parent_name() const; 1657 1658 void 1659 set_name(const string& n); 1660 1661 bool 1662 get_is_anonymous() const; 1663 1664 void 1665 set_is_anonymous(bool); 1666 1667 bool 1668 get_has_anonymous_parent() const; 1669 1670 bool 1671 get_is_anonymous_or_has_anonymous_parent() const; 1672 1673 typedef_decl_sptr 1674 get_naming_typedef() const; 1675 1676 void 1677 set_naming_typedef(const typedef_decl_sptr&); 1678 1679 const interned_string& 1680 get_linkage_name() const; 1681 1682 virtual void 1683 set_linkage_name(const string& m); 1684 1685 scope_decl* 1686 get_scope() const; 1687 1688 visibility 1689 get_visibility() const; 1690 1691 void 1692 set_visibility(visibility v); 1693 1694 const decl_base_sptr 1695 get_earlier_declaration() const; 1696 1697 void 1698 set_earlier_declaration(const decl_base_sptr&); 1699 1700 const decl_base_sptr 1701 get_definition_of_declaration() const; 1702 1703 void 1704 set_definition_of_declaration(const decl_base_sptr&); 1705 1706 const decl_base* 1707 get_naked_definition_of_declaration() const; 1708 1709 bool 1710 get_is_declaration_only() const; 1711 1712 void 1713 set_is_declaration_only(bool f); 1714 1715 friend bool 1716 equals(const decl_base&, const decl_base&, change_kind*); 1717 1718 friend bool 1719 equals(const var_decl&, const var_decl&, change_kind*); 1720 1721 friend bool 1722 var_equals_modulo_types(const var_decl&, const var_decl&, change_kind*); 1723 1724 friend bool 1725 maybe_compare_as_member_decls(const decl_base& l, 1726 const decl_base& r, 1727 change_kind* k); 1728 1729 friend decl_base_sptr 1730 add_decl_to_scope(decl_base_sptr decl, scope_decl* scpe); 1731 1732 friend void 1733 remove_decl_from_scope(decl_base_sptr); 1734 1735 friend decl_base_sptr 1736 insert_decl_into_scope(decl_base_sptr, 1737 vector<shared_ptr<decl_base> >::iterator, 1738 scope_decl*); 1739 1740 friend enum access_specifier 1741 get_member_access_specifier(const decl_base& d); 1742 1743 friend enum access_specifier 1744 get_member_access_specifier(const decl_base_sptr& d); 1745 1746 friend void 1747 set_member_access_specifier(decl_base& d, 1748 access_specifier a); 1749 1750 friend bool 1751 get_member_is_static(const decl_base& d); 1752 1753 friend bool 1754 get_member_is_static(const decl_base_sptr& d); 1755 1756 friend void 1757 set_member_is_static(const decl_base_sptr& d, bool s); 1758 1759 friend void 1760 set_member_is_static(decl_base& d, bool s); 1761 1762 friend bool 1763 get_member_function_is_virtual(const function_decl& f); 1764 1765 friend void 1766 set_member_function_is_virtual(function_decl&, bool); 1767 1768 friend class class_or_union; 1769 friend class class_decl; 1770 friend class scope_decl; 1771 };// end class decl_base 1772 1773 bool 1774 operator==(const decl_base_sptr&, const decl_base_sptr&); 1775 1776 bool 1777 operator!=(const decl_base_sptr&, const decl_base_sptr&); 1778 1779 bool 1780 operator==(const type_base_sptr&, const type_base_sptr&); 1781 1782 bool 1783 operator!=(const type_base_sptr&, const type_base_sptr&); 1784 1785 std::ostream& 1786 operator<<(std::ostream&, decl_base::visibility); 1787 1788 std::ostream& 1789 operator<<(std::ostream&, decl_base::binding); 1790 1791 bool 1792 equals(const scope_decl&, const scope_decl&, change_kind*); 1793 1794 /// A declaration that introduces a scope. 1795 class scope_decl : public virtual decl_base 1796 { 1797 struct priv; 1798 std::unique_ptr<priv> priv_; 1799 1800 public: 1801 1802 /// Convenience typedef for a vector of @ref decl_base_sptr. 1803 typedef std::vector<decl_base_sptr > declarations; 1804 /// Convenience typedef for a vector of @ref function_type_sptr. 1805 typedef std::vector<function_type_sptr > function_types; 1806 /// Convenience typedef for a vector of @ref scope_decl_sptr. 1807 typedef std::vector<scope_decl_sptr> scopes; 1808 1809 scope_decl(); 1810 1811 protected: 1812 virtual decl_base_sptr 1813 add_member_decl(const decl_base_sptr& member); 1814 1815 decl_base_sptr 1816 insert_member_decl(decl_base_sptr member, declarations::iterator before); 1817 1818 virtual void 1819 remove_member_decl(decl_base_sptr member); 1820 1821 public: 1822 struct hash; 1823 1824 scope_decl(const environment& env, 1825 const string& name, const location& locus, 1826 visibility vis = VISIBILITY_DEFAULT); 1827 1828 scope_decl(const environment& env, location& l); 1829 1830 virtual size_t 1831 get_hash() const; 1832 1833 virtual bool 1834 operator==(const decl_base&) const; 1835 1836 const canonical_type_sptr_set_type& 1837 get_canonical_types() const; 1838 1839 canonical_type_sptr_set_type& 1840 get_canonical_types(); 1841 1842 const type_base_sptrs_type& 1843 get_sorted_canonical_types() const; 1844 1845 const declarations& 1846 get_member_decls() const; 1847 1848 declarations& 1849 get_member_decls(); 1850 1851 const declarations& 1852 get_sorted_member_decls() const; 1853 1854 virtual size_t 1855 get_num_anonymous_member_classes() const; 1856 1857 virtual size_t 1858 get_num_anonymous_member_unions() const; 1859 1860 virtual size_t 1861 get_num_anonymous_member_enums() const; 1862 1863 scopes& 1864 get_member_scopes(); 1865 1866 const scopes& 1867 get_member_scopes() const; 1868 1869 bool 1870 is_empty() const; 1871 1872 bool 1873 find_iterator_for_member(const decl_base*, declarations::iterator&); 1874 1875 bool 1876 find_iterator_for_member(const decl_base_sptr, declarations::iterator&); 1877 1878 void 1879 insert_member_type(type_base_sptr t, 1880 declarations::iterator before); 1881 1882 void 1883 add_member_type(type_base_sptr t); 1884 1885 type_base_sptr 1886 add_member_type(type_base_sptr t, access_specifier a); 1887 1888 void 1889 remove_member_type(type_base_sptr t); 1890 1891 const type_base_sptrs_type& 1892 get_member_types() const; 1893 1894 const type_base_sptrs_type& 1895 get_sorted_member_types() const; 1896 1897 type_base_sptr 1898 find_member_type(const string& name) const; 1899 1900 virtual bool 1901 traverse(ir_node_visitor&); 1902 1903 virtual ~scope_decl(); 1904 1905 friend decl_base_sptr 1906 add_decl_to_scope(decl_base_sptr decl, scope_decl* scope); 1907 1908 friend decl_base_sptr 1909 insert_decl_into_scope(decl_base_sptr decl, 1910 scope_decl::declarations::iterator before, 1911 scope_decl* scope); 1912 1913 friend void 1914 remove_decl_from_scope(decl_base_sptr decl); 1915 };//end class scope_decl 1916 1917 bool 1918 operator==(const scope_decl_sptr&, const scope_decl_sptr&); 1919 1920 bool 1921 operator!=(const scope_decl_sptr&, const scope_decl_sptr&); 1922 1923 /// Hasher for the @ref scope_decl type. 1924 struct scope_decl::hash 1925 { 1926 size_t 1927 operator()(const scope_decl& d) const; 1928 1929 size_t 1930 operator()(const scope_decl* d) const; 1931 }; 1932 1933 /// This abstracts the global scope of a given translation unit. 1934 /// 1935 /// Only one instance of this class must be present in a given 1936 /// translation_unit. That instance is implicitely created the first 1937 /// time translatin_unit::get_global_scope is invoked. 1938 class global_scope : public scope_decl 1939 { 1940 translation_unit* translation_unit_; 1941 1942 global_scope(translation_unit *tu); 1943 1944 public: 1945 1946 friend class translation_unit; 1947 1948 translation_unit* get_translation_unit()1949 get_translation_unit() const 1950 {return translation_unit_;} 1951 1952 virtual ~global_scope(); 1953 }; 1954 1955 bool 1956 equals(const type_base&, const type_base&, change_kind*); 1957 1958 /// An abstraction helper for type declarations 1959 class type_base : public virtual type_or_decl_base 1960 { 1961 struct priv; 1962 1963 public: 1964 // This priv pointer is not handled by a shared_ptr because 1965 // accessing the data members of the priv struct for this type_base 1966 // shows up on performance profiles when dealing with big binaries 1967 // with a lot of types; dereferencing the shared_ptr involves 1968 // locking of some sort and that is slower than just dereferencing a 1969 // pointer likere here. There are other types for which the priv 1970 // pointer is managed using shared_ptr just fine, because those 1971 // didn't show up during our performance profiling. 1972 priv* priv_; 1973 1974 private: 1975 // Forbid this. 1976 type_base(); 1977 1978 static type_base_sptr 1979 get_canonical_type_for(type_base_sptr); 1980 1981 protected: 1982 virtual void 1983 on_canonical_type_set(); 1984 1985 public: 1986 1987 /// A hasher for type_base types. 1988 struct hash; 1989 1990 /// A hasher for types. It gets the dynamic type of the current 1991 /// instance of type and hashes it accordingly. Note that the hashing 1992 /// function of this hasher must be updated each time a new kind of 1993 /// type is added to the IR. 1994 struct dynamic_hash; 1995 1996 /// A hasher for shared_ptr<type_base> that will hash it based on the 1997 /// runtime type of the type pointed to. 1998 struct shared_ptr_hash; 1999 2000 type_base(const environment& e, size_t s, size_t a); 2001 2002 friend type_base_sptr canonicalize(type_base_sptr); 2003 2004 type_base_sptr 2005 get_canonical_type() const; 2006 2007 type_base* 2008 get_naked_canonical_type() const; 2009 2010 const interned_string& 2011 get_cached_pretty_representation(bool internal = false) const; 2012 2013 virtual bool 2014 operator==(const type_base&) const; 2015 2016 virtual bool 2017 operator!=(const type_base&) const; 2018 2019 virtual bool 2020 traverse(ir_node_visitor&); 2021 2022 virtual ~type_base(); 2023 2024 virtual void 2025 set_size_in_bits(size_t); 2026 2027 virtual size_t 2028 get_size_in_bits() const; 2029 2030 virtual void 2031 set_alignment_in_bits(size_t); 2032 2033 virtual size_t 2034 get_alignment_in_bits() const; 2035 };//end class type_base 2036 2037 /// Hash functor for instances of @ref type_base. 2038 struct type_base::hash 2039 { 2040 size_t 2041 operator()(const type_base& t) const; 2042 2043 size_t 2044 operator()(const type_base* t) const; 2045 2046 size_t 2047 operator()(const type_base_sptr t) const; 2048 }; // end struct type_base::hash 2049 2050 /// A predicate for deep equality of instances of 2051 /// type_base* 2052 struct type_ptr_equal 2053 { 2054 bool operatortype_ptr_equal2055 operator()(const type_base* l, const type_base* r) const 2056 { 2057 if (!!l != !!r) 2058 return false; 2059 2060 if (l == r) 2061 return true; 2062 2063 if (l) 2064 return *l == *r; 2065 2066 return true; 2067 } 2068 }; 2069 2070 /// A predicate for deep equality of instances of 2071 /// shared_ptr<type_base> 2072 struct type_shared_ptr_equal 2073 { 2074 bool operatortype_shared_ptr_equal2075 operator()(const type_base_sptr l, const type_base_sptr r) const 2076 { 2077 if (!!l != !!r) 2078 return false; 2079 2080 if (l.get() == r.get()) 2081 return true; 2082 2083 if (l) 2084 return *l == *r; 2085 2086 return true; 2087 } 2088 }; 2089 2090 bool 2091 equals(const type_decl&, const type_decl&, change_kind*); 2092 2093 /// A basic type declaration that introduces no scope. 2094 class type_decl : public virtual decl_base, public virtual type_base 2095 { 2096 // Forbidden. 2097 type_decl(); 2098 2099 public: 2100 2101 /// Facility to hash instance of type_decl 2102 struct hash; 2103 2104 type_decl(const environment& env, 2105 const string& name, 2106 size_t size_in_bits, 2107 size_t alignment_in_bits, 2108 const location& locus, 2109 const string& mangled_name = "", 2110 visibility vis = VISIBILITY_DEFAULT); 2111 2112 virtual bool 2113 operator==(const type_base&) const; 2114 2115 virtual bool 2116 operator==(const decl_base&) const; 2117 2118 virtual bool 2119 operator==(const type_decl&) const; 2120 2121 virtual bool 2122 operator!=(const type_base&)const; 2123 2124 virtual bool 2125 operator!=(const decl_base&)const; 2126 2127 virtual bool 2128 operator!=(const type_decl&)const; 2129 2130 virtual void 2131 get_qualified_name(interned_string& qualified_name, 2132 bool internal = false) const; 2133 2134 virtual const interned_string& 2135 get_qualified_name(bool internal = false) const; 2136 2137 virtual string 2138 get_pretty_representation(bool internal = false, 2139 bool qualified_name = true) const; 2140 2141 virtual bool 2142 traverse(ir_node_visitor&); 2143 2144 virtual ~type_decl(); 2145 };// end class type_decl. 2146 2147 bool 2148 equals(const scope_type_decl&, const scope_type_decl&, change_kind*); 2149 2150 bool 2151 operator==(const type_decl_sptr&, const type_decl_sptr&); 2152 2153 bool 2154 operator!=(const type_decl_sptr&, const type_decl_sptr&); 2155 2156 /// A type that introduces a scope. 2157 class scope_type_decl : public scope_decl, public virtual type_base 2158 { 2159 scope_type_decl(); 2160 2161 public: 2162 2163 /// Hasher for instances of scope_type_decl 2164 struct hash; 2165 2166 scope_type_decl(const environment& env, const string& name, 2167 size_t size_in_bits, size_t alignment_in_bits, 2168 const location& locus, visibility vis = VISIBILITY_DEFAULT); 2169 2170 virtual bool 2171 operator==(const decl_base&) const; 2172 2173 virtual bool 2174 operator==(const type_base&) const; 2175 2176 virtual bool 2177 traverse(ir_node_visitor&); 2178 2179 virtual ~scope_type_decl(); 2180 }; 2181 2182 /// The abstraction of a namespace declaration 2183 class namespace_decl : public scope_decl 2184 { 2185 public: 2186 2187 namespace_decl(const environment& env, const string& name, 2188 const location& locus, visibility vis = VISIBILITY_DEFAULT); 2189 2190 virtual string 2191 get_pretty_representation(bool internal = false, 2192 bool qualified_name = true) const; 2193 2194 virtual bool 2195 operator==(const decl_base&) const; 2196 2197 virtual bool 2198 traverse(ir_node_visitor&); 2199 2200 virtual ~namespace_decl(); 2201 2202 bool is_empty_or_has_empty_sub_namespaces() const; 2203 };// end class namespace_decl 2204 2205 /// A convenience typedef for vectors of @ref namespace_decl_sptr 2206 typedef vector<namespace_decl_sptr> namespaces_type; 2207 2208 bool 2209 equals(const qualified_type_def&, const qualified_type_def&, change_kind*); 2210 2211 /// The abstraction of a qualified type. 2212 class qualified_type_def : public virtual type_base, public virtual decl_base 2213 { 2214 class priv; 2215 std::unique_ptr<priv> priv_; 2216 2217 // Forbidden. 2218 qualified_type_def(); 2219 2220 protected: 2221 string build_name(bool, bool internal = false) const; 2222 virtual void on_canonical_type_set(); 2223 2224 public: 2225 2226 /// A Hasher for instances of qualified_type_def 2227 struct hash; 2228 2229 /// Bit field values representing the cv qualifiers of the 2230 /// underlying type. 2231 enum CV 2232 { 2233 CV_NONE = 0, 2234 CV_CONST = 1, 2235 CV_VOLATILE = 1 << 1, 2236 CV_RESTRICT = 1 << 2 2237 }; 2238 2239 qualified_type_def(type_base_sptr type, CV quals, const location& locus); 2240 2241 qualified_type_def(const environment& env, CV quals, const location& locus); 2242 2243 virtual size_t 2244 get_size_in_bits() const; 2245 2246 virtual bool 2247 operator==(const decl_base&) const; 2248 2249 virtual bool 2250 operator==(const type_base&) const; 2251 2252 virtual bool 2253 operator==(const qualified_type_def&) const; 2254 2255 CV 2256 get_cv_quals() const; 2257 2258 void 2259 set_cv_quals(CV cv_quals); 2260 2261 string 2262 get_cv_quals_string_prefix() const; 2263 2264 type_base_sptr 2265 get_underlying_type() const; 2266 2267 void 2268 set_underlying_type(const type_base_sptr&); 2269 2270 virtual void 2271 get_qualified_name(interned_string& qualified_name, 2272 bool internal = false) const; 2273 2274 virtual const interned_string& 2275 get_qualified_name(bool internal = false) const; 2276 2277 virtual bool 2278 traverse(ir_node_visitor& v); 2279 2280 virtual ~qualified_type_def(); 2281 }; // end class qualified_type_def. 2282 2283 bool 2284 operator==(const qualified_type_def_sptr&, const qualified_type_def_sptr&); 2285 2286 bool 2287 operator!=(const qualified_type_def_sptr&, const qualified_type_def_sptr&); 2288 2289 qualified_type_def::CV 2290 operator|(qualified_type_def::CV, qualified_type_def::CV); 2291 2292 qualified_type_def::CV& 2293 operator|=(qualified_type_def::CV&, qualified_type_def::CV); 2294 2295 qualified_type_def::CV& 2296 operator&=(qualified_type_def::CV&, qualified_type_def::CV); 2297 2298 qualified_type_def::CV 2299 operator&(qualified_type_def::CV, qualified_type_def::CV); 2300 2301 qualified_type_def::CV 2302 operator~(qualified_type_def::CV); 2303 2304 std::ostream& 2305 operator<<(std::ostream&, qualified_type_def::CV); 2306 2307 string 2308 get_string_representation_of_cv_quals(const qualified_type_def::CV); 2309 2310 interned_string 2311 get_name_of_qualified_type(const type_base_sptr& underlying_type, 2312 qualified_type_def::CV quals, 2313 bool qualified = true, bool internal = false); 2314 2315 qualified_type_def_sptr 2316 lookup_qualified_type(const type_base_sptr&, 2317 qualified_type_def::CV, 2318 const translation_unit&); 2319 bool 2320 equals(const pointer_type_def&, const pointer_type_def&, change_kind*); 2321 2322 /// The abstraction of a pointer type. 2323 class pointer_type_def : public virtual type_base, public virtual decl_base 2324 { 2325 struct priv; 2326 std::unique_ptr<priv> priv_; 2327 2328 // Forbidden. 2329 pointer_type_def(); 2330 2331 protected: 2332 virtual void on_canonical_type_set(); 2333 2334 public: 2335 2336 /// A hasher for instances of pointer_type_def 2337 struct hash; 2338 2339 pointer_type_def(const type_base_sptr& pointed_to_type, size_t size_in_bits, 2340 size_t alignment_in_bits, const location& locus); 2341 2342 pointer_type_def(const environment& env, size_t size_in_bits, 2343 size_t alignment_in_bits, const location& locus); 2344 2345 void 2346 set_pointed_to_type(const type_base_sptr&); 2347 2348 virtual bool 2349 operator==(const decl_base&) const; 2350 2351 virtual bool 2352 operator==(const type_base&) const; 2353 2354 bool 2355 operator==(const pointer_type_def&) const; 2356 2357 const type_base_sptr 2358 get_pointed_to_type() const; 2359 2360 type_base* 2361 get_naked_pointed_to_type() const; 2362 2363 virtual void 2364 get_qualified_name(interned_string&, bool internal = false) const; 2365 2366 virtual const interned_string& 2367 get_qualified_name(bool internal = false) const; 2368 2369 virtual bool 2370 traverse(ir_node_visitor& v); 2371 2372 virtual ~pointer_type_def(); 2373 }; // end class pointer_type_def 2374 2375 bool 2376 operator==(const pointer_type_def_sptr&, const pointer_type_def_sptr&); 2377 2378 bool 2379 operator!=(const pointer_type_def_sptr&, const pointer_type_def_sptr&); 2380 2381 bool 2382 equals(const reference_type_def&, const reference_type_def&, change_kind*); 2383 2384 2385 /// Abstracts a reference type. 2386 class reference_type_def : public virtual type_base, public virtual decl_base 2387 { 2388 struct priv; 2389 std::unique_ptr<priv> priv_; 2390 2391 // Forbidden. 2392 reference_type_def(); 2393 2394 protected: 2395 virtual void on_canonical_type_set(); 2396 2397 public: 2398 2399 /// Hasher for intances of reference_type_def. 2400 struct hash; 2401 2402 reference_type_def(const type_base_sptr pointed_to_type, 2403 bool lvalue, size_t size_in_bits, 2404 size_t alignment_in_bits, const location& locus); 2405 2406 reference_type_def(const environment& env, bool lvalue, size_t size_in_bits, 2407 size_t alignment_in_bits, const location& locus); 2408 2409 void 2410 set_pointed_to_type(type_base_sptr& pointed_to_type); 2411 2412 virtual bool 2413 operator==(const decl_base&) const; 2414 2415 virtual bool 2416 operator==(const type_base&) const; 2417 2418 bool 2419 operator==(const reference_type_def&) const; 2420 2421 type_base_sptr 2422 get_pointed_to_type() const; 2423 2424 bool 2425 is_lvalue() const; 2426 2427 virtual void 2428 get_qualified_name(interned_string& qualified_name, 2429 bool internal = false) const; 2430 2431 virtual const interned_string& 2432 get_qualified_name(bool internal = false) const; 2433 2434 virtual string 2435 get_pretty_representation(bool internal = false, 2436 bool qualified_name = true) const; 2437 2438 virtual bool 2439 traverse(ir_node_visitor& v); 2440 2441 virtual ~reference_type_def(); 2442 }; // end class reference_type_def 2443 2444 bool 2445 operator==(const reference_type_def_sptr&, const reference_type_def_sptr&); 2446 2447 bool 2448 operator!=(const reference_type_def_sptr&, const reference_type_def_sptr&); 2449 2450 bool 2451 equals(const array_type_def&, const array_type_def&, change_kind*); 2452 2453 /// The abstraction of an array type. 2454 class array_type_def : public virtual type_base, public virtual decl_base 2455 { 2456 struct priv; 2457 std::unique_ptr<priv> priv_; 2458 2459 // Forbidden. 2460 array_type_def(); 2461 2462 void update_size(); 2463 2464 public: 2465 2466 /// Hasher for intances of array_type_def. 2467 struct hash; 2468 2469 class subrange_type; 2470 2471 /// Convenience typedef for a shared pointer on a @ref 2472 /// function_decl::subrange 2473 typedef shared_ptr<subrange_type> subrange_sptr; 2474 2475 /// Convenience typedef for a vector of @ref subrange_sptr 2476 typedef std::vector<subrange_sptr> subranges_type; 2477 2478 /// Abstraction for an array range type, like in Ada, or just for an 2479 /// array dimension like in C or C++. 2480 class subrange_type : public virtual type_base, public virtual decl_base 2481 { 2482 struct priv; 2483 std::unique_ptr<priv> priv_; 2484 2485 // Forbidden. 2486 subrange_type(); 2487 public: 2488 2489 virtual ~subrange_type(); 2490 /// This class is to hold the value of the bound of a subrange. 2491 /// The value can be either signed or unsigned, at least when it 2492 /// comes from DWARF. The class keeps the sign information, but 2493 /// allows users to access the value as signed or unsigned as they 2494 /// see fit. 2495 class bound_value 2496 { 2497 public: 2498 enum signedness 2499 { 2500 UNSIGNED_SIGNEDNESS, 2501 SIGNED_SIGNEDNESS 2502 }; 2503 2504 private: 2505 signedness s_; 2506 2507 public: 2508 union 2509 { 2510 uint64_t unsigned_; 2511 int64_t signed_; 2512 } v_; 2513 bound_value(); 2514 bound_value(uint64_t); 2515 bound_value(int64_t); 2516 enum signedness get_signedness() const; 2517 void set_signedness(enum signedness s); 2518 int64_t get_signed_value() const; 2519 uint64_t get_unsigned_value(); 2520 void set_unsigned(uint64_t v); 2521 void set_signed(int64_t v); 2522 bool operator==(const bound_value&) const; 2523 }; //end class bound_value 2524 2525 /// Hasher for an instance of array::subrange 2526 struct hash; 2527 2528 subrange_type(const environment& env, 2529 const string& name, 2530 bound_value lower_bound, 2531 bound_value upper_bound, 2532 const type_base_sptr& underlying_type, 2533 const location& loc, 2534 translation_unit::language l = translation_unit::LANG_C11); 2535 2536 subrange_type(const environment& env, 2537 const string& name, 2538 bound_value lower_bound, 2539 bound_value upper_bound, 2540 const location& loc, 2541 translation_unit::language l = translation_unit::LANG_C11); 2542 2543 subrange_type(const environment& env, 2544 const string& name, 2545 bound_value upper_bound, 2546 const location& loc, 2547 translation_unit::language l = translation_unit::LANG_C11); 2548 2549 type_base_sptr 2550 get_underlying_type() const; 2551 2552 void 2553 set_underlying_type(const type_base_sptr &); 2554 2555 int64_t 2556 get_upper_bound() const; 2557 2558 int64_t 2559 get_lower_bound() const; 2560 2561 void 2562 set_upper_bound(int64_t ub); 2563 2564 void 2565 set_lower_bound(int64_t lb); 2566 2567 uint64_t 2568 get_length() const; 2569 2570 bool 2571 is_infinite() const; 2572 2573 void 2574 is_infinite(bool); 2575 2576 translation_unit::language 2577 get_language() const; 2578 2579 virtual bool 2580 operator==(const decl_base&) const; 2581 2582 virtual bool 2583 operator==(const type_base&) const; 2584 2585 bool 2586 operator==(const subrange_type& o) const; 2587 2588 bool 2589 operator!=(const decl_base& o) const; 2590 2591 bool 2592 operator!=(const type_base& o) const; 2593 2594 bool 2595 operator!=(const subrange_type& o) const; 2596 2597 string 2598 as_string() const; 2599 2600 static string 2601 vector_as_string(const vector<subrange_sptr>&); 2602 2603 virtual string 2604 get_pretty_representation(bool internal = false, 2605 bool qualified_name = true) const; 2606 2607 virtual bool 2608 traverse(ir_node_visitor&); 2609 }; // end class subrange_type 2610 2611 array_type_def(const type_base_sptr type, 2612 const std::vector<subrange_sptr>& subs, 2613 const location& locus); 2614 2615 array_type_def(const environment& env, 2616 const std::vector<subrange_sptr>& subs, 2617 const location& locus); 2618 2619 translation_unit::language 2620 get_language() const; 2621 2622 virtual bool 2623 operator==(const decl_base&) const; 2624 2625 virtual bool 2626 operator==(const type_base&) const; 2627 2628 virtual void 2629 get_qualified_name(interned_string& qualified_name, 2630 bool internal = false) const; 2631 2632 virtual const interned_string& 2633 get_qualified_name(bool internal = false) const; 2634 2635 const type_base_sptr 2636 get_element_type() const; 2637 2638 void 2639 set_element_type(const type_base_sptr& element_type); 2640 2641 virtual void 2642 append_subranges(const std::vector<subrange_sptr>& subs); 2643 2644 virtual int 2645 get_dimension_count() const; 2646 2647 virtual bool 2648 is_infinite() const; 2649 2650 virtual string 2651 get_pretty_representation(bool internal = false, 2652 bool qualified_name = true) const; 2653 2654 virtual string 2655 get_subrange_representation() const; 2656 2657 virtual bool 2658 traverse(ir_node_visitor& v); 2659 2660 const location& 2661 get_location() const; 2662 2663 const std::vector<subrange_sptr>& 2664 get_subranges() const; 2665 2666 virtual ~array_type_def(); 2667 2668 }; // end class array_type_def 2669 2670 array_type_def::subrange_type* 2671 is_subrange_type(const type_or_decl_base *type); 2672 2673 array_type_def::subrange_sptr 2674 is_subrange_type(const type_or_decl_base_sptr &type); 2675 2676 bool 2677 equals(const array_type_def::subrange_type&, 2678 const array_type_def::subrange_type&, 2679 change_kind*); 2680 2681 bool 2682 equals(const enum_type_decl&, const enum_type_decl&, change_kind*); 2683 2684 /// Abstracts a declaration for an enum type. 2685 class enum_type_decl : public virtual type_base, public virtual decl_base 2686 { 2687 class priv; 2688 std::unique_ptr<priv> priv_; 2689 2690 // Forbidden 2691 enum_type_decl(); 2692 2693 public: 2694 2695 /// A hasher for an enum_type_decl. 2696 struct hash; 2697 2698 /// Enumerator Datum. 2699 class enumerator; 2700 2701 /// Convenience typedef for a list of @ref enumerator. 2702 typedef std::vector<enumerator> enumerators; 2703 2704 /// Constructor of an enum type declaration. 2705 /// 2706 /// @param name the name of the enum 2707 /// 2708 /// @param locus the locus at which the enum appears in the source 2709 /// code. 2710 /// 2711 /// @param underlying_type the underlying type of the enum 2712 /// 2713 /// @param enms a list of enumerators for this enum. 2714 /// 2715 /// @param mangled_name the mangled name of the enum type. 2716 /// 2717 /// @param vis the visibility of instances of this type. 2718 enum_type_decl(const string& name, 2719 const location& locus, 2720 type_base_sptr underlying_type, 2721 enumerators& enms, 2722 const string& mangled_name = "", 2723 visibility vis = VISIBILITY_DEFAULT); 2724 2725 type_base_sptr 2726 get_underlying_type() const; 2727 2728 const enumerators& 2729 get_enumerators() const; 2730 2731 const enumerators& 2732 get_sorted_enumerators() const; 2733 2734 enumerators& 2735 get_enumerators(); 2736 2737 virtual string 2738 get_pretty_representation(bool internal = false, 2739 bool qualified_name = true) const; 2740 2741 virtual bool 2742 operator==(const decl_base&) const; 2743 2744 virtual bool 2745 operator==(const type_base&) const; 2746 2747 virtual bool 2748 traverse(ir_node_visitor& v); 2749 2750 virtual ~enum_type_decl(); 2751 2752 friend bool 2753 enum_has_non_name_change(const enum_type_decl& l, 2754 const enum_type_decl& r, 2755 change_kind* k); 2756 }; // end class enum_type_decl 2757 2758 bool 2759 operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r); 2760 2761 bool 2762 operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r); 2763 2764 bool 2765 enum_has_non_name_change(const enum_type_decl& l, 2766 const enum_type_decl& r, 2767 change_kind* k); 2768 2769 /// The abstraction of an enumerator 2770 class enum_type_decl::enumerator 2771 { 2772 class priv; 2773 std::unique_ptr<priv> priv_; 2774 2775 public: 2776 2777 enumerator(); 2778 2779 ~enumerator(); 2780 2781 enumerator(const string& name, int64_t value); 2782 2783 enumerator(const enumerator&); 2784 2785 enumerator& 2786 operator=(const enumerator&); 2787 2788 bool 2789 operator==(const enumerator& other) const; 2790 2791 bool 2792 operator!=(const enumerator& other) const; 2793 2794 const string& 2795 get_name() const; 2796 2797 const string& 2798 get_qualified_name(bool internal = false) const; 2799 2800 void 2801 set_name(const string& n); 2802 2803 int64_t 2804 get_value() const; 2805 2806 void 2807 set_value(int64_t v); 2808 2809 enum_type_decl* 2810 get_enum_type() const; 2811 2812 void 2813 set_enum_type(enum_type_decl*); 2814 }; // end class enum_type_def::enumerator 2815 2816 bool 2817 is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr, 2818 const enum_type_decl &enom); 2819 2820 bool 2821 equals(const typedef_decl&, const typedef_decl&, change_kind*); 2822 2823 /// The abstraction of a typedef declaration. 2824 class typedef_decl : public virtual type_base, public virtual decl_base 2825 { 2826 struct priv; 2827 std::unique_ptr<priv> priv_; 2828 2829 // Forbidden 2830 typedef_decl(); 2831 2832 public: 2833 2834 /// Hasher for the typedef_decl type. 2835 struct hash; 2836 2837 typedef_decl(const string& name, 2838 const type_base_sptr underlying_type, 2839 const location& locus, 2840 const string& mangled_name = "", 2841 visibility vis = VISIBILITY_DEFAULT); 2842 2843 typedef_decl(const string& name, 2844 const environment& env, 2845 const location& locus, 2846 const string& mangled_name = "", 2847 visibility vis = VISIBILITY_DEFAULT); 2848 2849 virtual size_t 2850 get_size_in_bits() const; 2851 2852 virtual size_t 2853 get_alignment_in_bits() const; 2854 2855 virtual bool 2856 operator==(const decl_base&) const; 2857 2858 virtual bool 2859 operator==(const type_base&) const; 2860 2861 virtual string 2862 get_pretty_representation(bool internal = false, 2863 bool qualified_name = true) const; 2864 2865 type_base_sptr 2866 get_underlying_type() const; 2867 2868 void 2869 set_underlying_type(const type_base_sptr&); 2870 2871 virtual void 2872 get_qualified_name(interned_string& qualified_name, 2873 bool internal = false) const; 2874 2875 virtual const interned_string& 2876 get_qualified_name(bool internal = false) const; 2877 2878 virtual bool 2879 traverse(ir_node_visitor&); 2880 2881 virtual ~typedef_decl(); 2882 };// end class typedef_decl 2883 2884 /// The abstraction for a data member context relationship. This 2885 /// relates a data member to its parent class. 2886 /// 2887 /// The relationship carries properties like the offset of the data 2888 /// member, if applicable. 2889 class dm_context_rel : public context_rel 2890 { 2891 protected: 2892 struct priv; 2893 std::unique_ptr<priv> priv_; 2894 2895 public: 2896 dm_context_rel(); 2897 2898 dm_context_rel(scope_decl* s, 2899 bool is_laid_out, 2900 size_t offset_in_bits, 2901 access_specifier a, 2902 bool is_static); 2903 2904 dm_context_rel(scope_decl* s); 2905 2906 bool 2907 get_is_laid_out() const; 2908 2909 void 2910 set_is_laid_out(bool f); 2911 2912 size_t 2913 get_offset_in_bits() const; 2914 2915 void 2916 set_offset_in_bits(size_t o); 2917 2918 const var_decl* 2919 get_anonymous_data_member() const; 2920 2921 void 2922 set_anonymous_data_member(var_decl *); 2923 2924 bool 2925 operator==(const dm_context_rel& o) const; 2926 2927 bool 2928 operator!=(const dm_context_rel& o) const; 2929 2930 virtual ~dm_context_rel(); 2931 };// end class class_decl::dm_context_rel 2932 2933 bool 2934 equals(const var_decl&, const var_decl&, change_kind*); 2935 2936 bool 2937 var_equals_modulo_types(const var_decl&, const var_decl&, change_kind*); 2938 2939 bool 2940 equals_modulo_cv_qualifier(const array_type_def*, const array_type_def*); 2941 2942 /// Abstracts a variable declaration. 2943 class var_decl : public virtual decl_base 2944 { 2945 struct priv; 2946 std::unique_ptr<priv> priv_; 2947 2948 // Forbidden 2949 var_decl(); 2950 2951 virtual void 2952 set_scope(scope_decl*); 2953 2954 public: 2955 2956 /// Hasher for a var_decl type. 2957 struct hash; 2958 2959 /// Equality functor to compare pointers to variable_decl. 2960 struct ptr_equal; 2961 2962 var_decl(const string& name, 2963 type_base_sptr type, 2964 const location& locus, 2965 const string& mangled_name, 2966 visibility vis = VISIBILITY_DEFAULT, 2967 binding bind = BINDING_NONE); 2968 2969 virtual bool 2970 operator==(const decl_base&) const; 2971 2972 const type_base_sptr 2973 get_type() const; 2974 2975 void 2976 set_type(type_base_sptr&); 2977 2978 const type_base* 2979 get_naked_type() const; 2980 2981 binding 2982 get_binding() const; 2983 2984 void 2985 set_binding(binding b); 2986 2987 void 2988 set_symbol(const elf_symbol_sptr& sym); 2989 2990 const elf_symbol_sptr& 2991 get_symbol() const; 2992 2993 var_decl_sptr 2994 clone() const; 2995 2996 interned_string 2997 get_id() const; 2998 2999 virtual const interned_string& 3000 get_qualified_name(bool internal = false) const; 3001 3002 virtual size_t 3003 get_hash() const; 3004 3005 virtual string 3006 get_pretty_representation(bool internal = false, 3007 bool qualified_name = true) const; 3008 3009 string 3010 get_anon_dm_reliable_name(bool qualified = true) const; 3011 3012 virtual bool 3013 traverse(ir_node_visitor& v); 3014 3015 virtual ~var_decl(); 3016 3017 friend void 3018 set_data_member_offset(var_decl_sptr m, uint64_t o); 3019 3020 friend uint64_t 3021 get_data_member_offset(const var_decl_sptr m); 3022 3023 friend uint64_t 3024 get_data_member_offset(const var_decl& m); 3025 3026 friend uint64_t 3027 get_absolute_data_member_offset(const var_decl& m); 3028 3029 friend uint64_t 3030 get_absolute_data_member_offset(const var_decl_sptr& m); 3031 3032 friend void 3033 set_data_member_is_laid_out(var_decl_sptr m, bool l); 3034 3035 friend bool 3036 get_data_member_is_laid_out(const var_decl& m); 3037 3038 friend bool 3039 get_data_member_is_laid_out(const var_decl_sptr m); 3040 }; // end class var_decl 3041 3042 bool 3043 equals(const function_decl&, const function_decl&, change_kind*); 3044 3045 /// Abstraction for a function declaration. 3046 class function_decl : public virtual decl_base 3047 { 3048 struct priv; 3049 // This priv pointer is not handled by a shared_ptr because 3050 // accessing the data members of the priv struct for this 3051 // function_decl shows up on performance profiles when dealing with 3052 // big binaries with a lot of types; dereferencing the shared_ptr 3053 // involves locking of some sort and that is slower than just 3054 // dereferencing a pointer likere here. There are other types for 3055 // which the priv pointer is managed using shared_ptr just fine, 3056 // because those didn't show up during our performance profiling. 3057 priv* priv_; 3058 3059 public: 3060 /// Hasher for function_decl 3061 struct hash; 3062 3063 /// Equality functor to compare pointers to function_decl 3064 struct ptr_equal; 3065 3066 /// Abstraction for the parameter of a function. 3067 class parameter; 3068 3069 /// Convenience typedef for a shared pointer on a @ref 3070 /// function_decl::parameter 3071 typedef shared_ptr<parameter> parameter_sptr; 3072 3073 /// Convenience typedef for a vector of @ref parameter_sptr 3074 typedef std::vector<parameter_sptr> parameters; 3075 3076 function_decl(const string& name, 3077 function_type_sptr function_type, 3078 bool declared_inline, 3079 const location& locus, 3080 const string& mangled_name, 3081 visibility vis, 3082 binding bind); 3083 3084 function_decl(const string& name, 3085 type_base_sptr fn_type, 3086 bool declared_inline, 3087 const location& locus, 3088 const string& mangled_name = "", 3089 visibility vis = VISIBILITY_DEFAULT, 3090 binding bind = BINDING_GLOBAL); 3091 3092 virtual string 3093 get_pretty_representation(bool internal = false, 3094 bool qualified_name = true) const; 3095 3096 string 3097 get_pretty_representation_of_declarator (bool internal = false) const; 3098 3099 const std::vector<parameter_sptr >& 3100 get_parameters() const; 3101 3102 void 3103 append_parameter(parameter_sptr parm); 3104 3105 void 3106 append_parameters(std::vector<parameter_sptr >& parms); 3107 3108 parameters::const_iterator 3109 get_first_non_implicit_parm() const; 3110 3111 const function_type_sptr 3112 get_type() const; 3113 3114 const function_type* 3115 get_naked_type() const; 3116 3117 const type_base_sptr 3118 get_return_type() const; 3119 3120 void 3121 set_type(const function_type_sptr& fn_type); 3122 3123 void 3124 set_symbol(const elf_symbol_sptr& sym); 3125 3126 const elf_symbol_sptr& 3127 get_symbol() const; 3128 3129 bool 3130 is_declared_inline() const; 3131 3132 binding 3133 get_binding() const; 3134 3135 function_decl_sptr 3136 clone() const; 3137 3138 virtual bool 3139 operator==(const decl_base& o) const; 3140 3141 /// Return true iff the function takes a variable number of 3142 /// parameters. 3143 /// 3144 /// @return true if the function taks a variable number 3145 /// of parameters. 3146 bool 3147 is_variadic() const; 3148 3149 virtual size_t 3150 get_hash() const; 3151 3152 interned_string 3153 get_id() const; 3154 3155 virtual bool 3156 traverse(ir_node_visitor&); 3157 3158 virtual ~function_decl(); 3159 }; // end class function_decl 3160 3161 bool 3162 operator==(const function_decl_sptr& l, const function_decl_sptr& r); 3163 3164 bool 3165 operator!=(const function_decl_sptr& l, const function_decl_sptr& r); 3166 3167 bool 3168 function_decls_alias(const function_decl& f1, const function_decl& f2); 3169 3170 bool 3171 equals(const function_decl::parameter&, 3172 const function_decl::parameter&, 3173 change_kind*); 3174 3175 /// A comparison functor to compare pointer to instances of @ref 3176 /// type_or_decl_base. 3177 struct type_or_decl_base_comp 3178 { 3179 /// Comparison operator for ABI artifacts. 3180 /// 3181 /// @param f the first ABI artifact to consider for the comparison. 3182 /// 3183 /// @param s the second ABI artifact to consider for the comparison. 3184 /// 3185 /// @return true iff @p f is lexicographically less than than @p s. 3186 bool operatortype_or_decl_base_comp3187 operator()(const type_or_decl_base *f, 3188 const type_or_decl_base *s) 3189 { 3190 function_decl *f_fn = is_function_decl(f), *s_fn = is_function_decl(s); 3191 if (f_fn && s_fn) 3192 return function_decl_is_less_than(*f_fn, *s_fn); 3193 3194 var_decl *f_var = is_var_decl(f), *s_var = is_var_decl(s); 3195 if (f_var && s_var) 3196 return get_name(f_var) < get_name(s_var); 3197 3198 string l_repr = get_pretty_representation(f), 3199 r_repr = get_pretty_representation(s); 3200 3201 return l_repr < r_repr; 3202 } 3203 3204 /// Comparison operator for ABI artifacts. 3205 /// 3206 /// @param f the first ABI artifact to consider for the comparison. 3207 /// 3208 /// @param s the second ABI artifact to consider for the comparison. 3209 /// 3210 /// @return true iff @p f is lexicographically less than than @p s. 3211 bool operatortype_or_decl_base_comp3212 operator()(const type_or_decl_base_sptr& f, 3213 const type_or_decl_base_sptr& s) 3214 {return operator()(f.get(), s.get());} 3215 }; // end struct type_or_decl_base_comp 3216 3217 /// Abstraction of a function parameter. 3218 class function_decl::parameter : public decl_base 3219 { 3220 struct priv; 3221 std::unique_ptr<priv> priv_; 3222 3223 public: 3224 3225 /// Hasher for an instance of function::parameter 3226 struct hash; 3227 3228 parameter(const type_base_sptr type, 3229 unsigned index, 3230 const string& name, 3231 const location& loc, 3232 bool variadic_marker = false); 3233 3234 parameter(const type_base_sptr type, 3235 unsigned index, 3236 const string& name, 3237 const location& loc, 3238 bool variadic_marker, 3239 bool is_artificial); 3240 3241 parameter(const type_base_sptr type, 3242 const string& name, 3243 const location& loc, 3244 bool variadic_marker = false, 3245 bool is_artificial = false); 3246 3247 parameter(const type_base_sptr type, 3248 unsigned index = 0, 3249 bool variadic_marker = false); 3250 3251 virtual ~parameter(); 3252 3253 const type_base_sptr 3254 get_type()const; 3255 3256 interned_string 3257 get_type_name() const; 3258 3259 const string 3260 get_type_pretty_representation() const; 3261 3262 interned_string 3263 get_name_id() const; 3264 3265 unsigned 3266 get_index() const; 3267 3268 void 3269 set_index(unsigned i); 3270 3271 bool 3272 get_variadic_marker() const; 3273 3274 bool 3275 operator==(const parameter& o) const; 3276 3277 virtual bool 3278 operator==(const decl_base&) const; 3279 3280 virtual bool 3281 traverse(ir_node_visitor& v); 3282 3283 virtual size_t 3284 get_hash() const; 3285 3286 virtual void 3287 get_qualified_name(interned_string& qualified_name, 3288 bool internal = false) const; 3289 3290 virtual string 3291 get_pretty_representation(bool internal = false, 3292 bool qualified_name = true) const; 3293 }; // end class function_decl::parameter 3294 3295 bool 3296 operator==(const function_decl::parameter_sptr&, 3297 const function_decl::parameter_sptr&); 3298 3299 /// A hashing functor for a function_decl::parameter. 3300 struct function_decl::parameter::hash 3301 { 3302 size_t 3303 operator()(const function_decl::parameter&) const; 3304 3305 size_t 3306 operator()(const function_decl::parameter*) const; 3307 3308 size_t 3309 operator()(const function_decl::parameter_sptr) const; 3310 }; // end struct function_decl::parameter::hash 3311 3312 function_decl::parameter* 3313 is_function_parameter(const type_or_decl_base*); 3314 3315 function_decl::parameter_sptr 3316 is_function_parameter(const type_or_decl_base_sptr tod); 3317 3318 bool 3319 equals(const function_type&, const function_type&, change_kind*); 3320 3321 /// Abstraction of a function type. 3322 class function_type : public virtual type_base 3323 { 3324 protected: 3325 virtual void on_canonical_type_set(); 3326 3327 public: 3328 /// Hasher for an instance of function_type 3329 struct hash; 3330 3331 /// Convenience typedef for a shared pointer on a @ref 3332 /// function_decl::parameter 3333 typedef shared_ptr<function_decl::parameter> parameter_sptr; 3334 /// Convenience typedef for a vector of @ref parameter_sptr 3335 typedef std::vector<parameter_sptr> parameters; 3336 3337 struct priv; 3338 std::unique_ptr<priv> priv_; 3339 3340 private: 3341 function_type(); 3342 3343 public: 3344 3345 function_type(type_base_sptr return_type, 3346 const parameters& parms, 3347 size_t size_in_bits, 3348 size_t alignment_in_bits); 3349 3350 function_type(type_base_sptr return_type, 3351 size_t size_in_bits, 3352 size_t alignment_in_bits); 3353 3354 function_type(const environment& env, 3355 size_t size_in_bits, 3356 size_t alignment_in_bits); 3357 3358 type_base_sptr 3359 get_return_type() const; 3360 3361 void 3362 set_return_type(type_base_sptr t); 3363 3364 const parameters& 3365 get_parameters() const; 3366 3367 const parameter_sptr 3368 get_parm_at_index_from_first_non_implicit_parm(size_t) const; 3369 3370 void 3371 set_parameters(const parameters &p); 3372 3373 void 3374 append_parameter(parameter_sptr parm); 3375 3376 bool 3377 is_variadic() const; 3378 3379 parameters::const_iterator 3380 get_first_non_implicit_parm() const; 3381 3382 parameters::const_iterator 3383 get_first_parm() const; 3384 3385 const interned_string& 3386 get_cached_name(bool internal = false) const; 3387 3388 virtual bool 3389 operator==(const type_base&) const; 3390 3391 virtual string 3392 get_pretty_representation(bool internal = false, 3393 bool qualified_name = true) const; 3394 3395 virtual bool 3396 traverse(ir_node_visitor&); 3397 3398 virtual ~function_type(); 3399 3400 friend bool 3401 equals(const function_type&, const function_type&, change_kind*); 3402 };//end class function_type 3403 3404 /// The hashing functor for @ref function_type. 3405 struct function_type::hash 3406 { 3407 size_t 3408 operator()(const function_type& t) const; 3409 3410 size_t 3411 operator()(const function_type* t) const; 3412 3413 size_t 3414 operator()(const function_type_sptr t) const; 3415 };// end struct function_type::hash 3416 3417 /// Abstracts the type of a class member function. 3418 class method_type : public function_type 3419 { 3420 struct priv; 3421 std::unique_ptr<priv> priv_; 3422 3423 method_type(); 3424 3425 public: 3426 3427 /// Hasher for intances of method_type 3428 struct hash; 3429 3430 method_type(type_base_sptr return_type, 3431 class_or_union_sptr class_type, 3432 const std::vector<function_decl::parameter_sptr>& parms, 3433 bool is_const, 3434 size_t size_in_bits, 3435 size_t alignment_in_bits); 3436 3437 method_type(type_base_sptr return_type, 3438 type_base_sptr class_type, 3439 const std::vector<function_decl::parameter_sptr>& parms, 3440 bool is_const, 3441 size_t size_in_bits, 3442 size_t alignment_in_bits); 3443 3444 method_type(class_or_union_sptr class_type, 3445 bool is_const, 3446 size_t size_in_bits, 3447 size_t alignment_in_bits); 3448 3449 method_type(const environment& env, 3450 size_t size_in_bits, 3451 size_t alignment_in_bits); 3452 3453 class_or_union_sptr 3454 get_class_type() const; 3455 3456 void 3457 set_class_type(const class_or_union_sptr& t); 3458 3459 void set_is_const(bool); 3460 3461 bool get_is_const() const; 3462 3463 virtual ~method_type(); 3464 3465 virtual string 3466 get_pretty_representation(bool internal = false, 3467 bool qualified_name = true) const; 3468 3469 friend interned_string 3470 get_method_type_name(const method_type& fn_type, bool internal); 3471 };// end class method_type. 3472 3473 /// The base class of templates. 3474 class template_decl : public virtual decl_base 3475 { 3476 class priv; 3477 std::unique_ptr<priv> priv_; 3478 3479 template_decl(); 3480 3481 public: 3482 3483 /// Hasher. 3484 struct hash; 3485 3486 template_decl(const environment& env, 3487 const string& name, 3488 const location& locus, 3489 visibility vis = VISIBILITY_DEFAULT); 3490 3491 void 3492 add_template_parameter(const template_parameter_sptr p); 3493 3494 const std::list<template_parameter_sptr>& 3495 get_template_parameters() const; 3496 3497 virtual bool 3498 operator==(const decl_base& o) const; 3499 3500 virtual bool 3501 operator==(const template_decl& o) const; 3502 3503 virtual ~template_decl(); 3504 };//end class template_decl 3505 3506 /// Base class for a template parameter. Client code should use the 3507 /// more specialized type_template_parameter, 3508 /// non_type_template_parameter and template_template_parameter below. 3509 class template_parameter 3510 { 3511 class priv; 3512 std::unique_ptr<priv> priv_; 3513 3514 // Forbidden 3515 template_parameter(); 3516 3517 public: 3518 3519 /// Hashers. 3520 struct hash; 3521 struct dynamic_hash; 3522 struct shared_ptr_hash; 3523 3524 template_parameter(unsigned index, 3525 template_decl_sptr enclosing_tdecl); 3526 3527 virtual bool 3528 operator==(const template_parameter&) const; 3529 3530 bool 3531 operator!=(const template_parameter&) const; 3532 3533 unsigned 3534 get_index() const; 3535 3536 const template_decl_sptr 3537 get_enclosing_template_decl() const; 3538 3539 bool 3540 get_hashing_has_started() const; 3541 3542 void 3543 set_hashing_has_started(bool f) const; 3544 3545 virtual ~template_parameter(); 3546 };//end class template_parameter 3547 3548 struct template_decl::hash 3549 { 3550 size_t 3551 operator()(const template_decl& t) const; 3552 };// end struct template_decl::hash 3553 3554 /// Abstracts a type template parameter. 3555 class type_tparameter : public template_parameter, public virtual type_decl 3556 { 3557 class priv; 3558 std::unique_ptr<priv> priv_; 3559 3560 // Forbidden 3561 type_tparameter(); 3562 3563 public: 3564 3565 /// Hasher. 3566 struct hash; 3567 3568 type_tparameter(unsigned index, 3569 template_decl_sptr enclosing_tdecl, 3570 const string& name, 3571 const location& locus); 3572 3573 virtual bool 3574 operator==(const type_base&) const; 3575 3576 virtual bool 3577 operator==(const type_decl&) const; 3578 3579 virtual bool 3580 operator==(const decl_base&) const; 3581 3582 virtual bool 3583 operator==(const template_parameter&) const; 3584 3585 virtual bool 3586 operator==(const type_tparameter&) const; 3587 3588 virtual ~type_tparameter(); 3589 };// end class type_tparameter. 3590 3591 /// Abstracts non type template parameters. 3592 class non_type_tparameter : public template_parameter, public virtual decl_base 3593 { 3594 class priv; 3595 std::unique_ptr<priv> priv_; 3596 3597 type_base_wptr type_; 3598 3599 // Forbidden 3600 non_type_tparameter(); 3601 3602 public: 3603 /// Hasher. 3604 struct hash; 3605 3606 non_type_tparameter(unsigned index, 3607 template_decl_sptr enclosing_tdecl, 3608 const string& name, 3609 type_base_sptr type, 3610 const location& locus); 3611 virtual size_t 3612 get_hash() const; 3613 3614 virtual bool 3615 operator==(const decl_base&) const; 3616 3617 virtual bool 3618 operator==(const template_parameter&) const; 3619 3620 const type_base_sptr 3621 get_type() const; 3622 3623 virtual ~non_type_tparameter(); 3624 };// end class non_type_tparameter 3625 3626 /// Hasher for the @ref non_type_tparameter type. 3627 struct non_type_tparameter::hash 3628 { 3629 size_t 3630 operator()(const non_type_tparameter& t) const; 3631 3632 size_t 3633 operator()(const non_type_tparameter* t) const; 3634 }; 3635 3636 class template_tparameter; 3637 3638 /// Abstracts a template template parameter. 3639 class template_tparameter : public type_tparameter, public template_decl 3640 { 3641 class priv; 3642 std::unique_ptr<priv> priv_; 3643 3644 // Forbidden 3645 template_tparameter(); 3646 3647 public: 3648 3649 /// A hasher for instances of template_tparameter 3650 struct hash; 3651 3652 template_tparameter(unsigned index, 3653 template_decl_sptr enclosing_tdecl, 3654 const string& name, 3655 const location& locus); 3656 3657 virtual bool 3658 operator==(const type_base&) const; 3659 3660 virtual bool 3661 operator==(const decl_base&) const; 3662 3663 virtual bool 3664 operator==(const template_parameter&) const; 3665 3666 virtual bool 3667 operator==(const template_decl&) const; 3668 3669 virtual ~template_tparameter(); 3670 }; 3671 3672 /// This abstracts a composition of types based on template type 3673 /// parameters. The result of the composition is a type that can be 3674 /// referred to by a template non-type parameter. Instances of this 3675 /// type can appear at the same level as template parameters, in the 3676 /// scope of a template_decl. 3677 class type_composition : public template_parameter, public virtual decl_base 3678 { 3679 class priv; 3680 std::unique_ptr<priv> priv_; 3681 3682 type_composition(); 3683 3684 public: 3685 struct hash; 3686 3687 type_composition(unsigned index, 3688 template_decl_sptr tdecl, 3689 type_base_sptr composed_type); 3690 3691 const type_base_sptr 3692 get_composed_type() const; 3693 3694 void 3695 set_composed_type(type_base_sptr t); 3696 3697 virtual size_t 3698 get_hash() const; 3699 3700 virtual ~type_composition(); 3701 }; 3702 3703 /// Hasher for the @ref type_composition type. 3704 struct type_composition::hash 3705 { 3706 size_t 3707 operator()(const type_composition& t) const; 3708 3709 size_t 3710 operator()(const type_composition* t) const; 3711 3712 }; //struct type_composition::hash 3713 3714 /// Abstract a function template declaration. 3715 class function_tdecl : public template_decl, public scope_decl 3716 { 3717 class priv; 3718 std::unique_ptr<priv> priv_; 3719 3720 // Forbidden 3721 function_tdecl(); 3722 3723 public: 3724 3725 /// Hash functor for function templates. 3726 struct hash; 3727 struct shared_ptr_hash; 3728 3729 function_tdecl(const environment& env, 3730 const location& locus, 3731 visibility vis = VISIBILITY_DEFAULT, 3732 binding bind = BINDING_NONE); 3733 3734 function_tdecl(function_decl_sptr pattern, 3735 const location& locus, 3736 visibility vis = VISIBILITY_DEFAULT, 3737 binding bind = BINDING_NONE); 3738 3739 virtual bool 3740 operator==(const decl_base&) const; 3741 3742 virtual bool 3743 operator==(const template_decl&) const; 3744 3745 virtual bool 3746 operator==(const function_tdecl&) const; 3747 3748 void 3749 set_pattern(shared_ptr<function_decl> p); 3750 3751 shared_ptr<function_decl> 3752 get_pattern() const; 3753 3754 binding 3755 get_binding() const; 3756 3757 virtual bool 3758 traverse(ir_node_visitor& v); 3759 3760 virtual ~function_tdecl(); 3761 }; // end class function_tdecl. 3762 3763 /// Abstract a class template. 3764 class class_tdecl : public template_decl, public scope_decl 3765 { 3766 class priv; 3767 std::unique_ptr<priv> priv_; 3768 3769 // Forbidden 3770 class_tdecl(); 3771 3772 public: 3773 3774 /// Hashers. 3775 struct hash; 3776 struct shared_ptr_hash; 3777 3778 class_tdecl(const environment& env, const location& locus, 3779 visibility vis = VISIBILITY_DEFAULT); 3780 3781 class_tdecl(class_decl_sptr pattern, 3782 const location& locus, 3783 visibility vis = VISIBILITY_DEFAULT); 3784 3785 virtual bool 3786 operator==(const decl_base&) const; 3787 3788 virtual bool 3789 operator==(const template_decl&) const; 3790 3791 virtual bool 3792 operator==(const class_tdecl&) const; 3793 3794 void 3795 set_pattern(class_decl_sptr p); 3796 3797 shared_ptr<class_decl> 3798 get_pattern() const; 3799 3800 virtual bool 3801 traverse(ir_node_visitor& v); 3802 3803 virtual ~class_tdecl(); 3804 };// end class class_tdecl 3805 3806 /// The base class for member types, data members and member 3807 /// functions. Its purpose is mainly to carry the access specifier 3808 /// (and possibly other properties that might be shared by all class 3809 /// members) for the member. 3810 class member_base 3811 { 3812 protected: 3813 enum access_specifier access_; 3814 bool is_static_; 3815 3816 private: 3817 // Forbidden 3818 member_base(); 3819 3820 public: 3821 /// Hasher. 3822 struct hash; 3823 3824 member_base(access_specifier a, bool is_static = false) access_(a)3825 : access_(a), is_static_(is_static) 3826 {} 3827 3828 /// Getter for the access specifier of this member. 3829 /// 3830 /// @return the access specifier for this member. 3831 access_specifier get_access_specifier()3832 get_access_specifier() const 3833 {return access_;} 3834 3835 /// Setter for the access specifier of this member. 3836 /// 3837 /// @param a the new access specifier. 3838 void set_access_specifier(access_specifier a)3839 set_access_specifier(access_specifier a) 3840 {access_ = a;} 3841 3842 /// @return true if the member is static, false otherwise. 3843 bool get_is_static()3844 get_is_static() const 3845 {return is_static_;} 3846 3847 /// Set a flag saying if the parameter is static or not. 3848 /// 3849 /// @param f set to true if the member is static, false otherwise. 3850 void set_is_static(bool f)3851 set_is_static(bool f) 3852 {is_static_ = f;} 3853 3854 virtual bool 3855 operator==(const member_base& o) const; 3856 };// end class member_base 3857 3858 /// Abstraction of the declaration of a method. 3859 class method_decl : public function_decl 3860 { 3861 method_decl(); 3862 3863 virtual void 3864 set_scope(scope_decl*); 3865 3866 public: 3867 3868 method_decl(const string& name, method_type_sptr type, 3869 bool declared_inline, const location& locus, 3870 const string& mangled_name = "", 3871 visibility vis = VISIBILITY_DEFAULT, 3872 binding bind = BINDING_GLOBAL); 3873 3874 method_decl(const string& name, 3875 function_type_sptr type, 3876 bool declared_inline, 3877 const location& locus, 3878 const string& mangled_name = "", 3879 visibility vis = VISIBILITY_DEFAULT, 3880 binding bind = BINDING_GLOBAL); 3881 3882 method_decl(const string& name, type_base_sptr type, 3883 bool declared_inline, const location& locus, 3884 const string& mangled_name = "", 3885 visibility vis = VISIBILITY_DEFAULT, 3886 binding bind = BINDING_GLOBAL); 3887 3888 virtual void 3889 set_linkage_name(const string&); 3890 3891 /// @return the type of the current instance of the 3892 /// method_decl. 3893 const method_type_sptr 3894 get_type() const; 3895 3896 void set_type(const method_type_sptr fn_type)3897 set_type(const method_type_sptr fn_type) 3898 {function_decl::set_type(fn_type);} 3899 3900 friend bool 3901 get_member_function_is_ctor(const function_decl&); 3902 3903 friend void 3904 set_member_function_is_ctor(function_decl&, bool); 3905 3906 friend void 3907 set_member_function_is_ctor(const function_decl_sptr&, bool); 3908 3909 friend bool 3910 get_member_function_is_dtor(const function_decl&); 3911 3912 friend void 3913 set_member_function_is_dtor(function_decl&, bool); 3914 3915 friend void 3916 set_member_function_is_dtor(const function_decl_sptr&, bool); 3917 3918 friend bool 3919 get_member_function_is_static(const function_decl&); 3920 3921 friend void 3922 set_member_function_is_static(const function_decl&, bool); 3923 3924 friend bool 3925 get_member_function_is_const(const function_decl&); 3926 3927 friend void 3928 set_member_function_is_const(function_decl&, bool); 3929 3930 friend void 3931 set_member_function_is_const(const function_decl_sptr&, bool); 3932 3933 friend bool 3934 member_function_has_vtable_offset(const function_decl&); 3935 3936 friend ssize_t 3937 get_member_function_vtable_offset(const function_decl&); 3938 3939 friend void 3940 set_member_function_vtable_offset(function_decl&, ssize_t); 3941 3942 friend void 3943 set_member_function_vtable_offset(const function_decl_sptr&, ssize_t); 3944 3945 friend bool 3946 get_member_function_is_virtual(const function_decl&); 3947 3948 friend void 3949 set_member_function_is_virtual(function_decl&, bool); 3950 3951 virtual ~method_decl(); 3952 };// end class method_decl 3953 3954 bool 3955 operator==(const method_decl_sptr& l, const method_decl_sptr& r); 3956 3957 bool 3958 operator!=(const method_decl_sptr& l, const method_decl_sptr& r); 3959 3960 /// The base type of @ref class_decl and @ref union_decl 3961 class class_or_union : public scope_type_decl 3962 { 3963 public: 3964 struct priv; 3965 priv *priv_; 3966 3967 private: 3968 // Forbidden 3969 class_or_union(); 3970 3971 protected: 3972 3973 virtual decl_base_sptr 3974 add_member_decl(const decl_base_sptr&); 3975 3976 decl_base_sptr 3977 insert_member_decl(decl_base_sptr member); 3978 3979 virtual void 3980 remove_member_decl(decl_base_sptr); 3981 3982 void 3983 maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm); 3984 3985 public: 3986 /// Hasher. 3987 struct hash; 3988 3989 /// Convenience typedef 3990 /// @{ 3991 typedef vector<type_base_sptr> member_types; 3992 typedef vector<var_decl_sptr> data_members; 3993 typedef vector<method_decl_sptr> member_functions; 3994 typedef unordered_map<ssize_t, member_functions> virtual_mem_fn_map_type; 3995 typedef unordered_map<string, method_decl*> string_mem_fn_ptr_map_type; 3996 typedef unordered_map<string, method_decl_sptr> string_mem_fn_sptr_map_type; 3997 /// @} 3998 3999 class_or_union(const environment& env, const string& name, 4000 size_t size_in_bits, size_t align_in_bits, 4001 const location& locus, visibility vis, 4002 member_types& mbrs, data_members& data_mbrs, 4003 member_functions& member_fns); 4004 4005 class_or_union(const environment& env, const string& name, 4006 size_t size_in_bits, size_t align_in_bits, 4007 const location& locus, visibility vis); 4008 4009 class_or_union(const environment& env, const string& name, 4010 bool is_declaration_only = true); 4011 4012 virtual void 4013 set_size_in_bits(size_t); 4014 4015 virtual size_t 4016 get_size_in_bits() const; 4017 4018 virtual size_t 4019 get_alignment_in_bits() const; 4020 4021 virtual void 4022 set_alignment_in_bits(size_t); 4023 4024 virtual size_t 4025 get_num_anonymous_member_classes() const; 4026 4027 virtual size_t 4028 get_num_anonymous_member_unions() const; 4029 4030 virtual size_t 4031 get_num_anonymous_member_enums() const; 4032 4033 void 4034 add_data_member(var_decl_sptr v, access_specifier a, 4035 bool is_laid_out, bool is_static, 4036 size_t offset_in_bits); 4037 4038 const data_members& 4039 get_data_members() const; 4040 4041 const var_decl_sptr 4042 find_data_member(const string&) const; 4043 4044 const var_decl_sptr 4045 find_data_member(const var_decl_sptr&) const; 4046 4047 const var_decl_sptr 4048 find_anonymous_data_member(const var_decl_sptr&) const; 4049 4050 const data_members& 4051 get_non_static_data_members() const; 4052 4053 void 4054 add_member_function(method_decl_sptr f, 4055 access_specifier a, 4056 bool is_static, bool is_ctor, 4057 bool is_dtor, bool is_const); 4058 4059 void 4060 add_member_function(method_decl_sptr f, 4061 access_specifier a, 4062 bool is_virtual, 4063 size_t vtable_offset, 4064 bool is_static, bool is_ctor, 4065 bool is_dtor, bool is_const); 4066 4067 const member_functions& 4068 get_member_functions() const; 4069 4070 const method_decl* 4071 find_member_function(const string& mangled_name) const; 4072 4073 method_decl* 4074 find_member_function(const string& mangled_name); 4075 4076 method_decl_sptr 4077 find_member_function_sptr(const string& mangled_name); 4078 4079 const method_decl* 4080 find_member_function_from_signature(const string& s) const; 4081 4082 method_decl* 4083 find_member_function_from_signature(const string& s); 4084 4085 void 4086 add_member_function_template(member_function_template_sptr); 4087 4088 const member_function_templates& 4089 get_member_function_templates() const; 4090 4091 void 4092 add_member_class_template(member_class_template_sptr m); 4093 4094 const member_class_templates& 4095 get_member_class_templates() const; 4096 4097 bool 4098 has_no_member() const; 4099 4100 virtual bool 4101 operator==(const decl_base&) const; 4102 4103 virtual bool 4104 operator==(const type_base&) const; 4105 4106 virtual bool 4107 operator==(const class_or_union&) const; 4108 4109 virtual bool 4110 traverse(ir_node_visitor& v); 4111 4112 virtual ~class_or_union(); 4113 4114 friend method_decl_sptr 4115 copy_member_function(class_or_union_sptr& t, 4116 const method_decl*m); 4117 4118 friend method_decl_sptr 4119 copy_member_function(class_or_union_sptr& t, 4120 const method_decl_sptr& m); 4121 4122 friend void 4123 fixup_virtual_member_function(method_decl_sptr method); 4124 4125 friend void 4126 set_member_is_static(decl_base& d, bool s); 4127 4128 friend bool 4129 equals(const class_or_union&, const class_or_union&, change_kind*); 4130 4131 friend bool 4132 equals(const class_decl&, const class_decl&, change_kind*); 4133 4134 friend class method_decl; 4135 friend class class_decl; 4136 }; // end class class_or_union 4137 4138 method_decl_sptr 4139 copy_member_function(const class_or_union_sptr& clazz, 4140 const method_decl_sptr& f); 4141 4142 method_decl_sptr 4143 copy_member_function(const class_or_union_sptr& clazz, 4144 const method_decl* f); 4145 4146 bool 4147 operator==(const class_or_union_sptr& l, const class_or_union_sptr& r); 4148 4149 bool 4150 operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r); 4151 4152 /// Hasher for the @ref class_or_union type 4153 struct class_or_union::hash 4154 { 4155 size_t 4156 operator()(const class_or_union& t) const; 4157 4158 size_t 4159 operator()(const class_or_union* t) const; 4160 }; // end struct class_decl::hash 4161 4162 /// Abstracts a class declaration. 4163 class class_decl : public class_or_union 4164 { 4165 // Forbidden 4166 class_decl(); 4167 4168 protected: 4169 4170 decl_base_sptr 4171 insert_member_decl(decl_base_sptr member); 4172 4173 public: 4174 /// Hasher. 4175 struct hash; 4176 4177 /// Forward declarations. 4178 class base_spec; 4179 4180 /// Convenience typedef 4181 /// @{ 4182 typedef shared_ptr<base_spec> base_spec_sptr; 4183 typedef vector<base_spec_sptr> base_specs; 4184 4185 /// @} 4186 4187 protected: 4188 virtual void 4189 on_canonical_type_set(); 4190 4191 private: 4192 struct priv; 4193 // This priv it's not handled by a shared_ptr because accessing the 4194 // data members of the priv struct for this class_decl shows up on 4195 // performance profiles when dealing with big binaries with a lot of 4196 // types; dereferencing the shared_ptr involves locking of some sort 4197 // and that is slower than just dereferencing a pointer likere here. 4198 // There are other types for which the priv pointer is managed using 4199 // shared_ptr just fine, because those didn't show up during our 4200 // performance profiling. 4201 priv * priv_; 4202 4203 public: 4204 4205 class_decl(const environment& env, const string& name, 4206 size_t size_in_bits, size_t align_in_bits, 4207 bool is_struct, const location& locus, 4208 visibility vis, base_specs& bases, 4209 member_types& mbrs, data_members& data_mbrs, 4210 member_functions& member_fns); 4211 4212 class_decl(const environment& env, const string& name, 4213 size_t size_in_bits, size_t align_in_bits, 4214 bool is_struct, const location& locus, 4215 visibility vis, base_specs& bases, 4216 member_types& mbrs, data_members& data_mbrs, 4217 member_functions& member_fns, bool is_anonymous); 4218 4219 class_decl(const environment& env, const string& name, 4220 size_t size_in_bits, size_t align_in_bits, 4221 bool is_struct, const location& locus, visibility vis); 4222 4223 class_decl(const environment& env, const string& name, 4224 size_t size_in_bits, size_t align_in_bits, 4225 bool is_struct, const location& locus, 4226 visibility vis, bool is_anonymous); 4227 4228 class_decl(const environment& env, const string& name, bool is_struct, 4229 bool is_declaration_only = true); 4230 4231 virtual string 4232 get_pretty_representation(bool internal = false, 4233 bool qualified_name = true) const; 4234 4235 void 4236 is_struct(bool f); 4237 4238 bool 4239 is_struct() const; 4240 4241 void 4242 add_base_specifier(shared_ptr<base_spec> b); 4243 4244 const base_specs& 4245 get_base_specifiers() const; 4246 4247 class_decl_sptr 4248 find_base_class(const string&) const; 4249 4250 const member_functions& 4251 get_virtual_mem_fns() const; 4252 4253 const virtual_mem_fn_map_type& 4254 get_virtual_mem_fns_map() const; 4255 4256 void 4257 sort_virtual_mem_fns(); 4258 4259 bool 4260 has_no_base_nor_member() const; 4261 4262 bool 4263 has_virtual_member_functions() const; 4264 4265 bool 4266 has_virtual_bases() const; 4267 4268 bool 4269 has_vtable() const; 4270 4271 ssize_t 4272 get_biggest_vtable_offset() const; 4273 4274 virtual size_t 4275 get_hash() const; 4276 4277 virtual bool 4278 operator==(const decl_base&) const; 4279 4280 virtual bool 4281 operator==(const type_base&) const; 4282 4283 virtual bool 4284 operator==(const class_or_union&) const; 4285 4286 virtual bool 4287 operator==(const class_decl&) const; 4288 4289 virtual bool 4290 traverse(ir_node_visitor& v); 4291 4292 virtual ~class_decl(); 4293 4294 friend void 4295 fixup_virtual_member_function(method_decl_sptr method); 4296 4297 friend void 4298 set_member_is_static(decl_base& d, bool s); 4299 4300 friend bool 4301 equals(const class_decl&, const class_decl&, change_kind*); 4302 4303 friend class method_decl; 4304 friend class class_or_union; 4305 };// end class class_decl 4306 4307 bool 4308 equals(const class_decl&, const class_decl&, change_kind*); 4309 4310 method_decl_sptr 4311 copy_member_function(const class_decl_sptr& clazz, 4312 const method_decl_sptr& f); 4313 4314 method_decl_sptr 4315 copy_member_function(const class_decl_sptr& clazz, 4316 const method_decl* f); 4317 void 4318 fixup_virtual_member_function(method_decl_sptr method); 4319 4320 /// Hasher for the @ref class_decl type 4321 struct class_decl::hash 4322 { 4323 size_t 4324 operator()(const class_decl& t) const; 4325 4326 size_t 4327 operator()(const class_decl* t) const; 4328 }; // end struct class_decl::hash 4329 4330 enum access_specifier 4331 get_member_access_specifier(const decl_base&); 4332 4333 enum access_specifier 4334 get_member_access_specifier(const decl_base_sptr&); 4335 4336 void 4337 set_member_access_specifier(decl_base&, 4338 access_specifier); 4339 4340 void 4341 set_member_access_specifier(const decl_base_sptr&, 4342 access_specifier); 4343 4344 std::ostream& 4345 operator<<(std::ostream&, access_specifier); 4346 4347 bool 4348 operator==(const class_decl_sptr& l, const class_decl_sptr& r); 4349 4350 bool 4351 operator!=(const class_decl_sptr& l, const class_decl_sptr& r); 4352 4353 bool 4354 equals(const class_decl::base_spec&, 4355 const class_decl::base_spec&, 4356 change_kind*); 4357 4358 /// Abstraction of a base specifier in a class declaration. 4359 class class_decl::base_spec : public member_base, 4360 public virtual decl_base 4361 { 4362 struct priv; 4363 std::unique_ptr<priv> priv_; 4364 4365 // Forbidden 4366 base_spec(); 4367 4368 public: 4369 4370 /// Hasher. 4371 struct hash; 4372 4373 base_spec(const class_decl_sptr& base, access_specifier a, 4374 long offset_in_bits = -1, bool is_virtual = false); 4375 4376 base_spec(const type_base_sptr& base, access_specifier a, 4377 long offset_in_bits = -1, bool is_virtual = false); 4378 4379 virtual ~base_spec(); 4380 4381 class_decl_sptr 4382 get_base_class() const; 4383 4384 bool 4385 get_is_virtual() const; 4386 4387 long 4388 get_offset_in_bits() const; 4389 4390 virtual bool 4391 operator==(const decl_base&) const; 4392 4393 virtual bool 4394 operator==(const member_base&) const; 4395 4396 virtual size_t 4397 get_hash() const; 4398 4399 virtual bool 4400 traverse(ir_node_visitor&); 4401 };// end class class_decl::base_spec 4402 4403 bool 4404 operator==(const class_decl::base_spec_sptr& l, 4405 const class_decl::base_spec_sptr& r); 4406 4407 bool 4408 operator!=(const class_decl::base_spec_sptr& l, 4409 const class_decl::base_spec_sptr& r); 4410 4411 class_decl::base_spec* 4412 is_class_base_spec(type_or_decl_base*); 4413 4414 class_decl::base_spec_sptr 4415 is_class_base_spec(type_or_decl_base_sptr); 4416 4417 /// Abstracts a union type declaration. 4418 class union_decl : public class_or_union 4419 { 4420 // Forbid 4421 union_decl(); 4422 4423 public: 4424 4425 union_decl(const environment& env, const string& name, 4426 size_t size_in_bits, const location& locus, 4427 visibility vis, member_types& mbrs, 4428 data_members& data_mbrs, member_functions& member_fns); 4429 4430 union_decl(const environment& env, const string& name, 4431 size_t size_in_bits, const location& locus, 4432 visibility vis, member_types& mbrs, 4433 data_members& data_mbrs, member_functions& member_fns, 4434 bool is_anonymous); 4435 4436 union_decl(const environment& env, const string& name, 4437 size_t size_in_bits, const location& locus, 4438 visibility vis); 4439 4440 union_decl(const environment& env, const string& name, 4441 size_t size_in_bits, const location& locus, 4442 visibility vis, bool is_anonymous); 4443 4444 union_decl(const environment& env, const string& name, 4445 bool is_declaration_only = true); 4446 4447 virtual string 4448 get_pretty_representation(bool internal = false, 4449 bool qualified_name = true) const; 4450 4451 virtual bool 4452 operator==(const decl_base&) const; 4453 4454 virtual bool 4455 operator==(const type_base&) const; 4456 4457 virtual bool 4458 operator==(const class_or_union&) const; 4459 4460 virtual bool 4461 operator==(const union_decl&) const; 4462 4463 virtual bool 4464 traverse(ir_node_visitor& v); 4465 4466 virtual ~union_decl(); 4467 }; // union_decl 4468 4469 bool 4470 equals(const union_decl&, const union_decl&, change_kind*); 4471 4472 method_decl_sptr 4473 copy_member_function(const union_decl_sptr& union_type, 4474 const method_decl_sptr& f); 4475 4476 method_decl_sptr 4477 copy_member_function(const union_decl_sptr& union_type, 4478 const method_decl* f); 4479 4480 bool 4481 operator==(const union_decl_sptr& l, const union_decl_sptr& r); 4482 4483 bool 4484 operator!=(const union_decl_sptr& l, const union_decl_sptr& r); 4485 4486 /// Abstraction of a member function context relationship. This 4487 /// relates a member function to its parent class. 4488 class mem_fn_context_rel : public context_rel 4489 { 4490 protected: 4491 bool is_virtual_; 4492 ssize_t vtable_offset_in_bits_; 4493 bool is_constructor_; 4494 bool is_destructor_; 4495 bool is_const_; 4496 4497 public: mem_fn_context_rel()4498 mem_fn_context_rel() 4499 : context_rel(), 4500 is_virtual_(false), 4501 vtable_offset_in_bits_(-1), 4502 is_constructor_(false), 4503 is_destructor_(false), 4504 is_const_(false) 4505 {} 4506 mem_fn_context_rel(scope_decl * s)4507 mem_fn_context_rel(scope_decl* s) 4508 : context_rel(s), 4509 is_virtual_(false), 4510 vtable_offset_in_bits_(-1), 4511 is_constructor_(false), 4512 is_destructor_(false), 4513 is_const_(false) 4514 {} 4515 mem_fn_context_rel(scope_decl * s,bool is_constructor,bool is_destructor,bool is_const,bool is_virtual,size_t vtable_offset_in_bits,access_specifier access,bool is_static)4516 mem_fn_context_rel(scope_decl* s, 4517 bool is_constructor, 4518 bool is_destructor, 4519 bool is_const, 4520 bool is_virtual, 4521 size_t vtable_offset_in_bits, 4522 access_specifier access, 4523 bool is_static) 4524 : context_rel(s, access, is_static), 4525 is_virtual_(is_virtual), 4526 vtable_offset_in_bits_(vtable_offset_in_bits), 4527 is_constructor_(is_constructor), 4528 is_destructor_(is_destructor), 4529 is_const_(is_const) 4530 {} 4531 4532 bool is_virtual()4533 is_virtual() const 4534 {return is_virtual_;} 4535 4536 void is_virtual(bool is_virtual)4537 is_virtual(bool is_virtual) 4538 {is_virtual_ = is_virtual;} 4539 4540 /// Getter for the vtable offset property. 4541 /// 4542 /// This is the vtable offset of the member function of this 4543 /// relation. 4544 /// 4545 /// @return the vtable offset property of the relation. 4546 size_t vtable_offset()4547 vtable_offset() const 4548 {return vtable_offset_in_bits_;} 4549 4550 /// Setter for the vtable offset property. 4551 /// 4552 /// This is the vtable offset of the member function of this 4553 /// relation. 4554 /// 4555 /// @partam s the new vtable offset. 4556 void vtable_offset(size_t s)4557 vtable_offset(size_t s) 4558 {vtable_offset_in_bits_ = s;} 4559 4560 /// Getter for the 'is-constructor' property. 4561 /// 4562 /// This tells if the member function of this relation is a 4563 /// constructor. 4564 /// 4565 /// @return the is-constructor property of the relation. 4566 bool is_constructor()4567 is_constructor() const 4568 {return is_constructor_;} 4569 4570 /// Setter for the 'is-constructor' property. 4571 /// 4572 /// @param f the new value of the the property. Is true if this is 4573 /// for a constructor, false otherwise. 4574 void is_constructor(bool f)4575 is_constructor(bool f) 4576 {is_constructor_ = f;} 4577 4578 /// Getter for the 'is-destructor' property. 4579 /// 4580 /// Tells if the member function of this relation is a destructor. 4581 /// 4582 /// @return the is-destructor property of the relation; 4583 bool is_destructor()4584 is_destructor() const 4585 {return is_destructor_;} 4586 4587 /// Setter for the 'is-destructor' property. 4588 /// 4589 /// @param f the new value of the property. Is true if this is for 4590 /// a destructor, false otherwise. 4591 void is_destructor(bool f)4592 is_destructor(bool f) 4593 {is_destructor_ = f;} 4594 4595 /// Getter for the 'is-const' property. 4596 /// 4597 /// Tells if the member function of this relation is a const member 4598 /// function. 4599 /// 4600 /// @return the 'is-const' property of the relation. 4601 bool is_const()4602 is_const() const 4603 {return is_const_;} 4604 4605 /// Setter for the 'is-const' property. 4606 /// 4607 /// @param f the new value of the property. Is true if this is for 4608 /// a const entity, false otherwise. 4609 void is_const(bool f)4610 is_const(bool f) 4611 {is_const_ = f;} 4612 4613 virtual ~mem_fn_context_rel(); 4614 }; // end class mem_fn_context_rel 4615 4616 method_decl* 4617 is_method_decl(const type_or_decl_base*); 4618 4619 method_decl* 4620 is_method_decl(const type_or_decl_base&); 4621 4622 method_decl_sptr 4623 is_method_decl(const type_or_decl_base_sptr&); 4624 4625 const var_decl* 4626 lookup_data_member(const type_base* type, 4627 const char* dm_name); 4628 4629 const var_decl_sptr 4630 lookup_data_member(const type_base_sptr& type, 4631 const var_decl_sptr& dm); 4632 4633 const function_decl::parameter* 4634 get_function_parameter(const decl_base* fun, 4635 unsigned parm_num); 4636 4637 /// Abstract a member function template. 4638 class member_function_template : public member_base, public virtual decl_base 4639 { 4640 bool is_constructor_; 4641 bool is_const_; 4642 shared_ptr<function_tdecl> fn_tmpl_; 4643 4644 // Forbiden 4645 member_function_template(); 4646 4647 public: 4648 /// Hasher. 4649 struct hash; 4650 member_function_template(function_tdecl_sptr f,access_specifier access,bool is_static,bool is_constructor,bool is_const)4651 member_function_template(function_tdecl_sptr f, 4652 access_specifier access, bool is_static, 4653 bool is_constructor, bool is_const) 4654 : type_or_decl_base(f->get_environment()), 4655 decl_base(f->get_environment(), f->get_name(), location()), 4656 member_base(access, is_static), is_constructor_(is_constructor), 4657 is_const_(is_const), fn_tmpl_(f) 4658 {} 4659 4660 bool is_constructor()4661 is_constructor() const 4662 {return is_constructor_;} 4663 4664 bool is_const()4665 is_const() const 4666 {return is_const_;} 4667 4668 operator const function_tdecl& () const 4669 {return *fn_tmpl_;} 4670 4671 function_tdecl_sptr as_function_tdecl()4672 as_function_tdecl() const 4673 {return fn_tmpl_;} 4674 4675 virtual bool 4676 operator==(const member_base& o) const; 4677 4678 virtual bool 4679 traverse(ir_node_visitor&); 4680 };// end class member_function_template 4681 4682 bool 4683 operator==(const member_function_template_sptr& l, 4684 const member_function_template_sptr& r); 4685 4686 bool 4687 operator!=(const member_function_template_sptr& l, 4688 const member_function_template_sptr& r); 4689 4690 /// Abstracts a member class template template 4691 class member_class_template 4692 : public member_base, 4693 public virtual decl_base 4694 { 4695 shared_ptr<class_tdecl> class_tmpl_; 4696 4697 // Forbidden 4698 member_class_template(); 4699 4700 public: 4701 4702 /// Hasher. 4703 struct hash; 4704 member_class_template(class_tdecl_sptr c,access_specifier access,bool is_static)4705 member_class_template(class_tdecl_sptr c, 4706 access_specifier access, bool is_static) 4707 : type_or_decl_base(c->get_environment()), 4708 decl_base(c->get_environment(), c->get_name(), location()), 4709 member_base(access, is_static), 4710 class_tmpl_(c) 4711 {} 4712 4713 operator const class_tdecl& () const 4714 { return *class_tmpl_; } 4715 4716 class_tdecl_sptr as_class_tdecl()4717 as_class_tdecl() const 4718 {return class_tmpl_;} 4719 4720 virtual bool 4721 operator==(const member_base& o) const; 4722 4723 virtual bool 4724 operator==(const decl_base&) const; 4725 4726 virtual bool 4727 operator==(const member_class_template&) const; 4728 4729 virtual bool 4730 traverse(ir_node_visitor& v); 4731 };// end class member_class_template 4732 4733 bool 4734 operator==(const member_class_template_sptr& l, 4735 const member_class_template_sptr& r); 4736 4737 bool 4738 operator!=(const member_class_template_sptr& l, 4739 const member_class_template_sptr& r); 4740 4741 // Forward declarations for select nested hashers. 4742 struct type_base::shared_ptr_hash 4743 { 4744 size_t 4745 operator()(const shared_ptr<type_base> t) const; 4746 }; 4747 4748 struct type_base::dynamic_hash 4749 { 4750 size_t 4751 operator()(const type_base* t) const; 4752 }; 4753 4754 /// A hashing functor for instances and pointers of @ref var_decl. 4755 struct var_decl::hash 4756 { 4757 size_t 4758 operator()(const var_decl& t) const; 4759 4760 size_t 4761 operator()(const var_decl* t) const; 4762 }; //end struct var_decl::hash 4763 4764 /// A comparison functor for pointers to @ref var_decl. 4765 struct var_decl::ptr_equal 4766 { 4767 /// Return true if the two instances of @ref var_decl are equal. 4768 /// 4769 /// @param l the first variable to compare. 4770 /// 4771 /// @param r the second variable to compare. 4772 /// 4773 /// @return true if @p l equals @p r. 4774 bool operatorptr_equal4775 operator()(const var_decl* l, const var_decl* r) const 4776 { 4777 if (l == r) 4778 return true; 4779 if (!!l != !!r) 4780 return false; 4781 return (*l == *r); 4782 } 4783 };// end struct var_decl::ptr_equal 4784 4785 /// A hashing functor fo instances and pointers of @ref function_decl. 4786 struct function_decl::hash 4787 { 4788 size_t 4789 operator()(const function_decl& t) const; 4790 4791 size_t 4792 operator()(const function_decl* t) const; 4793 };//end struct function_decl::hash 4794 4795 /// Equality functor for instances of @ref function_decl 4796 struct function_decl::ptr_equal 4797 { 4798 /// Tests if two pointers to @ref function_decl are equal. 4799 /// 4800 /// @param l the first pointer to @ref function_decl to consider in 4801 /// the comparison. 4802 /// 4803 /// @param r the second pointer to @ref function_decl to consider in 4804 /// the comparison. 4805 /// 4806 /// @return true if the two functions @p l and @p r are equal, false 4807 /// otherwise. 4808 bool operatorptr_equal4809 operator()(const function_decl* l, const function_decl* r) const 4810 { 4811 if (l == r) 4812 return true; 4813 if (!!l != !!r) 4814 return false; 4815 return (*l == *r); 4816 } 4817 };// function_decl::ptr_equal 4818 4819 /// The hashing functor for class_decl::base_spec. 4820 struct class_decl::base_spec::hash 4821 { 4822 size_t 4823 operator()(const base_spec& t) const; 4824 }; 4825 4826 /// The hashing functor for member_base. 4827 struct member_base::hash 4828 { 4829 size_t 4830 operator()(const member_base& m) const; 4831 }; 4832 4833 /// The hashing functor for member_function_template. 4834 struct member_function_template::hash 4835 { 4836 size_t 4837 operator()(const member_function_template& t) const; 4838 }; 4839 4840 /// The hashing functor for member_class_template 4841 struct member_class_template::hash 4842 { 4843 size_t 4844 operator()(const member_class_template& t) const; 4845 }; 4846 4847 struct function_tdecl::hash 4848 { 4849 size_t 4850 operator()(const function_tdecl& t) const; 4851 }; 4852 4853 struct function_tdecl::shared_ptr_hash 4854 { 4855 size_t 4856 operator()(const shared_ptr<function_tdecl> f) const; 4857 }; 4858 4859 struct class_tdecl::hash 4860 { 4861 size_t 4862 operator()(const class_tdecl& t) const; 4863 }; 4864 4865 struct class_tdecl::shared_ptr_hash 4866 { 4867 size_t 4868 operator()(const shared_ptr<class_tdecl> t) const; 4869 }; 4870 4871 /// The base class for the visitor type hierarchy used for traversing 4872 /// a translation unit. 4873 /// 4874 /// Client code willing to get notified for a certain kind of node 4875 /// during the IR traversal might want to define a visitor class that 4876 /// inherit ir_node_visitor, overload the ir_node_visitor::visit_begin() 4877 /// or ir_node_visitor::visit_end() method of its choice, and provide 4878 /// and implementation for it. If either 4879 /// ir_node_visitor::visit_begin() or ir_node_visitor::visit_end() 4880 /// return false, it means the traversal has to stop immediately after 4881 /// the methods' return. If the methods return true, it means the 4882 /// traversal keeps going. 4883 /// 4884 /// That new visitor class would then be passed to e.g, 4885 /// translation_unit::traverse or to the traverse method of any type 4886 /// where the traversal is supposed to start from. 4887 class ir_node_visitor : public node_visitor_base 4888 { 4889 struct priv; 4890 std::unique_ptr<priv> priv_; 4891 4892 public: 4893 4894 ir_node_visitor(); 4895 4896 virtual ~ir_node_visitor(); 4897 4898 void allow_visiting_already_visited_type_node(bool); 4899 bool allow_visiting_already_visited_type_node() const; 4900 void mark_type_node_as_visited(type_base *); 4901 void forget_visited_type_nodes(); 4902 bool type_node_has_been_visited(type_base*) const; 4903 4904 virtual bool visit_begin(decl_base*); 4905 virtual bool visit_end(decl_base*); 4906 4907 virtual bool visit_begin(scope_decl*); 4908 virtual bool visit_end(scope_decl*); 4909 4910 virtual bool visit_begin(type_base*); 4911 virtual bool visit_end(type_base*); 4912 4913 virtual bool visit_begin(scope_type_decl*); 4914 virtual bool visit_end(scope_type_decl*); 4915 4916 virtual bool visit_begin(type_decl*); 4917 virtual bool visit_end(type_decl*); 4918 4919 virtual bool visit_begin(namespace_decl*); 4920 virtual bool visit_end(namespace_decl*); 4921 4922 virtual bool visit_begin(qualified_type_def*); 4923 virtual bool visit_end(qualified_type_def*); 4924 4925 virtual bool visit_begin(pointer_type_def*); 4926 virtual bool visit_end(pointer_type_def*); 4927 4928 virtual bool visit_begin(reference_type_def*); 4929 virtual bool visit_end(reference_type_def*); 4930 4931 virtual bool visit_begin(array_type_def*); 4932 virtual bool visit_end(array_type_def*); 4933 4934 virtual bool visit_begin(array_type_def::subrange_type*); 4935 virtual bool visit_end(array_type_def::subrange_type*); 4936 4937 virtual bool visit_begin(enum_type_decl*); 4938 virtual bool visit_end(enum_type_decl*); 4939 4940 virtual bool visit_begin(typedef_decl*); 4941 virtual bool visit_end(typedef_decl*); 4942 4943 virtual bool visit_begin(function_type*); 4944 virtual bool visit_end(function_type*); 4945 4946 virtual bool visit_begin(var_decl*); 4947 virtual bool visit_end(var_decl*); 4948 4949 virtual bool visit_begin(function_decl*); 4950 virtual bool visit_end(function_decl*); 4951 4952 virtual bool visit_begin(function_decl::parameter*); 4953 virtual bool visit_end(function_decl::parameter*); 4954 4955 virtual bool visit_begin(function_tdecl*); 4956 virtual bool visit_end(function_tdecl*); 4957 4958 virtual bool visit_begin(class_tdecl*); 4959 virtual bool visit_end(class_tdecl*); 4960 4961 virtual bool visit_begin(class_or_union *); 4962 virtual bool visit_end(class_or_union *); 4963 4964 virtual bool visit_begin(class_decl*); 4965 virtual bool visit_end(class_decl*); 4966 4967 virtual bool visit_begin(union_decl*); 4968 virtual bool visit_end(union_decl*); 4969 4970 virtual bool visit_begin(class_decl::base_spec*); 4971 virtual bool visit_end(class_decl::base_spec*); 4972 4973 virtual bool visit_begin(member_function_template*); 4974 virtual bool visit_end(member_function_template*); 4975 4976 virtual bool visit_begin(member_class_template*); 4977 virtual bool visit_end(member_class_template*); 4978 }; // end struct ir_node_visitor 4979 4980 // Debugging facility 4981 void 4982 fns_to_str(vector<function_decl*>::const_iterator a_begin, 4983 vector<function_decl*>::const_iterator a_end, 4984 vector<function_decl*>::const_iterator b_begin, 4985 vector<function_decl*>::const_iterator b_end, 4986 std::ostream& o); 4987 4988 }// end namespace ir 4989 } // end namespace abigail 4990 #endif // __ABG_IR_H__ 4991