Consistently use std::unique_ptr for private implementations (pimpl)

Message ID 20210705094529.2485114-1-maennich@google.com
State New
Headers
Series Consistently use std::unique_ptr for private implementations (pimpl) |

Commit Message

Matthias Männich July 5, 2021, 9:45 a.m. UTC
  In the absence of non-refcounting smart pointers before C++11,
std::shared_ptr was commonly used instead. Having bumped the standard to
C++11, allows us to use std::unique_ptr consistently avoiding any costs
involved with shared_ptr ref counting. Hence do that and add default
virtual destructors where required.

	* include/abg-comparison.h (diff_maps): use unique_ptr for priv_
	(diff_context): Likewise.
	(diff_traversable_base): Likewise.
	(type_diff_base): Likewise.
	(decl_diff_base): Likewise.
	(distinct_diff): Likewise.
	(var_diff): Likewise.
	(pointer_diff): Likewise.
	(reference_diff): Likewise.
	(array_diff): Likewise.
	(qualified_type_diff): Likewise.
	(enum_diff): Likewise.
	(class_or_union_diff): Likewise.
	(class_diff): Likewise.
	(base_diff): Likewise.
	(scope_diff): Likewise.
	(fn_parm_diff): Likewise.
	(function_type_diff): Likewise.
	(function_decl_diff): Likewise.
	(typedef_diff): Likewise.
	(translation_unit_diff): Likewise.
	(diff_stats): Likewise.
	(diff_node_visitor): Likewise.
	* include/abg-corpus.h (corpus): Likewise.
	(exported_decls_builder): Likewise.
	(corpus_group): Likewise.
	* include/abg-ini.h (property): Likewise.
	(property_value): Likewise.
	(string_property_value): Likewise.
	(list_property_value): Likewise.
	(tuple_property_value): Likewise.
	(simple_property): Likewise.
	(list_property): Likewise.
	(tuple_property): Likewise.
	(config): Likewise.
	(section): Likewise.
	(function_call_expr): Likewise.
	* include/abg-interned-str.h (interned_string_pool): Likewise.
	* include/abg-ir.h (environment): Likewise.
	(location_manager): Likewise.
	(type_maps): Likewise.
	(translation_unit): Likewise.
	(elf_symbol::version): Likewise.
	(type_or_decl_base): Likewise.
	(scope_decl): Likewise.
	(qualified_type_def): Likewise.
	(pointer_type_def): Likewise.
	(array_type_def): Likewise.
	(subrange_type): Likewise.
	(enum_type_decl): Likewise.
	(enum_type_decl::enumerator): Likewise.
	(typedef_decl): Likewise.
	(dm_context_rel): Likewise.
	(var_decl): Likewise.
	(function_decl::parameter): Likewise.
	(function_type): Likewise.
	(method_type): Likewise.
	(template_decl): Likewise.
	(template_parameter): Likewise.
	(type_tparameter): Likewise.
	(non_type_tparameter): Likewise.
	(template_tparameter): Likewise.
	(type_composition): Likewise.
	(function_tdecl): Likewise.
	(class_tdecl): Likewise.
	(class_decl::base_spec): Likewise.
	(ir_node_visitor): Likewise.
	* include/abg-suppression.h (suppression_base): Likewise.
	(type_suppression::insertion_range): Likewise.
	(type_suppression::insertion_range::boundary): Likewise.
	(type_suppression::insertion_range::integer_boundary): Likewise.
	(type_suppression::insertion_range::fn_call_expr_boundary): Likewise.
	(function_suppression): Likewise.
	(function_suppression::parameter_spec): Likewise.
	(file_suppression): Likewise.
	* include/abg-tools-utils.h (temp_file): Likewise.
	(timer): Likewise.
	* include/abg-traverse.h (traversable_base): Likewise.
	* include/abg-workers.h (queue): Likewise.
	* src/abg-comparison.cc (diff_context): add default destructor.
	(diff_maps): Likewise.
	(corpus_diff): Likewise.
	(diff_node_visitor): Likewise.
	(class_or_union_diff::get_priv): adjust return type.
	(class_diff::get_priv): adjust return type.
	* src/abg-corpus.cc (corpus): add default destructor.
	* src/abg-ir.cc (location_manager): Likewise.
	(type_maps): Likewise.
	(elf_symbol::version): Likewise.
	(array_type_def::subrange_type): Likewise.
	(enum_type_decl::enumerator): Likewise.
	(function_decl::parameter): Likewise.
	(class_decl::base_spec): Likewise.
	(ir_node_visitor): Likewise.

Signed-off-by: Matthias Maennich <maennich@google.com>
---
 include/abg-comparison.h   |  86 +++++++++------------
 include/abg-corpus.h       |  24 ++----
 include/abg-ini.h          |  49 ++++--------
 include/abg-interned-str.h |   5 +-
 include/abg-ir.h           | 153 ++++++++++++++-----------------------
 include/abg-suppression.h  |  52 ++++---------
 include/abg-tools-utils.h  |   8 +-
 include/abg-traverse.h     |   4 +-
 include/abg-workers.h      |   3 +-
 src/abg-comparison.cc      |  14 +++-
 src/abg-corpus.cc          |   2 +
 src/abg-ir.cc              |  19 ++++-
 12 files changed, 164 insertions(+), 255 deletions(-)
  

Comments

Dodji Seketeli July 16, 2021, 9:13 a.m. UTC | #1
Hello,

Matthias Maennich <maennich@google.com> a écrit:

> In the absence of non-refcounting smart pointers before C++11,
> std::shared_ptr was commonly used instead. Having bumped the standard to
> C++11, allows us to use std::unique_ptr consistently avoiding any costs
> involved with shared_ptr ref counting. Hence do that and add default
> virtual destructors where required.

Thanks for doing this!

So, after testing on an old AMD machine, here is the difference in the
time taken (as reported by the 'time' command) by "make check" between
the master branch without the patch, and with the patch.

Without the patch:

    real	3m41,260s
    user	10m44,672s
    sys	1m27,097s

With the patch:

    real	2m7,102s
    user	11m48,024s
    sys	1m18,589s

Pretty neat isn't it? :-)

So thanks a lot for that!

