1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2016-2020 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7
8 /// @file
9 ///
10 /// This contains the private implementation of the suppression engine
11 /// of libabigail.
12
13 #ifndef __ABG_SUPPRESSION_PRIV_H__
14 #define __ABG_SUPPRESSION_PRIV_H__
15
16 #include "abg-fwd.h"
17 #include "abg-regex.h"
18 #include "abg-sptr-utils.h"
19 #include "abg-suppression.h"
20
21 namespace abigail
22 {
23
24 namespace suppr
25 {
26
27 // <suppression_base stuff>
28
29 /// The private data of @ref suppression_base.
30 class suppression_base::priv
31 {
32 bool is_artificial_;
33 bool drops_artifact_;
34 string label_;
35 string file_name_regex_str_;
36 mutable regex::regex_t_sptr file_name_regex_;
37 string file_name_not_regex_str_;
38 mutable regex::regex_t_sptr file_name_not_regex_;
39 string soname_regex_str_;
40 mutable regex::regex_t_sptr soname_regex_;
41 string soname_not_regex_str_;
42 mutable regex::regex_t_sptr soname_not_regex_;
43
44 public:
priv()45 priv()
46 : is_artificial_(),
47 drops_artifact_()
48 {}
49
priv(const string & label)50 priv(const string& label)
51 : is_artificial_(),
52 drops_artifact_(),
53 label_(label)
54 {}
55
priv(const string & label,const string & file_name_regex_str,const string & file_name_not_regex_str)56 priv(const string& label,
57 const string& file_name_regex_str,
58 const string& file_name_not_regex_str)
59 : is_artificial_(),
60 drops_artifact_(),
61 label_(label),
62 file_name_regex_str_(file_name_regex_str),
63 file_name_not_regex_str_(file_name_not_regex_str)
64 {}
65
66 friend class suppression_base;
67
68 /// Get the regular expression object associated to the 'file_name_regex'
69 /// property of @ref suppression_base.
70 ///
71 /// If the regular expression object is not created, this method
72 /// creates it and returns it.
73 ///
74 /// If the 'file_name_regex' property of @ref suppression_base is
75 /// empty then this method returns nil.
76 const regex::regex_t_sptr&
get_file_name_regex()77 get_file_name_regex() const
78 {
79 if (!file_name_regex_ && !file_name_regex_str_.empty())
80 file_name_regex_ = regex::compile(file_name_regex_str_);
81 return file_name_regex_;
82 }
83
84 /// Get the regular expression object associated to the
85 /// 'file_name_not_regex' property of @ref suppression_base.
86 ///
87 /// If the regular expression object is not created, this method
88 /// creates it and returns it.
89 ///
90 /// If the 'file_name_not_regex' property of @ref suppression_base
91 /// is empty then this method returns nil.
92 const regex::regex_t_sptr&
get_file_name_not_regex()93 get_file_name_not_regex() const
94 {
95 if (!file_name_not_regex_ && !file_name_not_regex_str_.empty())
96 file_name_not_regex_ = regex::compile(file_name_not_regex_str_);
97 return file_name_not_regex_;
98 }
99
100 /// Get the regular expression object associated to the
101 /// 'soname_regex' property of @ref suppression_base.
102 ///
103 /// If the regular expression object is not created, this method
104 /// creates it and returns it.
105 ///
106 /// If the 'soname_regex' property of @ref suppression_base is empty
107 /// then this method returns nil.
108 const regex::regex_t_sptr&
get_soname_regex()109 get_soname_regex() const
110 {
111 if (!soname_regex_ && !soname_regex_str_.empty())
112 soname_regex_ = regex::compile(soname_regex_str_);
113 return soname_regex_;
114 }
115
116 /// Get the regular expression object associated to the
117 /// 'soname_not_regex' property of @ref suppression_base.
118 ///
119 /// If the regular expression object is not created, this method
120 /// creates it and returns it.
121 ///
122 /// If the 'soname_not_regex' property of @ref suppression_base is
123 /// empty then this method returns nil.
124 const regex::regex_t_sptr&
get_soname_not_regex()125 get_soname_not_regex() const
126 {
127 if (!soname_not_regex_ && !soname_not_regex_str_.empty())
128 soname_not_regex_ = regex::compile(soname_not_regex_str_);
129 return soname_not_regex_;
130 }
131
132 /// Test if the current suppression matches a given SONAME.
133 ///
134 /// @param soname the SONAME to consider.
135 ///
136 /// @return true iff the suppression matches the SONAME denoted by
137 /// @p soname.
138 ///
139 /// Note that if the suppression contains no property that is
140 /// related to SONAMEs, the function returns false.
141 bool
matches_soname(const string & soname)142 matches_soname(const string& soname) const
143 {
144 bool has_regexp = false;
145 if (regex::regex_t_sptr regexp = get_soname_regex())
146 {
147 has_regexp = true;
148 if (!regex::match(regexp, soname))
149 return false;
150 }
151
152 if (regex::regex_t_sptr regexp = get_soname_not_regex())
153 {
154 has_regexp = true;
155 if (regex::match(regexp, soname))
156 return false;
157 }
158
159 if (!has_regexp)
160 return false;
161
162 return true;
163 }
164
165 /// Test if the current suppression matches the full file path to a
166 /// given binary.
167 ///
168 /// @param binary_name the full path to the binary.
169 ///
170 /// @return true iff the suppression matches the path denoted by @p
171 /// binary_name.
172 ///
173 /// Note that if the suppression contains no property that is
174 /// related to file name, the function returns false.
175 bool
matches_binary_name(const string & binary_name)176 matches_binary_name(const string& binary_name) const
177 {
178 bool has_regexp = false;
179
180 if (regex::regex_t_sptr regexp = get_file_name_regex())
181 {
182 has_regexp = true;
183 if (!regex::match(regexp, binary_name))
184 return false;
185 }
186
187 if (regex::regex_t_sptr regexp = get_file_name_not_regex())
188 {
189 has_regexp = true;
190 if (regex::match(regexp, binary_name))
191 return false;
192 }
193
194 if (!has_regexp)
195 return false;
196
197 return true;
198 }
199
200 }; // end clas suppression_base::priv
201
202 // </suppression_base stuff>
203
204 // <function_suppression stuff>
205
206 class function_suppression::parameter_spec::priv
207 {
208 friend class function_suppression::parameter_spec;
209 friend class function_suppression;
210
211 size_t index_;
212 string type_name_;
213 string type_name_regex_str_;
214 mutable regex::regex_t_sptr type_name_regex_;
215
priv()216 priv()
217 : index_()
218 {}
219
priv(size_t i,const string & tn)220 priv(size_t i, const string& tn)
221 : index_(i), type_name_(tn)
222 {}
223
priv(size_t i,const string & tn,const string & tn_regex)224 priv(size_t i, const string& tn, const string& tn_regex)
225 : index_(i), type_name_(tn), type_name_regex_str_(tn_regex)
226 {}
227
228 const regex::regex_t_sptr
get_type_name_regex()229 get_type_name_regex() const
230 {
231 if (!type_name_regex_ && !type_name_regex_str_.empty())
232 type_name_regex_ = regex::compile(type_name_regex_str_);
233 return type_name_regex_;
234 }
235 }; // end class function_suppression::parameter_spec::priv
236
237
238 /// The type of the private data of the @ref function_suppression
239 /// type.
240 struct function_suppression::priv
241 {
242 friend class function_suppression;
243
244 change_kind change_kind_;
245 string name_;
246 string name_regex_str_;
247 mutable regex::regex_t_sptr name_regex_;
248 string name_not_regex_str_;
249 mutable regex::regex_t_sptr name_not_regex_;
250 string return_type_name_;
251 string return_type_regex_str_;
252 mutable regex::regex_t_sptr return_type_regex_;
253 parameter_specs_type parm_specs_;
254 string symbol_name_;
255 string symbol_name_regex_str_;
256 mutable regex::regex_t_sptr symbol_name_regex_;
257 string symbol_name_not_regex_str_;
258 mutable regex::regex_t_sptr symbol_name_not_regex_;
259 string symbol_version_;
260 string symbol_version_regex_str_;
261 mutable regex::regex_t_sptr symbol_version_regex_;
262 bool allow_other_aliases_;
263
privpriv264 priv():
265 change_kind_(ALL_CHANGE_KIND),
266 allow_other_aliases_(true)
267 {}
268
privpriv269 priv(const string& name,
270 const string& name_regex_str,
271 const string& return_type_name,
272 const string& return_type_regex_str,
273 const parameter_specs_type& parm_specs,
274 const string& symbol_name,
275 const string& symbol_name_regex_str,
276 const string& symbol_version,
277 const string& symbol_version_regex_str)
278 : change_kind_(ALL_CHANGE_KIND),
279 name_(name),
280 name_regex_str_(name_regex_str),
281 return_type_name_(return_type_name),
282 return_type_regex_str_(return_type_regex_str),
283 parm_specs_(parm_specs),
284 symbol_name_(symbol_name),
285 symbol_name_regex_str_(symbol_name_regex_str),
286 symbol_version_(symbol_version),
287 symbol_version_regex_str_(symbol_version_regex_str),
288 allow_other_aliases_(true)
289 {}
290
291
292 /// Getter for a pointer to a regular expression object built from
293 /// the regular expression string
294 /// function_suppression::priv::name_regex_str_.
295 ///
296 /// If that string is empty, then an empty regular expression object
297 /// pointer is returned.
298 ///
299 /// @return a pointer to the regular expression object of
300 /// function_suppression::priv::name_regex_str_..
301 const regex::regex_t_sptr
get_name_regexpriv302 get_name_regex() const
303 {
304 if (!name_regex_ && !name_regex_str_.empty())
305 name_regex_ = regex::compile(name_regex_str_);
306 return name_regex_;
307 }
308
309 /// Getter for a pointer to a regular expression object built from
310 /// the regular expression string
311 /// function_suppression::priv::name_not_regex_str_.
312 ///
313 /// If that string is empty, then an empty regular expression object
314 /// pointer is returned.
315 ///
316 /// @return a pointer to the regular expression object of
317 /// function_suppression::priv::name_not_regex_str_..
318 const regex::regex_t_sptr
get_name_not_regexpriv319 get_name_not_regex() const
320 {
321 if (!name_not_regex_ && !name_not_regex_str_.empty())
322 name_not_regex_ = regex::compile(name_not_regex_str_);
323 return name_not_regex_;
324 }
325
326 /// Getter for a pointer to a regular expression object built from
327 /// the regular expression string
328 /// function_suppression::priv::return_type_regex_str_.
329 ///
330 /// If that string is empty, then an empty regular expression object
331 /// pointer is returned.
332 ///
333 /// @return a pointer to the regular expression object of
334 /// function_suppression::priv::return_type_regex_str_.
335 const regex::regex_t_sptr
get_return_type_regexpriv336 get_return_type_regex() const
337 {
338 if (!return_type_regex_ && !return_type_regex_str_.empty())
339 return_type_regex_ = regex::compile(return_type_regex_str_);
340 return return_type_regex_;
341 }
342
343 /// Getter for a pointer to a regular expression object built from
344 /// the regular expression string
345 /// function_suppression::priv::symbol_name_regex_str_.
346 ///
347 /// If that string is empty, then an empty regular expression object
348 /// pointer is returned.
349 ///
350 /// @return a pointer to the regular expression object of
351 /// function_suppression::priv::symbol_name_regex_str_.
352 const regex::regex_t_sptr
get_symbol_name_regexpriv353 get_symbol_name_regex() const
354 {
355 if (!symbol_name_regex_ && !symbol_name_regex_str_.empty())
356 symbol_name_regex_ = regex::compile(symbol_name_regex_str_);
357 return symbol_name_regex_;
358 }
359
360 /// Getter for a pointer to a regular expression object built from
361 /// the regular expression string
362 /// function_suppression::priv::symbol_name_not_regex_str_.
363 ///
364 /// If that string is empty, then an empty regular expression object
365 /// pointer is returned.
366 ///
367 /// @return a pointer to the regular expression object of
368 /// function_suppression::priv::symbol_name_not_regex_str_.
369 const regex::regex_t_sptr
get_symbol_name_not_regexpriv370 get_symbol_name_not_regex() const
371 {
372 if (!symbol_name_not_regex_ && !symbol_name_not_regex_str_.empty())
373 symbol_name_not_regex_ = regex::compile(symbol_name_not_regex_str_);
374 return symbol_name_not_regex_;
375 }
376
377 /// Getter for a pointer to a regular expression object built from
378 /// the regular expression string
379 /// function_suppression::priv::symbol_version_regex_str_.
380 ///
381 /// If that string is empty, then an empty regular expression object
382 /// pointer is returned.
383 ///
384 /// @return a pointer to the regular expression object of
385 /// function_suppression::priv::symbol_version_regex_str_.
386 const regex::regex_t_sptr
get_symbol_version_regexpriv387 get_symbol_version_regex() const
388 {
389 if (!symbol_version_regex_ && !symbol_version_regex_str_.empty())
390 symbol_version_regex_ = regex::compile(symbol_version_regex_str_);
391 return symbol_version_regex_;
392 }
393 }; // end class function_suppression::priv
394
395 bool
396 suppression_matches_function_name(const suppr::function_suppression& s,
397 const string& fn_name);
398
399 bool
400 suppression_matches_function_sym_name(const suppr::function_suppression& s,
401 const string& fn_linkage_name);
402
403 bool
404 suppression_matches_variable_name(const suppr::variable_suppression& s,
405 const string& var_name);
406
407
408 bool
409 suppression_matches_variable_sym_name(const suppr::variable_suppression& s,
410 const string& var_linkage_name);
411
412 /// Test if a given function denoted by its name and linkage name is
413 /// suppressed by any of the suppression specifications associated to
414 /// a given read context used to build the current internal
415 /// representation of ABI corpus.
416 ///
417 /// @param ctxt the reading context of interest.
418 ///
419 /// @param fn_name the name of the function that a specification can
420 /// match.
421 ///
422 /// @param fn_linkage_name the linkage name of the function that a
423 /// specification can match.
424 ///
425 /// @param require_drop_property if set to "true", tests if the
426 /// function is suppressed and if its representation is dropped from
427 /// the ABI corpus being built. Otherwise, if set to "false", only
428 /// test if the function is suppressed.
429 ///
430 /// @return true iff at least one function specification matches a
431 /// function with name @p fn_name or with linkage name @p
432 /// fn_linkage_name.
433 template <typename ReadContextType>
434 bool
435 function_is_suppressed(const ReadContextType& ctxt,
436 const string& fn_name,
437 const string& fn_linkage_name,
438 bool require_drop_property = false)
439 {
440 for (suppr::suppressions_type::const_iterator i =
441 ctxt.get_suppressions().begin();
442 i != ctxt.get_suppressions().end();
443 ++i)
444 if (suppr::function_suppression_sptr suppr = is_function_suppression(*i))
445 {
446 if (require_drop_property && !(*i)->get_drops_artifact_from_ir())
447 continue;
448 if (!fn_name.empty()
449 && ctxt.suppression_matches_function_name(*suppr, fn_name))
450 return true;
451 if (!fn_linkage_name.empty()
452 && ctxt.suppression_matches_function_sym_name(*suppr,
453 fn_linkage_name))
454 return true;
455 }
456 return false;
457 }
458 // </function_suppression stuff>
459
460 // <variable_suppression stuff>
461 /// The type of the private data of the @ref variable_suppression
462 /// type.
463 struct variable_suppression::priv
464 {
465 friend class variable_suppression;
466
467 change_kind change_kind_;
468 string name_;
469 string name_regex_str_;
470 mutable regex::regex_t_sptr name_regex_;
471 string name_not_regex_str_;
472 mutable regex::regex_t_sptr name_not_regex_;
473 string symbol_name_;
474 string symbol_name_regex_str_;
475 mutable regex::regex_t_sptr symbol_name_regex_;
476 string symbol_name_not_regex_str_;
477 mutable regex::regex_t_sptr symbol_name_not_regex_;
478 string symbol_version_;
479 string symbol_version_regex_str_;
480 mutable regex::regex_t_sptr symbol_version_regex_;
481 string type_name_;
482 string type_name_regex_str_;
483 mutable regex::regex_t_sptr type_name_regex_;
484
privpriv485 priv(const string& name,
486 const string& name_regex_str,
487 const string& symbol_name,
488 const string& symbol_name_regex_str,
489 const string& symbol_version,
490 const string& symbol_version_regex_str,
491 const string& type_name,
492 const string& type_name_regex_str)
493 : change_kind_(ALL_CHANGE_KIND),
494 name_(name),
495 name_regex_str_(name_regex_str),
496 symbol_name_(symbol_name),
497 symbol_name_regex_str_(symbol_name_regex_str),
498 symbol_version_(symbol_version),
499 symbol_version_regex_str_(symbol_version_regex_str),
500 type_name_(type_name),
501 type_name_regex_str_(type_name_regex_str)
502 {}
503
504 /// Getter for a pointer to a regular expression object built from
505 /// the regular expression string
506 /// variable_suppression::priv::name_regex_str_.
507 ///
508 /// If that string is empty, then an empty regular expression object
509 /// pointer is returned.
510 ///
511 /// @return a pointer to the regular expression object of
512 /// variable_suppression::priv::name_regex_str_.
513 const regex::regex_t_sptr
get_name_regexpriv514 get_name_regex() const
515 {
516 if (!name_regex_ && !name_regex_str_.empty())
517 name_regex_ = regex::compile(name_regex_str_);
518 return name_regex_;
519 }
520
521 /// Getter for a pointer to a regular expression object built from
522 /// the regular expression string
523 /// variable_suppression::priv::name_not_regex_str_.
524 ///
525 /// If that string is empty, then an empty regular expression object
526 /// pointer is returned.
527 ///
528 /// @return a pointer to the regular expression object of
529 /// variable_suppression::priv::name_not_regex_str_..
530 const regex::regex_t_sptr
get_name_not_regexpriv531 get_name_not_regex() const
532 {
533 if (!name_not_regex_ && !name_not_regex_str_.empty())
534 name_not_regex_ = regex::compile(name_not_regex_str_);
535 return name_not_regex_;
536 }
537
538 /// Getter for a pointer to a regular expression object built from
539 /// the regular expression string
540 /// variable_suppression::priv::symbol_name_regex_str_.
541 ///
542 /// If that string is empty, then an empty regular expression object
543 /// pointer is returned.
544 ///
545 /// @return a pointer to the regular expression object of
546 /// variable_suppression::priv::symbol_name_regex_str_.
547 const regex::regex_t_sptr
get_symbol_name_regexpriv548 get_symbol_name_regex() const
549 {
550 if (!symbol_name_regex_ && !symbol_name_regex_str_.empty())
551 symbol_name_regex_ = regex::compile(symbol_name_regex_str_);
552 return symbol_name_regex_;
553 }
554
555 /// Getter for a pointer to a regular expression object built from
556 /// the regular expression string
557 /// variable_suppression::priv::symbol_name_not_regex_str_.
558 ///
559 /// If that string is empty, then an empty regular expression object
560 /// pointer is returned.
561 ///
562 /// @return a pointer to the regular expression object of
563 /// variable_suppression::priv::symbol_name_not_regex_str_.
564 const regex::regex_t_sptr
get_symbol_name_not_regexpriv565 get_symbol_name_not_regex() const
566 {
567 if (!symbol_name_not_regex_ && !symbol_name_not_regex_str_.empty())
568 symbol_name_not_regex_ = regex::compile(symbol_name_not_regex_str_);
569 return symbol_name_not_regex_;
570 }
571
572 /// Getter for a pointer to a regular expression object built from
573 /// the regular expression string
574 /// variable_suppression::priv::symbol_version_regex_str_.
575 ///
576 /// If that string is empty, then an empty regular expression object
577 /// pointer is returned.
578 ///
579 /// @return a pointer to the regular expression object of
580 /// variable_suppression::priv::symbol_version_regex_str_.
581 const regex::regex_t_sptr
get_symbol_version_regexpriv582 get_symbol_version_regex() const
583 {
584 if (!symbol_version_regex_ && !symbol_version_regex_str_.empty())
585 symbol_version_regex_ = regex::compile(symbol_version_regex_str_);
586 return symbol_version_regex_;
587 }
588
589 /// Getter for a pointer to a regular expression object built from
590 /// the regular expression string
591 /// variable_suppression::priv::type_name_regex_str_.
592 ///
593 /// If that string is empty, then an empty regular expression object
594 /// pointer is returned.
595 ///
596 /// @return a pointer to the regular expression object of
597 /// variable_suppression::priv::type_name_regex_str_.
598 const regex::regex_t_sptr
get_type_name_regexpriv599 get_type_name_regex() const
600 {
601 if (!type_name_regex_ && !type_name_regex_str_.empty())
602 type_name_regex_ = regex::compile(type_name_regex_str_);
603 return type_name_regex_;
604 }
605 };// end class variable_supppression::priv
606
607 template <typename ReadContextType>
608 bool
609 variable_is_suppressed(const ReadContextType& ctxt,
610 const string& var_name,
611 const string& var_linkage_name,
612 bool require_drop_property = false)
613 {
614 for (suppr::suppressions_type::const_iterator i =
615 ctxt.get_suppressions().begin();
616 i != ctxt.get_suppressions().end();
617 ++i)
618 if (suppr::variable_suppression_sptr suppr = is_variable_suppression(*i))
619 {
620 if (require_drop_property && !(*i)->get_drops_artifact_from_ir())
621 continue;
622 if (!var_name.empty()
623 && ctxt.suppression_matches_variable_name(*suppr, var_name))
624 return true;
625 if (!var_linkage_name.empty()
626 && ctxt.suppression_matches_variable_sym_name(*suppr,
627 var_linkage_name))
628 return true;
629 }
630 return false;
631 }
632
633 // </variable_suppression stuff>
634
635 // <type_suppression stuff>
636 /// The private data for @ref type_suppression.
637 class type_suppression::priv
638 {
639 string type_name_regex_str_;
640 mutable regex::regex_t_sptr type_name_regex_;
641 string type_name_;
642 string type_name_not_regex_str_;
643 mutable regex::regex_t_sptr type_name_not_regex_;
644 bool consider_type_kind_;
645 type_suppression::type_kind type_kind_;
646 bool consider_reach_kind_;
647 type_suppression::reach_kind reach_kind_;
648 type_suppression::insertion_ranges insertion_ranges_;
649 unordered_set<string> source_locations_to_keep_;
650 string source_location_to_keep_regex_str_;
651 mutable regex::regex_t_sptr source_location_to_keep_regex_;
652 mutable vector<string> changed_enumerator_names_;
653
654 priv();
655
656 public:
priv(const string & type_name_regexp,const string & type_name,bool consider_type_kind,type_suppression::type_kind type_kind,bool consider_reach_kind,type_suppression::reach_kind reach_kind)657 priv(const string& type_name_regexp,
658 const string& type_name,
659 bool consider_type_kind,
660 type_suppression::type_kind type_kind,
661 bool consider_reach_kind,
662 type_suppression::reach_kind reach_kind)
663 : type_name_regex_str_(type_name_regexp),
664 type_name_(type_name),
665 consider_type_kind_(consider_type_kind),
666 type_kind_(type_kind),
667 consider_reach_kind_(consider_reach_kind),
668 reach_kind_(reach_kind)
669 {}
670
671 /// Get the regular expression object associated to the 'type_name_regex'
672 /// property of @ref type_suppression.
673 ///
674 /// If the regular expression object is not created, this method
675 /// creates it and returns it.
676 ///
677 /// If the 'type_name_regex' property of @ref type_suppression is
678 /// empty then this method returns nil.
679 const regex::regex_t_sptr
get_type_name_regex()680 get_type_name_regex() const
681 {
682 if (!type_name_regex_ && !type_name_regex_str_.empty())
683 type_name_regex_ = regex::compile(type_name_regex_str_);
684 return type_name_regex_;
685 }
686
687 /// Setter for the type_name_regex object.
688 ///
689 /// @param r the new type_name_regex object.
690 void
set_type_name_regex(regex::regex_t_sptr r)691 set_type_name_regex(regex::regex_t_sptr r)
692 {type_name_regex_ = r;}
693
694 /// Get the regular expression object associated to the
695 /// 'type_name_not_regex' property of @ref type_suppression.
696 ///
697 /// If the regular expression object is not created, this method
698 /// creates it and returns it.
699 ///
700 /// If the 'type_name_not_regex' property of @ref type_suppression is
701 /// empty then this method returns nil.
702 const regex::regex_t_sptr
get_type_name_not_regex()703 get_type_name_not_regex() const
704 {
705 if (!type_name_not_regex_ && !type_name_not_regex_str_.empty())
706 type_name_not_regex_ = regex::compile(type_name_not_regex_str_);
707 return type_name_not_regex_;
708 }
709
710 /// Setter for the type_name_not_regex object.
711 ///
712 /// @param r the new type_name_not_regex object.
713 void
set_type_name_not_regex(regex::regex_t_sptr r)714 set_type_name_not_regex(regex::regex_t_sptr r)
715 {type_name_not_regex_ = r;}
716
717 /// Getter for the string that denotes the 'type_name_not_regex'
718 /// property.
719 ///
720 /// @return the value of the string value of the
721 /// 'type_name_not_regex' property.
722 const string&
get_type_name_not_regex_str()723 get_type_name_not_regex_str() const
724 {return type_name_not_regex_str_;}
725
726 /// Setter for the string that denotes the 'type_name_not_regex'
727 /// property.
728 ///
729 /// @return the value of the string value of the
730 /// 'type_name_not_regex' property.
731 void
set_type_name_not_regex_str(const string regex_str)732 set_type_name_not_regex_str(const string regex_str)
733 {type_name_not_regex_str_ = regex_str;}
734
735 /// Getter for the source_location_to_keep_regex object.
736 ///
737 /// This function builds the regex if it's not yet built.
738 const regex::regex_t_sptr
get_source_location_to_keep_regex()739 get_source_location_to_keep_regex() const
740 {
741 if (!source_location_to_keep_regex_
742 && !source_location_to_keep_regex_str_.empty())
743 source_location_to_keep_regex_ =
744 regex::compile(source_location_to_keep_regex_str_);
745 return source_location_to_keep_regex_;
746 }
747
748 /// Setter for the source_location_to_keep_regex object.
749 ///
750 /// @param r the new regex object.
751 void
set_source_location_to_keep_regex(regex::regex_t_sptr r)752 set_source_location_to_keep_regex(regex::regex_t_sptr r)
753 {source_location_to_keep_regex_ = r;}
754
755 friend class type_suppression;
756 }; // class type_suppression::priv
757
758 bool
759 suppression_matches_type_name(const suppr::type_suppression& s,
760 const string& type_name);
761
762 bool
763 suppression_matches_type_name(const suppr::type_suppression& s,
764 const scope_decl* scope,
765 const type_base_sptr& type);
766
767 bool
768 suppression_matches_type_location(const type_suppression& s,
769 const location& loc);
770
771 bool
772 suppression_matches_type_location(const type_suppression& s,
773 const type_base_sptr& type);
774
775 bool
776 suppression_matches_type_name_or_location(const type_suppression& s,
777 const string& type_name,
778 const location& type_location);
779
780 /// Test if a type (designated by its name and location) is suppressed
781 /// by at least one suppression specification associated with a given
782 /// read context.
783 ///
784 /// @param ctxt the read context to consider.
785 ///
786 /// @param type_name the name of the type to consider.
787 ///
788 /// @param type_location the location of the type to consider.
789 ///
790 /// @param require_drop_property if set to "true", tests if the type
791 /// is suppressed and if its representation is dropped from the ABI
792 /// corpus being built. Otherwise, if set to "false", only test if
793 /// the type is suppressed.
794 ///
795 /// @return true iff at least one type specification matches a type
796 /// with name @p type_name and with location @p type_location.
797 template <typename ReadContextType>
798 bool
type_is_suppressed(const ReadContextType & ctxt,const string & type_name,const location & type_location)799 type_is_suppressed(const ReadContextType& ctxt,
800 const string& type_name,
801 const location& type_location)
802 {
803 bool type_is_private = false;
804 return type_is_suppressed(ctxt, type_name, type_location, type_is_private);
805 }
806
807 /// Test if a type (designated by its name and location) is suppressed
808 /// by at least one suppression specification associated with a given
809 /// read context.
810 ///
811 /// @param ctxt the read context to consider.
812 ///
813 /// @param type_name the name of the type to consider.
814 ///
815 /// @param type_location the location of the type to consider.
816 ///
817 /// @param type_is_private out parameter. If the type is suppressed
818 /// because it's private then this out parameter is set to true.
819 ///
820 /// @param require_drop_property if set to "true", tests if the type
821 /// is suppressed and if its representation is dropped from the ABI
822 /// corpus being built. Otherwise, if set to "false", only test if
823 /// the type is suppressed.
824 ///
825 /// @return true iff at least one type specification matches a type
826 /// with name @p type_name and with location @p type_location.
827 template <typename ReadContextType>
828 bool
829 type_is_suppressed(const ReadContextType& ctxt,
830 const string& type_name,
831 const location& type_location,
832 bool& type_is_private,
833 bool require_drop_property = false)
834 {
835 for (suppr::suppressions_type::const_iterator i =
836 ctxt.get_suppressions().begin();
837 i != ctxt.get_suppressions().end();
838 ++i)
839 if (suppr::type_suppression_sptr suppr = is_type_suppression(*i))
840 {
841 if (require_drop_property && !(*i)->get_drops_artifact_from_ir())
842 continue;
843 if (ctxt.suppression_matches_type_name_or_location(*suppr, type_name,
844 type_location))
845 {
846 if (is_private_type_suppr_spec(*suppr))
847 type_is_private = true;
848
849 return true;
850 }
851 }
852
853 type_is_private = false;
854 return false;
855 }
856
857 /// Test if a given ELF symbol is suppressed by a suppression
858 /// specification.
859 ///
860 /// @param ctxt the read context to use.
861 ///
862 /// @param sym_name the name of the symbol to consider.
863 ///
864 /// @param sym_type the type of the symbol to consider.
865 ///
866 /// @return true iff the elf symbol denoted by @p sym_name and @p
867 /// sym_type is suppressed.
868 template<typename ReadContextType>
869 bool
is_elf_symbol_suppressed(const ReadContextType & ctxt,const string & sym_name,elf_symbol::type sym_type)870 is_elf_symbol_suppressed(const ReadContextType& ctxt,
871 const string& sym_name,
872 elf_symbol::type sym_type)
873 {
874 if (elf_symbol_is_function(sym_type))
875 return suppr::function_is_suppressed(ctxt, /*fn_name=*/"",
876 /*symbol_name=*/sym_name);
877 else if (elf_symbol_is_variable(sym_type))
878 return suppr::variable_is_suppressed(ctxt, /*var_name=*/"",
879 /*symbol_name=*/sym_name);
880
881 return false;
882 }
883
884 // </type_suppression stuff>
885
886 }// end namespace suppr
887 } // end namespace abigail
888
889 #endif // __ABG_SUPPRESSION_PRIV_H__
890