]> sourceware.org Git - libabigail.git/commitdiff
Fix template parameter hashing: make it know about enclosing template
authorDodji Seketeli <dodji@redhat.com>
Fri, 7 Nov 2014 11:13:53 +0000 (12:13 +0100)
committerDodji Seketeli <dodji@redhat.com>
Fri, 7 Nov 2014 11:16:34 +0000 (12:16 +0100)
* include/abg-ir.h (template_parameter_sptr, template_decl_sptr)
(template_decl_wptr): Declare new typedefs.
(class template_decl): Make this virtually inherit decl_base and
pimpl-ify it.
(class template_parameter): Pimpl-ify this.  Make the constructor
take the enclosing template parameter.
(struct template_decl::hash): Declare this here, rather than in
src/abg-hash.cc
(class type_tparameter, non_type_tparameter, template_tparameter)
(class type_composition, function_tdecl, class_tdecl): Pimpl-ify
this.
* src/abg-hash.cc (template_parameter::hash::operator()): Hash the
enclosing template parameter.  Avoid infinite recursion due to the
loop hash parameter -> hash template -> hash parameter.
(template_decl::hash::operator()) Define this here, now that it's
declared in abg-ir.h.  Also, avoid infinite recursion here; this
is complementary to what is done in the hashing for
template_parameter.
({type_tparameter, template_tparameter, }::hash::operator()):
Cache the calculated hash just as what is done for other types
hashed.
(template_decl::priv): Define this new type.
(template_decl::{add_template_parameter, get_template_parameters,
~template_decl}): Define these here to pimpl-ify template_decl.
(template_parameter::priv): Define this new type.
(template_parameter::template_parameter): Define this here to
pimpl-ify template_parameter.  Note also that this now takes the
enclosing template decl.
(template_parameter::{get_index, get_enclosing_template_decl,
get_hashing_has_started, set_hashing_has_started, operator::==}):
Define these here to pimpl-ify template_parameter.
(type_tparameter::priv): Define this new type.
(type_tparameter::type_tparameter): Define this here to pimpl-ify
type_tparameter.   Also, not that this constructor now takes the
enclosing template decl.
(class non_type_tparameter::priv): Define new type.
(non_type_tparameter::{non_type_tparameter, get_type}): Define
these here to pimpl-ify non_type_tparameter.  The constructor now
takes the enclosing template.
(template_tparameter::priv): Define new type.
(template_tparameter::template_tparameter): Define this here to
pimpl-ify template_tparameter.  This constructor now takes the
enclosing template.
(class type_composition::priv): New type.
(type_composition::{type_composition, get_composed_type,
set_composed_type}): Define these here to pimpl-ify
type_composition.  The constructor now takes the enclosing
template decl.
(class function_tdecl::priv): Define new type.
(function_tdecl::{function_tdecl, set_pattern, get_pattern,
get_binding}): Define this here to pimpl-ify function_tdecl.
(class class_tdecl::priv): Define this new type.
(class_tdecl::class_tdecl): Define this here to pimpl-ify
class_tdecl.
(class_tdecl::set_pattern): Adjust to pimpl-ify.
(class_tdecl::get_pattern): Define new pimpl-ified getter.
* src/abg-reader.cc (build_function_tdecl, build_class_tdecl):
Cleanup.  Pass the enclosing template to the template parameters
that are built.
(build_type_tparameter, build_type_composition)
(build_non_type_tparameter, build_template_tparameter)
(build_template_parameter): Take the enclosing template
declaration and pass it to the template parameter being created.
* tests/data/test-read-write/test12.xml: Fix and Adjust.
* tests/data/test-read-write/test13.xml: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
include/abg-ir.h
src/abg-hash.cc
src/abg-ir.cc
src/abg-reader.cc
tests/data/test-read-write/test12.xml
tests/data/test-read-write/test13.xml

index eae039954324a7a86f30a387690ef2b2a2ab8716..a17530128dd1b75ea35ee6d085b6ca6b6e62fa41 100644 (file)
@@ -2067,27 +2067,38 @@ public:
   virtual ~method_type();
 };// end class method_type.
 
+/// Convenience typedef for shared pointer to template parameter
+typedef shared_ptr<template_parameter> template_parameter_sptr;
+
+/// Convenience typedef for a shared pointer to template_decl
+typedef shared_ptr<template_decl> template_decl_sptr;
+
+/// Convenience typedef for a weak pointer to template_decl
+typedef weak_ptr<template_decl> template_decl_wptr;
+
 /// The base class of templates.