>
> 	* include/abg-comparison.h (diff_maps): use unique_ptr for priv_
> 	(diff_context): Likewise.
> 	(diff_traversable_base): Likewise.
> 	(type_diff_base): Likewise.
> 	(decl_diff_base): Likewise.
> 	(distinct_diff): Likewise.
> 	(var_diff): Likewise.
> 	(pointer_diff): Likewise.
> 	(reference_diff): Likewise.
> 	(array_diff): Likewise.
> 	(qualified_type_diff): Likewise.
> 	(enum_diff): Likewise.
> 	(class_or_union_diff): Likewise.
> 	(class_diff): Likewise.
> 	(base_diff): Likewise.
> 	(scope_diff): Likewise.
> 	(fn_parm_diff): Likewise.
> 	(function_type_diff): Likewise.
> 	(function_decl_diff): Likewise.
> 	(typedef_diff): Likewise.
> 	(translation_unit_diff): Likewise.
> 	(diff_stats): Likewise.
> 	(diff_node_visitor): Likewise.
> 	* include/abg-corpus.h (corpus): Likewise.
> 	(exported_decls_builder): Likewise.
> 	(corpus_group): Likewise.
> 	* include/abg-ini.h (property): Likewise.
> 	(property_value): Likewise.
> 	(string_property_value): Likewise.
> 	(list_property_value): Likewise.
> 	(tuple_property_value): Likewise.
> 	(simple_property): Likewise.
> 	(list_property): Likewise.
> 	(tuple_property): Likewise.
> 	(config): Likewise.
> 	(section): Likewise.
> 	(function_call_expr): Likewise.
> 	* include/abg-interned-str.h (interned_string_pool): Likewise.
> 	* include/abg-ir.h (environment): Likewise.
> 	(location_manager): Likewise.
> 	(type_maps): Likewise.
> 	(translation_unit): Likewise.
> 	(elf_symbol::version): Likewise.
> 	(type_or_decl_base): Likewise.
> 	(scope_decl): Likewise.
> 	(qualified_type_def): Likewise.
> 	(pointer_type_def): Likewise.
> 	(array_type_def): Likewise.
> 	(subrange_type): Likewise.
> 	(enum_type_decl): Likewise.
> 	(enum_type_decl::enumerator): Likewise.
> 	(typedef_decl): Likewise.
> 	(dm_context_rel): Likewise.
> 	(var_decl): Likewise.
> 	(function_decl::parameter): Likewise.
> 	(function_type): Likewise.
> 	(method_type): Likewise.
> 	(template_decl): Likewise.
> 	(template_parameter): Likewise.
> 	(type_tparameter): Likewise.
> 	(non_type_tparameter): Likewise.
> 	(template_tparameter): Likewise.
> 	(type_composition): Likewise.
> 	(function_tdecl): Likewise.
> 	(class_tdecl): Likewise.
> 	(class_decl::base_spec): Likewise.
> 	(ir_node_visitor): Likewise.
> 	* include/abg-suppression.h (suppression_base): Likewise.
> 	(type_suppression::insertion_range): Likewise.
> 	(type_suppression::insertion_range::boundary): Likewise.
> 	(type_suppression::insertion_range::integer_boundary): Likewise.
> 	(type_suppression::insertion_range::fn_call_expr_boundary): Likewise.
> 	(function_suppression): Likewise.
> 	(function_suppression::parameter_spec): Likewise.
> 	(file_suppression): Likewise.
> 	* include/abg-tools-utils.h (temp_file): Likewise.
> 	(timer): Likewise.
> 	* include/abg-traverse.h (traversable_base): Likewise.
> 	* include/abg-workers.h (queue): Likewise.
> 	* src/abg-comparison.cc (diff_context): add default destructor.
> 	(diff_maps): Likewise.
> 	(corpus_diff): Likewise.
> 	(diff_node_visitor): Likewise.
> 	(class_or_union_diff::get_priv): adjust return type.
> 	(class_diff::get_priv): adjust return type.
> 	* src/abg-corpus.cc (corpus): add default destructor.
> 	* src/abg-ir.cc (location_manager): Likewise.
> 	(type_maps): Likewise.
> 	(elf_symbol::version): Likewise.
> 	(array_type_def::subrange_type): Likewise.
> 	(enum_type_decl::enumerator): Likewise.
> 	(function_decl::parameter): Likewise.
> 	(class_decl::base_spec): Likewise.
> 	(ir_node_visitor): Likewise.
>
> Signed-off-by: Matthias Maennich <maennich@google.com>

Applied to master.  Thanks!

[...]

Cheers,
  
Matthias Männich July 16, 2021, 9:48 a.m. UTC | #2
On Fri, Jul 16, 2021 at 10:13 AM Dodji Seketeli <dodji@seketeli.org> wrote:
>
> Hello,
>
> Matthias Maennich <maennich@google.com> a écrit:
>
> > In the absence of non-refcounting smart pointers before C++11,
> > std::shared_ptr was commonly used instead. Having bumped the standard to
> > C++11, allows us to use std::unique_ptr consistently avoiding any costs
> > involved with shared_ptr ref counting. Hence do that and add default
> > virtual destructors where required.
>
> Thanks for doing this!
>
> So, after testing on an old AMD machine, here is the difference in the
> time taken (as reported by the 'time' command) by "make check" between
> the master branch without the patch, and with the patch.
>
> Without the patch:
>
>     real        3m41,260s
>     user        10m44,672s
>     sys 1m27,097s
>
> With the patch:
>
>     real        2m7,102s
>     user        11m48,024s
>     sys 1m18,589s
>
> Pretty neat isn't it? :-)

Oh wow! That is indeed neat! Guiliano was benchmarking the change and
came to an improvement there as well. The effect was not as strong,
though:

abidw: 1:43 or 1:47
abidiff: 1:31

after:

abidw: 1:42 or 1:45
abidiff: 1:30

Cheers,
Matthias

