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