| // -*- Mode: C++ -*- |
| // |
| // Copyright (C) 2013-2020 Red Hat, Inc. |
| // |
| // This file is part of the GNU Application Binary Interface Generic |
| // Analysis and Instrumentation Library (libabigail). This library is |
| // free software; you can redistribute it and/or modify it under the |
| // terms of the GNU Lesser General Public License as published by the |
| // Free Software Foundation; either version 3, or (at your option) any |
| // later version. |
| |
| // This library is distributed in the hope that it will be useful, but |
| // WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| // General Lesser Public License for more details. |
| |
| // You should have received a copy of the GNU Lesser General Public |
| // License along with this program; see the file COPYING-LGPLV3. If |
| // not, see <http://www.gnu.org/licenses/>. |
| // |
| // Author: Dodji Seketeli |
| |
| /// @file |
| /// |
| /// Types of the main internal representation of libabigail. |
| /// |
| /// This internal representation abstracts the artifacts that make up |
| /// an application binary interface. |
| |
| #ifndef __ABG_IR_H__ |
| #define __ABG_IR_H__ |
| |
| #include <assert.h> |
| #include <stdint.h> |
| #include <cstdlib> |
| #include <set> |
| #include "abg-cxx-compat.h" |
| #include "abg-fwd.h" |
| #include "abg-hash.h" |
| #include "abg-traverse.h" |
| |
| /// @file |
| /// |
| /// This file contains the declarations of the Internal Representation |
| /// of libabigail. |
| |
| /// @defgroup Memory Memory management |
| /// @{ |
| /// |
| /// How objects' lifetime is handled in libabigail. |
| /// |
| /// For memory management and garbage collection of libabigail's IR |
| /// artifacts, we use std::tr1::shared_ptr and std::tr1::weak_ptr. |
| /// |
| /// When manipulating these IR artifacts, there are a few rules to keep in |
| /// mind. |
| /// |
| /// <b>The declaration for a type is owned by only one scope </b> |
| /// |
| /// This means that for each instance of abigail::type_base (a type) there |
| /// is an instance of abigail::scope_decl that owns a @ref |
| /// abigail::decl_base_sptr (a shared pointer to an abigail::decl_base) |
| /// that points to the declaration of that type. The |
| /// abigail::type_base_sptr is added to the scope using the function |
| /// abigail::add_decl_to_scope(). |
| /// |
| /// There is a kind of type that is usually not syntactically owned by |
| /// a scope: it's function type. In libabigail, function types are |
| /// represented by abigail::function_type and abigail::method_type. |
| /// These types must be owned by the translation unit they originate |
| /// from. Adding them to the translation unit must be done by a call |
| /// to the method function |
| /// abigail::translation::bind_function_type_life_time(). |
| /// |
| /// <b> A declaration that has a type does NOT own the type </b> |
| /// |
| /// This means that, for instance, in an abigail::var_decl (a variable |
| /// declaration), the type of the declaration is not owned by the |
| /// declaration. In other (concrete) words, the variable declaration |
| /// doesn't have a shared pointer to the type. Rather, it has a *weak* |
| /// pointer to its type. That means that it has a data member of type |
| /// abigail::type_base_wptr that contains the type of the declaration. |
| /// |
| /// But then abigail::var_decl::get_type() returns a shared pointer that |
| /// is constructed from the internal weak pointer to the type. That way, |
| /// users of the type of the var can own a temporary reference on it and |
| /// be assured that the type's life time is long enough for their need. |
| /// |
| /// Likewise, data members, function and template parameters similarly |
| /// have weak pointers on their type. |
| /// |
| /// If, for a reason, you really need to keep a type alive for the |
| /// entire lifetime of the type system, then you can bind the life |
| /// time of that type to the life time of the @ref environment that is |
| /// supposed to outlive the type system. You do that by passing the |
| /// type to the function environment::keep_type_alive(). |
| /// |
| /// @} |
| |
| namespace abigail |
| { |
| |
| /// The namespace of the internal representation of ABI artifacts like |
| /// types and decls. |
| namespace ir |
| { |
| |
| // Inject some std::tr1 types in here. |
| using abg_compat::unordered_map; |
| |
| /// A convenience typedef fo r an ordered set of size_t. |
| typedef unordered_set<size_t> pointer_set; |
| |
| /// Functor to hash a canonical type by using its pointer value. |
| struct canonical_type_hash |
| { |
| size_t operator()(const type_base_sptr& l) const; |
| size_t operator()(const type_base *l) const; |
| }; //end struct canonical_type_hash |
| |
| /// Helper typedef for an unordered set of type_base_sptr which uses |
| /// pointer value to tell its members appart, because the members are |
| /// canonical types. |
| typedef unordered_set<type_base_sptr, |
| canonical_type_hash> canonical_type_sptr_set_type; |
| |
| /// Helper typedef for a vector of pointer to type_base. |
| typedef vector<type_base*> type_base_ptrs_type; |
| |
| /// Helper typedef for a vector of shared pointer to a type_base. |
| typedef vector<type_base_sptr> type_base_sptrs_type; |
| |
| /// This is an abstraction of the set of resources necessary to manage |
| /// several aspects of the internal representations of the Abigail |
| /// library. |
| /// |
| /// An environment can be seen as the boundaries in which all related |
| /// Abigail artifacts live. So before doing anything using this |
| /// library, the first thing to create is, well, you know it now, an |
| /// environment. |
| /// |
| /// Note that the lifetime of environment objects must be longer than |
| /// the lifetime of any other type in the Abigail system. So a given |
| /// instance of @ref environment must stay around as long as you are |
| /// using libabigail. It's only when you are done using the library |
| /// that you can de-allocate the environment instance. |
| class environment |
| { |
| public: |
| |
| /// A convenience typedef for a map of canonical types. The key is |
| /// the pretty representation string of a particular type and the |
| /// value is the vector of canonical types that have the same pretty |
| /// representation string. |
| typedef abg_compat::unordered_map<string, std::vector<type_base_sptr> > |
| canonical_types_map_type; |
| |
| private: |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| public: |
| |
| environment(); |
| virtual ~environment(); |
| |
| canonical_types_map_type& |
| get_canonical_types_map(); |
| |
| const canonical_types_map_type& |
| get_canonical_types_map() const; |
| |
| const type_base_sptr& |
| get_void_type() const; |
| |
| const type_base_sptr& |
| get_variadic_parameter_type() const; |
| |
| bool |
| canonicalization_is_done() const; |
| |
| void |
| canonicalization_is_done(bool); |
| |
| bool |
| do_on_the_fly_canonicalization() const; |
| |
| void |
| do_on_the_fly_canonicalization(bool f); |
| |
| bool |
| decl_only_class_equals_definition() const; |
| |
| void |
| decl_only_class_equals_definition(bool f) const; |
| |
| bool |
| is_void_type(const type_base_sptr&) const; |
| |
| bool |
| is_void_type(const type_base*) const; |
| |
| bool |
| is_variadic_parameter_type(const type_base*) const; |
| |
| bool |
| is_variadic_parameter_type(const type_base_sptr&) const; |
| |
| interned_string |
| intern(const string&) const; |
| |
| friend class class_or_union; |
| friend class class_decl; |
| friend class function_type; |
| |
| friend void keep_type_alive(type_base_sptr); |
| }; // end class environment |
| |
| class location_manager; |
| /// @brief The source location of a token. |
| /// |
| /// This represents the location of a token coming from a given |
| /// translation unit. This location is actually an abstraction of |
| /// cursor in the table of all the locations of all the tokens of the |
| /// translation unit. That table is managed by the @ref location_manager |
| /// type. To get the file path, line and column numbers associated to |
| /// a given instance of @ref location, you need to use the |
| /// location_manager::expand_location method. |
| class location |
| { |
| unsigned value_; |
| // The location manager to use to decode the value above. There is |
| // one location manager per translation unit, and the location |
| // manager's life time is managed by its translation unit. |
| location_manager* loc_manager_; |
| |
| location(unsigned v, location_manager* m) |
| : value_(v), loc_manager_(m) |
| {} |
| |
| /// Get the location manager to use to decode the value of this |
| /// location. |
| /// |
| /// @return the location manager for the current location value. |
| location_manager* |
| get_location_manager() const |
| {return loc_manager_;} |
| |
| public: |
| |
| /// Copy constructor of the location. |
| /// |
| /// @param l the location to copy from. |
| location(const location& l) |
| : value_(l.value_), |
| loc_manager_(l.loc_manager_) |
| {} |
| |
| /// Assignment operator of the location. |
| /// |
| /// @param l the location to assign to the current one. |
| location& |
| operator=(const location& l) |
| { |
| value_ = l.value_; |
| loc_manager_ = l.loc_manager_; |
| return *this; |
| } |
| |
| /// Default constructor for the @ref location type. |
| location() |
| : value_(), loc_manager_() |
| {} |
| |
| /// Get the value of the location. |
| unsigned |
| get_value() const |
| {return value_;} |
| |
| /// Convert the location into a boolean. |
| /// |
| /// @return true iff the value of the location is different from |
| /// zero. |
| operator bool() const |
| {return !!value_;} |
| |
| /// Equality operator of the @ref location type. |
| /// |
| /// @param other the other location to compare against. |
| /// |
| /// @return true iff both locations are equal. |
| bool |
| operator==(const location &other) const |
| {return value_ == other.value_;} |
| |
| /// "Less than" operator of the @ref location type. |
| /// |
| /// @parm other the other location type to compare against. |
| /// |
| /// @return true iff the current instance is less than the @p other |
| /// one. |
| bool |
| operator<(const location &other) const |
| {return value_ < other.value_;} |
| |
| /// Expand the current location into a tripplet file path, line and |
| /// column number. |
| /// |
| /// @param path the output parameter this function sets the expanded |
| /// path to. |
| /// |
| /// @param line the output parameter this function sets the expanded |
| /// line number to. |
| /// |
| /// @param column the output parameter this function sets the |
| /// expanded column number to. |
| void |
| expand(std::string& path, unsigned& line, unsigned& column) const; |
| |
| string |
| expand(void) const; |
| |
| friend class location_manager; |
| }; // end class location |
| |
| /// @brief The entry point to manage locations. |
| /// |
| /// This type keeps a table of all the locations for tokens of a |
| /// given translation unit. |
| class location_manager |
| { |
| struct priv; |
| |
| /// Pimpl. |
| shared_ptr<priv> priv_; |
| |
| public: |
| |
| location_manager(); |
| |
| location |
| create_new_location(const std::string& fle, size_t lne, size_t col); |
| |
| void |
| expand_location(const location& location, std::string& path, |
| unsigned& line, unsigned& column) const; |
| }; |
| |
| /// The base of an entity of the intermediate representation that is |
| /// to be traversed. |
| struct ir_traversable_base : public traversable_base |
| { |
| /// Traverse a given IR node and its children, calling an visitor on |
| /// each node. |
| /// |
| /// @param v the visitor to call on each traversed node. |
| /// |
| /// @return true if the all the IR node tree was traversed. |
| virtual bool |
| traverse(ir_node_visitor& v); |
| }; // end class ir_traversable_base |
| |
| /// The hashing functor for using instances of @ref type_or_decl_base |
| /// as values in a hash map or set. |
| struct type_or_decl_hash |
| { |
| |
| /// Function-call Operator to hash the string representation of an |
| /// ABI artifact. |
| /// |
| /// @param artifact the ABI artifact to hash. |
| /// |
| /// @return the hash value of the string representation of @p |
| /// artifact. |
| size_t |
| operator()(const type_or_decl_base *artifact) const |
| { |
| string repr = get_pretty_representation(artifact); |
| abg_compat::hash<string> do_hash; |
| return do_hash(repr); |
| } |
| |
| /// Function-call Operator to hash the string representation of an |
| /// ABI artifact. |
| /// |
| /// @param artifact the ABI artifact to hash. |
| /// |
| /// @return the hash value of the string representation of @p |
| /// artifact. |
| size_t |
| operator()(const type_or_decl_base_sptr& artifact) const |
| {return operator()(artifact.get());} |
| }; // end struct type_or_decl_hash |
| |
| /// The comparison functor for using instances of @ref |
| /// type_or_decl_base as values in a hash map or set. |
| struct type_or_decl_equal |
| { |
| |
| /// The function-call operator to compare the string representations |
| /// of two ABI artifacts. |
| /// |
| /// @param l the left hand side ABI artifact operand of the |
| /// comparison. |
| /// |
| /// @param r the right hand side ABI artifact operand of the |
| /// comparison. |
| /// |
| /// @return true iff the string representation of @p l equals the one |
| /// of @p r. |
| bool |
| operator()(const type_or_decl_base *l, const type_or_decl_base *r) const |
| { |
| string repr1 = get_pretty_representation(l); |
| string repr2 = get_pretty_representation(r); |
| |
| return repr1 == repr2; |
| } |
| |
| /// The function-call operator to compare the string representations |
| /// of two ABI artifacts. |
| /// |
| /// @param l the left hand side ABI artifact operand of the |
| /// comparison. |
| /// |
| /// @param r the right hand side ABI artifact operand of the |
| /// comparison. |
| /// |
| /// @return true iff the string representation of @p l equals the one |
| /// of @p r. |
| bool |
| operator()(const type_or_decl_base_sptr &l, |
| const type_or_decl_base_sptr &r) const |
| {return operator()(l.get(), r.get());} |
| }; // end type_or_decl_equal |
| |
| /// A convenience typedef for a hash set of type_or_decl_base_sptr |
| typedef unordered_set<type_or_decl_base_sptr, |
| type_or_decl_hash, |
| type_or_decl_equal> artifact_sptr_set_type; |
| |
| /// A convenience typedef for a hash set of const type_or_decl_base* |
| typedef unordered_set<const type_or_decl_base*, |
| type_or_decl_hash, |
| type_or_decl_equal> artifact_ptr_set_type; |
| |
| /// A convenience typedef for a map which key is a string and which |
| /// value is a @ref type_base_wptr. |
| typedef unordered_map<string, type_base_wptr> string_type_base_wptr_map_type; |
| |
| /// A convenience typedef for a map which key is an @ref |
| /// interned_string and which value is a @ref type_base_wptr. |
| typedef unordered_map<interned_string, type_base_wptr, hash_interned_string> |
| istring_type_base_wptr_map_type; |
| |
| /// A convenience typedef for a map which key is an @ref |
| /// interned_string and which value is a @ref type_base_wptr. |
| typedef unordered_map<interned_string, |
| type_or_decl_base_sptr, |
| hash_interned_string> |
| istring_type_or_decl_base_sptr_map_type; |
| |
| /// This is a type that aggregates maps of all the kinds of types that |
| /// are supported by libabigail. |
| /// |
| /// For instance, the type_maps contains a map of string to basic |
| /// type, a map of string to class type, a map of string to union |
| /// types, etc. The key of a map entry is the pretty representation |
| /// of the type, and the value of the map entry is the type. |
| class type_maps |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| priv_sptr priv_; |
| |
| public: |
| |
| type_maps(); |
| |
| bool |
| empty() const; |
| |
| const istring_type_base_wptrs_map_type& |
| basic_types() const; |
| |
| istring_type_base_wptrs_map_type& |
| basic_types(); |
| |
| const istring_type_base_wptrs_map_type& |
| class_types() const; |
| |
| istring_type_base_wptrs_map_type& |
| class_types(); |
| |
| istring_type_base_wptrs_map_type& |
| union_types(); |
| |
| const istring_type_base_wptrs_map_type& |
| union_types() const; |
| |
| istring_type_base_wptrs_map_type& |
| enum_types(); |
| |
| const istring_type_base_wptrs_map_type& |
| enum_types() const; |
| |
| istring_type_base_wptrs_map_type& |
| typedef_types(); |
| |
| const istring_type_base_wptrs_map_type& |
| typedef_types() const; |
| |
| istring_type_base_wptrs_map_type& |
| qualified_types(); |
| |
| const istring_type_base_wptrs_map_type& |
| qualified_types() const; |
| |
| istring_type_base_wptrs_map_type& |
| pointer_types(); |
| |
| const istring_type_base_wptrs_map_type& |
| pointer_types() const; |
| |
| istring_type_base_wptrs_map_type& |
| reference_types(); |
| |
| const istring_type_base_wptrs_map_type& |
| reference_types() const; |
| |
| istring_type_base_wptrs_map_type& |
| array_types(); |
| |
| const istring_type_base_wptrs_map_type& |
| array_types() const; |
| |
| const istring_type_base_wptrs_map_type& |
| subrange_types() const; |
| |
| istring_type_base_wptrs_map_type& |
| subrange_types(); |
| |
| istring_type_base_wptrs_map_type& |
| function_types(); |
| |
| const istring_type_base_wptrs_map_type& |
| function_types() const; |
| |
| const vector<type_base_wptr>& |
| get_types_sorted_by_name() const; |
| }; // end class type_maps; |
| |
| /// This is the abstraction of the set of relevant artefacts (types, |
| /// variable declarations, functions, templates, etc) bundled together |
| /// into a translation unit. |
| class translation_unit : public traversable_base |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| // Forbidden |
| translation_unit(); |
| |
| public: |
| /// Convenience typedef for a shared pointer on a @ref global_scope. |
| typedef shared_ptr<scope_decl> global_scope_sptr; |
| |
| /// The language of the translation unit. |
| enum language |
| { |
| LANG_UNKNOWN = 0, |
| LANG_Cobol74, |
| LANG_Cobol85, |
| LANG_C89, |
| LANG_C99, |
| LANG_C11, |
| LANG_C, |
| LANG_C_plus_plus_03, |
| LANG_C_plus_plus_11, |
| LANG_C_plus_plus_14, |
| LANG_C_plus_plus, |
| LANG_ObjC, |
| LANG_ObjC_plus_plus, |
| LANG_Fortran77, |
| LANG_Fortran90, |
| LANG_Fortran95, |
| LANG_Ada83, |
| LANG_Ada95, |
| LANG_Pascal83, |
| LANG_Modula2, |
| LANG_Java, |
| LANG_PL1, |
| LANG_UPC, |
| LANG_D, |
| LANG_Python, |
| LANG_Go, |
| LANG_Rust, |
| LANG_Mips_Assembler |
| }; |
| |
| public: |
| translation_unit(const ir::environment* env, |
| const std::string& path, |
| char address_size = 0); |
| |
| virtual ~translation_unit(); |
| |
| const environment* |
| get_environment() const; |
| |
| environment* |
| get_environment(); |
| |
| void |
| set_environment(const environment*); |
| |
| language |
| get_language() const; |
| |
| void |
| set_language(language l); |
| |
| const std::string& |
| get_path() const; |
| |
| void |
| set_path(const string&); |
| |
| const std::string& |
| get_compilation_dir_path() const; |
| |
| void |
| set_compilation_dir_path(const std::string&); |
| |
| const std::string& |
| get_absolute_path() const; |
| |
| void |
| set_corpus(corpus*); |
| |
| const corpus* |
| get_corpus() const; |
| |
| corpus* |
| get_corpus(); |
| |
| const scope_decl_sptr& |
| get_global_scope() const; |
| |
| scope_decl_sptr& |
| get_global_scope(); |
| |
| const type_maps& |
| get_types() const; |
| |
| type_maps& |
| get_types(); |
| |
| const vector<function_type_sptr>& |
| get_live_fn_types() const; |
| |
| location_manager& |
| get_loc_mgr(); |
| |
| const location_manager& |
| get_loc_mgr() const; |
| |
| bool |
| is_empty() const; |
| |
| char |
| get_address_size() const; |
| |
| void |
| set_address_size(char); |
| |
| bool |
| is_constructed() const; |
| |
| void |
| set_is_constructed(bool); |
| |
| bool |
| operator==(const translation_unit&) const; |
| |
| bool |
| operator!=(const translation_unit&) const; |
| |
| void |
| bind_function_type_life_time(function_type_sptr) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| friend function_type_sptr |
| lookup_function_type_in_translation_unit(const function_type& t, |
| const translation_unit& tu); |
| |
| friend function_type_sptr |
| synthesize_function_type_from_translation_unit(const function_type& fn_type, |
| translation_unit& tu); |
| |
| friend type_base_sptr |
| synthesize_type_from_translation_unit(const type_base_sptr& type, |
| translation_unit& tu); |
| };//end class translation_unit |
| |
| /// A comparison functor to compare translation units based on their |
| /// absolute paths. |
| struct shared_translation_unit_comp |
| { |
| /// Compare two translations units based on their absolute paths. |
| /// |
| /// @param lhs the first translation unit to consider for the |
| /// comparison. |
| /// |
| /// @param rhs the second translatin unit to consider for the |
| /// comparison. |
| bool |
| operator()(const translation_unit_sptr& lhs, |
| const translation_unit_sptr& rhs) const |
| {return lhs->get_absolute_path() < rhs->get_absolute_path();} |
| }; // end struct shared_translation_unit_comp |
| |
| /// Convenience typedef for an ordered set of @ref |
| /// translation_unit_sptr. |
| typedef std::set<translation_unit_sptr, |
| shared_translation_unit_comp> translation_units; |
| |
| string |
| translation_unit_language_to_string(translation_unit::language); |
| |
| translation_unit::language |
| string_to_translation_unit_language(const string&); |
| |
| bool |
| is_c_language(translation_unit::language l); |
| |
| bool |
| is_cplus_plus_language(translation_unit::language l); |
| |
| bool |
| is_java_language(translation_unit::language l); |
| |
| bool |
| is_ada_language(translation_unit::language l); |
| |
| bool |
| operator==(const translation_unit_sptr&, const translation_unit_sptr&); |
| |
| bool |
| operator!=(const translation_unit_sptr&, const translation_unit_sptr&); |
| |
| /// Access specifier for class members. |
| enum access_specifier |
| { |
| no_access, |
| public_access, |
| protected_access, |
| private_access, |
| }; |
| |
| class elf_symbol; |
| /// A convenience typedef for a shared pointer to elf_symbol. |
| typedef shared_ptr<elf_symbol> elf_symbol_sptr; |
| |
| /// A convenience typedef for a weak pointer to elf_symbol. |
| typedef weak_ptr<elf_symbol> elf_symbol_wptr; |
| |
| /// Convenience typedef for a map which key is a string and which |
| /// value if the elf symbol of the same name. |
| typedef abg_compat::unordered_map<string, elf_symbol_sptr> |
| string_elf_symbol_sptr_map_type; |
| |
| /// Convenience typedef for a shared pointer to an |
| /// string_elf_symbol_sptr_map_type. |
| typedef shared_ptr<string_elf_symbol_sptr_map_type> |
| string_elf_symbol_sptr_map_sptr; |
| |
| /// Convenience typedef for a vector of elf_symbol |
| typedef std::vector<elf_symbol_sptr> elf_symbols; |
| |
| /// Convenience typedef for a map which key is a string and which |
| /// value is a vector of elf_symbol. |
| typedef abg_compat::unordered_map<string, elf_symbols> |
| string_elf_symbols_map_type; |
| |
| /// Convenience typedef for a shared pointer to |
| /// string_elf_symbols_map_type. |
| typedef shared_ptr<string_elf_symbols_map_type> string_elf_symbols_map_sptr; |
| |
| /// Abstraction of an elf symbol. |
| /// |
| /// This is useful when a given corpus has been read from an ELF file. |
| /// In that case, a given decl might be associated to its underlying |
| /// ELF symbol, if that decl is publicly exported in the ELF file. In |
| /// that case, comparing decls might involve comparing their |
| /// underlying symbols as well. |
| class elf_symbol |
| { |
| public: |
| /// The type of a symbol. |
| enum type |
| { |
| NOTYPE_TYPE = 0, |
| OBJECT_TYPE, |
| FUNC_TYPE, |
| SECTION_TYPE, |
| FILE_TYPE, |
| COMMON_TYPE, |
| TLS_TYPE, |
| GNU_IFUNC_TYPE |
| }; |
| |
| /// The binding of a symbol. |
| enum binding |
| { |
| LOCAL_BINDING = 0, |
| GLOBAL_BINDING, |
| WEAK_BINDING, |
| GNU_UNIQUE_BINDING |
| }; |
| |
| /// The visibility of the symbol. |
| enum visibility |
| { |
| DEFAULT_VISIBILITY, |
| PROTECTED_VISIBILITY, |
| HIDDEN_VISIBILITY, |
| INTERNAL_VISIBILITY, |
| }; |
| |
| /// Inject the elf_symbol::version here. |
| class version; |
| |
| private: |
| struct priv; |
| shared_ptr<priv> priv_; |
| |
| elf_symbol(); |
| |
| elf_symbol(const environment* e, |
| size_t i, |
| size_t s, |
| const string& n, |
| type t, |
| binding b, |
| bool d, |
| bool c, |
| const version& ve, |
| visibility vi, |
| bool is_linux_string_cst = false); |
| |
| elf_symbol(const elf_symbol&); |
| |
| elf_symbol& |
| operator=(const elf_symbol& s); |
| |
| public: |
| |
| static elf_symbol_sptr |
| create(); |
| |
| static elf_symbol_sptr |
| create(const environment* e, |
| size_t i, |
| size_t s, |
| const string& n, |
| type t, |
| binding b, |
| bool d, |
| bool c, |
| const version& ve, |
| visibility vi, |
| bool is_linux_string_cst = false); |
| |
| const environment* |
| get_environment() const; |
| |
| void |
| set_environment(const environment*) const; |
| |
| size_t |
| get_index() const; |
| |
| void |
| set_index(size_t); |
| |
| bool |
| get_is_linux_string_cst() const; |
| |
| const string& |
| get_name() const; |
| |
| void |
| set_name(const string& n); |
| |
| type |
| get_type() const; |
| |
| void |
| set_type(type t); |
| |
| size_t |
| get_size() const; |
| |
| void |
| set_size(size_t); |
| |
| binding |
| get_binding() const; |
| |
| void |
| set_binding(binding b); |
| |
| version& |
| get_version() const; |
| |
| void |
| set_version(const version& v); |
| |
| void |
| set_visibility(visibility v); |
| |
| visibility |
| get_visibility() const; |
| |
| bool |
| is_defined() const; |
| |
| void |
| is_defined(bool d); |
| |
| bool |
| is_public() const; |
| |
| bool |
| is_function() const; |
| |
| bool |
| is_variable() const; |
| |
| const elf_symbol_sptr |
| get_main_symbol() const; |
| |
| elf_symbol_sptr |
| get_main_symbol(); |
| |
| bool |
| is_main_symbol() const; |
| |
| elf_symbol_sptr |
| get_next_alias() const; |
| |
| bool |
| has_aliases() const; |
| |
| int |
| get_number_of_aliases() const; |
| |
| void |
| add_alias(const elf_symbol_sptr&); |
| |
| bool |
| is_common_symbol() const; |
| |
| bool |
| has_other_common_instances() const; |
| |
| elf_symbol_sptr |
| get_next_common_instance() const; |
| |
| void |
| add_common_instance(const elf_symbol_sptr&); |
| |
| const string& |
| get_id_string() const; |
| |
| elf_symbol_sptr |
| get_alias_from_name(const string& name) const; |
| |
| elf_symbol_sptr |
| get_alias_which_equals(const elf_symbol& other) const; |
| |
| string |
| get_aliases_id_string(const string_elf_symbols_map_type& symtab, |
| bool include_symbol_itself = true) const; |
| |
| string |
| get_aliases_id_string(bool include_symbol_itself = true) const; |
| |
| static bool |
| get_name_and_version_from_id(const string& id, |
| string& name, |
| string& ver); |
| |
| bool |
| operator==(const elf_symbol&) const; |
| |
| bool |
| does_alias(const elf_symbol&) const; |
| }; // end class elf_symbol. |
| |
| std::ostream& |
| operator<<(std::ostream& o, elf_symbol::type t); |
| |
| std::ostream& |
| operator<<(std::ostream& o, elf_symbol::binding t); |
| |
| bool |
| string_to_elf_symbol_type(const string&, elf_symbol::type&); |
| |
| bool |
| string_to_elf_symbol_binding(const string&, elf_symbol::binding&); |
| |
| bool |
| string_to_elf_symbol_visibility(const string&, elf_symbol::visibility&); |
| |
| bool |
| elf_symbol_is_function(elf_symbol::type); |
| |
| bool |
| elf_symbol_is_variable(elf_symbol::type); |
| |
| bool |
| operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs); |
| |
| bool |
| operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs); |
| |
| bool |
| elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2); |
| |
| void |
| compute_aliases_for_elf_symbol(const elf_symbol& symbol, |
| const string_elf_symbols_map_type& symtab, |
| vector<elf_symbol_sptr>& alias_set); |
| |
| /// The abstraction of the version of an ELF symbol. |
| class elf_symbol::version |
| { |
| struct priv; |
| shared_ptr<priv> priv_; |
| |
| public: |
| version(); |
| |
| version(const string& v, |
| bool is_default); |
| |
| version(const version& v); |
| |
| operator const string&() const; |
| |
| const string& |
| str() const; |
| |
| void |
| str(const string& s); |
| |
| bool |
| is_default() const; |
| |
| void |
| is_default(bool f); |
| |
| bool |
| is_empty() const; |
| |
| bool |
| operator==(const version& o) const; |
| |
| bool |
| operator!=(const version& o) const; |
| |
| version& |
| operator=(const version& o); |
| };// end class elf_symbol::version |
| |
| class context_rel; |
| /// A convenience typedef for shared pointers to @ref context_rel |
| typedef shared_ptr<context_rel> context_rel_sptr; |
| |
| /// The abstraction of the relationship between an entity and its |
| /// containing scope (its context). That relationship can carry |
| /// properties like access rights (if the parent is a class_decl), |
| /// etc. |
| /// |
| /// But importantly, this relationship carries a pointer to the |
| /// actualy parent. |
| class context_rel |
| { |
| protected: |
| scope_decl* scope_; |
| enum access_specifier access_; |
| bool is_static_; |
| |
| public: |
| context_rel() |
| : scope_(0), |
| access_(no_access), |
| is_static_(false) |
| {} |
| |
| context_rel(scope_decl* s) |
| : scope_(s), |
| access_(no_access), |
| is_static_(false) |
| {} |
| |
| context_rel(scope_decl* s, |
| access_specifier a, |
| bool f) |
| : scope_(s), |
| access_(a), |
| is_static_(f) |
| {} |
| |
| scope_decl* |
| get_scope() const |
| {return scope_;} |
| |
| access_specifier |
| get_access_specifier() const |
| {return access_;} |
| |
| void |
| set_access_specifier(access_specifier a) |
| {access_ = a;} |
| |
| bool |
| get_is_static() const |
| {return is_static_;} |
| |
| void |
| set_is_static(bool s) |
| {is_static_ = s;} |
| |
| void |
| set_scope(scope_decl* s) |
| {scope_ = s;} |
| |
| bool |
| operator==(const context_rel& o)const |
| { |
| return (access_ == o.access_ |
| && is_static_ == o.is_static_); |
| } |
| |
| /// Inequality operator. |
| /// |
| /// @param o the other instance of @ref context_rel to compare the |
| /// current instance against. |
| /// |
| /// @return true iff the current instance of @ref context_rel is |
| /// different from @p o. |
| bool |
| operator!=(const context_rel& o) const |
| {return !operator==(o);} |
| |
| virtual ~context_rel(); |
| };// end class context_rel |
| |
| /// A bitfield that gives callers of abigail::ir::equals() some |
| /// insight about how different two internal representation artifacts |
| /// are. |
| enum change_kind |
| { |
| NO_CHANGE_KIND = 0, |
| |
| /// This means that a given IR artifact has a local type change. |
| LOCAL_TYPE_CHANGE_KIND = 1 << 0, |
| |
| /// This means that a given IR artifact has a local non-type change. |
| /// That is a change that is carried by the artifact itself, not by |
| /// its type. |
| LOCAL_NON_TYPE_CHANGE_KIND = 1 << 1, |
| |
| /// Testing (anding) against this mask means that a given IR artifact has |
| /// local differences, with respect to the other artifact it was compared |
| /// against. A local change is a change that is carried by the artifact |
| /// itself (or its type), rather than by one off its sub-types. |
| ALL_LOCAL_CHANGES_MASK = LOCAL_TYPE_CHANGE_KIND | LOCAL_NON_TYPE_CHANGE_KIND, |
| |
| /// This means that a given IR artifact has changes in some of its |
| /// sub-types, with respect to the other artifact it was compared |
| /// against. |
| SUBTYPE_CHANGE_KIND = 1 << 2, |
| };// end enum change_kind |
| |
| change_kind |
| operator|(change_kind, change_kind); |
| |
| change_kind |
| operator&(change_kind, change_kind); |
| |
| change_kind& |
| operator|=(change_kind&, change_kind); |
| |
| change_kind& |
| operator&=(change_kind&, change_kind); |
| |
| bool |
| equals(const decl_base&, const decl_base&, change_kind*); |
| |
| /// The base class of both types and declarations. |
| class type_or_decl_base : public ir_traversable_base |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| mutable priv_sptr priv_; |
| |
| type_or_decl_base(); |
| |
| protected: |
| |
| /// This is a bitmap type which instance is meant to contain the |
| /// runtime type of a given ABI artifact. Bits of the identifiers |
| /// of the type of a given artifact as well as the types it inherits |
| /// from are to be set to 1. |
| enum type_or_decl_kind |
| { |
| ABSTRACT_TYPE_OR_DECL, |
| ABSTRACT_DECL_BASE = 1, |
| ABSTRACT_SCOPE_DECL = 1 << 1, |
| GLOBAL_SCOPE_DECL = 1 << 2, |
| NAMESPACE_DECL = 1 << 3, |
| VAR_DECL = 1 << 4, |
| FUNCTION_DECL = 1 << 5, |
| FUNCTION_PARAMETER_DECL = 1 << 6, |
| METHOD_DECL = 1 << 7, |
| TEMPLATE_DECL = 1 << 8, |
| ABSTRACT_TYPE_BASE = 1 << 9, |
| ABSTRACT_SCOPE_TYPE_DECL = 1 << 10, |
| BASIC_TYPE = 1 << 11, |
| QUALIFIED_TYPE = 1 << 12, |
| POINTER_TYPE = 1 << 13, |
| REFERENCE_TYPE = 1 << 14, |
| ARRAY_TYPE = 1 << 15, |
| ENUM_TYPE = 1 << 16, |
| TYPEDEF_TYPE = 1 << 17, |
| CLASS_TYPE = 1 << 18, |
| UNION_TYPE = 1 << 19, |
| FUNCTION_TYPE = 1 << 20, |
| METHOD_TYPE = 1 << 21, |
| }; // end enum type_or_decl_kind |
| |
| enum type_or_decl_kind |
| kind() const; |
| |
| void |
| kind(enum type_or_decl_kind); |
| |
| const void* |
| runtime_type_instance() const; |
| |
| void* |
| runtime_type_instance(); |
| |
| void |
| runtime_type_instance(void*); |
| |
| const void* |
| type_or_decl_base_pointer() const; |
| |
| void* |
| type_or_decl_base_pointer(); |
| |
| bool hashing_started() const; |
| |
| void hashing_started(bool) const; |
| |
| public: |
| |
| type_or_decl_base(const environment*, |
| enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL); |
| |
| type_or_decl_base(const type_or_decl_base&); |
| |
| virtual ~type_or_decl_base(); |
| |
| const environment* |
| get_environment() const; |
| |
| environment* |
| get_environment(); |
| |
| void |
| set_environment(const environment*); |
| |
| const corpus* |
| get_corpus() const; |
| |
| corpus* |
| get_corpus(); |
| |
| void |
| set_translation_unit(translation_unit*); |
| |
| const translation_unit* |
| get_translation_unit() const; |
| |
| translation_unit* |
| get_translation_unit(); |
| |
| type_or_decl_base& |
| operator=(const type_or_decl_base&); |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const = 0; |
| |
| friend type_or_decl_base::type_or_decl_kind |
| operator|(type_or_decl_base::type_or_decl_kind, |
| type_or_decl_base::type_or_decl_kind); |
| |
| friend type_or_decl_base::type_or_decl_kind& |
| operator|=(type_or_decl_base::type_or_decl_kind&, |
| type_or_decl_base::type_or_decl_kind); |
| |
| friend type_or_decl_base::type_or_decl_kind |
| operator&(type_or_decl_base::type_or_decl_kind, |
| type_or_decl_base::type_or_decl_kind); |
| |
| friend type_or_decl_base::type_or_decl_kind& |
| operator&=(type_or_decl_base::type_or_decl_kind&, |
| type_or_decl_base::type_or_decl_kind); |
| |
| friend class_decl* |
| is_class_type(const type_or_decl_base*); |
| |
| friend pointer_type_def* |
| is_pointer_type(type_or_decl_base*); |
| |
| friend type_base* |
| is_type(const type_or_decl_base*); |
| |
| friend decl_base* |
| is_decl(const type_or_decl_base* d); |
| }; // end class type_or_decl_base |
| |
| type_or_decl_base::type_or_decl_kind |
| operator|(type_or_decl_base::type_or_decl_kind, |
| type_or_decl_base::type_or_decl_kind); |
| |
| type_or_decl_base::type_or_decl_kind& |
| operator|=(type_or_decl_base::type_or_decl_kind&, |
| type_or_decl_base::type_or_decl_kind); |
| |
| type_or_decl_base::type_or_decl_kind |
| operator&(type_or_decl_base::type_or_decl_kind, |
| type_or_decl_base::type_or_decl_kind); |
| |
| type_or_decl_base::type_or_decl_kind& |
| operator&=(type_or_decl_base::type_or_decl_kind&, |
| type_or_decl_base::type_or_decl_kind); |
| |
| bool |
| operator==(const type_or_decl_base&, const type_or_decl_base&); |
| |
| bool |
| operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&); |
| |
| bool |
| operator!=(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&); |
| |
| void |
| set_environment_for_artifact(type_or_decl_base* artifact, |
| const environment* env); |
| |
| void |
| set_environment_for_artifact(type_or_decl_base_sptr artifact, |
| const environment* env); |
| |
| /// The base type of all declarations. |
| class decl_base : public virtual type_or_decl_base |
| { |
| // Forbidden |
| decl_base(); |
| |
| struct priv; |
| |
| protected: |
| |
| const interned_string& |
| peek_qualified_name() const; |
| |
| void |
| set_qualified_name(const interned_string&) const; |
| |
| const interned_string& |
| peek_temporary_qualified_name() const; |
| |
| void |
| set_temporary_qualified_name(const interned_string&) const; |
| |
| public: |
| // This is public because some internals of the library need to |
| // update it. But it's opaque to client code anyway, so no big |
| // deal. Also, it's not handled by a shared_ptr because accessing |
| // the data members of the priv struct for this decl_base shows up |
| // on performance profiles when dealing with big binaries with a lot |
| // of types; dereferencing the shared_ptr involves locking of some |
| // sort and that is slower than just dereferencing a pointer likere |
| // here. There are other types for which the priv pointer is |
| // managed using shared_ptr just fine, because those didn't show up |
| // during our performance profiling. |
| priv* priv_; |
| |
| /// Facility to hash instances of decl_base. |
| struct hash; |
| |
| /// ELF visibility |
| enum visibility |
| { |
| VISIBILITY_NONE, |
| VISIBILITY_DEFAULT, |
| VISIBILITY_PROTECTED, |
| VISIBILITY_HIDDEN, |
| VISIBILITY_INTERNAL |
| }; |
| |
| /// ELF binding |
| enum binding |
| { |
| BINDING_NONE, |
| BINDING_LOCAL, |
| BINDING_GLOBAL, |
| BINDING_WEAK |
| }; |
| |
| virtual void |
| set_scope(scope_decl*); |
| |
| protected: |
| const context_rel* |
| get_context_rel() const; |
| |
| context_rel* |
| get_context_rel(); |
| |
| void |
| set_context_rel(context_rel *c); |
| |
| public: |
| decl_base(const environment* e, |
| const string& name, |
| const location& locus, |
| const string& mangled_name = "", |
| visibility vis = VISIBILITY_DEFAULT); |
| |
| decl_base(const environment* e, |
| const interned_string& name, |
| const location& locus, |
| const interned_string& mangled_name = interned_string(), |
| visibility vis = VISIBILITY_DEFAULT); |
| |
| decl_base(const environment*, const location&); |
| |
| decl_base(const decl_base&); |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator!=(const decl_base&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~decl_base(); |
| |
| virtual size_t |
| get_hash() const; |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| virtual void |
| get_qualified_name(interned_string& qualified_name, |
| bool internal = false) const; |
| |
| virtual const interned_string& |
| get_qualified_name(bool internal = false) const; |
| |
| virtual const interned_string& |
| get_scoped_name() const; |
| |
| bool |
| get_is_in_public_symbol_table() const; |
| |
| void |
| set_is_in_public_symbol_table(bool); |
| |
| const location& |
| get_location() const; |
| |
| void |
| set_location(const location& l); |
| |
| const interned_string& |
| get_name() const; |
| |
| const interned_string& |
| get_qualified_parent_name() const; |
| |
| void |
| set_name(const string& n); |
| |
| bool |
| get_is_anonymous() const; |
| |
| void |
| set_is_anonymous(bool); |
| |
| bool |
| get_is_artificial() const; |
| |
| void |
| set_is_artificial(bool); |
| |
| bool |
| get_has_anonymous_parent() const; |
| |
| void |
| set_has_anonymous_parent(bool f) const; |
| |
| bool |
| get_is_anonymous_or_has_anonymous_parent() const; |
| |
| const interned_string& |
| get_linkage_name() const; |
| |
| virtual void |
| set_linkage_name(const string& m); |
| |
| scope_decl* |
| get_scope() const; |
| |
| visibility |
| get_visibility() const; |
| |
| void |
| set_visibility(visibility v); |
| |
| friend type_base_sptr |
| canonicalize(type_base_sptr); |
| |
| friend type_base_sptr |
| re_canonicalize(type_base_sptr); |
| |
| friend bool |
| equals(const decl_base&, const decl_base&, change_kind*); |
| |
| friend bool |
| equals(const var_decl&, const var_decl&, change_kind*); |
| |
| friend decl_base_sptr |
| add_decl_to_scope(decl_base_sptr decl, scope_decl* scpe); |
| |
| friend void |
| remove_decl_from_scope(decl_base_sptr); |
| |
| friend decl_base_sptr |
| insert_decl_into_scope(decl_base_sptr, |
| vector<shared_ptr<decl_base> >::iterator, |
| scope_decl*); |
| |
| friend enum access_specifier |
| get_member_access_specifier(const decl_base& d); |
| |
| friend enum access_specifier |
| get_member_access_specifier(const decl_base_sptr& d); |
| |
| friend void |
| set_member_access_specifier(decl_base& d, |
| access_specifier a); |
| |
| friend bool |
| get_member_is_static(const decl_base& d); |
| |
| friend bool |
| get_member_is_static(const decl_base_sptr& d); |
| |
| friend void |
| set_member_is_static(const decl_base_sptr& d, bool s); |
| |
| friend void |
| set_member_is_static(decl_base& d, bool s); |
| |
| friend bool |
| get_member_function_is_virtual(const function_decl& f); |
| |
| friend void |
| set_member_function_is_virtual(function_decl&, bool); |
| |
| friend class class_decl; |
| |
| friend class scope_decl; |
| };// end class decl_base |
| |
| bool |
| operator==(const decl_base_sptr&, const decl_base_sptr&); |
| |
| bool |
| operator!=(const decl_base_sptr&, const decl_base_sptr&); |
| |
| bool |
| operator==(const type_base_sptr&, const type_base_sptr&); |
| |
| bool |
| operator!=(const type_base_sptr&, const type_base_sptr&); |
| |
| std::ostream& |
| operator<<(std::ostream&, decl_base::visibility); |
| |
| std::ostream& |
| operator<<(std::ostream&, decl_base::binding); |
| |
| bool |
| equals(const scope_decl&, const scope_decl&, change_kind*); |
| |
| /// A declaration that introduces a scope. |
| class scope_decl : public virtual decl_base |
| { |
| public: |
| |
| /// Convenience typedef for a vector of @ref decl_base_sptr. |
| typedef std::vector<decl_base_sptr > declarations; |
| /// Convenience typedef for a vector of @ref function_type_sptr. |
| typedef std::vector<function_type_sptr > function_types; |
| /// Convenience typedef for a vector of @ref scope_decl_sptr. |
| typedef std::vector<scope_decl_sptr> scopes; |
| /// The type of the private data of @ref scope_decl. |
| struct priv; |
| /// A convenience typedef for a shared pointer to scope_decl::priv. |
| typedef shared_ptr<priv> priv_sptr; |
| |
| private: |
| priv_sptr priv_; |
| |
| scope_decl(); |
| |
| protected: |
| virtual decl_base_sptr |
| add_member_decl(const decl_base_sptr& member); |
| |
| virtual decl_base_sptr |
| insert_member_decl(const decl_base_sptr& member, |
| declarations::iterator before); |
| |
| virtual void |
| remove_member_decl(decl_base_sptr member); |
| |
| public: |
| struct hash; |
| |
| scope_decl(const environment* env, |
| const string& name, const location& locus, |
| visibility vis = VISIBILITY_DEFAULT); |
| |
| scope_decl(const environment* env, location& l); |
| |
| virtual size_t |
| get_hash() const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| const canonical_type_sptr_set_type& |
| get_canonical_types() const; |
| |
| canonical_type_sptr_set_type& |
| get_canonical_types(); |
| |
| const type_base_sptrs_type& |
| get_sorted_canonical_types() const; |
| |
| const declarations& |
| get_member_decls() const; |
| |
| declarations& |
| get_member_decls(); |
| |
| virtual size_t |
| get_num_anonymous_member_classes() const; |
| |
| virtual size_t |
| get_num_anonymous_member_unions() const; |
| |
| virtual size_t |
| get_num_anonymous_member_enums() const; |
| |
| scopes& |
| get_member_scopes(); |
| |
| const scopes& |
| get_member_scopes() const; |
| |
| bool |
| is_empty() const; |
| |
| bool |
| find_iterator_for_member(const decl_base*, declarations::iterator&); |
| |
| bool |
| find_iterator_for_member(const decl_base_sptr, declarations::iterator&); |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| |
| virtual ~scope_decl(); |
| |
| friend decl_base_sptr |
| add_decl_to_scope(decl_base_sptr decl, scope_decl* scope); |
| |
| friend decl_base_sptr |
| insert_decl_into_scope(decl_base_sptr decl, |
| scope_decl::declarations::iterator before, |
| scope_decl* scope); |
| |
| friend void |
| remove_decl_from_scope(decl_base_sptr decl); |
| |
| friend type_base_sptr |
| canonicalize(type_base_sptr); |
| };//end class scope_decl |
| |
| bool |
| operator==(const scope_decl_sptr&, const scope_decl_sptr&); |
| |
| bool |
| operator!=(const scope_decl_sptr&, const scope_decl_sptr&); |
| |
| /// Hasher for the @ref scope_decl type. |
| struct scope_decl::hash |
| { |
| size_t |
| operator()(const scope_decl& d) const; |
| |
| size_t |
| operator()(const scope_decl* d) const; |
| }; |
| |
| /// This abstracts the global scope of a given translation unit. |
| /// |
| /// Only one instance of this class must be present in a given |
| /// translation_unit. That instance is implicitely created the first |
| /// time translatin_unit::get_global_scope is invoked. |
| class global_scope : public scope_decl |
| { |
| translation_unit* translation_unit_; |
| |
| global_scope(translation_unit *tu); |
| |
| public: |
| |
| friend class translation_unit; |
| |
| translation_unit* |
| get_translation_unit() const |
| {return translation_unit_;} |
| |
| virtual ~global_scope(); |
| }; |
| |
| bool |
| equals(const type_base&, const type_base&, change_kind*); |
| |
| /// An abstraction helper for type declarations |
| class type_base : public virtual type_or_decl_base |
| { |
| struct priv; |
| |
| public: |
| // This priv pointer is not handled by a shared_ptr because |
| // accessing the data members of the priv struct for this type_base |
| // shows up on performance profiles when dealing with big binaries |
| // with a lot of types; dereferencing the shared_ptr involves |
| // locking of some sort and that is slower than just dereferencing a |
| // pointer likere here. There are other types for which the priv |
| // pointer is managed using shared_ptr just fine, because those |
| // didn't show up during our performance profiling. |
| priv* priv_; |
| |
| private: |
| // Forbid this. |
| type_base(); |
| |
| static type_base_sptr |
| get_canonical_type_for(type_base_sptr); |
| |
| protected: |
| virtual void |
| on_canonical_type_set(); |
| |
| public: |
| |
| /// A hasher for type_base types. |
| struct hash; |
| |
| /// A hasher for types. It gets the dynamic type of the current |
| /// instance of type and hashes it accordingly. Note that the hashing |
| /// function of this hasher must be updated each time a new kind of |
| /// type is added to the IR. |
| struct dynamic_hash; |
| |
| /// A hasher for shared_ptr<type_base> that will hash it based on the |
| /// runtime type of the type pointed to. |
| struct shared_ptr_hash; |
| |
| type_base(const environment* e, size_t s, size_t a); |
| |
| friend type_base_sptr canonicalize(type_base_sptr); |
| |
| friend type_base_sptr re_canonicalize(type_base_sptr); |
| |
| type_base_sptr |
| get_canonical_type() const; |
| |
| type_base* |
| get_naked_canonical_type() const; |
| |
| const interned_string& |
| get_cached_pretty_representation(bool internal = false) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| operator!=(const type_base&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| |
| virtual ~type_base(); |
| |
| virtual void |
| set_size_in_bits(size_t); |
| |
| virtual size_t |
| get_size_in_bits() const; |
| |
| virtual void |
| set_alignment_in_bits(size_t); |
| |
| virtual size_t |
| get_alignment_in_bits() const; |
| };//end class type_base |
| |
| /// Hash functor for instances of @ref type_base. |
| struct type_base::hash |
| { |
| size_t |
| operator()(const type_base& t) const; |
| |
| size_t |
| operator()(const type_base* t) const; |
| |
| size_t |
| operator()(const type_base_sptr t) const; |
| }; // end struct type_base::hash |
| |
| /// A predicate for deep equality of instances of |
| /// type_base* |
| struct type_ptr_equal |
| { |
| bool |
| operator()(const type_base* l, const type_base* r) const |
| { |
| if (!!l != !!r) |
| return false; |
| |
| if (l == r) |
| return true; |
| |
| if (l) |
| return *l == *r; |
| |
| return true; |
| } |
| }; |
| |
| /// A predicate for deep equality of instances of |
| /// shared_ptr<type_base> |
| struct type_shared_ptr_equal |
| { |
| bool |
| operator()(const type_base_sptr l, const type_base_sptr r) const |
| { |
| if (!!l != !!r) |
| return false; |
| |
| if (l.get() == r.get()) |
| return true; |
| |
| if (l) |
| return *l == *r; |
| |
| return true; |
| } |
| }; |
| |
| bool |
| equals(const type_decl&, const type_decl&, change_kind*); |
| |
| /// A basic type declaration that introduces no scope. |
| class type_decl : public virtual decl_base, public virtual type_base |
| { |
| // Forbidden. |
| type_decl(); |
| |
| public: |
| |
| /// Facility to hash instance of type_decl |
| struct hash; |
| |
| type_decl(const environment* env, |
| const string& name, |
| size_t size_in_bits, |
| size_t alignment_in_bits, |
| const location& locus, |
| const string& mangled_name = "", |
| visibility vis = VISIBILITY_DEFAULT); |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_decl&) const; |
| |
| bool operator!=(const type_decl&)const; |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = false) const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| |
| virtual ~type_decl(); |
| };// end class type_decl. |
| |
| bool |
| equals(const scope_type_decl&, const scope_type_decl&, change_kind*); |
| |
| bool |
| operator==(const type_decl_sptr&, const type_decl_sptr&); |
| |
| bool |
| operator!=(const type_decl_sptr&, const type_decl_sptr&); |
| |
| /// A type that introduces a scope. |
| class scope_type_decl : public scope_decl, public virtual type_base |
| { |
| scope_type_decl(); |
| |
| public: |
| |
| /// Hasher for instances of scope_type_decl |
| struct hash; |
| |
| scope_type_decl(const environment* env, const string& name, |
| size_t size_in_bits, size_t alignment_in_bits, |
| const location& locus, visibility vis = VISIBILITY_DEFAULT); |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| |
| virtual ~scope_type_decl(); |
| }; |
| |
| /// The abstraction of a namespace declaration |
| class namespace_decl : public scope_decl |
| { |
| public: |
| |
| namespace_decl(const environment* env, const string& name, |
| const location& locus, visibility vis = VISIBILITY_DEFAULT); |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| |
| virtual ~namespace_decl(); |
| |
| bool is_empty_or_has_empty_sub_namespaces() const; |
| };// end class namespace_decl |
| |
| bool |
| equals(const qualified_type_def&, const qualified_type_def&, change_kind*); |
| |
| /// The abstraction of a qualified type. |
| class qualified_type_def : public virtual type_base, public virtual decl_base |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| priv_sptr priv_; |
| |
| // Forbidden. |
| qualified_type_def(); |
| |
| protected: |
| string build_name(bool, bool internal = false) const; |
| |
| public: |
| |
| /// A Hasher for instances of qualified_type_def |
| struct hash; |
| |
| /// Bit field values representing the cv qualifiers of the |
| /// underlying type. |
| enum CV |
| { |
| CV_NONE = 0, |
| CV_CONST = 1, |
| CV_VOLATILE = 1 << 1, |
| CV_RESTRICT = 1 << 2 |
| }; |
| |
| qualified_type_def(type_base_sptr type, CV quals, const location& locus); |
| |
| virtual size_t |
| get_size_in_bits() const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| operator==(const qualified_type_def&) const; |
| |
| CV |
| get_cv_quals() const; |
| |
| void |
| set_cv_quals(CV cv_quals); |
| |
| string |
| get_cv_quals_string_prefix() const; |
| |
| type_base_sptr |
| get_underlying_type() const; |
| |
| virtual void |
| get_qualified_name(interned_string& qualified_name, |
| bool internal = false) const; |
| |
| virtual const interned_string& |
| get_qualified_name(bool internal = false) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~qualified_type_def(); |
| }; // end class qualified_type_def. |
| |
| bool |
| operator==(const qualified_type_def_sptr&, const qualified_type_def_sptr&); |
| |
| bool |
| operator!=(const qualified_type_def_sptr&, const qualified_type_def_sptr&); |
| |
| qualified_type_def::CV |
| operator|(qualified_type_def::CV, qualified_type_def::CV); |
| |
| qualified_type_def::CV& |
| operator|=(qualified_type_def::CV&, qualified_type_def::CV); |
| |
| qualified_type_def::CV |
| operator&(qualified_type_def::CV, qualified_type_def::CV); |
| |
| qualified_type_def::CV |
| operator~(qualified_type_def::CV); |
| |
| std::ostream& |
| operator<<(std::ostream&, qualified_type_def::CV); |
| |
| string |
| get_string_representation_of_cv_quals(const qualified_type_def::CV); |
| |
| interned_string |
| get_name_of_qualified_type(const type_base_sptr& underlying_type, |
| qualified_type_def::CV quals, |
| bool qualified = true, bool internal = false); |
| |
| qualified_type_def_sptr |
| lookup_qualified_type(const type_base_sptr&, |
| qualified_type_def::CV, |
| const translation_unit&); |
| bool |
| equals(const pointer_type_def&, const pointer_type_def&, change_kind*); |
| |
| /// The abstraction of a pointer type. |
| class pointer_type_def : public virtual type_base, public virtual decl_base |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| // Forbidden. |
| pointer_type_def(); |
| |
| public: |
| |
| /// A hasher for instances of pointer_type_def |
| struct hash; |
| |
| pointer_type_def(const type_base_sptr& pointed_to_type, size_t size_in_bits, |
| size_t alignment_in_bits, const location& locus); |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| bool |
| operator==(const pointer_type_def&) const; |
| |
| const type_base_sptr |
| get_pointed_to_type() const; |
| |
| type_base* |
| get_naked_pointed_to_type() const; |
| |
| virtual void |
| get_qualified_name(interned_string&, bool internal = false) const; |
| |
| virtual const interned_string& |
| get_qualified_name(bool internal = false) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~pointer_type_def(); |
| }; // end class pointer_type_def |
| |
| bool |
| operator==(const pointer_type_def_sptr&, const pointer_type_def_sptr&); |
| |
| bool |
| operator!=(const pointer_type_def_sptr&, const pointer_type_def_sptr&); |
| |
| bool |
| equals(const reference_type_def&, const reference_type_def&, change_kind*); |
| |
| |
| /// Abstracts a reference type. |
| class reference_type_def : public virtual type_base, public virtual decl_base |
| { |
| type_base_wptr pointed_to_type_; |
| bool is_lvalue_; |
| |
| // Forbidden. |
| reference_type_def(); |
| |
| public: |
| |
| /// Hasher for intances of reference_type_def. |
| struct hash; |
| |
| reference_type_def(const type_base_sptr pointed_to_type, |
| bool lvalue, size_t size_in_bits, |
| size_t alignment_in_bits, const location& locus); |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| bool |
| operator==(const reference_type_def&) const; |
| |
| type_base_sptr |
| get_pointed_to_type() const; |
| |
| bool |
| is_lvalue() const; |
| |
| virtual void |
| get_qualified_name(interned_string& qualified_name, |
| bool internal = false) const; |
| |
| virtual const interned_string& |
| get_qualified_name(bool internal = false) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~reference_type_def(); |
| }; // end class reference_type_def |
| |
| bool |
| operator==(const reference_type_def_sptr&, const reference_type_def_sptr&); |
| |
| bool |
| operator!=(const reference_type_def_sptr&, const reference_type_def_sptr&); |
| |
| bool |
| equals(const array_type_def&, const array_type_def&, change_kind*); |
| |
| /// The abstraction of an array type. |
| class array_type_def : public virtual type_base, public virtual decl_base |
| { |
| private: |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| priv_sptr priv_; |
| |
| // Forbidden. |
| array_type_def(); |
| |
| public: |
| |
| /// Hasher for intances of array_type_def. |
| struct hash; |
| |
| class subrange_type; |
| |
| /// Convenience typedef for a shared pointer on a @ref |
| /// function_decl::subrange |
| typedef shared_ptr<subrange_type> subrange_sptr; |
| |
| /// Convenience typedef for a vector of @ref subrange_sptr |
| typedef std::vector<subrange_sptr> subranges_type; |
| |
| /// Abstraction for an array range type, like in Ada, or just for an |
| /// array dimension like in C or C++. |
| class subrange_type : public virtual type_base, public virtual decl_base |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| priv_sptr priv_; |
| |
| // Forbidden. |
| subrange_type(); |
| public: |
| |
| /// This class is to hold the value of the bound of a subrange. |
| /// The value can be either signed or unsigned, at least when it |
| /// comes from DWARF. The class keeps the sign information, but |
| /// allows users to access the value as signed or unsigned as they |
| /// see fit. |
| class bound_value |
| { |
| public: |
| enum signedness |
| { |
| UNSIGNED_SIGNEDNESS, |
| SIGNED_SIGNEDNESS |
| }; |
| |
| private: |
| signedness s_; |
| |
| public: |
| union |
| { |
| uint64_t unsigned_; |
| int64_t signed_; |
| } v_; |
| bound_value(); |
| bound_value(uint64_t); |
| bound_value(int64_t); |
| enum signedness get_signedness() const; |
| void set_signedness(enum signedness s); |
| int64_t get_signed_value() const; |
| uint64_t get_unsigned_value(); |
| void set_unsigned(uint64_t v); |
| void set_signed(int64_t v); |
| }; //end class bound_value |
| |
| /// Hasher for an instance of array::subrange |
| struct hash; |
| |
| subrange_type(const environment* env, |
| const string& name, |
| bound_value lower_bound, |
| bound_value upper_bound, |
| type_base_sptr& underlying_type, |
| const location& loc, |
| translation_unit::language l = translation_unit::LANG_C11); |
| |
| subrange_type(const environment* env, |
| const string& name, |
| bound_value lower_bound, |
| bound_value upper_bound, |
| const location& loc, |
| translation_unit::language l = translation_unit::LANG_C11); |
| |
| subrange_type(const environment* env, |
| const string& name, |
| bound_value upper_bound, |
| const location& loc, |
| translation_unit::language l = translation_unit::LANG_C11); |
| |
| type_base_sptr |
| get_underlying_type() const; |
| |
| void |
| set_underlying_type(const type_base_sptr &); |
| |
| int64_t |
| get_upper_bound() const; |
| |
| int64_t |
| get_lower_bound() const; |
| |
| void |
| set_upper_bound(int64_t ub); |
| |
| void |
| set_lower_bound(int64_t lb); |
| |
| uint64_t |
| get_length() const; |
| |
| bool |
| is_infinite() const; |
| |
| void |
| is_infinite(bool); |
| |
| translation_unit::language |
| get_language() const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| bool |
| operator==(const subrange_type& o) const; |
| |
| bool |
| operator!=(const subrange_type& o) const; |
| |
| string |
| as_string() const; |
| |
| static string |
| vector_as_string(const vector<subrange_sptr>&); |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| }; // end class subrange_type |
| |
| array_type_def(const type_base_sptr type, |
| const std::vector<subrange_sptr>& subs, |
| const location& locus); |
| |
| translation_unit::language |
| get_language() const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual void |
| get_qualified_name(interned_string& qualified_name, |
| bool internal = false) const; |
| |
| virtual const interned_string& |
| get_qualified_name(bool internal = false) const; |
| |
| const type_base_sptr |
| get_element_type() const; |
| |
| void |
| set_element_type(const type_base_sptr& element_type); |
| |
| virtual void |
| append_subranges(const std::vector<subrange_sptr>& subs); |
| |
| virtual int |
| get_dimension_count() const; |
| |
| virtual bool |
| is_infinite() const; |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| virtual string |
| get_subrange_representation() const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| const location& |
| get_location() const; |
| |
| const std::vector<subrange_sptr>& |
| get_subranges() const; |
| |
| virtual ~array_type_def(); |
| |
| }; // end class array_type_def |
| |
| array_type_def::subrange_type* |
| is_subrange_type(const type_or_decl_base *type); |
| |
| array_type_def::subrange_sptr |
| is_subrange_type(const type_or_decl_base_sptr &type); |
| |
| bool |
| equals(const enum_type_decl&, const enum_type_decl&, change_kind*); |
| |
| /// Abstracts a declaration for an enum type. |
| class enum_type_decl : public virtual type_base, public virtual decl_base |
| { |
| public: |
| |
| /// A hasher for an enum_type_decl. |
| struct hash; |
| |
| /// Enumerator Datum. |
| class enumerator; |
| |
| /// Convenience typedef for a list of @ref enumerator. |
| typedef std::vector<enumerator> enumerators; |
| |
| private: |
| |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| // Forbidden |
| enum_type_decl(); |
| |
| public: |
| |
| /// Constructor of an enum type declaration. |
| /// |
| /// @param name the name of the enum |
| /// |
| /// @param locus the locus at which the enum appears in the source |
| /// code. |
| /// |
| /// @param underlying_type the underlying type of the enum |
| /// |
| /// @param enms a list of enumerators for this enum. |
| /// |
| /// @param mangled_name the mangled name of the enum type. |
| /// |
| /// @param vis the visibility of instances of this type. |
| enum_type_decl(const string& name, |
| const location& locus, |
| type_base_sptr underlying_type, |
| enumerators& enms, |
| const string& mangled_name = "", |
| visibility vis = VISIBILITY_DEFAULT); |
| |
| type_base_sptr |
| get_underlying_type() const; |
| |
| const enumerators& |
| get_enumerators() const; |
| |
| enumerators& |
| get_enumerators(); |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~enum_type_decl(); |
| |
| friend bool |
| enum_has_non_name_change(const enum_type_decl& l, |
| const enum_type_decl& r, |
| change_kind* k); |
| }; // end class enum_type_decl |
| |
| bool |
| operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r); |
| |
| bool |
| operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r); |
| |
| bool |
| enum_has_non_name_change(const enum_type_decl& l, |
| const enum_type_decl& r, |
| change_kind* k); |
| |
| /// The abstraction of an enumerator |
| class enum_type_decl::enumerator |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| priv_sptr priv_; |
| |
| |
| public: |
| |
| enumerator(); |
| |
| enumerator(const environment* env, const string& name, int64_t value); |
| |
| enumerator(const enumerator&); |
| |
| enumerator& |
| operator=(const enumerator&); |
| |
| bool |
| operator==(const enumerator& other) const; |
| |
| bool |
| operator!=(const enumerator& other) const; |
| |
| const environment* |
| get_environment() const; |
| |
| const interned_string& |
| get_name() const; |
| |
| const interned_string& |
| get_qualified_name(bool internal = false) const; |
| |
| void |
| set_name(const string& n); |
| |
| int64_t |
| get_value() const; |
| |
| void |
| set_value(int64_t v); |
| |
| enum_type_decl* |
| get_enum_type() const; |
| |
| void |
| set_enum_type(enum_type_decl*); |
| }; // end class enum_type_def::enumerator |
| |
| bool |
| equals(const typedef_decl&, const typedef_decl&, change_kind*); |
| |
| /// The abstraction of a typedef declaration. |
| class typedef_decl : public virtual type_base, public virtual decl_base |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| // Forbidden |
| typedef_decl(); |
| |
| public: |
| |
| /// Hasher for the typedef_decl type. |
| struct hash; |
| |
| typedef_decl(const string& name, |
| const type_base_sptr underlying_type, |
| const location& locus, |
| const string& mangled_name = "", |
| visibility vis = VISIBILITY_DEFAULT); |
| |
| virtual size_t |
| get_size_in_bits() const; |
| |
| virtual size_t |
| get_alignment_in_bits() const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| type_base_sptr |
| get_underlying_type() const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| |
| virtual ~typedef_decl(); |
| };// end class typedef_decl |
| |
| /// The abstraction for a data member context relationship. This |
| /// relates a data member to its parent class. |
| /// |
| /// The relationship carries properties like the offset of the data |
| /// member, if applicable. |
| class dm_context_rel : public context_rel |
| { |
| protected: |
| bool is_laid_out_; |
| size_t offset_in_bits_; |
| |
| public: |
| dm_context_rel() |
| : context_rel(), |
| is_laid_out_(!is_static_), |
| offset_in_bits_(0) |
| {} |
| |
| dm_context_rel(scope_decl* s, |
| bool is_laid_out, |
| size_t offset_in_bits, |
| access_specifier a, |
| bool is_static) |
| : context_rel(s, a, is_static), |
| is_laid_out_(is_laid_out), |
| offset_in_bits_(offset_in_bits) |
| {} |
| |
| dm_context_rel(scope_decl* s) |
| : context_rel(s), |
| is_laid_out_(!is_static_), |
| offset_in_bits_(0) |
| {} |
| |
| bool |
| get_is_laid_out() const |
| {return is_laid_out_;} |
| |
| void |
| set_is_laid_out(bool f) |
| {is_laid_out_ = f;} |
| |
| size_t |
| get_offset_in_bits() const |
| {return offset_in_bits_;} |
| |
| void |
| set_offset_in_bits(size_t o) |
| {offset_in_bits_ = o;} |
| |
| bool |
| operator==(const dm_context_rel& o) const |
| { |
| if (!context_rel::operator==(o)) |
| return false; |
| |
| return (is_laid_out_ == o.is_laid_out_ |
| && offset_in_bits_ == o.offset_in_bits_); |
| } |
| |
| bool |
| operator!=(const dm_context_rel& o) const |
| {return !operator==(o);} |
| |
| virtual ~dm_context_rel(); |
| };// end class class_decl::dm_context_rel |
| |
| bool |
| equals(const var_decl&, const var_decl&, change_kind*); |
| |
| bool |
| equals_modulo_cv_qualifier(const array_type_def*, const array_type_def*); |
| |
| /// Abstracts a variable declaration. |
| class var_decl : public virtual decl_base |
| { |
| struct priv; |
| shared_ptr<priv> priv_; |
| |
| // Forbidden |
| var_decl(); |
| |
| virtual void |
| set_scope(scope_decl*); |
| |
| public: |
| |
| /// Hasher for a var_decl type. |
| struct hash; |
| |
| /// Equality functor to compare pointers to variable_decl. |
| struct ptr_equal; |
| |
| var_decl(const string& name, |
| type_base_sptr type, |
| const location& locus, |
| const string& mangled_name, |
| visibility vis = VISIBILITY_DEFAULT, |
| binding bind = BINDING_NONE); |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| const type_base_sptr |
| get_type() const; |
| |
| const type_base* |
| get_naked_type() const; |
| |
| binding |
| get_binding() const; |
| |
| void |
| set_binding(binding b); |
| |
| void |
| set_symbol(const elf_symbol_sptr& sym); |
| |
| const elf_symbol_sptr& |
| get_symbol() const; |
| |
| var_decl_sptr |
| clone() const; |
| |
| interned_string |
| get_id() const; |
| |
| virtual const interned_string& |
| get_qualified_name(bool internal = false) const; |
| |
| virtual size_t |
| get_hash() const; |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~var_decl(); |
| |
| friend void |
| set_data_member_offset(var_decl_sptr m, uint64_t o); |
| |
| friend uint64_t |
| get_data_member_offset(const var_decl_sptr m); |
| |
| friend uint64_t |
| get_data_member_offset(const var_decl& m); |
| |
| friend void |
| set_data_member_is_laid_out(var_decl_sptr m, bool l); |
| |
| friend bool |
| get_data_member_is_laid_out(const var_decl& m); |
| |
| friend bool |
| get_data_member_is_laid_out(const var_decl_sptr m); |
| }; // end class var_decl |
| |
| bool |
| equals(const function_decl&, const function_decl&, change_kind*); |
| |
| /// Abstraction for a function declaration. |
| class function_decl : public virtual decl_base |
| { |
| struct priv; |
| // This priv pointer is not handled by a shared_ptr because |
| // accessing the data members of the priv struct for this |
| // function_decl shows up on performance profiles when dealing with |
| // big binaries with a lot of types; dereferencing the shared_ptr |
| // involves locking of some sort and that is slower than just |
| // dereferencing a pointer likere here. There are other types for |
| // which the priv pointer is managed using shared_ptr just fine, |
| // because those didn't show up during our performance profiling. |
| priv* priv_; |
| |
| public: |
| /// Hasher for function_decl |
| struct hash; |
| |
| /// Equality functor to compare pointers to function_decl |
| struct ptr_equal; |
| |
| /// Abstraction for the parameter of a function. |
| class parameter; |
| |
| /// Convenience typedef for a shared pointer on a @ref |
| /// function_decl::parameter |
| typedef shared_ptr<parameter> parameter_sptr; |
| |
| /// Convenience typedef for a vector of @ref parameter_sptr |
| typedef std::vector<parameter_sptr> parameters; |
| |
| function_decl(const string& name, |
| function_type_sptr function_type, |
| bool declared_inline, |
| const location& locus, |
| const string& mangled_name, |
| visibility vis, |
| binding bind); |
| |
| function_decl(const string& name, |
| type_base_sptr fn_type, |
| bool declared_inline, |
| const location& locus, |
| const string& mangled_name = "", |
| visibility vis = VISIBILITY_DEFAULT, |
| binding bind = BINDING_GLOBAL); |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| string |
| get_pretty_representation_of_declarator (bool internal = false) const; |
| |
| const std::vector<parameter_sptr >& |
| get_parameters() const; |
| |
| void |
| append_parameter(parameter_sptr parm); |
| |
| void |
| append_parameters(std::vector<parameter_sptr >& parms); |
| |
| parameters::const_iterator |
| get_first_non_implicit_parm() const; |
| |
| const function_type_sptr |
| get_type() const; |
| |
| const function_type* |
| get_naked_type() const; |
| |
| const type_base_sptr |
| get_return_type() const; |
| |
| void |
| set_type(const function_type_sptr& fn_type); |
| |
| void |
| set_symbol(const elf_symbol_sptr& sym); |
| |
| const elf_symbol_sptr& |
| get_symbol() const; |
| |
| bool |
| is_declared_inline() const; |
| |
| binding |
| get_binding() const; |
| |
| function_decl_sptr |
| clone() const; |
| |
| virtual bool |
| operator==(const decl_base& o) const; |
| |
| /// Return true iff the function takes a variable number of |
| /// parameters. |
| /// |
| /// @return true if the function taks a variable number |
| /// of parameters. |
| bool |
| is_variadic() const; |
| |
| virtual size_t |
| get_hash() const; |
| |
| interned_string |
| get_id() const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| |
| virtual ~function_decl(); |
| }; // end class function_decl |
| |
| bool |
| operator==(const function_decl_sptr& l, const function_decl_sptr& r); |
| |
| bool |
| operator!=(const function_decl_sptr& l, const function_decl_sptr& r); |
| |
| bool |
| function_decls_alias(const function_decl& f1, const function_decl& f2); |
| |
| bool |
| equals(const function_decl::parameter&, |
| const function_decl::parameter&, |
| change_kind*); |
| |
| /// A comparison functor to compare pointer to instances of @ref |
| /// type_or_decl_base. |
| struct type_or_decl_base_comp |
| { |
| /// Comparison operator for ABI artifacts. |
| /// |
| /// @param f the first ABI artifact to consider for the comparison. |
| /// |
| /// @param s the second ABI artifact to consider for the comparison. |
| /// |
| /// @return true iff @p f is lexicographically less than than @p s. |
| bool |
| operator()(const type_or_decl_base *f, |
| const type_or_decl_base *s) |
| { |
| function_decl *f_fn = is_function_decl(f), *s_fn = is_function_decl(s); |
| if (f_fn && s_fn) |
| return function_decl_is_less_than(*f_fn, *s_fn); |
| |
| var_decl *f_var = is_var_decl(f), *s_var = is_var_decl(s); |
| if (f_var && s_var) |
| return get_name(f_var) < get_name(s_var); |
| |
| string l_repr = get_pretty_representation(f), |
| r_repr = get_pretty_representation(s); |
| |
| return l_repr < r_repr; |
| } |
| |
| /// Comparison operator for ABI artifacts. |
| /// |
| /// @param f the first ABI artifact to consider for the comparison. |
| /// |
| /// @param s the second ABI artifact to consider for the comparison. |
| /// |
| /// @return true iff @p f is lexicographically less than than @p s. |
| bool |
| operator()(const type_or_decl_base_sptr& f, |
| const type_or_decl_base_sptr& s) |
| {return operator()(f.get(), s.get());} |
| }; // end struct type_or_decl_base_comp |
| |
| /// Abstraction of a function parameter. |
| class function_decl::parameter : public decl_base |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| public: |
| |
| /// Hasher for an instance of function::parameter |
| struct hash; |
| |
| parameter(const type_base_sptr type, |
| unsigned index, |
| const string& name, |
| const location& loc, |
| bool variadic_marker = false); |
| |
| parameter(const type_base_sptr type, |
| unsigned index, |
| const string& name, |
| const location& loc, |
| bool variadic_marker, |
| bool is_artificial); |
| |
| parameter(const type_base_sptr type, |
| const string& name, |
| const location& loc, |
| bool variadic_marker = false, |
| bool is_artificial = false); |
| |
| parameter(const type_base_sptr type, |
| unsigned index = 0, |
| bool variadic_marker = false); |
| |
| const type_base_sptr |
| get_type()const; |
| |
| interned_string |
| get_type_name() const; |
| |
| const string |
| get_type_pretty_representation() const; |
| |
| interned_string |
| get_name_id() const; |
| |
| unsigned |
| get_index() const; |
| |
| void |
| set_index(unsigned i); |
| |
| bool |
| get_variadic_marker() const; |
| |
| bool |
| operator==(const parameter& o) const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual size_t |
| get_hash() const; |
| |
| virtual void |
| get_qualified_name(interned_string& qualified_name, |
| bool internal = false) const; |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| }; // end class function_decl::parameter |
| |
| bool |
| operator==(const function_decl::parameter_sptr&, |
| const function_decl::parameter_sptr&); |
| |
| /// A hashing functor for a function_decl::parameter. |
| struct function_decl::parameter::hash |
| { |
| size_t |
| operator()(const function_decl::parameter&) const; |
| |
| size_t |
| operator()(const function_decl::parameter*) const; |
| |
| size_t |
| operator()(const function_decl::parameter_sptr) const; |
| }; // end struct function_decl::parameter::hash |
| |
| function_decl::parameter* |
| is_function_parameter(const type_or_decl_base*); |
| |
| function_decl::parameter_sptr |
| is_function_parameter(const type_or_decl_base_sptr tod); |
| |
| bool |
| equals(const function_type&, const function_type&, change_kind*); |
| |
| /// Abstraction of a function type. |
| class function_type : public virtual type_base |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| public: |
| /// Hasher for an instance of function_type |
| struct hash; |
| |
| /// Convenience typedef for a shared pointer on a @ref |
| /// function_decl::parameter |
| typedef shared_ptr<function_decl::parameter> parameter_sptr; |
| /// Convenience typedef for a vector of @ref parameter_sptr |
| typedef std::vector<parameter_sptr> parameters; |
| |
| priv_sptr priv_; |
| |
| private: |
| function_type(); |
| |
| public: |
| |
| function_type(type_base_sptr return_type, |
| const parameters& parms, |
| size_t size_in_bits, |
| size_t alignment_in_bits); |
| |
| function_type(type_base_sptr return_type, |
| size_t size_in_bits, |
| size_t alignment_in_bits); |
| |
| function_type(const environment* env, |
| size_t size_in_bits, |
| size_t alignment_in_bits); |
| |
| type_base_sptr |
| get_return_type() const; |
| |
| void |
| set_return_type(type_base_sptr t); |
| |
| const parameters& |
| get_parameters() const; |
| |
| const parameter_sptr |
| get_parm_at_index_from_first_non_implicit_parm(size_t) const; |
| |
| void |
| set_parameters(const parameters &p); |
| |
| void |
| append_parameter(parameter_sptr parm); |
| |
| bool |
| is_variadic() const; |
| |
| parameters::const_iterator |
| get_first_non_implicit_parm() const; |
| |
| const interned_string& |
| get_cached_name(bool internal = false) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| |
| virtual ~function_type(); |
| |
| friend bool |
| equals(const function_type&, const function_type&, change_kind*); |
| };//end class function_type |
| |
| /// The hashing functor for @ref function_type. |
| struct function_type::hash |
| { |
| size_t |
| operator()(const function_type& t) const; |
| |
| size_t |
| operator()(const function_type* t) const; |
| |
| size_t |
| operator()(const function_type_sptr t) const; |
| };// end struct function_type::hash |
| |
| /// Abstracts the type of a class member function. |
| class method_type : public function_type |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| priv_sptr priv_; |
| |
| method_type(); |
| |
| public: |
| |
| /// Hasher for intances of method_type |
| struct hash; |
| |
| method_type(type_base_sptr return_type, |
| class_or_union_sptr class_type, |
| const std::vector<function_decl::parameter_sptr>& parms, |
| bool is_const, |
| size_t size_in_bits, |
| size_t alignment_in_bits); |
| |
| method_type(type_base_sptr return_type, |
| type_base_sptr class_type, |
| const std::vector<function_decl::parameter_sptr>& parms, |
| bool is_const, |
| size_t size_in_bits, |
| size_t alignment_in_bits); |
| |
| method_type(class_or_union_sptr class_type, |
| bool is_const, |
| size_t size_in_bits, |
| size_t alignment_in_bits); |
| |
| method_type(const environment* env, |
| size_t size_in_bits, |
| size_t alignment_in_bits); |
| |
| class_or_union_sptr |
| get_class_type() const; |
| |
| void |
| set_class_type(const class_or_union_sptr& t); |
| |
| void set_is_const(bool); |
| |
| bool get_is_const() const; |
| |
| virtual ~method_type(); |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| friend interned_string |
| get_method_type_name(const method_type& fn_type, bool internal); |
| };// end class method_type. |
| |
| /// The base class of templates. |
| class template_decl : public virtual decl_base |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| priv_sptr priv_; |
| |
| template_decl(); |
| |
| public: |
| |
| /// Hasher. |
| struct hash; |
| |
| template_decl(const environment* env, |
| const string& name, |
| const location& locus, |
| visibility vis = VISIBILITY_DEFAULT); |
| |
| void |
| add_template_parameter(const template_parameter_sptr p); |
| |
| const std::list<template_parameter_sptr>& |
| get_template_parameters() const; |
| |
| virtual bool |
| operator==(const template_decl& o) const; |
| |
| virtual ~template_decl(); |
| };//end class template_decl |
| |
| /// Base class for a template parameter. Client code should use the |
| /// more specialized type_template_parameter, |
| /// non_type_template_parameter and template_template_parameter below. |
| class template_parameter |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| priv_sptr priv_; |
| |
| // Forbidden |
| template_parameter(); |
| |
| public: |
| |
| /// Hashers. |
| struct hash; |
| struct dynamic_hash; |
| struct shared_ptr_hash; |
| |
| template_parameter(unsigned index, |
| template_decl_sptr enclosing_tdecl); |
| |
| virtual bool |
| operator==(const template_parameter&) const; |
| |
| bool |
| operator!=(const template_parameter&) const; |
| |
| unsigned |
| get_index() const; |
| |
| const template_decl_sptr |
| get_enclosing_template_decl() const; |
| |
| bool |
| get_hashing_has_started() const; |
| |
| void |
| set_hashing_has_started(bool f) const; |
| |
| virtual ~template_parameter(); |
| };//end class template_parameter |
| |
| struct template_decl::hash |
| { |
| size_t |
| operator()(const template_decl& t) const; |
| };// end struct template_decl::hash |
| |
| /// Abstracts a type template parameter. |
| class type_tparameter : public template_parameter, public virtual type_decl |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| // Forbidden |
| type_tparameter(); |
| |
| public: |
| |
| /// Hasher. |
| struct hash; |
| |
| type_tparameter(unsigned index, |
| template_decl_sptr enclosing_tdecl, |
| const string& name, |
| const location& locus); |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| operator==(const template_parameter&) const; |
| |
| virtual bool |
| operator==(const type_tparameter&) const; |
| |
| virtual ~type_tparameter(); |
| };// end class type_tparameter. |
| |
| /// Abstracts non type template parameters. |
| class non_type_tparameter : public template_parameter, public virtual decl_base |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| type_base_wptr type_; |
| |
| // Forbidden |
| non_type_tparameter(); |
| |
| public: |
| /// Hasher. |
| struct hash; |
| |
| non_type_tparameter(unsigned index, |
| template_decl_sptr enclosing_tdecl, |
| const string& name, |
| type_base_sptr type, |
| const location& locus); |
| virtual size_t |
| get_hash() const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const template_parameter&) const; |
| |
| const type_base_sptr |
| get_type() const; |
| |
| virtual ~non_type_tparameter(); |
| };// end class non_type_tparameter |
| |
| /// Hasher for the @ref non_type_tparameter type. |
| struct non_type_tparameter::hash |
| { |
| size_t |
| operator()(const non_type_tparameter& t) const; |
| |
| size_t |
| operator()(const non_type_tparameter* t) const; |
| }; |
| |
| class template_tparameter; |
| |
| /// Abstracts a template template parameter. |
| class template_tparameter : public type_tparameter, public template_decl |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| priv_sptr priv_; |
| |
| // Forbidden |
| template_tparameter(); |
| |
| public: |
| |
| /// A hasher for instances of template_tparameter |
| struct hash; |
| |
| template_tparameter(unsigned index, |
| template_decl_sptr enclosing_tdecl, |
| const string& name, |
| const location& locus); |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| operator==(const template_parameter&) const; |
| |
| virtual bool |
| operator==(const template_decl&) const; |
| |
| virtual ~template_tparameter(); |
| }; |
| |
| /// This abstracts a composition of types based on template type |
| /// parameters. The result of the composition is a type that can be |
| /// referred to by a template non-type parameter. Instances of this |
| /// type can appear at the same level as template parameters, in the |
| /// scope of a template_decl. |
| class type_composition : public template_parameter, public virtual decl_base |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| type_composition(); |
| |
| public: |
| struct hash; |
| |
| type_composition(unsigned index, |
| template_decl_sptr tdecl, |
| type_base_sptr composed_type); |
| |
| const type_base_sptr |
| get_composed_type() const; |
| |
| void |
| set_composed_type(type_base_sptr t); |
| |
| virtual size_t |
| get_hash() const; |
| |
| virtual ~type_composition(); |
| }; |
| |
| /// Hasher for the @ref type_composition type. |
| struct type_composition::hash |
| { |
| size_t |
| operator()(const type_composition& t) const; |
| |
| size_t |
| operator()(const type_composition* t) const; |
| |
| }; //struct type_composition::hash |
| |
| /// Abstract a function template declaration. |
| class function_tdecl : public template_decl, public scope_decl |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| // Forbidden |
| function_tdecl(); |
| |
| public: |
| |
| /// Hash functor for function templates. |
| struct hash; |
| struct shared_ptr_hash; |
| |
| function_tdecl(const environment* env, |
| const location& locus, |
| visibility vis = VISIBILITY_DEFAULT, |
| binding bind = BINDING_NONE); |
| |
| function_tdecl(function_decl_sptr pattern, |
| const location& locus, |
| visibility vis = VISIBILITY_DEFAULT, |
| binding bind = BINDING_NONE); |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const template_decl&) const; |
| |
| virtual bool |
| operator==(const function_tdecl&) const; |
| |
| void |
| set_pattern(shared_ptr<function_decl> p); |
| |
| shared_ptr<function_decl> |
| get_pattern() const; |
| |
| binding |
| get_binding() const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~function_tdecl(); |
| }; // end class function_tdecl. |
| |
| /// Abstract a class template. |
| class class_tdecl : public template_decl, public scope_decl |
| { |
| class priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| // Forbidden |
| class_tdecl(); |
| |
| public: |
| |
| /// Hashers. |
| struct hash; |
| struct shared_ptr_hash; |
| |
| class_tdecl(const environment* env, const location& locus, |
| visibility vis = VISIBILITY_DEFAULT); |
| |
| class_tdecl(class_decl_sptr pattern, |
| const location& locus, |
| visibility vis = VISIBILITY_DEFAULT); |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const template_decl&) const; |
| |
| virtual bool |
| operator==(const class_tdecl&) const; |
| |
| void |
| set_pattern(class_decl_sptr p); |
| |
| shared_ptr<class_decl> |
| get_pattern() const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~class_tdecl(); |
| };// end class class_tdecl |
| |
| /// The base class for member types, data members and member |
| /// functions. Its purpose is mainly to carry the access specifier |
| /// (and possibly other properties that might be shared by all class |
| /// members) for the member. |
| class member_base |
| { |
| protected: |
| enum access_specifier access_; |
| bool is_static_; |
| |
| private: |
| // Forbidden |
| member_base(); |
| |
| public: |
| /// Hasher. |
| struct hash; |
| |
| member_base(access_specifier a, bool is_static = false) |
| : access_(a), is_static_(is_static) |
| {} |
| |
| /// Getter for the access specifier of this member. |
| /// |
| /// @return the access specifier for this member. |
| access_specifier |
| get_access_specifier() const |
| {return access_;} |
| |
| /// Setter for the access specifier of this member. |
| /// |
| /// @param a the new access specifier. |
| void |
| set_access_specifier(access_specifier a) |
| {access_ = a;} |
| |
| /// @return true if the member is static, false otherwise. |
| bool |
| get_is_static() const |
| {return is_static_;} |
| |
| /// Set a flag saying if the parameter is static or not. |
| /// |
| /// @param f set to true if the member is static, false otherwise. |
| void |
| set_is_static(bool f) |
| {is_static_ = f;} |
| |
| virtual bool |
| operator==(const member_base& o) const; |
| };// end class member_base |
| |
| /// Abstraction of the declaration of a method. |
| class method_decl : public function_decl |
| { |
| method_decl(); |
| |
| virtual void |
| set_scope(scope_decl*); |
| |
| public: |
| |
| method_decl(const string& name, method_type_sptr type, |
| bool declared_inline, const location& locus, |
| const string& mangled_name = "", |
| visibility vis = VISIBILITY_DEFAULT, |
| binding bind = BINDING_GLOBAL); |
| |
| method_decl(const string& name, |
| function_type_sptr type, |
| bool declared_inline, |
| const location& locus, |
| const string& mangled_name = "", |
| visibility vis = VISIBILITY_DEFAULT, |
| binding bind = BINDING_GLOBAL); |
| |
| method_decl(const string& name, type_base_sptr type, |
| bool declared_inline, const location& locus, |
| const string& mangled_name = "", |
| visibility vis = VISIBILITY_DEFAULT, |
| binding bind = BINDING_GLOBAL); |
| |
| virtual void |
| set_linkage_name(const string&); |
| |
| /// @return the type of the current instance of the |
| /// method_decl. |
| const method_type_sptr |
| get_type() const; |
| |
| void |
| set_type(const method_type_sptr fn_type) |
| {function_decl::set_type(fn_type);} |
| |
| friend bool |
| get_member_function_is_ctor(const function_decl&); |
| |
| friend void |
| set_member_function_is_ctor(function_decl&, bool); |
| |
| friend void |
| set_member_function_is_ctor(const function_decl_sptr&, bool); |
| |
| friend bool |
| get_member_function_is_dtor(const function_decl&); |
| |
| friend void |
| set_member_function_is_dtor(function_decl&, bool); |
| |
| friend void |
| set_member_function_is_dtor(const function_decl_sptr&, bool); |
| |
| friend bool |
| get_member_function_is_static(const function_decl&); |
| |
| friend void |
| set_member_function_is_static(const function_decl&, bool); |
| |
| friend bool |
| get_member_function_is_const(const function_decl&); |
| |
| friend void |
| set_member_function_is_const(function_decl&, bool); |
| |
| friend void |
| set_member_function_is_const(const function_decl_sptr&, bool); |
| |
| friend bool |
| member_function_has_vtable_offset(const function_decl&); |
| |
| friend ssize_t |
| get_member_function_vtable_offset(const function_decl&); |
| |
| friend void |
| set_member_function_vtable_offset(function_decl&, ssize_t); |
| |
| friend void |
| set_member_function_vtable_offset(const function_decl_sptr&, ssize_t); |
| |
| friend bool |
| get_member_function_is_virtual(const function_decl&); |
| |
| friend void |
| set_member_function_is_virtual(function_decl&, bool); |
| |
| virtual ~method_decl(); |
| };// end class method_decl |
| |
| bool |
| operator==(const method_decl_sptr& l, const method_decl_sptr& r); |
| |
| bool |
| operator!=(const method_decl_sptr& l, const method_decl_sptr& r); |
| |
| /// The base type of @ref class_decl and @ref union_decl |
| class class_or_union : public scope_type_decl |
| { |
| public: |
| struct priv; |
| priv *priv_; |
| |
| private: |
| // Forbidden |
| class_or_union(); |
| |
| protected: |
| |
| virtual decl_base_sptr |
| add_member_decl(const decl_base_sptr&); |
| |
| virtual decl_base_sptr |
| insert_member_decl(decl_base_sptr member, declarations::iterator before); |
| |
| virtual void |
| remove_member_decl(decl_base_sptr); |
| |
| public: |
| /// Hasher. |
| struct hash; |
| |
| /// Convenience typedef |
| /// @{ |
| typedef vector<type_base_sptr> member_types; |
| typedef vector<var_decl_sptr> data_members; |
| typedef vector<method_decl_sptr> member_functions; |
| typedef unordered_map<ssize_t, member_functions> virtual_mem_fn_map_type; |
| typedef unordered_map<string, method_decl*> string_mem_fn_ptr_map_type; |
| /// @} |
| |
| class_or_union(const environment* env, const string& name, |
| size_t size_in_bits, size_t align_in_bits, |
| const location& locus, visibility vis, |
| member_types& mbrs, data_members& data_mbrs, |
| member_functions& member_fns); |
| |
| class_or_union(const environment* env, const string& name, |
| size_t size_in_bits, size_t align_in_bits, |
| const location& locus, visibility vis); |
| |
| class_or_union(const environment* env, const string& name, |
| bool is_declaration_only = true); |
| |
| virtual void |
| set_size_in_bits(size_t); |
| |
| virtual size_t |
| get_size_in_bits() const; |
| |
| virtual size_t |
| get_alignment_in_bits() const; |
| |
| virtual void |
| set_alignment_in_bits(size_t); |
| |
| typedef_decl_sptr |
| get_naming_typedef() const; |
| |
| void |
| set_naming_typedef(const typedef_decl_sptr&); |
| |
| bool |
| get_is_declaration_only() const; |
| |
| void |
| set_is_declaration_only(bool f); |
| |
| void |
| set_definition_of_declaration(class_or_union_sptr); |
| |
| const class_or_union_sptr |
| get_definition_of_declaration() const; |
| |
| const class_or_union* |
| get_naked_definition_of_declaration() const; |
| |
| decl_base_sptr |
| get_earlier_declaration() const; |
| |
| void |
| set_earlier_declaration(decl_base_sptr declaration); |
| |
| void |
| insert_member_type(type_base_sptr t, |
| declarations::iterator before); |
| |
| void |
| add_member_type(type_base_sptr t); |
| |
| type_base_sptr |
| add_member_type(type_base_sptr t, access_specifier a); |
| |
| void |
| remove_member_type(type_base_sptr t); |
| |
| const member_types& |
| get_member_types() const; |
| |
| virtual size_t |
| get_num_anonymous_member_classes() const; |
| |
| virtual size_t |
| get_num_anonymous_member_unions() const; |
| |
| virtual size_t |
| get_num_anonymous_member_enums() const; |
| |
| type_base_sptr |
| find_member_type(const string& name) const; |
| |
| void |
| add_data_member(var_decl_sptr v, access_specifier a, |
| bool is_laid_out, bool is_static, |
| size_t offset_in_bits); |
| |
| const data_members& |
| get_data_members() const; |
| |
| const var_decl_sptr |
| find_data_member(const string&) const; |
| |
| const data_members& |
| get_non_static_data_members() const; |
| |
| void |
| add_member_function(method_decl_sptr f, |
| access_specifier a, |
| bool is_static, bool is_ctor, |
| bool is_dtor, bool is_const); |
| |
| void |
| add_member_function(method_decl_sptr f, |
| access_specifier a, |
| bool is_virtual, |
| size_t vtable_offset, |
| bool is_static, bool is_ctor, |
| bool is_dtor, bool is_const); |
| |
| const member_functions& |
| get_member_functions() const; |
| |
| const method_decl* |
| find_member_function(const string& mangled_name) const; |
| |
| method_decl* |
| find_member_function(const string& mangled_name); |
| |
| const method_decl* |
| find_member_function_from_signature(const string& s) const; |
| |
| method_decl* |
| find_member_function_from_signature(const string& s); |
| |
| void |
| add_member_function_template(member_function_template_sptr); |
| |
| const member_function_templates& |
| get_member_function_templates() const; |
| |
| void |
| add_member_class_template(member_class_template_sptr m); |
| |
| const member_class_templates& |
| get_member_class_templates() const; |
| |
| bool |
| has_no_member() const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| operator==(const class_or_union&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~class_or_union(); |
| |
| friend method_decl_sptr |
| copy_member_function(class_or_union_sptr& t, |
| const method_decl*m); |
| |
| friend method_decl_sptr |
| copy_member_function(class_or_union_sptr& t, |
| const method_decl_sptr& m); |
| |
| friend void |
| fixup_virtual_member_function(method_decl_sptr method); |
| |
| friend void |
| set_member_is_static(decl_base& d, bool s); |
| |
| friend bool |
| equals(const class_or_union&, const class_or_union&, change_kind*); |
| |
| friend bool |
| equals(const class_decl&, const class_decl&, change_kind*); |
| |
| friend class method_decl; |
| friend class class_decl; |
| }; // end class class_or_union |
| |
| method_decl_sptr |
| copy_member_function(const class_or_union_sptr& clazz, |
| const method_decl_sptr& f); |
| |
| method_decl_sptr |
| copy_member_function(const class_or_union_sptr& clazz, |
| const method_decl* f); |
| |
| bool |
| operator==(const class_or_union_sptr& l, const class_or_union_sptr& r); |
| |
| bool |
| operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r); |
| |
| /// Hasher for the @ref class_or_union type |
| struct class_or_union::hash |
| { |
| size_t |
| operator()(const class_or_union& t) const; |
| |
| size_t |
| operator()(const class_or_union* t) const; |
| }; // end struct class_decl::hash |
| |
| /// Abstracts a class declaration. |
| class class_decl : public class_or_union |
| { |
| // Forbidden |
| class_decl(); |
| |
| protected: |
| |
| virtual decl_base_sptr |
| insert_member_decl(decl_base_sptr member, declarations::iterator before); |
| |
| public: |
| /// Hasher. |
| struct hash; |
| |
| /// Forward declarations. |
| class base_spec; |
| |
| /// Convenience typedef |
| /// @{ |
| typedef shared_ptr<base_spec> base_spec_sptr; |
| typedef vector<base_spec_sptr> base_specs; |
| |
| /// @} |
| |
| protected: |
| virtual void |
| on_canonical_type_set(); |
| |
| private: |
| struct priv; |
| // This priv it's not handled by a shared_ptr because accessing the |
| // data members of the priv struct for this class_decl shows up on |
| // performance profiles when dealing with big binaries with a lot of |
| // types; dereferencing the shared_ptr involves locking of some sort |
| // and that is slower than just dereferencing a pointer likere here. |
| // There are other types for which the priv pointer is managed using |
| // shared_ptr just fine, because those didn't show up during our |
| // performance profiling. |
| priv * priv_; |
| |
| public: |
| |
| class_decl(const environment* env, const string& name, |
| size_t size_in_bits, size_t align_in_bits, |
| bool is_struct, const location& locus, |
| visibility vis, base_specs& bases, |
| member_types& mbrs, data_members& data_mbrs, |
| member_functions& member_fns); |
| |
| class_decl(const environment* env, const string& name, |
| size_t size_in_bits, size_t align_in_bits, |
| bool is_struct, const location& locus, visibility vis); |
| |
| class_decl(const environment* env, const string& name, bool is_struct, |
| bool is_declaration_only = true); |
| |
| const class_decl_sptr |
| get_definition_of_declaration() const; |
| |
| const class_decl* |
| get_naked_definition_of_declaration() const; |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| void |
| is_struct(bool f); |
| |
| bool |
| is_struct() const; |
| |
| void |
| add_base_specifier(shared_ptr<base_spec> b); |
| |
| const base_specs& |
| get_base_specifiers() const; |
| |
| class_decl_sptr |
| find_base_class(const string&) const; |
| |
| const member_functions& |
| get_virtual_mem_fns() const; |
| |
| const virtual_mem_fn_map_type& |
| get_virtual_mem_fns_map() const; |
| |
| void |
| sort_virtual_mem_fns(); |
| |
| bool |
| has_no_base_nor_member() const; |
| |
| bool |
| has_virtual_member_functions() const; |
| |
| bool |
| has_virtual_bases() const; |
| |
| bool |
| has_vtable() const; |
| |
| ssize_t |
| get_biggest_vtable_offset() const; |
| |
| virtual size_t |
| get_hash() const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| operator==(const class_decl&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~class_decl(); |
| |
| friend void |
| fixup_virtual_member_function(method_decl_sptr method); |
| |
| friend void |
| set_member_is_static(decl_base& d, bool s); |
| |
| friend bool |
| equals(const class_decl&, const class_decl&, change_kind*); |
| |
| friend class method_decl; |
| friend class class_or_union; |
| };// end class class_decl |
| |
| bool |
| equals(const class_decl&, const class_decl&, change_kind*); |
| |
| method_decl_sptr |
| copy_member_function(const class_decl_sptr& clazz, |
| const method_decl_sptr& f); |
| |
| method_decl_sptr |
| copy_member_function(const class_decl_sptr& clazz, |
| const method_decl* f); |
| void |
| fixup_virtual_member_function(method_decl_sptr method); |
| |
| /// Hasher for the @ref class_decl type |
| struct class_decl::hash |
| { |
| size_t |
| operator()(const class_decl& t) const; |
| |
| size_t |
| operator()(const class_decl* t) const; |
| }; // end struct class_decl::hash |
| |
| enum access_specifier |
| get_member_access_specifier(const decl_base&); |
| |
| enum access_specifier |
| get_member_access_specifier(const decl_base_sptr&); |
| |
| void |
| set_member_access_specifier(decl_base&, |
| access_specifier); |
| |
| void |
| set_member_access_specifier(const decl_base_sptr&, |
| access_specifier); |
| |
| std::ostream& |
| operator<<(std::ostream&, access_specifier); |
| |
| bool |
| operator==(const class_decl_sptr& l, const class_decl_sptr& r); |
| |
| bool |
| operator!=(const class_decl_sptr& l, const class_decl_sptr& r); |
| |
| bool |
| equals(const class_decl::base_spec&, |
| const class_decl::base_spec&, |
| change_kind*); |
| |
| /// Abstraction of a base specifier in a class declaration. |
| class class_decl::base_spec : public member_base, |
| public virtual decl_base |
| { |
| struct priv; |
| typedef shared_ptr<priv>priv_sptr; |
| |
| priv_sptr priv_; |
| |
| // Forbidden |
| base_spec(); |
| |
| public: |
| |
| /// Hasher. |
| struct hash; |
| |
| base_spec(const class_decl_sptr& base, access_specifier a, |
| long offset_in_bits = -1, bool is_virtual = false); |
| |
| base_spec(const type_base_sptr& base, access_specifier a, |
| long offset_in_bits = -1, bool is_virtual = false); |
| |
| class_decl_sptr |
| get_base_class() const; |
| |
| bool |
| get_is_virtual() const; |
| |
| long |
| get_offset_in_bits() const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const member_base&) const; |
| |
| virtual size_t |
| get_hash() const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| };// end class class_decl::base_spec |
| |
| bool |
| operator==(const class_decl::base_spec_sptr& l, |
| const class_decl::base_spec_sptr& r); |
| |
| bool |
| operator!=(const class_decl::base_spec_sptr& l, |
| const class_decl::base_spec_sptr& r); |
| |
| class_decl::base_spec* |
| is_class_base_spec(type_or_decl_base*); |
| |
| class_decl::base_spec_sptr |
| is_class_base_spec(type_or_decl_base_sptr); |
| |
| /// Abstracts a union type declaration. |
| class union_decl : public class_or_union |
| { |
| // Forbid |
| union_decl(); |
| |
| public: |
| |
| union_decl(const environment* env, const string& name, |
| size_t size_in_bits, const location& locus, |
| visibility vis, member_types& mbrs, |
| data_members& data_mbrs, member_functions& member_fns); |
| |
| union_decl(const environment* env, const string& name, |
| size_t size_in_bits, const location& locus, |
| visibility vis); |
| |
| union_decl(const environment* env, const string& name, |
| bool is_declaration_only = true); |
| |
| virtual string |
| get_pretty_representation(bool internal = false, |
| bool qualified_name = true) const; |
| |
| virtual bool |
| operator==(const decl_base&) const; |
| |
| virtual bool |
| operator==(const type_base&) const; |
| |
| virtual bool |
| operator==(const union_decl&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| |
| virtual ~union_decl(); |
| }; // union_decl |
| |
| bool |
| equals(const union_decl&, const union_decl&, change_kind*); |
| |
| method_decl_sptr |
| copy_member_function(const union_decl_sptr& union_type, |
| const method_decl_sptr& f); |
| |
| method_decl_sptr |
| copy_member_function(const union_decl_sptr& union_type, |
| const method_decl* f); |
| |
| bool |
| operator==(const union_decl_sptr& l, const union_decl_sptr& r); |
| |
| bool |
| operator!=(const union_decl_sptr& l, const union_decl_sptr& r); |
| |
| /// Abstraction of a member function context relationship. This |
| /// relates a member function to its parent class. |
| class mem_fn_context_rel : public context_rel |
| { |
| protected: |
| bool is_virtual_; |
| ssize_t vtable_offset_in_bits_; |
| bool is_constructor_; |
| bool is_destructor_; |
| bool is_const_; |
| |
| public: |
| mem_fn_context_rel() |
| : context_rel(), |
| is_virtual_(false), |
| vtable_offset_in_bits_(-1), |
| is_constructor_(false), |
| is_destructor_(false), |
| is_const_(false) |
| {} |
| |
| mem_fn_context_rel(scope_decl* s) |
| : context_rel(s), |
| is_virtual_(false), |
| vtable_offset_in_bits_(-1), |
| is_constructor_(false), |
| is_destructor_(false), |
| is_const_(false) |
| {} |
| |
| 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) |
| : context_rel(s, access, is_static), |
| is_virtual_(is_virtual), |
| vtable_offset_in_bits_(vtable_offset_in_bits), |
| is_constructor_(is_constructor), |
| is_destructor_(is_destructor), |
| is_const_(is_const) |
| {} |
| |
| bool |
| is_virtual() const |
| {return is_virtual_;} |
| |
| void |
| is_virtual(bool is_virtual) |
| {is_virtual_ = is_virtual;} |
| |
| /// Getter for the vtable offset property. |
| /// |
| /// This is the vtable offset of the member function of this |
| /// relation. |
| /// |
| /// @return the vtable offset property of the relation. |
| size_t |
| vtable_offset() const |
| {return vtable_offset_in_bits_;} |
| |
| /// Setter for the vtable offset property. |
| /// |
| /// This is the vtable offset of the member function of this |
| /// relation. |
| /// |
| /// @partam s the new vtable offset. |
| void |
| vtable_offset(size_t s) |
| {vtable_offset_in_bits_ = s;} |
| |
| /// Getter for the 'is-constructor' property. |
| /// |
| /// This tells if the member function of this relation is a |
| /// constructor. |
| /// |
| /// @return the is-constructor property of the relation. |
| bool |
| is_constructor() const |
| {return is_constructor_;} |
| |
| /// Setter for the 'is-constructor' property. |
| /// |
| /// @param f the new value of the the property. Is true if this is |
| /// for a constructor, false otherwise. |
| void |
| is_constructor(bool f) |
| {is_constructor_ = f;} |
| |
| /// Getter for the 'is-destructor' property. |
| /// |
| /// Tells if the member function of this relation is a destructor. |
| /// |
| /// @return the is-destructor property of the relation; |
| bool |
| is_destructor() const |
| {return is_destructor_;} |
| |
| /// Setter for the 'is-destructor' property. |
| /// |
| /// @param f the new value of the property. Is true if this is for |
| /// a destructor, false otherwise. |
| void |
| is_destructor(bool f) |
| {is_destructor_ = f;} |
| |
| /// Getter for the 'is-const' property. |
| /// |
| /// Tells if the member function of this relation is a const member |
| /// function. |
| /// |
| /// @return the 'is-const' property of the relation. |
| bool |
| is_const() const |
| {return is_const_;} |
| |
| /// Setter for the 'is-const' property. |
| /// |
| /// @param f the new value of the property. Is true if this is for |
| /// a const entity, false otherwise. |
| void |
| is_const(bool f) |
| {is_const_ = f;} |
| |
| virtual ~mem_fn_context_rel(); |
| }; // end class mem_fn_context_rel |
| |
| method_decl* |
| is_method_decl(const type_or_decl_base*); |
| |
| method_decl* |
| is_method_decl(const type_or_decl_base&); |
| |
| method_decl_sptr |
| is_method_decl(const type_or_decl_base_sptr&); |
| |
| const var_decl* |
| lookup_data_member(const type_base* type, |
| const char* dm_name); |
| |
| const function_decl::parameter* |
| get_function_parameter(const decl_base* fun, |
| unsigned parm_num); |
| |
| /// Abstract a member function template. |
| class member_function_template : public member_base, public virtual decl_base |
| { |
| bool is_constructor_; |
| bool is_const_; |
| shared_ptr<function_tdecl> fn_tmpl_; |
| |
| // Forbiden |
| member_function_template(); |
| |
| public: |
| /// Hasher. |
| struct hash; |
| |
| member_function_template(function_tdecl_sptr f, |
| access_specifier access, bool is_static, |
| bool is_constructor, bool is_const) |
| : type_or_decl_base(f->get_environment()), |
| decl_base(f->get_environment(), f->get_name(), location()), |
| member_base(access, is_static), is_constructor_(is_constructor), |
| is_const_(is_const), fn_tmpl_(f) |
| {} |
| |
| bool |
| is_constructor() const |
| {return is_constructor_;} |
| |
| bool |
| is_const() const |
| {return is_const_;} |
| |
| operator const function_tdecl& () const |
| {return *fn_tmpl_;} |
| |
| function_tdecl_sptr |
| as_function_tdecl() const |
| {return fn_tmpl_;} |
| |
| virtual bool |
| operator==(const member_base& o) const; |
| |
| virtual bool |
| traverse(ir_node_visitor&); |
| };// end class member_function_template |
| |
| bool |
| operator==(const member_function_template_sptr& l, |
| const member_function_template_sptr& r); |
| |
| bool |
| operator!=(const member_function_template_sptr& l, |
| const member_function_template_sptr& r); |
| |
| /// Abstracts a member class template template |
| class member_class_template |
| : public member_base, |
| public virtual decl_base |
| { |
| shared_ptr<class_tdecl> class_tmpl_; |
| |
| // Forbidden |
| member_class_template(); |
| |
| public: |
| |
| /// Hasher. |
| struct hash; |
| |
| member_class_template(class_tdecl_sptr c, |
| access_specifier access, bool is_static) |
| : type_or_decl_base(c->get_environment()), |
| decl_base(c->get_environment(), c->get_name(), location()), |
| member_base(access, is_static), |
| class_tmpl_(c) |
| {} |
| |
| operator const class_tdecl& () const |
| { return *class_tmpl_; } |
| |
| class_tdecl_sptr |
| as_class_tdecl() const |
| {return class_tmpl_;} |
| |
| virtual bool |
| operator==(const member_base& o) const; |
| |
| virtual bool |
| operator==(const member_class_template&) const; |
| |
| virtual bool |
| traverse(ir_node_visitor& v); |
| };// end class member_class_template |
| |
| bool |
| operator==(const member_class_template_sptr& l, |
| const member_class_template_sptr& r); |
| |
| bool |
| operator!=(const member_class_template_sptr& l, |
| const member_class_template_sptr& r); |
| |
| // Forward declarations for select nested hashers. |
| struct type_base::shared_ptr_hash |
| { |
| size_t |
| operator()(const shared_ptr<type_base> t) const; |
| }; |
| |
| struct type_base::dynamic_hash |
| { |
| size_t |
| operator()(const type_base* t) const; |
| }; |
| |
| /// A hashing functor for instances and pointers of @ref var_decl. |
| struct var_decl::hash |
| { |
| size_t |
| operator()(const var_decl& t) const; |
| |
| size_t |
| operator()(const var_decl* t) const; |
| }; //end struct var_decl::hash |
| |
| /// A comparison functor for pointers to @ref var_decl. |
| struct var_decl::ptr_equal |
| { |
| /// Return true if the two instances of @ref var_decl are equal. |
| /// |
| /// @param l the first variable to compare. |
| /// |
| /// @param r the second variable to compare. |
| /// |
| /// @return true if @p l equals @p r. |
| bool |
| operator()(const var_decl* l, const var_decl* r) const |
| { |
| if (l == r) |
| return true; |
| if (!!l != !!r) |
| return false; |
| return (*l == *r); |
| } |
| };// end struct var_decl::ptr_equal |
| |
| /// A hashing functor fo instances and pointers of @ref function_decl. |
| struct function_decl::hash |
| { |
| size_t |
| operator()(const function_decl& t) const; |
| |
| size_t |
| operator()(const function_decl* t) const; |
| };//end struct function_decl::hash |
| |
| /// Equality functor for instances of @ref function_decl |
| struct function_decl::ptr_equal |
| { |
| /// Tests if two pointers to @ref function_decl are equal. |
| /// |
| /// @param l the first pointer to @ref function_decl to consider in |
| /// the comparison. |
| /// |
| /// @param r the second pointer to @ref function_decl to consider in |
| /// the comparison. |
| /// |
| /// @return true if the two functions @p l and @p r are equal, false |
| /// otherwise. |
| bool |
| operator()(const function_decl* l, const function_decl* r) const |
| { |
| if (l == r) |
| return true; |
| if (!!l != !!r) |
| return false; |
| return (*l == *r); |
| } |
| };// function_decl::ptr_equal |
| |
| /// The hashing functor for class_decl::base_spec. |
| struct class_decl::base_spec::hash |
| { |
| size_t |
| operator()(const base_spec& t) const; |
| }; |
| |
| /// The hashing functor for member_base. |
| struct member_base::hash |
| { |
| size_t |
| operator()(const member_base& m) const; |
| }; |
| |
| /// The hashing functor for member_function_template. |
| struct member_function_template::hash |
| { |
| size_t |
| operator()(const member_function_template& t) const; |
| }; |
| |
| /// The hashing functor for member_class_template |
| struct member_class_template::hash |
| { |
| size_t |
| operator()(const member_class_template& t) const; |
| }; |
| |
| struct function_tdecl::hash |
| { |
| size_t |
| operator()(const function_tdecl& t) const; |
| }; |
| |
| struct function_tdecl::shared_ptr_hash |
| { |
| size_t |
| operator()(const shared_ptr<function_tdecl> f) const; |
| }; |
| |
| struct class_tdecl::hash |
| { |
| size_t |
| operator()(const class_tdecl& t) const; |
| }; |
| |
| struct class_tdecl::shared_ptr_hash |
| { |
| size_t |
| operator()(const shared_ptr<class_tdecl> t) const; |
| }; |
| |
| /// The base class for the visitor type hierarchy used for traversing |
| /// a translation unit. |
| /// |
| /// Client code willing to get notified for a certain kind of node |
| /// during the IR traversal might want to define a visitor class that |
| /// inherit ir_node_visitor, overload the ir_node_visitor::visit_begin() |
| /// or ir_node_visitor::visit_end() method of its choice, and provide |
| /// and implementation for it. If either |
| /// ir_node_visitor::visit_begin() or ir_node_visitor::visit_end() |
| /// return false, it means the traversal has to stop immediately after |
| /// the methods' return. If the methods return true, it means the |
| /// traversal keeps going. |
| /// |
| /// That new visitor class would then be passed to e.g, |
| /// translation_unit::traverse or to the traverse method of any type |
| /// where the traversal is supposed to start from. |
| class ir_node_visitor : public node_visitor_base |
| { |
| struct priv; |
| typedef shared_ptr<priv> priv_sptr; |
| |
| priv_sptr priv_; |
| |
| public: |
| |
| ir_node_visitor(); |
| |
| void allow_visiting_already_visited_type_node(bool); |
| bool allow_visiting_already_visited_type_node() const; |
| void mark_type_node_as_visited(type_base *); |
| void forget_visited_type_nodes(); |
| bool type_node_has_been_visited(type_base*) const; |
| |
| virtual bool visit_begin(decl_base*); |
| virtual bool visit_end(decl_base*); |
| |
| virtual bool visit_begin(scope_decl*); |
| virtual bool visit_end(scope_decl*); |
| |
| virtual bool visit_begin(type_base*); |
| virtual bool visit_end(type_base*); |
| |
| virtual bool visit_begin(scope_type_decl*); |
| virtual bool visit_end(scope_type_decl*); |
| |
| virtual bool visit_begin(type_decl*); |
| virtual bool visit_end(type_decl*); |
| |
| virtual bool visit_begin(namespace_decl*); |
| virtual bool visit_end(namespace_decl*); |
| |
| virtual bool visit_begin(qualified_type_def*); |
| virtual bool visit_end(qualified_type_def*); |
| |
| virtual bool visit_begin(pointer_type_def*); |
| virtual bool visit_end(pointer_type_def*); |
| |
| virtual bool visit_begin(reference_type_def*); |
| virtual bool visit_end(reference_type_def*); |
| |
| virtual bool visit_begin(array_type_def*); |
| virtual bool visit_end(array_type_def*); |
| |
| virtual bool visit_begin(array_type_def::subrange_type*); |
| virtual bool visit_end(array_type_def::subrange_type*); |
| |
| virtual bool visit_begin(enum_type_decl*); |
| virtual bool visit_end(enum_type_decl*); |
| |
| virtual bool visit_begin(typedef_decl*); |
| virtual bool visit_end(typedef_decl*); |
| |
| virtual bool visit_begin(function_type*); |
| virtual bool visit_end(function_type*); |
| |
| virtual bool visit_begin(var_decl*); |
| virtual bool visit_end(var_decl*); |
| |
| virtual bool visit_begin(function_decl*); |
| virtual bool visit_end(function_decl*); |
| |
| virtual bool visit_begin(function_decl::parameter*); |
| virtual bool visit_end(function_decl::parameter*); |
| |
| virtual bool visit_begin(function_tdecl*); |
| virtual bool visit_end(function_tdecl*); |
| |
| virtual bool visit_begin(class_tdecl*); |
| virtual bool visit_end(class_tdecl*); |
| |
| virtual bool visit_begin(class_or_union *); |
| virtual bool visit_end(class_or_union *); |
| |
| virtual bool visit_begin(class_decl*); |
| virtual bool visit_end(class_decl*); |
| |
| virtual bool visit_begin(union_decl*); |
| virtual bool visit_end(union_decl*); |
| |
| virtual bool visit_begin(class_decl::base_spec*); |
| virtual bool visit_end(class_decl::base_spec*); |
| |
| virtual bool visit_begin(member_function_template*); |
| virtual bool visit_end(member_function_template*); |
| |
| virtual bool visit_begin(member_class_template*); |
| virtual bool visit_end(member_class_template*); |
| }; // end struct ir_node_visitor |
| |
| // Debugging facility |
| void |
| fns_to_str(vector<function_decl*>::const_iterator a_begin, |
| vector<function_decl*>::const_iterator a_end, |
| vector<function_decl*>::const_iterator b_begin, |
| vector<function_decl*>::const_iterator b_end, |
| std::ostream& o); |
| |
| }// end namespace ir |
| } // end namespace abigail |
| #endif // __ABG_IR_H__ |