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