1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2016-2020 Red Hat, Inc.
5 
6 /// @file
7 ///
8 /// The private data and functions of the @ref abigail::ir::corpus type.
9 ///
10 /// Interfaces declared/defined in this file are to be used by parts
11 /// of libabigail but *NOT* by clients of libabigail.
12 ///
13 
14 #ifndef __ABG_CORPUS_PRIV_H__
15 #define __ABG_CORPUS_PRIV_H__
16 
17 #include "abg-internal.h"
18 #include "abg-ir.h"
19 #include "abg-regex.h"
20 #include "abg-sptr-utils.h"
21 #include "abg-symtab-reader.h"
22 
23 namespace abigail
24 {
25 
26 namespace sptr_utils
27 {
28 }// end namespace sptr_utils
29 
30 namespace ir
31 {
32 
33 using regex::regex_t_sptr;
34 
35 /// A convenience typedef for std::vector<regex_t_sptr>.
36 typedef vector<regex_t_sptr> regex_t_sptrs_type;
37 
38 // <corpus::exported_decls_builder>
39 
40 /// Convenience typedef for a hash map which key is a string and which
41 /// data is a vector of abigail::ir::function_decl*
42 typedef unordered_map<string, vector<function_decl*> > str_fn_ptrs_map_type;
43 /// Convenience typedef for a hash map which key is a string and
44 /// which data is an abigail::ir::var_decl*.
45 typedef unordered_map<string, var_decl*> str_var_ptr_map_type;
46 
47 /// The type of the private data of @ref
48 /// corpus::exported_decls_builder type.
49 class corpus::exported_decls_builder::priv
50 {
51   friend class corpus::exported_decls_builder;
52   friend class corpus;
53 
54   priv();
55 
56   functions&		fns_;
57   variables&		vars_;
58   // A map that associates a function ID (function symbol and its
59   // version) to to a vector of functions with that ID.  Normally, one
60   // would think that in the corpus, there must only one function for
61   // a given ID.  Actually, in c++, there can be two function template
62   // instantiations that produce the same function ID because the
63   // template parameters of the second instantiation are just typedefs
64   // of the first instantiation, for instance.  So there can be cases
65   // where one ID appertains to more than one function.
66   str_fn_ptrs_map_type	id_fns_map_;
67   str_var_ptr_map_type	id_var_map_;
68   strings_type&	fns_suppress_regexps_;
69   regex_t_sptrs_type	compiled_fns_suppress_regexp_;
70   strings_type&	vars_suppress_regexps_;
71   regex_t_sptrs_type	compiled_vars_suppress_regexp_;
72   strings_type&	fns_keep_regexps_;
73   regex_t_sptrs_type	compiled_fns_keep_regexps_;
74   strings_type&	vars_keep_regexps_;
75   regex_t_sptrs_type	compiled_vars_keep_regexps_;
76   strings_type&	sym_id_of_fns_to_keep_;
77   strings_type&	sym_id_of_vars_to_keep_;
78 
79 public:
80 
priv(functions & fns,variables & vars,strings_type & fns_suppress_regexps,strings_type & vars_suppress_regexps,strings_type & fns_keep_regexps,strings_type & vars_keep_regexps,strings_type & sym_id_of_fns_to_keep,strings_type & sym_id_of_vars_to_keep)81   priv(functions& fns,
82        variables& vars,
83        strings_type& fns_suppress_regexps,
84        strings_type& vars_suppress_regexps,
85        strings_type& fns_keep_regexps,
86        strings_type& vars_keep_regexps,
87        strings_type& sym_id_of_fns_to_keep,
88        strings_type& sym_id_of_vars_to_keep)
89     : fns_(fns),
90       vars_(vars),
91       fns_suppress_regexps_(fns_suppress_regexps),
92       vars_suppress_regexps_(vars_suppress_regexps),
93       fns_keep_regexps_(fns_keep_regexps),
94       vars_keep_regexps_(vars_keep_regexps),
95     sym_id_of_fns_to_keep_(sym_id_of_fns_to_keep),
96     sym_id_of_vars_to_keep_(sym_id_of_vars_to_keep)
97   {}
98 
99   /// Getter for the compiled regular expressions that designate the
100   /// functions to suppress from the set of exported functions.
101   ///
102   /// @return a vector of the compiled regular expressions.
103   regex_t_sptrs_type&
compiled_regex_fns_suppress()104   compiled_regex_fns_suppress()
105   {
106     if (compiled_fns_suppress_regexp_.empty())
107       {
108 	for (vector<string>::const_iterator i =
109 	       fns_suppress_regexps_.begin();
110 	     i != fns_suppress_regexps_.end();
111 	     ++i)
112 	  {
113 	    regex_t_sptr r = regex::compile(*i);
114 	    if (r)
115 	      compiled_fns_suppress_regexp_.push_back(r);
116 	  }
117       }
118     return compiled_fns_suppress_regexp_;
119   }
120 
121   /// Getter for the compiled regular expressions that designates the
122   /// functions to keep in the set of exported functions.
123   ///
124   /// @return a vector of compiled regular expressions.
125   regex_t_sptrs_type&
compiled_regex_fns_keep()126   compiled_regex_fns_keep()
127   {
128     if (compiled_fns_keep_regexps_.empty())
129       {
130 	for (vector<string>::const_iterator i =
131 	       fns_keep_regexps_.begin();
132 	     i != fns_keep_regexps_.end();
133 	     ++i)
134 	  {
135 	    regex_t_sptr r = regex::compile(*i);
136 	    if (r)
137 	      compiled_fns_keep_regexps_.push_back(r);
138 	  }
139       }
140     return compiled_fns_keep_regexps_;
141   }
142 
143   /// Getter of the compiled regular expressions that designate the
144   /// variables to suppress from the set of exported variables.
145   ///
146   /// @return a vector of compiled regular expressions.
147   regex_t_sptrs_type&
compiled_regex_vars_suppress()148   compiled_regex_vars_suppress()
149   {
150     if (compiled_vars_suppress_regexp_.empty())
151       {
152 	for (vector<string>::const_iterator i =
153 	       vars_suppress_regexps_.begin();
154 	     i != vars_suppress_regexps_.end();
155 	     ++i)
156 	  {
157 	    regex_t_sptr r = regex::compile(*i);
158 	    if (r)
159 	      compiled_vars_suppress_regexp_.push_back(r);
160 	  }
161       }
162     return compiled_vars_suppress_regexp_;
163   }
164 
165   /// Getter for the compiled regular expressions that designate the
166   /// variables to keep in the set of exported variables.
167   ///
168   /// @return a vector of compiled regular expressions.
169   regex_t_sptrs_type&
compiled_regex_vars_keep()170   compiled_regex_vars_keep()
171   {
172     if (compiled_vars_keep_regexps_.empty())
173       {
174 	for (vector<string>::const_iterator i =
175 	       vars_keep_regexps_.begin();
176 	     i != vars_keep_regexps_.end();
177 	     ++i)
178 	  {
179 	    regex_t_sptr r = regex::compile(*i);
180 	    if (r)
181 	      compiled_vars_keep_regexps_.push_back(r);
182 	  }
183       }
184     return compiled_vars_keep_regexps_;
185   }
186 
187   /// Getter for a map of the IDs of the functions that are present in
188   /// the set of exported functions.
189   ///
190   /// This map is useful during the construction of the set of
191   /// exported functions, at least to ensure that every function is
192   /// present only once in that set.  Actually, for each symbol ID,
193   /// there can be several functions, given that each of those have
194   /// different declaration names; this can happen with function
195   /// template instantiations which decl names differ because the type
196   /// parameters of the templates are typedefs of each other.
197   ///
198   /// @return a map which key is a string and which data is a pointer
199   /// to a function.
200   const str_fn_ptrs_map_type&
id_fns_map()201   id_fns_map() const
202   {return id_fns_map_;}
203 
204   /// Getter for a map of the IDs of the functions that are present in
205   /// the set of exported functions.
206   ///
207   /// This map is useful during the construction of the set of
208   /// exported functions, at least to ensure that every function is
209   /// present only once in that set.
210   ///
211   /// @return a map which key is a string and which data is a pointer
212   /// to a function.
213   str_fn_ptrs_map_type&
id_fns_map()214   id_fns_map()
215   {return id_fns_map_;}
216 
217   /// Getter for a map of the IDs of the variables that are present in
218   /// the set of exported variables.
219   ///
220   /// This map is useful during the construction of the set of
221   /// exported variables, at least to ensure that every function is
222   /// present only once in that set.
223   ///
224   /// @return a map which key is a string and which data is a pointer
225   /// to a function.
226   const str_var_ptr_map_type&
id_var_map()227   id_var_map() const
228   {return id_var_map_;}
229 
230   /// Getter for a map of the IDs of the variables that are present in
231   /// the set of exported variables.
232   ///
233   /// This map is useful during the construction of the set of
234   /// exported variables, at least to ensure that every function is
235   /// present only once in that set.
236   ///
237   /// @return a map which key is a string and which data is a pointer
238   /// to a function.
239   str_var_ptr_map_type&
id_var_map()240   id_var_map()
241   {return id_var_map_;}
242 
243   /// Returns an ID for a given function.
244   ///
245   /// @param fn the function to calculate the ID for.
246   ///
247   /// @return a reference to a string representing the function ID.
248   interned_string
get_id(const function_decl & fn)249   get_id(const function_decl& fn)
250   {return fn.get_id();}
251 
252   /// Returns an ID for a given variable.
253   ///
254   /// @param var the variable to calculate the ID for.
255   ///
256   /// @return a reference to a string representing the variable ID.
257   interned_string
get_id(const var_decl & var)258   get_id(const var_decl& var)
259   {return var.get_id();}
260 
261   /// Test if a given function ID is in the id-functions map.
262   ///
263   /// If it is, then return a pointer to the vector of functions with
264   /// that ID.  If not, just return nil.
265   ///
266   /// @param fn_id the ID to consider.
267   ///
268   /// @return the pointer to the vector of functions with ID @p fn_id,
269   /// or nil if no function with that ID exists.
270   vector<function_decl*>*
fn_id_is_in_id_fns_map(const string & fn_id)271   fn_id_is_in_id_fns_map(const string& fn_id)
272   {
273     str_fn_ptrs_map_type& m = id_fns_map();
274     str_fn_ptrs_map_type::iterator i = m.find(fn_id);
275     if (i == m.end())
276       return 0;
277     return &i->second;
278   }
279 
280   /// Test if a a function if the same ID as a given function is
281   /// present in the id-functions map.
282   ///
283   /// @param fn the function to consider.
284   ///
285   /// @return a pointer to the vector of functions with the same ID as
286   /// @p fn, that are present in the id-functions map, or nil if no
287   /// function with the same ID as @p fn is present in the
288   /// id-functions map.
289   vector<function_decl*>*
fn_id_is_in_id_fns_map(const function_decl * fn)290   fn_id_is_in_id_fns_map(const function_decl* fn)
291   {
292     string fn_id = fn->get_id();
293     return fn_id_is_in_id_fns_map(fn_id);
294   }
295 
296   /// Test if a given function is present in a vector of functions.
297   ///
298   /// The function compares the ID and the qualified name of
299   /// functions.
300   ///
301   /// @param fn the function to consider.
302   ///
303   /// @parm fns the vector of functions to consider.
304   static bool
fn_is_in_fns(const function_decl * fn,const vector<function_decl * > & fns)305   fn_is_in_fns(const function_decl* fn, const vector<function_decl*>& fns)
306   {
307     if (fns.empty())
308       return false;
309 
310     const string fn_id = fn->get_id();
311     for (vector<function_decl*>::const_iterator i = fns.begin();
312 	 i != fns.end();
313 	 ++i)
314       if ((*i)->get_id() == fn_id
315 	  && (*i)->get_qualified_name() == fn->get_qualified_name())
316 	return true;
317 
318     return false;
319   }
320 
321   ///  Test if a function is in the id-functions map.
322   ///
323   ///  @param fn the function to consider.
324   ///
325   ///  @return true iff the function is in the id-functions map.
326   bool
fn_is_in_id_fns_map(const function_decl * fn)327   fn_is_in_id_fns_map(const function_decl* fn)
328   {
329     vector<function_decl*>* fns = fn_id_is_in_id_fns_map(fn);
330     if (fns && fn_is_in_fns(fn, *fns))
331       return true;
332     return false;
333   }
334 
335   /// Add a given function to the map of functions that are present in
336   /// the set of exported functions.
337   ///
338   /// @param fn the function to add to the map.
339   void
add_fn_to_id_fns_map(function_decl * fn)340   add_fn_to_id_fns_map(function_decl* fn)
341   {
342     if (!fn)
343       return;
344 
345     // First associate the function id to the function.
346     string fn_id = fn->get_id();
347     vector<function_decl*>* fns = fn_id_is_in_id_fns_map(fn_id);
348     if (!fns)
349       fns = &(id_fns_map()[fn_id] = vector<function_decl*>());
350     fns->push_back(fn);
351 
352     // Now associate all aliases of the underlying symbol to the
353     // function too.
354     elf_symbol_sptr sym = fn->get_symbol();
355     ABG_ASSERT(sym);
356     string sym_id;
357     do
358       {
359 	sym_id = sym->get_id_string();
360 	if (sym_id == fn_id)
361 	  goto loop;
362 	fns = fn_id_is_in_id_fns_map(fn_id);
363 	if (!fns)
364 	  fns = &(id_fns_map()[fn_id] = vector<function_decl*>());
365 	fns->push_back(fn);
366       loop:
367 	sym = sym->get_next_alias();
368       }
369     while (sym && !sym->is_main_symbol());
370   }
371 
372   /// Test if a given (ID of a) varialble is present in the variable
373   /// map.  In other words, it tests if a given variable is present in
374   /// the set of exported variables.
375   ///
376   /// @param fn_id the ID of the variable to consider.
377   ///
378   /// @return true iff the variable designated by @p fn_id is present
379   /// in the set of exported variables.
380   bool
var_id_is_in_id_var_map(const string & var_id)381   var_id_is_in_id_var_map(const string& var_id) const
382   {
383     const str_var_ptr_map_type& m = id_var_map();
384     str_var_ptr_map_type::const_iterator i = m.find(var_id);
385     return i != m.end();
386   }
387 
388   /// Add a given variable to the map of functions that are present in
389   /// the set of exported functions.
390   ///
391   /// @param id the variable to add to the map.
392   void
add_var_to_map(var_decl * var)393   add_var_to_map(var_decl* var)
394   {
395     if (var)
396       {
397 	const string& var_id = get_id(*var);
398 	id_var_map()[var_id] = var;
399       }
400   }
401 
402   /// Add a function to the set of exported functions.
403   ///
404   /// @param fn the function to add to the set of exported functions.
405   void
add_fn_to_exported(function_decl * fn)406   add_fn_to_exported(function_decl* fn)
407   {
408     if (!fn_is_in_id_fns_map(fn))
409       {
410 	fns_.push_back(fn);
411 	add_fn_to_id_fns_map(fn);
412       }
413   }
414 
415   /// Add a variable to the set of exported variables.
416   ///
417   /// @param fn the variable to add to the set of exported variables.
418   void
add_var_to_exported(var_decl * var)419   add_var_to_exported(var_decl* var)
420   {
421     const string& id = get_id(*var);
422     if (!var_id_is_in_id_var_map(id))
423       {
424 	vars_.push_back(var);
425 	add_var_to_map(var);
426       }
427   }
428 
429   /// Getter for the set of ids of functions to keep in the set of
430   /// exported functions.
431   ///
432   /// @return the set of ids of functions to keep in the set of
433   /// exported functions.
434   const strings_type&
sym_id_of_fns_to_keep()435   sym_id_of_fns_to_keep() const
436   {return sym_id_of_fns_to_keep_;}
437 
438   /// Getter for the set of ids of variables to keep in the set of
439   /// exported variables.
440   ///
441   /// @return the set of ids of variables to keep in the set of
442   /// exported variables.
443   const strings_type&
sym_id_of_vars_to_keep()444   sym_id_of_vars_to_keep() const
445   {return sym_id_of_vars_to_keep_;}
446 
447   /// Look at the set of functions to keep and tell if if a given
448   /// function is to be kept, according to that set.
449   ///
450   /// @param fn the function to consider.
451   ///
452   /// @return true iff the function is to be kept.
453   bool
keep_wrt_id_of_fns_to_keep(const function_decl * fn)454   keep_wrt_id_of_fns_to_keep(const function_decl* fn)
455   {
456     if (!fn)
457       return false;
458 
459     bool keep = true;
460 
461     if (elf_symbol_sptr sym = fn->get_symbol())
462       {
463 	if (!sym_id_of_fns_to_keep().empty())
464 	  keep = false;
465 	if (!keep)
466 	  {
467 	    for (vector<string>::const_iterator i =
468 		   sym_id_of_fns_to_keep().begin();
469 		 i != sym_id_of_fns_to_keep().end();
470 		 ++i)
471 	      {
472 		string sym_name, sym_version;
473 		ABG_ASSERT(elf_symbol::get_name_and_version_from_id(*i,
474 								    sym_name,
475 								    sym_version));
476 		if (sym_name == sym->get_name()
477 		    && sym_version == sym->get_version().str())
478 		  {
479 		    keep = true;
480 		    break;
481 		  }
482 	      }
483 	  }
484       }
485     else
486       keep = false;
487 
488     return keep;
489   }
490 
491   /// Look at the set of functions to suppress from the exported
492   /// functions set and tell if if a given function is to be kept,
493   /// according to that set.
494   ///
495   /// @param fn the function to consider.
496   ///
497   /// @return true iff the function is to be kept.
498   bool
keep_wrt_regex_of_fns_to_suppress(const function_decl * fn)499   keep_wrt_regex_of_fns_to_suppress(const function_decl *fn)
500   {
501     if (!fn)
502       return false;
503 
504     string frep = fn->get_qualified_name();
505     bool keep = true;
506 
507     for (regex_t_sptrs_type::const_iterator i =
508 	   compiled_regex_fns_suppress().begin();
509 	 i != compiled_regex_fns_suppress().end();
510 	 ++i)
511       if (regex::match(*i, frep))
512 	{
513 	  keep = false;
514 	  break;
515 	}
516 
517     return keep;
518   }
519 
520   /// Look at the regular expressions of the functions to keep and
521   /// tell if if a given function is to be kept, according to that
522   /// set.
523   ///
524   /// @param fn the function to consider.
525   ///
526   /// @return true iff the function is to be kept.
527   bool
keep_wrt_regex_of_fns_to_keep(const function_decl * fn)528   keep_wrt_regex_of_fns_to_keep(const function_decl *fn)
529   {
530     if (!fn)
531       return false;
532 
533     string frep = fn->get_qualified_name();
534     bool keep = true;
535 
536     if (!compiled_regex_fns_keep().empty())
537       keep = false;
538 
539     if (!keep)
540       for (regex_t_sptrs_type::const_iterator i =
541 	     compiled_regex_fns_keep().begin();
542 	   i != compiled_regex_fns_keep().end();
543 	   ++i)
544 	if (regex::match(*i, frep))
545 	  {
546 	    keep = true;
547 	    break;
548 	  }
549 
550     return keep;
551   }
552 
553   /// Look at the regular expressions of the variables to keep and
554   /// tell if if a given variable is to be kept, according to that
555   /// set.
556   ///
557   /// @param fn the variable to consider.
558   ///
559   /// @return true iff the variable is to be kept.
560   bool
keep_wrt_id_of_vars_to_keep(const var_decl * var)561   keep_wrt_id_of_vars_to_keep(const var_decl* var)
562   {
563     if (!var)
564       return false;
565 
566     bool keep = true;
567 
568     if (elf_symbol_sptr sym = var->get_symbol())
569       {
570 	if (!sym_id_of_vars_to_keep().empty())
571 	  keep = false;
572 	if (!keep)
573 	  {
574 	    for (vector<string>::const_iterator i =
575 		   sym_id_of_vars_to_keep().begin();
576 		 i != sym_id_of_vars_to_keep().end();
577 		 ++i)
578 	      {
579 		string sym_name, sym_version;
580 		ABG_ASSERT(elf_symbol::get_name_and_version_from_id(*i,
581 								    sym_name,
582 								    sym_version));
583 		if (sym_name == sym->get_name()
584 		    && sym_version == sym->get_version().str())
585 		  {
586 		    keep = true;
587 		    break;
588 		  }
589 	      }
590 	  }
591       }
592     else
593       keep = false;
594 
595     return keep;
596   }
597 
598   /// Look at the set of variables to suppress from the exported
599   /// variables set and tell if if a given variable is to be kept,
600   /// according to that set.
601   ///
602   /// @param fn the variable to consider.
603   ///
604   /// @return true iff the variable is to be kept.
605   bool
keep_wrt_regex_of_vars_to_suppress(const var_decl * var)606   keep_wrt_regex_of_vars_to_suppress(const var_decl *var)
607   {
608     if (!var)
609       return false;
610 
611     string frep = var->get_qualified_name();
612     bool keep = true;
613 
614     for (regex_t_sptrs_type::const_iterator i =
615 	   compiled_regex_vars_suppress().begin();
616 	 i != compiled_regex_vars_suppress().end();
617 	 ++i)
618       if (regex::match(*i, frep))
619 	{
620 	  keep = false;
621 	  break;
622 	}
623 
624     return keep;
625   }
626 
627   /// Look at the regular expressions of the variables to keep and
628   /// tell if if a given variable is to be kept, according to that
629   /// set.
630   ///
631   /// @param fn the variable to consider.
632   ///
633   /// @return true iff the variable is to be kept.
634   bool
keep_wrt_regex_of_vars_to_keep(const var_decl * var)635   keep_wrt_regex_of_vars_to_keep(const var_decl *var)
636   {
637     if (!var)
638       return false;
639 
640     string frep = var->get_qualified_name();
641     bool keep = true;
642 
643     if (!compiled_regex_vars_keep().empty())
644       keep = false;
645 
646     if (!keep)
647       {
648 	for (regex_t_sptrs_type::const_iterator i =
649 	       compiled_regex_vars_keep().begin();
650 	     i != compiled_regex_vars_keep().end();
651 	     ++i)
652 	  if (regex::match(*i, frep))
653 	    {
654 	      keep = true;
655 	      break;
656 	    }
657       }
658 
659     return keep;
660   }
661 }; // end struct corpus::exported_decls_builder::priv
662 
663 
664 /// The private data of the @ref corpus type.
665 struct corpus::priv
666 {
667   mutable unordered_map<string, type_base_sptr> canonical_types_;
668   string					format_major_version_number_;
669   string					format_minor_version_number_;
670   environment*					env;
671   corpus_group*				group;
672   corpus::exported_decls_builder_sptr		exported_decls_builder;
673   origin					origin_;
674   vector<string>				regex_patterns_fns_to_suppress;
675   vector<string>				regex_patterns_vars_to_suppress;
676   vector<string>				regex_patterns_fns_to_keep;
677   vector<string>				regex_patterns_vars_to_keep;
678   vector<string>				sym_id_fns_to_keep;
679   vector<string>				sym_id_vars_to_keep;
680   string					path;
681   vector<string>				needed;
682   string					soname;
683   string					architecture_name;
684   translation_units				members;
685   string_tu_map_type				path_tu_map;
686   vector<function_decl*>			fns;
687   vector<var_decl*>				vars;
688   symtab_reader::symtab_sptr			symtab_;
689   // The type maps contained in this data member are populated if the
690   // corpus follows the One Definition Rule and thus if there is only
691   // one copy of a type with a given name, per corpus. Otherwise, if
692   // there can be several *different* types with the same name, then
693   // the type maps are all empty.  The types are then maintained in
694   // type maps that are in each translation units.
695   //
696   // In other words, to lookup a given type, if the corpus allows the
697   // One Definition Rule, then lookup can be done by looking into this
698   // data member.  Otherwise, the lookup must be made by looking into
699   // the type maps of each translation unit.
700   type_maps					types_;
701   type_maps					type_per_loc_map_;
702   mutable vector<type_base_wptr>		types_not_reachable_from_pub_ifaces_;
703   unordered_set<interned_string, hash_interned_string> *pub_type_pretty_reprs_;
704 
705 private:
706   priv();
707 
708   mutable abg_compat::optional<elf_symbols> sorted_var_symbols;
709   mutable abg_compat::optional<string_elf_symbols_map_type> var_symbol_map;
710   mutable abg_compat::optional<elf_symbols> sorted_undefined_var_symbols;
711   mutable abg_compat::optional<string_elf_symbols_map_type> undefined_var_symbol_map;
712   mutable abg_compat::optional<elf_symbols> unrefed_var_symbols;
713   mutable abg_compat::optional<elf_symbols> sorted_fun_symbols;
714   mutable abg_compat::optional<string_elf_symbols_map_type> fun_symbol_map;
715   mutable abg_compat::optional<elf_symbols> sorted_undefined_fun_symbols;
716   mutable abg_compat::optional<string_elf_symbols_map_type> undefined_fun_symbol_map;
717   mutable abg_compat::optional<elf_symbols> unrefed_fun_symbols;
718 
719 public:
privpriv720   priv(const string &	p,
721        environment*	e)
722     : env(e),
723       group(),
724       origin_(ARTIFICIAL_ORIGIN),
725       path(p),
726       pub_type_pretty_reprs_()
727   {}
728 
729   type_maps&
730   get_types();
731 
732   const type_maps&
733   get_types() const;
734 
735   const elf_symbols&
736   get_sorted_fun_symbols() const;
737 
738   const string_elf_symbols_map_type&
739   get_fun_symbol_map() const;
740 
741   const elf_symbols&
742   get_sorted_undefined_fun_symbols() const;
743 
744   const string_elf_symbols_map_type&
745   get_undefined_fun_symbol_map() const;
746 
747   const elf_symbols&
748   get_unreferenced_function_symbols() const;
749 
750   const elf_symbols&
751   get_sorted_var_symbols() const;
752 
753   const string_elf_symbols_map_type&
754   get_var_symbol_map() const;
755 
756   const elf_symbols&
757   get_sorted_undefined_var_symbols() const;
758 
759   const string_elf_symbols_map_type&
760   get_undefined_var_symbol_map() const;
761 
762   const elf_symbols&
763   get_unreferenced_variable_symbols() const;
764 
765   unordered_set<interned_string, hash_interned_string>*
766   get_public_types_pretty_representations();
767 
768   ~priv();
769 }; // end struct corpus::priv
770 
771 void
772 maybe_update_scope_lookup_map(const scope_decl_sptr& member_scope);
773 
774 void
775 maybe_update_scope_lookup_map(const decl_base_sptr& member_scope);
776 
777 void
778 maybe_update_types_lookup_map(const type_decl_sptr& basic_type);
779 
780 void
781 maybe_update_types_lookup_map(const class_decl_sptr& class_type);
782 
783 void
784 maybe_update_types_lookup_map(const union_decl_sptr& union_type);
785 
786 void
787 maybe_update_types_lookup_map(const enum_type_decl_sptr& enum_type);
788 
789 void
790 maybe_update_types_lookup_map(const typedef_decl_sptr& typedef_type);
791 
792 void
793 maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type);
794 
795 void
796 maybe_update_types_lookup_map(const pointer_type_def_sptr& pointer_type);
797 
798 void
799 maybe_update_types_lookup_map(const reference_type_def_sptr& reference_type);
800 
801 void
802 maybe_update_types_lookup_map(const array_type_def_sptr& array_type);
803 
804 void
805 maybe_update_types_lookup_map(scope_decl *scope,
806 			      const function_type_sptr& function_type);
807 
808 void
809 maybe_update_types_lookup_map(const decl_base_sptr& decl);
810 
811 void
812 maybe_update_types_lookup_map(const type_base_sptr& type);
813 
814 }// end namespace ir
815 
816 }// end namespace abigail
817 
818 #endif // __ABG_CORPUS_PRIV_H__
819