>
> So thanks a lot for that!
>
> >
> >       * include/abg-comparison.h (diff_maps): use unique_ptr for priv_
> >       (diff_context): Likewise.
> >       (diff_traversable_base): Likewise.
> >       (type_diff_base): Likewise.
> >       (decl_diff_base): Likewise.
> >       (distinct_diff): Likewise.
> >       (var_diff): Likewise.
> >       (pointer_diff): Likewise.
> >       (reference_diff): Likewise.
> >       (array_diff): Likewise.
> >       (qualified_type_diff): Likewise.
> >       (enum_diff): Likewise.
> >       (class_or_union_diff): Likewise.
> >       (class_diff): Likewise.
> >       (base_diff): Likewise.
> >       (scope_diff): Likewise.
> >       (fn_parm_diff): Likewise.
> >       (function_type_diff): Likewise.
> >       (function_decl_diff): Likewise.
> >       (typedef_diff): Likewise.
> >       (translation_unit_diff): Likewise.
> >       (diff_stats): Likewise.
> >       (diff_node_visitor): Likewise.
> >       * include/abg-corpus.h (corpus): Likewise.
> >       (exported_decls_builder): Likewise.
> >       (corpus_group): Likewise.
> >       * include/abg-ini.h (property): Likewise.
> >       (property_value): Likewise.
> >       (string_property_value): Likewise.
> >       (list_property_value): Likewise.
> >       (tuple_property_value): Likewise.
> >       (simple_property): Likewise.
> >       (list_property): Likewise.
> >       (tuple_property): Likewise.
> >       (config): Likewise.
> >       (section): Likewise.
> >       (function_call_expr): Likewise.
> >       * include/abg-interned-str.h (interned_string_pool): Likewise.
> >       * include/abg-ir.h (environment): Likewise.
> >       (location_manager): Likewise.
> >       (type_maps): Likewise.
> >       (translation_unit): Likewise.
> >       (elf_symbol::version): Likewise.
> >       (type_or_decl_base): Likewise.
> >       (scope_decl): Likewise.
> >       (qualified_type_def): Likewise.
> >       (pointer_type_def): Likewise.
> >       (array_type_def): Likewise.
> >       (subrange_type): Likewise.
> >       (enum_type_decl): Likewise.
> >       (enum_type_decl::enumerator): Likewise.
> >       (typedef_decl): Likewise.
> >       (dm_context_rel): Likewise.
> >       (var_decl): Likewise.
> >       (function_decl::parameter): Likewise.
> >       (function_type): Likewise.
> >       (method_type): Likewise.
> >       (template_decl): Likewise.
> >       (template_parameter): Likewise.
> >       (type_tparameter): Likewise.
> >       (non_type_tparameter): Likewise.
> >       (template_tparameter): Likewise.
> >       (type_composition): Likewise.
> >       (function_tdecl): Likewise.
> >       (class_tdecl): Likewise.
> >       (class_decl::base_spec): Likewise.
> >       (ir_node_visitor): Likewise.
> >       * include/abg-suppression.h (suppression_base): Likewise.
> >       (type_suppression::insertion_range): Likewise.
> >       (type_suppression::insertion_range::boundary): Likewise.
> >       (type_suppression::insertion_range::integer_boundary): Likewise.
> >       (type_suppression::insertion_range::fn_call_expr_boundary): Likewise.
> >       (function_suppression): Likewise.
> >       (function_suppression::parameter_spec): Likewise.
> >       (file_suppression): Likewise.
> >       * include/abg-tools-utils.h (temp_file): Likewise.
> >       (timer): Likewise.
> >       * include/abg-traverse.h (traversable_base): Likewise.
> >       * include/abg-workers.h (queue): Likewise.
> >       * src/abg-comparison.cc (diff_context): add default destructor.
> >       (diff_maps): Likewise.
> >       (corpus_diff): Likewise.
> >       (diff_node_visitor): Likewise.
> >       (class_or_union_diff::get_priv): adjust return type.
> >       (class_diff::get_priv): adjust return type.
> >       * src/abg-corpus.cc (corpus): add default destructor.
> >       * src/abg-ir.cc (location_manager): Likewise.
> >       (type_maps): Likewise.
> >       (elf_symbol::version): Likewise.
> >       (array_type_def::subrange_type): Likewise.
> >       (enum_type_decl::enumerator): Likewise.
> >       (function_decl::parameter): Likewise.
> >       (class_decl::base_spec): Likewise.
> >       (ir_node_visitor): Likewise.
> >
> > Signed-off-by: Matthias Maennich <maennich@google.com>
>
> Applied to master.  Thanks!
>
> [...]
>
> Cheers,
>
> --
>                 Dodji
  
Giuliano Procida July 16, 2021, 9:56 a.m. UTC | #3
I was benchmarking the kernel ABI use case. So it looks like perhaps the
more complex C++ ABIs really benefit from this change.

Matthias, I'm glad we found the performance improvement after all!


On Fri, 16 Jul 2021, 10:49 Matthias Männich, <maennich@google.com> wrote:

