// -*- Mode: C++ -*- // // Copyright (C) 2013 Free Software Foundation, 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 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 Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License // and a copy of the GCC Runtime Library Exception along with this // program; see the files COPYING3 and COPYING.RUNTIME respectively. // If not, see . /// @file #ifndef __ABG_IR_H__ #define __ABG_IR_H__ #include #include #include #include #include #include #include #include // for std::rel_ops, at least. #include "abg-hash.h" using std::tr1::shared_ptr; using std::tr1::hash; using std::string; // Our real stuff namespace abigail { using namespace std::rel_ops; // Pull in relational operators so that // we don't have to define them all here. class decl_base; class scope_decl; class global_scope; class class_decl; class translation_unit; void add_decl_to_scope(shared_ptr, scope_decl*); void add_decl_to_scope (shared_ptr, shared_ptr); global_scope* get_global_scope(const shared_ptr); translation_unit* get_translation_unit(const shared_ptr); bool is_global_scope(const scope_decl*); bool is_global_scope(const shared_ptr); bool is_at_global_scope(const shared_ptr); bool is_at_class_scope(const shared_ptr); bool is_at_template_scope(const shared_ptr); bool is_template_parameter(const shared_ptr); bool is_type(const shared_ptr); bool is_template_parm_composition_type(const shared_ptr); bool is_template_decl(const shared_ptr); bool is_function_template_pattern(const shared_ptr); /// \brief The source location of a token. /// /// This represents the location of a token coming from a given ABI /// Corpus. This location is actually an abstraction of cursor in the /// table of all the locations of all the tokens of the ABI Corpus. /// That table is managed by the location_manager type. class location { location (unsigned v) : m_value(v) { } public: location() : m_value(0) { } unsigned get_value() const { return m_value; } operator bool() const { return !!m_value; } bool operator==(const location other) const {return m_value == other.m_value;} bool operator<(const location other) const {return m_value < other.m_value;} friend class location_manager; private: unsigned m_value; }; /// \brief The entry point to manage locations. /// /// This type keeps a table of all the locations for tokens of a /// given ABI Corpus class location_manager { struct priv; shared_ptr m_priv; public: location_manager(); location create_new_location(const std::string& file, size_t line, size_t column); void expand_location(const location location, std::string& path, unsigned& line, unsigned& column) const; }; /// 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 { // Forbidden translation_unit(); public: typedef std::list > decls_type; translation_unit(const std::string& path); const std::string& get_path() const; const shared_ptr get_global_scope() const; location_manager& get_loc_mgr(); const location_manager& get_loc_mgr() const; bool is_empty() const; private: std::string m_path; location_manager m_loc_mgr; mutable shared_ptr m_global_scope; };//end class translation_unit /// \brief The base type of all declarations. class decl_base { // Forbidden decl_base(); void set_scope(scope_decl*); public: enum visibility { VISIBILITY_NONE, VISIBILITY_DEFAULT, VISIBILITY_PROTECTED, VISIBILITY_HIDDEN, VISIBILITY_INTERNAL };// end enum visibility enum binding { BINDING_NONE, BINDING_LOCAL, BINDING_GLOBAL, BINDING_WEAK };// end enum binding decl_base(const std::string& name, location locus, const std::string& mangled_name = "", visibility vis = VISIBILITY_DEFAULT); decl_base(location); decl_base(const decl_base&); virtual bool operator==(const decl_base&) const; virtual ~decl_base(); location get_location() const {return m_location;} void set_location(const location& l) {m_location = l;} const string& get_name() const {return m_name;} void set_name(const string& n) {m_name = n;} const string& get_mangled_name() const {return m_mangled_name;} void set_mangled_name(const std::string& m) {m_mangled_name = m;} scope_decl* get_scope() const {return m_context;} visibility get_visibility() const {return m_visibility;} void set_visibility(visibility v) {m_visibility = v;} friend void add_decl_to_scope(shared_ptr, scope_decl*); private: location m_location; std::string m_name; std::string m_mangled_name; scope_decl* m_context; visibility m_visibility; };// end class decl_base /// \brief A declaration that introduces a scope. class scope_decl : public virtual decl_base { scope_decl(); void add_member_decl(const shared_ptr); public: scope_decl(const std::string& name, location locus, visibility vis = VISIBILITY_DEFAULT) : decl_base(name, locus, /*mangled_name=*/name, vis) {} scope_decl(location l) : decl_base("", l) {} virtual bool operator==(const scope_decl&) const; const std::list >& get_member_decls() const {return m_members;} const std::list >& get_member_scopes() const {return m_member_scopes;} bool is_empty() const {return get_member_decls().empty();} virtual ~scope_decl(); friend void add_decl_to_scope(shared_ptr, scope_decl*); private: std::list > m_members; std::list > m_member_scopes; };// end class scope_decl. /// \brief Facility to hash instances of decl_base. struct decl_base_hash { size_t operator() (const decl_base& d) const; };//end struct decl_base_hash /// 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 { global_scope(translation_unit *tu) : decl_base("", location()), scope_decl("", location()), m_translation_unit(tu) { } public: friend class translation_unit; translation_unit* get_translation_unit() const {return m_translation_unit;} virtual ~global_scope(); private: translation_unit* m_translation_unit; };// end class global_scope; /// An abstraction helper for type declarations class type_base { // Forbid this. type_base(); public: type_base(size_t s, size_t a); virtual bool operator==(const type_base&) const; virtual ~type_base(); void set_size_in_bits(size_t); size_t get_size_in_bits() const; void set_alignment_in_bits(size_t); size_t get_alignment_in_bits() const; private: size_t m_size_in_bits; size_t m_alignment_in_bits; };//class type_base; /// A hasher for type_base types. struct type_base_hash { size_t operator()(const type_base& t) const; };//end struct type_base_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_type_hash { size_t operator()(const type_base* t) const; };//end struct dynamic_type_hash /// A hasher for shared_ptr that will hash it based on the /// runtime type of the type pointed to. struct type_shared_ptr_hash { size_t operator()(const shared_ptr t) const { return dynamic_type_hash()(t.get()); } };//end struct type_shared_ptr_hash /// A predicate for deep equality of instances of /// shared_ptr struct type_shared_ptr_equal { bool operator()(const shared_ptrl, const shared_ptrr) const { if (l != r) return false; if (l) return *l == *r; return true; } };//end struct type_shared_ptr_equal /// A basic type declaration that introduces no scope. class type_decl : public virtual decl_base, public virtual type_base { // Forbidden. type_decl(); public: type_decl(const std::string& name, size_t size_in_bits, size_t alignment_in_bits, location locus, const std::string& mangled_name = "", visibility vis = VISIBILITY_DEFAULT); virtual bool operator==(const type_decl&) const; virtual ~type_decl(); };// class type_decl /// Facility to hash instance of type_decl struct type_decl_hash { size_t operator()(const type_decl& t) const; };//end struct type_decl_hash /// A type that introduces a scope. class scope_type_decl : public scope_decl, public virtual type_base { scope_type_decl(); public: scope_type_decl(const std::string& name, size_t size_in_bits, size_t alignment_in_bits, location locus, visibility vis = VISIBILITY_DEFAULT); virtual bool operator==(const scope_type_decl&) const; virtual ~scope_type_decl(); }; /// Hasher for instances of scope_type_decl struct scope_type_decl_hash { size_t operator()(const scope_type_decl& t) const; };//end struct scope_type_decl_hash /// The abstraction of a namespace declaration class namespace_decl : public scope_decl { public: namespace_decl(const std::string& name, location locus, visibility vis = VISIBILITY_DEFAULT); virtual bool operator==(const namespace_decl&) const; virtual ~namespace_decl(); };//end class namespace_decl /// The abstraction of a qualified type. class qualified_type_def : public virtual type_base, public virtual decl_base { // Forbidden. qualified_type_def(); public: /// Bit field values representing the cv qualifiers of the /// underlying type. enum CV { CV_NONE = 0, CV_CONST = 1, CV_VOLATILE = 1 << 1 }; qualified_type_def(shared_ptr underlying_type, CV quals, location locus); virtual bool operator==(const qualified_type_def&) const; char get_cv_quals() const; void set_cv_quals(char cv_quals); const shared_ptr get_underlying_type() const; virtual ~qualified_type_def(); private: char m_cv_quals; shared_ptr m_underlying_type; };//end class qualified_type_def /// A Hasher for instances of qualified_type_def struct qualified_type_def_hash { size_t operator()(const qualified_type_def& t) const; };//end struct qualified_type_def_hash /// The abstraction of a pointer type. class pointer_type_def : public virtual type_base, public virtual decl_base { // Forbidden. pointer_type_def(); public: pointer_type_def(shared_ptr& pointed_to_type, size_t size_in_bits, size_t alignment_in_bits, location locus); virtual bool operator==(const pointer_type_def&) const; shared_ptr get_pointed_to_type() const; virtual ~pointer_type_def(); private: shared_ptr m_pointed_to_type; };//end class pointer_type_def /// A hasher for instances of pointer_type_def struct pointer_type_def_hash { size_t operator()(const pointer_type_def& t) const; };// end struct pointer_type_def_hash /// Abstracts a reference type. class reference_type_def : public virtual type_base, public virtual decl_base { // Forbidden. reference_type_def(); public: reference_type_def(shared_ptr& pointed_to_type, bool lvalue, size_t size_in_bits, size_t alignment_in_bits, location locus); virtual bool operator==(const reference_type_def&) const; shared_ptr get_pointed_to_type() const; bool is_lvalue() const; virtual ~reference_type_def(); private: shared_ptr m_pointed_to_type; bool m_is_lvalue; };//end class reference_type_def /// Hasher for intances of reference_type_def. struct reference_type_def_hash { size_t operator()(const reference_type_def& t); };//end struct reference_type_def_hash /// Abstracts a declaration for an enum type. class enum_type_decl: public virtual type_base, public virtual decl_base { // Forbidden enum_type_decl(); public: class enumerator { //Forbidden enumerator(); public: enumerator(const string& name, size_t value) :m_name(name), m_value(value) { } bool operator==(const enumerator& other) const { return (get_name() == other.get_name() && get_value() == other.get_value()); } const string& get_name() const {return m_name;} void set_name(const string& n) {m_name = n;} size_t get_value() const {return m_value;} void set_value(size_t v) {m_value=v;} private: string m_name; size_t m_value; };//end struct enumerator enum_type_decl(const string& name, location locus, shared_ptr underlying_type, const std::list& enumerators, const std::string& mangled_name = "", visibility vis = VISIBILITY_DEFAULT); shared_ptr get_underlying_type() const; const std::list& get_enumerators() const; virtual bool operator==(const enum_type_decl&) const; virtual ~enum_type_decl(); private: shared_ptr m_underlying_type; std::list m_enumerators; };// end class enum_type_decl /// A hasher for an enum_type_decl. struct enum_type_decl_hash { size_t operator()(const enum_type_decl& t) const; };//end struct enum_type_decl_hash /// The abstraction of a typedef declaration. class typedef_decl: public virtual type_base, public virtual decl_base { // Forbidden typedef_decl(); public: typedef_decl(const string& name, const shared_ptr underlying_type, location locus, const std::string& mangled_name = "", visibility vis = VISIBILITY_DEFAULT); virtual bool operator==(const typedef_decl&) const; shared_ptr get_underlying_type() const; virtual ~typedef_decl(); private: shared_ptr m_underlying_type; };//end class typedef_decl /// Hasher for the typedef_decl type. struct typedef_decl_hash { size_t operator()(const typedef_decl& t) const; };// end struct typedef_decl_hash /// Abstracts a variable declaration. class var_decl : public virtual decl_base { // Forbidden var_decl(); public: var_decl(const std::string& name, shared_ptr type, location locus, const std::string& mangled_name, visibility vis = VISIBILITY_DEFAULT, binding bind = BINDING_NONE); virtual bool operator==(const var_decl&) const; shared_ptr get_type() const {return m_type;} binding get_binding() const {return m_binding;} void set_binding(binding b) {m_binding = b;} virtual ~var_decl(); private: shared_ptr m_type; binding m_binding; };// end class var_decl /// Hasher for a var_decl type. struct var_decl_hash { size_t operator()(const var_decl& t) const; };// end struct var_decl_hash class function_type; /// Abstraction for a function declaration. class function_decl: public virtual decl_base { public: /// Abtraction for the parameter of a function. class parameter { public: parameter(const shared_ptr type, const std::string& name, location loc, bool variadic_marker = false) : m_type(type), m_name(name), m_location(loc), m_variadic_marker (variadic_marker) {} const shared_ptr get_type()const {return m_type;} const shared_ptr get_type() {return m_type;} const std::string& get_name() const {return m_name;} location get_location() const {return m_location;} bool operator==(const parameter& o) const {return *get_type() == *o.get_type();} bool get_variadic_marker () const {return m_variadic_marker;} private: shared_ptr m_type; std::string m_name; location m_location; bool m_variadic_marker; };// end class function::parameter /// Hasher for an instance of function::parameter struct parameter_hash { size_t operator()(const parameter& p) const; };//end struct parameter_hash function_decl (const std::string& name, const std::vector >& parms, shared_ptr return_type, size_t ftype_size_in_bits, size_t ftype_align_in_bits, bool declared_inline, location locus, const std::string& mangled_name = "", visibility vis = VISIBILITY_DEFAULT, binding bind = BINDING_GLOBAL); function_decl (const std::string& name, shared_ptr function_type, bool declared_inline, location locus, const std::string& mangled_name = "", visibility vis = VISIBILITY_DEFAULT, binding bind = BINDING_GLOBAL) : decl_base(name, locus, mangled_name, vis), m_type(function_type), m_declared_inline(declared_inline), m_binding(bind) {} function_decl (const std::string& name, shared_ptr function_type, bool declared_inline, location locus, const std::string& mangled_name = "", visibility vis = VISIBILITY_DEFAULT, binding bind = BINDING_GLOBAL); const std::vector >& get_parameters() const; void append_parameter(shared_ptr parm); void append_parameters(std::vector >& parms); const shared_ptr get_type() const {return m_type;} const shared_ptr get_return_type() const; void set_type(shared_ptr fn_type) {m_type = fn_type;} bool is_declared_inline() const {return m_declared_inline;} binding get_binding() const {return m_binding;} virtual bool operator==(const function_decl& 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 {return (!get_parameters().empty() && get_parameters().back()->get_variadic_marker());} virtual ~function_decl(); private: shared_ptr m_type; bool m_declared_inline; decl_base::binding m_binding; };// end class function_decl /// Hasher for function_decl struct function_decl_hash { size_t operator()(const function_decl& t) const; };// end function_decl_hash /// Abstraction of a function type. class function_type : public virtual type_base { function_type (); public: /// The most straightforward constructor for the the function_type /// class. /// /// \param return_type the return type of the function type. /// /// \param parms the list of parameters of the function type. /// Stricto sensu, we just need a list of types; we are using a list /// of parameters (where each parameter also carries the name of the /// parameter and its source location) to try and provide better /// diagnostics whenever it makes sense. If it appears that this /// wasts too many resources, we can fall back to taking just a /// vector of types here. /// /// \param size_in_bits the size of this type, in bits. /// /// \param alignment_in_bits the alignment of this type, in bits. /// /// \param size_in_bits the size of this type. function_type(shared_ptr return_type, const std::vector >& parms, size_t size_in_bits, size_t alignment_in_bits) : type_base(size_in_bits, alignment_in_bits), m_return_type(return_type), m_parms(parms) {} /// A constructor for a function_type that takes no parameters. /// /// \param return_type the return type of this function_type. /// /// \param size_in_bits the size of this type, in bits. /// /// \param alignment_in_bits the alignment of this type, in bits. function_type(shared_ptr return_type, size_t size_in_bits, size_t alignment_in_bits) : type_base(size_in_bits, alignment_in_bits), m_return_type (return_type) {} /// A constructor for a function_type that takes no parameter and /// that has no return_type yet. These missing parts can (and must) /// be added later. /// /// \param size_in_bits the size of this type, in bits. /// /// \param alignment_in_bits the alignment of this type, in bits. function_type(size_t size_in_bits, size_t alignment_in_bits) : type_base(size_in_bits, alignment_in_bits) {} const shared_ptr get_return_type() const {return m_return_type;} void set_return_type(shared_ptr t) {m_return_type = t;} const std::vector >& get_parameters() const {return m_parms;} std::vector >& get_parameters() {return m_parms;} void set_parameters(const std::vector > &p) {m_parms = p;} void append_parameter(shared_ptr parm) {m_parms.push_back (parm);} bool is_variadic() const {return !m_parms.empty() && m_parms.back()->get_variadic_marker();} bool operator==(const function_type&) const; virtual ~function_type(); private: shared_ptr m_return_type; std::vector > m_parms; };// end class function_type /// Hasher for an instance of function_type struct function_type_hash { size_t operator()(const function_type& t) const; }; // end struct function_type_hash class template_parameter; class template_type_parameter; class template_non_type_parameter; class template_template_parameter; /// The base class of templates. class template_decl { public: template_decl() {} void add_template_parameter(shared_ptr p) {m_parms.push_back(p);} const std::list >& get_template_parameters() const {return m_parms;} virtual bool operator==(const template_decl& o) const; virtual ~template_decl(); private: std::list > m_parms; };// end class template_decl struct template_decl_hash { size_t operator()(const template_decl&) const; };//end struct template_decl_hash /// 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 { // Forbidden template_parameter(); public: template_parameter(unsigned index) : m_index(index) {} virtual bool operator==(const template_parameter&) const; unsigned get_index() const {return m_index;} virtual ~template_parameter(); private: unsigned m_index; };//end class template_parameter struct template_parameter_hash { size_t operator()(const template_parameter& t) const; };//end class template_parameter_hash struct dynamic_template_parameter_hash { size_t operator()(const template_parameter*) const; };//end struct dynamic_template_parameter_hash struct template_parameter_shared_ptr_hash { size_t operator()(const shared_ptr t) const { return dynamic_template_parameter_hash()(t.get()); } };// end struct template_parameter_shared_ptr_hash /// Abstracts a type template parameter. class template_type_parameter : public template_parameter, public virtual type_decl { // Forbidden template_type_parameter(); public: template_type_parameter(unsigned index, const std::string& name, location locus) : decl_base(name, locus), type_base(0, 0), type_decl(name, 0, 0, locus), template_parameter(index) {} virtual bool operator==(const template_type_parameter&) const; virtual ~template_type_parameter(); };//end class template_type_parameter struct template_type_parameter_hash { size_t operator()(const template_type_parameter& t) const; };//end struct template_type_parameter_hash /// Abstracts non type template parameters. class template_non_type_parameter : public template_parameter, public virtual decl_base { // Forbidden template_non_type_parameter(); public: template_non_type_parameter(unsigned index, const std::string& name, shared_ptr type, location locus) : decl_base(name, locus, ""), template_parameter(index), m_type(type) {} virtual bool operator==(const template_non_type_parameter&) const; shared_ptr get_type() const {return m_type;} virtual ~template_non_type_parameter(); private: shared_ptr m_type; };// class template_non_type_parameter struct template_non_type_parameter_hash { size_t operator()(const template_non_type_parameter& t) const; };// end struct template_non_type_parameter_hash /// Abstracts a template template parameter. class template_template_parameter : public template_type_parameter, public template_decl { // Forbidden template_template_parameter(); public: template_template_parameter(unsigned index, const std::string& name, location locus) : decl_base(name, locus), type_base(0, 0), type_decl(name, 0, 0, locus, name, VISIBILITY_DEFAULT), template_type_parameter(index, name, locus) {} virtual bool operator==(const template_template_parameter& o) const; virtual ~template_template_parameter(); };//end class template_template_parameter /// A hasher for instances of template_template_parameter struct template_template_parameter_hash { size_t operator()(const template_template_parameter& t) const; };// end struct template_template_parameter_hash /// 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 tmpl_parm_type_composition : public template_parameter, public virtual decl_base { tmpl_parm_type_composition(); public: tmpl_parm_type_composition(unsigned index, shared_ptr composed_type); shared_ptr get_composed_type() const {return m_type;} void set_composed_type(shared_ptr t) {m_type = t;} virtual ~tmpl_parm_type_composition(); private: shared_ptr m_type; };// end class tmpl_parm_type_composition /// Abstract a function template declaration. class function_template_decl : public template_decl, public scope_decl { // Forbidden function_template_decl(); public: function_template_decl(location locus, visibility vis = VISIBILITY_DEFAULT, binding bind = BINDING_NONE) : decl_base("", locus, "", vis), scope_decl("", locus), m_binding(bind) {} function_template_decl(shared_ptr pattern, location locus, visibility vis = VISIBILITY_DEFAULT, binding bind = BINDING_NONE) : decl_base(pattern->get_name(), locus, pattern->get_name(), vis), scope_decl(pattern->get_name(), locus), m_binding(bind) {set_pattern(pattern);} virtual bool operator==(const function_template_decl&) const; void set_pattern(shared_ptr p) { m_pattern = p; add_decl_to_scope(p, this); set_name(p->get_name()); } shared_ptr get_pattern() const {return m_pattern;} binding get_binding() const {return m_binding;} virtual ~function_template_decl(); private: shared_ptr m_pattern; binding m_binding; };//end class function_template_decl /// Hashing functor for pointer to a function template. struct fn_tmpl_shared_ptr_hash { size_t operator()(const shared_ptr) const; };//end struct fn_tmpl_shared_ptr_hash /// Hash functor for function templates struct function_template_decl_hash { size_t operator()(const function_template_decl&) const; };// end struct function_template_decl_hash /// Abstract a class template. class class_template_decl : public template_decl, public scope_decl { // Forbidden class_template_decl(); public: class_template_decl(location locus, visibility vis = VISIBILITY_DEFAULT) : decl_base("", locus, "", vis), scope_decl("", locus) {} /// Constructor for the class_template_decl type. /// /// \param the pattern of the class template. This must NOT be a /// null pointer. If you really this to be null, please use the /// constructor above instead. /// /// \param the source location of the declaration of the type. /// /// \param the visibility of the instances of class instantiated /// from this template. class_template_decl(shared_ptr pattern, location locus, visibility vis = VISIBILITY_DEFAULT); virtual bool operator==(const class_template_decl&) const; void set_pattern(shared_ptr p); shared_ptr get_pattern() const {return m_pattern;} virtual ~class_template_decl(); private: shared_ptr m_pattern; };// end class class_template_decl struct class_template_decl_hash { size_t operator()(const class_template_decl&) const; };// end struct class_template_decl_hash struct class_tmpl_shared_ptr_hash { size_t operator()(const shared_ptr) const; };// end struct class_tmpl_shared_ptr_hash /// Abstracts a class declaration. class class_decl : public scope_type_decl { // Forbidden class_decl(); public: enum access_specifier { private_access, protected_access, public_access };//end enum access_specifier /// The base class for member types, data members and member /// functions. Its purpose is to mainly to carry the access /// specifier (and possibly other properties that might be shared by /// all class members) for the member. class member { // Forbidden member(); public: member(access_specifier a, bool is_static = false) : m_access(a), m_is_static(is_static) {} access_specifier get_access_specifier() const {return m_access;} bool is_static() const {return m_is_static;} bool operator==(const member& o) const { return (get_access_specifier() == o.get_access_specifier() && is_static() == o.is_static()); } private: enum access_specifier m_access; bool m_is_static; };//end class member. /// Hasher for a class_decl::member struct member_hash { size_t operator()(const member& m) const { hash hash_int; return hash_int(m.get_access_specifier()); } };// struct member_hash /// Abstracts a member type declaration. class member_type : public member, public virtual decl_base { //Forbidden member_type(); public: member_type(shared_ptr t, access_specifier access) : decl_base("", location()), member(access), m_type(t) { } bool operator==(const member_type& o) const { return (*as_type() == *o.as_type() && static_cast(*this) == o); } operator shared_ptr() const {return m_type;} shared_ptr as_type() const {return m_type;} private: shared_ptr m_type; };//end class member_type /// A hash functor for instances class_decl::member_type. struct member_type_hash { size_t operator()(const member_type& t)const; };// end struct member_type_hash /// Abstraction of a base specifier in a class declaration. class base_spec : public member { // Forbidden base_spec(); public: base_spec(shared_ptr base, access_specifier a) : member(a), m_base_class(base) {} const shared_ptr get_base_class() const {return m_base_class;} bool operator==(const base_spec& other) const { return (static_cast(*this) == other && *get_base_class() == *other.get_base_class()); } private: shared_ptr m_base_class; };// end class base_spec /// A hashing functor for instances of class_decl::base_spec. struct base_spec_hash { size_t operator()(const base_spec& t) const; };// end struct base_spec_hash /// Abstract a data member declaration in a class declaration. class data_member : public var_decl, public member { // Forbidden data_member(); public: data_member(shared_ptr data_member, access_specifier access, bool is_laid_out, bool is_static, size_t offset_in_bits) : decl_base(data_member->get_name(), data_member->get_location(), data_member->get_mangled_name(), data_member->get_visibility()), var_decl(data_member->get_name(), data_member->get_type(), data_member->get_location(), data_member->get_mangled_name(), data_member->get_visibility(), data_member->get_binding()), member(access, is_static), m_is_laid_out(is_laid_out), m_offset_in_bits(offset_in_bits) {} data_member(const std::string& name, shared_ptr& type, access_specifier access, location locus, const std::string& mangled_name, visibility vis, binding bind, bool is_laid_out, bool is_static, size_t offset_in_bits) : decl_base(name, locus, name, vis), var_decl(name, type, locus, mangled_name, vis, bind), member(access, is_static), m_is_laid_out(is_laid_out), m_offset_in_bits(offset_in_bits) {} bool is_laid_out() const {return m_is_laid_out;} size_t get_offset_in_bits() const {return m_offset_in_bits;} bool operator==(const data_member& other) const { return (is_laid_out() == other.is_laid_out() && get_offset_in_bits() == other.get_offset_in_bits() && static_cast(*this) ==other && static_cast(*this) == other); } private: bool m_is_laid_out; size_t m_offset_in_bits; };// end class data_member /// Hasher for a data_member. struct data_member_hash { size_t operator()(data_member& t); };// end struct data_member_hash /// Abstracts a member function declaration in a class declaration. class member_function : public function_decl, public member { // Forbidden member_function(); public: member_function (const std::string& name, std::vector > parms, shared_ptr return_type, size_t ftype_size_in_bits, size_t ftype_align_in_bits, access_specifier access, bool declared_inline, location locus, const std::string& mangled_name, visibility vis, binding bind, size_t vtable_offset_in_bits, bool is_static, bool is_constructor, bool is_destructor, bool is_const) : decl_base(name, locus, name, vis), function_decl(name, parms, return_type, ftype_size_in_bits, ftype_align_in_bits, declared_inline, locus, mangled_name, vis, bind), member(access, is_static), m_vtable_offset_in_bits(vtable_offset_in_bits), m_is_constructor(is_constructor), m_is_destructor(is_destructor), m_is_const(is_const) {} member_function(shared_ptr fn, access_specifier access, size_t vtable_offset_in_bits, bool is_static, bool is_constructor, bool is_destructor, bool is_const) : decl_base(fn->get_name(), fn->get_location(), fn->get_mangled_name(), fn->get_visibility()), function_decl(fn->get_name(), fn->get_type(), fn->is_declared_inline(), fn->get_location(), fn->get_mangled_name(), fn->get_visibility(), fn->get_binding()), member(access, is_static), m_vtable_offset_in_bits(vtable_offset_in_bits), m_is_constructor(is_constructor), m_is_destructor(is_destructor), m_is_const(is_const) {} size_t get_vtable_offset_in_bits() const {return m_vtable_offset_in_bits;} bool is_constructor() const {return m_is_constructor;} bool is_destructor() const {return m_is_destructor;} bool is_const() const {return m_is_const;} bool operator==(const member_function& o) const { return (get_vtable_offset_in_bits() == o.get_vtable_offset_in_bits() && is_constructor() == o.is_constructor() && is_destructor() == o.is_destructor() && is_const() == o.is_const() && static_cast(*this) == o && static_cast(*this) == o); } private: size_t m_vtable_offset_in_bits; bool m_is_constructor; bool m_is_destructor; bool m_is_const; };// end class member_function /// A hashing functor for instances of class_decl::member_function. struct member_function_hash { size_t operator()(const member_function& t) const; };// end struct member_function_hash /// Abstract a member function template. class member_function_template : public member { // Forbiden member_function_template(); public: member_function_template (shared_ptr f, access_specifier access, bool is_static, bool is_constructor, bool is_const) : member(access, is_static), m_is_constructor(is_constructor), m_is_const(is_const), m_fn_tmpl(f) {} bool is_constructor() const {return m_is_constructor;} bool is_const() const {return m_is_const;} operator const function_template_decl& () const {return *m_fn_tmpl;} shared_ptr as_function_template_decl() const {return m_fn_tmpl;} bool operator==(const member_function_template& o) const; private: bool m_is_constructor; bool m_is_const; shared_ptr m_fn_tmpl; };//end class member_function_template struct member_function_template_hash { size_t operator()(const member_function_template&) const; };// end struct member_function_template_hash /// Abstracts a member class template template class member_class_template : public member { // Forbidden member_class_template(); public: member_class_template(shared_ptrc, access_specifier access, bool is_static) : member(access, is_static), m_class_tmpl(c) {} operator const class_template_decl& () const {return *m_class_tmpl;} shared_ptr as_class_template_decl() const {return m_class_tmpl;} bool operator==(const member_class_template& o) const; private: shared_ptr m_class_tmpl; };// end class member_class_template /// A hashing functor for instances of member_class_template. struct member_class_template_hash { size_t operator()(member_class_template&) const; };// end struct member_class_template_hash typedef std::list > base_specs_type; typedef std::list > member_types_type; typedef std::list > data_members_type; typedef std::list > member_functions_type; typedef std::list > member_function_templates_type; typedef std::list > member_class_templates_type; class_decl(const std::string& name, size_t size_in_bits, size_t align_in_bits, location locus, visibility vis, const std::list >& bases, const std::list >& member_types, const std::list >& data_members, const std::list >& member_fns) : decl_base(name, locus, name, vis), type_base(size_in_bits, align_in_bits), scope_type_decl(name, size_in_bits, align_in_bits, locus, vis), m_bases(bases), m_member_types(member_types), m_data_members(data_members), m_member_functions(member_fns) {} void add_base_specifier(shared_ptr b) {m_bases.push_back(b);} const std::list >& get_base_specifiers() const {return m_bases;} void add_member_type(shared_ptrt); const std::list >& get_member_types() const {return m_member_types;} void add_data_member(shared_ptr m); const std::list >& get_data_members() const {return m_data_members;} void add_member_function(shared_ptr m); const std::list >& get_member_functions() const {return m_member_functions;} void add_member_function_template(shared_ptr); const member_function_templates_type& get_member_function_templates() const {return m_member_function_templates;} void add_member_class_template(shared_ptr); const member_class_templates_type& get_member_class_templates() const {return m_member_class_templates;} virtual bool operator==(const class_decl&) const; virtual ~class_decl(); private: base_specs_type m_bases; member_types_type m_member_types; data_members_type m_data_members; member_functions_type m_member_functions; member_function_templates_type m_member_function_templates; member_class_templates_type m_member_class_templates; };// end class class_decl /// Hasher for the class_decl type struct class_decl_hash { size_t operator()(const class_decl& t) const; };//end struct class_decl_hash } // end namespace abigail #endif // __ABG_IR_H__