-class template_decl
+class template_decl : public virtual decl_base
 {
-  // XXX
-  std::list<shared_ptr<template_parameter> > parms_;
+  class priv;
+  typedef shared_ptr<priv> priv_sptr;
+  priv_sptr priv_;
+
+  template_decl();
 
 public:
 
   /// Hasher.
   struct hash;
 
-  template_decl()
-  {}
+  template_decl(const string& name,
+               location locus,
+               visibility vis = VISIBILITY_DEFAULT);
 
   void
-  add_template_parameter(shared_ptr<template_parameter> p)
-  {parms_.push_back(p);}
+  add_template_parameter(const template_parameter_sptr p);
 
-  const std::list<shared_ptr<template_parameter> >&
-  get_template_parameters() const
-  {return parms_;}
+  const std::list<template_parameter_sptr>&
+  get_template_parameters() const;
 
   virtual bool
   operator==(const template_decl& o) const;
@@ -2100,7 +2111,9 @@ public:
 /// non_type_template_parameter and template_template_parameter below.
 class template_parameter
 {
-  unsigned index_;
+  class priv;
+  typedef shared_ptr<priv> priv_sptr;
+  priv_sptr priv_;
 
   // Forbidden
   template_parameter();
@@ -2112,22 +2125,44 @@ class template_parameter
   struct dynamic_hash;
   struct shared_ptr_hash;
 
-  template_parameter(unsigned index) : index_(index)
-  {}
+  template_parameter(unsigned                  index,
+                    template_decl_sptr enclosing_tdecl);
 
   virtual bool
   operator==(const template_parameter&) const;
 
   unsigned
-  get_index() const
-  {return index_;}
+  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
+
+/// Convenience typedef for a shared pointer to @ref type_tparameter.
+typedef shared_ptr<type_tparameter> type_tparameter_sptr;
+
 /// 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();
 
@@ -2136,14 +2171,10 @@ public:
   /// Hasher.
   struct hash;
 
-  type_tparameter(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)
-  {}
+  type_tparameter(unsigned             index,
+                 template_decl_sptr    enclosing_tdecl,
+                 const std::string&    name,
+                 location              locus);
 
   virtual bool
   operator==(const type_base&) const;
@@ -2157,9 +2188,18 @@ public:
   virtual ~type_tparameter();
 };// end class type_tparameter.
 
+/// Convenience typedef for shared pointer to @ref
+/// non_type_template_parameter
+typedef shared_ptr<non_type_tparameter> non_type_tparameter_sptr;
+
 /// 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
@@ -2169,13 +2209,11 @@ public:
   /// Hasher.
   struct hash;
 
-  non_type_tparameter(unsigned index, const std::string& name,
-                             shared_ptr<type_base> type, location locus)
-    : decl_base(name, locus, ""),
-      template_parameter(index),
-      type_(type)
-  {}
-
+  non_type_tparameter(unsigned                 index,
+                     template_decl_sptr        enclosing_tdecl,
+                     const std::string&        name,
+                     shared_ptr<type_base>     type,
+                     location                  locus);
   virtual size_t
   get_hash() const;
 
@@ -2185,13 +2223,8 @@ public:
   virtual bool
   operator==(const template_parameter&) const;
 
-  type_base_sptr
-  get_type() const
-  {
-    if (type_.expired())
-      return type_base_sptr();
-    return type_base_sptr(type_);
-  }
+  const type_base_sptr
+  get_type() const;
 
   virtual ~non_type_tparameter();
 };// end class non_type_tparameter
@@ -2206,9 +2239,18 @@ struct non_type_tparameter::hash
   operator()(const non_type_tparameter* t) const;
 };
 
+class template_tparameter;
+
+/// Convenience typedef for a shared_ptr to @ref template_tparameter.
+typedef shared_ptr<template_tparameter> template_tparameter_sptr;
+
 /// 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();
 
@@ -2218,13 +2260,9 @@ public:
   struct hash;
 
   template_tparameter(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),
-      type_tparameter(index, name, locus)
-  {}
+                     template_decl_sptr enclosing_tdecl,
+                     const std::string& name,
+                     location locus);
 
   virtual bool
   operator==(const type_base&) const;
@@ -2238,6 +2276,9 @@ public:
   virtual ~template_tparameter();
 };
 
+/// Convenience typedef for shared pointer to type_composition
+typedef shared_ptr<type_composition> type_composition_sptr;
+
 /// 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
