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