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