@@ -2245,27 +2286,25 @@ public:
 /// scope of a template_decl.
 class type_composition : public template_parameter, public virtual decl_base
 {
-  type_base_wptr type_;
+  class priv;
+  typedef shared_ptr<priv> priv_sptr;
+
+  priv_sptr priv_;
 
   type_composition();
 
 public:
   struct hash;
 
-  type_composition(unsigned                    index,
-                  shared_ptr<type_base>        composed_type);
+  type_composition(unsigned            index,
+                  template_decl_sptr   tdecl,
+                  type_base_sptr       composed_type);
 
-  type_base_sptr
-  get_composed_type() const
-  {
-    if (type_.expired())
-      return type_base_sptr();
-    return type_base_sptr(type_);
-  }
+  const type_base_sptr
+  get_composed_type() const;
 
   void
-  set_composed_type(type_base_sptr t)
-  {type_ = t;}
+  set_composed_type(type_base_sptr t);
 
   virtual size_t
   get_hash() const;
@@ -2290,8 +2329,10 @@ typedef shared_ptr<function_tdecl> function_tdecl_sptr;
 /// Abstract a function template declaration.
 class function_tdecl : public template_decl, public scope_decl
 {
-  shared_ptr<function_decl> pattern_;
-  binding binding_;
+  class priv;
+  typedef shared_ptr<priv> priv_sptr;
+
+  priv_sptr priv_;
 
   // Forbidden
   function_tdecl();
@@ -2302,22 +2343,14 @@ public:
   struct hash;
   struct shared_ptr_hash;
 
-  function_tdecl(location locus,
-                        visibility vis = VISIBILITY_DEFAULT,
-                        binding bind = BINDING_NONE)
-  : decl_base("", locus, "", vis), scope_decl("", locus),
-    binding_(bind)
-  {}
+  function_tdecl(location      locus,
+                visibility     vis = VISIBILITY_DEFAULT,
+                binding        bind = BINDING_NONE);
 
-  function_tdecl(shared_ptr<function_decl> 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),
-    binding_(bind)
-  {set_pattern(pattern);}
+  function_tdecl(function_decl_sptr    pattern,
+                location               locus,
+                visibility             vis = VISIBILITY_DEFAULT,
+                binding                bind = BINDING_NONE);
 
   virtual bool
   operator==(const decl_base&) const;
@@ -2326,20 +2359,13 @@ public:
   operator==(const template_decl&) const;
 
   void
-  set_pattern(shared_ptr<function_decl> p)
-  {
-    pattern_ = p;
-    add_decl_to_scope(p, this);
-    set_name(p->get_name());
-  }
+  set_pattern(shared_ptr<function_decl> p);
 
   shared_ptr<function_decl>
-  get_pattern() const
-  {return pattern_;}
+  get_pattern() const;
 
   binding
-  get_binding() const
-  {return binding_;}
+  get_binding() const;
 
   virtual bool
   traverse(ir_node_visitor& v);
@@ -2353,7 +2379,10 @@ typedef shared_ptr<class_tdecl> class_tdecl_sptr;
 /// Abstract a class template.
 class class_tdecl : public template_decl, public scope_decl
 {
-  shared_ptr<class_decl> pattern_;
+  class priv;
+  typedef shared_ptr<priv> priv_sptr;
+
+  priv_sptr priv_;
 
   // Forbidden
   class_tdecl();
@@ -2364,9 +2393,7 @@ public:
   struct hash;
   struct shared_ptr_hash;
 
-  class_tdecl(location locus, visibility vis = VISIBILITY_DEFAULT)
-  : decl_base("", locus, "", vis), scope_decl("", locus)
-  {}
+  class_tdecl(location locus, visibility vis = VISIBILITY_DEFAULT);
 
   class_tdecl(shared_ptr<class_decl> pattern,
              location locus, visibility vis = VISIBILITY_DEFAULT);
@@ -2381,11 +2408,10 @@ public:
   operator==(const class_tdecl&) const;
 
   void
-  set_pattern(shared_ptr<class_decl> p);
+  set_pattern(class_decl_sptr p);
 
   shared_ptr<class_decl>
-  get_pattern() const
-  {return pattern_;}
+  get_pattern() const;
 
   virtual bool
   traverse(ir_node_visitor& v);
index a27660bc4a82b1c54dacf32150bf28a2351241da..7d9ad2a38f1116aec72401f4ce5367acf5f89b80 100644 (file)
@@ -688,11 +688,26 @@ struct template_parameter::hash
   size_t
   operator()(const template_parameter& t) const
   {
+    // Let's avoid infinite recursion triggered from the fact that
+    // hashing a template parameter triggers hashing the enclosed
+    // template decl, which in turn triggers the hashing of its
+    // template parameters; so the initial template parameter that
+    // triggered the hashing could be hashed again ...
+    if (t.get_hashing_has_started())
+      return 0;
+
+    t.set_hashing_has_started(true);
+
     std::tr1::hash<unsigned> hash_unsigned;
     std::tr1::hash<std::string> hash_string;
+    template_decl::hash hash_template_decl;
 
     size_t v = hash_string(typeid(t).name());
     v = hashing::combine_hashes(v, hash_unsigned(t.get_index()));
+    v = hashing::combine_hashes(v, hash_template_decl
+                               (*t.get_enclosing_template_decl()));
+
+    t.set_hashing_has_started(false);
 
     return v;
   }
@@ -708,44 +723,46 @@ struct template_parameter::shared_ptr_hash
 {
   size_t
   operator()(const shared_ptr<template_parameter> t) const
-  { return template_parameter::dynamic_hash()(t.get()); }
+  {return template_parameter::dynamic_hash()(t.get());}
 };
 
-struct template_decl::hash
+size_t
+template_decl::hash::operator()(const template_decl& t) const
 {
-  size_t
-  operator()(const template_decl& t) const
-  {
-    std::tr1::hash<string> hash_string;
-    template_parameter::shared_ptr_hash hash_template_parameter;
+  std::tr1::hash<string> hash_string;
+  template_parameter::shared_ptr_hash hash_template_parameter;
 
-    size_t v = hash_string(typeid(t).name());
+  size_t v = hash_string(typeid(t).name());
+  v = hash_string(t.get_qualified_name());
 
-    for (list<shared_ptr<template_parameter> >::const_iterator p =
-          t.get_template_parameters().begin();
-        p != t.get_template_parameters().end();
-        ++p)
-      {
-       v = hashing::combine_hashes(v, hash_template_parameter(*p));
-      }
-    return v;
-  }
-};
+  for (list<template_parameter_sptr>::const_iterator p =
+        t.get_template_parameters().begin();
+       p != t.get_template_parameters().end();
+       ++p)
+    if (!(*p)->get_hashing_has_started())
+      v = hashing::combine_hashes(v, hash_template_parameter(*p));
+
+  return v;
+}
 
 struct type_tparameter::hash
 {
   size_t
   operator()(const type_tparameter& t) const
   {
-    std::tr1::hash<string> hash_string;
-    template_parameter::hash hash_template_parameter;
-    type_decl::hash hash_type;
+    if (t.peek_hash_value() == 0 || t.hashing_started())
+      {
+       std::tr1::hash<string> hash_string;
+       template_parameter::hash hash_template_parameter;
+       type_decl::hash hash_type;
 
-    size_t v = hash_string(typeid(t).name());
-    v = hashing::combine_hashes(v, hash_template_parameter(t));
-    v = hashing::combine_hashes(v, hash_type(t));
+       size_t v = hash_string(typeid(t).name());
+       v = hashing::combine_hashes(v, hash_template_parameter(t));
+       v = hashing::combine_hashes(v, hash_type(t));
 
-    return v;
+       t.set_hash(v);
+      }
+    return t.peek_hash_value();
   }
 };
 
@@ -783,15 +800,19 @@ struct template_tparameter::hash
   size_t
   operator()(const template_tparameter& t) const
   {
-    std::tr1::hash<string> hash_string;
-    type_tparameter::hash hash_template_type_parm;
-    template_decl::hash hash_template_decl;
+    if (t.peek_hash_value() == 0 || t.hashing_started())
+      {
+       std::tr1::hash<string> hash_string;
+       type_tparameter::hash hash_template_type_parm;
+       template_decl::hash hash_template_decl;
 
-    size_t v = hash_string(typeid(t).name());
-    v = hashing::combine_hashes(v, hash_template_type_parm(t));
-    v = hashing::combine_hashes(v, hash_template_decl(t));
+       size_t v = hash_string(typeid(t).name());
+       v = hashing::combine_hashes(v, hash_template_type_parm(t));
+       v = hashing::combine_hashes(v, hash_template_decl(t));
+       t.set_hash(v);
+      }
 
-    return v;
+    return t.peek_hash_value();
   }
 };
 
index 2c6b7412971b58d2ebfa9064d97c7c261760c331..90aa2b0982305b13967368359ed06946d8e270d7 100644 (file)
@@ -7517,10 +7517,43 @@ operator<<(std::ostream& o, access_specifier a)
 
 // <template_decl stuff>
 
-template_decl::~template_decl()
+/// Data type of the private data of the @template_decl type.
+class template_decl::priv
+{
+  friend class template_decl;
+
+  std::list<template_parameter_sptr> parms_;
+public:
+
+  priv()
+  {}
+}; // end class template_decl::priv
+
+/// Add a new template parameter to the current instance of @ref
+/// template_decl.
+///
+/// @param p the new template parameter to add.
+void
+template_decl::add_template_parameter(const template_parameter_sptr p)
+{priv_->parms_.push_back(p);}
+
+/// Get the list of template parameters of the current instance of
+/// @ref template_decl.
+///
+/// @return the list of template parameters.
+const std::list<template_parameter_sptr>&
+template_decl::get_template_parameters() const
+{return priv_->parms_;}
+
+template_decl::template_decl(const string& name, location locus, visibility vis)
+  : decl_base(name, locus, /*mangled_name=*/"", vis),
+    priv_(new priv)
 {
 }
 
+template_decl::~template_decl()
+{}
+
 bool
 template_decl::operator==(const template_decl& o) const
 {
@@ -7551,15 +7584,85 @@ template_decl::operator==(const template_decl& o) const
 
 //<template_parameter>
 
-bool
-template_parameter::operator==(const template_parameter& o) const
+/// The type of the private data of the @ref template_parameter type.
+class template_parameter::priv
 {
-  return (get_index() == o.get_index());
+  friend class template_parameter;
+
+  unsigned index_;
+  template_decl_wptr template_decl_;
+  mutable bool hashing_started_;
+
+  priv();
+
+public:
+
+  priv(unsigned index, template_decl_sptr enclosing_template_decl)
+    : index_(index),
+      template_decl_(enclosing_template_decl),
+      hashing_started_()
+  {}
+}; // end class template_parameter::priv
+
+template_parameter::template_parameter(unsigned         index,
+                                      template_decl_sptr enclosing_template)
+  : priv_(new priv(index, enclosing_template))
+  {}
+
+unsigned
+template_parameter::get_index() const
+{return priv_->index_;}
+
+const template_decl_sptr
+template_parameter::get_enclosing_template_decl() const
+{
+  if (priv_->template_decl_.expired())
+    return template_decl_sptr();
+  return template_decl_sptr(priv_->template_decl_);
 }
 
+bool
+template_parameter::get_hashing_has_started() const
+{return priv_->hashing_started_;}
+
+void
+template_parameter::set_hashing_has_started(bool f) const
+{priv_->hashing_started_ = f;}
+
+bool
+template_parameter::operator==(const template_parameter& o) const
+{return (get_index() == o.get_index());}
+
 template_parameter::~template_parameter()
 {}
 
+/// The type of the private data of the @ref type_tparameter type.
+class type_tparameter::priv
+{
+  friend class type_tparameter;
+}; // end class type_tparameter::priv
+
+/// Constructor of the @ref type_tparameter type.
+///
+/// @param index the index the type template parameter.
+///
+/// @param enclosing_tdecl the enclosing template declaration.
+///
+/// @param name the name of the template parameter.
+///
+/// @param locus the location of the declaration of this type template
+/// parameter.
+type_tparameter::type_tparameter(unsigned              index,
+                                template_decl_sptr     enclosing_tdecl,
+                                const std::string&     name,
+                                location               locus)
+  : decl_base(name, locus),
+    type_base(0, 0),
+    type_decl(name, 0, 0, locus),
+    template_parameter(index, enclosing_tdecl),
+    priv_(new priv)
+{}
+
 bool
 type_tparameter::operator==(const type_base& other) const
 {
@@ -7594,6 +7697,56 @@ type_tparameter::operator==(const type_tparameter& other) const
 type_tparameter::~type_tparameter()
 {}
 
+/// The type of the private data of the @ref non_type_tparameter type.
+class non_type_tparameter::priv
+{
+  friend class non_type_tparameter;
+
+  type_base_wptr type_;
+
+  priv();
+
+public:
+
+  priv(type_base_sptr type)
+    : type_(type)
+  {}
+}; // end class non_type_tparameter::priv
+
+/// The constructor for the @ref non_type_tparameter type.
+///
+/// @param index the index of the template parameter.
+///
+/// @param enclosing_tdecl the enclosing template declaration that
+/// holds this parameter parameter.
+///
+/// @param name the name of the template parameter.
+///
+/// @param type the type of the template parameter.
+///
+/// @param locus the location of the declaration of this template
+/// parameter.
+non_type_tparameter::non_type_tparameter(unsigned              index,
+                                        template_decl_sptr     enclosing_tdecl,
+                                        const std::string&     name,
+                                        type_base_sptr type,
+                                        location               locus)
+    : decl_base(name, locus, ""),
+      template_parameter(index, enclosing_tdecl),
+      priv_(new priv(type))
+{}
+
+/// Getter for the type of the template parameter.
+///
+/// @return the type of the template parameter.
+const type_base_sptr
+non_type_tparameter::get_type() const
+{
+  if (priv_->type_.expired())
+    return type_base_sptr();
+  return type_base_sptr(priv_->type_);
+}
+
 /// Get the hash value of the current instance.
 ///
 /// @return the hash value.
@@ -7636,6 +7789,35 @@ non_type_tparameter::operator==(const template_parameter& other) const
 non_type_tparameter::~non_type_tparameter()
 {}
 
+// <template_tparameter stuff>
+
+/// Type of the private data of the @ref template_tparameter type.
+class template_tparameter::priv
+{
+}; //end class template_tparameter::priv
+
+/// Constructor for the @ref template_tparameter.
+///
+/// @param index the index of the template parameter.
+///
+/// @param enclosing_tdecl the enclosing template declaration.
+///
+/// @param name the name of the template parameter.
+///
+/// @param locus the location of the declaration of the template
+/// parameter.
+template_tparameter::template_tparameter(unsigned              index,
+                                        template_decl_sptr     enclosing_tdecl,
+                                        const std::string&     name,
+                                        location               locus)
+    : decl_base(name, locus),
+      type_base(0, 0),
+      type_decl(name, 0, 0, locus, name, VISIBILITY_DEFAULT),
+      type_tparameter(index, enclosing_tdecl, name, locus),
+      template_decl(name, locus),
+      priv_(new priv)
+{}
+
 bool
 template_tparameter::operator==(const type_base& other) const
 {
@@ -7679,11 +7861,61 @@ template_tparameter::operator==(const template_decl& o) const
 template_tparameter::~template_tparameter()
 {}
 
-type_composition::type_composition(unsigned index, shared_ptr<type_base> t)
-: decl_base("", location()), template_parameter(index),
-  type_(std::tr1::dynamic_pointer_cast<type_base>(t))
+// </template_tparameter stuff>
+
+// <type_composition stuff>
+
+/// The type of the private data of the @ref type_composition type.
+class type_composition::priv
+{
+  friend class type_composition;
+
+  type_base_wptr type_;
+
+  // Forbid this.
+  priv();
+
+public:
+
+  priv(type_base_wptr type)
+    : type_(type)
+  {}
+}; //end class type_composition::priv
+
+/// Constructor for the @ref type_composition type.
+///
+/// @param index the index of the template type composition.
+///
+/// @param tdecl the enclosing template parameter that owns the
+/// composition.
+///
+/// @param t the resulting type.
+type_composition::type_composition(unsigned            index,
+                                  template_decl_sptr   tdecl,
+                                  type_base_sptr       t)
+  : decl_base("", location()),
+    template_parameter(index, tdecl),
+    priv_(new priv(t))
 {}
 
+/// Getter for the resulting composed type.
+///
+/// @return the composed type.
+const type_base_sptr
+type_composition::get_composed_type() const
+{
+  if (priv_->type_.expired())
+    return type_base_sptr();
+  return type_base_sptr(priv_->type_);
+}
+
+/// Setter for the resulting composed type.
+///
+/// @param t the composed type.
+void
+type_composition::set_composed_type(type_base_sptr t)
+{priv_->type_ = t;}
+
 /// Get the hash value for the current instance.
 ///
 /// @return the hash value.
@@ -7697,9 +7929,99 @@ type_composition::get_hash() const
 type_composition::~type_composition()
 {}
 
-//</template_parameter>
+// </type_composition stuff>
+
+//</template_parameter stuff>
 
 // <function_template>
+
+class function_tdecl::priv
+{
+  friend class function_tdecl;
+
+  function_decl_sptr pattern_;
+  binding binding_;
+
+  priv();
+
+public:
+
+  priv(function_decl_sptr pattern, binding bind)
+    : pattern_(pattern), binding_(bind)
+  {}
+
+  priv(binding bind)
+    : binding_(bind)
+  {}
+}; // end class function_tdecl::priv
+
+/// Constructor for a function template declaration.
+///
+/// @param locus the location of the declaration.
+///
+/// @param vis the visibility of the declaration.  This is the
+/// visibility the functions instantiated from this template are going
+/// to have.
+///
+/// @param bind the binding of the declaration.  This is the binding
+/// the functions instantiated from this template are going to have.
+function_tdecl::function_tdecl(location        locus,
+                              visibility       vis,
+                              binding          bind)
+  : decl_base("", locus, "", vis),
+    template_decl("", locus, vis),
+    scope_decl("", locus),
+    priv_(new priv(bind))
+{}
+
+/// Constructor for a function template declaration.
+///
+/// @param pattern the pattern of the template.
+///
+/// @param locus the location of the declaration.
+///
+/// @param vis the visibility of the declaration.  This is the
+/// visibility the functions instantiated from this template are going
+/// to have.
+///
+/// @param bind the binding of the declaration.  This is the binding
+/// the functions instantiated from this template are going to have.
+function_tdecl::function_tdecl(function_decl_sptr      pattern,
+                              location         locus,
+                              visibility               vis,
+                              binding                  bind)
+  : decl_base(pattern->get_name(), locus,
+             pattern->get_name(), vis),
+    template_decl(pattern->get_name(), locus, vis),
+    scope_decl(pattern->get_name(), locus),
+    priv_(new priv(pattern, bind))
+{}
+
+/// Set a new pattern to the function template.
+///
+/// @param p the new pattern.
+void
+function_tdecl::set_pattern(function_decl_sptr p)
+{
+  priv_->pattern_ = p;
+  add_decl_to_scope(p, this);
+  set_name(p->get_name());
+}
+
+/// Get the pattern of the function template.
+///
+/// @return the pattern.
+function_decl_sptr
+function_tdecl::get_pattern() const
+{return priv_->pattern_;}
+
+/// Get the binding of the function template.
+///
+/// @return the binding
+decl_base::binding
+function_tdecl::get_binding() const
+{return priv_->binding_;}
+
 bool
 function_tdecl::operator==(const decl_base& other) const
 {
@@ -7758,7 +8080,37 @@ function_tdecl::~function_tdecl()
 
 // <class template>
 
-/// Constructor for the class_tdecl type.
+/// Type of the private data of the the @ref class_tdecl type.
+class class_tdecl::priv
+{
+  friend class class_tdecl;
+  class_decl_sptr pattern_;
+
+public:
+
+  priv()
+  {}
+
+  priv(class_decl_sptr pattern)
+    : pattern_(pattern)
+  {}
+}; // end class class_tdecl::priv
+
+/// Constructor for the @ref class_tdecl type.
+///
+/// @param locus the location of the declaration of the class_tdecl
+/// type.
+///
+/// @param vis the visibility of the instance of class instantiated
+/// from this template.
+class_tdecl::class_tdecl(location locus, visibility vis)
+  : decl_base("", locus, "", vis),
+    template_decl("", locus, vis),
+    scope_decl("", locus),
+    priv_(new priv)
+{}
+
+/// Constructor for the @ref class_tdecl type.
 ///
 /// @param pattern The details of the class template. This must NOT be a
 /// null pointer.  If you really this to be null, please use the
@@ -7768,21 +8120,33 @@ function_tdecl::~function_tdecl()
 ///
 /// @param vis the visibility of the instances of class instantiated
 /// from this template.
-class_tdecl::class_tdecl(shared_ptr<class_decl> pattern,
+class_tdecl::class_tdecl(class_decl_sptr pattern,
                         location locus, visibility vis)
 : decl_base(pattern->get_name(), locus,
            pattern->get_name(), vis),
-  scope_decl(pattern->get_name(), locus)
-{set_pattern(pattern);}
+  template_decl(pattern->get_name(), locus, vis),
+  scope_decl(pattern->get_name(), locus),
+  priv_(new priv(pattern))
+{}
 
+/// Setter of the pattern of the template.
+///
+/// @param p the new template.
 void
-class_tdecl::set_pattern(shared_ptr<class_decl> p)
+class_tdecl::set_pattern(class_decl_sptr p)
 {
-  pattern_ = p;
+  priv_->pattern_ = p;
   add_decl_to_scope(p, this);
   set_name(p->get_name());
 }
 
+/// Getter of the pattern of the template.
+///
+/// @return p the new template.
+class_decl_sptr
+class_tdecl::get_pattern() const
+{return priv_->pattern_;}
+
 bool
 class_tdecl::operator==(const decl_base& other) const
 {
index da7ffaf7207568effaf0dcb29be4a00a0273ec1f..fb9bbac74746d266e15767f982d0185711fbea29 100644 (file)
@@ -606,20 +606,25 @@ build_function_tdecl(read_context&, const xmlNodePtr, bool);
 static shared_ptr<class_tdecl>
 build_class_tdecl(read_context&, const xmlNodePtr, bool);
 
-static shared_ptr<type_tparameter>
-build_type_tparameter(read_context&, const xmlNodePtr, unsigned);
+static type_tparameter_sptr
+build_type_tparameter(read_context&, const xmlNodePtr,
+                     unsigned, template_decl_sptr);
 
-static shared_ptr<type_composition>
-build_type_composition(read_context&, const xmlNodePtr, unsigned);
+static type_composition_sptr
+build_type_composition(read_context&, const xmlNodePtr,
+                      unsigned, template_decl_sptr);
 
-static shared_ptr<non_type_tparameter>
-build_non_type_tparameter(read_context&, const xmlNodePtr, unsigned);
+static non_type_tparameter_sptr
+build_non_type_tparameter(read_context&, const xmlNodePtr,
+                         unsigned, template_decl_sptr);
 
-static shared_ptr<template_tparameter>
-build_template_tparameter(read_context&, const xmlNodePtr, unsigned);
+static template_tparameter_sptr
+build_template_tparameter(read_context&, const xmlNodePtr,
+                         unsigned, template_decl_sptr);
 
-static shared_ptr<template_parameter>
-build_template_parameter(read_context&, const xmlNodePtr, unsigned);
+static template_parameter_sptr
+build_template_parameter(read_context&, const xmlNodePtr,
+                        unsigned, template_decl_sptr);
 
 // Please make this build_type function be the last one of the list.
 // Note that it should call each type-building function above.  So
@@ -2918,8 +2923,7 @@ build_function_tdecl(read_context& ctxt,
   decl_base::binding bind = decl_base::BINDING_NONE;
   read_binding(node, bind);
 
-  shared_ptr<function_tdecl> fn_tmpl_decl
-    (new function_tdecl(loc, vis, bind));
+  function_tdecl_sptr fn_tmpl_decl(new function_tdecl(loc, vis, bind));
 
   ctxt.push_decl_to_current_scope(fn_tmpl_decl, add_to_current_scope);
 
@@ -2929,8 +2933,8 @@ build_function_tdecl(read_context& ctxt,
       if (n->type != XML_ELEMENT_NODE)
        continue;
 
-      if (shared_ptr<template_parameter> parm =
-         build_template_parameter(ctxt, n, parm_index))
+      if (template_parameter_sptr parm =
+         build_template_parameter(ctxt, n, parm_index, fn_tmpl_decl))
        {
          fn_tmpl_decl->add_template_parameter(parm);
          ++parm_index;
@@ -2980,8 +2984,7 @@ build_class_tdecl(read_context&   ctxt,
   decl_base::visibility vis = decl_base::VISIBILITY_NONE;
   read_visibility(node, vis);
 
-  shared_ptr<class_tdecl> class_tmpl
-    (new class_tdecl(loc, vis));
+  class_tdecl_sptr class_tmpl (new class_tdecl(loc, vis));
 
   ctxt.push_decl_to_current_scope(class_tmpl, add_to_current_scope);
 
@@ -2991,8 +2994,8 @@ build_class_tdecl(read_context&   ctxt,
       if (n->type != XML_ELEMENT_NODE)
        continue;
 
-      if (shared_ptr<template_parameter> parm=
-         build_template_parameter(ctxt, n, parm_index))
+      if (template_parameter_sptr parm=
+         build_template_parameter(ctxt, n, parm_index, class_tmpl))
        {
          class_tmpl->add_template_parameter(parm);
          ++parm_index;
@@ -3017,14 +3020,18 @@ build_class_tdecl(read_context& ctxt,
 /// @param index the index (occurrence index, starting from 0) of the
 /// template parameter.
 ///
+/// @param tdecl the enclosing template declaration that holds the
+/// template type parameter.
+///
 /// @return a pointer to a newly created instance of
 /// type_tparameter, a null pointer otherwise.
-static shared_ptr<type_tparameter>
-build_type_tparameter(read_context&    ctxt,
-                     const xmlNodePtr  node,
-                     unsigned          index)
+static type_tparameter_sptr
+build_type_tparameter(read_context&            ctxt,
+                     const xmlNodePtr          node,
+                     unsigned                  index,
+                     template_decl_sptr        tdecl)
 {
-  shared_ptr<type_tparameter> nil, result;
+  type_tparameter_sptr nil, result;
 
   if (!xmlStrEqual(node->name, BAD_CAST("template-type-parameter")))
     return nil;
@@ -3050,7 +3057,7 @@ build_type_tparameter(read_context&       ctxt,
   location loc;
   read_location(ctxt, node,loc);
 
-  result.reset(new type_tparameter(index, name, loc));
+  result.reset(new type_tparameter(index, tdecl, name, loc));
 
   if (id.empty())
     ctxt.push_decl_to_current_scope(dynamic_pointer_cast<decl_base>(result),
@@ -3071,20 +3078,24 @@ build_type_tparameter(read_context&     ctxt,
 ///
 /// @param index the index of the previous normal template parameter.
 ///
+/// @param tdecl the enclosing template declaration that holds this
+/// template parameter type composition.
+///
 /// @return a pointer to a new instance of tmpl_parm_type_composition
 /// upon successful completion, a null pointer otherwise.
-static shared_ptr<type_composition>
-build_type_composition(read_context&   ctxt,
-                      const xmlNodePtr node,
-                      unsigned index)
+static type_composition_sptr
+build_type_composition(read_context&           ctxt,
+                      const xmlNodePtr node,
+                      unsigned         index,
+                      template_decl_sptr       tdecl)
 {
-  shared_ptr<type_composition> nil, result;
+  type_composition_sptr nil, result;
 
   if (!xmlStrEqual(node->name, BAD_CAST("template-parameter-type-composition")))
     return nil;
 
-  shared_ptr<type_base> composed_type;
-  result.reset(new type_composition(index, composed_type));
+  type_base_sptr composed_type;
+  result.reset(new type_composition(index, tdecl, composed_type));
   ctxt.push_decl_to_current_scope(dynamic_pointer_cast<decl_base>(result),
                                  /*add_to_current_scope=*/true);
 
@@ -3123,15 +3134,19 @@ build_type_composition(read_context&    ctxt,
 ///
 /// @param index the index of the parameter.
 ///
+/// @param tdecl the enclosing template declaration that holds this
+/// non type template parameter.
+///
 /// @return a pointer to a newly created instance of
 /// non_type_tparameter upon successful completion, a null
 /// pointer code otherwise.
-static shared_ptr<non_type_tparameter>
-build_non_type_tparameter(read_context&                ctxt,
-                                 const xmlNodePtr      node,
-                                 unsigned              index)
+static non_type_tparameter_sptr
+build_non_type_tparameter(read_context&        ctxt,
+                         const xmlNodePtr      node,
+                         unsigned              index,
+                         template_decl_sptr    tdecl)
 {
-  shared_ptr<non_type_tparameter> r;
+  non_type_tparameter_sptr r;
 
   if (!xmlStrEqual(node->name, BAD_CAST("template-non-type-parameter")))
     return r;
@@ -3139,7 +3154,7 @@ build_non_type_tparameter(read_context&           ctxt,
   string type_id;
   if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
     type_id = CHAR_STR(s);
-  shared_ptr<type_base> type;
+  type_base_sptr type;
   if (type_id.empty()
       || !(type = ctxt.build_or_get_type_decl(type_id, true)))
     abort();
@@ -3151,7 +3166,7 @@ build_non_type_tparameter(read_context&           ctxt,
   location loc;
   read_location(ctxt, node,loc);
 
-  r.reset(new non_type_tparameter(index, name, type, loc));
+  r.reset(new non_type_tparameter(index, tdecl, name, type, loc));
   ctxt.push_decl_to_current_scope(dynamic_pointer_cast<decl_base>(r),
                                  /*add_to_current_scope=*/true);
 
@@ -3167,14 +3182,18 @@ build_non_type_tparameter(read_context&         ctxt,
 ///
 /// @param index the index of the template parameter.
 ///
+/// @param tdecl the enclosing template declaration that holds this
+/// template template parameter.
+///
 /// @return a pointer to a new instance of template_tparameter
 /// upon successful completion, a null pointer otherwise.
-static shared_ptr<template_tparameter>
-build_template_tparameter(read_context& ctxt,
-                         const xmlNodePtr node,
-                         unsigned index)
+static template_tparameter_sptr
+build_template_tparameter(read_context&        ctxt,
+                         const xmlNodePtr      node,
+                         unsigned              index,
+                         template_decl_sptr    tdecl)
 {
-  shared_ptr<template_tparameter> nil;
+  template_tparameter_sptr nil;
 
   if (!xmlStrEqual(node->name, BAD_CAST("template-template-parameter")))
     return nil;
@@ -3201,8 +3220,8 @@ build_template_tparameter(read_context& ctxt,
   location loc;
   read_location(ctxt, node, loc);
 
-  shared_ptr<template_tparameter> result
-    (new template_tparameter(index, name, loc));
+  template_tparameter_sptr result(new template_tparameter(index, tdecl,
+                                                         name, loc));
 
   ctxt.push_decl_to_current_scope(result, /*add_to_current_scope=*/true);
 
@@ -3214,7 +3233,7 @@ build_template_tparameter(read_context& ctxt,
        continue;
 
       if (shared_ptr<template_parameter> p =
-         build_template_parameter(ctxt, n, parm_index))
+         build_template_parameter(ctxt, n, parm_index, result))
        {
          result->add_template_parameter(p);
          ++parm_index;
@@ -3236,19 +3255,23 @@ build_template_tparameter(read_context& ctxt,
 ///
 /// @param index the index of the template parameter we are parsing.
 ///
+/// @param tdecl the enclosing template declaration that holds this
+/// template parameter.
+///
 /// @return a pointer to a newly created instance of
 /// template_parameter upon successful completion, a null pointer
 /// otherwise.
-static shared_ptr<template_parameter>
+static template_parameter_sptr
 build_template_parameter(read_context&         ctxt,
                         const xmlNodePtr       node,
-                        unsigned               index)
+                        unsigned               index,
+                        template_decl_sptr     tdecl)
 {
   shared_ptr<template_parameter> r;
-  ((r = build_type_tparameter(ctxt, node, index))
-   || (r = build_non_type_tparameter(ctxt, node, index))
-   || (r = build_template_tparameter(ctxt, node, index))
-   || (r = build_type_composition(ctxt, node, index)));
+  ((r = build_type_tparameter(ctxt, node, index, tdecl))
+   || (r = build_non_type_tparameter(ctxt, node, index, tdecl))
+   || (r = build_template_tparameter(ctxt, node, index, tdecl))
+   || (r = build_type_composition(ctxt, node, index, tdecl)));
 
   return r;
 }
index c97a2ab07becb1fe0dd279cb204e30146dfed0d0..76e1cfa028f277f3ca3d89c873f5eb19853f55c1 100644 (file)
@@ -17,9 +17,9 @@
     <namespace-decl name='ns3'>
       <namespace-decl name='ns4'>
         <function-template-decl id='fn-tmpl-id-5'>
-          <template-type-parameter type-id='type-id-3' name='T'/>
+          <template-type-parameter id='type-id-6' name='T'/>
           <function-decl name='bar' binding='global'>
-            <parameter type-id='type-id-3' name='first'/>
+            <parameter type-id='type-id-6' name='first'/>
             <return type-id='type-id-1'/>
           </function-decl>
         </function-template-decl>
index 6ffea59816ed8870a44337185aad10e938458c09..42cad52b88e734e6bb9942522cb79072664dadac 100644 (file)
@@ -19,9 +19,9 @@
     <namespace-decl name='ns3'>
       <namespace-decl name='ns4'>
         <function-template-decl id='fn-tmpl-id-5'>
-          <template-type-parameter type-id='type-id-3' name='T'/>
+          <template-type-parameter id='type-id-6' name='T'/>
           <function-decl name='bar' binding='global'>
-            <parameter type-id='type-id-3' name='first'/>
+            <parameter type-id='type-id-6' name='first'/>
             <return type-id='type-id-1'/>
           </function-decl>
         </function-template-decl>
This page took 0.067789 seconds and 5 git commands to generate.