> On Fri, Jul 16, 2021 at 10:13 AM Dodji Seketeli <dodji@seketeli.org>
> wrote:
> >
> > Hello,
> >
> > Matthias Maennich <maennich@google.com> a écrit:
> >
> > > In the absence of non-refcounting smart pointers before C++11,
> > > std::shared_ptr was commonly used instead. Having bumped the standard
> to
> > > C++11, allows us to use std::unique_ptr consistently avoiding any costs
> > > involved with shared_ptr ref counting. Hence do that and add default
> > > virtual destructors where required.
> >
> > Thanks for doing this!
> >
> > So, after testing on an old AMD machine, here is the difference in the
> > time taken (as reported by the 'time' command) by "make check" between
> > the master branch without the patch, and with the patch.
> >
> > Without the patch:
> >
> >     real        3m41,260s
> >     user        10m44,672s
> >     sys 1m27,097s
> >
> > With the patch:
> >
> >     real        2m7,102s
> >     user        11m48,024s
> >     sys 1m18,589s
> >
> > Pretty neat isn't it? :-)
>
> Oh wow! That is indeed neat! Guiliano was benchmarking the change and
> came to an improvement there as well. The effect was not as strong,
> though:
>
> abidw: 1:43 or 1:47
> abidiff: 1:31
>
> after:
>
> abidw: 1:42 or 1:45
> abidiff: 1:30
>
> Cheers,
> Matthias
>
> >
> > So thanks a lot for that!
> >
> > >
> > >       * include/abg-comparison.h (diff_maps): use unique_ptr for priv_
> > >       (diff_context): Likewise.
> > >       (diff_traversable_base): Likewise.
> > >       (type_diff_base): Likewise.
> > >       (decl_diff_base): Likewise.
> > >       (distinct_diff): Likewise.
> > >       (var_diff): Likewise.
> > >       (pointer_diff): Likewise.
> > >       (reference_diff): Likewise.
> > >       (array_diff): Likewise.
> > >       (qualified_type_diff): Likewise.
> > >       (enum_diff): Likewise.
> > >       (class_or_union_diff): Likewise.
> > >       (class_diff): Likewise.
> > >       (base_diff): Likewise.
> > >       (scope_diff): Likewise.
> > >       (fn_parm_diff): Likewise.
> > >       (function_type_diff): Likewise.
> > >       (function_decl_diff): Likewise.
> > >       (typedef_diff): Likewise.
> > >       (translation_unit_diff): Likewise.
> > >       (diff_stats): Likewise.
> > >       (diff_node_visitor): Likewise.
> > >       * include/abg-corpus.h (corpus): Likewise.
> > >       (exported_decls_builder): Likewise.
> > >       (corpus_group): Likewise.
> > >       * include/abg-ini.h (property): Likewise.
> > >       (property_value): Likewise.
> > >       (string_property_value): Likewise.
> > >       (list_property_value): Likewise.
> > >       (tuple_property_value): Likewise.
> > >       (simple_property): Likewise.
> > >       (list_property): Likewise.
> > >       (tuple_property): Likewise.
> > >       (config): Likewise.
> > >       (section): Likewise.
> > >       (function_call_expr): Likewise.
> > >       * include/abg-interned-str.h (interned_string_pool): Likewise.
> > >       * include/abg-ir.h (environment): Likewise.
> > >       (location_manager): Likewise.
> > >       (type_maps): Likewise.
> > >       (translation_unit): Likewise.
> > >       (elf_symbol::version): Likewise.
> > >       (type_or_decl_base): Likewise.
> > >       (scope_decl): Likewise.
> > >       (qualified_type_def): Likewise.
> > >       (pointer_type_def): Likewise.
> > >       (array_type_def): Likewise.
> > >       (subrange_type): Likewise.
> > >       (enum_type_decl): Likewise.
> > >       (enum_type_decl::enumerator): Likewise.
> > >       (typedef_decl): Likewise.
> > >       (dm_context_rel): Likewise.
> > >       (var_decl): Likewise.
> > >       (function_decl::parameter): Likewise.
> > >       (function_type): Likewise.
> > >       (method_type): Likewise.
> > >       (template_decl): Likewise.
> > >       (template_parameter): Likewise.
> > >       (type_tparameter): Likewise.
> > >       (non_type_tparameter): Likewise.
> > >       (template_tparameter): Likewise.
> > >       (type_composition): Likewise.
> > >       (function_tdecl): Likewise.
> > >       (class_tdecl): Likewise.
> > >       (class_decl::base_spec): Likewise.
> > >       (ir_node_visitor): Likewise.
> > >       * include/abg-suppression.h (suppression_base): Likewise.
> > >       (type_suppression::insertion_range): Likewise.
> > >       (type_suppression::insertion_range::boundary): Likewise.
> > >       (type_suppression::insertion_range::integer_boundary): Likewise.
> > >       (type_suppression::insertion_range::fn_call_expr_boundary):
> Likewise.
> > >       (function_suppression): Likewise.
> > >       (function_suppression::parameter_spec): Likewise.
> > >       (file_suppression): Likewise.
> > >       * include/abg-tools-utils.h (temp_file): Likewise.
> > >       (timer): Likewise.
> > >       * include/abg-traverse.h (traversable_base): Likewise.
> > >       * include/abg-workers.h (queue): Likewise.
> > >       * src/abg-comparison.cc (diff_context): add default destructor.
> > >       (diff_maps): Likewise.
> > >       (corpus_diff): Likewise.
> > >       (diff_node_visitor): Likewise.
> > >       (class_or_union_diff::get_priv): adjust return type.
> > >       (class_diff::get_priv): adjust return type.
> > >       * src/abg-corpus.cc (corpus): add default destructor.
> > >       * src/abg-ir.cc (location_manager): Likewise.
> > >       (type_maps): Likewise.
> > >       (elf_symbol::version): Likewise.
> > >       (array_type_def::subrange_type): Likewise.
> > >       (enum_type_decl::enumerator): Likewise.
> > >       (function_decl::parameter): Likewise.
> > >       (class_decl::base_spec): Likewise.
> > >       (ir_node_visitor): Likewise.
> > >
> > > Signed-off-by: Matthias Maennich <maennich@google.com>
> >
> > Applied to master.  Thanks!
> >
> > [...]
> >
> > Cheers,
> >
> > --
> >                 Dodji
>
  

Patch

diff --git a/include/abg-comparison.h b/include/abg-comparison.h
index fc5efe74a403..1350608a3f95 100644
--- a/include/abg-comparison.h
+++ b/include/abg-comparison.h
@@ -10,6 +10,7 @@ 
 
 /// @file
 
+#include <memory>
 #include <ostream>
 #include <unordered_map>
 #include <unordered_set>
@@ -502,13 +503,14 @@  class corpus_diff;
 class diff_maps
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
 
   diff_maps();
 
+  ~diff_maps();
+
   const string_diff_ptr_map&
   get_type_decl_diff_map() const;
 
@@ -598,7 +600,7 @@  typedef shared_ptr<corpus_diff> corpus_diff_sptr;
 class diff_context
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
   diff_sptr
   has_diff_for(const type_or_decl_base_sptr first,
@@ -638,6 +640,8 @@  class diff_context
 public:
   diff_context();
 
+  ~diff_context();
+
   void
   set_corpus_diff(const corpus_diff_sptr&);
 
@@ -895,14 +899,12 @@  class diff : public diff_traversable_base
 {
   friend class diff_context;
 
-  struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
   // Forbidden
   diff();
 
 protected:
-  priv_sptr priv_;
+  struct priv;
+  std::unique_ptr<priv> priv_;
 
   diff(type_or_decl_base_sptr first_subject,
        type_or_decl_base_sptr second_subject);
@@ -1063,9 +1065,7 @@  compute_diff(const type_base_sptr,
 class type_diff_base : public diff
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   type_diff_base();
 
@@ -1086,9 +1086,7 @@  public:
 class decl_diff_base : public diff
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   decl_diff_base(decl_base_sptr	first_subject,
@@ -1116,8 +1114,7 @@  typedef shared_ptr<distinct_diff> distinct_diff_sptr;
 class distinct_diff : public diff
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   distinct_diff(type_or_decl_base_sptr first,
@@ -1172,8 +1169,7 @@  compute_diff_for_distinct_kinds(const type_or_decl_base_sptr,
 class var_diff : public decl_diff_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   var_diff(var_decl_sptr first,
@@ -1227,7 +1223,7 @@  typedef shared_ptr<pointer_diff> pointer_diff_sptr;
 class pointer_diff : public type_diff_base
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   pointer_diff(pointer_type_def_sptr	first,
@@ -1287,7 +1283,7 @@  typedef shared_ptr<reference_diff> reference_diff_sptr;
 class reference_diff : public type_diff_base
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   reference_diff(const reference_type_def_sptr	first,
@@ -1347,7 +1343,7 @@  typedef shared_ptr<array_diff> array_diff_sptr;
 class array_diff : public type_diff_base
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   array_diff(const array_type_def_sptr	first,
@@ -1404,8 +1400,7 @@  typedef class shared_ptr<qualified_type_diff> qualified_type_diff_sptr;
 class qualified_type_diff : public type_diff_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   qualified_type_diff(qualified_type_def_sptr	first,
@@ -1465,8 +1460,7 @@  typedef shared_ptr<enum_diff> enum_diff_sptr;
 class enum_diff : public type_diff_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   void
   clear_lookup_tables();
@@ -1536,8 +1530,8 @@  class class_or_union_diff : public type_diff_base
 {
 protected:
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  typedef std::unique_ptr<priv> priv_ptr;
+  priv_ptr priv_;
 
   void
   clear_lookup_tables(void);
@@ -1561,7 +1555,7 @@  protected:
 
 public:
 
-  const class_or_union_diff::priv_sptr&
+  const class_or_union_diff::priv_ptr&
   get_priv() const;
 
   //TODO: add change of the name of the type.
@@ -1656,10 +1650,10 @@  public:
 class class_diff : public class_or_union_diff
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  typedef std::unique_ptr<priv> priv_ptr;
+  priv_ptr priv_;
 
-  const priv_sptr& get_priv()const;
+  const priv_ptr& get_priv()const;
 
   void
   clear_lookup_tables(void);
@@ -1791,7 +1785,7 @@  compute_diff(const union_decl_sptr	first,
 class base_diff : public diff
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   base_diff(class_decl::base_spec_sptr	first,
@@ -1850,7 +1844,7 @@  typedef shared_ptr<scope_diff> scope_diff_sptr;
 class scope_diff : public diff
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
   bool
   lookup_tables_empty() const;
@@ -1958,9 +1952,7 @@  compute_diff(const scope_decl_sptr first_scope,
 class fn_parm_diff : public decl_diff_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   virtual void
   finish_diff_type();
@@ -2015,8 +2007,7 @@  typedef shared_ptr<function_type_diff> function_type_diff_sptr;
 class function_type_diff: public type_diff_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   void
   ensure_lookup_tables_populated();
@@ -2093,7 +2084,7 @@  compute_diff(const function_type_sptr	first,
 class function_decl_diff : public decl_diff_base
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
   void
   ensure_lookup_tables_populated();
@@ -2201,7 +2192,7 @@  typedef shared_ptr<typedef_diff> typedef_diff_sptr;
 class typedef_diff : public type_diff_base
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
   typedef_diff();
 
@@ -2266,8 +2257,7 @@  typedef shared_ptr<translation_unit_diff> translation_unit_diff_sptr;
 class translation_unit_diff : public scope_diff
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   translation_unit_diff(translation_unit_sptr	first,
@@ -2306,8 +2296,7 @@  compute_diff(const translation_unit_sptr first,
 class corpus_diff
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
   corpus_diff(corpus_sptr	first,
@@ -2321,7 +2310,7 @@  public:
 
   class diff_stats;
 
-  virtual ~corpus_diff() {}
+  virtual ~corpus_diff();
 
   /// A convenience typedef for a shared pointer to @ref diff_stats
   typedef shared_ptr<diff_stats> diff_stats_sptr;
@@ -2479,9 +2468,7 @@  compute_diff(const corpus_group_sptr&,
 class corpus_diff::diff_stats
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   diff_stats();
 
@@ -2628,14 +2615,13 @@  class diff_node_visitor : public node_visitor_base
 {
 protected:
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
 
   diff_node_visitor();
 
-  virtual ~diff_node_visitor() {}
+  virtual ~diff_node_visitor();
 
   diff_node_visitor(visiting_kind k);
 
diff --git a/include/abg-corpus.h b/include/abg-corpus.h
index 287f7707c339..136c348c6d41 100644
--- a/include/abg-corpus.h
+++ b/include/abg-corpus.h
@@ -24,10 +24,6 @@  namespace ir
 class corpus
 {
 public:
-  struct priv;
-  /// Convenience typedef for shared_ptr of corpus::priv
-  typedef shared_ptr<priv> priv_sptr;
-
   /// A convenience typedef for std::vector<string>.
   typedef vector<string> strings_type;
 
@@ -60,11 +56,12 @@  private:
   void init_format_version();
 
 public:
-  shared_ptr<priv> priv_;
+  struct priv;
+  std::unique_ptr<priv> priv_;
 
   corpus(ir::environment*, const string& path= "");
 
-  virtual ~corpus() {}
+  virtual ~corpus();
 
   const environment*
   get_environment() const;
@@ -290,21 +287,14 @@  public:
 /// parameters needed.
 class corpus::exported_decls_builder
 {
-public:
   class priv;
-
-  /// Convenience typedef for shared_ptr<priv>
-  typedef shared_ptr<priv> priv_sptr;
-
-  friend class corpus;
-
-private:
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbid default construction.
   exported_decls_builder();
 
 public:
+  friend class corpus;
 
   exported_decls_builder(functions& fns,
 			 variables& vars,
@@ -344,9 +334,7 @@  public:
 class corpus_group : public corpus
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbid copy
   corpus_group(const corpus_group&);
diff --git a/include/abg-ini.h b/include/abg-ini.h
index 4ccb63bc4550..ef46fbc252a9 100644
--- a/include/abg-ini.h
+++ b/include/abg-ini.h
@@ -40,8 +40,7 @@  typedef shared_ptr<property> property_sptr;
 class property
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
 
@@ -66,6 +65,9 @@  typedef shared_ptr<property_value> property_value_sptr;
 /// Base class of propertie values.
 class property_value
 {
+  struct priv;
+  std::unique_ptr<priv> priv_;
+
 public:
   enum value_kind
   {
@@ -75,13 +77,6 @@  public:
     TUPLE_PROPERTY_VALUE = 3,
   };
 
-private:
-  struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
-
-public:
-
   property_value();
   property_value(value_kind);
 
@@ -105,8 +100,7 @@  typedef shared_ptr<string_property_value> string_property_value_sptr;
 class string_property_value : public property_value
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   string_property_value();
@@ -147,9 +141,7 @@  typedef shared_ptr<list_property_value> list_property_value_sptr;
 class list_property_value : public property_value
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   list_property_value();
@@ -184,8 +176,7 @@  typedef shared_ptr<tuple_property_value> tuple_property_value_sptr;
 class tuple_property_value : public property_value
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   tuple_property_value(const vector<property_value_sptr>&);
@@ -219,9 +210,7 @@  typedef shared_ptr<simple_property> simple_property_sptr;
 class simple_property : public property
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   simple_property();
@@ -265,9 +254,7 @@  typedef shared_ptr<list_property> list_property_sptr;
 class list_property : public property
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   list_property();
@@ -299,9 +286,7 @@  typedef shared_ptr<tuple_property> tuple_property_sptr;
 class tuple_property : public property
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   tuple_property();
@@ -336,7 +321,7 @@  typedef shared_ptr<config> config_sptr;
 class config
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
+  std::unique_ptr<priv> priv_;
 
 public:
   class section;
@@ -349,11 +334,6 @@  public:
   /// A convenience typedef for a vector of @ref property_sptr
   typedef vector<property_sptr> properties_type;
 
-private:
-  priv_sptr priv_;
-
-public:
-
   config();
 
   config(const string& path,
@@ -378,9 +358,7 @@  public:
 class config::section
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbid this
   section();
@@ -455,8 +433,7 @@  typedef shared_ptr<function_call_expr> function_call_expr_sptr;
 class function_call_expr
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   function_call_expr();
 
diff --git a/include/abg-interned-str.h b/include/abg-interned-str.h
index e25ea566d656..acd7bdf8691a 100644
--- a/include/abg-interned-str.h
+++ b/include/abg-interned-str.h
@@ -27,7 +27,6 @@  namespace abigail
 {
 // Inject some std types into this namespace.
 using std::unordered_set;
-using std::shared_ptr;
 using std::string;
 using std::ostream;
 
@@ -227,9 +226,7 @@  struct hash_interned_string
 class interned_string_pool
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
 
diff --git a/include/abg-ir.h b/include/abg-ir.h
index da43727f9026..db28a526e4fd 100644
--- a/include/abg-ir.h
+++ b/include/abg-ir.h
@@ -133,6 +133,9 @@  typedef vector<type_base_sptr> type_base_sptrs_type;
 /// that you can de-allocate the environment instance.
 class environment
 {
+  struct priv;
+  std::unique_ptr<priv> priv_;
+
 public:
 
   /// A convenience typedef for a map of canonical types.  The key is
@@ -141,15 +144,8 @@  public:
   /// representation string.
   typedef std::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&
@@ -401,14 +397,14 @@  public:
 class location_manager
 {
   struct priv;
-
-  /// Pimpl.
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
 
   location_manager();
 
+  ~location_manager();
+
   location
   create_new_location(const std::string& fle, size_t lne, size_t col);
 
@@ -541,13 +537,14 @@  istring_type_or_decl_base_sptr_map_type;
 class type_maps
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
 
   type_maps();
 
+  ~type_maps();
+
   bool
   empty() const;
 
@@ -627,12 +624,10 @@  public:
 class translation_unit : public traversable_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden
-  translation_unit();
+  translation_unit() = delete;
 
 public:
   /// Convenience typedef for a shared pointer on a @ref global_scope.
@@ -908,7 +903,7 @@  public:
 
 private:
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
   elf_symbol();
 
@@ -1140,7 +1135,7 @@  compute_aliases_for_elf_symbol(const elf_symbol& symbol,
 class elf_symbol::version
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   version();
@@ -1150,6 +1145,8 @@  public:
 
   version(const version& v);
 
+  ~version();
+
   operator const string&() const;
 
   const string&
@@ -1312,8 +1309,7 @@  equals(const decl_base&, const decl_base&, change_kind*);
 class type_or_decl_base : public ir_traversable_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  mutable priv_sptr priv_;
+  mutable std::unique_ptr<priv> priv_;
 
   type_or_decl_base();
 
@@ -1767,6 +1763,9 @@  equals(const scope_decl&, const scope_decl&, change_kind*);
 /// A declaration that introduces a scope.
 class scope_decl : public virtual decl_base
 {
+  struct priv;
+  std::unique_ptr<priv> priv_;
+
 public:
 
   /// Convenience typedef for a vector of @ref decl_base_sptr.
@@ -1775,13 +1774,6 @@  public:
   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();
 
@@ -2153,8 +2145,7 @@  equals(const qualified_type_def&, const qualified_type_def&, change_kind*);
 class qualified_type_def : public virtual type_base, public virtual decl_base
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden.
   qualified_type_def();
@@ -2262,9 +2253,7 @@  equals(const pointer_type_def&, const pointer_type_def&, change_kind*);
 class pointer_type_def : public virtual type_base, public virtual decl_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden.
   pointer_type_def();
@@ -2391,10 +2380,8 @@  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_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden.
   array_type_def();
@@ -2420,13 +2407,13 @@  public:
   class subrange_type : public virtual type_base,  public virtual decl_base
   {
     struct priv;
-    typedef shared_ptr<priv> priv_sptr;
-    priv_sptr priv_;
+    std::unique_ptr<priv> priv_;
 
     // Forbidden.
     subrange_type();
   public:
 
+    virtual ~subrange_type();
     /// 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
@@ -2613,6 +2600,12 @@  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
 {
+  class priv;
+  std::unique_ptr<priv> priv_;
+
+  // Forbidden
+  enum_type_decl();
+
 public:
 
   /// A hasher for an enum_type_decl.
@@ -2624,18 +2617,6 @@  public:
   /// 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
@@ -2702,14 +2683,14 @@  enum_has_non_name_change(const enum_type_decl& l,
 class enum_type_decl::enumerator
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
-
+  std::unique_ptr<priv> priv_;
 
 public:
 
   enumerator();
 
+  ~enumerator();
+
   enumerator(const environment* env, const string& name, int64_t value);
 
   enumerator(const enumerator&);
@@ -2755,9 +2736,7 @@  equals(const typedef_decl&, const typedef_decl&, change_kind*);
 class typedef_decl : public virtual type_base, public virtual decl_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden
   typedef_decl();
@@ -2816,9 +2795,7 @@  class dm_context_rel : public context_rel
 {
 protected:
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   dm_context_rel();
@@ -2868,7 +2845,7 @@  equals_modulo_cv_qualifier(const array_type_def*, const array_type_def*);
 class var_decl : public virtual decl_base
 {
   struct priv;
-  shared_ptr<priv> priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden
   var_decl();
@@ -3140,9 +3117,7 @@  struct type_or_decl_base_comp
 class function_decl::parameter : public decl_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
 
@@ -3172,6 +3147,8 @@  public:
 	    unsigned			index = 0,
 	    bool			variadic_marker = false);
 
+  virtual ~parameter();
+
   const type_base_sptr
   get_type()const;
 
@@ -3243,9 +3220,6 @@  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;
-
 protected:
   virtual void on_canonical_type_set();
 
@@ -3259,7 +3233,8 @@  public:
   /// Convenience typedef for a vector of @ref parameter_sptr
   typedef std::vector<parameter_sptr>		parameters;
 
-  priv_sptr priv_;
+  struct priv;
+  std::unique_ptr<priv> priv_;
 
 private:
   function_type();
@@ -3342,8 +3317,7 @@  struct function_type::hash
 class method_type : public function_type
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   method_type();
 
@@ -3399,8 +3373,7 @@  public:
 class template_decl : public virtual decl_base
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   template_decl();
 
@@ -3432,8 +3405,7 @@  public:
 class template_parameter
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden
   template_parameter();
@@ -3479,9 +3451,7 @@  struct template_decl::hash
 class type_tparameter : public template_parameter, public virtual type_decl
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden
   type_tparameter();
@@ -3512,9 +3482,7 @@  public:
 class non_type_tparameter : public template_parameter, public virtual decl_base
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   type_base_wptr type_;
 
@@ -3561,8 +3529,7 @@  class template_tparameter;
 class template_tparameter : public type_tparameter, public template_decl
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden
   template_tparameter();
@@ -3597,9 +3564,7 @@  public:
 class type_composition : public template_parameter, public virtual decl_base
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   type_composition();
 
@@ -3637,9 +3602,7 @@  struct type_composition::hash
 class function_tdecl : public template_decl, public scope_decl
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden
   function_tdecl();
@@ -3688,9 +3651,7 @@  public:
 class class_tdecl : public template_decl, public scope_decl
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden
   class_tdecl();
@@ -4308,9 +4269,7 @@  class class_decl::base_spec : public member_base,
 			      public virtual decl_base
 {
   struct priv;
-  typedef shared_ptr<priv>priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbidden
   base_spec();
@@ -4326,6 +4285,8 @@  public:
   base_spec(const type_base_sptr& base, access_specifier a,
 	    long offset_in_bits = -1, bool is_virtual = false);
 
+  virtual ~base_spec();
+
   class_decl_sptr
   get_base_class() const;
 
@@ -4825,14 +4786,14 @@  struct class_tdecl::shared_ptr_hash
 class ir_node_visitor : public node_visitor_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
 
   ir_node_visitor();
 
+  virtual ~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 *);
diff --git a/include/abg-suppression.h b/include/abg-suppression.h
index de2c60193887..db0334e71d54 100644
--- a/include/abg-suppression.h
+++ b/include/abg-suppression.h
@@ -38,14 +38,14 @@  using std::unordered_set;
 /// it matches the supppression specification.
 class suppression_base
 {
-  class priv;
-  typedef shared_ptr<priv> priv_sptr;
-
+public:
+  class priv; // declare publicly to allow subclasses to reuse the priv
+private:
   // Forbid default constructor
   suppression_base();
 
 public:
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   suppression_base(const string& label);
 
@@ -139,14 +139,12 @@  typedef vector<type_suppression_sptr> type_suppressions_type;
 class type_suppression : public suppression_base
 {
   class priv;
-  typedef shared_ptr<priv> priv_sptr;
 
   // Forbid this;
   type_suppression();
 
 public:
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   /// The kind of the type the current type suppression is supposed to
   /// be about.
@@ -289,6 +287,9 @@  is_type_suppression(const suppression_sptr);
 /// might get inserted.
 class type_suppression::insertion_range
 {
+  struct priv;
+  std::unique_ptr<priv> priv_;
+
 public:
 
   class boundary;
@@ -305,13 +306,6 @@  public:
   /// fn_call_expr_boundary
   typedef shared_ptr<fn_call_expr_boundary> fn_call_expr_boundary_sptr;
 
-private:
-  struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
-
-public:
   insertion_range();
 
   insertion_range(boundary_sptr begin, boundary_sptr end);
@@ -348,9 +342,7 @@  is_fn_call_expr_boundary(type_suppression::insertion_range::boundary_sptr);
 class type_suppression::insertion_range::boundary
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   boundary();
@@ -363,9 +355,7 @@  class type_suppression::insertion_range::integer_boundary
   : public type_suppression::insertion_range::boundary
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   integer_boundary();
 
@@ -383,9 +373,7 @@  class type_suppression::insertion_range::fn_call_expr_boundary
   : public type_suppression::insertion_range::boundary
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   fn_call_expr_boundary();
 
@@ -412,11 +400,10 @@  typedef vector<function_suppression_sptr> function_suppressions_type;
 class function_suppression : public suppression_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
 
 public:
 
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
   class parameter_spec;
 
   /// Convenience typedef for shared_ptr of @ref parameter_spec.
@@ -582,12 +569,10 @@  operator|(function_suppression::change_kind l,
 /// function suppression specification.
 class function_suppression::parameter_spec
 {
-  class priv;
-  typedef shared_ptr<priv> priv_sptr;
-
   friend class function_suppression;
 
-  priv_sptr priv_;
+  class priv;
+  std::unique_ptr<priv> priv_;
 
   // Forbid this.
   parameter_spec();
@@ -657,11 +642,9 @@  public:
 
 private:
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
 
 public:
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   variable_suppression(const string& label = "",
 		       const string& name = "",
@@ -791,10 +774,7 @@  typedef shared_ptr<file_suppression> file_suppression_sptr;
 /// which file it has to avoid loading.
 class file_suppression: public suppression_base
 {
-  class priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   // Forbid this
   file_suppression();
diff --git a/include/abg-tools-utils.h b/include/abg-tools-utils.h
index 66b288ca6722..ba09f30f1d7b 100644
--- a/include/abg-tools-utils.h
+++ b/include/abg-tools-utils.h
@@ -135,9 +135,7 @@  typedef shared_ptr<temp_file> temp_file_sptr;
 class temp_file
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
   temp_file();
 
@@ -249,9 +247,7 @@  abidiff_status_has_incompatible_abi_change(abidiff_status s);
 class timer
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 public:
   enum kind
diff --git a/include/abg-traverse.h b/include/abg-traverse.h
index fce72b290108..b15aece5f361 100644
--- a/include/abg-traverse.h
+++ b/include/abg-traverse.h
@@ -38,9 +38,7 @@  struct node_visitor_base
 class traversable_base
 {
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
-
-  priv_sptr priv_;
+  std::unique_ptr<priv> priv_;
 
 protected:
 
diff --git a/include/abg-workers.h b/include/abg-workers.h
index 5b5524471e1c..678c06a36ffd 100644
--- a/include/abg-workers.h
+++ b/include/abg-workers.h
@@ -68,13 +68,12 @@  class queue
 {
 public:
   struct priv;
-  typedef shared_ptr<priv> priv_sptr;
 
   /// A convenience typedef for a vector of @ref task_sptr
   typedef std::vector<task_sptr> tasks_type;
 
 private:
-  priv_sptr p_;
+  std::unique_ptr<priv> p_;
 
 public:
   struct task_done_notify;
diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc
index 7bbc389488be..878a6de44ac3 100644
--- a/src/abg-comparison.cc
+++ b/src/abg-comparison.cc
@@ -914,6 +914,8 @@  diff_context::diff_context()
   // add_diff_filter(f);
 }
 
+diff_context::~diff_context() = default;
+
 /// Set the corpus diff relevant to this context.
 ///
 /// @param d the corpus_diff we are interested in.
@@ -4954,7 +4956,7 @@  class_or_union_diff::finish_diff_type()
 ///
 /// @return the (possibly) shared private data of the current instance
 /// of @ref class_or_union_diff.
-const class_or_union_diff::priv_sptr&
+const class_or_union_diff::priv_ptr&
 class_or_union_diff::get_priv() const
 {
   if (priv_)
@@ -5310,7 +5312,7 @@  class_diff::ensure_lookup_tables_populated(void) const
 				 get_priv()->sorted_changed_bases_);
 
   {
-    const class_or_union_diff::priv_sptr &p = class_or_union_diff::get_priv();
+    const class_or_union_diff::priv_ptr &p = class_or_union_diff::get_priv();
 
     edit_script& e = p->member_fns_changes_;
 
@@ -5531,7 +5533,7 @@  class_diff::~class_diff()
 ///
 /// @return the (possibly) shared private data of the current instance
 /// of class_diff.
-const class_diff::priv_sptr&
+const class_diff::priv_ptr&
 class_diff::get_priv() const
 {
   if (priv_)
@@ -7664,6 +7666,8 @@  diff_maps::diff_maps()
   : priv_(new diff_maps::priv())
 {}
 
+diff_maps::~diff_maps() = default;
+
 /// Getter of the map that contains basic type diffs.
 ///
 /// @return the map that contains basic type diffs.
@@ -10402,6 +10406,8 @@  corpus_diff::corpus_diff(corpus_sptr first,
   : priv_(new priv(first, second, ctxt))
 {}
 
+corpus_diff::~corpus_diff() = default;
+
 /// Finish building the current instance of @ref corpus_diff.
 void
 corpus_diff::finish_diff_type()
@@ -11183,6 +11189,8 @@  diff_node_visitor::diff_node_visitor()
   : priv_(new priv)
 {}
 
+diff_node_visitor::~diff_node_visitor() = default;
+
 /// Constructor of the @ref diff_node_visitor type.
 ///
 /// @param k how the visiting has to be performed.
diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc
index 0c684a93eac6..a517f3840f5e 100644
--- a/src/abg-corpus.cc
+++ b/src/abg-corpus.cc
@@ -602,6 +602,8 @@  corpus::corpus(ir::environment* env, const string& path)
   init_format_version();
 }
 
+corpus::~corpus() = default;
+
 /// Getter of the enviroment of the corpus.
 ///
 /// @return the environment of this corpus.
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index f8664566f3b5..330cf8416aeb 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -360,7 +360,10 @@  struct location_manager::priv
 };
 
 location_manager::location_manager()
-{priv_ = shared_ptr<location_manager::priv>(new location_manager::priv);}
+  : priv_(new location_manager::priv)
+{}
+
+location_manager::~location_manager() = default;
 
 /// Insert the triplet representing a source locus into our internal
 /// vector of location triplet.  Return an instance of location type,
@@ -434,6 +437,8 @@  type_maps::type_maps()
   : priv_(new priv)
 {}
 
+type_maps::~type_maps() = default;
+
 /// Test if the type_maps is empty.
 ///
 /// @return true iff the type_maps is empty.
@@ -2680,6 +2685,8 @@  elf_symbol::version::version(const elf_symbol::version& v)
 {
 }
 
+elf_symbol::version::~version() = default;
+
 /// Cast the version_type into a string that is its name.
 ///
 /// @return the name of the version.
@@ -15760,6 +15767,7 @@  operator!=(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
 // <array_type_def definitions>
 
 // <array_type_def::subrange_type>
+array_type_def::subrange_type::~subrange_type() = default;
 
 // <array_type_def::subrante_type::bound_value>
 
@@ -17153,6 +17161,9 @@  enum_type_decl::enumerator::enumerator()
   : priv_(new priv)
 {}
 
+enum_type_decl::enumerator::~enumerator() = default;
+
+
 /// Constructor of the @ref enum_type_decl::enumerator type.
 ///
 /// @param env the environment we are operating from.
@@ -19594,6 +19605,8 @@  function_decl::parameter::parameter(const type_base_sptr	type,
   runtime_type_instance(this);
 }
 
+function_decl::parameter::~parameter() = default;
+
 const type_base_sptr
 function_decl::parameter::get_type()const
 {return priv_->type_.lock();}
@@ -21846,6 +21859,8 @@  class_decl::base_spec::base_spec(const type_base_sptr& base,
   runtime_type_instance(this);
 }
 
+class_decl::base_spec::~base_spec() = default;
+
 /// Compares two instances of @ref class_decl::base_spec.
 ///
 /// If the two intances are different, set a bitfield to give some
@@ -25113,6 +25128,8 @@  ir_node_visitor::ir_node_visitor()
   : priv_(new priv)
 {}
 
+ir_node_visitor::~ir_node_visitor() = default;
+
 /// Set if the walker using this visitor is allowed to re-visit a type
 /// node that was previously visited or not.
 ///