libabigail
Loading...
Searching...
No Matches
abg-ir.cc
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -*-
2// -*- Mode: C++ -*-
3//
4// Copyright (C) 2013-2026 Red Hat, Inc.
5//
6//Author: Dodji Seketeli
7
8/// @file
9///
10/// Definitions for the Internal Representation artifacts of libabigail.
11
12#include <cxxabi.h>
13#include <cstdint>
14#include <functional>
15#include <iterator>
16#include <memory>
17#include <sstream>
18#include <typeinfo>
19#include <unordered_map>
20#include <utility>
21#include <vector>
22#include <atomic>
23#include <mutex>
24
25#include "abg-internal.h"
26// <headers defining libabigail's API go under here>
27ABG_BEGIN_EXPORT_DECLARATIONS
28
29#include "abg-interned-str.h"
30#include "abg-ir.h"
31#include "abg-corpus.h"
32#include "abg-regex.h"
33
34ABG_END_EXPORT_DECLARATIONS
35// </headers defining libabigail's API>
36
37#include "abg-corpus-priv.h"
38#include "abg-comp-filter.h"
39#include "abg-ir-priv.h"
40
41namespace
42{
43/// This internal type is a tree walking that is used to set the
44/// qualified name of a tree of decls and types. It used by the
45/// function update_qualified_name().
46class qualified_name_setter : public abigail::ir::ir_node_visitor
47{
48
49public:
50 bool
51 do_update(abigail::ir::decl_base* d);
52
53 bool
54 visit_begin(abigail::ir::decl_base* d);
55
56 bool
57 visit_begin(abigail::ir::type_base* d);
58}; // end class qualified_name_setter
59
60}// end anon namespace
61
62namespace abigail
63{
64
65// Inject.
66using std::string;
67using std::list;
68using std::vector;
69using std::unordered_map;
70using std::dynamic_pointer_cast;
71using std::static_pointer_cast;
72using std::mutex;
73using std::recursive_mutex;
74using std::atomic;
75using std::unique_ptr;
76
77using namespace abg_compat::views;
78
79/// Convenience typedef for a map of string -> string*.
80typedef unordered_map<string, string*> pool_map_type;
81
82/// The type of the private data structure of type @ref
83/// intered_string_pool.
84struct interned_string_pool::priv
85{
86 mutex mutex_;
87 pool_map_type map;
88}; //end struc struct interned_string_pool::priv
89
90/// Default constructor.
92 : priv_(new priv)
93{
94 lock_guard<mutex> lock(priv_->mutex_);
95 priv_->map[""] = 0;
96}
97
98/// Test if the interned string pool already contains a string with a
99/// given value.
100///
101/// @param s the string to test for.
102///
103/// @return true if the pool contains a string with the value @p s.
104bool
106{
107 lock_guard<mutex> lock(priv_->mutex_);
108 return priv_->map.find(s) != priv_->map.end();
109}
110
111/// Get a pointer to the interned string which has a given value.
112///
113/// @param s the value of the interned string to look for.
114///
115/// @return a pointer to the raw string of characters which has the
116/// value of @p s. Or null if no string with value @p s was interned.
117const char*
119{
120 lock_guard<mutex> lock(priv_->mutex_);
121 unordered_map<string, string*>::const_iterator i =
122 priv_->map.find(s);
123 if (i == priv_->map.end())
124 return 0;
125 if (i->second)
126 return i->second->c_str();
127 return "";
128}
129
130/// Create an interned string with a given value.
131///
132/// @param str_value the value of the interned string to create.
133///
134/// @return the new created instance of @ref interned_string created.
136interned_string_pool::create_string(const std::string& str_value)
137{
138 lock_guard<mutex> lock(priv_->mutex_);
139 string*& result = priv_->map[str_value];
140 if (!result && !str_value.empty())
141 result = new string(str_value);
142 interned_string s(result);
143 return s;
144}
145
147interned_string_pool::create_string() const
148{
149 string* result = nullptr;
150 interned_string s(result);
151 return s;
152}
153
154/// Destructor.
156{
157 lock_guard<mutex> lock(priv_->mutex_);
158 for (pool_map_type::iterator i = priv_->map.begin();
159 i != priv_->map.end();
160 ++i)
161 if (i->second)
162 delete i->second;
163}
164
165
166struct interned_string::priv
167{
168 atomic<string*> raw;
169 mutex m;
170
171 priv(string* r)
172 : raw(r)
173 {}
174
175 priv()
176 : raw(nullptr)
177 {}
178
179}; //end struct interned_string::priv
180
181/// Constructor.
182///
183/// @param raw the pointer to string that this interned_string
184/// wraps.
185interned_string::interned_string(string* raw)
186 : priv_(new priv(raw))
187{
188}
189
190interned_string::interned_string()
191 : priv_(new priv)
192{
193}
194
195interned_string::~interned_string()
196{
197}
198
199/// Copy constructor.
200///
201/// @param o the other instance to copy from.
202interned_string::interned_string(const interned_string& o)
203 : priv_(new priv(o.priv_->raw.load()))
204{
205}
206
207/// Assignment operator.
208///
209/// @param o the other instance to assign to the current one.
212{
213 lock_guard<mutex> lock(priv_->m);
214 priv_->raw = o.priv_->raw.load();
215
216 return *this;
217}
218
219/// Clear the string.
220void
222{
223 lock_guard<mutex> lock(priv_->m);
224 priv_->raw = nullptr;
225}
226
227/// Test if the current instance of @ref interned_string is empty.
228///
229/// @return true iff the currentisntance of @ref interned_string is
230/// empty.
231bool
233{
234 lock_guard<mutex> lock(priv_->m);
235 return !raw() || raw()->empty();
236}
237
238/// Return the underlying pointer to std::string that this
239/// interned_string wraps.
240///
241/// @return a pointer to the underlying std::string, or 0 if this
242/// interned_string is empty.
243const string*
245{
246 return priv_->raw;
247}
248
249/// Compare the current instance of @ref interned_string against
250/// another instance of @ref interned_string.
251///
252/// Note that this comparison is done in O(1), because it compares
253/// the pointer values of the two underlying pointers to std::string
254/// held by each instances of @ref interned_string.
255///
256/// @param o the other @ref interned_string to compare against.
257///
258/// @return true iff the current instance equals @p o.
259bool
261{
262 return priv_->raw == o.priv_->raw.load();
263}
264
265/// Inequality operator.
266///
267/// @param o the other @ref interned_string to compare the current
268/// instance against.
269///
270/// @return true iff the current instance is different from the @p
271/// o.
272bool
275
276/// Compare the current instance of @ref interned_string against
277/// an instance of std::string.
278///
279/// Note that this comparison is done in O(N), N being the size (in
280/// number of characters) of the strings being compared.
281///
282/// @param o the instance of std::string to compare against.
283///
284/// @return true iff the current instance equals @p o.
285bool
286interned_string::operator==(const string& o) const
287{
288 if (priv_->raw)
289 return *priv_->raw == o;
290 return o.empty();
291}
292
293/// Inequality operator.
294///
295/// Takes the current instance of @ref interned_string and an
296/// instance of std::string.
297///
298/// @param o the instance of std::string to compare the current
299/// instance of @ref interned_string against.
300///
301/// @return true if the current instance of @ref interned_string is
302/// different from @p o.
303bool
304interned_string::operator!=(const string& o) const
305{return ! operator==(o);}
306
307/// "Less than" operator.
308///
309/// Lexicographically compares the current instance of @ref
310/// interned_string against another instance.
311///
312/// @param o the other instance of @ref interned_string to compare
313/// against.
314///
315/// @return true iff the current instance of interned_string is
316/// lexicographycally less than the string @p o.
317bool
319{return static_cast<string>(*this) < static_cast<std::string>(o);}
320
321/// Conversion operator to string.
322///
323/// @return the underlying string this instance refers too.
324interned_string::operator string() const
325{
326 if (!priv_->raw)
327 return "";
328 return *priv_->raw;
329}
330
331/// Equality operator.
332///
333/// @param l the instance of std::string on the left-hand-side of the
334/// equality operator.
335///
336/// @param r the instance of @ref interned_string on the
337/// right-hand-side of the equality operator.
338///
339/// @return true iff the two string are equal.
340bool
341operator==(const std::string& l, const interned_string& r)
342{return r.operator==(l);}
343
344bool
345operator!=(const std::string& l, const interned_string& r)
346{return !(l == r);}
347
348/// Streaming operator.
349///
350/// Streams an instance of @ref interned_string to an output stream.
351///
352/// @param o the destination output stream.
353///
354/// @param s the instance of @ref interned_string to stream out.
355///
356/// @return the output stream this function just streamed to.
357std::ostream&
358operator<<(std::ostream& o, const interned_string& s)
359{
360 o << static_cast<std::string>(s);
361 return o;
362}
363
364/// Concatenation operator.
365///
366/// Concatenate two instances of @ref interned_string, builds an
367/// instance of std::string with the resulting string and return it.
368///
369/// @param s1 the first string to consider.
370///
371/// @param s2 the second string to consider.
372///
373/// @return the resuting concatenated string.
374std::string
375operator+(const interned_string& s1,const std::string& s2)
376{return static_cast<std::string>(s1) + s2;}
377
378/// Concatenation operator.
379///
380/// Concatenate two instances of @ref interned_string, builds an
381/// instance of std::string with the resulting string and return it.
382///
383/// @param s1 the first string to consider.
384///
385/// @param s2 the second string to consider.
386///
387/// @return the resuting concatenated string.
388std::string
389operator+(const std::string& s1, const interned_string& s2)
390{return s1 + static_cast<std::string>(s2);}
391
392namespace ir
393{
394
395static size_t
396hash_as_canonical_type_or_constant(const type_base *t);
397
398static bool
399has_generic_anonymous_internal_type_name(const decl_base *d);
400
401static interned_string
402get_generic_anonymous_internal_type_name(const decl_base *d);
403
404static string
405get_internal_real_type_name(const type_base*);
406
407static void
408update_qualified_name(decl_base * d);
409
410static void
411update_qualified_name(decl_base_sptr d);
412
413static interned_string
414pointer_declaration_name(const type_base* ptr,
415 const string& variable_name,
416 bool qualified, bool internal);
417
418static interned_string
419pointer_declaration_name(const type_base_sptr& ptr,
420 const string& variable_name,
421 bool qualified, bool internal);
422
423static interned_string
424ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
425 const string& variable_name,
426 bool qualified, bool internal);
427
428static interned_string
429ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
430 const string& variable_name,
431 bool qualified, bool internal);
432
433static interned_string
434array_declaration_name(const array_type_def* array,
435 const string& variable_name,
436 bool qualified, bool internal);
437
438static interned_string
439array_declaration_name(const array_type_def_sptr& array,
440 const string& variable_name,
441 bool qualified, bool internal);
442
443static void
444stream_pretty_representation_of_fn_parms(const function_type& fn_type,
445 ostream& o, bool qualified,
446 bool internal);
447static string
448add_outer_pointer_to_fn_type_expr(const type_base* pointer_to_fn,
449 const string& input, bool qualified,
450 bool internal);
451
452static string
453add_outer_pointer_to_fn_type_expr(const type_base_sptr& pointer_to_fn,
454 const string& input, bool qualified,
455 bool internal);
456
457static string
458add_outer_pointer_to_array_type_expr(const type_base* pointer_to_ar,
459 const string& input, bool qualified,
460 bool internal);
461
462static string
463add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
464 const string& input, bool qualified,
465 bool internal);
466
467static string
468add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
469 const string& input, bool qualified,
470 bool internal);
471
472static string
473add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
474 const string& input, bool qualified,
475 bool internal);
476
477static string
478add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
479 const string& input,
480 bool qualified, bool internal);
481
482template <typename TypeArtifact>
483void
484maybe_update_types_lookup_map(const shared_ptr<TypeArtifact> type);
485
486/// Getter of the canonical type index of a given type.
487///
488/// @param t the type to consider.
489///
490/// @return the CTI of the type.
491size_t
493{return t.priv_->canonical_type_index;}
494
495/// Getter of the canonical type index of a given type.
496///
497/// @param t the type to consider.
498///
499/// @return the CTI of the type.
500size_t
503
504/// Getter of the canonical type index of a given type.
505///
506/// @param t the type to consider.
507///
508/// @return the CTI of the type.
509size_t
510get_canonical_type_index(const type_base_sptr& t)
511{return get_canonical_type_index(t.get());}
512
513/// Test if a type originates from a corpus.
514///
515/// Note that this function supports testing if a type originates from
516/// a corpus group.
517///
518/// @param t the type to consider.
519///
520/// @param c the corpus or corpus group to consider.
521///
522/// @return true iff the type @p t originates from the corpus (or
523/// group) @p c.
524bool
525type_originates_from_corpus(type_base_sptr t, corpus_sptr& c)
526{
527 bool result = false;
528 if (c && t->get_corpus())
529 {
530 corpus_group_sptr g = is_corpus_group(c);
531 if (g)
532 {
533 if (t->get_corpus()->get_group() == g.get())
534 result = true;
535 }
536 else
537 {
538 if (t->get_corpus() == c.get())
539 result = true;
540 }
541 }
542 return result;
543}
544
545/// @brief the location of a token represented in its simplest form.
546/// Instances of this type are to be stored in a sorted vector, so the
547/// type must have proper relational operators.
548class expanded_location
549{
550 string path_;
551 unsigned line_;
552 unsigned column_;
553
554 expanded_location();
555
556public:
557
558 friend class location_manager;
559
560 expanded_location(const string& path, unsigned line, unsigned column)
561 : path_(path), line_(line), column_(column)
562 {}
563
564 bool
565 operator==(const expanded_location& l) const
566 {
567 return (path_ == l.path_
568 && line_ == l.line_
569 && column_ && l.column_);
570 }
571
572 bool
573 operator<(const expanded_location& l) const
574 {
575 if (path_ < l.path_)
576 return true;
577 else if (path_ > l.path_)
578 return false;
579
580 if (line_ < l.line_)
581 return true;
582 else if (line_ > l.line_)
583 return false;
584
585 return column_ < l.column_;
586 }
587};
588
589struct location::priv
590{
591 std::atomic<unsigned> value_;
592 // The location manager to use to decode the value above. There is
593 // one location manager per translation unit, and the location
594 // manager's life time is managed by its translation unit.
595 std::atomic<location_manager*> loc_manager_;
596 // Whether the location is artificial, and if non-zero, the value of
597 // the artificial location. Being artificial means that the
598 // location wasn't generated by the original emitter of the metadata
599 // (i.e, the compiler if the metadata is debug info). For instance,
600 // implicit location derived from the position of XML elements in
601 // the abixml file is represented as artificial locations.
602 std::atomic<size_t> artificial_location_;
603
604 priv()
605 : value_(),
606 loc_manager_(nullptr),
607 artificial_location_()
608 {}
609
610 priv(unsigned v, location_manager* m)
611 : value_(v),
612 loc_manager_(m),
613 artificial_location_()
614 {}
615}; // end struct location::priv
616
617location::~location()
618{
619}
620
621location::location(unsigned v, location_manager* m)
622 : priv_(new priv(v, m))
623{}
624
625/// Get the location manager to use to decode the value of this
626/// location.
627///
628/// @return the location manager for the current location value.
629location_manager*
630location::get_location_manager() const
631{return priv_->loc_manager_;}
632
633/// Test if the location is artificial.
634///
635/// Being artificial means that the location wasn't generated by the
636/// original emitter of the metadata (i.e, the compiler if the
637/// metadata is debug info). For instance, the implicit location
638/// derived from the position of a given XML element in the abixml
639/// file is represented as artificial locations. The same XML
640/// element might carry a non-artificial (natural?) location that was
641/// originally emitted by the compiler that generated the original
642/// debug info the abixml file is derived from.
643///
644/// @return true iff the location is artificial.
645bool
647{return !!get_artificial_value();}
648
649size_t
650location::get_artificial_value() const
651{return priv_->artificial_location_;}
652
653/// Set the artificial-ness of the location.
654///
655/// Being artificial means that the location wasn't generated by the
656/// original emitter of the metadata (i.e, the compiler if the
657/// metadata is debug info). For instance, the implicit location
658/// derived from the position of a given XML element in the abixml
659/// file is represented as artificial locations. The same XML
660/// element might carry a non-artificial (natural?) location that
661/// was originally emitted by the compiler that generated the
662/// original debug info the abixml file is derived from.
663///
664/// @param f the new artificial-ness state, and if non-zero,
665/// represents the valueof the artificial location.
666void
668{priv_->artificial_location_ = l;}
669
670/// Copy constructor of the location.
671///
672/// @param l the location to copy from.
674 : priv_(new priv(l.priv_->value_, l.priv_->loc_manager_))
675{
676 priv_->artificial_location_.store(l.priv_->artificial_location_);
677}
678
679/// Assignment operator of the location.
680///
681/// @param l the location to assign to the current one.
684{
685 priv_->value_.store(l.priv_->value_);
686 priv_->loc_manager_.store(l.priv_->loc_manager_);
687 priv_->artificial_location_.store(l.priv_->artificial_location_);
688 return *this;
689}
690
691/// Default constructor for the @ref location type.
693 : priv_(new priv())
694{}
695
696/// Get the value of the location.
697unsigned
699{return priv_->value_;}
700
701/// Convert the location into a boolean.
702///
703/// @return true iff the value of the location is different from
704/// zero.
705location::operator bool() const
706{return !!priv_->value_;}
707
708/// Equality operator of the @ref location type.
709///
710/// @param other the other location to compare against.
711///
712/// @return true iff both locations are equal.
713bool
715{return priv_->value_ == other.priv_->value_;}
716
717/// "Less than" operator of the @ref location type.
718///
719/// @parm other the other location type to compare against.
720///
721/// @return true iff the current instance is less than the @p other
722/// one.
723bool
724location::operator<(const location &other) const
725{return priv_->value_ < other.priv_->value_;}
726
727/// Expand the location into a tripplet path, line and column number.
728///
729/// @param path the output parameter where this function sets the
730/// expanded path.
731///
732/// @param line the output parameter where this function sets the
733/// expanded line.
734///
735/// @param column the ouptut parameter where this function sets the
736/// expanded column.
737void
738location::expand(std::string& path, unsigned& line, unsigned& column) const
739{
740 if (!get_location_manager())
741 {
742 // We don't have a location manager maybe because this location
743 // was just freshly instanciated. We still want to be able to
744 // expand to default values.
745 path = "";
746 line = 0;
747 column = 0;
748 return;
749 }
750 get_location_manager()->expand_location(*this, path, line, column);
751}
752
753
754/// Expand the location into a string.
755///
756/// @return the string representing the location.
757string
759{
760 string path, result;
761 unsigned line = 0, column = 0;
762 expand(path, line, column);
763
764 std::ostringstream o;
765 o << path << ":" << line << ":" << column;
766 return o.str();
767}
768
769struct location_manager::priv
770{
771 /// This sorted vector contains the expanded locations of the tokens
772 /// coming from a given ABI Corpus. The index of a given expanded
773 /// location in the table gives us an integer that is used to build
774 /// instance of location types.
775 std::vector<expanded_location> locs;
776 mutex locs_mutex;
777};
778
779location_manager::location_manager()
780 : priv_(new location_manager::priv)
781{}
782
783location_manager::~location_manager() = default;
784
785/// Insert the triplet representing a source locus into our internal
786/// vector of location triplet. Return an instance of location type,
787/// built from an real type that represents the index of the
788/// source locus triplet into our source locus table.
789///
790/// @param file_path the file path of the source locus
791/// @param line the line number of the source location
792/// @param col the column number of the source location
793location
794location_manager::create_new_location(const std::string& file_path,
795 size_t line,
796 size_t col)
797{
798 expanded_location l(file_path, line, col);
799
800 // Just append the new expanded location to the end of the vector
801 // and return its index. Note that indexes start at 1.
802 lock_guard<mutex> lock(priv_->locs_mutex);
803 priv_->locs.push_back(l);
804 return location(priv_->locs.size(), this);
805}
806
807/// Given an instance of location type, return the triplet
808/// {path,line,column} that represents the source locus. Note that
809/// the location must have been previously created from the function
810/// location_manager::create_new_location, otherwise this function yields
811/// unexpected results, including possibly a crash.
812///
813/// @param location the instance of location type to expand
814/// @param path the resulting path of the source locus
815/// @param line the resulting line of the source locus
816/// @param column the resulting colum of the source locus
817void
819 std::string& path,
820 unsigned& line,
821 unsigned& column) const
822{
823 if (location.priv_->value_ == 0)
824 return;
825 lock_guard<mutex> lock(priv_->locs_mutex);
826 expanded_location &l = priv_->locs[location.priv_->value_ - 1];
827 path = l.path_;
828 line = l.line_;
829 column = l.column_;
830}
831
832typedef unordered_map<function_type_sptr,
833 bool,
835 type_shared_ptr_equal> fn_type_ptr_map;
836
837// <type_maps stuff>
838
839struct type_maps::priv
840{
841 typedef unordered_map<size_t,
842 istring_type_base_wptrs_map_type*> type_map_hash_type;
843
844 mutable type_map_hash_type type_maps_hash_;
845 mutable istring_type_base_wptrs_map_type basic_types_;
846 mutable istring_type_base_wptrs_map_type class_types_;
847 mutable istring_type_base_wptrs_map_type union_types_;
848 mutable istring_type_base_wptrs_map_type enum_types_;
849 mutable istring_type_base_wptrs_map_type typedef_types_;
850 mutable istring_type_base_wptrs_map_type qualified_types_;
851 mutable istring_type_base_wptrs_map_type pointer_types_;
852 mutable istring_type_base_wptrs_map_type reference_types_;
853 mutable istring_type_base_wptrs_map_type ptr_to_mbr_types_;
854 mutable istring_type_base_wptrs_map_type array_types_;
855 mutable istring_type_base_wptrs_map_type subrange_types_;
856 mutable istring_type_base_wptrs_map_type function_types_;
857 mutable vector<type_base_wptr> sorted_types_;
858}; // end struct type_maps::priv
859
860type_maps::type_maps()
861 : priv_(new priv)
862{
863 priv_->type_maps_hash_[typeid(type_decl).hash_code()] = &priv_->basic_types_;
864 priv_->type_maps_hash_[typeid(class_decl).hash_code()] = &priv_->class_types_;
865 priv_->type_maps_hash_[typeid(union_decl).hash_code()] = &priv_->union_types_;
866 priv_->type_maps_hash_[typeid(enum_type_decl).hash_code()] =
867 &priv_->enum_types_;
868 priv_->type_maps_hash_[typeid(typedef_decl).hash_code()] =
869 &priv_->typedef_types_;
870 priv_->type_maps_hash_[typeid(qualified_type_def).hash_code()] =
871 &priv_->qualified_types_;
872 priv_->type_maps_hash_[typeid(pointer_type_def).hash_code()] =
873 &priv_->pointer_types_;
874 priv_->type_maps_hash_[typeid(reference_type_def).hash_code()] =
875 &priv_->reference_types_;
876 priv_->type_maps_hash_[typeid(ptr_to_mbr_type).hash_code()] =
877 &priv_->ptr_to_mbr_types_;
878 priv_->type_maps_hash_[typeid(array_type_def).hash_code()] =
879 &priv_->array_types_;
880 priv_->type_maps_hash_[typeid(array_type_def::subrange_type).hash_code()] =
881 &priv_->subrange_types_;
882 priv_->type_maps_hash_[typeid(function_type).hash_code()] =
883 &priv_->function_types_;
884 priv_->type_maps_hash_[typeid(method_type).hash_code()] =
885 &priv_->function_types_;
886}
887
888type_maps::~type_maps() = default;
889
890/// Test if the type_maps is empty.
891///
892/// @return true iff the type_maps is empty.
893bool
895{
896 return (basic_types().empty()
897 && class_types().empty()
898 && union_types().empty()
899 && enum_types().empty()
900 && typedef_types().empty()
902 && pointer_types().empty()
904 && array_types().empty()
905 && subrange_types().empty()
906 && function_types().empty());
907}
908
909/// Getter for the map that associates the name of a basic type to the
910/// vector instances of type_decl_sptr that represents that type.
913{return priv_->basic_types_;}
914
915/// Getter for the map that associates the name of a basic type to the
916/// vector of instances of @ref type_decl_sptr that represents that
917/// type.
920{return priv_->basic_types_;}
921
922/// Getter for the map that associates the name of a class type to the
923/// vector of instances of @ref class_decl_sptr that represents that
924/// type.
927{return priv_->class_types_;}
928
929/// Getter for the map that associates the name of a class type to the
930/// vector of instances of @ref class_decl_sptr that represents that
931/// type.
934{return priv_->class_types_;}
935
936/// Getter for the map that associates the name of a union type to the
937/// vector of instances of @ref union_decl_sptr that represents that
938/// type.
941{return priv_->union_types_;}
942
943/// Getter for the map that associates the name of a union type to the
944/// vector of instances of @ref union_decl_sptr that represents that
945/// type.
948{return priv_->union_types_;}
949
950/// Getter for the map that associates the name of an enum type to the
951/// vector of instances of @ref enum_type_decl_sptr that represents
952/// that type.
955{return priv_->enum_types_;}
956
957/// Getter for the map that associates the name of an enum type to the
958/// vector of instances of @ref enum_type_decl_sptr that represents
959/// that type.
962{return priv_->enum_types_;}
963
964/// Getter for the map that associates the name of a typedef to the
965/// vector of instances of @ref typedef_decl_sptr that represents tha
966/// type.
969{return priv_->typedef_types_;}
970
971/// Getter for the map that associates the name of a typedef to the
972/// vector of instances of @ref typedef_decl_sptr that represents tha
973/// type.
976{return priv_->typedef_types_;}
977
978/// Getter for the map that associates the name of a qualified type to
979/// the vector of instances of @ref qualified_type_def_sptr.
982{return priv_->qualified_types_;}
983
984/// Getter for the map that associates the name of a qualified type to
985/// the vector of instances of @ref qualified_type_def_sptr.
988{return priv_->qualified_types_;}
989
990/// Getter for the map that associates the name of a pointer type to
991/// the vector of instances of @ref pointer_type_def_sptr that
992/// represents that type.
995{return priv_->pointer_types_;}
996
997/// Getter for the map that associates the name of a pointer-to-member
998/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
999/// represents that type.
1002{return priv_->ptr_to_mbr_types_;}
1003
1004/// Getter for the map that associates the name of a pointer-to-member
1005/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
1006/// represents that type.
1009{return priv_->ptr_to_mbr_types_;}
1010
1011/// Getter for the map that associates the name of a pointer type to
1012/// the vector of instances of @ref pointer_type_def_sptr that
1013/// represents that type.
1016{return priv_->pointer_types_;}
1017
1018/// Getter for the map that associates the name of a reference type to
1019/// the vector of instances of @ref reference_type_def_sptr that
1020/// represents that type.
1023{return priv_->reference_types_;}
1024
1025/// Getter for the map that associates the name of a reference type to
1026/// the vector of instances of @ref reference_type_def_sptr that
1027/// represents that type.
1030{return priv_->reference_types_;}
1031
1032/// Getter for the map that associates the name of an array type to
1033/// the vector of instances of @ref array_type_def_sptr that
1034/// represents that type.
1037{return priv_->array_types_;}
1038
1039/// Getter for the map that associates the name of an array type to
1040/// the vector of instances of @ref array_type_def_sptr that
1041/// represents that type.
1044{return priv_->array_types_;}
1045
1046/// Getter for the map that associates the name of a subrange type to
1047/// the vector of instances of @ref array_type_def::subrange_sptr that
1048/// represents that type.
1051{return priv_->subrange_types_;}
1052
1053/// Getter for the map that associates the name of a subrange type to
1054/// the vector of instances of @ref array_type_def::subrange_sptr that
1055/// represents that type.
1058{return priv_->subrange_types_;}
1059
1060/// Getter for the map that associates the name of a function type to
1061/// the vector of instances of @ref function_type_sptr that represents
1062/// that type.
1065{return priv_->function_types_;}
1066
1067/// Getter for the map that associates the name of a function type to
1068/// the vector of instances of @ref function_type_sptr that represents
1069/// that type.
1072{return priv_->function_types_;}
1073
1074/// A comparison functor to compare/sort types based on their pretty
1075/// representations.
1076struct type_name_comp
1077{
1078 /// Comparison operator for two instances of @ref type_base.
1079 ///
1080 /// This compares the two types by lexicographically comparing their
1081 /// pretty representation.
1082 ///
1083 /// @param l the left-most type to compare.
1084 ///
1085 /// @param r the right-most type to compare.
1086 ///
1087 /// @return true iff @p l < @p r.
1088 bool
1089 operator()(type_base *l, type_base *r) const
1090 {
1091 if (l == 0 && r == 0)
1092 return false;
1093
1094 string l_repr = get_pretty_representation(l);
1095 string r_repr = get_pretty_representation(r);
1096 return l_repr < r_repr;
1097 }
1098
1099 /// Comparison operator for two instances of @ref type_base.
1100 ///
1101 /// This compares the two types by lexicographically comparing their
1102 /// pretty representation.
1103 ///
1104 /// @param l the left-most type to compare.
1105 ///
1106 /// @param r the right-most type to compare.
1107 ///
1108 /// @return true iff @p l < @p r.
1109 bool
1110 operator()(const type_base_sptr &l, const type_base_sptr &r) const
1111 {return operator()(l.get(), r.get());}
1112
1113 /// Comparison operator for two instances of @ref type_base.
1114 ///
1115 /// This compares the two types by lexicographically comparing their
1116 /// pretty representation.
1117 ///
1118 /// @param l the left-most type to compare.
1119 ///
1120 /// @param r the right-most type to compare.
1121 ///
1122 /// @return true iff @p l < @p r.
1123 bool
1124 operator()(const type_base_wptr &l, const type_base_wptr &r) const
1125 {return operator()(type_base_sptr(l), type_base_sptr(r));}
1126}; // end struct type_name_comp
1127
1128#ifdef WITH_DEBUG_SELF_COMPARISON
1129
1130/// This is a function called when the ABG_RETURN* macros defined
1131/// below return false.
1132///
1133/// The purpose of this function is to ease debugging. To know where
1134/// the equality functions first compare non-equal, we can just set a
1135/// breakpoint on this notify_equality_failed function and run the
1136/// equality functions. Because all the equality functions use the
1137/// ABG_RETURN* macros to return their values, this function is always
1138/// called when any of those equality function return false.
1139///
1140/// @param l the first operand of the equality.
1141///
1142/// @param r the second operand of the equality.
1143static void
1144notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
1145 const type_or_decl_base &r __attribute__((unused)))
1146{}
1147
1148/// This is a function called when the ABG_RETURN* macros defined
1149/// below return false.
1150///
1151/// The purpose of this function is to ease debugging. To know where
1152/// the equality functions first compare non-equal, we can just set a
1153/// breakpoint on this notify_equality_failed function and run the
1154/// equality functions. Because all the equality functions use the
1155/// ABG_RETURN* macros to return their values, this function is always
1156/// called when any of those equality function return false.
1157///
1158/// @param l the first operand of the equality.
1159///
1160/// @param r the second operand of the equality.
1161static void
1162notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
1163 const type_or_decl_base *r __attribute__((unused)))
1164{}
1165
1166#define ABG_RETURN_EQUAL(l, r) \
1167 do \
1168 { \
1169 if (l != r) \
1170 notify_equality_failed(l, r); \
1171 return (l == r); \
1172 } \
1173 while(false)
1174
1175
1176#define ABG_RETURN_FALSE \
1177 do \
1178 { \
1179 notify_equality_failed(l, r); \
1180 return false; \
1181 } while(false)
1182
1183#define ABG_RETURN(value) \
1184 do \
1185 { \
1186 if (value == false) \
1187 notify_equality_failed(l, r); \
1188 return value; \
1189 } while (false)
1190
1191#else // WITH_DEBUG_SELF_COMPARISON
1192
1193#define ABG_RETURN_FALSE return false
1194#define ABG_RETURN(value) return (value)
1195#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
1196#endif
1197
1198/// Get the canonical type of a given type T* as a T*.
1199///
1200/// Note that normally, canonical types are returned as @ref
1201/// type_base* (un-typed form, kind of). This function returns the
1202/// canonical type as a T*, just like the T* it is looking at.
1203///
1204///
1205/// @param t the type to consider.
1206///
1207/// @return either the canonical type of @p t or @p t itself if it
1208/// doesn't have any canonical type.
1209template<typename T>
1210T*
1212{
1213 if (!t)
1214 return nullptr;
1215 if (type_base* type = t->get_naked_canonical_type())
1216 return dynamic_cast<T*>(type);
1217 return t;
1218}
1219
1220/// Compare two types by comparing their canonical types if present.
1221///
1222/// If the canonical types are not present (because the types have not
1223/// yet been canonicalized, for instance) then the types are compared
1224/// structurally.
1225///
1226/// @param l the first type to take into account in the comparison.
1227///
1228/// @param r the second type to take into account in the comparison.
1229template<typename T>
1230bool
1231try_canonical_compare(const T *l, const T *r)
1232{
1233#if WITH_DEBUG_TYPE_CANONICALIZATION
1234 // We are debugging the canonicalization of a type down the stack.
1235 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
1236 // type being canonicalized. We are at a point where we can compare
1237 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
1238 // have canonical types) or structural comparison.
1239 //
1240 // Because we are debugging the process of type canonicalization, we
1241 // want to compare 'l' and 'r' canonically *AND* structurally. Both
1242 // kinds of comparison should yield the same result, otherwise type
1243 // canonicalization just failed for the subtype 'r' of the type
1244 // being canonicalized.
1245 //
1246 // In concrete terms, this function is going to be called twice with
1247 // the same pair {'l', 'r'} to compare: The first time with
1248 // environment::priv_->use_canonical_type_comparison_ set to true,
1249 // instructing us to compare them canonically, and the second time
1250 // with that boolean set to false, instructing us to compare them
1251 // structurally.
1252 const environment&env = l->get_environment();
1253 if (env.priv_->use_canonical_type_comparison_)
1254 {
1255 if (const type_base *lc = l->get_naked_canonical_type())
1256 if (const type_base *rc = r->get_naked_canonical_type())
1257 ABG_RETURN_EQUAL(lc, rc);
1258 }
1259
1260 // If the two types have a non-empty hash value, then consider those
1261 // hash values. If the hashes are different then the two types are
1262 // different. If the hashes are equal then we'll compare then
1263 // structurally.
1264 if (hash_t l_hash = peek_hash_value(*l))
1265 if (hash_t r_hash = peek_hash_value(*r))
1266 if (l_hash != r_hash)
1267 ABG_RETURN_FALSE;
1268
1269 // If a type has a canonical type, use its canonical type, always.
1272
1273 return equals(*l, *r, 0);
1274#else
1275 if (const type_base *lc = l->get_naked_canonical_type())
1276 if (const type_base *rc = r->get_naked_canonical_type())
1277 ABG_RETURN_EQUAL(lc, rc);
1278
1279 // If the two types have a non-empty hash value, then consider those
1280 // hash values. If the hashes are different then the two types are
1281 // different. If the hashes are equal then we'll compare then
1282 // structurally.
1283 if (hash_t l_hash = peek_hash_value(*l))
1284 if (hash_t r_hash = peek_hash_value(*r))
1285 if (l_hash != r_hash)
1286 ABG_RETURN_FALSE;
1287
1288 // If a type has a canonical type, use its canonical type, always.
1291
1292 return equals(*l, *r, 0);
1293#endif
1294}
1295
1296thread_local class_set_type class_or_union::priv::left_classes_being_compared_;
1297thread_local class_set_type class_or_union::priv::right_classes_being_compared_;
1298thread_local class_set_type class_or_union::priv::classes_being_printed_;
1299
1300/// Detect if a recursive comparison cycle is detected while
1301/// structurally comparing two types (a.k.a member-wise comparison).
1302///
1303/// @param l the left-hand-side operand of the current comparison.
1304///
1305/// @param r the right-hand-side operand of the current comparison.
1306///
1307/// @return true iff a comparison cycle is detected.
1308template<typename T>
1309bool
1311{
1312 bool result = l.priv_->comparison_started(l, r);
1313 return result ;
1314}
1315
1316/// Detect if a recursive comparison cycle is detected while
1317/// structurally comparing two @ref class_decl types.
1318///
1319/// @param l the left-hand-side operand of the current comparison.
1320///
1321/// @param r the right-hand-side operand of the current comparison.
1322///
1323/// @return true iff a comparison cycle is detected.
1324template<>
1325bool
1327{
1328 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
1329 static_cast<const class_or_union&>(r));
1330}
1331
1332/// This macro is to be used while comparing composite types that
1333/// might recursively refer to themselves. Comparing two such types
1334/// might get us into a cyle.
1335///
1336/// Practically, if we detect that we are already into comparing 'l'
1337/// and 'r'; then, this is a cycle.
1338//
1339/// To break the cycle, we assume the result of the comparison is true
1340/// for now. Comparing the other sub-types of l & r will tell us later
1341/// if l & r are actually different or not.
1342///
1343/// In the mean time, returning true from this macro should not be
1344/// used to propagate the canonical type of 'l' onto 'r' as we don't
1345/// know yet if l equals r. All the types that depend on l and r
1346/// can't (and that are in the comparison stack currently) can't have
1347/// their canonical type propagated either. So this macro disallows
1348/// canonical type propagation for those types that depend on a
1349/// recursively defined sub-type for now.
1350///
1351/// @param l the left-hand-side operand of the comparison.
1352#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
1353 do \
1354 { \
1355 if (is_comparison_cycle_detected(l, r)) \
1356 return true; \
1357 } \
1358 while(false)
1359
1360
1361/// Mark a pair of types as being compared.
1362///
1363/// This is helpful to later detect recursive cycles in the comparison
1364/// stack.
1365///
1366/// @param l the left-hand-side operand of the comparison.
1367///
1368/// @parm r the right-hand-side operand of the comparison.
1369template<typename T>
1370void
1372{
1373 l.priv_->mark_as_being_compared(l, r);
1374}
1375
1376/// Mark a pair of @ref class_decl types as being compared.
1377///
1378/// This is helpful to later detect recursive cycles in the comparison
1379/// stack.
1380///
1381/// @param l the left-hand-side operand of the comparison.
1382///
1383/// @parm r the right-hand-side operand of the comparison.
1384template<>
1385void
1387{
1388 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
1389 static_cast<const class_or_union&>(r));
1390}
1391
1392/// Mark a pair of types as being not compared anymore.
1393///
1394/// This is helpful to later detect recursive cycles in the comparison
1395/// stack.
1396///
1397/// Note that the types must have been passed to
1398/// mark_types_as_being_compared prior to calling this function.
1399///
1400/// @param l the left-hand-side operand of the comparison.
1401///
1402/// @parm r the right-hand-side operand of the comparison.
1403template<typename T>
1404void
1406{
1407 l.priv_->unmark_as_being_compared(l, r);
1408}
1409
1410/// Mark a pair of @ref class_decl types as being not compared
1411/// anymore.
1412///
1413/// This is helpful to later detect recursive cycles in the comparison
1414/// stack.
1415///
1416/// Note that the types must have been passed to
1417/// mark_types_as_being_compared prior to calling this function.
1418///
1419/// @param l the left-hand-side operand of the comparison.
1420///
1421/// @parm r the right-hand-side operand of the comparison.
1422template<>
1423void
1425{
1426 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
1427 static_cast<const class_or_union&>(r));
1428}
1429
1430thread_local type_comparison_result_type environment::priv::type_comparison_results_cache_;
1431thread_local bool environment::priv::allow_type_comparison_results_caching_ = false;
1432std::atomic<size_t> environment::priv::number_of_threads_to_use_
1434
1435/// Process a thread pool size string and convert it to a numeric value.
1436///
1437/// The string can be either an absolute number of threads or a
1438/// percentage of available threads (indicated by a trailing '%').
1439///
1440/// @param tps the thread pool size string to process. If empty, the
1441/// default value (number of available threads) is returned.
1442///
1443/// @return the computed thread pool size. If @p tps is a percentage,
1444/// returns that percentage of available threads. If @p tps is an
1445/// absolute value, returns that value directly. If @p tps is empty,
1446/// returns the number of available threads.
1447size_t
1450
1451/// Compute the number of threads to use by looking at if
1452/// multithreading is enabled in libabigail at all. Then look at the
1453/// underlying hardware concurrency. Then, look at the value of the
1454/// environment variable ABIGAIL_THREAD_POOL_SIZE.
1455size_t
1457{
1458 size_t initial_value = workers::get_number_of_available_threads();
1459 size_t computed_value = initial_value;
1460
1461 if (initial_value > 1)
1462 if (const char* v = std::getenv("ABIGAIL_THREAD_POOL_SIZE"))
1463 computed_value = process_thread_pool_size_string(v);
1464
1465 return computed_value;
1466}
1467
1468/// Process a thread pool size string and convert it to a numeric value.
1469///
1470/// The string can be either an absolute number of threads or a
1471/// percentage of available threads (indicated by a trailing '%').
1472///
1473/// @param tps the thread pool size string to process. If empty, the
1474/// default value (number of available threads) is returned.
1475///
1476/// @return the computed thread pool size. If @p tps is a percentage,
1477/// returns that percentage of available threads. If @p tps is an
1478/// absolute value, returns that value directly. If @p tps is empty,
1479/// returns the number of available threads.
1480size_t
1482{
1483 size_t default_value = workers::get_number_of_available_threads();
1484 if (tps.empty())
1485 return default_value;
1486
1487 size_t result = 0;
1488 bool is_percentage = false;
1489 if (tools_utils::string_ends_with(tps, "%"))
1490 is_percentage = true;
1491
1492 if (is_percentage)
1493 {
1494 // tps is a percentage.
1495 string percentage_value;
1496 ABG_ASSERT(tools_utils::string_prefix(tps, "%", percentage_value));
1497 result = strtoull(percentage_value.c_str(), 0, 0);
1498 // The percentage of default_value.
1499 result = (default_value * result) / 100;
1500 }
1501 else
1502 // str is an absolute value.
1503 result = strtoull(tps.c_str(), 0, 0);
1504
1505 if (result == 0)
1506 result = default_value;
1507
1508 return result;
1509}
1510
1511/// Clear the cache type comparison results.
1512void
1514{type_comparison_results_cache_.clear();}
1515
1516/// Allow caching of the sub-types comparison results during the
1517/// invocation of the @ref equal overloads for class and function
1518/// types.
1519///
1520/// @param f if true, allow type comparison result caching.
1521void
1523{allow_type_comparison_results_caching_ = f;}
1524
1525/// Check whether if caching of the sub-types comparison results during the
1526/// invocation of the @ref equal overloads for class and function
1527/// types is in effect.
1528///
1529/// @return true iff caching of the sub-types comparison results
1530/// during the invocation of the @ref equal overloads for class and
1531/// function types is in effect.
1532bool
1534{return allow_type_comparison_results_caching_;}
1535
1536
1537/// Return the result of the comparison of two (sub) types.
1538///
1539/// The function does the necessary book keeping before returning the
1540/// result of the comparison of two (sub) types.
1541///
1542/// The book-keeping done is essentially about type comparison cycle detection.
1543///
1544/// @param l the left-hand-side operand of the type comparison
1545///
1546/// @param r the right-hand-side operand of the type comparison
1547///
1548/// @param value the result of the comparison of @p l and @p r.
1549///
1550/// @return the value @p value.
1551template<typename T>
1552bool
1553return_comparison_result(T& l, T& r, bool value)
1554{
1556 ABG_RETURN(value);
1557}
1558
1559#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1560 do \
1561 { \
1562 bool res = return_comparison_result(l, r, value); \
1563 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1564 return res; \
1565 } while (false)
1566
1567/// Cache the result of a comparison between too artifacts (l & r) and
1568/// return immediately.
1569///
1570/// @param value the value to cache.
1571#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1572 do \
1573 { \
1574 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1575 return value; \
1576 } while (false)
1577
1578/// Getter of all types types sorted by their pretty representation.
1579///
1580/// @return a sorted vector of all types sorted by their pretty
1581/// representation.
1582const vector<type_base_wptr>&
1584{
1585 if (priv_->sorted_types_.empty())
1586 {
1587 for (auto e : basic_types())
1588 for (auto t : e.second)
1589 priv_->sorted_types_.push_back(t);
1590
1591 for (auto e : class_types())
1592 for (auto t : e.second)
1593 priv_->sorted_types_.push_back(t);
1594
1595 for (auto e : union_types())
1596 for (auto t : e.second)
1597 priv_->sorted_types_.push_back(t);
1598
1599 for (auto e : enum_types())
1600 for (auto t : e.second)
1601 priv_->sorted_types_.push_back(t);
1602
1603 for (auto e : typedef_types())
1604 for (auto t : e.second)
1605 priv_->sorted_types_.push_back(t);
1606
1607 for (auto e : qualified_types())
1608 for (auto t : e.second)
1609 priv_->sorted_types_.push_back(t);
1610
1611 for (auto e : pointer_types())
1612 for (auto t : e.second)
1613 priv_->sorted_types_.push_back(t);
1614
1615 for (auto e : ptr_to_mbr_types())
1616 for (auto t : e.second)
1617 priv_->sorted_types_.push_back(t);
1618
1619 for (auto e : reference_types())
1620 for (auto t : e.second)
1621 priv_->sorted_types_.push_back(t);
1622
1623 for (auto e : array_types())
1624 for (auto t : e.second)
1625 priv_->sorted_types_.push_back(t);
1626
1627 for (auto e : subrange_types())
1628 for (auto t : e.second)
1629 priv_->sorted_types_.push_back(t);
1630
1631 for (auto e : function_types())
1632 for (auto t : e.second)
1633 priv_->sorted_types_.push_back(t);
1634
1635 type_topo_comp comp;
1636 sort_types(priv_->sorted_types_.begin(),
1637 priv_->sorted_types_.end(),
1638 comp);
1639 }
1640
1641 return priv_->sorted_types_;
1642}
1643
1645type_maps::get_type_map(const std::type_info& ti)
1646{
1647 auto i = priv_->type_maps_hash_.find(ti.hash_code());
1648 if (i == priv_->type_maps_hash_.end())
1649 return nullptr;
1650 return i->second;
1651}
1652
1653// </type_maps stuff>
1654
1655// <translation_unit stuff>
1656
1657/// Constructor of translation_unit.
1658///
1659/// @param env the environment of this translation unit. Please note
1660/// that the life time of the environment must be greater than the
1661/// life time of the translation unit because the translation uses
1662/// resources that are allocated in the environment.
1663///
1664/// @param path the location of the translation unit.
1665///
1666/// @param address_size the size of addresses in the translation unit,
1667/// in bits.
1668translation_unit::translation_unit(const environment& env,
1669 const std::string& path,
1670 char address_size)
1671 : priv_(new priv(env))
1672{
1673 priv_->path_ = path;
1674 priv_->address_size_ = address_size;
1675}
1676
1677/// Getter of the the global scope of the translation unit.
1678///
1679/// @return the global scope of the current translation unit. If
1680/// there is not global scope allocated yet, this function creates one
1681/// and returns it.
1682const scope_decl_sptr
1684{
1685 return const_cast<translation_unit*>(this)->get_global_scope();
1686}
1687
1688/// Getter of the global scope of the translation unit.
1689///
1690/// @return the global scope of the current translation unit. If
1691/// there is not allocated yet, this function creates one and returns
1692/// it.
1695{
1696 lock_guard<recursive_mutex> lock(priv_->mutex_);
1697 {
1698 if (!priv_->global_scope_)
1699 priv_->global_scope_.reset(new global_scope(this));
1700 }
1701
1702 return priv_->global_scope_;
1703}
1704
1705/// Getter of the types of the current @ref translation_unit.
1706///
1707/// @return the maps of the types of the translation unit.
1708const type_maps&
1710{return priv_->types_;}
1711
1712/// Getter of the types of the current @ref translation_unit.
1713///
1714/// @return the maps of the types of the translation unit.
1715type_maps&
1717{return priv_->types_;}
1718
1719/// Get the vector of function types that are used in the current
1720/// translation unit.
1721///
1722/// @return the set of function types that are used in the current
1723/// translation unit.
1724const type_sptr_set_type&
1726{return priv_->live_fn_types_;}
1727
1728/// Getter of the environment of the current @ref translation_unit.
1729///
1730/// @return the translation unit of the current translation unit.
1731const environment&
1733{return priv_->env_;}
1734
1735/// Getter of the language of the source code of the translation unit.
1736///
1737/// @return the language of the source code.
1740{
1741 lock_guard<recursive_mutex> lock(priv_->mutex_);
1742 return priv_->language_;
1743}
1744
1745/// Setter of the language of the source code of the translation unit.
1746///
1747/// @param l the new language.
1748void
1750{
1751 lock_guard<recursive_mutex> lock(priv_->mutex_);
1752 priv_->language_ = l;
1753}
1754
1755
1756/// Get the path of the current translation unit.
1757///
1758/// This path is relative to the build directory of the translation
1759/// unit as returned by translation_unit::get_compilation_dir_path.
1760///
1761/// @return the relative path of the compilation unit associated to
1762/// the current instance of translation_unit.
1763//
1764const std::string&
1766{
1767 lock_guard<recursive_mutex> lock(priv_->mutex_);
1768 return priv_->path_;
1769}
1770
1771/// Set the path associated to the current instance of
1772/// translation_unit.
1773///
1774/// This path is relative to the build directory of the translation
1775/// unit as returned by translation_unit::get_compilation_dir_path.
1776///
1777/// @param a_path the new relative path to set.
1778void
1779translation_unit::set_path(const string& a_path)
1780{
1781 lock_guard<recursive_mutex> lock(priv_->mutex_);
1782 priv_->path_ = a_path;
1783}
1784
1785
1786/// Get the path of the directory that was 'current' when the
1787/// translation unit was compiled.
1788///
1789/// Note that the path returned by translation_unit::get_path is
1790/// relative to the path returned by this function.
1791///
1792/// @return the compilation directory for the current translation
1793/// unit.
1794const std::string&
1796{
1797 lock_guard<recursive_mutex> lock(priv_->mutex_);
1798 return priv_->comp_dir_path_;
1799}
1800
1801/// Set the path of the directory that was 'current' when the
1802/// translation unit was compiled.
1803///
1804/// Note that the path returned by translation_unit::get_path is
1805/// relative to the path returned by this function.
1806///
1807/// @param the compilation directory for the current translation unit.
1808void
1810{
1811 lock_guard<recursive_mutex> lock(priv_->mutex_);
1812 priv_->comp_dir_path_ = d;
1813}
1814
1815/// Get the concatenation of the build directory and the relative path
1816/// of the translation unit.
1817///
1818/// @return the absolute path of the translation unit.
1819const std::string&
1821{
1822 lock_guard<recursive_mutex> lock(priv_->mutex_);
1823 {
1824 if (priv_->abs_path_.empty())
1825 {
1826 string path;
1827 if (!priv_->path_.empty())
1828 {
1829 if (!priv_->comp_dir_path_.empty())
1830 {
1831 path = priv_->comp_dir_path_;
1832 path += "/";
1833 }
1834 path += priv_->path_;
1835 }
1836 priv_->abs_path_ = path;
1837 }
1838 }
1839
1840 return priv_->abs_path_;
1841 }
1842
1843/// Set the corpus this translation unit is a member of.
1844///
1845/// Note that adding a translation unit to a @ref corpus automatically
1846/// triggers a call to this member function.
1847///
1848/// @param corpus the corpus.
1849void
1851{
1852 lock_guard<recursive_mutex> lock(priv_->mutex_);
1853 priv_->corp = c;
1854}
1855
1856/// Get the corpus this translation unit is a member of.
1857///
1858/// @return the parent corpus, or nil if this doesn't belong to any
1859/// corpus yet.
1860corpus*
1862{
1863 lock_guard<recursive_mutex> lock(priv_->mutex_);
1864 return priv_->corp;
1865}
1866
1867/// Get the corpus this translation unit is a member of.
1868///
1869/// @return the parent corpus, or nil if this doesn't belong to any
1870/// corpus yet.
1871const corpus*
1873{return const_cast<translation_unit*>(this)->get_corpus();}
1874
1875/// Getter of the location manager for the current translation unit.
1876///
1877/// @return a reference to the location manager for the current
1878/// translation unit.
1881{return priv_->loc_mgr_;}
1882
1883/// const Getter of the location manager.
1884///
1885/// @return a const reference to the location manager for the current
1886/// translation unit.
1887const location_manager&
1889{return priv_->loc_mgr_;}
1890
1891/// Tests whether if the current translation unit contains ABI
1892/// artifacts or not.
1893///
1894/// @return true iff the current translation unit is empty.
1895bool
1897{
1898 {
1899 lock_guard<recursive_mutex> lock(priv_->mutex_);
1900 if (!priv_->global_scope_)
1901 return true;
1902 }
1903 return get_global_scope()->is_empty();
1904}
1905
1906/// Getter of the address size in this translation unit.
1907///
1908/// @return the address size, in bits.
1909char
1911{
1912 lock_guard<recursive_mutex> lock(priv_->mutex_);
1913 return priv_->address_size_;
1914}
1915
1916/// Setter of the address size in this translation unit.
1917///
1918/// @param a the new address size in bits.
1919void
1921{
1922 lock_guard<recursive_mutex> lock(priv_->mutex_);
1923 priv_->address_size_= a;
1924}
1925
1926/// Getter of the 'is_constructed" flag. It says if the translation
1927/// unit is fully constructed or not.
1928///
1929/// This flag is important for cases when comparison might depend on
1930/// if the translation unit is fully built or not. For instance, when
1931/// reading types from DWARF, the virtual methods of a class are not
1932/// necessarily fully constructed until we have reached the end of the
1933/// translation unit. In that case, before we've reached the end of
1934/// the translation unit, we might not take virtual functions into
1935/// account when comparing classes.
1936///
1937/// @return true if the translation unit is constructed.
1938bool
1940{
1941 lock_guard<recursive_mutex> lock(priv_->mutex_);
1942 return priv_->is_constructed_;
1943}
1944
1945/// Setter of the 'is_constructed" flag. It says if the translation
1946/// unit is fully constructed or not.
1947///
1948/// This flag is important for cases when comparison might depend on
1949/// if the translation unit is fully built or not. For instance, when
1950/// reading types from DWARF, the virtual methods of a class are not
1951/// necessarily fully constructed until we have reached the end of the
1952/// translation unit. In that case, before we've reached the end of
1953/// the translation unit, we might not take virtual functions into
1954/// account when comparing classes.
1955///
1956/// @param f true if the translation unit is constructed.
1957void
1959{
1960 lock_guard<recursive_mutex> lock(priv_->mutex_);
1961 priv_->is_constructed_ = f;
1962}
1963
1964/// Compare the current translation unit against another one.
1965///
1966/// @param other the other tu to compare against.
1967///
1968/// @return true if the two translation units are equal, false
1969/// otherwise.
1970bool
1972{
1973 if (get_address_size() != other.get_address_size())
1974 return false;
1975
1976 return *get_global_scope() == *other.get_global_scope();
1977}
1978
1979/// Inequality operator.
1980///
1981/// @param o the instance of @ref translation_unit to compare the
1982/// current instance against.
1983///
1984/// @return true iff the current instance is different from @p o.
1985bool
1988
1989/// Ensure that the life time of a function type is bound to the life
1990/// time of the current translation unit.
1991///
1992/// @param ftype the function time which life time to bind to the life
1993/// time of the current instance of @ref translation_unit. That is,
1994/// it's onlyh when the translation unit is destroyed that the
1995/// function type can be destroyed to.
1996void
1998{
1999 if (!ftype)
2000 return;
2001
2002 // TODO: function type life time should prolly not be bound to a
2003 // translation unit but rather to a corpus because otherwise, the
2004 // same function type might be being bound to two TUs at the same
2005 // time.
2006
2007 const environment& env = get_environment();
2008
2009 interned_string repr = get_type_name(ftype);
2010
2011 if (ftype->get_translation_unit())
2012 return;
2013
2014 // The function type must be out of the same environment as its
2015 // translation unit.
2016 {
2017 const environment& e = ftype->get_environment();
2018 ABG_ASSERT(&env == &e);
2019 }
2020
2021 {
2022 lock_guard<mutex> lock(priv_->live_fn_types_mutex_);
2023 const_cast<translation_unit*>(this)->priv_->live_fn_types_.insert(ftype);
2024 }
2025
2026 {
2027 lock_guard<recursive_mutex> lock(priv_->types_mutex_);
2028 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
2029 push_back(ftype);
2030 }
2031
2032 if (const translation_unit* existing_tu = ftype->get_translation_unit())
2033 // Guard against some multithreading woes, who knows.
2034 ABG_ASSERT(existing_tu == this);
2035
2036 ftype->set_translation_unit(const_cast<translation_unit*>(this));
2038}
2039
2040/// This implements the ir_traversable_base::traverse virtual
2041/// function.
2042///
2043/// @param v the visitor used on the member nodes of the translation
2044/// unit during the traversal.
2045///
2046/// @return true if the entire type IR tree got traversed, false
2047/// otherwise.
2048bool
2051
2052translation_unit::~translation_unit()
2053{}
2054
2055/// Converts a translation_unit::language enumerator into a string.
2056///
2057/// @param l the language enumerator to translate.
2058///
2059/// @return the resulting string.
2060string
2062{
2063 switch (l)
2064 {
2065 case translation_unit::LANG_UNKNOWN:
2066 return "LANG_UNKNOWN";
2067 case translation_unit::LANG_Cobol74:
2068 return "LANG_Cobol74";
2069 case translation_unit::LANG_Cobol85:
2070 return "LANG_Cobol85";
2071 case translation_unit::LANG_C89:
2072 return "LANG_C89";
2073 case translation_unit::LANG_C99:
2074 return "LANG_C99";
2075 case translation_unit::LANG_C11:
2076 return "LANG_C11";
2077 case translation_unit::LANG_C17:
2078 return "LANG_C17";
2079 case translation_unit::LANG_C23:
2080 return "LANG_C23";
2081 case translation_unit::LANG_C:
2082 return "LANG_C";
2083 case translation_unit::LANG_C_plus_plus_03:
2084 return "LANG_C_plus_plus_03";
2085 case translation_unit::LANG_C_plus_plus_11:
2086 return "LANG_C_plus_plus_11";
2087 case translation_unit::LANG_C_plus_plus_14:
2088 return "LANG_C_plus_plus_14";
2089 case translation_unit::LANG_C_plus_plus_17:
2090 return "LANG_C_plus_plus_17";
2091 case translation_unit::LANG_C_plus_plus_20:
2092 return "LANG_C_plus_plus_20";
2093 case translation_unit::LANG_C_plus_plus_23:
2094 return "LANG_C_plus_plus_23";
2095 case translation_unit::LANG_C_plus_plus:
2096 return "LANG_C_plus_plus";
2097 case translation_unit::LANG_OCaml:
2098 return "LANG_OCaml";
2099 case translation_unit::LANG_Zig:
2100 return "LANG_Zig";
2101 case translation_unit::LANG_ObjC:
2102 return "LANG_ObjC";
2103 case translation_unit::LANG_ObjC_plus_plus:
2104 return "LANG_ObjC_plus_plus";
2105 case translation_unit::LANG_D:
2106 return "LANG_D";
2107 case translation_unit::LANG_Go:
2108 return "LANG_Go";
2109 case translation_unit::LANG_Rust:
2110 return "LANG_Rust";
2111 case translation_unit::LANG_Fortran77:
2112 return "LANG_Fortran77";
2113 case translation_unit::LANG_Fortran90:
2114 return "LANG_Fortran90";
2115 case translation_unit::LANG_Fortran95:
2116 return "LANG_Fortran95";
2117 case translation_unit::LANG_Fortran18:
2118 return "LANG_Fortran18";
2119 case translation_unit::LANG_Fortran23:
2120 return "LANG_Fortran23";
2121 case translation_unit::LANG_Ada83:
2122 return "LANG_Ada83";
2123 case translation_unit::LANG_Ada95:
2124 return "LANG_Ada95";
2125 case translation_unit::LANG_Ada2005:
2126 return "LANG_Ada2005";
2127 case translation_unit::LANG_Ada2012:
2128 return "LANG_Ada2012";
2129 case translation_unit::LANG_Pascal83:
2130 return "LANG_Pascal83";
2131 case translation_unit::LANG_Modula2:
2132 return "LANG_Modula2";
2133 case translation_unit::LANG_Java:
2134 return "LANG_Java";
2135 case translation_unit::LANG_Kotlin:
2136 return "LANG_Kotlin";
2137 case translation_unit::LANG_C_sharp:
2138 return "LANG_C_sharp";
2139 case translation_unit::LANG_Python:
2140 return "LANG_Python";
2141 case translation_unit::LANG_Ruby:
2142 return "LANG_Ruby";
2143 case translation_unit::LANG_PLI:
2144 return "LANG_PLI";
2145 case translation_unit::LANG_UPC:
2146 return "LANG_UPC";
2147 case translation_unit::LANG_Mips_Assembler:
2148 return "LANG_Mips_Assembler";
2149 case translation_unit::LANG_Assembly:
2150 return "LANG_Assembly";
2151 case translation_unit::LANG_Crystal:
2152 return "LANG_Crystal";
2153 case translation_unit::LANG_HIP:
2154 return "LANG_HIP";
2155 case translation_unit::LANG_Mojo:
2156 return "LANG_Mojo";
2157 case translation_unit::LANG_GLSL:
2158 return "LANG_GLSL";
2159 case translation_unit::LANG_GLSL_ES:
2160 return "LANG_GLSL_ES";
2161 case translation_unit::LANG_HLSL:
2162 return "LANG_HLSL";
2163 case translation_unit::LANG_OpenCL_CPP:
2164 return "LANG_OpenCL_CPP";
2165 case translation_unit::LANG_CPP_for_OpenCL:
2166 return "LANG_CPP_for_OpenCL";
2167 case translation_unit::LANG_SYCL:
2168 return "LANG_SYCL";
2169 case translation_unit::LANG_Odin:
2170 return "LANG_Odin";
2171 case translation_unit::LANG_P4:
2172 return "LANG_P4";
2173 case translation_unit::LANG_Metal:
2174 return "LANG_Metal";
2175 case translation_unit::LANG_Move:
2176 return "LANG_Move";
2177 case translation_unit::LANG_Hylo:
2178 return "LANG_Hylo";
2179 }
2180
2181 return "LANG_UNKNOWN";
2182}
2183
2184/// Parse a string representing a language into a
2185/// translation_unit::language enumerator into a string.
2186///
2187/// @param l the string representing the language.
2188///
2189/// @return the resulting translation_unit::language enumerator.
2192{
2193 if (l == "LANG_Cobol74")
2194 return translation_unit::LANG_Cobol74;
2195 else if (l == "LANG_Cobol85")
2196 return translation_unit::LANG_Cobol85;
2197 else if (l == "LANG_C89")
2198 return translation_unit::LANG_C89;
2199 else if (l == "LANG_C99")
2200 return translation_unit::LANG_C99;
2201 else if (l == "LANG_C11")
2202 return translation_unit::LANG_C11;
2203 else if (l == "LANG_C17")
2204 return translation_unit::LANG_C17;
2205 else if (l == "LANG_C23")
2206 return translation_unit::LANG_C23;
2207 else if (l == "LANG_C")
2208 return translation_unit::LANG_C;
2209 else if (l == "LANG_C_plus_plus_03")
2210 return translation_unit::LANG_C_plus_plus_03;
2211 else if (l == "LANG_C_plus_plus_11")
2212 return translation_unit::LANG_C_plus_plus_11;
2213 else if (l == "LANG_C_plus_plus_14")
2214 return translation_unit::LANG_C_plus_plus_14;
2215 else if (l == "LANG_C_plus_plus_17")
2216 return translation_unit::LANG_C_plus_plus_17;
2217 else if (l == "LANG_C_plus_plus_20")
2218 return translation_unit::LANG_C_plus_plus_20;
2219 else if (l == "LANG_C_plus_plus_23")
2220 return translation_unit::LANG_C_plus_plus_23;
2221 else if (l == "LANG_C_plus_plus")
2222 return translation_unit::LANG_C_plus_plus;
2223 else if (l == "LANG_OCaml")
2224 return translation_unit::LANG_OCaml;
2225 else if (l == "LANG_ObjC")
2226 return translation_unit::LANG_ObjC;
2227 else if (l == "LANG_ObjC_plus_plus")
2228 return translation_unit::LANG_ObjC_plus_plus;
2229 else if (l == "LANG_Zig")
2230 return translation_unit::LANG_Zig;
2231 else if (l == "LANG_Metal")
2232 return translation_unit::LANG_Metal;
2233 else if (l == "LANG_Fortran77")
2234 return translation_unit::LANG_Fortran77;
2235 else if (l == "LANG_Fortran90")
2236 return translation_unit::LANG_Fortran90;
2237 else if (l == "LANG_Fortran95")
2238 return translation_unit::LANG_Fortran95;
2239 else if (l == "LANG_Fortran18")
2240 return translation_unit::LANG_Fortran23;
2241 else if (l == "LANG_Ada83")
2242 return translation_unit::LANG_Ada83;
2243 else if (l == "LANG_Ada95")
2244 return translation_unit::LANG_Ada95;
2245 else if (l == "LANG_Ada2005")
2246 return translation_unit::LANG_Ada2005;
2247 else if (l == "LANG_Ada2012")
2248 return translation_unit::LANG_Ada2012;
2249 else if (l == "LANG_Pascal83")
2250 return translation_unit::LANG_Pascal83;
2251 else if (l == "LANG_Modula2")
2252 return translation_unit::LANG_Modula2;
2253 else if (l == "LANG_Java")
2254 return translation_unit::LANG_Java;
2255 else if (l == "LANG_Kotlin")
2256 return translation_unit::LANG_Kotlin;
2257 else if (l == "LANG_PLI")
2258 return translation_unit::LANG_PLI;
2259 else if (l == "LANG_UPC")
2260 return translation_unit::LANG_UPC;
2261 else if (l == "LANG_D")
2262 return translation_unit::LANG_D;
2263 else if (l == "LANG_Go")
2264 return translation_unit::LANG_Go;
2265 else if (l == "LANG_Rust")
2266 return translation_unit::LANG_Rust;
2267 else if (l == "LANG_Python")
2268 return translation_unit::LANG_Python;
2269 else if (l == "LANG_Ruby")
2270 return translation_unit::LANG_Ruby;
2271 else if (l == "LANG_Mips_Assembler")
2272 return translation_unit::LANG_Mips_Assembler;
2273 else if (l == "LANG_Assembly")
2274 return translation_unit::LANG_Assembly;
2275 else if (l == "LANG_Crystal")
2276 return translation_unit::LANG_Crystal;
2277 else if (l == "LANG_HIP")
2278 return translation_unit::LANG_HIP;
2279 else if (l == "LANG_C_sharp")
2280 return translation_unit::LANG_C_sharp;
2281 else if (l == "LANG_Mojo")
2282 return translation_unit::LANG_Mojo;
2283 else if (l == "LANG_GLSL")
2284 return translation_unit::LANG_GLSL;
2285 else if (l == "LANG_GLSL_ES")
2286 return translation_unit::LANG_GLSL_ES;
2287 else if (l == "LANG_HLSL")
2288 return translation_unit::LANG_HLSL;
2289 else if (l == "LANG_OpenCL_CPP")
2290 return translation_unit::LANG_OpenCL_CPP;
2291 else if (l == "LANG_CPP_for_OpenCL")
2292 return translation_unit::LANG_CPP_for_OpenCL;
2293 else if (l == "LANG_SYCL")
2294 return translation_unit::LANG_SYCL;
2295 else if (l == "LANG_Odin")
2296 return translation_unit::LANG_Odin;
2297 else if (l == "LANG_P4")
2298 return translation_unit::LANG_P4;
2299 else if (l == "LANG_Move")
2300 return translation_unit::LANG_Move;
2301 else if (l == "LANG_Hylo")
2302 return translation_unit::LANG_Hylo;
2303
2304 return translation_unit::LANG_UNKNOWN;
2305}
2306
2307/// Test if a language enumerator designates the C language.
2308///
2309/// @param l the language enumerator to consider.
2310///
2311/// @return true iff @p l designates the C language.
2312bool
2314{
2315 return (l == translation_unit::LANG_C89
2316 || l == translation_unit::LANG_C99
2317 || l == translation_unit::LANG_C11
2318 || l == translation_unit::LANG_C17
2319 || l == translation_unit::LANG_C23
2320 || l == translation_unit::LANG_C);
2321}
2322
2323/// Test if a language enumerator designates the C++ language.
2324///
2325/// @param l the language enumerator to consider.
2326///
2327/// @return true iff @p l designates the C++ language.
2328bool
2330{
2331 return (l == translation_unit::LANG_C_plus_plus_03
2332 || l == translation_unit::LANG_C_plus_plus_11
2333 || l == translation_unit::LANG_C_plus_plus_14
2334 || l == translation_unit::LANG_C_plus_plus_20
2335 || l == translation_unit::LANG_C_plus_plus_23
2336 || l == translation_unit::LANG_C_plus_plus);
2337}
2338
2339/// Test if a language enumerator designates the Java language.
2340///
2341/// @param l the language enumerator to consider.
2342///
2343/// @return true iff @p l designates the Java language.
2344bool
2346{return l == translation_unit::LANG_Java;}
2347
2348/// Test if a language enumerator designates the Ada language.
2349///
2350/// @param l the language enumerator to consider.
2351///
2352/// @return true iff @p l designates the Ada language.
2353bool
2355{
2356 return (l == translation_unit::LANG_Ada83
2357 || l == translation_unit::LANG_Ada95
2358 || l == translation_unit::LANG_Ada2005
2359 || l == translation_unit::LANG_Ada2012);
2360}
2361
2362/// A deep comparison operator for pointers to translation units.
2363///
2364/// @param l the first translation unit to consider for the comparison.
2365///
2366/// @param r the second translation unit to consider for the comparison.
2367///
2368/// @return true if the two translation units are equal, false otherwise.
2369bool
2371{
2372 if (l.get() == r.get())
2373 return true;
2374
2375 if (!!l != !!r)
2376 return false;
2377
2378 return *l == *r;
2379}
2380
2381/// A deep inequality operator for pointers to translation units.
2382///
2383/// @param l the first translation unit to consider for the comparison.
2384///
2385/// @param r the second translation unit to consider for the comparison.
2386///
2387/// @return true iff the two translation units are different.
2388bool
2390{return !operator==(l, r);}
2391
2392// </translation_unit stuff>
2393
2394// <elf_symbol stuff>
2395struct elf_symbol::priv
2396{
2397 recursive_mutex mutex_;
2398 const environment& env_;
2399 size_t index_;
2400 size_t size_;
2401 string name_;
2402 elf_symbol::type type_;
2403 elf_symbol::binding binding_;
2404 elf_symbol::version version_;
2405 elf_symbol::visibility visibility_;
2406 bool is_defined_;
2407 // This flag below says if the symbol is a common elf symbol. In
2408 // relocatable files, a common symbol is a symbol defined in a
2409 // section of kind SHN_COMMON.
2410 //
2411 // Note that a symbol of kind STT_COMMON is also considered a common
2412 // symbol. Here is what the gABI says about STT_COMMON and
2413 // SHN_COMMON:
2414 //
2415 // Symbols with type STT_COMMON label uninitialized common
2416 // blocks. In relocatable objects, these symbols are not
2417 // allocated and must have the special section index SHN_COMMON
2418 // (see below). In shared objects and executables these symbols
2419 // must be allocated to some section in the defining object.
2420 //
2421 // In relocatable objects, symbols with type STT_COMMON are
2422 // treated just as other symbols with index SHN_COMMON. If the
2423 // link-editor allocates space for the SHN_COMMON symbol in an
2424 // output section of the object it is producing, it must
2425 // preserve the type of the output symbol as STT_COMMON.
2426 //
2427 // When the dynamic linker encounters a reference to a symbol
2428 // that resolves to a definition of type STT_COMMON, it may (but
2429 // is not required to) change its symbol resolution rules as
2430 // follows: instead of binding the reference to the first symbol
2431 // found with the given name, the dynamic linker searches for
2432 // the first symbol with that name with type other than
2433 // STT_COMMON. If no such symbol is found, it looks for the
2434 // STT_COMMON definition of that name that has the largest size.
2435 bool is_common_;
2436 bool is_in_ksymtab_;
2439 bool is_suppressed_;
2440 elf_symbol_wptr main_symbol_;
2441 elf_symbol_wptr next_alias_;
2442 elf_symbol_wptr next_common_instance_;
2443 string id_string_;
2444
2445 priv(const environment& e)
2446 : env_(e),
2447 index_(),
2448 size_(),
2449 type_(elf_symbol::NOTYPE_TYPE),
2450 binding_(elf_symbol::GLOBAL_BINDING),
2451 visibility_(elf_symbol::DEFAULT_VISIBILITY),
2452 is_defined_(false),
2453 is_common_(false),
2454 is_in_ksymtab_(false),
2455 crc_(),
2456 namespace_(),
2457 is_suppressed_(false)
2458 {}
2459
2460 priv(const environment& e,
2461 size_t i,
2462 size_t s,
2463 const string& n,
2466 bool d,
2467 bool c,
2468 const elf_symbol::version& ve,
2470 bool is_in_ksymtab,
2473 bool is_suppressed)
2474 : env_(e),
2475 index_(i),
2476 size_(s),
2477 name_(n),
2478 type_(t),
2479 binding_(b),
2480 version_(ve),
2481 visibility_(vi),
2482 is_defined_(d),
2483 is_common_(c),
2484 is_in_ksymtab_(is_in_ksymtab),
2485 crc_(crc),
2486 namespace_(ns),
2487 is_suppressed_(is_suppressed)
2488 {
2489 if (!is_common_)
2490 is_common_ = type_ == COMMON_TYPE;
2491 }
2492}; // end struct elf_symbol::priv
2493
2494/// Constructor of the @ref elf_symbol type.
2495///
2496/// Note that this constructor is private, so client code cannot use
2497/// it to create instances of @ref elf_symbol. Rather, client code
2498/// should use the @ref elf_symbol::create() function to create
2499/// instances of @ref elf_symbol instead.
2500///
2501/// @param e the environment we are operating from.
2502///
2503/// @param i the index of the symbol in the (ELF) symbol table.
2504///
2505/// @param s the size of the symbol.
2506///
2507/// @param n the name of the symbol.
2508///
2509/// @param t the type of the symbol.
2510///
2511/// @param b the binding of the symbol.
2512///
2513/// @param d true if the symbol is defined, false otherwise.
2514///
2515/// @param c true if the symbol is a common symbol, false otherwise.
2516///
2517/// @param ve the version of the symbol.
2518///
2519/// @param vi the visibility of the symbol.
2520///
2521/// @param crc the CRC (modversions) value of Linux Kernel symbols
2522///
2523/// @param ns the namespace of Linux Kernel symbols, if any
2524elf_symbol::elf_symbol(const environment& e,
2525 size_t i,
2526 size_t s,
2527 const string& n,
2528 type t,
2529 binding b,
2530 bool d,
2531 bool c,
2532 const version& ve,
2533 visibility vi,
2534 bool is_in_ksymtab,
2537 bool is_suppressed)
2538 : priv_(new priv(e,
2539 i,
2540 s,
2541 n,
2542 t,
2543 b,
2544 d,
2545 c,
2546 ve,
2547 vi,
2548 is_in_ksymtab,
2549 crc,
2550 ns,
2551 is_suppressed))
2552{}
2553
2554/// Factory of instances of @ref elf_symbol.
2555///
2556/// This is the function to use to create instances of @ref elf_symbol.
2557///
2558/// @param e the environment we are operating from.
2559///
2560/// @param i the index of the symbol in the (ELF) symbol table.
2561///
2562/// @param s the size of the symbol.
2563///
2564/// @param n the name of the symbol.
2565///
2566/// @param t the type of the symbol.
2567///
2568/// @param b the binding of the symbol.
2569///
2570/// @param d true if the symbol is defined, false otherwise.
2571///
2572/// @param c true if the symbol is a common symbol.
2573///
2574/// @param ve the version of the symbol.
2575///
2576/// @param vi the visibility of the symbol.
2577///
2578/// @param crc the CRC (modversions) value of Linux Kernel symbols
2579///
2580/// @param ns the namespace of Linux Kernel symbols, if any
2581///
2582/// @return a (smart) pointer to a newly created instance of @ref
2583/// elf_symbol.
2586 size_t i,
2587 size_t s,
2588 const string& n,
2589 type t,
2590 binding b,
2591 bool d,
2592 bool c,
2593 const version& ve,
2594 visibility vi,
2595 bool is_in_ksymtab,
2598 bool is_suppressed)
2599{
2600 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
2601 is_in_ksymtab, crc, ns, is_suppressed));
2602 sym->priv_->main_symbol_ = sym;
2603 return sym;
2604}
2605
2606/// Test textual equality between two symbols.
2607///
2608/// Textual equality means that the aliases of the compared symbols
2609/// are not taken into account. Only the name, type, and version of
2610/// the symbols are compared.
2611///
2612/// @parm l the first ELF symbol to take into consideration in the
2613/// comparison.
2614///
2615/// @param r the second ELF symbol to take into consideration in the
2616/// comparison.
2617///
2618/// @param k a pointer to a bitfield that gives information about the
2619/// kind of changes there are between @p l and @p r. This one is set
2620/// iff it's non-null and if the function returns false.
2621///
2622/// @return true iff the two symbols are textually equal.
2623static bool
2624textually_equals(const elf_symbol&l, const elf_symbol&r,
2625 change_kind* k = nullptr)
2626{
2627 bool equals = (l.get_name() == r.get_name()
2628 && l.get_type() == r.get_type()
2629 && l.is_public() == r.is_public()
2630 && l.is_defined() == r.is_defined()
2632 && l.get_version() == r.get_version()
2633 && l.get_crc() == r.get_crc()
2634 && l.get_namespace() == r.get_namespace());
2635
2636 if (!equals)
2637 if (k)
2639
2640 if (equals && l.is_variable())
2641 // These are variable symbols. Let's compare their symbol size.
2642 // The symbol size in this case is the size taken by the storage
2643 // of the variable. If that size changes, then it's an ABI
2644 // change.
2645 if (l.get_size() != r.get_size())
2646 {
2647 equals = false;
2648 if (k)
2650 }
2651
2652 return equals;
2653}
2654
2655/// Getter of the environment used by the current instance of @ref
2656/// elf_symbol.
2657///
2658/// @return the enviroment used by the current instance of @ref elf_symbol.
2659const environment&
2661{return priv_->env_;}
2662
2663/// Getter for the index
2664///
2665/// @return the index of the symbol.
2666size_t
2668{
2669 lock_guard<recursive_mutex> lock(priv_->mutex_);
2670 return priv_->index_;
2671}
2672
2673/// Setter for the index.
2674///
2675/// @param s the new index.
2676void
2678{
2679 lock_guard<recursive_mutex> lock(priv_->mutex_);
2680 priv_->index_ = s;
2681}
2682
2683/// Getter for the name of the @ref elf_symbol.
2684///
2685/// @return a reference to the name of the @ref symbol.
2686const string&
2688{
2689 lock_guard<recursive_mutex> lock(priv_->mutex_);
2690 return priv_->name_;
2691}
2692
2693/// Setter for the name of the current intance of @ref elf_symbol.
2694///
2695/// @param n the new name.
2696void
2697elf_symbol::set_name(const string& n)
2698{
2699 lock_guard<recursive_mutex> lock(priv_->mutex_);
2700 priv_->name_ = n;
2701 priv_->id_string_.clear();
2702}
2703
2704/// Getter for the type of the current instance of @ref elf_symbol.
2705///
2706/// @return the type of the elf symbol.
2709{
2710 lock_guard<recursive_mutex> lock(priv_->mutex_);
2711 return priv_->type_;
2712}
2713
2714/// Setter for the type of the current instance of @ref elf_symbol.
2715///
2716/// @param t the new symbol type.
2717void
2719{
2720 lock_guard<recursive_mutex> lock(priv_->mutex_);
2721 priv_->type_ = t;
2722}
2723
2724/// Getter of the size of the symbol.
2725///
2726/// @return the size of the symbol, in bytes.
2727size_t
2729{
2730 lock_guard<recursive_mutex> lock(priv_->mutex_);
2731 return priv_->size_;
2732}
2733
2734/// Setter of the size of the symbol.
2735///
2736/// @param size the new size of the symbol, in bytes.
2737void
2739{
2740 lock_guard<recursive_mutex> lock(priv_->mutex_);
2741 priv_->size_ = size;
2742}
2743
2744/// Getter for the binding of the current instance of @ref elf_symbol.
2745///
2746/// @return the binding of the symbol.
2749{
2750 lock_guard<recursive_mutex> lock(priv_->mutex_);
2751 return priv_->binding_;
2752}
2753
2754/// Setter for the binding of the current instance of @ref elf_symbol.
2755///
2756/// @param b the new binding.
2757void
2759{
2760 lock_guard<recursive_mutex> lock(priv_->mutex_);
2761 priv_->binding_ = b;
2762}
2763
2764/// Getter for the version of the current instanc of @ref elf_symbol.
2765///
2766/// @return the version of the elf symbol.
2769{
2770 lock_guard<recursive_mutex> lock(priv_->mutex_);
2771 return priv_->version_;
2772}
2773
2774/// Setter for the version of the current instance of @ref elf_symbol.
2775///
2776/// @param v the new version of the elf symbol.
2777void
2779{
2780 lock_guard<recursive_mutex> lock(priv_->mutex_);
2781 priv_->version_ = v;
2782 priv_->id_string_.clear();
2783}
2784
2785/// Setter of the visibility of the current instance of @ref
2786/// elf_symbol.
2787///
2788/// @param v the new visibility of the elf symbol.
2789void
2791{
2792 lock_guard<recursive_mutex> lock(priv_->mutex_);
2793 priv_->visibility_ = v;
2794}
2795
2796/// Getter of the visibility of the current instance of @ref
2797/// elf_symbol.
2798///
2799/// @return the visibility of the elf symbol.
2802{
2803 lock_guard<recursive_mutex> lock(priv_->mutex_);
2804 return priv_->visibility_;
2805}
2806
2807/// Test if the current instance of @ref elf_symbol is defined or not.
2808///
2809/// @return true if the current instance of @ref elf_symbol is
2810/// defined, false otherwise.
2811bool
2813{
2814 lock_guard<recursive_mutex> lock(priv_->mutex_);
2815 return priv_->is_defined_;
2816}
2817
2818/// Sets a flag saying if the current instance of @ref elf_symbol is
2819/// defined
2820///
2821/// @param b the new value of the flag.
2822void
2824{
2825 lock_guard<recursive_mutex> lock(priv_->mutex_);
2826 priv_->is_defined_ = d;
2827}
2828
2829/// Test if the current instance of @ref elf_symbol is public or not.
2830///
2831/// This tests if the symbol is defined, has default or protected
2832///visibility, and either:
2833/// - has global binding
2834/// - has weak binding
2835/// - or has a GNU_UNIQUE binding.
2836///
2837/// return true if the current instance of @ref elf_symbol is public,
2838/// false otherwise.
2839bool
2841{
2842 return (is_defined()
2843 && (get_binding() == GLOBAL_BINDING
2844 || get_binding() == WEAK_BINDING
2845 || get_binding() == GNU_UNIQUE_BINDING)
2846 && (get_visibility() == DEFAULT_VISIBILITY
2847 || get_visibility() == PROTECTED_VISIBILITY));
2848}
2849
2850/// Test if the current instance of @ref elf_symbol is a function
2851/// symbol or not.
2852///
2853/// @return true if the current instance of @ref elf_symbol is a
2854/// function symbol, false otherwise.
2855bool
2857{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2858
2859/// Test if the current instance of @ref elf_symbol is a variable
2860/// symbol or not.
2861///
2862/// @return true if the current instance of @ref elf_symbol is a
2863/// variable symbol, false otherwise.
2864bool
2866{
2867 return (get_type() == OBJECT_TYPE
2868 || get_type() == TLS_TYPE
2869 // It appears that undefined variables have NOTYPE type.
2870 || (get_type() == NOTYPE_TYPE
2871 && !is_defined()));
2872}
2873
2874/// Getter of the 'is-in-ksymtab' property.
2875///
2876/// @return true iff the current symbol is in the Linux Kernel
2877/// specific 'ksymtab' symbol table.
2878bool
2880{
2881 lock_guard<recursive_mutex> lock(priv_->mutex_);
2882 return priv_->is_in_ksymtab_;
2883}
2884
2885/// Setter of the 'is-in-ksymtab' property.
2886///
2887/// @param is_in_ksymtab this is true iff the current symbol is in the
2888/// Linux Kernel specific 'ksymtab' symbol table.
2889void
2891{
2892 lock_guard<recursive_mutex> lock(priv_->mutex_);
2893 priv_->is_in_ksymtab_ = is_in_ksymtab;
2894}
2895
2896/// Getter of the 'crc' property.
2897///
2898/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2901{
2902 lock_guard<recursive_mutex> lock(priv_->mutex_);
2903 return priv_->crc_;
2904}
2905
2906/// Setter of the 'crc' property.
2907///
2908/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2909void
2911{
2912 lock_guard<recursive_mutex> lock(priv_->mutex_);
2913 priv_->crc_ = crc;
2914}
2915
2916/// Getter of the 'namespace' property.
2917///
2918/// @return the namespace for Linux Kernel symbols, if any
2921{
2922 lock_guard<recursive_mutex> lock(priv_->mutex_);
2923 return priv_->namespace_;
2924}
2925
2926/// Setter of the 'namespace' property.
2927///
2928/// @param ns the new namespace for Linux Kernel symbols, if any
2929void
2931{
2932 lock_guard<recursive_mutex> lock(priv_->mutex_);
2933 priv_->namespace_ = ns;
2934}
2935
2936/// Getter for the 'is-suppressed' property.
2937///
2938/// @return true iff the current symbol has been suppressed by a
2939/// suppression specification that was provided in the context that
2940/// led to the creation of the corpus this ELF symbol belongs to.
2941bool
2943{
2944 lock_guard<recursive_mutex> lock(priv_->mutex_);
2945 return priv_->is_suppressed_;
2946}
2947
2948/// Setter for the 'is-suppressed' property.
2949///
2950/// @param true iff the current symbol has been suppressed by a
2951/// suppression specification that was provided in the context that
2952/// led to the creation of the corpus this ELF symbol belongs to.
2953void
2955{
2956 lock_guard<recursive_mutex> lock(priv_->mutex_);
2957 priv_->is_suppressed_ = is_suppressed;
2958}
2959
2960/// @name Elf symbol aliases
2961///
2962/// An alias A for an elf symbol S is a symbol that is defined at the
2963/// same address as S. S is chained to A through the
2964/// elf_symbol::get_next_alias() method.
2965///
2966/// When there are several aliases to a symbol, the main symbol is the
2967/// the first symbol found in the symbol table for a given address.
2968///
2969/// The alias chain is circular. That means if S is the main symbol
2970/// and A is the alias, S is chained to A and A
2971/// is chained back to the main symbol S. The last alias in an alias
2972///chain is always chained to the main symbol.
2973///
2974/// Thus, when looping over the aliases of an elf_symbol A, detecting
2975/// an alias that is equal to the main symbol should logically be a
2976/// loop exit condition.
2977///
2978/// Accessing and adding aliases for instances of elf_symbol is done
2979/// through the member functions below.
2980
2981/// @{
2982
2983/// Get the main symbol of an alias chain.
2984///
2985///@return the main symbol.
2986const elf_symbol_sptr
2988{
2989 lock_guard<recursive_mutex> lock(priv_->mutex_);
2990 return priv_->main_symbol_.lock();
2991}
2992
2993/// Get the main symbol of an alias chain.
2994///
2995///@return the main symbol.
2998{
2999 lock_guard<recursive_mutex> lock(priv_->mutex_);
3000 return priv_->main_symbol_.lock();
3001}
3002
3003/// Tests whether this symbol is the main symbol.
3004///
3005/// @return true iff this symbol is the main symbol.
3006bool
3008{
3009 lock_guard<recursive_mutex> lock(priv_->mutex_);
3010 return get_main_symbol().get() == this;
3011}
3012
3013/// Get the next alias of the current symbol.
3014///
3015///@return the alias, or NULL if there is no alias.
3018{
3019 lock_guard<recursive_mutex> lock(priv_->mutex_);
3020 return priv_->next_alias_.lock();
3021}
3022
3023
3024/// Check if the current elf_symbol has an alias.
3025///
3026///@return true iff the current elf_symbol has an alias.
3027bool
3029{return bool(get_next_alias());}
3030
3031/// Get the number of aliases to this elf symbol
3032///
3033/// @return the number of aliases to this elf symbol.
3034int
3036{
3037 lock_guard<recursive_mutex> lock(priv_->mutex_);
3038 int result = 0;
3039
3041 a && a.get() != get_main_symbol().get();
3042 a = a->get_next_alias())
3043 ++result;
3044
3045 return result;
3046}
3047
3048/// Add an alias to the current elf symbol.
3049///
3050/// @param alias the new alias. Note that this elf_symbol should *NOT*
3051/// have aliases prior to the invocation of this function.
3052void
3054{
3055 if (!alias)
3056 return;
3057
3058 ABG_ASSERT(!alias->has_aliases());
3060
3061 if (has_aliases())
3062 {
3063 elf_symbol_sptr last_alias;
3065 a && !a->is_main_symbol();
3066 a = a->get_next_alias())
3067 {
3068 if (a->get_next_alias()->is_main_symbol())
3069 {
3070 ABG_ASSERT(last_alias == 0);
3071 last_alias = a;
3072 }
3073 }
3074 ABG_ASSERT(last_alias);
3075
3076 last_alias->priv_->next_alias_ = alias;
3077 }
3078 else
3079 {
3080 lock_guard<recursive_mutex> lock(priv_->mutex_);
3081 priv_->next_alias_ = alias;
3082 }
3083
3084 alias->priv_->next_alias_ = get_main_symbol();
3085 alias->priv_->main_symbol_ = get_main_symbol();
3086}
3087
3088/// Update the main symbol for a group of aliased symbols
3089///
3090/// If after the construction of the symbols (in order of discovery), the
3091/// actual main symbol can be identified (e.g. as the symbol that actually is
3092/// defined in the code), this method offers a way of updating the main symbol
3093/// through one of the aliased symbols.
3094///
3095/// For that, locate the new main symbol by name and update all references to
3096/// the main symbol among the group of aliased symbols.
3097///
3098/// @param name the name of the main symbol
3099///
3100/// @return the new main elf_symbol
3102elf_symbol::update_main_symbol(const std::string& name)
3103{
3104 if (!has_aliases() || get_name() == name)
3105 return get_main_symbol();
3106
3107 // find the new main symbol
3108 elf_symbol_sptr new_main;
3109 // we've already checked this; check the rest of the aliases
3110 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
3111 a = a->get_next_alias())
3112 if (a->get_name() == name)
3113 {
3114 new_main = a;
3115 break;
3116 }
3117
3118 if (!new_main)
3119 return get_main_symbol();
3120
3121 {
3122 lock_guard<recursive_mutex> lock(priv_->mutex_);
3123 // now update all main symbol references
3124 priv_->main_symbol_ = new_main;
3125 }
3126
3128 a.get() != this;
3129 a = a->get_next_alias())
3130 {
3131 lock_guard<recursive_mutex> lock(a->priv_->mutex_);
3132 a->priv_->main_symbol_ = new_main;
3133 }
3134
3135
3136 return new_main;
3137}
3138
3139/// Return true if the symbol is a common one.
3140///
3141/// @return true iff the symbol is common.
3142bool
3144{
3145 lock_guard<recursive_mutex> lock(priv_->mutex_);
3146 return priv_->is_common_;
3147}
3148
3149/// Return true if this common common symbol has other common instances.
3150///
3151/// A common instance of a given common symbol is another common
3152/// symbol with the same name. Those exist in relocatable files. The
3153/// linker normally allocates all the instances into a common block in
3154/// the final output file.
3155///
3156/// Note that the current object must be a common symbol, otherwise,
3157/// this function aborts.
3158///
3159/// @return true iff the current common symbol has other common
3160/// instances.
3161bool
3167
3168/// Get the next common instance of the current common symbol.
3169///
3170/// A common instance of a given common symbol is another common
3171/// symbol with the same name. Those exist in relocatable files. The
3172/// linker normally allocates all the instances into a common block in
3173/// the final output file.
3174///
3175/// @return the next common instance, or nil if there is not any.
3178{
3179 lock_guard<recursive_mutex> lock(priv_->mutex_);
3180 return priv_->next_common_instance_.lock();
3181}
3182
3183/// Add a common instance to the current common elf symbol.
3184///
3185/// Note that this symbol must be the main symbol. Being the main
3186/// symbol means being the first common symbol to appear in the symbol
3187/// table.
3188///
3189/// @param common the other common instance to add.
3190void
3192{
3193 if (!common)
3194 return;
3195
3196 lock_guard<recursive_mutex> lock(priv_->mutex_);
3197
3198 ABG_ASSERT(!common->has_other_common_instances());
3201
3203 {
3204 elf_symbol_sptr last_common_instance;
3206 c && (c.get() != get_main_symbol().get());
3207 c = c->get_next_common_instance())
3208 {
3209 if (c->get_next_common_instance().get() == get_main_symbol().get())
3210 {
3211 ABG_ASSERT(last_common_instance == 0);
3212 last_common_instance = c;
3213 }
3214 }
3215 ABG_ASSERT(last_common_instance);
3216
3217 last_common_instance->priv_->next_common_instance_ = common;
3218 }
3219 else
3220 priv_->next_common_instance_ = common;
3221
3222 common->priv_->next_common_instance_ = get_main_symbol();
3223 common->priv_->main_symbol_ = get_main_symbol();
3224}
3225
3226/// Get a string that is representative of a given elf_symbol.
3227///
3228/// If the symbol has a version, then the ID string is the
3229/// concatenation of the name of the symbol, the '@' character, and
3230/// the version of the symbol. If the version is the default version
3231/// of the symbol then the '@' character is replaced by a "@@" string.
3232///
3233/// Otherwise, if the symbol does not have any version, this function
3234/// returns the name of the symbol.
3235///
3236/// @return a the ID string.
3237const string&
3239{
3240 if (priv_->id_string_.empty())
3241 {
3242 string s = get_name ();
3243
3244 if (!get_version().is_empty())
3245 {
3246 if (get_version().is_default())
3247 s += "@@";
3248 else
3249 s += "@";
3250 s += get_version().str();
3251 }
3252 priv_->id_string_ = s;
3253 }
3254
3255 return priv_->id_string_;
3256}
3257
3258/// From the aliases of the current symbol, lookup one with a given name.
3259///
3260/// @param name the name of symbol alias we are looking for.
3261///
3262/// @return the symbol alias that has the name @p name, or nil if none
3263/// has been found.
3265elf_symbol::get_alias_from_name(const string& name) const
3266{
3267 if (name == get_name())
3268 return elf_symbol_sptr(priv_->main_symbol_);
3269
3271 a && a.get() != get_main_symbol().get();
3272 a = a->get_next_alias())
3273 if (a->get_name() == name)
3274 return a;
3275
3276 return elf_symbol_sptr();
3277}
3278
3279/// In the list of aliases of a given elf symbol, get the alias that
3280/// equals this current symbol.
3281///
3282/// @param other the elf symbol to get the potential aliases from.
3283///
3284/// @return the alias of @p other that texually equals the current
3285/// symbol, or nil if no alias textually equals the current symbol.
3288{
3289 for (elf_symbol_sptr a = other.get_next_alias();
3290 a && a.get() != a->get_main_symbol().get();
3291 a = a->get_next_alias())
3292 if (textually_equals(*this, *a))
3293 return a;
3294 return elf_symbol_sptr();
3295}
3296
3297/// Return a comma separated list of the id of the current symbol as
3298/// well as the id string of its aliases.
3299///
3300/// @param syms a map of all the symbols of the corpus the current
3301/// symbol belongs to.
3302///
3303/// @param include_symbol_itself if set to true, then the name of the
3304/// current symbol is included in the list of alias names that is emitted.
3305///
3306/// @return the string.
3307string
3309 bool include_symbol_itself) const
3310{
3311 string result;
3312
3313 if (include_symbol_itself)
3314 result = get_id_string();
3315
3316 vector<elf_symbol_sptr> aliases;
3317 compute_aliases_for_elf_symbol(*this, syms, aliases);
3318 if (!aliases.empty() && include_symbol_itself)
3319 result += ", ";
3320
3321 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
3322 i != aliases.end();
3323 ++i)
3324 {
3325 if (i != aliases.begin())
3326 result += ", ";
3327 result += (*i)->get_id_string();
3328 }
3329 return result;
3330}
3331
3332/// Return a comma separated list of the id of the current symbol as
3333/// well as the id string of its aliases.
3334///
3335/// @param include_symbol_itself if set to true, then the name of the
3336/// current symbol is included in the list of alias names that is emitted.
3337///
3338/// @return the string.
3339string
3340elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
3341{
3342 vector<elf_symbol_sptr> aliases;
3343 if (include_symbol_itself)
3344 aliases.push_back(get_main_symbol());
3345
3347 a && a.get() != get_main_symbol().get();
3348 a = a->get_next_alias())
3349 aliases.push_back(a);
3350
3351 string result;
3352 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
3353 i != aliases.end();
3354 ++i)
3355 {
3356 if (i != aliases.begin())
3357 result += ", ";
3358 result += (*i)->get_id_string();
3359 }
3360
3361 return result;
3362}
3363
3364/// Given the ID of a symbol, get the name and the version of said
3365/// symbol.
3366///
3367/// @param id the symbol ID to consider.
3368///
3369/// @param name the symbol name extracted from the ID. This is set
3370/// only if the function returned true.
3371///
3372/// @param ver the symbol version extracted from the ID.
3373bool
3375 string& name,
3376 string& ver)
3377{
3378 name.clear(), ver.clear();
3379
3380 string::size_type i = id.find('@');
3381 if (i == string::npos)
3382 {
3383 name = id;
3384 return true;
3385 }
3386
3387 name = id.substr(0, i);
3388 ++i;
3389
3390 if (i >= id.size())
3391 return true;
3392
3393 string::size_type j = id.find('@', i);
3394 if (j == string::npos)
3395 j = i;
3396 else
3397 ++j;
3398
3399 if (j >= id.size())
3400 {
3401 ver = "";
3402 return true;
3403 }
3404
3405 ver = id.substr(j);
3406 return true;
3407}
3408
3409///@}
3410
3411/// Test if two main symbols are textually equal, or, if they have
3412/// aliases that are textually equal.
3413///
3414/// @param other the symbol to compare against.
3415///
3416/// @return true iff the current instance of elf symbol equals the @p
3417/// other.
3418bool
3420{
3421 bool are_equal = textually_equals(*this, other);
3422 if (!are_equal)
3423 are_equal = bool(get_alias_which_equals(other));
3424 return are_equal;
3425}
3426
3427/// Test if the current symbol aliases another one.
3428///
3429/// @param o the other symbol to test against.
3430///
3431/// @return true iff the current symbol aliases @p o.
3432bool
3434{
3435 if (*this == o)
3436 return true;
3437
3438 if (get_main_symbol() == o.get_main_symbol())
3439 return true;
3440
3442 a && !a->is_main_symbol();
3443 a = a->get_next_alias())
3444 {
3445 if (o == *a)
3446 return true;
3447 }
3448 return false;
3449}
3450
3451/// Equality operator for smart pointers to elf_symbol.
3452///
3453/// @param lhs the first elf symbol to consider.
3454///
3455/// @param rhs the second elf symbol to consider.
3456///
3457/// @return true iff @p lhs equals @p rhs.
3458bool
3460{
3461 if (!!lhs != !!rhs)
3462 return false;
3463
3464 if (!lhs)
3465 return true;
3466
3467 return *lhs == *rhs;
3468}
3469
3470/// Inequality operator for smart pointers to elf_symbol.
3471///
3472/// @param lhs the first elf symbol to consider.
3473///
3474/// @param rhs the second elf symbol to consider.
3475///
3476/// @return true iff @p lhs is different from @p rhs.
3477bool
3479{return !operator==(lhs, rhs);}
3480
3481/// Test if two symbols alias.
3482///
3483/// @param s1 the first symbol to consider.
3484///
3485/// @param s2 the second symbol to consider.
3486///
3487/// @return true if @p s1 aliases @p s2.
3488bool
3490{return s1.does_alias(s2) || s2.does_alias(s1);}
3491
3492void
3493compute_aliases_for_elf_symbol(const elf_symbol& sym,
3494 const string_elf_symbols_map_type& symtab,
3495 vector<elf_symbol_sptr>& aliases)
3496{
3497
3498 if (elf_symbol_sptr a = sym.get_next_alias())
3499 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
3500 aliases.push_back(a);
3501 else
3502 {
3503 // No pre-linked alias chain (e.g. symbols loaded from abixml).
3504 // Look up by name in the symtab (O(1) hash lookup) instead of
3505 // scanning the entire table (which was O(N) per call).
3506 string_elf_symbols_map_type::const_iterator i =
3507 symtab.find(sym.get_name());
3508 if (i == symtab.end())
3509 return;
3510
3511 for (elf_symbols::const_iterator j = i->second.begin();
3512 j != i->second.end();
3513 ++j)
3514 {
3515 if (**j == sym)
3516 for (elf_symbol_sptr s = (*j)->get_next_alias();
3517 s && !s->is_main_symbol();
3518 s = s->get_next_alias())
3519 aliases.push_back(s);
3520 else
3521 for (elf_symbol_sptr s = (*j)->get_next_alias();
3522 s && !s->is_main_symbol();
3523 s = s->get_next_alias())
3524 if (*s == sym)
3525 aliases.push_back(*j);
3526 }
3527 }
3528}
3529
3530/// Test if two symbols alias.
3531///
3532/// @param s1 the first symbol to consider.
3533///
3534/// @param s2 the second symbol to consider.
3535///
3536/// @return true if @p s1 aliases @p s2.
3537bool
3539{
3540 if (!!s1 != !!s2)
3541 return false;
3542 if (s1 == s2)
3543 return true;
3544 return elf_symbols_alias(*s1, *s2);
3545}
3546
3547/// Test if two symbols alias.
3548///
3549/// @param s1 the first symbol to consider.
3550///
3551/// @param s2 the second symbol to consider.
3552///
3553/// @return true if @p s1 aliases @p s2.
3554bool
3556{return elf_symbols_alias(s1.get(), s2.get());}
3557
3558/// Serialize an instance of @ref symbol_type and stream it to a given
3559/// output stream.
3560///
3561/// @param o the output stream to serialize the symbole type to.
3562///
3563/// @param t the symbol type to serialize.
3564std::ostream&
3565operator<<(std::ostream& o, elf_symbol::type t)
3566{
3567 string repr;
3568
3569 switch (t)
3570 {
3571 case elf_symbol::NOTYPE_TYPE:
3572 repr = "unspecified symbol type";
3573 break;
3574 case elf_symbol::OBJECT_TYPE:
3575 repr = "variable symbol type";
3576 break;
3577 case elf_symbol::FUNC_TYPE:
3578 repr = "function symbol type";
3579 break;
3580 case elf_symbol::SECTION_TYPE:
3581 repr = "section symbol type";
3582 break;
3583 case elf_symbol::FILE_TYPE:
3584 repr = "file symbol type";
3585 break;
3586 case elf_symbol::COMMON_TYPE:
3587 repr = "common data object symbol type";
3588 break;
3589 case elf_symbol::TLS_TYPE:
3590 repr = "thread local data object symbol type";
3591 break;
3592 case elf_symbol::GNU_IFUNC_TYPE:
3593 repr = "indirect function symbol type";
3594 break;
3595 default:
3596 {
3597 std::ostringstream s;
3598 s << "unknown symbol type (" << (char)t << ')';
3599 repr = s.str();
3600 }
3601 break;
3602 }
3603
3604 o << repr;
3605 return o;
3606}
3607
3608/// Serialize an instance of @ref symbol_binding and stream it to a
3609/// given output stream.
3610///
3611/// @param o the output stream to serialize the symbole type to.
3612///
3613/// @param b the symbol binding to serialize.
3614std::ostream&
3615operator<<(std::ostream& o, elf_symbol::binding b)
3616{
3617 string repr;
3618
3619 switch (b)
3620 {
3621 case elf_symbol::LOCAL_BINDING:
3622 repr = "local binding";
3623 break;
3624 case elf_symbol::GLOBAL_BINDING:
3625 repr = "global binding";
3626 break;
3627 case elf_symbol::WEAK_BINDING:
3628 repr = "weak binding";
3629 break;
3630 case elf_symbol::GNU_UNIQUE_BINDING:
3631 repr = "GNU unique binding";
3632 break;
3633 default:
3634 {
3635 std::ostringstream s;
3636 s << "unknown binding (" << (unsigned char) b << ")";
3637 repr = s.str();
3638 }
3639 break;
3640 }
3641
3642 o << repr;
3643 return o;
3644}
3645
3646/// Serialize an instance of @ref elf_symbol::visibility and stream it
3647/// to a given output stream.
3648///
3649/// @param o the output stream to serialize the symbole type to.
3650///
3651/// @param v the symbol visibility to serialize.
3652std::ostream&
3653operator<<(std::ostream& o, elf_symbol::visibility v)
3654{
3655 string repr;
3656
3657 switch (v)
3658 {
3659 case elf_symbol::DEFAULT_VISIBILITY:
3660 repr = "default visibility";
3661 break;
3662 case elf_symbol::PROTECTED_VISIBILITY:
3663 repr = "protected visibility";
3664 break;
3665 case elf_symbol::HIDDEN_VISIBILITY:
3666 repr = "hidden visibility";
3667 break;
3668 case elf_symbol::INTERNAL_VISIBILITY:
3669 repr = "internal visibility";
3670 break;
3671 default:
3672 {
3673 std::ostringstream s;
3674 s << "unknown visibility (" << (unsigned char) v << ")";
3675 repr = s.str();
3676 }
3677 break;
3678 }
3679
3680 o << repr;
3681 return o;
3682}
3683
3684/// Convert a string representing a symbol type into an
3685/// elf_symbol::type.
3686///
3687///@param s the string to convert.
3688///
3689///@param t the resulting elf_symbol::type.
3690///
3691/// @return true iff the conversion completed successfully.
3692bool
3694{
3695 if (s == "no-type")
3696 t = elf_symbol::NOTYPE_TYPE;
3697 else if (s == "object-type")
3698 t = elf_symbol::OBJECT_TYPE;
3699 else if (s == "func-type")
3700 t = elf_symbol::FUNC_TYPE;
3701 else if (s == "section-type")
3702 t = elf_symbol::SECTION_TYPE;
3703 else if (s == "file-type")
3704 t = elf_symbol::FILE_TYPE;
3705 else if (s == "common-type")
3706 t = elf_symbol::COMMON_TYPE;
3707 else if (s == "tls-type")
3708 t = elf_symbol::TLS_TYPE;
3709 else if (s == "gnu-ifunc-type")
3710 t = elf_symbol::GNU_IFUNC_TYPE;
3711 else
3712 return false;
3713
3714 return true;
3715}
3716
3717/// Convert a string representing a an elf symbol binding into an
3718/// elf_symbol::binding.
3719///
3720/// @param s the string to convert.
3721///
3722/// @param b the resulting elf_symbol::binding.
3723///
3724/// @return true iff the conversion completed successfully.
3725bool
3727{
3728 if (s == "local-binding")
3729 b = elf_symbol::LOCAL_BINDING;
3730 else if (s == "global-binding")
3731 b = elf_symbol::GLOBAL_BINDING;
3732 else if (s == "weak-binding")
3733 b = elf_symbol::WEAK_BINDING;
3734 else if (s == "gnu-unique-binding")
3735 b = elf_symbol::GNU_UNIQUE_BINDING;
3736 else
3737 return false;
3738
3739 return true;
3740}
3741
3742/// Convert a string representing a an elf symbol visibility into an
3743/// elf_symbol::visibility.
3744///
3745/// @param s the string to convert.
3746///
3747/// @param b the resulting elf_symbol::visibility.
3748///
3749/// @return true iff the conversion completed successfully.
3750bool
3752{
3753 if (s == "default-visibility")
3754 v = elf_symbol::DEFAULT_VISIBILITY;
3755 else if (s == "protected-visibility")
3756 v = elf_symbol::PROTECTED_VISIBILITY;
3757 else if (s == "hidden-visibility")
3758 v = elf_symbol::HIDDEN_VISIBILITY;
3759 else if (s == "internal-visibility")
3760 v = elf_symbol::INTERNAL_VISIBILITY;
3761 else
3762 return false;
3763
3764 return true;
3765}
3766
3767/// Test if the type of an ELF symbol denotes a function symbol.
3768///
3769/// @param t the type of the ELF symbol.
3770///
3771/// @return true iff elf symbol type @p t denotes a function symbol
3772/// type.
3773bool
3775{return t == elf_symbol::FUNC_TYPE;}
3776
3777/// Test if the type of an ELF symbol denotes a function symbol.
3778///
3779/// @param t the type of the ELF symbol.
3780///
3781/// @return true iff elf symbol type @p t denotes a function symbol
3782/// type.
3783bool
3785{return t == elf_symbol::OBJECT_TYPE;}
3786
3787// <elf_symbol::version stuff>
3788
3789struct elf_symbol::version::priv
3790{
3791 string version_;
3792 bool is_default_;
3793
3794 priv()
3795 : is_default_(false)
3796 {}
3797
3798 priv(const string& v,
3799 bool d)
3800 : version_(v),
3801 is_default_(d)
3802 {}
3803}; // end struct elf_symbol::version::priv
3804
3805elf_symbol::version::version()
3806 : priv_(new priv)
3807{}
3808
3809/// @param v the name of the version.
3810///
3811/// @param is_default true if this is a default version.
3812elf_symbol::version::version(const string& v,
3813 bool is_default)
3814 : priv_(new priv(v, is_default))
3815{}
3816
3817elf_symbol::version::version(const elf_symbol::version& v)
3818 : priv_(new priv(v.str(), v.is_default()))
3819{
3820}
3821
3822elf_symbol::version::~version() = default;
3823
3824/// Cast the version_type into a string that is its name.
3825///
3826/// @return the name of the version.
3827elf_symbol::version::operator const string&() const
3828{return priv_->version_;}
3829
3830/// Getter for the version name.
3831///
3832/// @return the version name.
3833const string&
3835{return priv_->version_;}
3836
3837/// Setter for the version name.
3838///
3839/// @param s the version name.
3840void
3842{priv_->version_ = s;}
3843
3844/// Getter for the 'is_default' property of the version.
3845///
3846/// @return true iff this is a default version.
3847bool
3849{return priv_->is_default_;}
3850
3851/// Setter for the 'is_default' property of the version.
3852///
3853/// @param f true if this is the default version.
3854void
3856{priv_->is_default_ = f;}
3857
3858bool
3859elf_symbol::version::is_empty() const
3860{return str().empty();}
3861
3862/// Compares the current version against another one.
3863///
3864/// @param o the other version to compare the current one to.
3865///
3866/// @return true iff the current version equals @p o.
3867bool
3869{return str() == o.str();}
3870
3871/// Inequality operator.
3872///
3873/// @param o the version to compare against the current one.
3874///
3875/// @return true iff both versions are different.
3876bool
3878{return !operator==(o);}
3879
3880/// Assign a version to the current one.
3881///
3882/// @param o the other version to assign to this one.
3883///
3884/// @return a reference to the assigned version.
3887{
3888 str(o.str());
3889 is_default(o.is_default());
3890 return *this;
3891}
3892
3893// </elf_symbol::version stuff>
3894
3895// </elf_symbol stuff>
3896
3897// <class dm_context_rel stuff>
3898struct dm_context_rel::priv
3899{
3900 bool is_laid_out_;
3901 size_t offset_in_bits_;
3902 var_decl_wptr anonymous_data_member_;
3903
3904 priv(bool is_static = false)
3905 : is_laid_out_(!is_static),
3906 offset_in_bits_(0)
3907 {}
3908
3909 priv(bool is_laid_out, size_t offset_in_bits)
3910 : is_laid_out_(is_laid_out),
3911 offset_in_bits_(offset_in_bits)
3912 {}
3913}; //end struct dm_context_rel::priv
3914
3915dm_context_rel::dm_context_rel()
3916 : context_rel(),
3917 priv_(new priv)
3918{}
3919
3920dm_context_rel::dm_context_rel(scope_decl_sptr s,
3921 bool is_laid_out,
3922 size_t offset_in_bits,
3924 bool is_static)
3925 : context_rel(s, a, is_static),
3926 priv_(new priv(is_laid_out, offset_in_bits))
3927{}
3928
3929dm_context_rel::dm_context_rel(scope_decl_sptr s)
3930 : context_rel(s),
3931 priv_(new priv())
3932{}
3933
3934bool
3935dm_context_rel::get_is_laid_out() const
3936{return priv_->is_laid_out_;}
3937
3938void
3939dm_context_rel::set_is_laid_out(bool f)
3940{priv_->is_laid_out_ = f;}
3941
3942size_t
3943dm_context_rel::get_offset_in_bits() const
3944{return priv_->offset_in_bits_;}
3945
3946void
3947dm_context_rel::set_offset_in_bits(size_t o)
3948{priv_->offset_in_bits_ = o;}
3949
3950bool
3951dm_context_rel::operator==(const dm_context_rel& o) const
3952{
3953 if (!context_rel::operator==(o))
3954 return false;
3955
3956 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3957 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3958}
3959
3960bool
3961dm_context_rel::operator!=(const dm_context_rel& o) const
3962{return !operator==(o);}
3963
3964/// Return a non-nil value if this data member context relationship
3965/// has an anonymous data member. That means, if the data member this
3966/// relation belongs to is part of an anonymous data member.
3967///
3968/// @return the containing anonymous data member of this data member
3969/// relationship. Nil if there is none.
3970const var_decl_sptr
3972{
3973 var_decl_sptr result = priv_->anonymous_data_member_.lock();
3974 return result;
3975}
3976
3977/// Set the containing anonymous data member of this data member
3978/// context relationship. That means that the data member this
3979/// relation belongs to is part of an anonymous data member.
3980///
3981/// @param anon_dm the containing anonymous data member of this data
3982/// member relationship. Nil if there is none.
3983void
3985{priv_->anonymous_data_member_ = anon_dm;}
3986
3987dm_context_rel::~dm_context_rel()
3988{}
3989// </class dm_context_rel stuff>
3990
3991// <homonym_type_group stuff>
3992
3993/// Add a type to a homonym type group.
3994///
3995/// If the type is already present in the group, this function does
3996/// nothing.
3997///
3998/// @param t the type to add to the group.
3999///
4000/// @param group the homonym type group to add the type to.
4001void
4002add_type(type_base_sptr t, homonym_type_group_sptr group)
4003{
4004 if (group->types_set_.find(t) != group->types_set_.end())
4005 return;
4006 group->types_set_.insert(t);
4007 group->types_.push_back(t);
4008 t->priv_->group = group;
4009}
4010
4011/// Add a canonical type to a homonym type group.
4012///
4013/// If @p t is already in the group's canonical type set, it is not
4014/// added again.
4015///
4016/// @param t the canonical type to add to @p group.
4017///
4018/// @param group the homonym type group to add @p t to.
4019void
4021{
4022 if (group->canonical_types_set_.find(t) != group->types_set_.end())
4023 return;
4024 group->canonical_types_set_.insert(t);
4025 group->canonical_types_.push_back(t);
4026 t->priv_->group = group;
4027}
4028
4029/// Compute the canonical type for a given instance of @ref type_base.
4030///
4031/// Consider two types T and T'. The canonical type of T, denoted
4032/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
4033/// otherwise, to compare two types, one just needs to compare their
4034/// canonical types using pointer equality. That makes type
4035/// comparison faster than the structural comparison performed by the
4036/// abigail::ir::equals() overloads.
4037///
4038/// If there is not yet any canonical type for @p t, then @p t is its
4039/// own canonical type. Otherwise, this function returns the
4040/// canonical type of @p t which is the canonical type that has the
4041/// same hash value as @p t and that structurally equals @p t. Note
4042/// that after invoking this function, the life time of the returned
4043/// canonical time is then equals to the life time of the current
4044/// process.
4045///
4046/// @param t a smart pointer to instance of @ref type_base we want to
4047/// compute a canonical type for.
4048///
4049/// @param this_group this a shared_ptr to the current instance of
4050/// @ref homonym_type_group. This is used as an argument for
4051/// homonym_type_group::add_canonical_type.
4052///
4053/// @return the canonical type for @p t.
4054type_base_sptr
4056 homonym_type_group_sptr this_group)
4057{
4058 ABG_ASSERT(this_group.get() == this);
4059
4060 if (!t)
4061 return t;
4062
4064 // This type should not be canonicalized!
4065 return type_base_sptr();
4066
4067 if (t->get_canonical_type())
4068 return t->get_canonical_type();
4069
4070 if (auto d = is_decl(t))
4071 {
4072 // All type decalrations must have a scope at this point.
4073 ABG_ASSERT(d->get_scope());
4075 }
4076
4077 string repr = t->get_cached_pretty_representation(/*internal=*/true);
4078
4079 type_base_sptr result;
4080 result = candidate_matches_a_canonical_type_hash(canonical_types_, *t);
4081 if (!result)
4082 for (auto canonical_type : reverse(canonical_types_))
4083 {
4084 bool equal =
4086 if (equal)
4087 {
4088 result = canonical_type;
4089 break;
4090 }
4091 }
4092
4093#ifdef WITH_DEBUG_SELF_COMPARISON
4094 environment& env = const_cast<environment&>(t->get_environment());
4095
4096 if (env.self_comparison_debug_is_on())
4097 {
4098 // So we are debugging the canonicalization process,
4099 // possibly via the use of 'abidw --debug-abidiff <binary>' or
4100 // 'abidiff --debug-self-comparison <binary> <binary>'
4101 corpus_sptr corp1, corp2;
4102 env.get_self_comparison_debug_inputs(corp1, corp2);
4103 if (corp1 && corp2 && type_originates_from_corpus(t, corp2))
4104 {
4105 // If 't' comes from the second corpus, then it *must* be
4106 // equal to its matching canonical type coming from the
4107 // first corpus because the second corpus is equivalent to
4108 // the first corpus. In other words, all types coming from
4109 // the second corpus must have canonical types coming from
4110 // the first corpus.
4111 if (result)
4112 {
4113 if ((corp1->get_origin() != corp2->get_origin()
4114 && (corp2->get_origin() & corpus::NATIVE_XML_ORIGIN))
4115 && !env.priv_->
4116 check_canonical_type_from_abixml_during_self_comp(t, result))
4117 {
4118 // We must be in the case of 'abidw --debug-abidiff <binary>'
4119 //
4120 // The canonical type of the type re-read from abixml
4121 // type doesn't match the canonical type that was
4122 // initially serialized down.
4123 uintptr_t should_have_canonical_type = 0;
4124 string type_id = env.get_type_id_from_type(t.get());
4125 if (type_id.empty())
4126 type_id = "type-id-<not-found>";
4127 else
4128 should_have_canonical_type =
4129 env.get_canonical_type_from_type_id(type_id.c_str());
4130
4131 std::cerr << "error: wrong canonical type for '"
4132 << repr
4133 << "' / type: @"
4134 << std::hex
4135 << t.get()
4136 << "/ canon: @"
4137 << result.get()
4138 << ", type-id: '"
4139 << type_id
4140 << "'. Should have had canonical type: "
4141 << std::hex
4142 << should_have_canonical_type
4143 << std::dec
4144 << std::endl;
4145 }
4146 }
4147 else //!result
4148 {
4149 if (corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
4150 {
4151 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
4152 string type_id = env.get_type_id_from_pointer(ptr_val);
4153 if (type_id.empty())
4154 type_id = "type-id-<not-found>";
4155 // We are in the case where 't' is different from all
4156 // the canonical types of the same name that come from
4157 // the first corpus.
4158 //
4159 // If 't' indeed comes from the second corpus then this
4160 // clearly is a canonicalization failure.
4161 //
4162 // There was a problem either during the serialization
4163 // of 't' into abixml, or during the de-serialization
4164 // from abixml into abigail::ir. Further debugging is
4165 // needed to determine what that root cause problem is.
4166 //
4167 // Note that the first canonicalization problem of this
4168 // kind must be fixed before looking at the subsequent
4169 // ones, because the later might well just be
4170 // consequences of the former.
4171 std::cerr << "error: wrong induced canonical type for '"
4172 << repr
4173 << "' from second corpus"
4174 << ", ptr: " << std::hex << t.get()
4175 << " type-id: " << type_id
4176 << " /hash="
4177 << *t->hash_value()
4178 << std::dec
4179 << std::endl;
4180 }
4181 else // The second corpus is not ABIXML
4182 {
4183 std::cerr << "error: wrong induced canonical type for '"
4184 << repr
4185 << "' from second corpus"
4186 << ", ptr: " << std::hex << t.get()
4187 << " /hash="
4188 << *t->hash_value()
4189 << std::dec
4190 << std::endl;
4191 }
4192 }
4193 }
4194 if (result)
4195 {
4196 if (!is_type_decl(t))
4197 if (hash_t t_hash = peek_hash_value(*t))
4198 if (hash_t result_hash = peek_hash_value(*result))
4199 if (t_hash != result_hash)
4200 {
4201 std::cerr << "error: type hash mismatch"
4202 << " between type: '"
4203 << repr
4204 << "' @ "
4205 << std::hex
4206 << t.get()
4207 << "/hash="
4208 << *t->hash_value()
4209 << " and its computed canonical type @"
4210 << std::hex
4211 << result.get()
4212 << "/hash="
4213 << std::hex
4214 << *result->hash_value()
4215 << std::dec
4216 << std::endl;
4217 }
4218 }
4219 }
4220#endif //WITH_DEBUG_SELF_COMPARISON
4221
4222 if (result)
4223 return result;
4224
4225 result = t;
4226
4227 if (!canonical_types_.empty())
4228 {
4229 int canonical_type_index = 0;
4230 if (compute_canonical_type_index(canonical_types_, result,
4231 canonical_type_index))
4232 t->priv_->canonical_type_index = canonical_type_index;
4233 }
4234
4235 add_canonical_type(result, this_group);
4236
4237 return result;
4238}
4239
4240// </homonym_type_group stuff>
4241
4242// <environment stuff>
4243
4244thread_local string variadic_parameter_type_name = "variadic parameter type";
4245
4246/// Convenience typedef for a map of interned_string -> bool.
4247typedef unordered_map<interned_string,
4249
4250
4251/// Default constructor of the @ref environment type.
4253 :priv_(new priv)
4254{}
4255
4256/// Destructor for the @ref environment type.
4259
4260/// Getter the map of canonical types.
4261///
4262/// @return the map of canonical types. The key of the map is the
4263/// hash of the canonical type and its value if the canonical type.
4266{return priv_->canonical_types_;}
4267
4268/// Getter the map of canonical types.
4269///
4270/// @return the map of canonical types. The key of the map is the
4271/// hash of the canonical type and its value if the canonical type.
4275
4276/// Helper to detect if a type is either a reference, a pointer, or a
4277/// qualified type.
4278bool
4280{
4281 if (is_pointer_type(t)
4282 || is_reference_type(t)
4283 || is_qualified_type(t))
4284 return true;
4285 return false;
4286}
4287
4288/// Compare decls using their locations.
4289///
4290/// @param f the first decl to compare.
4291///
4292/// @param s the second decl to compare.
4293///
4294/// @param result out parameter; set true if @p f compares less than
4295/// @p s. This is set iff the function returned true.
4296///
4297/// @return true iff if comparison could be actually done.
4298bool
4299compare_using_locations(const decl_base *f, const decl_base *s, bool& result)
4300{
4301 // If a decl has artificial location, then use that one over the
4302 // natural one.
4305
4306 ABG_ASSERT(fl.get_value() && sl.get_value());
4307 if (fl.get_is_artificial() && sl.get_is_artificial())
4308 {
4309 result = fl.get_artificial_value() < sl.get_artificial_value();
4310 return true;
4311 }
4312 else
4313 {
4314 // The locations of the two artifacts are not artificial so they
4315 // have to be expanded to be compared.
4316 string p1, p2;
4317 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
4318
4319 fl.expand(p1, l1, c1);
4320 sl.expand(p2, l2, c2);
4321 if (p1 != p2)
4322 {
4323 result = p1 < p2;
4324 return true;
4325 }
4326 if (l1 != l2)
4327 {
4328 result =l1 < l2;
4329 return true;
4330 }
4331 if (c1 != c2)
4332 {
4333 result = c1 < c2;
4334 return true;
4335 }
4336 }
4337
4338 auto fs = f->get_cached_pretty_representation(/*internal=*/false);
4339 auto ss = s->get_cached_pretty_representation(/*internal=*/false);
4340 if (fs != ss)
4341 {
4342 result = fs < ss;
4343 return true;
4344 }
4345
4346 return false;
4347}
4348
4349/// Sort types in a hopefully stable manner.
4350///
4351/// @param types a set of types with canonical types to sort.
4352///
4353/// @param result the resulting sorted vector.
4354void
4356 vector<type_base_sptr>& result)
4357{
4358 for (auto t: types)
4359 result.push_back(t);
4360
4361 type_topo_comp comp;
4362 std::stable_sort(result.begin(), result.end(), comp);
4363}
4364
4365/// Get the unique @ref type_decl that represents a "void" type for
4366/// the current environment. This node must be the only one
4367/// representing a void type in the system.
4368///
4369/// Note that upon first use of this IR node (by the relevant
4370/// front-end, for instance) it must be added to a scope using e.g,
4371/// the @ref add_decl_to_scope() function.
4372///
4373/// @return the @ref type_decl that represents a "void" type.
4374const type_base_sptr&
4376{
4377 lock_guard<mutex> lock(priv_->void_type_mutex_);
4378 if (!priv_->void_type_)
4379 priv_->void_type_.reset(new type_decl(*this,
4380 intern("void"),
4381 0, 0, location()));
4382 return priv_->void_type_;
4383}
4384
4385/// Getter of the "pointer-to-void" IR node that is shared across the
4386/// ABI corpus. This node must be the only one representing a void
4387/// pointer type in the system.
4388///
4389/// Note that upon first use of this IR node (by the relevant
4390/// front-end, for instance) it must be added to a scope using e.g,
4391/// the @ref add_decl_to_scope() function.
4392///
4393/// @return the "pointer-to-void" IR node.
4394const type_base_sptr&
4396{
4397 lock_guard<mutex> lock(priv_->void_pointer_type_mutex_);
4398 if (!priv_->void_pointer_type_)
4399 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
4400 0, 0, location()));
4401 return priv_->void_pointer_type_;
4402}
4403
4404/// Get a @ref type_decl instance that represents a the type of a
4405/// variadic function parameter. This node must be the only one
4406/// representing a variadic parameter type in the system.
4407///
4408/// Note that upon first use of this IR node (by the relevant
4409/// front-end, for instance) it must be added to a scope using e.g,
4410/// the @ref add_decl_to_scope() function.
4411///
4412/// @return the Get a @ref type_decl instance that represents a the
4413/// type of a variadic function parameter.
4414const type_base_sptr&
4416{
4417 lock_guard<mutex> lock(priv_->variadic_marker_type_mutex_);
4418 if (!priv_->variadic_marker_type_)
4419 priv_->variadic_marker_type_.
4421 0, 0, location()));
4422 return priv_->variadic_marker_type_;
4423}
4424
4425/// Getter of the name of the variadic parameter type.
4426///
4427/// @return the name of the variadic parameter type.
4428string&
4430{
4431 return variadic_parameter_type_name;
4432}
4433
4434/// Getter of the "decl-only-class-equals-definition" flag.
4435///
4436/// Usually, a declaration-only class named 'struct foo' compares
4437/// equal to any class definition named "struct foo'. This is at
4438/// least true for C++.
4439///
4440/// In C, though, because there can be multiple definitions of 'struct
4441/// foo' in the binary, a declaration-only "struct foo" might be
4442/// considered to *NOT* resolve to any of the struct foo defined. In
4443/// that case, the declaration-only "struct foo" is considered
4444/// different from the definitions.
4445///
4446/// This flag controls the behaviour of the comparison of an
4447/// unresolved decl-only class against a definition of the same name.
4448///
4449/// If set to false, the the declaration equals the definition. If
4450/// set to false, then the decalration is considered different from
4451/// the declaration.
4452///
4453/// @return the value of the "decl-only-class-equals-definition" flag.
4454bool
4456{return priv_->decl_only_class_equals_definition_;}
4457
4458/// Setter of the "decl-only-class-equals-definition" flag.
4459///
4460/// Usually, a declaration-only class named 'struct foo' compares
4461/// equal to any class definition named "struct foo'. This is at
4462/// least true for C++.
4463///
4464/// In C, though, because there can be multiple definitions of 'struct
4465/// foo' in the binary, a declaration-only "struct foo" might be
4466/// considered to *NOT* resolve to any of the struct foo defined. In
4467/// that case, the declaration-only "struct foo" is considered
4468/// different from the definitions.
4469///
4470/// This flag controls the behaviour of the comparison of an
4471/// unresolved decl-only class against a definition of the same name.
4472///
4473/// If set to false, the the declaration equals the definition. If
4474/// set to false, then the decalration is considered different from
4475/// the declaration.
4476///
4477/// @param the new value of the "decl-only-class-equals-definition"
4478/// flag.
4479void
4481{priv_->decl_only_class_equals_definition_ = f;}
4482
4483/// Test if a given type is a void type as defined in the current
4484/// environment.
4485///
4486/// @param t the type to consider.
4487///
4488/// @return true iff @p t is a void type as defined in the current
4489/// environment.
4490bool
4491environment::is_void_type(const type_base_sptr& t) const
4492{
4493 if (!t)
4494 return false;
4495 return is_void_type(t.get());
4496}
4497
4498/// Test if a given type is a void type as defined in the current
4499/// environment.
4500///
4501/// @param t the type to consider.
4502///
4503/// @return true iff @p t is a void type as defined in the current
4504/// environment.
4505bool
4507{
4508 if (!t)
4509 return false;
4510 return (t == get_void_type().get()
4511 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
4512}
4513
4514/// Test if a given type is the same as the void pointer type of the
4515/// environment.
4516///
4517/// @param t the IR type to test.
4518///
4519/// @return true iff @p t is the void pointer returned by
4520/// environment::get_void_pointer_type().
4521bool
4522environment::is_void_pointer_type(const type_base_sptr& t) const
4523{
4524 if (!t)
4525 return false;
4526
4527 return t.get() == get_void_pointer_type().get();
4528}
4529
4530/// Test if a given type is the same as the void pointer type of the
4531/// environment.
4532///
4533/// @param t the IR type to test.
4534///
4535/// @return true iff @p t is the void pointer returned by
4536/// environment::get_void_pointer_type().
4537bool
4539{
4540 if (!t)
4541 return false;
4542
4543 return t == get_void_pointer_type().get();
4544}
4545
4546/// Test if a type is a variadic parameter type as defined in the
4547/// current environment.
4548///
4549/// @param t the type to consider.
4550///
4551/// @return true iff @p t is a variadic parameter type as defined in
4552/// the current environment.
4553bool
4555{
4556 if (!t)
4557 return false;
4558 return t == get_variadic_parameter_type().get();
4559}
4560
4561/// Test if a type is a variadic parameter type as defined in the
4562/// current environment.
4563///
4564/// @param t the type to consider.
4565///
4566/// @return true iff @p t is a variadic parameter type as defined in
4567/// the current environment.
4568bool
4569environment::is_variadic_parameter_type(const type_base_sptr& t) const
4570{return is_variadic_parameter_type(t.get());}
4571
4572/// Do intern a string.
4573///
4574/// If a value of this string already exists in the interned string
4575/// pool of the current environment, then this function returns a new
4576/// interned_string pointing to that already existing string.
4577/// Otherwise, a new string is created, stored in the interned string
4578/// pool and a new interned_string instance is created to point to
4579/// that new intrerned string, and it's return.
4580///
4581/// @param s the value of the string to intern.
4582///
4583/// @return the interned string.
4585environment::intern(const string& s) const
4586{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
4587
4588/// Getter of the general configuration object.
4589///
4590/// @return the configuration object.
4591const config&
4593{return priv_->config_;}
4594
4595/// Getter for a property that says if the user actually did set the
4596/// analyze_exported_interfaces_only() property. If not, it means
4597/// the default behaviour prevails.
4598///
4599/// @return tru iff the user did set the
4600/// analyze_exported_interfaces_only() property.
4601bool
4603{return priv_->analyze_exported_interfaces_only_.has_value();}
4604
4605/// Setter for the property that controls if we are to restrict the
4606/// analysis to the types that are only reachable from the exported
4607/// interfaces only, or if the set of types should be more broad than
4608/// that. Typically, we'd restrict the analysis to types reachable
4609/// from exported interfaces only (stricto sensu, that would really be
4610/// only the types that are part of the ABI of well designed
4611/// libraries) for performance reasons.
4612///
4613/// @param f the value of the flag.
4614void
4616{priv_->analyze_exported_interfaces_only_ = f;}
4617
4618/// Getter for the property that controls if we are to restrict the
4619/// analysis to the types that are only reachable from the exported
4620/// interfaces only, or if the set of types should be more broad than
4621/// that. Typically, we'd restrict the analysis to types reachable
4622/// from exported interfaces only (stricto sensu, that would really be
4623/// only the types that are part of the ABI of well designed
4624/// libraries) for performance reasons.
4625///
4626/// @param f the value of the flag.
4627bool
4629{return priv_->analyze_exported_interfaces_only_.value_or(false);}
4630
4631bool
4632environment::user_set_load_all_types() const
4633{return priv_->load_all_types_.has_value();}
4634
4635void
4636environment::load_all_types(bool f)
4637{priv_->load_all_types_ = f;}
4638
4639bool
4640environment::load_all_types() const
4641{return priv_->load_all_types_.value_or(false);}
4642
4643/// Getter of the number of threads to use, as set by the user.
4644///
4645/// If the function returns zero, then it means the user didn't set
4646/// any value.
4647///
4648/// @return the number of threads to use, as set by the user.
4649size_t
4651{return environment::priv::number_of_threads_to_use_.load();}
4652
4653/// Setter of the number of threads to use, as set by the user.
4654///
4655/// If the number is zero, then it means the user didn't set any
4656/// value. Also, note that the number cannot be higher than twice the
4657/// number of available cores on the undelying machine.
4658///
4659/// @param n the number of threads to use, as set by the user.
4660void
4662{
4663 environment::priv::number_of_threads_to_use_ =
4665}
4666
4667#ifdef WITH_DEBUG_SELF_COMPARISON
4668/// Setter of the corpus of the input corpus of the self comparison
4669/// that takes place when doing "abidw --debug-abidiff <binary>".
4670///
4671/// The first invocation of this function sets the first corpus of the
4672/// self comparison. The second invocation of this very same function
4673/// sets the second corpus of the self comparison. That second corpus
4674/// is supposed to come from the abixml serialization of the first
4675/// corpus.
4676///
4677/// @param c the corpus of the input binary or the corpus of the
4678/// abixml serialization of the initial binary input.
4679void
4680environment::set_self_comparison_debug_input(const corpus_sptr& c)
4681{
4682 self_comparison_debug_is_on(true);
4683 if (priv_->first_self_comparison_corpus_.expired())
4684 priv_->first_self_comparison_corpus_ = c;
4685 else if (priv_->second_self_comparison_corpus_.expired()
4686 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
4687 priv_->second_self_comparison_corpus_ = c;
4688}
4689
4690/// Getter for the corpora of the input binary and the intermediate
4691/// abixml of the self comparison that takes place when doing
4692/// 'abidw --debug-abidiff <binary>'.
4693///
4694/// @param first_corpus output parameter that is set to the corpus of
4695/// the input corpus.
4696///
4697/// @param second_corpus output parameter that is set to the corpus of
4698/// the second corpus.
4699void
4700environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
4701 corpus_sptr& second_corpus)
4702{
4703 first_corpus = priv_->first_self_comparison_corpus_.lock();
4704 second_corpus = priv_->second_self_comparison_corpus_.lock();
4705}
4706
4707/// Turn on/off the self comparison debug mode.
4708///
4709/// @param f true iff the self comparison debug mode is turned on.
4710void
4711environment::self_comparison_debug_is_on(bool f)
4712{priv_->self_comparison_debug_on_ = f;}
4713
4714/// Test if we are in the process of the 'self-comparison
4715/// debugging' as triggered by 'abidw --debug-abidiff' command.
4716///
4717/// @return true if self comparison debug is on.
4718bool
4719environment::self_comparison_debug_is_on() const
4720{return priv_->self_comparison_debug_on_;}
4721#endif
4722
4723#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
4724/// Set the "type canonicalization debugging" mode, triggered by using
4725/// the command: "abidw --debug-tc".
4726///
4727/// @param flag if true then the type canonicalization debugging mode
4728/// is enabled.
4729void
4730environment::debug_type_canonicalization_is_on(bool flag)
4731{priv_->debug_type_canonicalization_ = flag;}
4732
4733/// Getter of the "type canonicalization debugging" mode, triggered by
4734/// using the command: "abidw --debug-tc".
4735///
4736/// @return true iff the type canonicalization debugging mode is
4737/// enabled.
4738bool
4739environment::debug_type_canonicalization_is_on() const
4740{return priv_->debug_type_canonicalization_;}
4741
4742/// Setter of the "DIE canonicalization debugging" mode, triggered by
4743/// using the command: "abidw --debug-dc".
4744///
4745/// @param flag true iff the DIE canonicalization debugging mode is
4746/// enabled.
4747void
4748environment::debug_die_canonicalization_is_on(bool flag)
4749{priv_->debug_die_canonicalization_ = flag;}
4750
4751/// Getter of the "DIE canonicalization debugging" mode, triggered by
4752/// using the command: "abidw --debug-dc".
4753///
4754/// @return true iff the DIE canonicalization debugging mode is
4755/// enabled.
4756bool
4757environment::debug_die_canonicalization_is_on() const
4758{return priv_->debug_die_canonicalization_;}
4759#endif // WITH_DEBUG_TYPE_CANONICALIZATION
4760
4761/// Get the vector of canonical types which have a given "string
4762/// representation".
4763///
4764/// @param 'name', the textual representation of the type as returned
4765/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
4766/// /*qualified=*/true)
4767///
4768/// This is useful to for debugging purposes as it's handy to use from
4769/// inside a debugger like GDB.
4770///
4771/// @return a pointer to the vector of canonical types having the
4772/// representation @p name, or nullptr if no type with that
4773/// representation exists.
4774const vector<type_base_sptr>*
4776{
4777 auto ti = get_canonical_types_map().find(name);
4778 if (ti == get_canonical_types_map().end())
4779 return nullptr;
4780 return &ti->second;
4781}
4782
4783/// Get the vector of canonical types which have a given "string
4784/// representation".
4785///
4786/// @param 'name', the textual representation of the type as returned
4787/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
4788/// /*qualified=*/true)
4789///
4790/// This is useful to for debugging purposes as it's handy to use from
4791/// inside a debugger like GDB.
4792///
4793/// @return a pointer to the vector of canonical types having the
4794/// representation @p name, or nullptr if no type with that
4795/// representation exists.
4796const vector<type_base_sptr>*
4797environment::get_canonical_types(const string& name) const
4798{
4799 if (name.empty())
4800 return nullptr;
4801 return get_canonical_types(name.c_str());
4802}
4803
4804/// Get a given canonical type which has a given "string
4805/// representation".
4806///
4807/// @param 'name', the textual representation of the type as returned
4808/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
4809/// /*qualified=*/true).
4810///
4811/// @param index, the index of the type in the vector of types that
4812/// all have the same textual representation @p 'name'. That vector
4813/// is returned by the function environment::get_canonical_types().
4814///
4815/// @return the canonical type which has the representation @p name,
4816/// and which is at index @p index in the vector of canonical types
4817/// having that same textual representation.
4818type_base*
4819environment::get_canonical_type(const char* name, unsigned index)
4820{
4821 const vector<type_base_sptr> *types = get_canonical_types(name);
4822 if (!types ||index >= types->size())
4823 return nullptr;
4824 return (*types)[index].get();
4825}
4826
4827/// Get the sorted list of canonical types
4828///
4829/// @return the sorted list of canonical types.
4830const vector<type_base_sptr>&
4832{
4833 if (priv_->sorted_canonical_types_.empty())
4834 {
4835 for (auto& entry : priv_->canonical_types_)
4836 for (auto t : entry.second)
4837 priv_->sorted_canonical_types_.push_back(t);
4838
4839 type_topo_comp comp;
4840 std::sort(priv_->sorted_canonical_types_.begin(),
4841 priv_->sorted_canonical_types_.end(),
4842 comp);
4843 }
4844
4845 return priv_->sorted_canonical_types_;
4846}
4847
4848#ifdef WITH_DEBUG_SELF_COMPARISON
4849/// Get the set of abixml type-id and the pointer value of the
4850/// (canonical) type it's associated to.
4851///
4852/// This is useful for debugging purposes, especially in the context
4853/// of the use of the command:
4854/// 'abidw --debug-abidiff <binary>'.
4855///
4856/// @return the set of abixml type-id and the pointer value of the
4857/// (canonical) type it's associated to.
4858const unordered_map<string, uintptr_t>&
4859environment::get_type_id_canonical_type_map() const
4860{return priv_->get_type_id_canonical_type_map();}
4861
4862/// Get the set of abixml type-id and the pointer value of the
4863/// (canonical) type it's associated to.
4864///
4865/// This is useful for debugging purposes, especially in the context
4866/// of the use of the command:
4867/// 'abidw --debug-abidiff <binary>'.
4868///
4869/// @return the set of abixml type-id and the pointer value of the
4870/// (canonical) type it's associated to.
4871unordered_map<string, uintptr_t>&
4872environment::get_type_id_canonical_type_map()
4873{return priv_->get_type_id_canonical_type_map();}
4874
4875/// Getter of the map that associates the values of type pointers to
4876/// their type-id strings.
4877///
4878/// Note that this map is populated at abixml reading time, (by
4879/// build_type()) when a given XML element representing a type is
4880/// read into a corresponding abigail::ir::type_base.
4881///
4882/// This is used only for the purpose of debugging the
4883/// self-comparison process. That is, when invoking "abidw
4884/// --debug-abidiff".
4885///
4886/// @return the map that associates the values of type pointers to
4887/// their type-id strings.
4888const unordered_map<uintptr_t, string>&
4889environment::get_pointer_type_id_map() const
4890{return priv_->get_pointer_type_id_map();}
4891
4892/// Getter of the map that associates the values of type pointers to
4893/// their type-id strings.
4894///
4895/// Note that this map is populated at abixml reading time, (by
4896/// build_type()) when a given XML element representing a type is
4897/// read into a corresponding abigail::ir::type_base.
4898///
4899/// This is used only for the purpose of debugging the
4900/// self-comparison process. That is, when invoking "abidw
4901/// --debug-abidiff".
4902///
4903/// @return the map that associates the values of type pointers to
4904/// their type-id strings.
4905unordered_map<uintptr_t, string>&
4906environment::get_pointer_type_id_map()
4907{return priv_->get_pointer_type_id_map();}
4908
4909/// Getter of the type-id that corresponds to the value of a pointer
4910/// to abigail::ir::type_base that was created from the abixml reader.
4911///
4912/// That value is retrieved from the map returned from
4913/// environment::get_pointer_type_id_map().
4914///
4915/// That map is populated at abixml reading time, (by build_type())
4916/// when a given XML element representing a type is read into a
4917/// corresponding abigail::ir::type_base.
4918///
4919/// This is used only for the purpose of debugging the
4920/// self-comparison process. That is, when invoking "abidw
4921/// --debug-abidiff".
4922///
4923/// @return the type-id strings that corresponds
4924string
4925environment::get_type_id_from_pointer(uintptr_t ptr) const
4926{return priv_->get_type_id_from_pointer(ptr);}
4927
4928/// Getter of the type-id that corresponds to the value of an
4929/// abigail::ir::type_base that was created from the abixml reader.
4930///
4931/// That value is retrieved from the map returned from
4932/// environment::get_pointer_type_id_map().
4933///
4934/// That map is populated at abixml reading time, (by build_type())
4935/// when a given XML element representing a type is read into a
4936/// corresponding abigail::ir::type_base.
4937///
4938/// This is used only for the purpose of debugging the
4939/// self-comparison process. That is, when invoking "abidw
4940/// --debug-abidiff".
4941///
4942/// @return the type-id strings that corresponds
4943string
4944environment::get_type_id_from_type(const type_base *t) const
4945{return priv_->get_type_id_from_type(t);}
4946
4947/// Getter of the canonical type of the artifact designated by a
4948/// type-id.
4949///
4950/// That type-id was generated by the abixml writer at the emitting
4951/// time of the abixml file. The corresponding canonical type was
4952/// stored in the map returned by
4953/// environment::get_type_id_canonical_type_map().
4954///
4955/// This is useful for debugging purposes, especially in the context
4956/// of the use of the command:
4957/// 'abidw --debug-abidiff <binary>'.
4958///
4959/// @return the set of abixml type-id and the pointer value of the
4960/// (canonical) type it's associated to.
4961uintptr_t
4962environment::get_canonical_type_from_type_id(const char* type_id) const
4963{return priv_->get_canonical_type_from_type_id(type_id);}
4964#endif
4965
4966// </environment stuff>
4967
4968// <type_or_decl_base stuff>
4969
4970/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4971/// bitmap type.
4975{
4976 return static_cast<type_or_decl_base::type_or_decl_kind>
4977 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4978}
4979
4980/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4981/// bitmap type.
4985{
4986 l = l | r;
4987 return l;
4988}
4989
4990/// bitwise "AND" operator for the
4991/// type_or_decl_base::type_or_decl_kind bitmap type.
4995{
4996 return static_cast<type_or_decl_base::type_or_decl_kind>
4997 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4998}
4999
5000/// bitwise "A&=" operator for the
5001/// type_or_decl_base::type_or_decl_kind bitmap type.
5005{
5006 l = l & r;
5007 return l;
5008}
5009
5010/// Constructor of @ref type_or_decl_base.
5011///
5012/// @param the environment the current ABI artifact is constructed
5013/// from.
5014///
5015/// @param k the runtime identifier bitmap of the type being built.
5016type_or_decl_base::type_or_decl_base(const environment& e,
5017 enum type_or_decl_kind k)
5018 :priv_(new priv(e, k))
5019{}
5020
5021/// The destructor of the @ref type_or_decl_base type.
5024
5025/// Getter of the flag that says if the artefact is artificial.
5026///
5027/// Being artificial means it was not explicitely mentionned in the
5028/// source code, but was rather artificially created by the compiler
5029/// or libabigail.
5030///
5031/// @return true iff the declaration is artificial.
5032bool
5034{return priv_->is_artificial_;}
5035
5036/// Setter of the flag that says if the artefact is artificial.
5037///
5038/// Being artificial means the artefact was not explicitely
5039/// mentionned in the source code, but was rather artificially created
5040/// by the compiler or by libabigail.
5041///
5042/// @param f the new value of the flag that says if the artefact is
5043/// artificial.
5044void
5046{priv_->is_artificial_ = f;}
5047
5048/// Getter for the "kind" property of @ref type_or_decl_base type.
5049///
5050/// This property holds the identifier bitmap of the runtime type of
5051/// an ABI artifact.
5052///
5053/// @return the runtime type identifier bitmap of the current ABI
5054/// artifact.
5057{return priv_->kind();}
5058
5059/// Setter for the "kind" property of @ref type_or_decl_base type.
5060///
5061/// This property holds the identifier bitmap of the runtime type of
5062/// an ABI artifact.
5063///
5064/// @param the runtime type identifier bitmap of the current ABI
5065/// artifact.
5066void
5068{priv_->kind(k);}
5069
5070/// Getter of the pointer to the runtime type sub-object of the
5071/// current instance.
5072///
5073/// @return the pointer to the runtime type sub-object of the current
5074/// instance.
5075const void*
5077{return priv_->rtti_;}
5078
5079/// Getter of the pointer to the runtime type sub-object of the
5080/// current instance.
5081///
5082/// @return the pointer to the runtime type sub-object of the current
5083/// instance.
5084void*
5086{return priv_->rtti_;}
5087
5088/// Setter of the pointer to the runtime type sub-object of the
5089/// current instance.
5090///
5091/// @param i the new pointer to the runtime type sub-object of the
5092/// current instance.
5093void
5095{
5096 priv_->rtti_ = i;
5097 if (type_base* t = dynamic_cast<type_base*>(this))
5098 priv_->type_or_decl_ptr_ = t;
5099 else if (decl_base *d = dynamic_cast<decl_base*>(this))
5100 priv_->type_or_decl_ptr_ = d;
5101}
5102
5103/// Getter of the pointer to either the type_base sub-object of the
5104/// current instance if it's a type, or to the decl_base sub-object of
5105/// the current instance if it's a decl.
5106///
5107/// @return the pointer to either the type_base sub-object of the
5108/// current instance if it's a type, or to the decl_base sub-object of
5109/// the current instance if it's a decl.
5110const void*
5115
5116/// Getter of the pointer to either the type_base sub-object of the
5117/// current instance if it's a type, or to the decl_base sub-object of
5118/// the current instance if it's a decl.
5119///
5120/// @return the pointer to either the type_base sub-object of the
5121/// current instance if it's a type, or to the decl_base sub-object of
5122/// the current instance if it's a decl.
5123void*
5125{return priv_->type_or_decl_ptr_;}
5126
5127/// Return the hash value of the current IR node.
5128///
5129/// Note that upon the first invocation, this member functions
5130/// computes the hash value and returns it. Subsequent invocations
5131/// just return the hash value that was previously calculated.
5132///
5133/// @return the hash value of the current IR node.
5134hash_t
5136{
5137 return priv_->hash_value_;
5138}
5139
5140void
5141type_or_decl_base::set_hash_value(hash_t h) const
5142{priv_->set_hash_value(h);}
5143
5144/// Getter of the environment of the current ABI artifact.
5145///
5146/// @return the environment of the artifact.
5147const environment&
5149{return priv_->env_;}
5150
5151/// Setter of the artificial location of the artificat.
5152///
5153/// The artificial location is a location that was artificially
5154/// generated by libabigail, not generated by the original emitter of
5155/// the ABI meta-data. For instance, when reading an XML element from
5156/// an abixml file, the artificial location is the source location of
5157/// the XML element within the file, not the value of the
5158/// 'location'property that might be carried by the element.
5159///
5160/// Artificial locations might be useful to ensure that abixml emitted
5161/// by the abixml writer are sorted the same way as the input abixml
5162/// read by the reader.
5163///
5164/// @param l the new artificial location.
5165void
5167{priv_->artificial_location_ = l;}
5168
5169/// Getter of the artificial location of the artifact.
5170///
5171/// The artificial location is a location that was artificially
5172/// generated by libabigail, not generated by the original emitter of
5173/// the ABI meta-data. For instance, when reading an XML element from
5174/// an abixml file, the artificial location is the source location of
5175/// the XML element within the file, not the value of the
5176/// 'location'property that might be carried by the element.
5177///
5178/// Artificial locations might be useful to ensure that the abixml
5179/// emitted by the abixml writer is sorted the same way as the input
5180/// abixml read by the reader.
5181///
5182/// @return the new artificial location.
5183location&
5185{return priv_->artificial_location_;}
5186
5187/// Test if the current ABI artifact carries an artificial location.
5188///
5189/// @return true iff the current ABI artifact carries an artificial location.
5190bool
5196
5197/// Get the native offset of a given artifact.
5198///
5199/// The native offset is for instance the offset of the Debug
5200/// Information Entry of the artifact has been constructed from, when
5201/// looking at DWARF debug info.
5202///
5203/// @return the native offset.
5206{return priv_->native_offset_.load();}
5207
5208/// Set the native offset of a given artifact.
5209///
5210/// The native offset is for instance the offset of the Debug
5211/// Information Entry of the artifact has been constructed from, when
5212/// looking at DWARF debug info.
5213///
5214/// @param o the new native offset of the current artifact.
5215void
5217{priv_->native_offset_ = o;}
5218
5219/// Get the @ref corpus this ABI artifact belongs to.
5220///
5221/// @return the corpus this ABI artifact belongs to, or nil if it
5222/// belongs to none for now.
5223corpus*
5225{
5226 return priv_->corpus_.load();
5227}
5228
5229/// Set the ABI corpus associated to the current ABI artifact.
5230///
5231/// @param abi_corpus the new ABI corpus of the current artifact.
5232void
5234{
5235 priv_->corpus_ = abi_corpus;
5236}
5237
5238/// Get the @ref corpus this ABI artifact belongs to.
5239///
5240/// @return the corpus this ABI artifact belongs to, or nil if it
5241/// belongs to none for now.
5242const corpus*
5244{return const_cast<type_or_decl_base*>(this)->get_corpus();}
5245
5246/// Set the @ref translation_unit this ABI artifact belongs to.
5247///
5248/// Note that adding an ABI artifact to a containining on should
5249/// invoke this member function.
5250void
5252{
5253 {
5254 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5255 priv_->translation_unit_ = tu;
5256 }
5257 if (tu)
5258 set_corpus(tu->get_corpus());
5259}
5260
5261
5262/// Get the @ref translation_unit this ABI artifact belongs to.
5263///
5264/// @return the translation unit this ABI artifact belongs to, or nil
5265/// if belongs to none for now.
5268{
5269 if (!priv_->translation_unit_)
5270 {
5271 if (decl_base *d = is_decl(this))
5272 if (auto s = d->get_scope())
5273 priv_->translation_unit_ = s->get_translation_unit();
5274 }
5275 return priv_->translation_unit_;
5276}
5277
5278/// Get the @ref translation_unit this ABI artifact belongs to.
5279///
5280/// @return the translation unit this ABI artifact belongs to, or nil
5281/// if belongs to none for now.
5282const translation_unit*
5285
5286/// Get the original artefact that the current artefact was copied from.
5287///
5288/// If the current artefact wasn't copied from anything else, then
5289/// this returns nullptr. This is set, for instance, by
5290/// copy_member_function or copy_member_variable by invoking
5291/// type_or_decl_base::set_original_artefact.
5292///
5293/// @return the original artefact that the current artefact was copied
5294/// from.
5295const type_or_decl_base*
5297{return priv_->original_artefact_;}
5298
5299/// Set the original artefact that the current artefact was copied
5300/// from.
5301///
5302/// @param o the original artefact that the current artefact was
5303/// copied from.
5304void
5306{
5307 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5308 priv_->original_artefact_ = o;
5309}
5310
5311/// Get the pretty representation of the current decl.
5312///
5313/// The pretty representation is retrieved from a cache. If the cache
5314/// is empty, this function computes the pretty representation, put it
5315/// in the cache and returns it.
5316///
5317/// Please note that if this function is called too early in the life
5318/// cycle of the decl (before it is fully constructed), then the
5319/// pretty representation that is cached is going to represent a
5320/// non-complete (and thus wrong) representation of the decl. Thus
5321/// this function must be called only once the decl is fully
5322/// constructed.
5323///
5324/// @param internal if true, then the pretty representation is to be
5325/// used for purpuses that are internal to the libabigail library
5326/// itself. If you don't know what this means, then you probably
5327/// should set this parameter to "false".
5328///
5329/// @return a reference to a cached @ref interned_string holding the
5330/// pretty representation of the current decl.
5331const interned_string&
5333{
5334 if (internal)
5335 {
5336 if (priv_->internal_cached_repr_.empty())
5337 {
5338 string r = ir::get_pretty_representation(this, internal);
5339 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5340 priv_->internal_cached_repr_ = get_environment().intern(r);
5341 }
5342 return priv_->internal_cached_repr_;
5343 }
5344
5345 if (priv_->cached_repr_.empty())
5346 {
5347 string r = ir::get_pretty_representation(this, internal);
5348 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5349 priv_->cached_repr_ = get_environment().intern(r);
5350 }
5351
5352 return priv_->cached_repr_;
5353}
5354
5355/// Get the recursive mutex associated to the artifact.
5356///
5357/// @return the recursive mutex associated to the artifact.
5358std::recursive_mutex&
5360{return priv_->mutex_;}
5361
5362/// Traverse the the ABI artifact.
5363///
5364/// @param v the visitor used to traverse the sub-tree nodes of the
5365/// artifact.
5366bool
5369
5370/// Non-member equality operator for the @type_or_decl_base type.
5371///
5372/// @param lr the left-hand operand of the equality.
5373///
5374/// @param rr the right-hand operatnr of the equality.
5375///
5376/// @return true iff @p lr equals @p rr.
5377bool
5379{
5380 const type_or_decl_base* l = &lr;
5381 const type_or_decl_base* r = &rr;
5382
5383 const decl_base* dl = dynamic_cast<const decl_base*>(l),
5384 *dr = dynamic_cast<const decl_base*>(r);
5385
5386 if (!!dl != !!dr)
5387 return false;
5388
5389 if (dl && dr)
5390 return *dl == *dr;
5391
5392 const type_base* tl = dynamic_cast<const type_base*>(l),
5393 *tr = dynamic_cast<const type_base*>(r);
5394
5395 if (!!tl != !!tr)
5396 return false;
5397
5398 if (tl && tr)
5399 return *tl == *tr;
5400
5401 return false;
5402}
5403
5404/// Non-member equality operator for the @type_or_decl_base type.
5405///
5406/// @param l the left-hand operand of the equality.
5407///
5408/// @param r the right-hand operatnr of the equality.
5409///
5410/// @return true iff @p l equals @p r.
5411bool
5413{
5414 if (!! l != !!r)
5415 return false;
5416
5417 if (!l)
5418 return true;
5419
5420 return *r == *l;
5421}
5422
5423/// Non-member inequality operator for the @type_or_decl_base type.
5424///
5425/// @param l the left-hand operand of the equality.
5426///
5427/// @param r the right-hand operator of the equality.
5428///
5429/// @return true iff @p l is different from @p r.
5430bool
5433
5434// </type_or_decl_base stuff>
5435
5436// <Decl definition>
5437
5438struct decl_base::priv
5439{
5440 // This is mutext is to be used only by add_decl_to_scope.
5441 recursive_mutex add_decl_to_scope_mutex_;
5442 // Local mutex for direct access to local data.
5443 // This mutex must be taken to access *only* local data.
5444 recursive_mutex local_mutex_;
5445 bool in_pub_sym_tab_;
5446 bool is_anonymous_;
5447 location location_;
5448 std::atomic<context_rel*> context_;
5449 interned_string name_;
5450 interned_string qualified_parent_name_;
5451 // This temporary qualified name is the cache used for the qualified
5452 // name before the type associated to this decl (if applicable) is
5453 // canonicalized. Once the type is canonicalized, the cached use is
5454 // the data member qualified_parent_name_ above.
5455 interned_string temporary_qualified_name_;
5456 // This is the fully qualified name of the decl. It contains the
5457 // name of the decl and the qualified name of its scope. So if in
5458 // the parent scopes of the decl, there is one anonymous struct,
5459 // somewhere in the name, there is going to by an
5460 // __anonymous_struct__ string, even if the anonymous struct is not
5461 // the direct containing scope of this decl.
5462 interned_string qualified_name_;
5463 interned_string temporary_internal_qualified_name_;
5464 interned_string internal_qualified_name_;
5465 interned_string internal_cached_repr_;
5466 interned_string cached_repr_;
5467 // Unline qualified_name_, scoped_name_ contains the name of the
5468 // decl and the name of its scope; not the qualified name of the
5469 // scope.
5470 interned_string scoped_name_;
5471 interned_string linkage_name_;
5472 visibility visibility_;
5473 decl_base_sptr declaration_;
5474 decl_base_wptr definition_of_declaration_;
5475 decl_base* naked_definition_of_declaration_;
5476 std::atomic<bool> is_declaration_only_;
5477 std::list<typedef_decl_sptr> naming_typedefs_;
5478
5479 priv()
5480 : in_pub_sym_tab_(false),
5481 is_anonymous_(true),
5482 context_(nullptr),
5483 visibility_(VISIBILITY_DEFAULT),
5484 naked_definition_of_declaration_(),
5485 is_declaration_only_(false)
5486 {}
5487
5488 priv(interned_string name, interned_string linkage_name, visibility vis)
5489 : in_pub_sym_tab_(false),
5490 context_(nullptr),
5491 name_(name),
5492 qualified_name_(name),
5493 linkage_name_(linkage_name),
5494 visibility_(vis),
5495 naked_definition_of_declaration_(),
5496 is_declaration_only_(false)
5497 {
5498 is_anonymous_ = name_.empty();
5499 }
5500
5501 ~priv()
5502 {
5503 delete context_.load();
5504 }
5505};// end struct decl_base::priv
5506
5507/// Constructor for the @ref decl_base type.
5508///
5509/// @param e the environment the current @ref decl_base is being
5510/// created in.
5511///
5512/// @param name the name of the declaration.
5513///
5514/// @param locus the location where to find the declaration in the
5515/// source code.
5516///
5517/// @param linkage_name the linkage name of the declaration.
5518///
5519/// @param vis the visibility of the declaration.
5520decl_base::decl_base(const environment& e,
5521 const string& name,
5522 const location& locus,
5523 const string& linkage_name,
5524 visibility vis)
5525 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
5526 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
5527{
5528 set_location(locus);
5529}
5530
5531/// Constructor.
5532///
5533/// @param e the environment this instance of @ref decl_base is
5534/// created in.
5535///
5536/// @param name the name of the declaration being constructed.
5537///
5538/// @param locus the source location of the declaration being constructed.
5539///
5540/// @param linkage_name the linkage name of the declaration being
5541/// constructed.
5542///
5543/// @param vis the visibility of the declaration being constructed.
5544decl_base::decl_base(const environment& e,
5545 const interned_string& name,
5546 const location& locus,
5547 const interned_string& linkage_name,
5548 visibility vis)
5549 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
5550 priv_(new priv(name, linkage_name, vis))
5551{
5552 set_location(locus);
5553}
5554
5555/// Constructor for the @ref decl_base type.
5556///
5557///@param environment the environment this instance of @ref decl_base
5558/// is being constructed in.
5559///
5560/// @param l the location where to find the declaration in the source
5561/// code.
5562decl_base::decl_base(const environment& e, const location& l)
5563 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
5564 priv_(new priv())
5565{
5566 set_location(l);
5567}
5568
5569/// Getter for the qualified name.
5570///
5571/// Unlike decl_base::get_qualified_name() this doesn't try to update
5572/// the qualified name.
5573///
5574/// @return the qualified name.
5575const interned_string&
5577{
5578 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5579 return priv_->qualified_name_;
5580}
5581
5582/// Clear the qualified name of this decl.
5583///
5584/// This is useful to ensure that the cache for the qualified name of
5585/// the decl is refreshed right after type canonicalization, for
5586/// instance.
5587void
5589{
5590 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5591 priv_->qualified_name_.clear();
5592}
5593
5594/// Setter for the qualified name.
5595///
5596/// @param n the new qualified name.
5597void
5599{
5600 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5601 priv_->qualified_name_ = n;
5602}
5603
5604/// Getter of the temporary qualified name of the current declaration.
5605///
5606/// This temporary qualified name is used as a qualified name cache by
5607/// the type for which this is the declaration (when applicable)
5608/// before the type is canonicalized. Once the type is canonicalized,
5609/// it's the result of decl_base::peek_qualified_name() that becomes
5610/// the qualified name cached.
5611///
5612/// @return the temporary qualified name.
5613const interned_string&
5615{
5616 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5617 return priv_->temporary_qualified_name_;
5618}
5619
5620/// Setter for the temporary qualified name of the current
5621/// declaration.
5622///
5623///@param n the new temporary qualified name.
5624///
5625/// This temporary qualified name is used as a qualified name cache by
5626/// the type for which this is the declaration (when applicable)
5627/// before the type is canonicalized. Once the type is canonicalized,
5628/// it's the result of decl_base::peek_qualified_name() that becomes
5629/// the qualified name cached.
5630void
5632{
5633 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5634 priv_->temporary_qualified_name_ = n;
5635}
5636
5637///Getter for the context relationship.
5638///
5639///@return the context relationship for the current decl_base.
5640const context_rel*
5642{
5643 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5644 return priv_->context_;
5645}
5646
5647///Getter for the context relationship.
5648///
5649///@return the context relationship for the current decl_base.
5652{
5653 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5654 return priv_->context_;
5655}
5656
5657void
5658decl_base::set_context_rel(context_rel *c)
5659{
5660 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5661 priv_->context_ = c;
5662}
5663
5664/// Test if the decl is defined in a ELF symbol table as a public
5665/// symbol.
5666///
5667/// @return true iff the decl is defined in a ELF symbol table as a
5668/// public symbol.
5669bool
5671{
5672 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5673 return priv_->in_pub_sym_tab_;
5674}
5675
5676/// Set the flag saying if this decl is from a symbol that is in
5677/// a public symbols table, defined as public (global or weak).
5678///
5679/// @param f the new flag value.
5680void
5682{
5683 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5684 priv_->in_pub_sym_tab_ = f;
5685}
5686
5687/// Get the location of a given declaration.
5688///
5689/// The location is an abstraction for the tripplet {file path,
5690/// line, column} that defines where the declaration appeared in the
5691/// source code.
5692///
5693/// To get the value of the tripplet {file path, line, column} from
5694/// the @ref location, you need to use the
5695/// location_manager::expand_location() method.
5696///
5697/// The instance of @ref location_manager that you want is
5698/// accessible from the instance of @ref translation_unit that the
5699/// current instance of @ref decl_base belongs to, via a call to
5700/// translation_unit::get_loc_mgr().
5701///
5702/// @return the location of the current instance of @ref decl_base.
5703const location&
5705{
5706 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5707 return priv_->location_;
5708}
5709
5710/// Set the location for a given declaration.
5711///
5712/// The location is an abstraction for the tripplet {file path,
5713/// line, column} that defines where the declaration appeared in the
5714/// source code.
5715///
5716/// To create a location from a tripplet {file path, line, column},
5717/// you need to use the method @ref
5718/// location_manager::create_new_location().
5719///
5720/// Note that there can be two kinds of location. An artificial
5721/// location and a non-artificial one. The non-artificial location is
5722/// the one emitted by the original emitter of the ABI artifact, for
5723/// instance, if the ABI artifact comes from debug info, then the
5724/// source location that is present in the debug info represent a
5725/// non-artificial location. When looking at an abixml file on the
5726/// other hand, the value of the 'location' attribute of an XML
5727/// element describing an artifact is the non-artificial location.
5728/// The artificial location is the location (line number from the
5729/// beginning of the file) of the XML element within the abixml file.
5730///
5731/// So, if the location that is being set is artificial, note that the
5732/// type_or_decl_base::has_artificial_location() method of this decl will
5733/// subsequently return true and that artificial location will have to
5734/// be retrieved using type_or_decl_base::get_artificial_location().
5735/// If the location is non-artificial however,
5736/// type_or_decl_base::has_artificial_location() will subsequently
5737/// return false and the non-artificial location will have to be
5738/// retrieved using decl_base::get_location().
5739///
5740/// The instance of @ref location_manager that you want is
5741/// accessible from the instance of @ref translation_unit that the
5742/// current instance of @ref decl_base belongs to, via a call to
5743/// translation_unit::get_loc_mgr().
5744void
5746{
5747 if (l.get_is_artificial())
5749 else
5750 {
5751 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5752 priv_->location_ = l;
5753 }
5754}
5755
5756/// Setter for the name of the decl.
5757///
5758/// @param n the new name to set.
5759void
5760decl_base::set_name(const string& n)
5761{
5762 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5763 priv_->name_ = get_environment().intern(n);
5764 priv_->is_anonymous_ = n.empty();
5765}
5766
5767/// Test if the current declaration is anonymous.
5768///
5769/// Being anonymous means that the declaration was created without a
5770/// name. This can usually happen for enum or struct types.
5771///
5772/// @return true iff the type is anonymous.
5773bool
5775{
5776 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5777 return priv_->is_anonymous_;
5778}
5779
5780/// Set the "is_anonymous" flag of the current declaration.
5781///
5782/// Being anonymous means that the declaration was created without a
5783/// name. This can usually happen for enum or struct types.
5784///
5785/// @param f the new value of the flag.
5786void
5788{
5789 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5790 priv_->is_anonymous_ = f;
5791}
5792
5793
5794/// Get the "has_anonymous_parent" flag of the current declaration.
5795///
5796/// Having an anoymous parent means having a anonymous parent scope
5797/// (containing type or namespace) which is either direct or indirect.
5798///
5799/// @return true iff the current decl has a direct or indirect scope
5800/// which is anonymous.
5801bool
5803{
5804 auto scope = get_scope();
5805 if (!scope)
5806 return false;
5807 return scope->get_is_anonymous();
5808}
5809
5810/// @return the logical "OR" of decl_base::get_is_anonymous() and
5811/// decl_base::get_has_anonymous_parent().
5812bool
5815
5816/// Getter for the naming typedef of the current decl.
5817///
5818/// Consider the C idiom:
5819///
5820/// typedef struct {int member;} foo_type;
5821///
5822/// In that idiom, foo_type is the naming typedef of the anonymous
5823/// struct that is declared.
5824///
5825/// @return the naming typedef, if any. Otherwise, returns nil.
5826list<typedef_decl_sptr>&
5828{
5829 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5830 return priv_->naming_typedefs_;
5831}
5832
5833/// Set the naming typedef of the current instance of @ref decl_base.
5834///
5835/// Consider the C idiom:
5836///
5837/// typedef struct {int member;} foo_type;
5838///
5839/// In that idiom, foo_type is the naming typedef of the anonymous
5840/// struct that is declared.
5841///
5842/// After completion of this function, the decl will not be considered
5843/// anonymous anymore. It's name is going to be the name of the
5844/// naming typedef.
5845///
5846/// @param typedef_type the new naming typedef.
5847void
5849{
5850 ABG_ASSERT(t);
5851 {
5852 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5853 priv_->naming_typedefs_.push_back(t);
5854 }
5855}
5856
5857/// Test if the current decl has a given naming typedef.
5858///
5859/// Note that the comparison is done canonically if the types are
5860/// canonicalized, structurally otherwise.
5861///
5862/// @param naming_typedef the naming typedef to consider.
5863///
5864/// @return true iff if the current instance of @ref decl_base has the
5865/// naming typedef @p naming_typedef.
5866bool
5868{
5869 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5870 for (auto t : priv_->naming_typedefs_)
5871 if (t == naming_typedef)
5872 return true;
5873
5874 return false;
5875}
5876
5877/// Getter for the mangled name.
5878///
5879/// @return the new mangled name.
5880const interned_string&
5882{
5883 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5884 return priv_->linkage_name_;
5885}
5886
5887/// Setter for the linkage name.
5888///
5889/// @param m the new linkage name.
5890void
5892{
5893 const environment& env = get_environment();
5894 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5895 priv_->linkage_name_ = env.intern(m);
5896}
5897
5898/// Getter for the visibility of the decl.
5899///
5900/// @return the new visibility.
5903{
5904 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5905 return priv_->visibility_;
5906}
5907
5908/// Setter for the visibility of the decl.
5909///
5910/// @param v the new visibility.
5911void
5913{
5914 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5915 priv_->visibility_ = v;
5916}
5917
5918/// Return the type containing the current decl, if any.
5919///
5920/// @return the type that contains the current decl, or NULL if there
5921/// is none.
5924{
5925 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5926 if (auto c = priv_->context_.load())
5927 return c->get_scope();
5928 return nullptr;
5929}
5930
5931/// Return a copy of the qualified name of the parent of the current
5932/// decl.
5933///
5934/// @return the newly-built qualified name of the of the current decl.
5935const interned_string&
5937{
5938 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5939 return priv_->qualified_parent_name_;
5940}
5941
5942/// Getter for the name of the current decl.
5943///
5944/// @return the name of the current decl.
5945const interned_string&
5947{
5948 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5949 return priv_->name_;
5950}
5951
5952/// Compute the qualified name of the decl.
5953///
5954/// @param qn the resulting qualified name.
5955///
5956/// @param internal set to true if the call is intended for an
5957/// internal use (for technical use inside the library itself), false
5958/// otherwise. If you don't know what this is for, then set it to
5959/// false.
5960void
5962{
5963 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5964 qn = get_qualified_name(internal);
5965}
5966
5967/// Get the pretty representatin of the current declaration.
5968///
5969///
5970/// @param internal set to true if the call is intended to get a
5971/// representation of the decl (or type) for the purpose of canonical
5972/// type comparison. This is mainly used in the function
5973/// homonym_type_group::get_canonical_type_for().
5974///
5975/// In other words if the argument for this parameter is true then the
5976/// call is meant for internal use (for technical use inside the
5977/// library itself), false otherwise. If you don't know what this is
5978/// for, then set it to false.
5979///
5980/// @param qualified_name if true, names emitted in the pretty
5981/// representation are fully qualified.
5982///
5983/// @return the default pretty representation for a decl. This is
5984/// basically the fully qualified name of the decl optionally prefixed
5985/// with a meaningful string to add context for the user.
5986string
5988 bool qualified_name) const
5989{
5990 if (internal
5991 && get_is_anonymous()
5992 && has_generic_anonymous_internal_type_name(this))
5993 {
5994 // We are looking at an anonymous enum, union or class and we
5995 // want an *internal* pretty representation for it. All
5996 // anonymous types of this kind in the same namespace must have
5997 // the same internal representation for type canonicalization to
5998 // work properly.
5999 //
6000 // OK, in practise, we are certainly looking at an enum because
6001 // classes and unions should have their own overloaded virtual
6002 // member function for this.
6003 string name = get_generic_anonymous_internal_type_name(this);
6004 if (qualified_name && !get_qualified_parent_name().empty())
6005 name = get_qualified_parent_name() + "::" + name;
6006 return name;
6007 }
6008
6009 if (qualified_name)
6010 return get_qualified_name(internal);
6011 return get_name();
6012}
6013
6014
6015/// Return the qualified name of the decl.
6016///
6017/// This is the fully qualified name of the decl. It's made of the
6018/// concatenation of the name of the decl with the qualified name of
6019/// its scope.
6020///
6021/// Note that the value returned by this function is computed by @ref
6022/// update_qualified_name when the decl is added to its scope.
6023///
6024/// @param internal set to true if the call is intended for an
6025/// internal use (for technical use inside the library itself), false
6026/// otherwise. If you don't know what this is for, then set it to
6027/// false.
6028///
6029/// @return the resulting qualified name.
6030const interned_string&
6031decl_base::get_qualified_name(bool /*internal*/) const
6032{
6033 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6034 return priv_->qualified_name_;
6035}
6036
6037/// Return the scoped name of the decl.
6038///
6039/// This is made of the concatenation of the name of the decl with the
6040/// name of its scope. It doesn't contain the qualified name of its
6041/// scope, unlike what is returned by decl_base::get_qualified_name.
6042///
6043/// Note that the value returned by this function is computed by @ref
6044/// update_qualified_name when the decl is added to its scope.
6045///
6046/// @return the scoped name of the decl.
6047const interned_string&
6049{
6050 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6051 return priv_->scoped_name_;
6052}
6053
6054/// If this @ref decl_base is a definition, get its earlier
6055/// declaration.
6056///
6057/// @return the earlier declaration of the class, if any.
6058const decl_base_sptr
6060{
6061 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6062 return priv_->declaration_;
6063}
6064
6065/// set the earlier declaration of this @ref decl_base definition.
6066///
6067/// @param d the earlier declaration to set. Note that it's set only
6068/// if it's a pure declaration.
6069void
6071{
6072 if (d && d->get_is_declaration_only())
6073 {
6074 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6075 priv_->declaration_ = d;
6076 }
6077}
6078
6079
6080/// If this @ref decl_base is declaration-only, get its definition, if
6081/// any.
6082///
6083/// @return the definition of this decl-only @ref decl_base.
6084const decl_base_sptr
6086{
6087 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6088 return priv_->definition_of_declaration_.lock();
6089}
6090
6091/// If this @ref decl_base is declaration-only, get its definition,
6092/// if any.
6093///
6094/// Note that this function doesn't return a smart pointer, but rather
6095/// the underlying pointer managed by the smart pointer. So it's as
6096/// fast as possible. This getter is to be used in code paths that
6097/// are proven to be performance hot spots; especially, when comparing
6098/// sensitive types like enums, classes or unions. Those are compared
6099/// extremely frequently and thus, their access to the definition of
6100/// declaration must be fast.
6101///
6102/// @return the definition of the declaration.
6103const decl_base*
6105{
6106 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6107 return priv_->naked_definition_of_declaration_;
6108}
6109
6110/// Test if a @ref decl_base is a declaration-only decl.
6111///
6112/// @return true iff the current @ref decl_base is declaration-only.
6113bool
6115{
6116 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6117 return priv_->is_declaration_only_;
6118}
6119
6120/// Set a flag saying if the @ref enum_type_decl is a declaration-only
6121/// @ref enum_type_decl.
6122///
6123/// @param f true if the @ref enum_type_decl is a declaration-only
6124/// @ref enum_type_decl.
6125void
6127{
6128 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
6129
6130 {
6131 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6132 priv_->is_declaration_only_ = f;
6133 }
6134
6135 if (update_types_lookup_map)
6136 if (auto s = get_scope())
6137 {
6138 scope_decl::declarations::iterator i;
6139 if (s->find_iterator_for_member(this, i))
6141 else
6143 }
6144}
6145
6148{
6149 return static_cast<change_kind>(static_cast<unsigned>(l)
6150 | static_cast<unsigned>(r));
6151}
6152
6155{
6156 return static_cast<change_kind>(static_cast<unsigned>(l)
6157 & static_cast<unsigned>(r));
6158}
6159
6162{
6163 l = l | r;
6164 return l;
6165}
6166
6169{
6170 l = l & r;
6171 return l;
6172}
6173
6174/// Compare the properties that belong to the "is-a-member-relation"
6175/// of a decl.
6176///
6177/// For instance, access specifiers are part of the
6178/// "is-a-member-relation" of a decl.
6179///
6180/// This comparison however doesn't take decl names into account. So
6181/// typedefs for instance are decls that we want to compare with this
6182/// function.
6183///
6184/// This function is a sub-routine of the more general 'equals'
6185/// overload for instances of decl_base.
6186///
6187/// @param l the left-hand side operand of the comparison.
6188///
6189/// @param r the right-hand side operand of the comparison.
6190///
6191/// @return true iff @p l compare equals, as a member decl, to @p r.
6192bool
6194 const decl_base& r,
6195 change_kind* k)
6196{
6197 bool result = true;
6198 if (is_member_decl(l) && is_member_decl(r))
6199 {
6200 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
6201 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
6202
6203 bool rels_are_different = *r1 != *r2;
6204
6205 if (rels_are_different)
6206 {
6207 result = false;
6208 if (k)
6210 }
6211 }
6212 ABG_RETURN(result);
6213}
6214
6215/// Compares two instances of @ref decl_base.
6216///
6217/// If the two intances are different, set a bitfield to give some
6218/// insight about the kind of differences there are.
6219///
6220/// @param l the first artifact of the comparison.
6221///
6222/// @param r the second artifact of the comparison.
6223///
6224/// @param k a pointer to a bitfield that gives information about the
6225/// kind of changes there are between @p l and @p r. This one is set
6226/// iff it's non-null and if the function returns false.
6227///
6228/// Please note that setting k to a non-null value does have a
6229/// negative performance impact because even if @p l and @p r are not
6230/// equal, the function keeps up the comparison in order to determine
6231/// the different kinds of ways in which they are different.
6232///
6233/// @param qualified_name if this is true, then the function considers
6234/// the qualified name when comparing the two decls. Otherwise, the
6235/// qualified name is ignored.
6236///
6237/// @param linkage_name if this is true, then the function considers
6238/// the linkage name when comparing the two decls. Otherwise, the
6239/// linkage_name name is ignored.
6240///
6241/// @return true if @p l equals @p r, false otherwise.
6242bool
6243equals(const decl_base& l, const decl_base& r, change_kind* k,
6244 bool qualified_name, bool linkage_name)
6245{
6246 bool result = true;
6247 const interned_string &l_linkage_name = l.get_linkage_name();
6248 const interned_string &r_linkage_name = r.get_linkage_name();
6249 if (linkage_name)
6250 if (!l_linkage_name.empty() && !r_linkage_name.empty())
6251 {
6252 if (l_linkage_name != r_linkage_name)
6253 {
6254 // Linkage names are different. That usually means the two
6255 // decls are different, unless we are looking at two
6256 // function declarations which have two different symbols
6257 // that are aliases of each other.
6258 const function_decl *f1 = is_function_decl(&l),
6259 *f2 = is_function_decl(&r);
6260 if (f1 && f2 && function_decls_alias(*f1, *f2))
6261 ;// The two functions are aliases, so they are not
6262 // different.
6263 else
6264 {
6265 result = false;
6266 if (k)
6268 else
6269 ABG_RETURN_FALSE;
6270 }
6271 }
6272 }
6273
6274 bool decls_are_same = true;
6275 if (qualified_name)
6276 {
6279 decls_are_same = (ln == rn);
6280 }
6281
6282 if (!decls_are_same)
6283 {
6284 result = false;
6285 if (k)
6287 else
6288 ABG_RETURN_FALSE;
6289 }
6290
6291 result &= maybe_compare_as_member_decls(l, r, k);
6292
6293 ABG_RETURN(result);
6294}
6295
6296/// Return true iff the two decls have the same name.
6297///
6298/// This function doesn't test if the scopes of the the two decls are
6299/// equal.
6300///
6301/// Note that this virtual function is to be implemented by classes
6302/// that extend the \p decl_base class.
6303bool
6305{return equals(*this, other, nullptr);}
6306
6307/// Inequality operator.
6308///
6309/// @param other to other instance of @ref decl_base to compare the
6310/// current instance to.
6311///
6312/// @return true iff the current instance of @ref decl_base is
6313/// different from @p other.
6314bool
6316{return !operator==(other);}
6317
6318/// Destructor of the @ref decl_base type.
6322
6323/// This implements the ir_traversable_base::traverse pure virtual
6324/// function.
6325///
6326/// @param v the visitor used on the member nodes of the translation
6327/// unit during the traversal.
6328///
6329/// @return true if the entire IR node tree got traversed, false
6330/// otherwise.
6331bool
6333{
6334 // Do nothing in the base class.
6335 return true;
6336}
6337
6338/// Setter of the scope of the current decl.
6339///
6340/// Note that the decl won't hold a reference on the scope. It's
6341/// rather the scope that holds a reference on its members.
6342void
6344{
6345 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6346 if (!priv_->context_.load())
6347 priv_->context_ = new context_rel(scope);
6348 else
6349 priv_->context_.load()->set_scope(scope);
6350}
6351
6352// </decl_base definition>
6353
6354/// Streaming operator for the decl_base::visibility.
6355///
6356/// @param o the output stream to serialize the visibility to.
6357///
6358/// @param v the visibility to serialize.
6359///
6360/// @return the output stream.
6361std::ostream&
6362operator<<(std::ostream& o, decl_base::visibility v)
6363{
6364 string r;
6365 switch (v)
6366 {
6367 case decl_base::VISIBILITY_NONE:
6368 r = "none";
6369 break;
6370 case decl_base::VISIBILITY_DEFAULT:
6371 r = "default";
6372 break;
6373 case decl_base::VISIBILITY_PROTECTED:
6374 r = "protected";
6375 break;
6376 case decl_base::VISIBILITY_HIDDEN:
6377 r = "hidden";
6378 break;
6379 case decl_base::VISIBILITY_INTERNAL:
6380 r = "internal";
6381 break;
6382 }
6383 return o;
6384}
6385
6386/// Streaming operator for decl_base::binding.
6387///
6388/// @param o the output stream to serialize the visibility to.
6389///
6390/// @param b the binding to serialize.
6391///
6392/// @return the output stream.
6393std::ostream&
6394operator<<(std::ostream& o, decl_base::binding b)
6395{
6396 string r;
6397 switch (b)
6398 {
6399 case decl_base::BINDING_NONE:
6400 r = "none";
6401 break;
6402 case decl_base::BINDING_LOCAL:
6403 r = "local";
6404 break;
6405 case decl_base::BINDING_GLOBAL:
6406 r = "global";
6407 break;
6408 case decl_base::BINDING_WEAK:
6409 r = "weak";
6410 break;
6411 }
6412 o << r;
6413 return o;
6414}
6415
6416/// Turn equality of shared_ptr of decl_base into a deep equality;
6417/// that is, make it compare the pointed to objects, not just the
6418/// pointers.
6419///
6420/// @param l the shared_ptr of decl_base on left-hand-side of the
6421/// equality.
6422///
6423/// @param r the shared_ptr of decl_base on right-hand-side of the
6424/// equality.
6425///
6426/// @return true if the decl_base pointed to by the shared_ptrs are
6427/// equal, false otherwise.
6428bool
6429operator==(const decl_base_sptr& l, const decl_base_sptr& r)
6430{
6431 if (l.get() == r.get())
6432 return true;
6433 if (!!l != !!r)
6434 return false;
6435
6436 return *l == *r;
6437}
6438
6439/// Inequality operator of shared_ptr of @ref decl_base.
6440///
6441/// This is a deep equality operator, that is, it compares the
6442/// pointed-to objects, rather than just the pointers.
6443///
6444/// @param l the left-hand-side operand.
6445///
6446/// @param r the right-hand-side operand.
6447///
6448/// @return true iff @p l is different from @p r.
6449bool
6450operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
6451{return !operator==(l, r);}
6452
6453/// Turn equality of shared_ptr of type_base into a deep equality;
6454/// that is, make it compare the pointed to objects too.
6455///
6456/// @param l the shared_ptr of type_base on left-hand-side of the
6457/// equality.
6458///
6459/// @param r the shared_ptr of type_base on right-hand-side of the
6460/// equality.
6461///
6462/// @return true if the type_base pointed to by the shared_ptrs are
6463/// equal, false otherwise.
6464bool
6465operator==(const type_base_sptr& l, const type_base_sptr& r)
6466{
6467 if (l.get() == r.get())
6468 return true;
6469 if (!!l != !!r)
6470 return false;
6471
6472 return *l == *r;
6473}
6474
6475/// Turn inequality of shared_ptr of type_base into a deep equality;
6476/// that is, make it compare the pointed to objects..
6477///
6478/// @param l the shared_ptr of type_base on left-hand-side of the
6479/// equality.
6480///
6481/// @param r the shared_ptr of type_base on right-hand-side of the
6482/// equality.
6483///
6484/// @return true iff the type_base pointed to by the shared_ptrs are
6485/// different.
6486bool
6487operator!=(const type_base_sptr& l, const type_base_sptr& r)
6488{return !operator==(l, r);}
6489
6490/// Tests if a declaration has got a scope.
6491///
6492/// @param d the declaration to consider.
6493///
6494/// @return true if the declaration has got a scope, false otherwise.
6495bool
6497{return !!d.get_scope();}
6498
6499/// Tests if a declaration has got a scope.
6500///
6501/// @param d the declaration to consider.
6502///
6503/// @return true if the declaration has got a scope, false otherwise.
6504bool
6505has_scope(const decl_base_sptr d)
6506{return has_scope(*d.get());}
6507
6508/// Tests if a declaration is a class member.
6509///
6510/// @param d the declaration to consider.
6511///
6512/// @return true if @p d is a class member, false otherwise.
6513bool
6514is_member_decl(const decl_base_sptr d)
6515{return is_at_class_scope(d) || is_method_decl(d);}
6516
6517/// Tests if a declaration is a class member.
6518///
6519/// @param d the declaration to consider.
6520///
6521/// @return true if @p d is a class member, false otherwise.
6522bool
6525
6526/// Tests if a declaration is a class member.
6527///
6528/// @param d the declaration to consider.
6529///
6530/// @return true if @p d is a class member, false otherwise.
6531bool
6534
6535/// Test if a declaration is a @ref scope_decl.
6536///
6537/// @param d the declaration to take in account.
6538///
6539/// @return the a pointer to the @ref scope_decl sub-object of @p d,
6540/// if d is a @ref scope_decl.
6541const scope_decl*
6543{return dynamic_cast<const scope_decl*>(d);}
6544
6545/// Test if a declaration is a @ref scope_decl.
6546///
6547/// @param d the declaration to take in account.
6548///
6549/// @return the a pointer to the @ref scope_decl sub-object of @p d,
6550/// if d is a @ref scope_decl.
6553{return dynamic_pointer_cast<scope_decl>(d);}
6554
6555/// Tests if a type is a class member.
6556///
6557/// @param t the type to consider.
6558///
6559/// @return true if @p t is a class member type, false otherwise.
6560bool
6561is_member_type(const type_base_sptr& t)
6562{
6563 decl_base_sptr d = get_type_declaration(t);
6564 return is_member_decl(d);
6565}
6566
6567/// Tests if a type is a class member.
6568///
6569/// @param t the type to consider.
6570///
6571/// @return true if @p t is a class member type, false otherwise.
6572bool
6574{
6575 const decl_base* d = get_type_declaration(t);
6576 return is_member_decl(d);
6577}
6578
6579/// Test if a type is user-defined.
6580///
6581/// A type is considered user-defined if it's a
6582/// struct/class/union/enum that is *NOT* artificial.
6583///
6584/// @param t the type to consider.
6585///
6586/// @return true iff the type @p t is user-defined.
6587bool
6589{
6590 if (t == 0)
6591 return false;
6592
6594 decl_base *d = is_decl(t);
6595
6597 && d && !d->get_is_artificial())
6598 return true;
6599
6600 return false;
6601}
6602
6603/// Test if a type is user-defined.
6604///
6605/// A type is considered user-defined if it's a
6606/// struct/class/union/enum.
6607///
6608///
6609/// @param t the type to consider.
6610///
6611/// @return true iff the type @p t is user-defined.
6612bool
6613is_user_defined_type(const type_base_sptr& t)
6614{return is_user_defined_type(t.get());}
6615
6616/// Gets the access specifier for a class member.
6617///
6618/// @param d the declaration of the class member to consider. Note
6619/// that this must be a class member otherwise the function aborts the
6620/// current process.
6621///
6622/// @return the access specifier for the class member @p d.
6625{
6627
6628 const context_rel* c = d.get_context_rel();
6629 ABG_ASSERT(c);
6630
6631 return c->get_access_specifier();
6632}
6633
6634/// Gets the access specifier for a class member.
6635///
6636/// @param d the declaration of the class member to consider. Note
6637/// that this must be a class member otherwise the function aborts the
6638/// current process.
6639///
6640/// @return the access specifier for the class member @p d.
6642get_member_access_specifier(const decl_base_sptr& d)
6643{return get_member_access_specifier(*d);}
6644
6645/// Sets the access specifier for a class member.
6646///
6647/// @param d the class member to set the access specifier for. Note
6648/// that this must be a class member otherwise the function aborts the
6649/// current process.
6650///
6651/// @param a the new access specifier to set the class member to.
6652void
6655{
6657
6659 ABG_ASSERT(c);
6660
6661 c->set_access_specifier(a);
6662}
6663
6664/// Sets the access specifier for a class member.
6665///
6666/// @param d the class member to set the access specifier for. Note
6667/// that this must be a class member otherwise the function aborts the
6668/// current process.
6669///
6670/// @param a the new access specifier to set the class member to.
6671void
6672set_member_access_specifier(const decl_base_sptr& d,
6675
6676/// Gets a flag saying if a class member is static or not.
6677///
6678/// @param d the declaration for the class member to consider. Note
6679/// that this must be a class member otherwise the function aborts the
6680/// current process.
6681///
6682/// @return true if the class member @p d is static, false otherwise.
6683bool
6685{
6687
6688 const context_rel* c = d.get_context_rel();
6689 ABG_ASSERT(c);
6690
6691 return c->get_is_static();
6692}
6693
6694/// Gets a flag saying if a class member is static or not.
6695///
6696/// @param d the declaration for the class member to consider. Note
6697/// that this must be a class member otherwise the function aborts the
6698/// current process.
6699///
6700/// @return true if the class member @p d is static, false otherwise.
6701bool
6704
6705/// Gets a flag saying if a class member is static or not.
6706///
6707/// @param d the declaration for the class member to consider. Note
6708/// that this must be a class member otherwise the function aborts the
6709/// current process.
6710///
6711/// @return true if the class member @p d is static, false otherwise.
6712bool
6713get_member_is_static(const decl_base_sptr& d)
6714{return get_member_is_static(*d);}
6715
6716/// Test if a var_decl is a data member.
6717///
6718/// @param v the var_decl to consider.
6719///
6720/// @return true if @p v is data member, false otherwise.
6721bool
6723{return !!is_at_class_scope(v);}
6724
6725/// Test if a var_decl is a data member.
6726///
6727/// @param v the var_decl to consider.
6728///
6729/// @return true if @p v is data member, false otherwise.
6730bool
6732{return is_data_member(*v);}
6733
6734/// Test if a decl is a data member.
6735///
6736/// @param d the decl to consider.
6737///
6738/// @return a pointer to the data member iff @p d is a data member, or
6739/// a null pointer.
6742{
6743 if (var_decl_sptr v = is_var_decl(d))
6744 if (is_at_class_scope(v))
6745 return v;
6746
6747 return var_decl_sptr();
6748}
6749
6750/// Test if a decl is a data member.
6751///
6752/// @param d the decl to consider.
6753///
6754/// @return a pointer to the data member iff @p d is a data member, or
6755/// a null pointer.
6756var_decl*
6758{
6759 if (var_decl *v = is_var_decl(d))
6760 if (is_data_member(v))
6761 return v;
6762 return 0;
6763}
6764
6765/// Test if a decl is a data member.
6766///
6767/// @param d the decl to consider.
6768///
6769/// @return a pointer to the data member iff @p d is a data member, or
6770/// a null pointer.
6771var_decl*
6773{
6774 if (var_decl *v = is_var_decl(d))
6775 if (is_data_member(v))
6776 return v;
6777 return 0;
6778}
6779
6780/// Get the first non-anonymous data member of a given anonymous data
6781/// member.
6782///
6783/// E.g:
6784///
6785/// struct S
6786/// {
6787/// union // <-- for this anonymous data member, the function
6788/// // returns a.
6789/// {
6790/// int a;
6791/// charb;
6792/// };
6793/// };
6794///
6795/// @return anon_dm the anonymous data member to consider.
6796///
6797/// @return the first non-anonymous data member of @p anon_dm. If no
6798/// data member was found then this function returns @p anon_dm.
6799const var_decl_sptr
6801{
6802 if (!anon_dm || !is_anonymous_data_member(anon_dm))
6803 return anon_dm;
6804
6805 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
6806 lock_guard<recursive_mutex> lock(klass->get_mutex());
6807 var_decl_sptr first = *klass->get_non_static_data_members().begin();
6808
6809 if (is_anonymous_data_member(first))
6811
6812 return first;
6813}
6814
6815/// In the context of a given class or union, this function returns
6816/// the data member that is located after a given data member.
6817///
6818/// @param klass the class or union to consider.
6819///
6820/// @param the data member to consider.
6821///
6822/// @return the data member that is located right after @p
6823/// data_member.
6824const var_decl_sptr
6826 const var_decl_sptr &data_member)
6827{
6828 if (!klass ||!data_member)
6829 return var_decl_sptr();
6830
6831 lock_guard<recursive_mutex> lock(klass->get_mutex());
6832 for (class_or_union::data_members::const_iterator it =
6833 klass->get_non_static_data_members().begin();
6834 it != klass->get_non_static_data_members().end();
6835 ++it)
6836 if (**it == *data_member)
6837 {
6838 ++it;
6839 if (it != klass->get_non_static_data_members().end())
6841 break;
6842 }
6843
6844 return var_decl_sptr();
6845}
6846
6847/// In the context of a given class or union, this function returns
6848/// the data member that is located after a given data member.
6849///
6850/// @param klass the class or union to consider.
6851///
6852/// @param the data member to consider.
6853///
6854/// @return the data member that is located right after @p
6855/// data_member.
6856const var_decl_sptr
6857get_next_data_member(const class_or_union_sptr& klass,
6858 const var_decl_sptr &data_member)
6859{return get_next_data_member(klass.get(), data_member);}
6860
6861/// Get the last data member of a class type.
6862///
6863/// @param klass the class type to consider.
6866{return klass.get_non_static_data_members().back();}
6867
6868/// Get the last data member of a class type.
6869///
6870/// @param klass the class type to consider.
6874
6875/// Get the last data member of a class type.
6876///
6877/// @param klass the class type to consider.
6879get_last_data_member(const class_or_union_sptr &klass)
6880{return get_last_data_member(klass.get());}
6881
6882/// Collect all the non-anonymous data members of a class or union type.
6883///
6884/// If the class contains any anonymous data member, this function
6885/// looks through it to collect the non-anonymous data members that it
6886/// contains. The function also looks through the base classes of the
6887/// current type.
6888///
6889/// @param cou the class or union type to consider.
6890///
6891/// @param dms output parameter. This is populated by the function
6892/// with a map containing the non-anonymous data members that were
6893/// collected. The key of the map is the name of the data member.
6894/// This is set iff the function returns true.
6895///
6896/// @return true iff at least one non-anonymous data member was
6897/// collected.
6898bool
6901{
6902 if (!cou)
6903 return false;
6904
6905 bool result = false;
6906 class_decl* klass = is_class_type(cou);
6907 if (klass)
6908 // First look into base classes for data members.
6910 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
6911
6912 // Then look into our data members
6913 lock_guard<recursive_mutex> lock(cou->get_mutex());
6914 for (var_decl_sptr member : cou->get_non_static_data_members())
6915 {
6916 if (is_anonymous_data_member(member))
6917 {
6918 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
6919 ABG_ASSERT(cl);
6920 result |= collect_non_anonymous_data_members(cl.get(), dms);
6921 }
6922 else
6923 {
6924 dms[member->get_name()] = member;
6925 result = true;
6926 }
6927 }
6928 return result;
6929}
6930
6931/// Collect all the non-anonymous data members of a class or union type.
6932///
6933/// If the class contains any anonymous data member, this function
6934/// looks through it to collect the non-anonymous data members that it
6935/// contains. The function also also looks through the base classes
6936/// of the current type.
6937///
6938/// @param cou the class or union type to consider.
6939///
6940/// @param dms output parameter. This is populated by the function
6941/// with a map containing the non-anonymous data members that were
6942/// collected. The key of the map is the name of the data member.
6943/// This is set iff the function returns true.
6944///
6945/// @return true iff at least one non-anonymous data member was
6946/// collected.
6947bool
6949{return collect_non_anonymous_data_members(cou.get(), dms);}
6950
6951/// Test if a decl is an anonymous data member.
6952///
6953/// @param d the decl to consider.
6954///
6955/// @return true iff @p d is an anonymous data member.
6956bool
6959
6960/// Test if a decl is an anonymous data member.
6961///
6962/// @param d the decl to consider.
6963///
6964/// @return the var_decl representing the data member iff @p d is an
6965/// anonymous data member.
6966const var_decl*
6968{
6969 if (const var_decl* v = is_data_member(d))
6970 {
6972 return v;
6973 }
6974 return 0;
6975}
6976
6977/// Test if a decl is an anonymous data member.
6978///
6979/// @param d the decl to consider.
6980///
6981/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6982/// it's an anonymous data member. Otherwise returns a nil pointer.
6983const var_decl*
6985{
6986 if (const var_decl* v = is_data_member(d))
6987 {
6989 return v;
6990 }
6991 return 0;
6992}
6993
6994/// Test if a decl is an anonymous data member.
6995///
6996/// @param d the decl to consider.
6997///
6998/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6999/// it's an anonymous data member. Otherwise returns a nil pointer.
7002{
7003 if (var_decl_sptr v = is_data_member(d))
7004 {
7006 return v;
7007 }
7008 return var_decl_sptr();
7009}
7010
7011/// Test if a decl is an anonymous data member.
7012///
7013/// @param d the decl to consider.
7014///
7015/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
7016/// it's an anonymous data member. Otherwise returns a nil pointer.
7018is_anonymous_data_member(const decl_base_sptr& d)
7019{
7020 if (var_decl_sptr v = is_data_member(d))
7021 return is_anonymous_data_member(v);
7022 return var_decl_sptr();
7023}
7024
7025/// Test if a @ref var_decl is an anonymous data member.
7026///
7027/// @param d the @ref var_decl to consider.
7028///
7029/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
7030/// it's an anonymous data member. Otherwise returns a nil pointer.
7033{
7034 if (is_anonymous_data_member(d.get()))
7035 return d;
7036 return var_decl_sptr();
7037}
7038
7039/// Test if a @ref var_decl is an anonymous data member.
7040///
7041/// @param d the @ref var_decl to consider.
7042///
7043/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
7044/// it's an anonymous data member. Otherwise returns a nil pointer.
7045const var_decl*
7047{
7048 if (d && is_anonymous_data_member(*d))
7049 return d;
7050 return 0;
7051}
7052
7053/// Test if a @ref var_decl is an anonymous data member.
7054///
7055/// @param d the @ref var_decl to consider.
7056///
7057/// @return true iff @p d is an anonymous data member.
7058bool
7060{
7061 return (is_data_member(d)
7062 && d.get_is_anonymous()
7063 && d.get_name().empty()
7065}
7066
7067/// Test if a @ref var_decl is a data member belonging to an anonymous
7068/// type.
7069///
7070/// @param d the @ref var_decl to consider.
7071///
7072/// @return true iff @p d is a data member belonging to an anonymous
7073/// type.
7074bool
7076{
7077 if (is_data_member(d))
7078 {
7079 auto scope = d.get_scope();
7080 if (scope && scope->get_is_anonymous())
7081 return true;
7082 }
7083 return false;
7084}
7085
7086/// Test if a @ref var_decl is a data member belonging to an anonymous
7087/// type.
7088///
7089/// @param d the @ref var_decl to consider.
7090///
7091/// @return true iff @p d is a data member belonging to an anonymous
7092/// type.
7093bool
7096
7097/// Test if a @ref var_decl is a data member belonging to an anonymous
7098/// type.
7099///
7100/// @param d the @ref var_decl to consider.
7101///
7102/// @return true iff @p d is a data member belonging to an anonymous
7103/// type.
7104bool
7107
7108/// Get the @ref class_or_union type of a given anonymous data member.
7109///
7110/// @param d the anonymous data member to consider.
7111///
7112/// @return the @ref class_or_union type of the anonymous data member
7113/// @p d.
7116{
7117 if ((d = is_anonymous_data_member(d)))
7118 return is_class_or_union_type(d->get_type().get());
7119 return 0;
7120}
7121
7122/// Get the @ref class_or_union type of a given anonymous data member.
7123///
7124/// @param d the anonymous data member to consider.
7125///
7126/// @return the @ref class_or_union type of the anonymous data member
7127/// @p d.
7128class_or_union_sptr
7130{
7132 return is_class_or_union_type(d.get_type());
7133 return class_or_union_sptr();
7134}
7135
7136/// Test if a data member has annonymous type or not.
7137///
7138/// @param d the data member to consider.
7139///
7140/// @return the anonymous class or union type iff @p turns out to have
7141/// an anonymous type. Otherwise, returns nil.
7142const class_or_union_sptr
7144{
7145 if (is_data_member(d))
7146 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
7147 if (cou->get_is_anonymous())
7148 return cou;
7149
7150 return class_or_union_sptr();
7151}
7152
7153/// Test if a data member has annonymous type or not.
7154///
7155/// @param d the data member to consider.
7156///
7157/// @return the anonymous class or union type iff @p turns out to have
7158/// an anonymous type. Otherwise, returns nil.
7159const class_or_union_sptr
7161{
7162 if (d)
7164 return class_or_union_sptr();
7165}
7166
7167/// Test if a data member has annonymous type or not.
7168///
7169/// @param d the data member to consider.
7170///
7171/// @return the anonymous class or union type iff @p turns out to have
7172/// an anonymous type. Otherwise, returns nil.
7173const class_or_union_sptr
7176
7177/// Get the @ref class_or_union type of a given anonymous data member.
7178///
7179/// @param d the anonymous data member to consider.
7180///
7181/// @return the @ref class_or_union type of the anonymous data member
7182/// @p d.
7183class_or_union_sptr
7185{
7187 return is_class_or_union_type(v->get_type());
7188 return class_or_union_sptr();
7189}
7190
7191/// Test if a given anonymous data member exists in a class or union.
7192///
7193/// @param anon_dm the anonymous data member to consider.
7194///
7195/// @param clazz the class to consider.
7196///
7197/// @return true iff @p anon_dm exists in the @clazz.
7198bool
7200 const class_or_union& clazz)
7201{
7202 if (!anon_dm.get_is_anonymous()
7203 || !is_class_or_union_type(anon_dm.get_type()))
7204 return false;
7205
7206 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
7207 ABG_ASSERT(cl);
7208
7209 // Look for the presence of each data member of anon_dm in clazz.
7210 //
7211 // If one data member of anon_dm is not present in clazz, then the
7212 // data member anon_dm is considered to not exist in clazz.
7213 lock_guard<recursive_mutex> lock(cl->get_mutex());
7214 for (auto anon_dm_m : cl->get_non_static_data_members())
7215 {
7216 // If the data member anon_dm_m is not an anonymous data member,
7217 // it's easy to look for it.
7218 if (!is_anonymous_data_member(anon_dm_m))
7219 {
7220 if (!clazz.find_data_member(anon_dm_m->get_name()))
7221 return false;
7222 }
7223 // If anon_dm_m is itself an anonymous data member then recurse
7224 else
7225 {
7226 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
7227 return false;
7228 }
7229 }
7230
7231 return true;
7232}
7233
7234/// Test if a given decl is anonymous or has a naming typedef.
7235///
7236/// @param d the decl to consider.
7237///
7238/// @return true iff @p d is anonymous or has a naming typedef.
7239bool
7241{
7242 if (d.get_is_anonymous() || !d.get_naming_typedefs().empty())
7243 return true;
7244 return false;
7245}
7246
7247/// Set the offset of a data member into its containing class.
7248///
7249/// @param m the data member to consider.
7250///
7251/// @param o the offset, in bits.
7252void
7254{
7256
7257 dm_context_rel* ctxt_rel =
7258 dynamic_cast<dm_context_rel*>(m->get_context_rel());
7259 ABG_ASSERT(ctxt_rel);
7260
7261 ctxt_rel->set_offset_in_bits(o);
7262}
7263
7264/// Get the offset of a data member.
7265///
7266/// @param m the data member to consider.
7267///
7268/// @return the offset (in bits) of @p m in its containing class.
7269uint64_t
7271{
7273 const dm_context_rel* ctxt_rel =
7274 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
7275 ABG_ASSERT(ctxt_rel);
7276 return ctxt_rel->get_offset_in_bits();
7277}
7278
7279/// Get the offset of a data member.
7280///
7281/// @param m the data member to consider.
7282///
7283/// @return the offset (in bits) of @p m in its containing class.
7284uint64_t
7287
7288/// Get the offset of a data member.
7289///
7290/// @param m the data member to consider.
7291///
7292/// @return the offset (in bits) of @p m in its containing class.
7293uint64_t
7294get_data_member_offset(const decl_base_sptr d)
7295{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
7296
7297/// Get the offset of the non-static data member that comes after a
7298/// given one.
7299///
7300/// If there is no data member after after the one given to this
7301/// function (maybe because the given one is the last data member of
7302/// the class type) then the function return false.
7303///
7304/// @param klass the class to consider.
7305///
7306/// @param dm the data member before the one we want to retrieve.
7307///
7308/// @param offset out parameter. This parameter is set by the
7309/// function to the offset of the data member that comes right after
7310/// the data member @p dm, iff the function returns true.
7311///
7312/// @return true iff the data member coming right after @p dm was
7313/// found.
7314bool
7316 const var_decl_sptr& dm,
7317 uint64_t& offset)
7318{
7319 var_decl_sptr next_dm = get_next_data_member(klass, dm);
7320 if (!next_dm)
7321 return false;
7322 offset = get_data_member_offset(next_dm);
7323 return true;
7324}
7325
7326/// Get the offset of the non-static data member that comes after a
7327/// given one.
7328///
7329/// If there is no data member after after the one given to this
7330/// function (maybe because the given one is the last data member of
7331/// the class type) then the function return false.
7332///
7333/// @param klass the class to consider.
7334///
7335/// @param dm the data member before the one we want to retrieve.
7336///
7337/// @param offset out parameter. This parameter is set by the
7338/// function to the offset of the data member that comes right after
7339/// the data member @p dm, iff the function returns true.
7340///
7341/// @return true iff the data member coming right after @p dm was
7342/// found.
7343bool
7344get_next_data_member_offset(const class_or_union_sptr& klass,
7345 const var_decl_sptr& dm,
7346 uint64_t& offset)
7347{return get_next_data_member_offset(klass.get(), dm, offset);}
7348
7349/// Get the absolute offset of a data member.
7350///
7351/// If the data member is part of an anonymous data member then this
7352/// returns the absolute offset -- relative to the beginning of the
7353/// containing class of the anonymous data member.
7354///
7355/// @param m the data member to consider.
7356///
7357/// @return the aboslute offset of the data member @p m.
7358uint64_t
7360{
7362 const dm_context_rel* ctxt_rel =
7363 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
7364 ABG_ASSERT(ctxt_rel);
7365
7366 var_decl_sptr containing_anonymous_data_member =
7367 ctxt_rel->get_anonymous_data_member();
7368
7369 uint64_t containing_anonymous_data_member_offset = 0;
7370 if (containing_anonymous_data_member)
7371 containing_anonymous_data_member_offset =
7372 get_absolute_data_member_offset(*containing_anonymous_data_member);
7373
7374 return (ctxt_rel->get_offset_in_bits()
7375 +
7376 containing_anonymous_data_member_offset);
7377}
7378
7379/// Get the absolute offset of a data member.
7380///
7381/// If the data member is part of an anonymous data member then this
7382/// returns the absolute offset -- relative to the beginning of the
7383/// containing class of the anonymous data member.
7384///
7385/// @param m the data member to consider.
7386///
7387/// @return the aboslute offset of the data member @p m.
7388uint64_t
7390{
7391 if (!m)
7392 return 0;
7394}
7395
7396/// Get the size of a given variable.
7397///
7398/// @param v the variable to consider.
7399///
7400/// @return the size of variable @p v.
7401uint64_t
7403{
7404 type_base_sptr t = v->get_type();
7405 ABG_ASSERT(t);
7406
7407 return t->get_size_in_bits();
7408}
7409
7410/// Set a flag saying if a data member is laid out.
7411///
7412/// @param m the data member to consider.
7413///
7414/// @param l true if @p m is to be considered as laid out.
7415void
7417{
7419 dm_context_rel* ctxt_rel =
7420 dynamic_cast<dm_context_rel*>(m->get_context_rel());
7421 ctxt_rel->set_is_laid_out(l);
7422}
7423
7424/// Test whether a data member is laid out.
7425///
7426/// @param m the data member to consider.
7427///
7428/// @return true if @p m is laid out, false otherwise.
7429bool
7431{
7433 const dm_context_rel* ctxt_rel =
7434 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
7435
7436 return ctxt_rel->get_is_laid_out();
7437}
7438
7439/// Test whether a data member is laid out.
7440///
7441/// @param m the data member to consider.
7442///
7443/// @return true if @p m is laid out, false otherwise.
7444bool
7447
7448/// Test whether a function_decl is a member function.
7449///
7450/// @param f the function_decl to test.
7451///
7452/// @return true if @p f is a member function, false otherwise.
7453bool
7456
7457/// Test whether a function_decl is a member function.
7458///
7459/// @param f the function_decl to test.
7460///
7461/// @return true if @p f is a member function, false otherwise.
7462bool
7465
7466/// Test whether a function_decl is a member function.
7467///
7468/// @param f the function_decl to test.
7469///
7470/// @return true if @p f is a member function, false otherwise.
7471bool
7474
7475/// Test whether a member function is a constructor.
7476///
7477/// @param f the member function to test.
7478///
7479/// @return true if @p f is a constructor, false otherwise.
7480bool
7482{
7484
7485 const method_decl* m = is_method_decl(&f);
7486 ABG_ASSERT(m);
7487
7488 lock_guard<recursive_mutex> lock(f.get_mutex());
7489
7490 const mem_fn_context_rel* ctxt =
7491 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
7492
7493 return ctxt->is_constructor();
7494}
7495
7496/// Test whether a member function is a constructor.
7497///
7498/// @param f the member function to test.
7499///
7500/// @return true if @p f is a constructor, false otherwise.
7501bool
7504
7505
7506/// Setter for the is_ctor property of the member function.
7507///
7508/// @param f the member function to set.
7509///
7510/// @param f the new boolean value of the is_ctor property. Is true
7511/// if @p f is a constructor, false otherwise.
7512void
7514{
7516
7517 method_decl* m = is_method_decl(&f);
7518 ABG_ASSERT(m);
7519
7520 lock_guard<recursive_mutex> lock(f.get_mutex());
7521
7522 mem_fn_context_rel* ctxt =
7523 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
7524
7525 ctxt->is_constructor(c);
7526}
7527
7528/// Setter for the is_ctor property of the member function.
7529///
7530/// @param f the member function to set.
7531///
7532/// @param f the new boolean value of the is_ctor property. Is true
7533/// if @p f is a constructor, false otherwise.
7534void
7537
7538/// Test whether a member function is a destructor.
7539///
7540/// @param f the function to test.
7541///
7542/// @return true if @p f is a destructor, false otherwise.
7543bool
7545{
7547
7548 const method_decl* m = is_method_decl(&f);
7549 ABG_ASSERT(m);
7550
7551 lock_guard<recursive_mutex> lock(f.get_mutex());
7552
7553 const mem_fn_context_rel* ctxt =
7554 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
7555
7556 return ctxt->is_destructor();
7557}
7558
7559/// Test whether a member function is a destructor.
7560///
7561/// @param f the function to test.
7562///
7563/// @return true if @p f is a destructor, false otherwise.
7564bool
7567
7568/// Set the destructor-ness property of a member function.
7569///
7570/// @param f the function to set.
7571///
7572/// @param d true if @p f is a destructor, false otherwise.
7573void
7575{
7577
7578 method_decl* m = is_method_decl(&f);
7579 ABG_ASSERT(m);
7580
7581 mem_fn_context_rel* ctxt =
7582 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
7583
7584 ctxt->is_destructor(d);
7585}
7586
7587/// Set the destructor-ness property of a member function.
7588///
7589/// @param f the function to set.
7590///
7591/// @param d true if @p f is a destructor, false otherwise.
7592void
7595
7596/// Test whether a member function is const.
7597///
7598/// @param f the function to test.
7599///
7600/// @return true if @p f is const, false otherwise.
7601bool
7603{
7605
7606 const method_decl* m = is_method_decl(&f);
7607 ABG_ASSERT(m);
7608
7609 lock_guard<recursive_mutex> lock(f.get_mutex());
7610
7611 const mem_fn_context_rel* ctxt =
7612 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
7613
7614 return ctxt->is_const();
7615}
7616
7617/// Test whether a member function is const.
7618///
7619/// @param f the function to test.
7620///
7621/// @return true if @p f is const, false otherwise.
7622bool
7625
7626/// set the const-ness property of a member function.
7627///
7628/// @param f the function to set.
7629///
7630/// @param is_const the new value of the const-ness property of @p f
7631void
7633{
7635
7636
7637 method_decl* m = is_method_decl(&f);
7638 ABG_ASSERT(m);
7639
7640 lock_guard<recursive_mutex> lock(f.get_mutex());
7641
7642 mem_fn_context_rel* ctxt =
7643 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
7644
7645 ctxt->is_const(is_const);
7646}
7647
7648/// set the const-ness property of a member function.
7649///
7650/// @param f the function to set.
7651///
7652/// @param is_const the new value of the const-ness property of @p f
7653void
7656
7657/// Test if a virtual member function has a vtable offset set.
7658///
7659/// @param f the virtual member function to consider.
7660///
7661/// @return true iff the virtual member function has its vtable offset
7662/// set, i.e, if the vtable offset of @p is different from -1.
7663bool
7666
7667/// Get the vtable offset of a member function.
7668///
7669/// @param f the member function to consider.
7670///
7671/// @return the vtable offset of @p f. Note that a vtable offset of
7672/// value -1 means that the member function does *NOT* yet have a
7673/// vtable offset associated to it.
7674ssize_t
7676{
7678
7679 const method_decl* m =
7680 dynamic_cast<const method_decl*>(&f);
7681 ABG_ASSERT(m);
7682
7683 lock_guard<recursive_mutex> lock(f.get_mutex());
7684
7685 const mem_fn_context_rel* ctxt =
7686 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
7687
7688 return ctxt->vtable_offset();
7689}
7690
7691/// Get the vtable offset of a member function.
7692///
7693/// @param f the member function to consider.
7694///
7695/// @return the vtable offset of @p f. Note that a vtable offset of
7696/// value -1 means that the member function does *NOT* yet have a
7697/// vtable offset associated to it.
7698ssize_t
7701
7702/// Set the vtable offset of a member function.
7703///
7704/// @param f the member function to consider.
7705///
7706/// @param s the new vtable offset. Please note that a vtable offset
7707/// of value -1 means that the virtual member function does not (yet)
7708/// have any vtable offset associated to it.
7709static void
7710set_member_function_vtable_offset(function_decl& f, ssize_t s)
7711{
7713
7714 method_decl* m = is_method_decl(&f);
7715 ABG_ASSERT(m);
7716
7717 lock_guard<recursive_mutex> lock(f.get_mutex());
7718
7719 mem_fn_context_rel* ctxt =
7720 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
7721
7722 ctxt->vtable_offset(s);
7723}
7724
7725/// Get the vtable offset of a member function.
7726///
7727/// @param f the member function to consider.
7728///
7729/// @param s the new vtable offset. Please note that a vtable offset
7730/// of value -1 means that the virtual member function does not (yet)
7731/// have any vtable offset associated to it.
7732static void
7733set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
7734{return set_member_function_vtable_offset(*f, s);}
7735
7736/// Test if a given member function is virtual.
7737///
7738/// @param mem_fn the member function to consider.
7739///
7740/// @return true iff a @p mem_fn is virtual.
7741bool
7743{
7745
7746 const method_decl* m =
7747 dynamic_cast<const method_decl*>(&f);
7748 ABG_ASSERT(m);
7749
7750 lock_guard<recursive_mutex> lock(f.get_mutex());
7751
7752 const mem_fn_context_rel* ctxt =
7753 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
7754
7755 return ctxt->is_virtual();
7756}
7757
7758/// Test if a given member function is virtual.
7759///
7760/// @param mem_fn the member function to consider.
7761///
7762/// @return true iff a @p mem_fn is virtual.
7763bool
7765{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
7766
7767/// Test if a given member function is virtual.
7768///
7769/// @param mem_fn the member function to consider.
7770///
7771/// @return true iff a @p mem_fn is virtual.
7772bool
7774{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
7775
7776/// Set the virtual-ness of a member function.
7777///
7778/// @param f the member function to consider.
7779///
7780/// @param is_virtual set to true if the function is virtual.
7781static void
7782set_member_function_is_virtual(function_decl& f, bool is_virtual)
7783{
7785
7786 method_decl* m = is_method_decl(&f);
7787 ABG_ASSERT(m);
7788
7789 lock_guard<recursive_mutex> lock(f.get_mutex());
7790
7791 mem_fn_context_rel* ctxt =
7792 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
7793
7794 ctxt->is_virtual(is_virtual);
7795}
7796
7797/// Set the virtual-ness of a member function.
7798///
7799/// @param f the member function to consider.
7800///
7801/// @param is_virtual set to true if the function is virtual.
7802static void
7803set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
7804{
7805 if (fn)
7806 {
7807 set_member_function_is_virtual(*fn, is_virtual);
7809 }
7810}
7811
7812/// Set the virtual-ness of a member fcuntion
7813///
7814/// @param fn the member function to consider.
7815///
7816/// @param is_virtual whether the function is virtual.
7817///
7818/// @param voffset the virtual offset of the virtual function.
7819void
7821 bool is_virtual,
7822 ssize_t voffset)
7823{
7824 set_member_function_vtable_offset(fn, voffset);
7825 set_member_function_is_virtual(fn, is_virtual);
7826}
7827
7828/// Recursively returns the the underlying type of a typedef. The
7829/// return type should not be a typedef of anything anymore.
7830///
7831///
7832/// Also recursively strip typedefs from the sub-types of the type
7833/// given in arguments.
7834///
7835/// Note that this function builds types in which typedefs are
7836/// stripped off. Usually, types are held by their scope, so their
7837/// life time is bound to the life time of their scope. But as this
7838/// function cannot really insert the built type into it's scope, it
7839/// must ensure that the newly built type stays live long enough.
7840///
7841/// So, if the newly built type has a canonical type, this function
7842/// returns the canonical type. Otherwise, this function ensure that
7843/// the newly built type has a life time that is the same as the life
7844/// time of the entire libabigail library.
7845///
7846/// @param type the type to strip the typedefs from.
7847///
7848/// @return the resulting type stripped from its typedefs, or just
7849/// return @p type if it has no typedef in any of its sub-types.
7850type_base_sptr
7851strip_typedef(const type_base_sptr type)
7852{
7853 if (!type)
7854 return type;
7855
7856 // If type is a class type then do not try to strip typedefs from it.
7857 // And if it has no canonical type (which can mean that it's a
7858 // declaration-only class), then, make sure its live for ever and
7859 // return it.
7860 if (class_decl_sptr cl = is_class_type(type))
7861 {
7862 if (!cl->get_canonical_type())
7863 keep_type_alive(type);
7864 return type;
7865 }
7866
7867 const environment& env = type->get_environment();
7868 type_base_sptr t = type;
7869
7870 if (const typedef_decl_sptr ty = is_typedef(t))
7871 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
7872 else if (const reference_type_def_sptr ty = is_reference_type(t))
7873 {
7874 auto typ = type_or_void(ty->get_pointed_to_type(), env);
7875 type_base_sptr p = strip_typedef(typ);
7876 ABG_ASSERT(p);
7877 t.reset(new reference_type_def(p,
7878 ty->is_lvalue(),
7879 ty->get_size_in_bits(),
7880 ty->get_alignment_in_bits(),
7881 ty->get_location()));
7883 ABG_ASSERT(scope);
7884 add_decl_to_scope(is_decl(t), scope);
7885 }
7886 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
7887 {
7888 auto typ = type_or_void(ty->get_pointed_to_type(), env);
7889 type_base_sptr p = strip_typedef(typ);
7890 ABG_ASSERT(p);
7891 t.reset(new pointer_type_def(p,
7892 ty->get_size_in_bits(),
7893 ty->get_alignment_in_bits(),
7894 ty->get_location()));
7896 ABG_ASSERT(scope);
7897 add_decl_to_scope(is_decl(t), scope);
7898 }
7899 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
7900 {
7901 auto typ = type_or_void(ty->get_underlying_type(), env);
7902 type_base_sptr p = strip_typedef(typ);
7903 ABG_ASSERT(p);
7904 t.reset(new qualified_type_def(p,
7905 ty->get_cv_quals(),
7906 ty->get_location()));
7908 ABG_ASSERT(scope);
7909 add_decl_to_scope(is_decl(t), scope);
7910 }
7911 else if (const array_type_def_sptr ty = is_array_type(t))
7912 {
7913 auto typ = type_or_void(ty->get_element_type(), env);
7914 type_base_sptr p = strip_typedef(typ);
7915 ABG_ASSERT(p);
7916 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
7918 ABG_ASSERT(scope);
7919 add_decl_to_scope(is_decl(t), scope);
7920 }
7921 else if (const method_type_sptr ty = is_method_type(t))
7922 {
7924 for (function_decl::parameters::const_iterator i =
7925 ty->get_parameters().begin();
7926 i != ty->get_parameters().end();
7927 ++i)
7928 {
7930 type_base_sptr typ = strip_typedef(p->get_type());
7931 ABG_ASSERT(typ);
7933 (new function_decl::parameter(typ,
7934 p->get_index(),
7935 p->get_name(),
7936 p->get_location(),
7937 p->get_variadic_marker(),
7938 p->get_is_artificial()));
7939 parm.push_back(stripped);
7940 }
7941 type_base_sptr p = strip_typedef(ty->get_return_type());
7942 ABG_ASSERT(!!p == !!ty->get_return_type());
7943 t.reset(new method_type(p, ty->get_class_type(),
7944 parm, ty->get_is_const(),
7945 ty->get_size_in_bits(),
7946 ty->get_alignment_in_bits()));
7948 ABG_ASSERT(scope);
7949 add_decl_to_scope(is_decl(t), scope);
7950 }
7951 else if (const function_type_sptr ty = is_function_type(t))
7952 {
7954 for (function_decl::parameters::const_iterator i =
7955 ty->get_parameters().begin();
7956 i != ty->get_parameters().end();
7957 ++i)
7958 {
7960 type_base_sptr typ = strip_typedef(p->get_type());
7961 ABG_ASSERT(typ);
7963 (new function_decl::parameter(typ,
7964 p->get_index(),
7965 p->get_name(),
7966 p->get_location(),
7967 p->get_variadic_marker(),
7968 p->get_is_artificial()));
7969 parm.push_back(stripped);
7970 }
7971 type_base_sptr p = strip_typedef(ty->get_return_type());
7972 ABG_ASSERT(!!p == !!ty->get_return_type());
7973 t.reset(new function_type(p, parm,
7974 ty->get_size_in_bits(),
7975 ty->get_alignment_in_bits()));
7977 ABG_ASSERT(scope);
7978 add_decl_to_scope(is_decl(t), scope);
7979 }
7980
7981 if (!t->get_translation_unit())
7982 t->set_translation_unit(type->get_translation_unit());
7983 if (!t->get_corpus())
7984 t->set_corpus(type->get_corpus());
7985
7986 if (!(type->get_canonical_type() && hash_and_canonicalize_type(t)))
7987 keep_type_alive(t);
7988
7989 return t->get_canonical_type() ? t->get_canonical_type() : t;
7990}
7991
7992/// Strip qualification from a qualified type, when it makes sense.
7993///
7994/// DWARF constructs "const reference". This is redundant because a
7995/// reference is always const. It also constructs the useless "const
7996/// void" type. The issue is these redundant types then leak into the
7997/// IR and make for bad diagnostics.
7998///
7999/// This function thus strips the const qualifier from the type in
8000/// that case. It might contain code to strip other cases like this
8001/// in the future.
8002///
8003/// @param t the type to strip const qualification from.
8004///
8005/// @return the stripped type or just return @p t.
8006decl_base_sptr
8007strip_useless_const_qualification(const qualified_type_def_sptr t)
8008{
8009 if (!t)
8010 return t;
8011
8012 decl_base_sptr result = t;
8013 type_base_sptr u = t->get_underlying_type();
8014 const environment& env = t->get_environment();
8015
8016 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
8017 && (is_reference_type(u)))
8018 || (t->get_cv_quals() & qualified_type_def::CV_CONST
8019 && env.is_void_type(u))
8020 || t->get_cv_quals() == qualified_type_def::CV_NONE)
8021 // Let's strip the const qualifier because a reference is always
8022 // 'const' and a const void doesn't make sense. They will just
8023 // lead to spurious changes later down the pipeline, that we'll
8024 // have to deal with by doing painful and error-prone editing of
8025 // the diff IR. Dropping that useless and inconsistent artefact
8026 // right here seems to be a good way to go.
8027 result = is_decl(u);
8028
8029 return result;
8030}
8031
8032/// Merge redundant qualifiers from a tree of qualified types.
8033///
8034/// Suppose a tree of qualified types leads to:
8035///
8036/// const virtual const restrict const int;
8037///
8038/// Suppose the IR tree of qualified types ressembles (with C meaning
8039/// const, V meaning virtual and R meaning restrict):
8040///
8041/// [C|V]-->[C|R] -->[C] --> [int].
8042///
8043/// This function walks the IR and remove the redundant CV qualifiers
8044/// so the IR becomes:
8045///
8046/// [C|V] --> [R] --> [] -->[int].
8047///
8048/// Note that the empty qualified type (noted []) represents a
8049/// qualified type with no qualifier. It's rare, but it can exist.
8050/// I've put it here just for the sake of example.
8051///
8052/// The resulting IR thus represents the (merged) type:
8053///
8054/// const virtual restrict int.
8055///
8056/// This function is a sub-routine of the overload @ref
8057/// strip_useless_const_qualification which doesn't return any value.
8058///
8059/// @param t the qualified type to consider.
8060///
8061/// @param redundant_quals the (redundant) qualifiers to be removed
8062/// from the qualifiers of the underlying types of @p t.
8063///
8064/// @return the underlying type of @p t which might have had its
8065/// redundant qualifiers removed.
8066static qualified_type_def_sptr
8067strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
8068 qualified_type_def::CV redundant_quals)
8069{
8070 if (!t)
8071 return t;
8072
8073 // We must NOT edit canonicalized types.
8074 ABG_ASSERT(!t->get_canonical_type());
8075
8076 qualified_type_def_sptr underlying_qualified_type =
8077 is_qualified_type(t->get_underlying_type());
8078
8079 // Let's build 'currated qualifiers' that are the qualifiers of the
8080 // current type from which redundant qualifiers are removed.
8081 qualified_type_def::CV currated_quals = t->get_cv_quals();
8082
8083 // Remove the redundant qualifiers from these currated qualifiers
8084 currated_quals &= ~redundant_quals;
8085 t->set_cv_quals(currated_quals);
8086
8087 // The redundant qualifiers, moving forward, is now the union of the
8088 // previous set of redundant qualifiers and the currated qualifiers.
8089 redundant_quals |= currated_quals;
8090
8091 qualified_type_def_sptr result = t;
8092 if (underlying_qualified_type)
8093 // Now remove the redundant qualifiers from the qualified types
8094 // potentially carried by the underlying type.
8095 result =
8096 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
8097 redundant_quals);
8098
8099 return result;
8100}
8101
8102/// Merge redundant qualifiers from a tree of qualified types.
8103///
8104/// Suppose a tree of qualified types leads to:
8105///
8106/// const virtual const restrict const int;
8107///
8108/// Suppose the IR tree of qualified types ressembles (with C meaning
8109/// const, V meaning virtual and R meaning restrict):
8110///
8111/// [C|V]-->[C|R] -->[C] --> [int].
8112///
8113/// This function walks the IR and remove the redundant CV qualifiers
8114/// so the IR becomes:
8115///
8116/// [C|V] --> [R] --> [] -->[int].
8117///
8118/// Note that the empty qualified type (noted []) represents a
8119/// qualified type with no qualifier. It's rare, but it can exist.
8120/// I've put it here just for the sake of example.
8121///
8122/// The resulting IR thus represents the (merged) type:
8123///
8124/// const virtual restrict int.
8125///
8126/// @param t the qualified type to consider. The IR below the
8127/// argument to this parameter will be edited to remove redundant
8128/// qualifiers where applicable.
8129void
8130strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
8131{
8132 if (!t)
8133 return;
8134
8135 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
8136 strip_redundant_quals_from_underyling_types(t, redundant_quals);
8137}
8138
8139/// Return the leaf underlying type node of a @ref typedef_decl node.
8140///
8141/// If the underlying type of a @ref typedef_decl node is itself a
8142/// @ref typedef_decl node, then recursively look at the underlying
8143/// type nodes to get the first one that is not a a @ref typedef_decl
8144/// node. This is what a leaf underlying type node means.
8145///
8146/// Otherwise, if the underlying type node of @ref typedef_decl is
8147/// *NOT* a @ref typedef_decl node, then just return the underlying
8148/// type node.
8149///
8150/// And if the type node considered is not a @ref typedef_decl node,
8151/// then just return it.
8152///
8153/// @return the leaf underlying type node of a @p type.
8154type_base_sptr
8155peel_typedef_type(const type_base_sptr& type)
8156{
8157 typedef_decl_sptr t = is_typedef(type);
8158 if (!t)
8159 return type;
8160
8161 if (is_typedef(t->get_underlying_type())
8162 && *t->get_underlying_type() != *type)
8163 return peel_typedef_type(t->get_underlying_type());
8164 return t->get_underlying_type();
8165}
8166
8167/// Return the leaf underlying type node of a @ref typedef_decl node.
8168///
8169/// If the underlying type of a @ref typedef_decl node is itself a
8170/// @ref typedef_decl node, then recursively look at the underlying
8171/// type nodes to get the first one that is not a a @ref typedef_decl
8172/// node. This is what a leaf underlying type node means.
8173///
8174/// Otherwise, if the underlying type node of @ref typedef_decl is
8175/// *NOT* a @ref typedef_decl node, then just return the underlying
8176/// type node.
8177///
8178/// And if the type node considered is not a @ref typedef_decl node,
8179/// then just return it.
8180///
8181/// @return the leaf underlying type node of a @p type.
8182const type_base*
8184{
8185 const typedef_decl* t = is_typedef(type);
8186 if (!t)
8187 return type;
8188
8189 return peel_typedef_type(t->get_underlying_type()).get();
8190}
8191
8192/// Return the leaf pointed-to type node of a @ref pointer_type_def
8193/// node.
8194///
8195/// If the pointed-to type of a @ref pointer_type_def node is itself a
8196/// @ref pointer_type_def node, then recursively look at the
8197/// pointed-to type nodes to get the first one that is not a a @ref
8198/// pointer_type_def node. This is what a leaf pointed-to type node
8199/// means.
8200///
8201/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
8202/// *NOT* a @ref pointer_type_def node, then just return the
8203/// pointed-to type node.
8204///
8205/// And if the type node considered is not a @ref pointer_type_def
8206/// node, then just return it.
8207///
8208/// @return the leaf pointed-to type node of a @p type.
8209type_base_sptr
8210peel_pointer_type(const type_base_sptr& type)
8211{
8213 if (!t)
8214 return type;
8215
8216 if (is_pointer_type(t->get_pointed_to_type()))
8217 return peel_pointer_type(t->get_pointed_to_type());
8218 return t->get_pointed_to_type();
8219}
8220
8221/// Return the leaf pointed-to type node of a @ref pointer_type_def
8222/// node.
8223///
8224/// If the pointed-to type of a @ref pointer_type_def node is itself a
8225/// @ref pointer_type_def node, then recursively look at the
8226/// pointed-to type nodes to get the first one that is not a a @ref
8227/// pointer_type_def node. This is what a leaf pointed-to type node
8228/// means.
8229///
8230/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
8231/// *NOT* a @ref pointer_type_def node, then just return the
8232/// pointed-to type node.
8233///
8234/// And if the type node considered is not a @ref pointer_type_def
8235/// node, then just return it.
8236///
8237/// @return the leaf pointed-to type node of a @p type.
8238const type_base*
8240{
8241 const pointer_type_def* t = is_pointer_type(type);
8242 if (!t)
8243 return type;
8244
8245 return peel_pointer_type(t->get_pointed_to_type()).get();
8246}
8247
8248/// Return the leaf pointed-to type node of a @ref reference_type_def
8249/// node.
8250///
8251/// If the pointed-to type of a @ref reference_type_def node is itself
8252/// a @ref reference_type_def node, then recursively look at the
8253/// pointed-to type nodes to get the first one that is not a a @ref
8254/// reference_type_def node. This is what a leaf pointed-to type node
8255/// means.
8256///
8257/// Otherwise, if the pointed-to type node of @ref reference_type_def
8258/// is *NOT* a @ref reference_type_def node, then just return the
8259/// pointed-to type node.
8260///
8261/// And if the type node considered is not a @ref reference_type_def
8262/// node, then just return it.
8263///
8264/// @return the leaf pointed-to type node of a @p type.
8265type_base_sptr
8266peel_reference_type(const type_base_sptr& type)
8267{
8269 if (!t)
8270 return type;
8271
8272 if (is_reference_type(t->get_pointed_to_type()))
8273 return peel_reference_type(t->get_pointed_to_type());
8274 return t->get_pointed_to_type();
8275}
8276
8277/// Return the leaf pointed-to type node of a @ref reference_type_def
8278/// node.
8279///
8280/// If the pointed-to type of a @ref reference_type_def node is itself
8281/// a @ref reference_type_def node, then recursively look at the
8282/// pointed-to type nodes to get the first one that is not a a @ref
8283/// reference_type_def node. This is what a leaf pointed-to type node
8284/// means.
8285///
8286/// Otherwise, if the pointed-to type node of @ref reference_type_def
8287/// is *NOT* a @ref reference_type_def node, then just return the
8288/// pointed-to type node.
8289///
8290/// And if the type node considered is not a @ref reference_type_def
8291/// node, then just return it.
8292///
8293/// @return the leaf pointed-to type node of a @p type.
8294const type_base*
8296{
8297 const reference_type_def* t = is_reference_type(type);
8298 if (!t)
8299 return type;
8300
8301 return peel_reference_type(t->get_pointed_to_type()).get();
8302}
8303
8304/// Return the leaf element type of an array.
8305///
8306/// If the element type is itself an array, then recursively return
8307/// the element type of that array itself.
8308///
8309/// @param type the array type to consider. If this is not an array
8310/// type, this type is returned by the function.
8311///
8312/// @return the leaf element type of the array @p type, or, if it's
8313/// not an array type, then just return @p.
8314const type_base_sptr
8315peel_array_type(const type_base_sptr& type)
8316{
8317 const array_type_def_sptr t = is_array_type(type);
8318 if (!t)
8319 return type;
8320
8321 return peel_array_type(t->get_element_type());
8322}
8323
8324/// Return the leaf element type of an array.
8325///
8326/// If the element type is itself an array, then recursively return
8327/// the element type of that array itself.
8328///
8329/// @param type the array type to consider. If this is not an array
8330/// type, this type is returned by the function.
8331///
8332/// @return the leaf element type of the array @p type, or, if it's
8333/// not an array type, then just return @p.
8334const type_base*
8336{
8337 const array_type_def* t = is_array_type(type);
8338 if (!t)
8339 return type;
8340
8341 return peel_array_type(t->get_element_type()).get();
8342}
8343
8344/// Return the leaf underlying type of a qualified type.
8345///
8346/// If the underlying type is itself a qualified type, then
8347/// recursively return the first underlying type of that qualified
8348/// type to return the first underlying type that is not a qualified type.
8349///
8350/// If the underlying type is NOT a qualified type, then just return
8351/// that underlying type.
8352///
8353/// @param type the qualified type to consider.
8354///
8355/// @return the leaf underlying type.
8356const type_base*
8358{
8359 const qualified_type_def* t = is_qualified_type(type);
8360 if (!t)
8361 return type;
8362
8363 return peel_qualified_type(t->get_underlying_type().get());
8364}
8365
8366/// Return the leaf underlying type of a qualified type.
8367///
8368/// If the underlying type is itself a qualified type, then
8369/// recursively return the first underlying type of that qualified
8370/// type to return the first underlying type that is not a qualified type.
8371///
8372/// If the underlying type is NOT a qualified type, then just return
8373/// that underlying type.
8374///
8375/// @param type the qualified type to consider.
8376///
8377/// @return the leaf underlying type.
8378const type_base_sptr
8379peel_qualified_type(const type_base_sptr& type)
8380{
8381 const qualified_type_def_sptr t = is_qualified_type(type);
8382 if (!t)
8383 return type;
8384
8385 return peel_qualified_type(t->get_underlying_type());
8386}
8387
8388/// Test if a given qualified type is const.
8389///
8390/// @pram t the qualified type to consider.
8391///
8392/// @return true iff @p t is a const qualified type.
8393bool
8394is_const_qualified_type(const qualified_type_def_sptr& t)
8395{
8396 if (!t)
8397 return false;
8398
8399 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
8400 return true;
8401
8402 return false;
8403}
8404
8405/// Test if a given type is const-qualified.
8406///
8407/// @pram t the type to consider.
8408///
8409/// @return true iff @p t is a const qualified type.
8410bool
8411is_const_qualified_type(const type_base_sptr& t)
8412{
8413 qualified_type_def_sptr q = is_qualified_type(t);
8414 if (!q)
8415 return false;
8416 return is_const_qualified_type(q);
8417}
8418
8419/// If a qualified type is const, then return its underlying type.
8420///
8421/// @param q the qualified type to consider.
8422///
8423/// @return the underlying type of @p q if it's a const-qualified
8424/// type, otherwise, return @p q itself.
8425type_base_sptr
8426peel_const_qualified_type(const qualified_type_def_sptr& q)
8427{
8428 if (!q)
8429 return q;
8430
8432 return q->get_underlying_type();
8433
8434 return q;
8435}
8436
8437/// Return the leaf underlying type of a qualified or typedef type.
8438///
8439/// If the underlying type is itself a qualified or typedef type, then
8440/// recursively return the first underlying type of that qualified or
8441/// typedef type to return the first underlying type that is not a
8442/// qualified or typedef type.
8443///
8444/// If the underlying type is NOT a qualified nor a typedef type, then
8445/// just return that underlying type.
8446///
8447/// @param type the qualified or typedef type to consider.
8448///
8449/// @return the leaf underlying type.
8450type_base*
8452{
8453 while (is_typedef(type) || is_qualified_type(type))
8454 {
8455 if (const typedef_decl* t = is_typedef(type))
8456 type = peel_typedef_type(t);
8457
8458 if (const qualified_type_def* t = is_qualified_type(type))
8459 type = peel_qualified_type(t);
8460 }
8461
8462 return const_cast<type_base*>(type);
8463}
8464
8465/// Return the leaf underlying type of a qualified or typedef type.
8466///
8467/// If the underlying type is itself a qualified or typedef type, then
8468/// recursively return the first underlying type of that qualified or
8469/// typedef type to return the first underlying type that is not a
8470/// qualified or typedef type.
8471///
8472/// If the underlying type is NOT a qualified nor a typedef type, then
8473/// just return that underlying type.
8474///
8475/// @param type the qualified or typedef type to consider.
8476///
8477/// @return the leaf underlying type.
8478type_base_sptr
8479peel_qualified_or_typedef_type(const type_base_sptr &t)
8480{
8481 type_base_sptr type = t;
8482 while (is_typedef(type) || is_qualified_type(type))
8483 {
8484 if (typedef_decl_sptr t = is_typedef(type))
8485 type = peel_typedef_type(t);
8486
8487 if (qualified_type_def_sptr t = is_qualified_type(type))
8488 type = peel_qualified_type(t);
8489 }
8490
8491 return type;
8492}
8493
8494/// Return the leaf underlying or pointed-to type node of a @ref
8495/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
8496/// or @ref array_type_def node.
8497///
8498/// @param type the type to peel.
8499///
8500/// @return the leaf underlying or pointed-to type node of @p type.
8501type_base_sptr
8503{
8504 type_base_sptr typ = type;
8505 while (is_typedef(typ)
8506 || is_pointer_type(typ)
8507 || is_reference_type(typ)
8508 || is_array_type(typ))
8509 {
8510 if (typedef_decl_sptr t = is_typedef(typ))
8511 typ = peel_typedef_type(t);
8512
8514 typ = peel_pointer_type(t);
8515
8517 typ = peel_reference_type(t);
8518
8519 if (const array_type_def_sptr t = is_array_type(typ))
8520 typ = peel_array_type(t);
8521 }
8522
8523 return typ;
8524}
8525
8526/// Return the leaf underlying or pointed-to type node of a @ref
8527/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
8528/// node.
8529///
8530/// @param type the type to peel.
8531///
8532/// @return the leaf underlying or pointed-to type node of @p type.
8533type_base*
8535{
8536 while (is_typedef(type)
8537 || is_pointer_type(type)
8538 || is_reference_type(type)
8539 || is_array_type(type))
8540 {
8541 if (const typedef_decl* t = is_typedef(type))
8542 type = peel_typedef_type(t);
8543
8544 if (const pointer_type_def* t = is_pointer_type(type))
8545 type = peel_pointer_type(t);
8546
8547 if (const reference_type_def* t = is_reference_type(type))
8548 type = peel_reference_type(t);
8549
8550 if (const array_type_def* t = is_array_type(type))
8551 type = peel_array_type(t);
8552 }
8553
8554 return const_cast<type_base*>(type);
8555}
8556
8557/// Return the leaf underlying or pointed-to type node of a @ref
8558/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
8559/// node.
8560///
8561/// @param type the type to peel.
8562///
8563/// @return the leaf underlying or pointed-to type node of @p type.
8564type_base*
8566 bool peel_qual_type)
8567{
8568 while (is_typedef(type)
8569 || is_pointer_type(type)
8570 || is_reference_type(type)
8571 || is_array_type(type)
8572 || (peel_qual_type && is_qualified_type(type)))
8573 {
8574 if (const typedef_decl* t = is_typedef(type))
8575 type = peel_typedef_type(t);
8576
8577 if (const pointer_type_def* t = is_pointer_type(type))
8578 type = peel_pointer_type(t);
8579
8580 if (const reference_type_def* t = is_reference_type(type))
8581 type = peel_reference_type(t);
8582
8583 if (const array_type_def* t = is_array_type(type))
8584 type = peel_array_type(t);
8585
8586 if (peel_qual_type)
8587 if (const qualified_type_def* t = is_qualified_type(type))
8588 type = peel_qualified_type(t);
8589 }
8590
8591 return const_cast<type_base*>(type);
8592}
8593
8594/// Return the leaf underlying or pointed-to type node of a, @ref
8595/// pointer_type_def, @ref reference_type_def or @ref
8596/// qualified_type_def type node.
8597///
8598/// @param type the type to peel.
8599///
8600/// @param peel_qualified_type if true, also peel qualified types.
8601///
8602/// @return the leaf underlying or pointed-to type node of @p type.
8603type_base*
8605 bool peel_qual_type)
8606{
8607 while (is_pointer_type(type)
8608 || is_reference_type(type)
8609 || is_array_type(type)
8610 || (peel_qual_type && is_qualified_type(type)))
8611 {
8612 if (const pointer_type_def* t = is_pointer_type(type))
8613 type = peel_pointer_type(t);
8614
8615 if (const reference_type_def* t = is_reference_type(type))
8616 type = peel_reference_type(t);
8617
8618 if (const array_type_def* t = is_array_type(type))
8619 type = peel_array_type(t);
8620
8621 if (peel_qual_type)
8622 if (const qualified_type_def* t = is_qualified_type(type))
8623 type = peel_qualified_type(t);
8624 }
8625
8626 return const_cast<type_base*>(type);
8627}
8628
8629/// Clone an array type.
8630///
8631/// Note that the element type of the new array is shared witht the
8632/// old one.
8633///
8634/// @param array the array type to clone.
8635///
8636/// @return a newly built array type. Note that it needs to be added
8637/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
8638/// bound to the one of that scope. Otherwise, its lifetime is bound
8639/// to the lifetime of its containing shared pointer.
8642{
8643 vector<array_type_def::subrange_sptr> subranges;
8644
8645 for (vector<array_type_def::subrange_sptr>::const_iterator i =
8646 array->get_subranges().begin();
8647 i != array->get_subranges().end();
8648 ++i)
8649 {
8651 (new array_type_def::subrange_type(array->get_environment(),
8652 (*i)->get_name(),
8653 (*i)->get_lower_bound(),
8654 (*i)->get_upper_bound(),
8655 (*i)->get_underlying_type(),
8656 (*i)->get_location(),
8657 (*i)->get_language()));
8658 subrange->is_non_finite((*i)->is_non_finite());
8659 subrange->set_native_offset((*i)->get_native_offset());
8660 if (auto scope = (*i)->get_scope())
8661 add_decl_to_scope(subrange, scope);
8662 subranges.push_back(subrange);
8663 }
8664
8665 array_type_def_sptr result
8666 (new array_type_def(array->get_element_type(),
8667 subranges, array->get_location()));
8668 result->set_native_offset(array->get_native_offset());
8669
8670 return result;
8671}
8672
8673/// Clone a typedef type.
8674///
8675/// Note that the underlying type of the newly constructed typedef is
8676/// shared with the old one.
8677///
8678/// @param t the typedef to clone.
8679///
8680/// @return the newly constructed typedef. Note that it needs to be
8681/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
8682/// to be bound to the one of that scope. Otherwise, its lifetime is
8683/// bound to the lifetime of its containing shared pointer.
8686{
8687 if (!t)
8688 return t;
8689
8690 typedef_decl_sptr result
8691 (new typedef_decl(t->get_name(), t->get_underlying_type(),
8692 t->get_location(), t->get_linkage_name(),
8693 t->get_visibility()));
8694 result->set_native_offset(0xDEADBEEF);
8695 return result;
8696}
8697
8698/// Clone a qualifiend type.
8699///
8700/// Note that underlying type of the newly constructed qualified type
8701/// is shared with the old one.
8702///
8703/// @param t the qualified type to clone.
8704///
8705/// @return the newly constructed qualified type. Note that it needs
8706/// to be added to a scope (e.g, using add_decl_to_scope) for its
8707/// lifetime to be bound to the one of that scope. Otherwise, its
8708/// lifetime is bound to the lifetime of its containing shared
8709/// pointer.
8710qualified_type_def_sptr
8711clone_qualified_type(const qualified_type_def_sptr& t)
8712{
8713 if (!t)
8714 return t;
8715
8716 qualified_type_def_sptr result
8717 (new qualified_type_def(t->get_underlying_type(),
8718 t->get_cv_quals(), t->get_location()));
8719
8720 return result;
8721}
8722
8723/// Clone a typedef, an array or a qualified tree.
8724///
8725/// @param type the typedef, array or qualified tree to clone. any
8726/// order.
8727///
8728/// @return the cloned type, or NULL if @type was neither a typedef,
8729/// array nor a qualified type.
8730static type_base_sptr
8731clone_typedef_array_qualified_type(type_base_sptr type)
8732{
8733 if (!type)
8734 return type;
8735
8736 auto scope = is_decl(type) ? is_decl(type)->get_scope() : nullptr;
8737 type_base_sptr result;
8738
8739 if (typedef_decl_sptr t = is_typedef(type))
8740 result = clone_typedef(is_typedef(t));
8741 else if (qualified_type_def_sptr t = is_qualified_type(type))
8742 result = clone_qualified_type(t);
8743 else if (array_type_def_sptr t = is_array_type(type))
8744 result = clone_array(t);
8745 else
8746 return type_base_sptr();
8747
8748 if (scope)
8749 add_decl_to_scope(is_decl(result), scope);
8750
8751 return result;
8752}
8753
8754/// Clone a type tree made of an array or a typedef of array.
8755///
8756/// Note that this can be a tree which root node is a typedef an which
8757/// sub-tree can be any arbitrary combination of typedef, qualified
8758/// type and arrays.
8759///
8760/// @param t the array or typedef of qualified array to consider.
8761///
8762/// @return a clone of @p t.
8763type_base_sptr
8764clone_array_tree(const type_base_sptr t)
8765{
8767
8768 auto scope = is_decl(t)->get_scope();
8769 type_base_sptr result = clone_typedef_array_qualified_type(t);
8770 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
8771
8772 type_base_sptr subtree;
8773 if (typedef_decl_sptr type = is_typedef(result))
8774 {
8775 type_base_sptr s =
8776 clone_typedef_array_qualified_type(type->get_underlying_type());
8777 if (s)
8778 {
8779 subtree = s;
8780 type->set_underlying_type(subtree);
8781 }
8782 }
8783 else if (array_type_def_sptr type = is_array_type(result))
8784 {
8785 type_base_sptr s =
8786 clone_typedef_array_qualified_type(type->get_element_type());
8787 if (s)
8788 {
8789 subtree = s;
8790 type->set_element_type(subtree);
8791 }
8792 }
8793 add_decl_to_scope(is_decl(subtree), scope);
8794
8795 for (;;)
8796 {
8797 if (typedef_decl_sptr t = is_typedef(subtree))
8798 {
8799 type_base_sptr s =
8800 clone_typedef_array_qualified_type(t->get_underlying_type());
8801 if (s)
8802 {
8803 auto scope =
8804 is_decl(t->get_underlying_type())->get_scope();
8805 ABG_ASSERT(scope);
8806 add_decl_to_scope(is_decl(s), scope);
8807 t->set_underlying_type (s);
8808 subtree = s;
8809 }
8810 else
8811 break;
8812 }
8813 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
8814 {
8815 type_base_sptr s =
8816 clone_typedef_array_qualified_type(t->get_underlying_type());
8817 if (s)
8818 {
8819 auto scope =
8820 is_decl(t->get_underlying_type())->get_scope();
8821 ABG_ASSERT(scope);
8822 add_decl_to_scope(is_decl(s), scope);
8823 t->set_underlying_type(s);
8824 subtree = s;
8825 }
8826 else
8827 break;
8828 }
8829 else if (array_type_def_sptr t = is_array_type(subtree))
8830 {
8831 type_base_sptr e = t->get_element_type();
8832 if (is_typedef(e) || is_qualified_type(e))
8833 {
8834 type_base_sptr s =
8835 clone_typedef_array_qualified_type(e);
8836 if (s)
8837 {
8838 auto scope = is_decl(e)->get_scope();
8839 ABG_ASSERT(scope);
8840 add_decl_to_scope(is_decl(s), scope);
8841 t->set_element_type(s);
8842 }
8843 else
8844 break;
8845 }
8846 break;
8847 }
8848 else
8849 break;
8850 }
8851 return result;
8852}
8853
8854/// Update the qualified name of a given sub-tree.
8855///
8856/// @param d the sub-tree for which to update the qualified name.
8857static void
8858update_qualified_name(decl_base * d)
8859{
8860 ::qualified_name_setter setter;
8861 d->traverse(setter);
8862}
8863
8864/// Update the qualified name of a given sub-tree.
8865///
8866/// @param d the sub-tree for which to update the qualified name.
8867static void
8868update_qualified_name(decl_base_sptr d)
8869{return update_qualified_name(d.get());}
8870
8871// <scope_decl stuff>
8872
8873/// Hash a type by returning the pointer value of its canonical type.
8874///
8875/// @param l the type to hash.
8876///
8877/// @return the the pointer value of the canonical type of @p l.
8878size_t
8879canonical_type_hash::operator()(const type_base_sptr& l) const
8880{return operator()(l.get());}
8881
8882/// Hash a (canonical) type by returning its pointer value
8883///
8884/// @param l the canonical type to hash.
8885///
8886/// @return the pointer value of the canonical type of @p l.
8887size_t
8889{
8890 if (l->get_naked_canonical_type())
8891 return reinterpret_cast<size_t>(l->get_naked_canonical_type());
8892 return reinterpret_cast<size_t>(l);
8893}
8894
8895/// Constructor of the @ref scope_decl type.
8896///
8897/// @param the environment to use for the new instance.
8898///
8899/// @param the name of the scope decl.
8900///
8901/// @param locus the source location where the scope_decl is defined.
8902///
8903/// @param vis the visibility of the declaration.
8904scope_decl::scope_decl(const environment& env,
8905 const string& name,
8906 const location& locus,
8907 visibility vis)
8908 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
8909 decl_base(env, name, locus, /*mangled_name=*/name, vis),
8910 priv_(new priv)
8911{}
8912
8913/// Constructor of the @ref scope_decl type.
8914///
8915/// @param the environment to use for the new instance.
8916///
8917/// @param l the source location where the scope_decl is defined.
8918///
8919/// @param vis the visibility of the declaration.
8920scope_decl::scope_decl(const environment& env, location& l)
8921 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
8922 decl_base(env, "", l),
8923 priv_(new priv)
8924{}
8925
8926/// @eturn the set of canonical types of the the current scope.
8929{return priv_->canonical_types_;}
8930
8931/// @eturn the set of canonical types of the the current scope.
8934{return const_cast<scope_decl*>(this)->get_canonical_types();}
8935
8936/// Return a vector of sorted canonical types of the current scope.
8937///
8938/// The types are sorted "almost topologically". That means, they are
8939/// sorted using the lexicographic order of the string representing
8940/// the location their definition point. If a type doesn't have a
8941/// location, then its pretty representation is used.
8942///
8943/// @return a vector of sorted canonical types of the current scope.
8946{
8947 if (priv_->sorted_canonical_types_.empty())
8948 {
8949 {
8950 lock_guard<recursive_mutex> lock(get_mutex());
8951 for (auto t : get_canonical_types())
8952 priv_->sorted_canonical_types_.push_back(t);
8953 }
8954
8955 type_topo_comp comp;
8956 std::stable_sort(priv_->sorted_canonical_types_.begin(),
8957 priv_->sorted_canonical_types_.end(),
8958 comp);
8959 }
8960 return priv_->sorted_canonical_types_;
8961}
8962
8963/// Getter for the member declarations carried by the current @ref
8964/// scope_decl.
8965///
8966/// @return the member declarations carried by the current @ref
8967/// scope_decl.
8970{return priv_->members_;}
8971
8972/// Getter for the member declarations carried by the current @ref
8973/// scope_decl.
8974///
8975/// @return the member declarations carried by the current @ref
8976/// scope_decl.
8979{return priv_->members_;}
8980
8981/// Getter for a copy of the member declarations carried by the
8982/// current @ref scope_decl.
8983///
8984/// @return the member declarations carried by the current @ref
8985/// scope_decl.
8988{
8989 declarations result;
8990 {
8991 lock_guard<recursive_mutex> lock(get_mutex());
8992 result.reserve(priv_->members_.size());
8993 for (auto m : priv_->members_)
8994 result.push_back(m);
8995 }
8996 return result;
8997}
8998
8999/// Getter for the sorted member declarations carried by the current
9000/// @ref scope_decl.
9001///
9002/// @return the sorted member declarations carried by the current @ref
9003/// scope_decl. The declarations are sorted topologically.
9006{
9007 decl_topo_comp comp;
9008 if (priv_->sorted_members_.empty())
9009 {
9010 {
9011 lock_guard<recursive_mutex> lock(get_mutex());
9012 for (auto m : get_member_decls())
9013 priv_->sorted_members_.push_back(m);
9014 }
9015
9016 std::stable_sort(priv_->sorted_members_.begin(),
9017 priv_->sorted_members_.end(),
9018 comp);
9019 }
9020 return priv_->sorted_members_;
9021}
9022
9023/// Getter for the number of anonymous classes contained in this
9024/// scope.
9025///
9026/// @return the number of anonymous classes contained in this scope.
9027size_t
9029{
9030 int result = 0;
9031 for (declarations::const_iterator it = get_member_decls().begin();
9032 it != get_member_decls().end();
9033 ++it)
9034 if (class_decl_sptr t = is_class_type(*it))
9035 if (t->get_is_anonymous())
9036 ++result;
9037
9038 return result;
9039}
9040
9041/// Getter for the number of anonymous unions contained in this
9042/// scope.
9043///
9044/// @return the number of anonymous unions contained in this scope.
9045size_t
9047{
9048 int result = 0;
9049 for (declarations::const_iterator it = get_member_decls().begin();
9050 it != get_member_decls().end();
9051 ++it)
9052 if (union_decl_sptr t = is_union_type(*it))
9053 if (t->get_is_anonymous())
9054 ++result;
9055
9056 return result;
9057}
9058
9059/// Getter for the number of anonymous enums contained in this
9060/// scope.
9061///
9062/// @return the number of anonymous enums contained in this scope.
9063size_t
9065{
9066 int result = 0;
9067 for (declarations::const_iterator it = get_member_decls().begin();
9068 it != get_member_decls().end();
9069 ++it)
9070 if (enum_type_decl_sptr t = is_enum_type(*it))
9071 if (t->get_is_anonymous())
9072 ++result;
9073
9074 return result;
9075}
9076
9077/// Getter for the scopes carried by the current scope.
9078///
9079/// @return the scopes carried by the current scope.
9082{return priv_->member_scopes_;}
9083
9084/// Getter for the scopes carried by the current scope.
9085///
9086/// @return the scopes carried by the current scope.
9087const scope_decl::scopes&
9089{return priv_->member_scopes_;}
9090
9091/// Test if the current scope is empty.
9092///
9093/// @return true iff the current scope is empty.
9094bool
9096{
9097 lock_guard<recursive_mutex> lock(get_mutex());
9098 return (get_member_decls().empty()
9099 && get_canonical_types().empty());
9100}
9101
9102/// Set the translation unit of a decl
9103///
9104/// It also perform some IR integrity checks.
9105///
9106/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
9107///
9108/// @param decl the decl to set the translation unit for.
9109///
9110/// @param tu the translation unit to set.
9111static void
9112maybe_set_translation_unit(const decl_base_sptr& decl,
9113 translation_unit* tu)
9114{
9115 ABG_ASSERT(tu);
9116
9117 if (translation_unit* existing_tu = decl->get_translation_unit())
9118 // The decl already belongs to a translation unit.
9119 // Either:
9120 //
9121 // 1/ it's a unique type, in which case we should not add it to
9122 // any translation unique since unique types are "logically"
9123 // supposed to belong to no translation unit in particular, as
9124 // they are unique.
9125 //
9126 // 2/ or the decl was already added to this translation unit.
9127 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
9128 else
9129 decl->set_translation_unit(tu);
9130
9131 if (tu->get_corpus())
9132 decl->set_corpus(tu->get_corpus());
9133}
9134
9135/// Add a member decl to this scope. Note that user code should not
9136/// use this, but rather use add_decl_to_scope.
9137///
9138/// Note that this function updates the qualified name of the member
9139/// decl that is added. It also sets the scope of the member. Thus,
9140/// it ABG_ASSERTs that member should not have its scope set, prior to
9141/// calling this function.
9142///
9143/// @param scope the scope to consider.
9144///
9145/// @param member the new member decl to add to this scope.
9146decl_base_sptr
9147add_member_decl(scope_decl_sptr scope, decl_base_sptr member)
9148{
9149 ABG_ASSERT(!has_scope(member));
9150
9151 {
9152 lock_guard<recursive_mutex> lock(scope->get_mutex());
9153 member->set_scope(scope);
9154 scope->priv_->members_.push_back(member);
9155 if (is_type(member))
9156 {
9157 scope->priv_->member_types_.push_back(is_type(member));
9158 scope->priv_->clear_sorted_member_types_cache_ = true;
9159 }
9160
9161 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
9162 scope->priv_->member_scopes_.push_back(m);
9163 }
9164
9165 update_qualified_name(member);
9166
9167 if (translation_unit* tu = scope->get_translation_unit())
9168 maybe_set_translation_unit(member, tu);
9169
9171
9172 return member;
9173}
9174
9175/// Get the member types of this @ref scope_decl.
9176///
9177/// @return a vector of the member types of this ref class_or_union.
9180{return priv_->member_types_;}
9181
9182/// Find a member type of a given name, inside the current @ref
9183/// scope_decl.
9184///
9185/// @param name the name of the member type to look for.
9186///
9187/// @return a pointer to the @ref type_base that represents the member
9188/// type of name @p name, for the current scope.
9189type_base_sptr
9190scope_decl::find_member_type(const string& name) const
9191{
9192 lock_guard<recursive_mutex> lock(get_mutex());
9193 for (auto t : get_member_types())
9194 if (get_type_name(t, /*qualified*/false) == name)
9195 return t;
9196 return type_base_sptr();
9197}
9198
9199/// Insert a member type to a given scope.
9200///
9201/// @param scope the scope to add the member type to.
9202///
9203/// @param t the type to insert in the @ref scope_decl type.
9204///
9205/// @param an iterator right before which @p t has to be inserted.
9206void
9208 type_base_sptr t,
9209 scope_decl::declarations::iterator before)
9210{
9211 decl_base_sptr d = get_type_declaration(t);
9212 ABG_ASSERT(d);
9213 ABG_ASSERT(!has_scope(d));
9214
9215 {
9216 lock_guard<recursive_mutex> lock(scope->get_mutex());
9217 scope->priv_->member_types_.push_back(t);
9218 scope->priv_->clear_sorted_member_types_cache_= true;
9219 }
9220
9221 insert_member_decl(scope, d, before);
9222}
9223
9224/// Add a member type to a given scope.
9225///
9226/// @param scope the scope to add the member type.
9227///
9228/// @param t the member type to add. It must not have been added to a
9229/// scope, otherwise this will violate an ABG_ASSERTion.
9230void
9231add_member_type(scope_decl_sptr scope, type_base_sptr t)
9232{insert_member_type(scope, t, scope->get_member_decls().end());}
9233
9234/// Add a member type to a given instance of @ref scope_decl_sptr.
9235///
9236/// @param scope the scope to add the member type to.
9237///
9238/// @param t the type to be added as a member type to the current
9239/// instance of class_or_union. An instance of class_or_union::member_type
9240/// will be created out of @p t and and added to the the class.
9241///
9242/// @param a the access specifier for the member type to be created.
9243type_base_sptr
9245{
9246 decl_base_sptr d = get_type_declaration(t);
9247 ABG_ASSERT(d);
9249 add_member_type(scope, t);
9251 return t;
9252}
9253
9254/// Remove a member type from the current @ref class_or_union scope.
9255///
9256/// @param t the type to remove.
9257bool
9259{
9260 lock_guard<recursive_mutex> lock(get_mutex());
9261 for (auto i = priv_->member_types_.begin();
9262 i != priv_->member_types_.end();
9263 ++i)
9264 {
9265 if (*((*i)) == *t)
9266 {
9267 priv_->member_types_.erase(i);
9268 return true;
9269 }
9270 }
9271 return false;
9272}
9273
9274/// Get the sorted member types of this @ref scope_decl
9275///
9276/// @return a vector of the sorted member types of this ref
9277/// class_or_union.
9280{
9281 lock_guard<recursive_mutex> lock(get_mutex());
9282
9283 if (priv_->clear_sorted_member_types_cache_)
9284 {
9285 priv_->sorted_member_types_.clear();
9286 priv_->clear_sorted_member_types_cache_ = false;
9287 }
9288
9289 if (priv_->sorted_member_types_.empty())
9290 {
9291 unordered_set<type_base_sptr> canonical_pointer_types;
9292
9293 for (auto t : get_member_types())
9294 {
9296 priv_->sorted_member_types_.push_back(t);
9297 else if (auto c = t->get_canonical_type())
9298 canonical_pointer_types.insert(c);
9299 else
9300 canonical_pointer_types.insert(t);
9301 }
9302
9303 for (auto t : canonical_pointer_types)
9304 priv_->sorted_member_types_.push_back(t);
9305
9306 type_topo_comp comp;
9307 std::stable_sort(priv_->sorted_member_types_.begin(),
9308 priv_->sorted_member_types_.end(),
9309 comp);
9310 }
9311
9312 auto abi = get_corpus();
9313 if (!abi || !abi->priv_->types_are_canonicalized())
9314 priv_->clear_sorted_member_types_cache_ = true;
9315
9316 return priv_->sorted_member_types_;
9317}
9318
9319/// Get a copy of the sorted member types.
9320///
9321/// This is to be used in a multithreaded context to avoid data races.
9322///
9323/// @return a copy of the sorted member types.
9326{
9328 return result;
9329}
9330
9331/// Insert a member decl to a scope, right before an element pointed
9332/// to by a given iterator. Note that user code should not use this,
9333/// but rather use insert_decl_into_scope.
9334///
9335/// Note that this function updates the qualified name of the inserted
9336/// member.
9337///
9338/// @param scope the scope to insert the member decl to.
9339///
9340/// @param member the new member decl to add to this scope.
9341///
9342/// @param before an interator pointing to the element before which
9343/// the new member should be inserted.
9344decl_base_sptr
9346 decl_base_sptr member,
9347 scope_decl::declarations::iterator before)
9348{
9349 ABG_ASSERT(!member->get_scope());
9350
9351 {
9352 lock_guard<recursive_mutex> lock(scope->get_mutex());
9353 member->set_scope(scope);
9354 scope->priv_->members_.insert(before, member);
9355 }
9356
9357 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
9358 {
9359 lock_guard<recursive_mutex> lock(scope->get_mutex());
9360 scope->priv_-> member_scopes_.push_back(m);
9361 }
9362
9363 update_qualified_name(member);
9364
9365 if (translation_unit* tu = scope->get_translation_unit())
9366 maybe_set_translation_unit(member, tu);
9367
9369
9370 return member;
9371}
9372
9373/// Remove a declaration from the current scope.
9374///
9375/// @param member the declaration to remove from the scope.
9376bool
9378 decl_base_sptr member)
9379{
9380 {
9381 lock_guard<recursive_mutex> lock(scope->get_mutex());
9382 for (auto i = scope->priv_->members_.begin();
9383 i < scope->priv_->members_.end(); ++i)
9384 {
9385 if (**i == *member)
9386 {
9387 scope->priv_->members_.erase(i);
9388 // Do not access i after this point as it's invalided by the
9389 // erase call.
9390 lock_guard<recursive_mutex> lock(member->get_mutex());
9391 {
9392 member->set_scope(nullptr);
9393 member->set_translation_unit(nullptr);
9394 update_qualified_name(member);
9395 }
9396 return true;
9397 }
9398 }
9399 }
9400
9401 scope_decl_sptr m_scope = dynamic_pointer_cast<scope_decl>(member);
9402 if (m_scope)
9403 {
9404 lock_guard<recursive_mutex> lock(scope->get_mutex());
9405 for (auto i = scope->priv_->member_scopes_.begin();
9406 i != scope->priv_->member_scopes_.end();
9407 ++i)
9408 {
9409 if (**i == *member)
9410 {
9411 scope->priv_->member_scopes_.erase(i);
9412 member->set_scope(nullptr);
9413 member->set_translation_unit(nullptr);
9414 update_qualified_name(member);
9415 return true;
9416 }
9417 }
9418 }
9419
9420 return false;
9421}
9422
9423/// Compares two instances of @ref scope_decl.
9424///
9425/// If the two intances are different, set a bitfield to give some
9426/// insight about the kind of differences there are.
9427///
9428/// @param l the first artifact of the comparison.
9429///
9430/// @param r the second artifact of the comparison.
9431///
9432/// @param k a pointer to a bitfield that gives information about the
9433/// kind of changes there are between @p l and @p r. This one is set
9434/// iff @p k is non-null and the function returns false.
9435///
9436/// Please note that setting k to a non-null value does have a
9437/// negative performance impact because even if @p l and @p r are not
9438/// equal, the function keeps up the comparison in order to determine
9439/// the different kinds of ways in which they are different.
9440///
9441/// @return true if @p l equals @p r, false otherwise.
9442bool
9444{
9445 bool result = true;
9446
9447 if (!l.decl_base::operator==(r))
9448 {
9449 result = false;
9450 if (k)
9452 else
9453 ABG_RETURN_FALSE;
9454 }
9455
9456 scope_decl::declarations::const_iterator i, j;
9457 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
9458 i != l.get_member_decls().end() && j != r.get_member_decls().end();
9459 ++i, ++j)
9460 {
9461 if (**i != **j)
9462 {
9463 result = false;
9464 if (k)
9465 {
9466 *k |= SUBTYPE_CHANGE_KIND;
9467 break;
9468 }
9469 else
9470 ABG_RETURN_FALSE;
9471 }
9472 }
9473
9474 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
9475 {
9476 result = false;
9477 if (k)
9479 else
9480 ABG_RETURN_FALSE;
9481 }
9482
9483 ABG_RETURN(result);
9484}
9485
9486/// Return true iff both scopes have the same names and have the same
9487/// member decls.
9488///
9489/// This function doesn't check for equality of the scopes of its
9490/// arguments.
9491bool
9493{
9494 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
9495 if (!other)
9496 return false;
9497
9498 return equals(*this, *other, 0);
9499}
9500
9501/// Equality operator for @ref scope_decl_sptr.
9502///
9503/// @param l the left hand side operand of the equality operator.
9504///
9505/// @pram r the right hand side operand of the equalify operator.
9506///
9507/// @return true iff @p l equals @p r.
9508bool
9510{
9511 if (!!l != !!r)
9512 return false;
9513 if (l.get() == r.get())
9514 return true;
9515 return *l == *r;
9516}
9517
9518/// Inequality operator for @ref scope_decl_sptr.
9519///
9520/// @param l the left hand side operand of the equality operator.
9521///
9522/// @pram r the right hand side operand of the equalify operator.
9523///
9524/// @return true iff @p l equals @p r.
9525bool
9527{return !operator==(l, r);}
9528
9529/// Find a member of the current scope and return an iterator on it.
9530///
9531/// @param decl the scope member to find.
9532///
9533/// @param i the iterator to set to the member @p decl. This is set
9534/// iff the function returns true.
9535///
9536/// @return true if the member decl was found, false otherwise.
9537bool
9539 declarations::iterator& i)
9540{
9541 if (!decl)
9542 return false;
9543
9544 lock_guard<recursive_mutex> lock(get_mutex());
9545 if (get_member_decls().empty())
9546 {
9547 i = get_member_decls().end();
9548 return false;
9549 }
9550
9551 for (declarations::iterator it = get_member_decls().begin();
9552 it != get_member_decls().end();
9553 ++it)
9554 {
9555 if ((*it).get() == decl)
9556 {
9557 i = it;
9558 return true;
9559 }
9560 }
9561
9562 return false;
9563}
9564
9565/// Find a member of the current scope and return an iterator on it.
9566///
9567/// @param decl the scope member to find.
9568///
9569/// @param i the iterator to set to the member @p decl. This is set
9570/// iff the function returns true.
9571///
9572/// @return true if the member decl was found, false otherwise.
9573bool
9575 declarations::iterator& i)
9576{return find_iterator_for_member(decl.get(), i);}
9577
9578/// This implements the ir_traversable_base::traverse pure virtual
9579/// function.
9580///
9581/// @param v the visitor used on the current instance of scope_decl
9582/// and on its member nodes.
9583///
9584/// @return true if the traversal of the tree should continue, false
9585/// otherwise.
9586bool
9588{
9589 if (visiting())
9590 return true;
9591
9592 if (v.visit_begin(this))
9593 {
9594 visiting(true);
9595 for (auto i = get_member_decls().begin();
9596 i != get_member_decls ().end();
9597 ++i)
9598 if (!(*i)->traverse(v))
9599 break;
9600 visiting(false);
9601 }
9602 return v.visit_end(this);
9603}
9604
9605scope_decl::~scope_decl()
9606{}
9607
9608/// Appends a declaration to a given scope, if the declaration
9609/// doesn't already belong to one and if the declaration is not for a
9610/// type that is supposed to be unique.
9611///
9612/// @param decl the declaration to add to the scope
9613///
9614/// @param scope the scope to append the declaration to
9615decl_base_sptr
9616add_decl_to_scope(decl_base_sptr decl, scope_decl_sptr scope)
9617{
9618 if (!scope || !decl)
9619 return decl;
9620
9621 {
9622 // Prevent the same decl from being added to two different scopes
9623 // due to TOCTOU-style errors.
9624 lock_guard<recursive_mutex> lock(decl->priv_->add_decl_to_scope_mutex_);
9625 if (!decl->get_scope())
9626 {
9627 if (auto c = is_class_or_union_type(scope))
9628 decl = add_member_decl(c, decl);
9629 else
9630 decl = add_member_decl(scope, decl);
9631 }
9632 }
9633
9634 return decl;
9635}
9636
9637
9638/// Remove a given decl from its scope
9639///
9640/// @param decl the decl to remove from its scope.
9641void
9642remove_decl_from_scope(decl_base_sptr decl)
9643{
9644 if (!decl)
9645 return;
9646
9647 scope_decl_sptr scope = decl->get_scope();
9648 if (remove_member_decl(scope, decl))
9649 {
9650 decl->set_scope(nullptr);
9651 decl->set_translation_unit(nullptr);
9652 decl->set_corpus(nullptr);
9653 }
9654}
9655
9656/// Inserts a declaration into a given scope, before a given IR child
9657/// node of the scope.
9658///
9659/// @param decl the declaration to insert into the scope.
9660///
9661/// @param before an iterator pointing to the child IR node before
9662/// which to insert the declaration.
9663///
9664/// @param scope the scope into which to insert the declaration.
9665decl_base_sptr
9666insert_decl_into_scope(decl_base_sptr decl,
9667 scope_decl::declarations::iterator before,
9668 scope_decl_sptr scope)
9669{
9670 if (!scope ||!decl)
9671 return decl;
9672
9673 {
9674 lock_guard<recursive_mutex> lock(decl->get_mutex());
9675 if (scope && decl && !decl->get_scope())
9676 {
9677 decl_base_sptr d = insert_member_decl(scope, decl, before);
9678 decl = d;
9679 }
9680 }
9681 return decl;
9682}
9683
9684// <class global_scope stuff>
9685
9686struct global_scope::priv
9687{
9688 translation_unit * tu = nullptr;
9689
9690 priv(translation_unit* t)
9691 : tu(t)
9692 {}
9693}; // end struct global_scope::priv
9694
9695/// Constructor of the @ref global_scope type.
9696///
9697/// @param tu the translation unit the scope belongs to.
9699 : type_or_decl_base(tu->get_environment(),
9700 GLOBAL_SCOPE_DECL
9701 | ABSTRACT_DECL_BASE
9702 | ABSTRACT_SCOPE_DECL),
9703 decl_base(tu->get_environment(), "", location()),
9704 scope_decl(tu->get_environment(), "", location()),
9705 priv_(new priv(tu))
9706{
9709}
9710
9712 : type_or_decl_base(env,
9713 GLOBAL_SCOPE_DECL
9714 | ABSTRACT_DECL_BASE
9715 | ABSTRACT_SCOPE_DECL),
9716 decl_base(env, "", location()),
9717 scope_decl(env, "", location()),
9718 priv_(new priv(nullptr))
9719{
9721}
9722
9724global_scope::get_translation_unit() const
9725{return priv_->tu;}
9726
9727/// Return the global scope as seen by a given declaration.
9728///
9729/// @param decl the declaration to consider.
9730///
9731/// @return the global scope of the decl, or a null pointer if the
9732/// decl is not yet added to a translation_unit.
9734get_global_scope(decl_base_sptr decl)
9735{
9736 if (global_scope_sptr s = dynamic_pointer_cast<global_scope>(decl))
9737 return s;
9738
9739 auto scope = decl->get_scope();
9740 while (scope && !dynamic_pointer_cast<global_scope>(scope))
9741 scope = scope->get_scope();
9742
9743 return scope ? dynamic_pointer_cast<global_scope>(scope) : nullptr;
9744}
9745
9746// </class global_scope stuff>
9747
9748/// Getter of the scope of a type.
9749///
9750/// For a @ref function_type, this returns the global scope of the
9751/// translation unit the type belongs to.
9752///
9753/// @param type the type to consider.
9754///
9755/// @return the scope of the type, or theglobal scope of the
9756/// translation unit the type belongs to if we are looking at a @ref
9757/// function_type.
9760{
9761 scope_decl_sptr scope;
9762 if (auto d = dynamic_cast<decl_base*>(&type))
9763 scope = d->get_scope();
9764 else if (auto tu = type.get_translation_unit())
9765 scope = tu->get_global_scope();
9766
9767 return scope;
9768}
9769
9770/// Getter of the scope of a type.
9771///
9772/// For a @ref function_type, this returns the global scope of the
9773/// translation unit the type belongs to.
9774///
9775/// @param type the type to consider.
9776///
9777/// @return the scope of the type, or theglobal scope of the
9778/// translation unit the type belongs to if we are looking at a @ref
9779/// function_type.
9782{
9783 if (!type)
9784 return nullptr;
9785 return get_scope_of_type(*type);
9786}
9787
9788/// Getter of the scope of a type.
9789///
9790/// For a @ref function_type, this returns the global scope of the
9791/// translation unit the type belongs to.
9792///
9793/// @param type the type to consider.
9794///
9795/// @return the scope of the type, or theglobal scope of the
9796/// translation unit the type belongs to if we are looking at a @ref
9797/// function_type.
9799get_scope_of_type(type_base_sptr type)
9800{
9801 return get_scope_of_type(type.get());
9802}
9803
9804/// Return the a scope S containing a given declaration and that is
9805/// right under a given scope P.
9806///
9807/// Note that @p scope must come before @p decl in topological
9808/// order.
9809///
9810/// @param decl the decl for which to find a scope.
9811///
9812/// @param scope the scope under which the resulting scope must be.
9813///
9814/// @return the resulting scope.
9817{
9818 if (!decl)
9819 return nullptr;
9820
9821 if (scope == nullptr)
9822 return get_global_scope(decl);
9823
9824 // Handle the case where decl is a scope itself.
9825 scope_decl_sptr s = dynamic_pointer_cast<scope_decl>(decl);
9826 if (!s)
9827 s = decl->get_scope();
9828
9829 if (is_global_scope(s))
9830 return scope;
9831
9832 // Here, decl is in the scope 'scope', or decl and 'scope' are the
9833 // same. The caller needs to be prepared to deal with this case.
9834 if (s.get() == scope.get())
9835 return s;
9836
9837 while (s && !is_global_scope(s) && s->get_scope().get() != scope.get())
9838 s = s->get_scope();
9839
9840 if (!s || is_global_scope(s))
9841 // SCOPE must come before decl in topological order, but I don't
9842 // know how to ensure that ...
9843 return scope;
9844 ABG_ASSERT(s);
9845
9846 return s;
9847}
9848
9849// </scope_decl stuff>
9850
9851
9852/// Get the string representation of a CV qualifier bitmap.
9853///
9854/// @param cv_quals the bitmap of CV qualifiers to consider.
9855///
9856/// @return the string representation.
9857string
9859{
9860 string repr;
9861 if (cv_quals & qualified_type_def::CV_RESTRICT)
9862 repr = "restrict";
9863 if (cv_quals & qualified_type_def::CV_CONST)
9864 {
9865 if (!repr.empty())
9866 repr += ' ';
9867 repr += "const";
9868 }
9869 if (cv_quals & qualified_type_def::CV_VOLATILE)
9870 {
9871 if (!repr.empty())
9872 repr += ' ';
9873 repr += "volatile";
9874 }
9875 return repr;
9876}
9877
9878/// Build and return a copy of the name of an ABI artifact that is
9879/// either a type or a decl.
9880///
9881/// @param tod the ABI artifact to get the name for.
9882///
9883/// @param qualified if yes, return the qualified name of @p tod;
9884/// otherwise, return the non-qualified name;
9885///
9886/// @return the name of @p tod.
9887string
9888get_name(const type_or_decl_base *tod, bool qualified)
9889{
9890 string result;
9891
9892 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
9893
9894 if (type_base* t = dynamic_cast<type_base*>(a))
9895 result = get_type_name(t, qualified);
9896 else if (decl_base *d = dynamic_cast<decl_base*>(a))
9897 {
9898 if (qualified)
9899 result = d->get_qualified_name();
9900 else
9901 result = d->get_name();
9902 }
9903 else
9904 // We should never reach this point.
9905 abort();
9906
9907 return result;
9908}
9909
9910/// Build and return a copy of the name of an ABI artifact that is
9911/// either a type of a decl.
9912///
9913/// @param tod the ABI artifact to get the name for.
9914///
9915/// @param qualified if yes, return the qualified name of @p tod;
9916/// otherwise, return the non-qualified name;
9917///
9918/// @return the name of @p tod.
9919string
9920get_name(const type_or_decl_base_sptr& tod, bool qualified)
9921{return get_name(tod.get(), qualified);}
9922
9923/// Build and return a qualified name from a name and its scope.
9924///
9925/// The name is supposed to be for an entity that is part of the
9926/// scope.
9927///
9928/// @param the scope to consider.
9929///
9930/// @param name of the name to consider.
9931///
9932/// @return a copy of the string that represents the qualified name.
9933string
9934build_qualified_name(const scope_decl_sptr scope, const string& name)
9935{
9936 if (name.empty())
9937 return "";
9938
9939 string qualified_name;
9940 if (scope)
9941 qualified_name = scope->get_qualified_name();
9942
9943 if (qualified_name.empty())
9944 qualified_name = name;
9945 else
9946 qualified_name = qualified_name + "::" + name;
9947
9948 return qualified_name;
9949}
9950
9951/// Build and return the qualified name of a type in its scope.
9952///
9953/// @param scope the scope of the type to consider.
9954///
9955/// @param type the type to consider.
9956string
9957build_qualified_name(const scope_decl_sptr scope, const type_base_sptr& type)
9958{return build_qualified_name(scope, get_name((type)));}
9959
9960// </scope_decl stuff>
9961
9962/// Get the location of the declaration of a given type.
9963///
9964/// @param type the type to consider.
9965///
9966/// @return the location of the declaration of type @p type.
9968get_location(const type_base_sptr& type)
9969{
9970 if (decl_base_sptr decl = get_type_declaration(type))
9971 return get_location(decl);
9972 return location();
9973}
9974
9975/// Get the location of a given declaration.
9976///
9977/// @param decl the declaration to consider.
9978///
9979/// @return the location of the declaration @p decl.
9981get_location(const decl_base_sptr& decl)
9982{
9983 location loc = decl->get_location();
9984 if (!loc)
9985 {
9986 if (class_or_union_sptr c = is_class_or_union_type(decl))
9987 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
9988 {
9989 c = is_class_or_union_type(c->get_definition_of_declaration());
9990 loc = c->get_location();
9991 }
9992 }
9993 return loc;
9994}
9995
9996/// Get the scope of a given type.
9997///
9998/// @param t the type to consider.
9999///
10000/// @return the scope of type @p t or 0 if the type has no scope yet.
10003{
10004 if (!t)
10005 return 0;
10006
10008 if (d)
10009 return d->get_scope();
10010 return 0;
10011}
10012
10013/// Get the scope of a given type.
10014///
10015/// @param t the type to consider.
10016///
10017/// @return the scope of type @p t or 0 if the type has no scope yet.
10019get_type_scope(const type_base_sptr& t)
10020{return get_type_scope(t.get());}
10021
10022/// Get the name of a given type and return a copy of it.
10023///
10024/// @param t the type to consider.
10025///
10026/// @param qualified if true then return the qualified name of the
10027/// type.
10028///
10029/// @param internal set to true if the call is intended for an
10030/// internal use (for technical use inside the library itself), false
10031/// otherwise. If you don't know what this is for, then set it to
10032/// false.
10033///
10034/// @return a copy of the type name if the type has a name, or the
10035/// empty string if it does not.
10037get_type_name(const type_base_sptr& t, bool qualified, bool internal)
10038{return get_type_name(t.get(), qualified, internal);}
10039
10040/// Return true iff a decl is for a type type that has a generic
10041/// anonymous internal type name.
10042///
10043/// @param d the decl to considier.
10044///
10045/// @return true iff @p d is for a type type that has a generic
10046/// anonymous internal type name.
10047static bool
10048has_generic_anonymous_internal_type_name(const decl_base *d)
10049{
10050 return (is_class_or_union_type(d)
10051 || is_enum_type(d)
10052 || is_subrange_type(d));
10053}
10054
10055/// Return the generic internal name of an anonymous type.
10056///
10057/// For internal purposes, we want to define a generic name for all
10058/// anonymous types of a certain kind. For instance, all anonymous
10059/// structs will be have a generic name of "__anonymous_struct__", all
10060/// anonymous unions will have a generic name of
10061/// "__anonymous_union__", etc.
10062///
10063/// That generic name can be used as a hash to put all anonymous types
10064/// of a certain kind in the same hash table bucket, for instance.
10065static interned_string
10066get_generic_anonymous_internal_type_name(const decl_base *d)
10067{
10068 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
10069
10070 const environment&env = d->get_environment();
10071
10072 interned_string result;
10073 if (is_class_type(d))
10074 result =
10076 else if (is_union_type(d))
10077 result =
10079 else if (is_enum_type(d))
10080 result =
10082 else if (is_subrange_type(d))
10083 result =
10085 else
10087
10088 return result;
10089}
10090
10091/// Get the internal name for a given real type.
10092///
10093/// All real types that have the modifiers 'short, long or long
10094/// long' have the same internal name. This is so that they can all
10095/// have the same canonical type if they are of the same size.
10096/// Otherwise, 'long int' and 'long long int' would have different
10097/// canonical types even though they are equivalent from an ABI point
10098/// of view.
10099///
10100/// @param t the real type to consider
10101///
10102/// @return the internal name for @p t if it's an integral type, or
10103/// the empty string if @p t is not a real type.
10104static string
10105get_internal_real_type_name(const type_base* t)
10106{
10107 string name;
10108 type_decl *type = is_real_type(t);
10109
10110 if (!type)
10111 return name;
10112
10113 real_type int_type;
10114 if (parse_real_type(type->get_name(), int_type))
10115 name = int_type.to_string(/*internal=*/true);
10116
10117 return name;
10118}
10119
10120/// Get the name of a given type and return a copy of it.
10121///
10122/// @param t the type to consider.
10123///
10124/// @param qualified if true then return the qualified name of the
10125/// type.
10126///
10127/// @param internal set to true if the call is intended for an
10128/// internal use (for technical use inside the library itself), false
10129/// otherwise. If you don't know what this is for, then set it to
10130/// false.
10131///
10132/// @return a copy of the type name if the type has a name, or the
10133/// empty string if it does not.
10134interned_string
10135get_type_name(const type_base* t, bool qualified, bool internal)
10136{
10137 interned_string empty_string;
10138
10139 if (!t)
10140 return empty_string;
10141
10142 const decl_base* d = dynamic_cast<const decl_base*>(t);
10143 if (!d)
10144 {
10145 const function_type* fn_type = is_function_type(t);
10146 if (!fn_type)
10147 return empty_string;
10148 return fn_type->get_cached_name(internal);
10149 }
10150
10151 const environment&env = d->get_environment();
10152
10153 // All anonymous types of a given kind get to have the same internal
10154 // name for internal purpose. This to allow them to be compared
10155 // among themselves during type canonicalization.
10156 if (internal)
10157 {
10158 if (d->get_is_anonymous() && !qualified && !is_type_decl(t))
10159 {
10160 // Note that anonymous type_decl that are used for
10161 // enumerators are not handled here because they don't have
10162 // generic internal type names.
10163 string r;
10164 r += get_generic_anonymous_internal_type_name(d);
10165 return t->get_environment().intern(r);
10166 }
10167
10168 if (is_real_type(t))
10169 return env.intern(get_internal_real_type_name(t));
10170
10171 if (qualified)
10172 return d->get_qualified_name(internal);
10173 }
10174
10175 if (d->get_is_anonymous())
10176 {
10178 {
10179 string repr =
10181 /*one_line=*/true,
10182 internal, qualified);
10183 decl_base* td = is_decl(t);
10184 if (qualified && !td->get_qualified_parent_name().empty())
10185 repr = td->get_qualified_parent_name() + "::" + repr;
10186
10187 return env.intern(repr);
10188 }
10189 }
10190
10191 if (qualified)
10192 return d->get_qualified_name(internal);
10193 return d->get_name();
10194}
10195
10196/// Get the name of a given type and return a copy of it.
10197///
10198/// @param t the type to consider.
10199///
10200/// @param qualified if true then return the qualified name of the
10201/// type.
10202///
10203/// @param internal set to true if the call is intended for an
10204/// internal use (for technical use inside the library itself), false
10205/// otherwise. If you don't know what this is for, then set it to
10206/// false.
10207///
10208/// @return a copy of the type name if the type has a name, or the
10209/// empty string if it does not.
10211get_type_name(const type_base& t, bool qualified, bool internal)
10212{return get_type_name(&t, qualified, internal);}
10213
10214/// Get the name of the pointer to a given type.
10215///
10216/// @param pointed_to_type the pointed-to-type to consider.
10217///
10218/// @param qualified this is true if the resulting name should be of a
10219/// pointer to a *fully-qualified* pointed-to-type.
10220///
10221/// @param internal true if the name is for libabigail-internal
10222/// purposes.
10223///
10224/// @return the name (string representation) of the pointer.
10227 bool qualified, bool internal)
10228{
10229 const environment& env = pointed_to_type.get_environment();
10230 string tn = get_type_name(pointed_to_type, qualified, internal);
10231 tn = tn + "*";
10232
10233 return env.intern(tn);
10234}
10235
10236/// Get the name of the reference to a given type.
10237///
10238/// @param pointed_to_type the pointed-to-type to consider.
10239///
10240/// @param qualified this is true if the resulting name should be of a
10241/// reference to a *fully-qualified* pointed-to-type.
10242///
10243/// @param internal true if the name is for libabigail-internal
10244/// purposes.
10245///
10246/// @return the name (string representation) of the reference.
10249 bool lvalue_reference,
10250 bool qualified, bool internal)
10251{
10252 const environment& env = pointed_to_type.get_environment();
10253
10254 string name = get_type_name(pointed_to_type, qualified, internal);
10255 if (lvalue_reference)
10256 name = name + "&";
10257 else
10258 name = name + "&&";
10259
10260 return env.intern(name);
10261}
10262
10263/// Get the name of a qualified type, given the underlying type and
10264/// its qualifiers.
10265///
10266/// @param underlying_type the underlying type to consider.
10267///
10268/// @param quals the CV qualifiers of the name.
10269///
10270/// @param qualified true if we should consider the fully qualified
10271/// name of @p underlying_type.
10272///
10273/// @param internal true if the result is to be used for
10274/// libabigail-internal purposes.
10275///
10276/// @return the name (string representation) of the qualified type.
10278get_name_of_qualified_type(const type_base_sptr& underlying_type,
10280 bool qualified, bool internal)
10281{
10282 const environment& env = underlying_type->get_environment();
10283
10284 string quals_repr = get_string_representation_of_cv_quals(quals);
10285 string name = get_type_name(underlying_type, qualified, internal);
10286
10287 if (quals_repr.empty() && internal)
10288 // We are asked to return the internal name, that might be used
10289 // for type canonicalization. For that canonicalization, we need
10290 // to make a difference between a no-op qualified type which
10291 // underlying type is foo (the qualified type is named "none
10292 // foo"), and the name of foo, which is just "foo".
10293 //
10294 // Please remember that this has to be kept in sync with what is
10295 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
10296 // change this code here, please change that code there too.
10297 quals_repr = "";
10298
10299 if (!quals_repr.empty())
10300 {
10301 if (is_pointer_type(peel_qualified_type(underlying_type))
10302 || is_reference_type(peel_qualified_type(underlying_type)))
10303 {
10304 name += " ";
10305 name += quals_repr;
10306 }
10307 else
10308 name = quals_repr + " " + name;
10309 }
10310
10311 return env.intern(name);
10312}
10313
10314/// Get the name of a given function type and return a copy of it.
10315///
10316/// @param fn_type the function type to consider.
10317///
10318/// @param internal set to true if the call is intended for an
10319/// internal use (for technical use inside the library itself), false
10320/// otherwise. If you don't know what this is for, then set it to
10321/// false.
10322///
10323/// @return a copy of the function type name
10326 bool internal)
10327{return get_function_type_name(fn_type.get(), internal);}
10328
10329/// Get the name of a given function type and return a copy of it.
10330///
10331/// @param fn_type the function type to consider.
10332///
10333/// @param internal set to true if the call is intended for an
10334/// internal use (for technical use inside the library itself), false
10335/// otherwise. If you don't know what this is for, then set it to
10336/// false.
10337///
10338/// @return a copy of the function type name
10341 bool internal)
10342{
10343 ABG_ASSERT(fn_type);
10344
10345 if (const method_type* method = is_method_type(fn_type))
10346 return get_method_type_name(method, internal);
10347
10348 return get_function_type_name(*fn_type, internal);
10349}
10350
10351/// Get the name of a given function type and return a copy of it.
10352///
10353/// @param fn_type the function type to consider.
10354///
10355/// @param internal set to true if the call is intended for an
10356/// internal use (for technical use inside the library itself), false
10357/// otherwise. If you don't know what this is for, then set it to
10358/// false.
10359///
10360/// @return a copy of the function type name
10363 bool internal)
10364{
10365 std::ostringstream o;
10366 // When the function name is used for internal purposes (e.g, for
10367 // canonicalization), we want its representation to stay the same,
10368 // regardless of typedefs. So let's strip typedefs from the return
10369 // type.
10370 type_base_sptr return_type = fn_type.get_return_type();
10371 const environment& env = fn_type.get_environment();
10372
10373 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
10374 stream_pretty_representation_of_fn_parms(fn_type, o,
10375 /*qualified=*/true,
10376 internal);
10377 return env.intern(o.str());
10378}
10379
10380/// Get the ID of the symbol of a function or the linkage name of the
10381/// function if it has no symbol.
10382///
10383/// @return the function symbol ID or the linkage name of the
10384/// function. several functions for the same symbol ID.
10387{
10388 ABG_ASSERT(fn);
10389
10390 string n = fn->get_symbol()
10391 ? fn->get_symbol()->get_id_string()
10392 : fn->get_linkage_name();
10393
10394 interned_string result = fn->get_environment().intern(n);
10395
10396 return result;
10397}
10398
10399/// Get the ID of the symbol of a function, or, if the ID can
10400/// designate several different functions, get its unique function ID.
10401///
10402/// @param fn the function to consider
10403///
10404/// @return the function symbol ID or unique function ID if there are
10405/// several functions for the same symbol ID.
10408{
10410
10411 if (const corpus *c = fn->get_corpus())
10412 {
10414 c->get_exported_decls_builder();
10415 if (b->fn_id_maps_to_several_fns(fn))
10416 result = fn->get_environment().intern(fn->get_id());
10417 }
10418
10419 return result;
10420}
10421
10422/// Get the name of a given method type and return a copy of it.
10423///
10424/// @param fn_type the function type to consider.
10425///
10426/// @param internal set to true if the call is intended for an
10427/// internal use (for technical use inside the library itself), false
10428/// otherwise. If you don't know what this is for, then set it to
10429/// false.
10430///
10431/// @return a copy of the function type name
10434 bool internal)
10435{return get_method_type_name(fn_type.get(), internal);}
10436
10437/// Get the name of a given method type and return a copy of it.
10438///
10439/// @param fn_type the function type to consider.
10440///
10441/// @param internal set to true if the call is intended for an
10442/// internal use (for technical use inside the library itself), false
10443/// otherwise. If you don't know what this is for, then set it to
10444/// false.
10445///
10446/// @return a copy of the function type name
10449 bool internal)
10450{
10451 if (fn_type)
10452 return get_method_type_name(*fn_type, internal);
10453
10454 return interned_string();
10455}
10456
10457/// Get the name of a given method type and return a copy of it.
10458///
10459/// @param fn_type the function type to consider.
10460///
10461/// @param internal set to true if the call is intended for an
10462/// internal use (for technical use inside the library itself), false
10463/// otherwise. If you don't know what this is for, then set it to
10464/// false.
10465///
10466/// @return a copy of the function type name
10469 bool internal)
10470{
10471 std::ostringstream o;
10472 // When the function name is used for internal purposes (e.g, for
10473 // canonicalization), we want its representation to stay the same,
10474 // regardless of typedefs. So let's strip typedefs from the return
10475 // type.
10476 type_base_sptr return_type = fn_type.get_return_type();
10477
10478 const environment& env = fn_type.get_environment();
10479
10480 if (return_type)
10481 o << get_type_name(return_type, /*qualified=*/true, internal);
10482 else
10483 // There are still some abixml files out there in which "void"
10484 // can be expressed as an empty type.
10485 o << "void";
10486
10487 class_or_union_sptr class_type = fn_type.get_class_type();
10488 ABG_ASSERT(class_type);
10489
10490 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
10491 stream_pretty_representation_of_fn_parms(fn_type, o,
10492 /*qualified=*/true,
10493 internal);
10494
10495 return env.intern(o.str());
10496}
10497
10498/// Build and return a copy of the pretty representation of an ABI
10499/// artifact that could be either a type of a decl.
10500///
10501/// param tod the ABI artifact to consider.
10502///
10503/// @param internal set to true if the call is intended for an
10504/// internal use (for technical use inside the library itself), false
10505/// otherwise. If you don't know what this is for, then set it to
10506/// false.
10507///
10508/// @return a copy of the pretty representation of an ABI artifact
10509/// that could be either a type of a decl.
10510string
10512{
10513 string result;
10514
10515 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
10516 result = get_pretty_representation(t, internal);
10517 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
10518 result = get_pretty_representation(d, internal);
10519 else
10520 // We should never reach this point
10521 abort();
10522
10523 return result;
10524}
10525
10526/// Build and return a copy of the pretty representation of an ABI
10527/// artifact that could be either a type of a decl.
10528///
10529/// param tod the ABI artifact to consider.
10530///
10531/// @param internal set to true if the call is intended for an
10532/// internal use (for technical use inside the library itself), false
10533/// otherwise. If you don't know what this is for, then set it to
10534/// false.
10535///
10536/// @return a copy of the pretty representation of an ABI artifact
10537/// that could be either a type of a decl.
10538string
10540{return get_pretty_representation(tod.get(), internal);}
10541
10542/// Get a copy of the pretty representation of a decl.
10543///
10544/// @param d the decl to consider.
10545///
10546/// @param internal set to true if the call is intended for an
10547/// internal use (for technical use inside the library itself), false
10548/// otherwise. If you don't know what this is for, then set it to
10549/// false.
10550///
10551/// @return the pretty representation of the decl.
10552string
10553get_pretty_representation(const decl_base* d, bool internal)
10554{
10555 if (!d)
10556 return "";
10557 return d->get_pretty_representation(internal);
10558}
10559
10560/// Get a copy of the pretty representation of a type.
10561///
10562/// @param d the type to consider.
10563///
10564/// @param internal set to true if the call is intended for an
10565/// internal use (for technical use inside the library itself), false
10566/// otherwise. If you don't know what this is for, then set it to
10567/// false.
10568///
10569/// @return the pretty representation of the type.
10570string
10571get_pretty_representation(const type_base* t, bool internal)
10572{
10573 if (!t)
10574 return "void";
10575 if (const function_type* fn_type = is_function_type(t))
10576 return get_pretty_representation(fn_type, internal);
10577
10578 const decl_base* d = get_type_declaration(t);
10579 ABG_ASSERT(d);
10580 return get_pretty_representation(d, internal);
10581}
10582
10583/// Get a copy of the pretty representation of a decl.
10584///
10585/// @param d the decl to consider.
10586///
10587/// @param internal set to true if the call is intended for an
10588/// internal use (for technical use inside the library itself), false
10589/// otherwise. If you don't know what this is for, then set it to
10590/// false.
10591///
10592/// @return the pretty representation of the decl.
10593string
10594get_pretty_representation(const decl_base_sptr& d, bool internal)
10595{return get_pretty_representation(d.get(), internal);}
10596
10597/// Get a copy of the pretty representation of a type.
10598///
10599/// @param d the type to consider.
10600///
10601/// @param internal set to true if the call is intended for an
10602/// internal use (for technical use inside the library itself), false
10603/// otherwise. If you don't know what this is for, then set it to
10604/// false.
10605///
10606/// @return the pretty representation of the type.
10607string
10608get_pretty_representation(const type_base_sptr& t, bool internal)
10609{return get_pretty_representation(t.get(), internal);}
10610
10611/// Get the pretty representation of a function type.
10612///
10613/// @param fn_type the function type to consider.
10614///
10615/// @param internal set to true if the call is intended for an
10616/// internal use (for technical use inside the library itself), false
10617/// otherwise. If you don't know what this is for, then set it to
10618/// false.
10619///
10620/// @return the string represenation of the function type.
10621string
10623 bool internal)
10624{return get_pretty_representation(fn_type.get(), internal);}
10625
10626/// Get the pretty representation of a function type.
10627///
10628/// @param fn_type the function type to consider.
10629///
10630/// @param internal set to true if the call is intended for an
10631/// internal use (for technical use inside the library itself), false
10632/// otherwise. If you don't know what this is for, then set it to
10633/// false.
10634///
10635/// @return the string represenation of the function type.
10636string
10637get_pretty_representation(const function_type* fn_type, bool internal)
10638{
10639 if (!fn_type)
10640 return "void";
10641
10642 if (const method_type* method = is_method_type(fn_type))
10643 return get_pretty_representation(method, internal);
10644
10645 return get_pretty_representation(*fn_type, internal);
10646}
10647
10648/// Get the pretty representation of a function type.
10649///
10650/// @param fn_type the function type to consider.
10651///
10652/// @param internal set to true if the call is intended for an
10653/// internal use (for technical use inside the library itself), false
10654/// otherwise. If you don't know what this is for, then set it to
10655/// false.
10656///
10657/// @return the string represenation of the function type.
10658string
10659get_pretty_representation(const function_type& fn_type, bool internal)
10660{
10661 std::ostringstream o;
10662 o << "function type " << get_function_type_name(fn_type, internal);
10663 return o.str();
10664}
10665
10666/// Get the pretty representation of a method type.
10667///
10668/// @param method the method type to consider.
10669///
10670/// @param internal set to true if the call is intended for an
10671/// internal use (for technical use inside the library itself), false
10672/// otherwise. If you don't know what this is for, then set it to
10673/// false.
10674///
10675/// @return the string represenation of the method type.
10676string
10677get_pretty_representation(const method_type& method, bool internal)
10678{
10679 std::ostringstream o;
10680 o << "method type " << get_method_type_name(method, internal);
10681 return o.str();
10682}
10683
10684/// Get the pretty representation of a method type.
10685///
10686/// @param method the method type to consider.
10687///
10688/// @param internal set to true if the call is intended for an
10689/// internal use (for technical use inside the library itself), false
10690/// otherwise. If you don't know what this is for, then set it to
10691/// false.
10692///
10693/// @return the string represenation of the method type.
10694string
10695get_pretty_representation(const method_type* method, bool internal)
10696{
10697 if (!method)
10698 return "void";
10699 return get_pretty_representation(*method, internal);
10700}
10701
10702/// Get the pretty representation of a method type.
10703///
10704/// @param method the method type to consider.
10705///
10706/// @param internal set to true if the call is intended for an
10707/// internal use (for technical use inside the library itself), false
10708/// otherwise. If you don't know what this is for, then set it to
10709/// false.
10710///
10711/// @return the string represenation of the method type.
10712string
10714{return get_pretty_representation(method.get(), internal);}
10715
10716/// Get the flat representation of an instance of @ref class_or_union
10717/// type.
10718///
10719/// The flat representation of a given @ref class_or_union type is the
10720/// actual definition of the type, for instance:
10721///
10722/// struct foo {int a; char b;}
10723///
10724///@param cou the instance of @ref class_or_union to consider.
10725///
10726///@param indent the identation spaces to use in the representation.
10727///
10728///@param one_line if true, then the flat representation stands on one
10729///line. Otherwise, it stands on multiple lines.
10730///
10731///@return the resulting flat representation.
10732string
10734 const string& indent,
10735 bool one_line,
10736 bool internal,
10737 bool qualified_names)
10738{
10739 string repr;
10740 string local_indent = " ";
10741
10742 if (class_decl* clazz = is_class_type(&cou))
10743 {
10744 repr = indent;
10745 if (!internal && clazz->is_struct())
10746 repr += "struct";
10747 else
10748 repr += "class";
10749 }
10750 else if (is_union_type(cou))
10751 repr = indent + "union";
10752 else
10753 return "";
10754
10755 repr += " ";
10756
10757 string name = cou.get_qualified_name();
10758
10759 if (!cou.get_is_anonymous())
10760 repr += name;
10761
10763 {
10764 // We have just detected a cycle while walking the sub-tree
10765 // of this class or union type for the purpose of printing
10766 // its flat representation. We need to get out of here
10767 // pronto or else we'll be spinning endlessly.
10768 repr += "{}";
10769 return repr;
10770 }
10771
10772 // Let's mark this class or union type to signify that we started
10773 // walking its sub-tree. This is to detect potential cycles and
10774 // avoid looping endlessly.
10776
10777 repr += "{";
10778
10779 if (!one_line)
10780 repr += "\n";
10781
10782 string real_indent;
10783 {
10785 for (class_or_union::data_members::const_iterator dm = dmems.begin();
10786 dm != dmems.end();
10787 ++dm)
10788 {
10789 if (dm != dmems.begin())
10790 {
10791 if (one_line)
10792 real_indent = " ";
10793 else
10794 real_indent = "\n" + indent + local_indent;
10795 }
10796
10798 repr +=
10801 real_indent, one_line, internal, qualified_names);
10802 else
10803 {
10804 if (one_line)
10805 {
10806 if (dm != dmems.begin())
10807 repr += real_indent;
10808 repr += (*dm)->get_pretty_representation(internal,
10809 qualified_names);
10810 }
10811 else
10812 repr +=
10813 real_indent+ (*dm)->get_pretty_representation(internal,
10814 qualified_names);
10815 }
10816 repr += ";";
10817 }
10818 }
10819 if (one_line)
10820 repr += "}";
10821 else
10822 repr += indent + "}";
10823
10824 // Let's unmark this class or union type to signify that we are done
10825 // walking its sub-tree. This was to detect potential cycles and
10826 // avoid looping endlessly.
10828
10829 return repr;
10830}
10831
10832/// Get the flat representation of an instance of @ref class_or_union
10833/// type.
10834///
10835/// The flat representation of a given @ref class_or_union type is the
10836/// actual definition of the type, for instance:
10837///
10838/// struct foo {int a; char b;}
10839///
10840///@param cou the instance of @ref class_or_union to consider.
10841///
10842///@param indent the identation spaces to use in the representation.
10843///
10844///@param one_line if true, then the flat representation stands on one
10845///line. Otherwise, it stands on multiple lines.
10846///
10847///@return the resulting flat representation.
10848string
10850 const string& indent,
10851 bool one_line,
10852 bool internal,
10853 bool qualified_names)
10854{
10855 if (cou)
10856 return get_class_or_union_flat_representation(*cou, indent, one_line,
10857 internal, qualified_names);
10858 return "";
10859}
10860
10861/// Get the flat representation of an instance of @ref class_or_union
10862/// type.
10863///
10864/// The flat representation of a given @ref class_or_union type is the
10865/// actual definition of the type, for instance:
10866///
10867/// struct foo {int a; char b;}
10868///
10869///@param cou the instance of @ref class_or_union to consider.
10870///
10871///@param indent the identation spaces to use in the representation.
10872///
10873///@param one_line if true, then the flat representation stands on one
10874///line. Otherwise, it stands on multiple lines.
10875///
10876///@return the resulting flat representation.
10877string
10878get_class_or_union_flat_representation(const class_or_union_sptr cou,
10879 const string& indent,
10880 bool one_line,
10881 bool internal,
10882 bool qualified_names)
10884 indent,
10885 one_line,
10886 internal,
10887 qualified_names);}
10888
10889/// Get the flat representation of an instance of @ref enum_type_decl
10890/// type.
10891///
10892/// The flat representation of a given @ref enum_type_decl type is the
10893/// actual definition of the type, for instance:
10894///
10895/// enum {E_0 =0, E_1 = 1}
10896///
10897///@param enum_type the enum type to consider.
10898///
10899///@param indent the identation spaces to use in the representation.
10900///
10901///@param one_line if true, then the flat representation stands on one
10902///line. Otherwise, it stands on multiple lines.
10903///
10904///@param qualified_names use qualified names when applicable.
10905///Typically, if this is true, the name of the enum is going to be
10906///qualified.
10907///
10908///@return the resulting flat representation.
10909string
10911 const string& indent, bool one_line,
10912 bool qualified_names)
10913{
10914 string repr;
10915 std::ostringstream o;
10916 string local_indent = " ";
10917
10918 repr = indent + "enum ";
10919
10920 if (!enum_type.get_is_anonymous())
10921 o << (qualified_names
10922 ? enum_type.get_qualified_name()
10923 : enum_type.get_name()) + " ";
10924
10925 o << "{";
10926
10927 if (!one_line)
10928 o << "\n";
10929
10930 for (const auto &enumerator : enum_type.get_sorted_enumerators())
10931 {
10932 if (!one_line)
10933 o << "\n" + indent;
10934
10935 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
10936 }
10937
10938 if (!one_line)
10939 o << "\n" + indent << "}";
10940 else
10941 o << "}";
10942
10943 repr =o.str();
10944
10945 return repr;
10946}
10947
10948/// Get the flat representation of an instance of @ref enum_type_decl
10949/// type.
10950///
10951/// The flat representation of a given @ref enum_type_decl type is the
10952/// actual definition of the type, for instance:
10953///
10954/// enum {E_0 =0, E_1 = 1}
10955///
10956///@param enum_type the enum type to consider.
10957///
10958///@param indent the identation spaces to use in the representation.
10959///
10960///@param one_line if true, then the flat representation stands on one
10961///line. Otherwise, it stands on multiple lines.
10962///
10963///@param qualified_names use qualified names when applicable.
10964///Typically, if this is true, the name of the enum is going to be
10965///qualified.
10966///
10967///@return the resulting flat representation.
10968string
10970 const string& indent, bool one_line,
10971 bool qualified_names)
10972{
10973 if (!enum_type)
10974 return "";
10975
10976 return get_enum_flat_representation(*enum_type, indent,
10977 one_line, qualified_names);
10978}
10979
10980/// Get the flat representation of an instance of @ref enum_type_decl
10981/// type.
10982///
10983/// The flat representation of a given @ref enum_type_decl type is the
10984/// actual definition of the type, for instance:
10985///
10986/// enum {E_0 =0, E_1 = 1}
10987///
10988///@param enum_type the enum type to consider.
10989///
10990///@param indent the identation spaces to use in the representation.
10991///
10992///@param one_line if true, then the flat representation stands on one
10993///line. Otherwise, it stands on multiple lines.
10994///
10995///@param qualified_names use qualified names when applicable.
10996///Typically, if this is true, the name of the enum is going to be
10997///qualified.
10998///
10999///@return the resulting flat representation.
11000string
11002 const string& indent, bool one_line,
11003 bool qualified_names)
11004{
11005 return get_enum_flat_representation(enum_type.get(),
11006 indent, one_line,
11007 qualified_names);
11008}
11009
11010/// Get the flat representation of an instance of @ref enum_type_decl
11011/// type.
11012///
11013/// The flat representation of a given @ref enum_type_decl type is the
11014/// actual definition of the type, for instance:
11015///
11016/// enum {E_0 =0, E_1 = 1}
11017///
11018///@param enum_type the enum type to consider.
11019///
11020///@param indent the identation spaces to use in the representation.
11021///
11022///@param one_line if true, then the flat representation stands on one
11023///line. Otherwise, it stands on multiple lines.
11024///
11025///@param qualified_names use qualified names when applicable.
11026///Typically, if this is true, the name of the enum is going to be
11027///qualified.
11028///
11029///@return the resulting flat representation.
11030string
11032 const string& indent,
11033 bool one_line,
11034 bool internal,
11035 bool qualified_name)
11036
11037{
11038 string repr;
11039 if (const class_or_union* cou = is_class_or_union_type(&coe))
11040 repr = get_class_or_union_flat_representation(cou, indent, one_line,
11041 internal, qualified_name);
11042 else if (const enum_type_decl* enom = is_enum_type(&coe))
11043 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
11044
11045 return repr;
11046}
11047
11048/// Get the textual representation of a type for debugging purposes.
11049///
11050/// If the type is a class/union, this shows the data members, virtual
11051/// member functions, size, pointer value of its canonical type, etc.
11052/// Otherwise, this just shows the name of the artifact as returned by
11053/// type_or_decl_base:get_pretty_representation().
11054///
11055/// @param artifact the artifact to show a debugging representation of.
11056///
11057/// @return a debugging string representation of @p artifact.
11058string
11060{
11061 string nil_str;
11062 if (!artifact)
11063 return nil_str;
11064
11065 class_or_union * c = is_class_or_union_type(artifact);
11066 if (c)
11067 {
11068 class_decl *clazz = is_class_type(c);
11069 string name = c->get_qualified_name();
11070 std::ostringstream o;
11071 if (clazz)
11072 {
11073 if (clazz->is_struct())
11074 o << "struct ";
11075 else
11076 o << "class ";
11077 }
11078 else if (is_union_type(c))
11079 o << "union ";
11080 o << name;
11081
11082 if (clazz)
11083 {
11084 if (!clazz->get_base_specifiers().empty())
11085 o << " :" << std::endl;
11086 for (auto &b : clazz->get_base_specifiers())
11087 {
11088 o << " ";
11089 if (b->get_is_virtual())
11090 o << "virtual ";
11091 o << b->get_base_class()->get_qualified_name()
11092 << " // hash: ";
11093 hash_t h = peek_hash_value(*b->get_base_class());
11094 if (h)
11095 o << std::hex << *h << std::dec;
11096 else
11097 o << "none";
11098 o << std::endl;
11099 }
11100 }
11101 o << std::endl
11102 << "{"
11103 << " // size in bits: " << c->get_size_in_bits() << "\n"
11104 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
11105 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
11106 << " // translation unit: "
11107 << (c->get_translation_unit()
11109 : nil_str)
11110 << std::endl
11111 << " // @: " << std::hex << is_type(c)
11112 << ", @canonical: " << c->get_canonical_type().get() << std::dec << "\n"
11113 << " // hash: " ;
11114
11115 hash_t h = peek_hash_value(*c);
11116 if (h)
11117 o << std::hex << *h << std::dec;
11118 else
11119 o << "none";
11120 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*c);
11121 o << "\n\n";
11122
11123
11124 for (auto member_type : c->get_sorted_member_types())
11125 {
11126 o << " "
11127 << member_type->get_pretty_representation(/*internal=*/false,
11128 /*qualified=*/false)
11129 << ";";
11130 if (member_type->get_canonical_type())
11131 {
11132 o << " // uses canonical type: '@"
11133 << std::hex << member_type->get_canonical_type().get() << "'";
11134 o << " / h:";
11135 hash_t h = peek_hash_value(*member_type);
11136 o << std::hex << *h << std::dec;
11137 if (get_canonical_type_index(*member_type))
11138 o << "#" << get_canonical_type_index(*member_type);
11139 }
11140 o << "\n";
11141 }
11142
11143 if (!c->get_sorted_member_types().empty())
11144 o << std::endl;
11145
11146 for (auto m : c->get_data_members())
11147 {
11148 type_base_sptr t = m->get_type();
11150
11151 o << " "
11152 << m->get_pretty_representation(/*internal=*/false,
11153 /*qualified=*/false)
11154 << ";";
11155
11156 if (t && t->get_canonical_type())
11157 o << " // uses canonical type '@"
11158 << std::hex << t->get_canonical_type().get() << "'";
11159
11160 o << "/ h:";
11161 hash_t h = peek_hash_value(*m->get_type());
11162 if (h)
11163 o << std::hex << *h << std::dec;
11164 else
11165 o << "none";
11166 o << std::endl;
11167 }
11168
11169 if (!c->get_data_members().empty())
11170 o << std::endl;
11171
11172 if (clazz && clazz->has_vtable())
11173 {
11174 o << " // virtual member functions\n\n";
11175 for (auto f : clazz->get_virtual_mem_fns())
11176 {
11177 o << std::hex << "(" << is_method_decl(f).get() << ") "
11178 << " " << f->get_pretty_representation(/*internal=*/false,
11179 /*qualified=*/false)
11180 << " // voffset: " << get_member_function_vtable_offset(f)
11181 << ", h: ";
11182 hash_t h = peek_hash_value(*f->get_type());
11183 if (h)
11184 o << std::hex << *h << std::dec;
11185 else
11186 o << "none";
11187 if (!f->get_linkage_name().empty())
11188 o << ", {"
11189 << f->get_linkage_name()
11190 << "} ";
11191 o << ";" << std::endl;
11192 }
11193 }
11194
11195 o << "};" << std::endl;
11196
11197 return o.str();
11198 }
11199 else if (const enum_type_decl* e = is_enum_type(artifact))
11200 {
11201 string name = e->get_qualified_name();
11202 std::ostringstream o;
11203 o << "enum " << name
11204 << " : "
11205 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
11206 true)
11207 << "\n"
11208 << "{\n"
11209 << " // size in bits: " << e->get_size_in_bits() << "\n"
11210 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
11211 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
11212 << " // translation unit: "
11213 << e->get_translation_unit()->get_absolute_path() << "\n"
11214 << " // @: " << std::hex << is_type(e)
11215 << ", @canonical: " << e->get_canonical_type().get() << std::dec << "\n"
11216 << " // hash: ";
11217
11218 hash_t h = peek_hash_value(*e);
11219 if (h)
11220 o << std::hex << *h << std::dec;
11221 else
11222 o << "none";
11223 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*e);
11224 o << "\n\n";
11225
11226 for (const auto &enom : e->get_enumerators())
11227 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
11228
11229 o << "};\n";
11230
11231 return o.str();
11232 }
11233 else if (type_base *t = is_type(artifact))
11234 {
11235 std::ostringstream o;
11236 o << t->get_pretty_representation(/*internal=*/true,
11237 /*qualified=*/true)
11238 << " // cti: " << get_canonical_type_index(*t)
11239 << "\n";
11240 return o.str();
11241 }
11242
11243 return artifact->get_pretty_representation(/*internal=*/true,
11244 /*qualified=*/true);
11245}
11246
11247/// Get a given data member, referred to by its name, of a class type.
11248///
11249/// @param clazz the class to consider.
11250///
11251/// @param member_name name of the data member to get.
11252///
11253/// @return the resulting data member or nullptr if none was found.
11255get_data_member(class_or_union *clazz, const char* member_name)
11256{
11257 if (!clazz)
11258 return var_decl_sptr();
11259 return clazz->find_data_member(member_name);
11260}
11261
11262/// Get a given data member, referred to by its name, of a class type.
11263///
11264/// @param clazz the class to consider.
11265///
11266/// @param member_name name of the data member to get.
11267///
11268/// @return the resulting data member or nullptr if none was found.
11270get_data_member(type_base *clazz, const char* member_name)
11271{return get_data_member(is_class_or_union_type(clazz), member_name);}
11272
11273/// Get the non-artificial (natural) location of a decl.
11274///
11275/// If the decl doesn't have a natural location then return its
11276/// artificial one.
11277///
11278/// @param decl the decl to consider.
11279///
11280/// @return the natural location @p decl if it has one; otherwise,
11281/// return its artificial one.
11282const location&
11284{
11285 ABG_ASSERT(decl);
11286
11287 if (decl->get_location())
11288 return decl->get_location();
11289 return decl->get_artificial_location();
11290}
11291
11292/// Get the artificial location of a decl.
11293///
11294/// If the decl doesn't have an artificial location then return its
11295/// natural one.
11296///
11297/// @param decl the decl to consider.
11298///
11299/// @return the artificial location @p decl if it has one; otherwise,
11300/// return its natural one.
11301const location&
11303{
11304 ABG_ASSERT(decl);
11305
11306 if (decl->has_artificial_location())
11307 return decl->get_artificial_location();
11308 return decl->get_location();
11309}
11310
11311/// Emit a textual representation of an artifact to std error stream
11312/// for debugging purposes.
11313///
11314/// This is useful to invoke from within a command line debugger like
11315/// GDB to help make sense of a given ABI artifact.
11316///
11317/// @param artifact the ABI artifact to emit the debugging
11318/// representation for.
11319///
11320/// @return the artifact @p artifact.
11322debug(const type_or_decl_base* artifact)
11323{
11324 std::cerr << get_debug_representation(artifact) << std::endl;
11325 return const_cast<type_or_decl_base*>(artifact);
11326}
11327
11328/// Emit a textual representation of an artifact to std error stream
11329/// for debugging purposes.
11330///
11331/// This is useful to invoke from within a command line debugger like
11332/// GDB to help make sense of a given ABI artifact.
11333///
11334/// @param artifact the ABI artifact to emit the debugging
11335/// representation for.
11336///
11337/// @return the artifact @p artifact.
11338type_base*
11339debug(const type_base* artifact)
11340{
11341 debug(static_cast<const type_or_decl_base*>(artifact));
11342 return const_cast<type_base*>(artifact);
11343}
11344
11345/// Emit a textual representation of an artifact to std error stream
11346/// for debugging purposes.
11347///
11348/// This is useful to invoke from within a command line debugger like
11349/// GDB to help make sense of a given ABI artifact.
11350///
11351/// @param artifact the ABI artifact to emit the debugging
11352/// representation for.
11353///
11354/// @return the artifact @p artifact.
11355decl_base*
11356debug(const decl_base* artifact)
11357{
11358 debug(static_cast<const type_or_decl_base*>(artifact));
11359 return const_cast<decl_base*>(artifact);
11360}
11361
11362/// Test if two ABI artifacts are equal.
11363///
11364/// This can be useful when used from the command line of a debugger
11365/// like GDB.
11366///
11367/// @param l the first ABI artifact to consider in the comparison.
11368///
11369/// @param r the second ABI artifact to consider in the comparison.
11370///
11371/// @return true iff @p l equals @p r.
11372bool
11374{
11375 if (!!l != !!r)
11376 return false;
11377 if (!l && !r)
11378 return true;
11379
11380 return (*l == *r);
11381}
11382
11383/// By looking at the language of the TU a given ABI artifact belongs
11384/// to, test if the ONE Definition Rule should apply.
11385///
11386/// To date, it applies to c++, java and ada.
11387///
11388/// @param artifact the ABI artifact to consider.
11389///
11390/// @return true iff the One Definition Rule should apply.
11391bool
11393{
11394 if (!artifact.get_translation_unit())
11395 return false;
11396
11398 artifact.get_translation_unit()->get_language();
11399
11401 || is_java_language(l)
11402 || is_ada_language(l))
11403 return true;
11404
11405 return false;
11406}
11407
11408/// Get the declaration for a given type.
11409///
11410/// @param t the type to consider.
11411///
11412/// @return the declaration for the type to return.
11413const decl_base*
11415{return dynamic_cast<const decl_base*>(t);}
11416
11417/// Get the declaration for a given type.
11418///
11419/// @param t the type to consider.
11420///
11421/// @return the declaration for the type to return.
11422decl_base*
11424{return dynamic_cast<decl_base*>(t);}
11425
11426/// Get the declaration for a given type.
11427///
11428/// @param t the type to consider.
11429///
11430/// @return the declaration for the type to return.
11431decl_base_sptr
11432get_type_declaration(const type_base_sptr t)
11433{return dynamic_pointer_cast<decl_base>(t);}
11434
11435/// Test if two classes have the same layout.
11436///
11437/// Test if all the types and offsets of the members are equal,
11438/// regardless of their access modifiers.
11439///
11440/// @param f the first class to take into account.
11441///
11442/// @param s the second class to take into account.
11443///
11444/// @return true iff @p s and @p f are class types with the same
11445/// layout.
11446bool
11447classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
11448{
11449#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
11450#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
11451#endif
11452
11453#ifdef ENSURE_NO_ENDLESS_LOOP
11454#undef ENSURE_NO_ENDLESS_LOOP
11455#endif
11456
11457#define RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(VALUE) \
11458 do \
11459 { \
11460 auto t1 = is_class_or_union_type(f); \
11461 auto t2 = is_class_or_union_type(s); \
11462 t1->priv_->comparing_class_layouts_.erase(t2.get()); \
11463 t2->priv_->comparing_class_layouts_.erase(t1.get()); \
11464 return VALUE; \
11465 } while (false)
11466
11467#define ENSURE_NO_ENDLESS_LOOP \
11468 do \
11469 { \
11470 auto t1 = is_class_or_union_type(f); \
11471 auto t2 = is_class_or_union_type(s); \
11472 const auto& END = t1->priv_->comparing_class_layouts_.end(); \
11473 if (t1->priv_->comparing_class_layouts_.find(t2.get()) != END \
11474 || t2->priv_->comparing_class_layouts_.find(t1.get()) != END) \
11475 return true; \
11476 t1->priv_->comparing_class_layouts_.insert(t2.get()); \
11477 t2->priv_->comparing_class_layouts_.insert(t1.get()); \
11478 } while (false)
11479
11482
11483 if (!fc
11484 || !sc
11485 || (fc->get_qualified_name() != sc->get_qualified_name())
11486 || (fc->get_size_in_bits() != sc->get_size_in_bits())
11487 || (fc->get_data_members().size() != sc->get_data_members().size()))
11488 return false;
11489
11490 if (*fc == *sc)
11491 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
11492
11493 // Compare the types and offsets of data members one by one.
11494 for (auto f_decl_it = fc->get_data_members().begin(),
11495 s_decl_it = sc->get_data_members().begin();
11496 (f_decl_it != fc->get_data_members().end()
11497 && s_decl_it != sc->get_data_members().end());
11498 ++f_decl_it, ++s_decl_it)
11499 {
11500 var_decl_sptr dm1 = *f_decl_it, dm2 = *s_decl_it;
11501 type_base_sptr dm1_type = dm1->get_type(), dm2_type = dm2->get_type();
11502
11503 if (*dm1_type != *dm2_type
11505 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
11506 }
11507
11508 // Compare the layout of base types
11509 for (auto f_bs_it = fc->get_base_specifiers().begin(),
11510 s_bs_it = sc->get_base_specifiers().end();
11511 (f_bs_it != fc->get_base_specifiers().end()
11512 && s_bs_it != sc->get_base_specifiers().end());
11513 ++f_bs_it, ++s_bs_it)
11514 {
11515 class_decl::base_spec_sptr f_bs = *f_bs_it, s_bs = *s_bs_it;
11516 if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
11517 || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
11518 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
11519
11520 class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
11521 if (!classes_have_same_layout(fb, sb))
11522 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
11523 }
11524
11525 if (fc->has_vtable() != sc->has_vtable())
11526 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
11527
11528 // Compare virtual function types
11529 ENSURE_NO_ENDLESS_LOOP;
11530 if (fc->has_vtable())
11531 {
11532 if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
11533 // Some virtual member function got removed. Bad.
11534 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
11535
11536 for (auto it1 = fc->get_virtual_mem_fns().begin(),
11537 it2 = sc->get_virtual_mem_fns().begin();
11538 (it1 != fc->get_virtual_mem_fns().end()
11539 && it2 != sc->get_virtual_mem_fns().end());
11540 ++it1, ++it2)
11541 {
11542 method_decl_sptr method1 = *it1;
11543 method_decl_sptr method2 = *it2;
11544
11547 || !types_are_compatible(method1->get_type(),
11548 method2->get_type()))
11549 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
11550 }
11551 }
11552
11553 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
11554
11555#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
11556#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
11557#endif
11558
11559#ifdef ENSURE_NO_ENDLESS_LOOP
11560#undef ENSURE_NO_ENDLESS_LOOP
11561#endif
11562}
11563
11564/// Test if two types are equal modulo a typedef or CV qualifiers.
11565///
11566/// Type A and B are compatible if
11567///
11568/// - A and B are equal
11569/// - or A and B are integral types with harmless name change
11570/// - or if one type is a typedef of the other one.
11571/// - or if one type is the CV qualified version of the other
11572/// - or if A and B are classes with the same layout.
11573/// - or if A and B are pointers, references or arrays of
11574/// compatible types
11575///
11576/// @param type1 the first type to consider.
11577///
11578/// @param type2 the second type to consider.
11579///
11580/// @return true iff @p type1 and @p type2 are compatible.
11581bool
11582types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
11583{
11584 if (!type1 || !type2)
11585 return false;
11586
11587 if (type1 == type2 || *type1 == *type2)
11588 return true;
11589
11590 type_base_sptr t1 = peel_qualified_or_typedef_type(type1);
11591 type_base_sptr t2 = peel_qualified_or_typedef_type(type2);
11592
11593 if (t1 && t2 && *t1 == *t2)
11594 return true;
11595
11597 return true;
11598
11599 if (is_pointer_type(t1) && is_pointer_type(t2))
11600 {
11603 return types_are_compatible(t1, t2);
11604 }
11605
11606 if (is_reference_type(t1) && is_reference_type(t2))
11607 {
11608 t1 = is_reference_type(t1)->get_pointed_to_type();
11609 t2 = is_reference_type(t2)->get_pointed_to_type();
11610 return types_are_compatible(t1, t2);
11611 }
11612
11613 if (is_array_type(t1) && is_array_type(t2))
11614 {
11617 type_base_sptr e1 = a1->get_element_type();
11618 type_base_sptr e2 = a2->get_element_type();
11621
11622 if ((a1->get_size_in_bits() != a2->get_size_in_bits())
11623 || (a1->get_dimension_count() != a2->get_dimension_count())
11624 || !types_are_compatible(e1, e2))
11625 return false;
11626
11627 return true;
11628 }
11629
11630 if (function_type_sptr fn_type1 = is_function_type(t1))
11631 if (function_type_sptr fn_type2 = is_function_type(t2))
11632 {
11633 // Compare return types
11634 if (!types_are_compatible(fn_type1->get_return_type(),
11635 fn_type2->get_return_type()))
11636 return false;
11637
11638 // Compare parameter types, omitting the implicit parameter to
11639 // avoid infinite recursion when we are being called from
11640 // classes_have_same_layout on classes with virtual member
11641 // functions.
11642 if (fn_type1->get_parameters().size()
11643 != fn_type2->get_parameters().size())
11644 return false;
11645
11646 for (auto p1 = fn_type1->get_first_non_implicit_parm(),
11647 p2 = fn_type2->get_first_non_implicit_parm();
11648 (p1 != fn_type1->get_parameters().end()
11649 && p2 != fn_type2->get_parameters().end());
11650 ++p1, ++p2)
11651 if (!types_are_compatible((*p1)->get_type(),
11652 (*p2)->get_type()))
11653 return false;
11654
11655 return true;
11656 }
11657
11658 if (classes_have_same_layout(t1, t2))
11659 return true;
11660
11661 return false;
11662}
11663
11664/// Test if two types are equal modulo a typedef.
11665///
11666/// Type A and B are compatible if
11667///
11668/// - A and B are equal
11669/// - or if one type is a typedef of the other one.
11670///
11671/// @param type1 the declaration of the first type to consider.
11672///
11673/// @param type2 the declaration of the second type to consider.
11674///
11675/// @return true iff @p type1 and @p type2 are compatible.
11676bool
11677types_are_compatible(const decl_base_sptr d1,
11678 const decl_base_sptr d2)
11679{return types_are_compatible(is_type(d1), is_type(d2));}
11680
11681/// Return the translation unit a declaration belongs to.
11682///
11683/// @param decl the declaration to consider.
11684///
11685/// @return the resulting translation unit, or null if the decl is not
11686/// yet added to a translation unit.
11689{
11690 translation_unit* result =
11691 const_cast<translation_unit*>(t.get_translation_unit());
11692
11693 if (result)
11694 return result;
11695
11696 if (decl_base* decl = is_decl(&t))
11697 {
11698 auto scope = decl->get_scope();
11699 while (scope)
11700 {
11701 result = scope->get_translation_unit();
11702 if (result)
11703 break;
11704 scope = scope->get_scope();
11705 }
11706 }
11707
11708 return result;
11709}
11710
11711/// Return the translation unit a declaration belongs to.
11712///
11713/// @param decl the declaration to consider.
11714///
11715/// @return the resulting translation unit, or null if the decl is not
11716/// yet added to a translation unit.
11719{return decl ? get_translation_unit(*decl) : nullptr;}
11720
11721/// Return the translation unit a declaration belongs to.
11722///
11723/// @param decl the declaration to consider.
11724///
11725/// @return the resulting translation unit, or null if the decl is not
11726/// yet added to a translation unit.
11730
11731/// Tests whether if a given scope is the global scope.
11732///
11733/// @param scope the scope to consider.
11734///
11735/// @return true iff the current scope is the global one.
11736bool
11738{return !!dynamic_cast<const global_scope*>(&scope);}
11739
11740/// Tests whether if a given scope is the global scope.
11741///
11742/// @param scope the scope to consider.
11743///
11744/// @return the @ref global_scope* representing the scope @p scope or
11745/// 0 if @p scope is not a global scope.
11746const global_scope*
11748{return dynamic_cast<const global_scope*>(scope);}
11749
11750/// Tests whether if a given scope is the global scope.
11751///
11752/// @param scope the scope to consider.
11753///
11754/// @return true iff the current scope is the global one.
11755bool
11756is_global_scope(const shared_ptr<scope_decl>scope)
11757{return is_global_scope(scope.get());}
11758
11759/// Tests whether a given declaration is at global scope.
11760///
11761/// @param decl the decl to consider.
11762///
11763/// @return true iff decl is at global scope.
11764bool
11766{return (is_global_scope(decl.get_scope()));}
11767
11768/// Tests whether a given declaration is at global scope.
11769///
11770/// @param decl the decl to consider.
11771///
11772/// @return true iff decl is at global scope.
11773bool
11774is_at_global_scope(const decl_base_sptr decl)
11775{return (decl && is_global_scope(decl->get_scope()));}
11776
11777/// Tests whether a given declaration is at global scope.
11778///
11779/// @param decl the decl to consider.
11780///
11781/// @return true iff decl is at global scope.
11782bool
11784{return decl && is_at_global_scope(*decl);}
11785
11786/// Tests whether a given decl is at class scope.
11787///
11788/// @param decl the decl to consider.
11789///
11790/// @return true iff decl is at class scope.
11791class_or_union_sptr
11792is_at_class_scope(const decl_base_sptr decl)
11793{return is_at_class_scope(decl.get());}
11794
11795/// Tests whether a given decl is at class scope.
11796///
11797/// @param decl the decl to consider.
11798///
11799/// @return true iff decl is at class scope.
11800class_or_union_sptr
11802{
11803 if (!decl)
11804 return nullptr;
11805
11806 return is_at_class_scope(*decl);
11807}
11808
11809/// Tests whether a given decl is at class scope.
11810///
11811/// @param decl the decl to consider.
11812///
11813/// @return true iff decl is at class scope.
11814class_or_union_sptr
11816{
11817 scope_decl_sptr scope = decl.get_scope();
11818 if (!scope)
11819 return nullptr;
11820
11821 if (class_or_union_sptr cl = is_class_type(scope))
11822 return cl;
11823 if (class_or_union_sptr cl = is_union_type(scope))
11824 return cl;
11825 return 0;
11826}
11827
11828/// Tests whether a given decl is at function scope.
11829///
11830/// @param decl the decl to consider.
11831///
11832/// @return true iff decl is at function scope.
11835{
11836 auto scope = decl.get_scope();
11837 if (auto fn = is_function_decl(scope))
11838 return fn;
11839 return nullptr;
11840}
11841
11842/// Tests whether a given decl is at function scope.
11843///
11844/// @param decl the decl to consider.
11845///
11846/// @return true iff decl is at function scope.
11849{
11850 if (decl)
11851 return is_at_function_scope(*decl);
11852 return nullptr;
11853}
11854
11855/// Tests whether a given decl is at function scope.
11856///
11857/// @param decl the decl to consider.
11858///
11859/// @return true iff decl is at function scope.
11861is_at_function_scope(const decl_base_sptr& decl)
11862{return is_at_function_scope(decl.get());}
11863
11864/// Find a data member inside an anonymous data member.
11865///
11866/// An anonymous data member has a type which is a class or union.
11867/// This function looks for a data member inside the type of that
11868/// anonymous data member.
11869///
11870/// @param anon_dm the anonymous data member to consider.
11871///
11872/// @param name the name of the data member to look for.
11875 const string& name)
11876{
11877 const class_or_union* containing_class_or_union =
11879
11880 if (!containing_class_or_union)
11881 return var_decl_sptr();
11882
11883 var_decl_sptr result = containing_class_or_union->find_data_member(name);
11884 return result;
11885}
11886
11887/// Tests whether a given decl is at template scope.
11888///
11889/// Note that only template parameters , types that are compositions,
11890/// and template patterns (function or class) can be at template scope.
11891///
11892/// @param decl the decl to consider.
11893///
11894/// @return true iff the decl is at template scope.
11895bool
11896is_at_template_scope(decl_base_sptr decl)
11897{return (decl && dynamic_pointer_cast<template_decl>(decl->get_scope()));}
11898
11899/// Tests whether a decl is a template parameter.
11900///
11901/// @param decl the decl to consider.
11902///
11903/// @return true iff decl is a template parameter.
11904bool
11905is_template_parameter(decl_base_sptr decl)
11906{
11907 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
11908 || dynamic_pointer_cast<non_type_tparameter>(decl)
11909 || dynamic_pointer_cast<template_tparameter>(decl)));
11910}
11911
11912/// Test whether a declaration is a @ref function_decl.
11913///
11914/// @param d the declaration to test for.
11915///
11916/// @return a shared pointer to @ref function_decl if @p d is a @ref
11917/// function_decl. Otherwise, a nil shared pointer.
11920{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
11921
11922/// Test whether a declaration is a @ref function_decl.
11923///
11924/// @param d the declaration to test for.
11925///
11926/// @return true if @p d is a function_decl.
11927bool
11930
11931/// Test whether a declaration is a @ref function_decl.
11932///
11933/// @param d the declaration to test for.
11934///
11935/// @return a shared pointer to @ref function_decl if @p d is a @ref
11936/// function_decl. Otherwise, a nil shared pointer.
11939{return dynamic_pointer_cast<function_decl>(d);}
11940
11941/// Test whether a declaration is a @ref function_decl.
11942///
11943/// @param d the declaration to test for.
11944///
11945/// @return a pointer to @ref function_decl if @p d is a @ref
11946/// function_decl. Otherwise, a nil shared pointer.
11949{
11950 return dynamic_cast<function_decl::parameter*>
11951 (const_cast<type_or_decl_base*>(tod));
11952}
11953
11954/// Test whether an ABI artifact is a @ref function_decl.
11955///
11956/// @param tod the declaration to test for.
11957///
11958/// @return a pointer to @ref function_decl if @p d is a @ref
11959/// function_decl. Otherwise, a nil shared pointer.
11962{return dynamic_pointer_cast<function_decl::parameter>(tod);}
11963
11964/// Test if an ABI artifact is a declaration.
11965///
11966/// @param d the artifact to consider.
11967///
11968/// @param return the declaration sub-object of @p d if it's a
11969/// declaration, or NULL if it is not.
11970decl_base*
11972{
11973 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
11974 {
11975 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
11976 // The artifact is a decl-only (like a function or a
11977 // variable). That is, it's not a type that also has a
11978 // declaration. In this case, we are in the fast path and we
11979 // have a pointer to the decl sub-object handy. Just return
11980 // it ...
11981 return reinterpret_cast<decl_base*>
11982 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
11983
11984 // ... Otherwise, we are in the slow path, which is that the
11985 // artifact is a type which has a declaration. In that case,
11986 // let's use the slow dynamic_cast because we don't have the
11987 // pointer to the decl sub-object handily present.
11988 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
11989 }
11990 return 0;
11991}
11992
11993/// Test if an ABI artifact is a declaration.
11994///
11995/// @param d the artifact to consider.
11996///
11997/// @param return the declaration sub-object of @p d if it's a
11998/// declaration, or NULL if it is not.
11999decl_base_sptr
12001{return dynamic_pointer_cast<decl_base>(d);}
12002
12003/// Test if an ABI artifact is a declaration.
12004///
12005/// This is done using a slow path that uses dynamic_cast.
12006///
12007/// @param d the artifact to consider.
12008///
12009/// @param return the declaration sub-object of @p d if it's a
12010decl_base*
12012{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
12013
12014/// Test if an ABI artifact is a declaration.
12015///
12016/// This is done using a slow path that uses dynamic_cast.
12017///
12018/// @param d the artifact to consider.
12019///
12020/// @param return the declaration sub-object of @p d if it's a
12021decl_base_sptr
12023{return dynamic_pointer_cast<decl_base>(t);}
12024
12025/// Test whether a declaration is a type.
12026///
12027/// @param d the IR artefact to test for.
12028///
12029/// @return true if the artifact is a type, false otherwise.
12030bool
12032{
12033 if (dynamic_cast<const type_base*>(&tod))
12034 return true;
12035 return false;
12036}
12037
12038/// Test whether a declaration is a type.
12039///
12040/// @param d the IR artefact to test for.
12041///
12042/// @return true if the artifact is a type, false otherwise.
12043type_base*
12045{
12046 if (!t)
12047 return nullptr;
12048 return const_cast<type_base*>(dynamic_cast<const type_base*>(t));
12049}
12050
12051/// Test whether a declaration is a type.
12052///
12053/// @param d the IR artefact to test for.
12054///
12055/// @return true if the artifact is a type, false otherwise.
12056type_base_sptr
12058{return dynamic_pointer_cast<type_base>(tod);}
12059
12060/// Test whether a declaration is a type.
12061///
12062/// @param d the declaration to test for.
12063///
12064/// @return true if the declaration is a type, false otherwise.
12065
12066/// Test if a given type is anonymous.
12067///
12068/// Note that this function considers that an anonymous class that is
12069/// named by a typedef is not anonymous anymore. This is the C idiom:
12070///
12071/// typedef struct {int member;} s_type;
12072///
12073/// The typedef s_type becomes the name of the originally anonymous
12074/// struct.
12075///
12076/// @param t the type to consider.
12077///
12078/// @return true iff @p t is anonymous.
12079bool
12081{
12082 const decl_base* d = get_type_declaration(t);
12083 if (d)
12084 if (d->get_is_anonymous())
12085 return true;
12086
12087 return false;
12088}
12089
12090/// Test if a given type is anonymous.
12091///
12092/// @param t the type to consider.
12093///
12094/// @return true iff @p t is anonymous.
12095bool
12096is_anonymous_type(const type_base_sptr& t)
12097{return is_anonymous_type(t.get());}
12098
12099bool
12100is_naming_typedef(const typedef_decl_sptr typedf)
12101{
12102 if (!typedf)
12103 return false;
12104
12105 type_base_sptr utype = typedf->get_underlying_type();
12106 ABG_ASSERT(utype);
12107
12108 if (decl_base_sptr d = is_decl(utype))
12109 for (auto naming_typedef : d->get_naming_typedefs())
12110 if (naming_typedef.get() == typedf.get())
12111 return true;
12112
12113 return false;
12114}
12115
12116/// Test if a type is a neither a pointer, an array nor a function
12117/// type.
12118///
12119/// @param t the type to consider.
12120///
12121/// @return true if the @p t is NOT a pointer, an array nor a
12122/// function.
12123bool
12124is_npaf_type(const type_base_sptr& t)
12125{
12126 if (!(is_pointer_type(t)
12127 || is_array_type(t)
12128 || is_function_type(t)
12129 || is_ptr_to_mbr_type(t)))
12130 return true;
12131 return false;
12132}
12133
12134/// Test whether a type is a type_decl (a builtin type).
12135///
12136/// @return the type_decl* for @t if it's type_decl, otherwise, return
12137/// nil.
12138const type_decl*
12140{return dynamic_cast<const type_decl*>(t);}
12141
12142/// Test whether a type is a type_decl (a builtin type).
12143///
12144/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
12145/// return nil.
12148{return dynamic_pointer_cast<type_decl>(t);}
12149
12150/// Test if a type is a real type.
12151///
12152/// @param t the type to test.
12153///
12154/// @return the real type @p t can be converted to, or nil if @p
12155/// is not a real type.
12156type_decl*
12158{
12159 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
12160 if (!type)
12161 return nullptr;
12162
12163 real_type int_type;
12164 if (!parse_real_type(type->get_name(), int_type))
12165 return nullptr;
12166
12167 return type;
12168}
12169
12170/// Test if a type is a real type.
12171///
12172/// @param t the type to test.
12173///
12174/// @return the real type @p t can be converted to, or nil if @p is
12175/// not a real type.
12178{
12179 const type_decl_sptr type = is_type_decl(t);
12180 if (!type)
12181 return type_decl_sptr();
12182
12183 real_type int_type;
12184 if (!parse_real_type(type->get_name(), int_type))
12185 return type_decl_sptr();
12186
12187 return type;
12188}
12189
12190/// Test if a type is an integral type.
12191///
12192/// @param t the type to test.
12193///
12194/// @return the integral type @p t can be converted to, or nil if @p
12195/// is not an integral type.
12196type_decl*
12198{
12199 type_decl* type = is_real_type(t);
12200 if (!type)
12201 return nullptr;
12202
12203 real_type rt;
12204 ABG_ASSERT(parse_real_type(type->get_name(), rt));
12207 return nullptr;
12208
12209 return type;
12210}
12211
12212/// Test if a type is an integral type.
12213///
12214/// @param t the type to test.
12215///
12216/// @return the integral type @p t can be converted to, or nil if @p
12217/// is not an integral type.
12220{
12221 type_decl_sptr type = is_real_type(t);
12222 if (!type)
12223 return type;
12224
12225 real_type rt;
12226 ABG_ASSERT(parse_real_type(type->get_name(), rt));
12229 return type_decl_sptr();
12230
12231 return type;
12232}
12233
12234/// Test whether a type is a typedef.
12235///
12236/// @param t the type to test for.
12237///
12238/// @return the typedef declaration of the @p t, or NULL if it's not a
12239/// typedef.
12242{return dynamic_pointer_cast<typedef_decl>(t);}
12243
12244/// Test whether a type is a typedef.
12245///
12246/// @param t the declaration of the type to test for.
12247///
12248/// @return the typedef declaration of the @p t, or NULL if it's not a
12249/// typedef.
12250const typedef_decl*
12252{return dynamic_cast<const typedef_decl*>(t);}
12253
12254/// Test whether a type is a typedef.
12255///
12256/// @param t the declaration of the type to test for.
12257///
12258/// @return the typedef declaration of the @p t, or NULL if it's not a
12259/// typedef.
12262{return dynamic_cast<typedef_decl*>(t);}
12263
12264/// Test whether a type is a typedef.
12265///
12266/// @param t the declaration of the type to test for.
12267///
12268/// @return the typedef declaration of the @p t, or NULL if it's not a
12269/// typedef.
12270const typedef_decl*
12272{return dynamic_cast<const typedef_decl*>(t);}
12273
12274/// Test if a type is an enum. This function looks through typedefs.
12275///
12276/// @parm t the type to consider.
12277///
12278/// @return the enum_decl if @p t is an @ref enum_decl or null
12279/// otherwise.
12280const enum_type_decl*
12282{
12283 if (!t)
12284 return nullptr;
12285
12286 type_base* ty = const_cast<type_base*>(peel_typedef_type(t));
12287 return is_enum_type(ty);
12288}
12289
12290/// Test if a type is an enum. This function looks through typedefs.
12291///
12292/// @parm t the type to consider.
12293///
12294/// @return the enum_decl if @p t is an @ref enum_decl or null
12295/// otherwise.
12297is_compatible_with_enum_type(const type_base_sptr& t)
12298{
12299 if (!t)
12300 return enum_type_decl_sptr();
12301
12302 // Normally we should strip typedefs entirely, but this is
12303 // potentially costly, especially on binaries with huge changesets
12304 // like the Linux Kernel. So we just get the leaf types for now.
12305 //
12306 // Maybe there should be an option by which users accepts to pay the
12307 // CPU usage toll in exchange for finer filtering?
12308
12309 // type_base_sptr ty = strip_typedef(t);
12310 type_base_sptr ty = peel_typedef_type(t);;
12311 return is_enum_type(ty);
12312}
12313
12314/// Test if a type is an enum. This function looks through typedefs.
12315///
12316/// @parm t the type to consider.
12317///
12318/// @return the enum_decl if @p t is an @ref enum_decl or null
12319/// otherwise.
12321is_compatible_with_enum_type(const decl_base_sptr& t)
12323
12324/// Test if a decl is an enum_type_decl
12325///
12326/// @param d the decl to test for.
12327///
12328/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
12329const enum_type_decl*
12331{return dynamic_cast<const enum_type_decl*>(d);}
12332
12333/// Test if a decl is an enum_type_decl
12334///
12335/// @param d the decl to test for.
12336///
12337/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
12340{return dynamic_pointer_cast<enum_type_decl>(d);}
12341
12342/// Test if a type is a class. This function looks through typedefs.
12343///
12344/// @parm t the type to consider.
12345///
12346/// @return the class_decl if @p t is a class_decl or null otherwise.
12347const class_decl*
12349{
12350 if(!t)
12351 return nullptr;
12352
12353 const type_base* ty = peel_typedef_type(t);
12354 return is_class_type(ty);
12355}
12356
12357/// Test if a type is a class. This function looks through typedefs.
12358///
12359/// @parm t the type to consider.
12360///
12361/// @return the class_decl if @p t is a class_decl or null otherwise.
12363is_compatible_with_class_type(const type_base_sptr& t)
12364{
12365 if (!t)
12366 return class_decl_sptr();
12367
12368 // Normally we should strip typedefs entirely, but this is
12369 // potentially costly, especially on binaries with huge changesets
12370 // like the Linux Kernel. So we just get the leaf types for now.
12371 //
12372 // Maybe there should be an option by which users accepts to pay the
12373 // CPU usage toll in exchange for finer filtering?
12374
12375 // type_base_sptr ty = strip_typedef(t);
12376 type_base_sptr ty = peel_typedef_type(t);
12377 return is_class_type(ty);
12378}
12379
12380/// Test if a type is a class. This function looks through typedefs.
12381///
12382/// @parm t the type to consider.
12383///
12384/// @return the class_decl if @p t is a class_decl or null otherwise.
12386is_compatible_with_class_type(const decl_base_sptr& t)
12388
12389/// Test whether a type is a class.
12390///
12391/// @parm t the type to consider.
12392///
12393/// @return true iff @p t is a class_decl.
12394bool
12396{return is_class_type(&t);}
12397
12398/// Test whether a type is a class.
12399///
12400/// @parm t the type to consider.
12401///
12402/// @return the class_decl if @p t is a class_decl or null otherwise.
12405{
12406 if (!t)
12407 return 0;
12408
12409 if (t->kind() & type_or_decl_base::CLASS_TYPE)
12410 return reinterpret_cast<class_decl*>
12411 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
12412
12413 return 0;
12414}
12415
12416/// Test whether a type is a class.
12417///
12418/// @parm t the type to consider.
12419///
12420/// @return the class_decl if @p t is a class_decl or null otherwise.
12423{return dynamic_pointer_cast<class_decl>(d);}
12424
12425/// Test if the last data member of a class is an array with
12426/// non-finite data member.
12427///
12428/// The flexible data member idiom is a well known C idiom:
12429/// https://en.wikipedia.org/wiki/Flexible_array_member.
12430///
12431/// @param klass the class to consider.
12432///
12433/// @return the data member which type is a flexible array, if any, or
12434/// nil.
12437{
12438 var_decl_sptr nil;
12440 if (dms.empty())
12441 return nil;
12442
12443 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
12444 {// The type of the last data member is an array.
12445 if (array->is_non_finite())
12446 // The array has a non-finite size. We are thus looking at a
12447 // flexible array data member. Let's return it.
12448 return dms.back();
12449 }
12450
12451 return nil;
12452}
12453
12454/// Test if the last data member of a class is an array with
12455/// non-finite data member.
12456///
12457/// The flexible data member idiom is a well known C idiom:
12458/// https://en.wikipedia.org/wiki/Flexible_array_member.
12459///
12460/// @param klass the class to consider.
12461///
12462/// @return the data member which type is a flexible array, if any, or
12463/// nil.
12466{
12467 if (!klass)
12468 return var_decl_sptr();
12469
12470 return has_flexible_array_data_member(*klass);
12471}
12472
12473/// Test if the last data member of a class is an array with
12474/// non-finite data member.
12475///
12476/// The flexible data member idiom is a well known C idiom:
12477/// https://en.wikipedia.org/wiki/Flexible_array_member.
12478///
12479/// @param klass the class to consider.
12480///
12481/// @return the data member which type is a flexible array, if any, or
12482/// nil.
12486
12487/// Test if the last data member of a class is an array with
12488/// one element.
12489///
12490/// An array with one element is a way to mimic the flexible data
12491/// member idiom that was later standardized in C99.
12492///
12493/// To learn more about the flexible data member idiom, please
12494/// consider reading :
12495/// https://en.wikipedia.org/wiki/Flexible_array_member.
12496///
12497/// The various ways of representing that idiom pre-standardization
12498/// are presented in this article:
12499/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
12500///
12501/// @param klass the class to consider.
12502///
12503/// @return the data member which type is a fake flexible array, if
12504/// any, or nil.
12507{
12508 var_decl_sptr nil;
12510 if (dms.empty())
12511 return nil;
12512
12513 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
12514 {// The type of the last data member is an array.
12515 if (array->get_subranges().size() == 1
12516 && array->get_subranges()[0]->get_length() == 1)
12517 // The array has a size of one. We are thus looking at a
12518 // "fake" flexible array data member. Let's return it.
12519 return dms.back();
12520 }
12521
12522 return nil;
12523}
12524
12525/// Test if the last data member of a class is an array with
12526/// one element.
12527///
12528/// An array with one element is a way to mimic the flexible data
12529/// member idiom that was later standardized in C99.
12530///
12531/// To learn more about the flexible data member idiom, please
12532/// consider reading :
12533/// https://en.wikipedia.org/wiki/Flexible_array_member.
12534///
12535/// The various ways of representing that idiom pre-standardization
12536/// are presented in this article:
12537/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
12538///
12539/// @param klass the class to consider.
12540///
12541/// @return the data member which type is a fake flexible array, if
12542/// any, or nil.
12546
12547/// Test if the last data member of a class is an array with
12548/// one element.
12549///
12550/// An array with one element is a way to mimic the flexible data
12551/// member idiom that was later standardized in C99.
12552///
12553/// To learn more about the flexible data member idiom, please
12554/// consider reading :
12555/// https://en.wikipedia.org/wiki/Flexible_array_member.
12556///
12557/// The various ways of representing that idiom pre-standardization
12558/// are presented in this article:
12559/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
12560///
12561/// @param klass the class to consider.
12562///
12563/// @return the data member which type is a fake flexible array, if
12564/// any, or nil.
12568
12569/// Test wheter a type is a declaration-only class.
12570///
12571/// @param t the type to considier.
12572///
12573/// @param look_through_decl_only if true, then look through the
12574/// decl-only class to see if it actually has a class definition in
12575/// the same ABI corpus.
12576///
12577/// @return true iff @p t is a declaration-only class.
12578bool
12581{
12582 if (class_or_union *klass = is_class_or_union_type(t))
12583 {
12585 klass = look_through_decl_only_class(klass);
12586 return klass->get_is_declaration_only();
12587 }
12588 return false;
12589}
12590
12591/// Test wheter a type is a declaration-only class.
12592///
12593/// @param t the type to considier.
12594///
12595/// @param look_through_decl_only if true, then look through the
12596/// decl-only class to see if it actually has a class definition in
12597/// the same ABI corpus.
12598///
12599/// @return true iff @p t is a declaration-only class.
12600bool
12604
12605/// Test wheter a type is a declaration-only class.
12606///
12607/// @param t the type to considier.
12608///
12609/// @param look_through_decl_only if true, then look through the
12610/// decl-only class to see if it actually has a class definition in
12611/// the same ABI corpus.
12612///
12613/// @return true iff @p t is a declaration-only class.
12614bool
12618
12619/// Test if a type is a @ref class_or_union.
12620///
12621/// @param t the type to consider.
12622///
12623/// @return the @ref class_or_union is @p is a @ref class_or_union, or
12624/// nil otherwise.
12627{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
12628
12629/// Test if a type is a @ref class_or_union.
12630///
12631/// @param t the type to consider.
12632///
12633/// @return the @ref class_or_union is @p is a @ref class_or_union, or
12634/// nil otherwise.
12635shared_ptr<class_or_union>
12636is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
12637{return dynamic_pointer_cast<class_or_union>(t);}
12638
12639/// Test if two class or union types are of the same kind.
12640///
12641/// @param first the first type to consider.
12642///
12643/// @param second the second type to consider.
12644///
12645/// @return true iff @p first is of the same kind as @p second.
12646bool
12648 const class_or_union* second)
12649{
12650 if ((is_class_type(first) && is_class_type(second))
12651 || (is_union_type(first) && is_union_type(second)))
12652 return true;
12653
12654 return false;
12655}
12656
12657/// Test if two class or union types are of the same kind.
12658///
12659/// @param first the first type to consider.
12660///
12661/// @param second the second type to consider.
12662///
12663/// @return true iff @p first is of the same kind as @p second.
12664bool
12665class_or_union_types_of_same_kind(const class_or_union_sptr& first,
12666 const class_or_union_sptr& second)
12667{return class_or_union_types_of_same_kind(first.get(), second.get());}
12668
12669/// Test if a type is a @ref union_decl.
12670///
12671/// @param t the type to consider.
12672///
12673/// @return true iff @p t is a union_decl.
12674bool
12676{return is_union_type(&t);}
12677
12678/// Test if a type is a @ref union_decl.
12679///
12680/// @param t the type to consider.
12681///
12682/// @return the @ref union_decl is @p is a @ref union_decl, or nil
12683/// otherwise.
12686{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
12687
12688/// Test if a type is a @ref union_decl.
12689///
12690/// @param t the type to consider.
12691///
12692/// @return the @ref union_decl is @p is a @ref union_decl, or nil
12693/// otherwise.
12694union_decl_sptr
12695is_union_type(const shared_ptr<type_or_decl_base>& t)
12696{return dynamic_pointer_cast<union_decl>(t);}
12697
12698/// Test whether a type is a pointer_type_def.
12699///
12700/// @param t the type to test.
12701///
12702/// @param look_through_decl_only if this is true, then look through
12703/// qualified types to see if the underlying type is a
12704/// pointer_type_def.
12705///
12706/// @return the @ref pointer_type_def_sptr if @p t is a
12707/// pointer_type_def, null otherwise.
12708const pointer_type_def*
12710 bool look_through_qualifiers)
12711{
12712 if (!t)
12713 return 0;
12714
12715 const type_base* type = is_type(t);
12716 if (look_through_qualifiers)
12717 type = peel_qualified_type(is_type(t));
12718
12719 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
12720}
12721
12722/// Test whether a type is a pointer_type_def.
12723///
12724/// @param t the type to test.
12725///
12726/// @param look_through_decl_only if this is true, then look through
12727/// qualified types to see if the underlying type is a
12728/// pointer_type_def.
12729///
12730/// @return the @ref pointer_type_def_sptr if @p t is a
12731/// pointer_type_def, null otherwise.
12734 bool look_through_qualifiers)
12735{
12736 type_base_sptr type = is_type(t);
12737 if (look_through_qualifiers)
12738 type = peel_qualified_type(type);
12739 return dynamic_pointer_cast<pointer_type_def>(type);
12740}
12741
12742/// Test if a type is a pointer to function type.
12743///
12744/// @param t the type to consider.
12745///
12746/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
12747/// function type.
12749is_pointer_to_function_type(const type_base_sptr& t)
12750{
12752 {
12753 if (is_function_type(p->get_pointed_to_type()))
12754 return p;
12755 }
12756 return pointer_type_def_sptr();
12757}
12758
12759/// Test if a type is a pointer to array type.
12760///
12761/// @param t the type to consider.
12762///
12763/// @return the pointer_type_def_sptr iff @p t is a pointer to array
12764/// type.
12766is_pointer_to_array_type(const type_base_sptr& t)
12767{
12769 {
12770 if (is_array_type(p->get_pointed_to_type()))
12771 return p;
12772 }
12773 return pointer_type_def_sptr();
12774}
12775
12776/// Test if we are looking at a pointer to a
12777/// neither-a-pointer-to-an-array-nor-a-function type.
12778///
12779/// @param t the type to consider.
12780///
12781/// @return the @ref pointer_type_def_sptr type iff @p t is a
12782/// neither-a-pointer-an-array-nor-a-function type.
12784is_pointer_to_npaf_type(const type_base_sptr& t)
12785{
12787 {
12788 if (is_npaf_type(p->get_pointed_to_type()))
12789 return p;
12790 }
12791 return pointer_type_def_sptr();
12792}
12793
12794/// Test if we are looking at a pointer to pointer to member type.
12795///
12796/// @param t the type to consider.
12797///
12798/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
12799/// to pointer to member type.
12801is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
12802{
12804 {
12805 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
12806 return p;
12807 }
12808 return pointer_type_def_sptr();
12809}
12810
12811/// Test if a type is a typedef, pointer or reference to a decl-only
12812/// class/union.
12813///
12814/// This looks into qualified types too.
12815///
12816/// @param t the type to consider.
12817///
12818/// @return true iff @p t is a type is a typedef, pointer or reference
12819/// to a decl-only class/union.
12820bool
12822{
12823 const type_base * type =
12824 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
12825
12827 /*look_through_decl_only=*/true))
12828 return true;
12829
12830 return false;
12831}
12832
12833/// Test if a type is a typedef of a class or union type, or a typedef
12834/// of a qualified class or union type.
12835///
12836/// Note that if the type is directly a class or union type, the
12837/// function returns true as well.
12838///
12839/// @param t the type to consider.
12840///
12841/// @return true iff @p t is a typedef of a class or union type, or a
12842/// typedef of a qualified class or union type.
12843bool
12845{
12846 if (!t)
12847 return false;
12848
12851 return true;
12852
12853return false;
12854}
12855
12856/// Test if a type is a typedef of a class or union type, or a typedef
12857/// of a qualified class or union type.
12858///
12859/// Note that if the type is directly a class or union type, the
12860/// function returns true as well.
12861///
12862/// @param t the type to consider.
12863///
12864/// @return true iff @p t is a typedef of a class or union type, or a
12865/// typedef of a qualified class or union type.
12866bool
12869
12870/// Test whether a type is a reference_type_def.
12871///
12872/// @param t the type to test.
12873///
12874/// @param look_through_decl_only if this is true, then look through
12875/// qualified types to see if the underlying type is a
12876/// reference_type_def.
12877///
12878/// @return the @ref reference_type_def_sptr if @p t is a
12879/// reference_type_def, null otherwise.
12882 bool look_through_qualifiers)
12883{
12884 const type_base* type = is_type(t);
12885 if (!type)
12886 return nullptr;
12887
12888 if (look_through_qualifiers)
12889 type = peel_qualified_type(type);
12890 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
12891}
12892
12893/// Test whether a type is a reference_type_def.
12894///
12895/// @param t the type to test.
12896///
12897/// @param look_through_decl_only if this is true, then look through
12898/// qualified types to see if the underlying type is a
12899/// reference_type_def.
12900///
12901/// @return the @ref reference_type_def_sptr if @p t is a
12902/// reference_type_def, null otherwise.
12903const reference_type_def*
12905 bool look_through_qualifiers)
12906{
12907 const type_base* type = is_type(t);
12908
12909 if (look_through_qualifiers)
12910 type = peel_qualified_type(type);
12911 return dynamic_cast<const reference_type_def*>(type);
12912}
12913
12914/// Test whether a type is a reference_type_def.
12915///
12916/// @param t the type to test.
12917///
12918/// @param look_through_decl_only if this is true, then look through
12919/// qualified types to see if the underlying type is a
12920/// reference_type_def.
12921///
12922/// @return the @ref reference_type_def_sptr if @p t is a
12923/// reference_type_def, null otherwise.
12926 bool look_through_qualifiers)
12927{
12928 type_base_sptr type = is_type(t);
12929 if (look_through_qualifiers)
12930 type = peel_qualified_type(type);
12931 return dynamic_pointer_cast<reference_type_def>(type);
12932}
12933
12934/// Test whether a type is a @ref ptr_to_mbr_type.
12935///
12936/// @param t the type to test.
12937///
12938/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
12939/// ptr_to_mbr_type type, null otherwise.
12940const ptr_to_mbr_type*
12942 bool look_through_qualifiers)
12943{
12944 const type_base* type = is_type(t);
12945 if (look_through_qualifiers)
12946 type = peel_qualified_type(type);
12947 return dynamic_cast<const ptr_to_mbr_type*>(type);
12948}
12949
12950/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
12951///
12952/// @param t the type to test.
12953///
12954/// @param look_through_decl_only if this is true, then look through
12955/// qualified types to see if the underlying type is a
12956/// ptr_to_mbr_type..
12957///
12958/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
12959/// ptr_to_mbr_type type, null otherwise.
12962 bool look_through_qualifiers)
12963{
12964 type_base_sptr type = is_type(t);
12965 if (look_through_qualifiers)
12966 type = peel_qualified_type(type);
12967 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
12968}
12969
12970/// Test if a type is equivalent to a pointer to void type.
12971///
12972/// Note that this looks trough typedefs or CV qualifiers to look for
12973/// the void pointer.
12974///
12975/// @param type the type to consider.
12976///
12977/// @return the actual void pointer if @p is eqivalent to a void
12978/// pointer or NULL if it's not.
12979const type_base*
12981{
12982 type = peel_qualified_or_typedef_type(type);
12983
12984 const pointer_type_def * t = is_pointer_type(type);
12985 if (!t)
12986 return 0;
12987
12988 // Look through typedefs in the pointed-to type as well.
12989 type_base * ty = t->get_pointed_to_type().get();
12991 if (ty && ty->get_environment().is_void_type(ty))
12992 return ty;
12993
12994 return 0;
12995}
12996
12997/// Test if a type is equivalent to a pointer to void type.
12998///
12999/// Note that this looks trough typedefs or CV qualifiers to look for
13000/// the void pointer.
13001///
13002/// @param type the type to consider.
13003///
13004/// @return the actual void pointer if @p is eqivalent to a void
13005/// pointer or NULL if it's not.
13006const type_base*
13009
13010/// Test if a type is a pointer to void type.
13011///
13012/// @param type the type to consider.
13013///
13014/// @return the actual void pointer if @p is a void pointer or NULL if
13015/// it's not.
13016const type_base*
13018{
13019 if (!t)
13020 return nullptr;
13021
13022 if (t->get_environment().get_void_pointer_type().get() == t)
13023 return t;
13024
13025 const pointer_type_def* ptr = is_pointer_type(t);
13026 if (!ptr)
13027 return nullptr;
13028
13030 return t;
13031
13032 return nullptr;
13033}
13034
13035/// Test if a type is a pointer to void type.
13036///
13037/// @param type the type to consider.
13038///
13039/// @return the actual void pointer if @p is a void pointer or NULL if
13040/// it's not.
13041const type_base_sptr
13042is_void_pointer_type(const type_base_sptr& t)
13043{
13044 type_base_sptr nil;
13045 if (!t)
13046 return nil;
13047
13048 if (t->get_environment().get_void_pointer_type().get() == t.get())
13049 return t;
13050
13051 const pointer_type_def* ptr = is_pointer_type(t.get());
13052 if (!ptr)
13053 return nil;
13054
13055 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
13056 return t;
13057
13058 return nil;
13059}
13060
13061/// Test whether a type is a reference_type_def.
13062///
13063/// @param t the type to test.
13064///
13065/// @return the @ref reference_type_def_sptr if @p t is a
13066/// reference_type_def, null otherwise.
13069{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
13070
13071/// Test whether a type is a qualified_type_def.
13072///
13073/// @param t the type to test.
13074///
13075/// @return the @ref qualified_type_def_sptr if @p t is a
13076/// qualified_type_def, null otherwise.
13077qualified_type_def_sptr
13079{return dynamic_pointer_cast<qualified_type_def>(t);}
13080
13081/// Test whether a type is a function_type.
13082///
13083/// @param t the type to test.
13084///
13085/// @return the @ref function_type_sptr if @p t is a
13086/// function_type, null otherwise.
13089{return dynamic_pointer_cast<function_type>(t);}
13090
13091/// Test whether a type is a function_type.
13092///
13093/// @param t the type to test.
13094///
13095/// @return the @ref function_type_sptr if @p t is a
13096/// function_type, null otherwise.
13099{return dynamic_cast<function_type*>(t);}
13100
13101/// Test whether a type is a function_type.
13102///
13103/// @param t the type to test.
13104///
13105/// @return the @ref function_type_sptr if @p t is a
13106/// function_type, null otherwise.
13107const function_type*
13109{return dynamic_cast<const function_type*>(t);}
13110
13111/// Test whether a type is a method_type.
13112///
13113/// @param t the type to test.
13114///
13115/// @return the @ref method_type_sptr if @p t is a
13116/// method_type, null otherwise.
13119{return dynamic_pointer_cast<method_type>(t);}
13120
13121/// Test whether a type is a method_type.
13122///
13123/// @param t the type to test.
13124///
13125/// @return the @ref method_type_sptr if @p t is a
13126/// method_type, null otherwise.
13127const method_type*
13129{return dynamic_cast<const method_type*>(t);}
13130
13131/// Test whether a type is a method_type.
13132///
13133/// @param t the type to test.
13134///
13135/// @return the @ref method_type_sptr if @p t is a
13136/// method_type, null otherwise.
13139{return dynamic_cast<method_type*>(t);}
13140
13141/// If a class (or union) is a decl-only class, get its definition.
13142/// Otherwise, just return the initial class.
13143///
13144/// @param the_class the class (or union) to consider.
13145///
13146/// @return either the definition of the class, or the class itself.
13150
13151/// If a class (or union) is a decl-only class, get its definition.
13152/// Otherwise, just return the initial class.
13153///
13154/// @param the_class the class (or union) to consider.
13155///
13156/// @return either the definition of the class, or the class itself.
13157class_or_union_sptr
13160
13161/// If a class (or union) is a decl-only class, get its definition.
13162/// Otherwise, just return the initial class.
13163///
13164/// @param klass the class (or union) to consider.
13165///
13166/// @return either the definition of the class, or the class itself.
13167class_or_union_sptr
13168look_through_decl_only_class(class_or_union_sptr klass)
13170
13171/// If an enum is a decl-only enum, get its definition.
13172/// Otherwise, just return the initial enum.
13173///
13174/// @param the_enum the enum to consider.
13175///
13176/// @return either the definition of the enum, or the enum itself.
13180
13181/// If an enum is a decl-only enum, get its definition.
13182/// Otherwise, just return the initial enum.
13183///
13184/// @param enom the enum to consider.
13185///
13186/// @return either the definition of the enum, or the enum itself.
13190
13191/// If a decl is decl-only get its definition. Otherwise, just return nil.
13192///
13193/// @param d the decl to consider.
13194///
13195/// @return either the definition of the decl, or nil.
13196decl_base_sptr
13198{
13199 decl_base_sptr decl;
13202
13203 if (!decl)
13204 return decl;
13205
13206 while (decl->get_is_declaration_only()
13207 && decl->get_definition_of_declaration())
13208 decl = decl->get_definition_of_declaration();
13209
13210 return decl;
13211}
13212
13213/// If a decl is decl-only enum, get its definition. Otherwise, just
13214/// return the initial decl.
13215///
13216/// @param d the decl to consider.
13217///
13218/// @return either the definition of the enum, or the decl itself.
13219decl_base*
13221{
13222 if (!d)
13223 return d;
13224
13225 decl_base* result = look_through_decl_only(*d).get();
13226 if (!result)
13227 result = d;
13228
13229 return result;
13230}
13231
13232/// If a decl is decl-only get its definition. Otherwise, just return nil.
13233///
13234/// @param d the decl to consider.
13235///
13236/// @return either the definition of the decl, or nil.
13237decl_base_sptr
13238look_through_decl_only(const decl_base_sptr& d)
13239{
13240 if (!d)
13241 return d;
13242
13243 decl_base_sptr result = look_through_decl_only(*d);
13244 if (!result)
13245 result = d;
13246
13247 return result;
13248}
13249
13250/// If a type is is decl-only, then get its definition. Otherwise,
13251/// just return the initial type.
13252///
13253/// @param d the decl to consider.
13254///
13255/// @return either the definition of the decl, or the initial type.
13256type_base*
13258{
13259 decl_base* d = is_decl(t);
13260 if (!d)
13261 return t;
13263 return is_type(d);
13264}
13265
13266/// If a type is is decl-only, then get its definition. Otherwise,
13267/// just return the initial type.
13268///
13269/// @param d the decl to consider.
13270///
13271/// @return either the definition of the decl, or the initial type.
13272type_base_sptr
13273look_through_decl_only_type(const type_base_sptr& t)
13274{
13275 decl_base_sptr d = is_decl(t);
13276 if (!d)
13277 return t;
13279 return is_type(d);
13280}
13281
13282/// Tests if a declaration is a variable declaration.
13283///
13284/// @param decl the decl to test.
13285///
13286/// @return the var_decl_sptr iff decl is a variable declaration; nil
13287/// otherwise.
13288var_decl*
13290{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
13291
13292/// Tests if a declaration is a variable declaration.
13293///
13294/// @param decl the decl to test.
13295///
13296/// @return the var_decl_sptr iff decl is a variable declaration; nil
13297/// otherwise.
13300{return dynamic_pointer_cast<var_decl>(decl);}
13301
13302/// Tests if a declaration is a namespace declaration.
13303///
13304/// @param d the decalration to consider.
13305///
13306/// @return the namespace declaration if @p d is a namespace.
13309{return dynamic_pointer_cast<namespace_decl>(d);}
13310
13311/// Tests if a declaration is a namespace declaration.
13312///
13313/// @param d the decalration to consider.
13314///
13315/// @return the namespace declaration if @p d is a namespace.
13318{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
13319
13320/// Tests whether a decl is a template parameter composition type.
13321///
13322/// @param decl the declaration to consider.
13323///
13324/// @return true iff decl is a template parameter composition type.
13325bool
13326is_template_parm_composition_type(const shared_ptr<decl_base> decl)
13327{
13328 return (decl
13329 && is_at_template_scope(decl)
13330 && is_type(decl)
13331 && !is_template_parameter(decl));
13332}
13333
13334/// Test whether a decl is the pattern of a function template.
13335///
13336/// @param decl the decl to consider.
13337///
13338/// @return true iff decl is the pattern of a function template.
13339bool
13341{
13342 return (decl
13343 && dynamic_pointer_cast<function_decl>(decl)
13344 && dynamic_pointer_cast<template_decl>(decl->get_scope()));
13345}
13346
13347/// Test if a type is an array_type_def.
13348///
13349/// @param type the type to consider.
13350///
13351/// @return true iff @p type is an array_type_def.
13354 bool look_through_qualifiers)
13355{
13356 const type_base* t = is_type(type);
13357
13358 if (look_through_qualifiers)
13359 t = peel_qualified_type(t);
13360 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
13361}
13362
13363/// Test if a type is an array_type_def.
13364///
13365/// @param type the type to consider.
13366///
13367/// @return true iff @p type is an array_type_def.
13370 bool look_through_qualifiers)
13371{
13372 type_base_sptr t = is_type(type);
13373
13374 if (look_through_qualifiers)
13375 t = peel_qualified_type(t);
13376 return dynamic_pointer_cast<array_type_def>(t);
13377}
13378
13379/// Tests if the element of a given array is a qualified type.
13380///
13381/// @param array the array type to consider.
13382///
13383/// @return the qualified element of the array iff it's a qualified
13384/// type. Otherwise, return a nil object.
13385qualified_type_def_sptr
13387{
13388 if (!array)
13389 return qualified_type_def_sptr();
13390
13391 return is_qualified_type(array->get_element_type());
13392}
13393
13394/// Test if an array type is an array to a qualified element type.
13395///
13396/// @param type the array type to consider.
13397///
13398/// @return true the array @p type iff it's an array to a qualified
13399/// element type.
13401is_array_of_qualified_element(const type_base_sptr& type)
13402{
13403 if (array_type_def_sptr array = is_array_type(type))
13405 return array;
13406
13407 return array_type_def_sptr();
13408}
13409
13410/// Test if a type is a typedef of an array.
13411///
13412/// Note that the function looks through qualified and typedefs types
13413/// of the underlying type of the current typedef. In other words, if
13414/// we are looking at a typedef of a CV-qualified array, or at a
13415/// typedef of a CV-qualified typedef of an array, this function will
13416/// still return TRUE.
13417///
13418/// @param t the type to consider.
13419///
13420/// @return true if t is a typedef which underlying type is an array.
13421/// That array might be either cv-qualified array or a typedef'ed
13422/// array, or a combination of both.
13424is_typedef_of_array(const type_base_sptr& t)
13425{
13426 array_type_def_sptr result;
13427
13428 if (typedef_decl_sptr typdef = is_typedef(t))
13429 {
13430 type_base_sptr u =
13431 peel_qualified_or_typedef_type(typdef->get_underlying_type());
13432 if (auto a = is_array_type(u))
13433 result = a;
13434 }
13435
13436 return result;
13437}
13438
13439/// Test if a type is an array_type_def::subrange_type.
13440///
13441/// @param type the type to consider.
13442///
13443/// @return the array_type_def::subrange_type which @p type is a type
13444/// of, or nil if it's not of that type.
13447{
13448 return dynamic_cast<array_type_def::subrange_type*>
13449 (const_cast<type_or_decl_base*>(type));
13450}
13451
13452/// Test if a type is an array_type_def::subrange_type.
13453///
13454/// @param type the type to consider.
13455///
13456/// @return the array_type_def::subrange_type which @p type is a type
13457/// of, or nil if it's not of that type.
13460{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
13461
13462/// Tests whether a decl is a template.
13463///
13464/// @param decl the decl to consider.
13465///
13466/// @return true iff decl is a function template, class template, or
13467/// template template parameter.
13468bool
13469is_template_decl(const decl_base_sptr& decl)
13470{return decl && dynamic_pointer_cast<template_decl>(decl);}
13471
13472/// This enum describe the kind of entity to lookup, while using the
13473/// lookup API.
13475{
13476 LOOKUP_ENTITY_TYPE,
13477 LOOKUP_ENTITY_VAR,
13478};
13479
13480/// Find the first relevant delimiter (the "::" string) in a fully
13481/// qualified C++ type name, starting from a given position. The
13482/// delimiter returned separates a type name from the name of its
13483/// context.
13484///
13485/// This is supposed to work correctly on names in cases like this:
13486///
13487/// foo<ns1::name1, ns2::name2>
13488///
13489/// In that case when called with with parameter @p begin set to 0, no
13490/// delimiter is returned, because the type name in this case is:
13491/// 'foo<ns1::name1, ns2::name2>'.
13492///
13493/// But in this case:
13494///
13495/// foo<p1, bar::name>::some_type
13496///
13497/// The "::" returned is the one right before 'some_type'.
13498///
13499/// @param fqn the fully qualified name of the type to consider.
13500///
13501/// @param begin the position from which to look for the delimiter.
13502///
13503/// @param delim_pos out parameter. Is set to the position of the
13504/// delimiter iff the function returned true.
13505///
13506/// @return true iff the function found and returned the delimiter.
13507static bool
13508find_next_delim_in_cplus_type(const string& fqn,
13509 size_t begin,
13510 size_t& delim_pos)
13511{
13512 int angle_count = 0;
13513 bool found = false;
13514 size_t i = begin;
13515 for (; i < fqn.size(); ++i)
13516 {
13517 if (fqn[i] == '<')
13518 ++angle_count;
13519 else if (fqn[i] == '>')
13520 --angle_count;
13521 else if (i + 1 < fqn.size()
13522 && !angle_count
13523 && fqn[i] == ':'
13524 && fqn[i+1] == ':')
13525 {
13526 delim_pos = i;
13527 found = true;
13528 break;
13529 }
13530 }
13531 return found;
13532}
13533
13534/// Decompose a fully qualified name into the list of its components.
13535///
13536/// @param fqn the fully qualified name to decompose.
13537///
13538/// @param comps the resulting list of component to fill.
13539void
13540fqn_to_components(const string& fqn,
13541 list<string>& comps)
13542{
13543 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
13544 do
13545 {
13546 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
13547 comp_end = fqn_size;
13548
13549 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
13550 comps.push_back(comp);
13551
13552 comp_begin = comp_end + 2;
13553 if (comp_begin >= fqn_size)
13554 break;
13555 } while (true);
13556}
13557
13558/// Turn a set of qualified name components (that name a type) into a
13559/// qualified name string.
13560///
13561/// @param comps the name components
13562///
13563/// @return the resulting string, which would be the qualified name of
13564/// a type.
13565string
13566components_to_type_name(const list<string>& comps)
13567{
13568 string result;
13569 for (list<string>::const_iterator c = comps.begin();
13570 c != comps.end();
13571 ++c)
13572 if (c == comps.begin())
13573 result = *c;
13574 else
13575 result += "::" + *c;
13576 return result;
13577}
13578
13579/// This predicate returns true if a given container iterator points
13580/// to the last element of the container, false otherwise.
13581///
13582/// @tparam T the type of the container of the iterator.
13583///
13584/// @param container the container the iterator points into.
13585///
13586/// @param i the iterator to consider.
13587///
13588/// @return true iff the iterator points to the last element of @p
13589/// container.
13590template<typename T>
13591static bool
13592iterator_is_last(T& container,
13593 typename T::const_iterator i)
13594{
13595 typename T::const_iterator next = i;
13596 ++next;
13597 return (next == container.end());
13598}
13599
13600//--------------------------------
13601// <type and decls lookup stuff>
13602// ------------------------------
13603
13604/// Lookup all the type*s* that have a given fully qualified name.
13605///
13606/// @param type_name the fully qualified name of the type to
13607/// lookup.
13608///
13609/// @param type_map the map to look into.
13610///
13611/// @return the vector containing the types named @p type_name. If
13612/// the lookup didn't yield any type, then this function returns nil.
13613static const type_base_wptrs_type*
13614lookup_types_in_map(const interned_string& type_name,
13615 const istring_type_base_wptrs_map_type& type_map)
13616{
13617 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
13618 if (i != type_map.end())
13619 return &i->second;
13620 return 0;
13621}
13622
13623
13624/// Lookup a basic type from a translation unit.
13625///
13626/// This is done by looking the type up in the type map that is
13627/// maintained in the translation unit. So this is as fast as
13628/// possible.
13629///
13630/// @param type_name the name of the basic type to look for.
13631///
13632/// @param tu the translation unit to look into.
13633///
13634/// @return the basic type found or nil if no basic type was found.
13637{
13638 return lookup_type_in_map<type_decl>(type_name,
13639 tu.get_types().basic_types());
13640}
13641
13642/// Lookup a basic type from a translation unit.
13643///
13644/// This is done by looking the type up in the type map that is
13645/// maintained in the translation unit. So this is as fast as
13646/// possible.
13647///
13648/// @param type_name the name of the basic type to look for.
13649///
13650/// @param tu the translation unit to look into.
13651///
13652/// @return the basic type found or nil if no basic type was found.
13654lookup_basic_type(const string& type_name, const translation_unit& tu)
13655{
13656 const environment& env = tu.get_environment();
13657
13658 interned_string s = env.intern(type_name);
13659 return lookup_basic_type(s, tu);
13660}
13661
13662/// Lookup a class type from a translation unit.
13663///
13664/// This is done by looking the type up in the type map that is
13665/// maintained in the translation unit. So this is as fast as
13666/// possible.
13667///
13668/// @param fqn the fully qualified name of the class type node to look
13669/// up.
13670///
13671/// @param tu the translation unit to perform lookup from.
13672///
13673/// @return the declaration of the class type IR node found, NULL
13674/// otherwise.
13676lookup_class_type(const string& fqn, const translation_unit& tu)
13677{
13678 const environment& env = tu.get_environment();
13679 interned_string s = env.intern(fqn);
13680 return lookup_class_type(s, tu);
13681}
13682
13683/// Lookup a class type from a translation unit.
13684///
13685/// This is done by looking the type up in the type map that is
13686/// maintained in the translation unit. So this is as fast as
13687/// possible.
13688///
13689/// @param type_name the name of the class type to look for.
13690///
13691/// @param tu the translation unit to look into.
13692///
13693/// @return the class type found or nil if no class type was found.
13696{
13697 return lookup_type_in_map<class_decl>(type_name,
13698 tu.get_types().class_types());
13699}
13700
13701/// Lookup a union type from a translation unit.
13702///
13703/// This is done by looking the type up in the type map that is
13704/// maintained in the translation unit. So this is as fast as
13705/// possible.
13706///
13707/// @param type_name the name of the union type to look for.
13708///
13709/// @param tu the translation unit to look into.
13710///
13711/// @return the union type found or nil if no union type was found.
13712union_decl_sptr
13714{
13715 return lookup_type_in_map<union_decl>(type_name,
13716 tu.get_types().union_types());
13717}
13718
13719/// Lookup a union type from a translation unit.
13720///
13721/// This is done by looking the type up in the type map that is
13722/// maintained in the translation unit. So this is as fast as
13723/// possible.
13724///
13725/// @param fqn the fully qualified name of the type to lookup.
13726///
13727/// @param tu the translation unit to look into.
13728///
13729/// @return the union type found or nil if no union type was found.
13730union_decl_sptr
13731lookup_union_type(const string& fqn, const translation_unit& tu)
13732{
13733 const environment& env = tu.get_environment();
13734 interned_string s = env.intern(fqn);
13735 return lookup_union_type(s, tu);
13736}
13737
13738/// Lookup a union type in a given corpus, from its location.
13739///
13740/// @param loc the location of the union type to look for.
13741///
13742/// @param corp the corpus to look it from.
13743///
13744/// @return the resulting union_decl.
13745union_decl_sptr
13747{
13750 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
13751
13752 return result;
13753}
13754
13755/// Lookup a union type in a given corpus, from its location.
13756///
13757/// @param loc the location of the union type to look for.
13758///
13759/// @param corp the corpus to look it from.
13760///
13761/// @return the resulting union_decl.
13762union_decl_sptr
13763lookup_union_type_per_location(const string& loc, const corpus& corp)
13764{
13765 const environment& env = corp.get_environment();
13766 return lookup_union_type_per_location(env.intern(loc), corp);
13767}
13768
13769/// Lookup an enum type from a translation unit.
13770///
13771/// This is done by looking the type up in the type map that is
13772/// maintained in the translation unit. So this is as fast as
13773/// possible.
13774///
13775/// @param type_name the name of the enum type to look for.
13776///
13777/// @param tu the translation unit to look into.
13778///
13779/// @return the enum type found or nil if no enum type was found.
13782{
13783 return lookup_type_in_map<enum_type_decl>(type_name,
13784 tu.get_types().enum_types());
13785}
13786
13787/// Lookup an enum type from a translation unit.
13788///
13789/// This is done by looking the type up in the type map that is
13790/// maintained in the translation unit. So this is as fast as
13791/// possible.
13792///
13793/// @param type_name the name of the enum type to look for.
13794///
13795/// @param tu the translation unit to look into.
13796///
13797/// @return the enum type found or nil if no enum type was found.
13799lookup_enum_type(const string& type_name, const translation_unit& tu)
13800{
13801 const environment& env = tu.get_environment();
13802 interned_string s = env.intern(type_name);
13803 return lookup_enum_type(s, tu);
13804}
13805
13806/// Lookup a typedef type from a translation unit.
13807///
13808/// This is done by looking the type up in the type map that is
13809/// maintained in the translation unit. So this is as fast as
13810/// possible.
13811///
13812/// @param type_name the name of the typedef type to look for.
13813///
13814/// @param tu the translation unit to look into.
13815///
13816/// @return the typedef type found or nil if no typedef type was
13817/// found.
13820 const translation_unit& tu)
13821{
13822 return lookup_type_in_map<typedef_decl>(type_name,
13823 tu.get_types().typedef_types());
13824}
13825
13826/// Lookup a typedef type from a translation unit.
13827///
13828/// This is done by looking the type up in the type map that is
13829/// maintained in the translation unit. So this is as fast as
13830/// possible.
13831///
13832/// @param type_name the name of the typedef type to look for.
13833///
13834/// @param tu the translation unit to look into.
13835///
13836/// @return the typedef type found or nil if no typedef type was
13837/// found.
13839lookup_typedef_type(const string& type_name, const translation_unit& tu)
13840{
13841 const environment& env = tu.get_environment();
13842 interned_string s = env.intern(type_name);
13843 return lookup_typedef_type(s, tu);
13844}
13845
13846/// Lookup a qualified type from a translation unit.
13847///
13848/// This is done by looking the type up in the type map that is
13849/// maintained in the translation unit. So this is as fast as
13850/// possible.
13851///
13852/// @param type_name the name of the qualified type to look for.
13853///
13854/// @param tu the translation unit to look into.
13855///
13856/// @return the qualified type found or nil if no qualified type was
13857/// found.
13858qualified_type_def_sptr
13860 const translation_unit& tu)
13861{
13862 const type_maps& m = tu.get_types();
13863 return lookup_type_in_map<qualified_type_def>(type_name,
13864 m.qualified_types());
13865}
13866
13867/// Lookup a qualified type from a translation unit.
13868///
13869/// This is done by looking the type up in the type map that is
13870/// maintained in the translation unit. So this is as fast as
13871/// possible.
13872///
13873/// @param underlying_type the underying type of the qualified type to
13874/// look up.
13875///
13876/// @param quals the CV-qualifiers of the qualified type to look for.
13877///
13878/// @param tu the translation unit to look into.
13879///
13880/// @return the qualified type found or nil if no qualified type was
13881/// found.
13882qualified_type_def_sptr
13883lookup_qualified_type(const type_base_sptr& underlying_type,
13885 const translation_unit& tu)
13886{
13887 interned_string type_name = get_name_of_qualified_type(underlying_type,
13888 quals);
13889 return lookup_qualified_type(type_name, tu);
13890}
13891
13892/// Lookup a pointer type from a translation unit.
13893///
13894/// This is done by looking the type up in the type map that is
13895/// maintained in the translation unit. So this is as fast as
13896/// possible.
13897///
13898/// @param type_name the name of the pointer type to look for.
13899///
13900/// @param tu the translation unit to look into.
13901///
13902/// @return the pointer type found or nil if no pointer type was
13903/// found.
13906 const translation_unit& tu)
13907{
13908 const type_maps& m = tu.get_types();
13909 return lookup_type_in_map<pointer_type_def>(type_name,
13910 m.pointer_types());
13911}
13912
13913/// Lookup a pointer type from a translation unit.
13914///
13915/// This is done by looking the type up in the type map that is
13916/// maintained in the translation unit. So this is as fast as
13917/// possible.
13918///
13919/// @param type_name the name of the pointer type to look for.
13920///
13921/// @param tu the translation unit to look into.
13922///
13923/// @return the pointer type found or nil if no pointer type was
13924/// found.
13926lookup_pointer_type(const string& type_name, const translation_unit& tu)
13927{
13928 const environment& env = tu.get_environment();
13929 interned_string s = env.intern(type_name);
13930 return lookup_pointer_type(s, tu);
13931}
13932
13933/// Lookup a pointer type from a translation unit.
13934///
13935/// This is done by looking the type up in the type map that is
13936/// maintained in the translation unit. So this is as fast as
13937/// possible.
13938///
13939/// @param pointed_to_type the pointed-to-type of the pointer to look for.
13940///
13941/// @param tu the translation unit to look into.
13942///
13943/// @return the pointer type found or nil if no pointer type was
13944/// found.
13946lookup_pointer_type(const type_base_sptr& pointed_to_type,
13947 const translation_unit& tu)
13948{
13949 type_base_sptr t = look_through_decl_only_type(pointed_to_type);
13951 return lookup_pointer_type(type_name, tu);
13952}
13953
13954/// Lookup a reference type from a translation unit.
13955///
13956/// This is done by looking the type up in the type map that is
13957/// maintained in the translation unit. So this is as fast as
13958/// possible.
13959///
13960/// @param type_name the name of the reference type to look for.
13961///
13962/// @param tu the translation unit to look into.
13963///
13964/// @return the reference type found or nil if no reference type was
13965/// found.
13968 const translation_unit& tu)
13969{
13970 const type_maps& m = tu.get_types();
13971 return lookup_type_in_map<reference_type_def>(type_name,
13972 m.reference_types());
13973}
13974
13975/// Lookup a reference type from a translation unit.
13976///
13977/// This is done by looking the type up in the type map that is
13978/// maintained in the translation unit. So this is as fast as
13979/// possible.
13980///
13981/// @param pointed_to_type the pointed-to-type of the reference to
13982/// look up.
13983///
13984/// @param tu the translation unit to look into.
13985///
13986/// @return the reference type found or nil if no reference type was
13987/// found.
13989lookup_reference_type(const type_base_sptr& pointed_to_type,
13990 bool lvalue_reference,
13991 const translation_unit& tu)
13992{
13993 interned_string type_name =
13995 lvalue_reference);
13996 return lookup_reference_type(type_name, tu);
13997}
13998
13999/// Lookup an array type from a translation unit.
14000///
14001/// This is done by looking the type up in the type map that is
14002/// maintained in the translation unit. So this is as fast as
14003/// possible.
14004///
14005/// @param type_name the name of the array type to look for.
14006///
14007/// @param tu the translation unit to look into.
14008///
14009/// @return the array type found or nil if no array type was found.
14012 const translation_unit& tu)
14013{
14014 const type_maps& m = tu.get_types();
14015 return lookup_type_in_map<array_type_def>(type_name,
14016 m.array_types());
14017}
14018
14019/// Lookup a function type from a translation unit.
14020///
14021/// This is done by looking the type up in the type map that is
14022/// maintained in the translation unit. So this is as fast as
14023/// possible.
14024///
14025/// @param type_name the name of the type to lookup.
14026///
14027/// @param tu the translation unit to look into.
14028///
14029/// @return the function type found, or NULL of none was found.
14032 const translation_unit& tu)
14033{
14034 const type_maps& m = tu.get_types();
14035 return lookup_type_in_map<function_type>(type_name,
14036 m.function_types());
14037}
14038
14039/// Lookup a function type from a translation unit.
14040///
14041/// This walks all the function types held by the translation unit and
14042/// compare their sub-type *names*. If the names match then return
14043/// the function type found in the translation unit.
14044///
14045/// @param t the function type to look for.
14046///
14047/// @param tu the translation unit to look into.
14048///
14049/// @return the function type found, or NULL of none was found.
14052 const translation_unit& tu)
14053{
14054 interned_string type_name = get_type_name(t);
14055 return lookup_function_type(type_name, tu);
14056}
14057
14058/// Lookup a function type from a translation unit.
14059///
14060/// This is done by looking the type up in the type map that is
14061/// maintained in the translation unit. So this is as fast as
14062/// possible.
14063///
14064/// @param t the function type to look for.
14065///
14066/// @param tu the translation unit to look into.
14067///
14068/// @return the function type found, or NULL of none was found.
14071 const translation_unit& tu)
14072{return lookup_function_type(*t, tu);}
14073
14074/// Lookup a type in a translation unit.
14075///
14076/// @param fqn the fully qualified name of the type to lookup.
14077///
14078/// @param tu the translation unit to consider.
14079///
14080/// @return the declaration of the type if found, NULL otherwise.
14081const type_base_sptr
14082lookup_type(const interned_string& fqn,
14083 const translation_unit& tu)
14084{
14085 type_base_sptr result;
14086 ((result = lookup_typedef_type(fqn, tu))
14087 || (result = lookup_class_type(fqn, tu))
14088 || (result = lookup_union_type(fqn, tu))
14089 || (result = lookup_enum_type(fqn, tu))
14090 || (result = lookup_qualified_type(fqn, tu))
14091 || (result = lookup_pointer_type(fqn, tu))
14092 || (result = lookup_reference_type(fqn, tu))
14093 || (result = lookup_array_type(fqn, tu))
14094 || (result = lookup_function_type(fqn, tu))
14095 || (result = lookup_basic_type(fqn, tu)));
14096
14097 return result;
14098}
14099
14100/// Lookup a type in a translation unit, starting from the global
14101/// namespace.
14102///
14103/// @param fqn the fully qualified name of the type to lookup.
14104///
14105/// @param tu the translation unit to consider.
14106///
14107/// @return the declaration of the type if found, NULL otherwise.
14108type_base_sptr
14109lookup_type(const string& fqn, const translation_unit& tu)
14110{
14111 const environment&env = tu.get_environment();
14112 interned_string ifqn = env.intern(fqn);
14113 return lookup_type(ifqn, tu);
14114}
14115
14116/// Lookup a type from a translation unit.
14117///
14118/// @param fqn the components of the fully qualified name of the node
14119/// to look up.
14120///
14121/// @param tu the translation unit to perform lookup from.
14122///
14123/// @return the declaration of the IR node found, NULL otherwise.
14124const type_base_sptr
14125lookup_type(const type_base_sptr type,
14126 const translation_unit& tu)
14127{
14128 interned_string type_name = get_type_name(type);
14129 return lookup_type(type_name, tu);
14130}
14131
14132/// Lookup a type in a scope.
14133///
14134/// This is really slow as it walks the member types of the scope in
14135/// sequence to find the type with a given name.
14136///
14137/// If possible, users should prefer looking up types from the
14138/// enclosing translation unit or even ABI corpus because both the
14139/// translation unit and the corpus have a map of type, indexed by
14140/// their name. Looking up a type from those maps is thus much
14141/// faster.
14142///
14143/// @param fqn the fully qualified name of the type to lookup.
14144///
14145/// @param skope the scope to look into.
14146///
14147/// @return the declaration of the type if found, NULL otherwise.
14148const type_base_sptr
14149lookup_type_in_scope(const string& fqn,
14150 scope_decl_sptr skope)
14151{
14152 list<string> comps;
14153 fqn_to_components(fqn, comps);
14154 return lookup_type_in_scope(comps, skope);
14155}
14156
14157/// Lookup a @ref var_decl in a scope.
14158///
14159/// @param fqn the fuly qualified name of the @var_decl to lookup.
14160///
14161/// @param skope the scope to look into.
14162///
14163/// @return the declaration of the @ref var_decl if found, NULL
14164/// otherwise.
14165decl_base_sptr
14167{
14168 list<string> comps;
14169 fqn_to_components(fqn, comps);
14170 return lookup_var_decl_in_scope(comps, skope);
14171}
14172
14173/// A generic function (template) to get the name of a node, whatever
14174/// node it is. This has to be specialized for the kind of node we
14175/// want.
14176///
14177/// Note that a node is a member of a scope.
14178///
14179/// @tparam NodeKind the kind of node to consider.
14180///
14181/// @param node the node to get the name from.
14182///
14183/// @return the name of the node.
14184template<typename NodeKind>
14185static const interned_string&
14186get_node_name(shared_ptr<NodeKind> node);
14187
14188/// Gets the name of a class_decl node.
14189///
14190/// @param node the decl_base node to get the name from.
14191///
14192/// @return the name of the node.
14193template<>
14194const interned_string&
14195get_node_name(class_decl_sptr node)
14196{return node->get_name();}
14197
14198/// Gets the name of a type_base node.
14199///
14200/// @param node the type_base node to get the name from.
14201///
14202/// @return the name of the node.
14203template<>
14204const interned_string&
14205get_node_name(type_base_sptr node)
14206{return get_type_declaration(node)->get_name();}
14207
14208/// Gets the name of a var_decl node.
14209///
14210/// @param node the var_decl node to get the name from.
14211///
14212/// @return the name of the node.
14213template<>
14214const interned_string&
14215get_node_name(var_decl_sptr node)
14216{return node->get_name();}
14217
14218/// Generic function to get the declaration of a given node, whatever
14219/// it is. There has to be specializations for the kind of the nodes
14220/// we want to support.
14221///
14222/// @tparam NodeKind the type of the node we are looking at.
14223///
14224/// @return the declaration.
14225template<typename NodeKind>
14226static decl_base_sptr
14227convert_node_to_decl(shared_ptr<NodeKind> node);
14228
14229/// Lookup a node in a given scope.
14230///
14231/// @tparam the type of the node to lookup.
14232///
14233/// @param fqn the components of the fully qualified name of the node
14234/// to lookup.
14235///
14236/// @param skope the scope to look into.
14237///
14238/// @return the declaration of the looked up node, or NULL if it
14239/// wasn't found.
14240template<typename NodeKind>
14241static const type_or_decl_base_sptr
14242lookup_node_in_scope(const list<string>& fqn,
14243 const scope_decl_sptr& skope)
14244{
14245 ABG_ASSERT(skope);
14246 type_or_decl_base_sptr resulting_decl;
14247 shared_ptr<NodeKind> node;
14248 bool it_is_last = false;
14249 scope_decl_sptr cur_scope = skope, new_scope, scope;
14250
14251 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
14252 {
14253 new_scope.reset();
14254 it_is_last = iterator_is_last(fqn, c);
14255 lock_guard<recursive_mutex> lock(cur_scope->get_mutex());
14256 for (scope_decl::declarations::const_iterator m =
14257 cur_scope->get_member_decls().begin();
14258 m != cur_scope->get_member_decls().end();
14259 ++m)
14260 {
14261 if (!it_is_last)
14262 {
14263 // looking for a scope
14264 scope = dynamic_pointer_cast<scope_decl>(*m);
14265 if (scope && scope->get_name() == *c)
14266 {
14267 new_scope = scope;
14268 break;
14269 }
14270 }
14271 else
14272 {
14273 //looking for a final type.
14274 node = dynamic_pointer_cast<NodeKind>(*m);
14275 if (node && get_node_name(node) == *c)
14276 {
14277 if (class_decl_sptr cl =
14278 dynamic_pointer_cast<class_decl>(node))
14279 if (cl->get_is_declaration_only()
14280 && !cl->get_definition_of_declaration())
14281 continue;
14282 resulting_decl = node;
14283 break;
14284 }
14285 }
14286 }
14287 if (!new_scope && !resulting_decl)
14288 return decl_base_sptr();
14289 cur_scope = new_scope;
14290 }
14291 ABG_ASSERT(resulting_decl);
14292 return resulting_decl;
14293}
14294
14295/// lookup a type in a scope.
14296///
14297///
14298/// This is really slow as it walks the member types of the scope in
14299/// sequence to find the type with a given name.
14300///
14301/// If possible, users should prefer looking up types from the
14302/// enclosing translation unit or even ABI corpus because both the
14303/// translation unit and the corpus have a map of type, indexed by
14304/// their name. Looking up a type from those maps is thus much
14305/// faster.
14306///
14307/// @param comps the components of the fully qualified name of the
14308/// type to lookup.
14309///
14310/// @param skope the scope to look into.
14311///
14312/// @return the declaration of the type found.
14313const type_base_sptr
14314lookup_type_in_scope(const list<string>& comps,
14315 const scope_decl_sptr& scope)
14316{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
14317
14318/// lookup a type in a scope.
14319///
14320/// This is really slow as it walks the member types of the scope in
14321/// sequence to find the type with a given name.
14322///
14323/// If possible, users should prefer looking up types from the
14324/// enclosing translation unit or even ABI corpus because both the
14325/// translation unit and the corpus have a map of type, indexed by
14326/// their name. Looking up a type from those maps is thus much
14327/// faster.
14328///
14329/// @param type the type to look for.
14330///
14331/// @param access_path a vector of scopes the path of scopes to follow
14332/// before reaching the scope into which to look for @p type. Note
14333/// that the deepest scope (the one immediately containing @p type) is
14334/// at index 0 of this vector, and the top-most scope is the last
14335/// element of the vector.
14336///
14337/// @param scope the top-most scope into which to look for @p type.
14338///
14339/// @return the scope found in @p scope, or NULL if it wasn't found.
14340static const type_base_sptr
14342 const vector<scope_decl_sptr>& access_path,
14343 scope_decl_sptr scope)
14344{
14345 vector<scope_decl_sptr> a = access_path;
14346 type_base_sptr result;
14347
14348 scope_decl_sptr first_scope;
14349 if (!a.empty())
14350 {
14351 first_scope = a.back();
14352 ABG_ASSERT(first_scope->get_name() == scope->get_name());
14353 a.pop_back();
14354 }
14355
14356 if (a.empty())
14357 {
14358 interned_string n = get_type_name(type, false);
14359 lock_guard<recursive_mutex> lock(scope->get_mutex());
14360 for (scope_decl::declarations::const_iterator i =
14361 scope->get_member_decls().begin();
14362 i != scope->get_member_decls().end();
14363 ++i)
14364 if (is_type(*i) && (*i)->get_name() == n)
14365 {
14366 result = is_type(*i);
14367 break;
14368 }
14369 }
14370 else
14371 {
14372 first_scope = a.back();
14373 interned_string scope_name, cur_scope_name = first_scope->get_name();
14374 lock_guard<recursive_mutex> lock(scope->get_mutex());
14375 for (scope_decl::scopes::const_iterator i =
14376 scope->get_member_scopes().begin();
14377 i != scope->get_member_scopes().end();
14378 ++i)
14379 {
14380 scope_name = (*i)->get_name();
14381 if (scope_name == cur_scope_name)
14382 {
14383 result = lookup_type_in_scope(type, a, *i);
14384 break;
14385 }
14386 }
14387 }
14388 return result;
14389}
14390
14391/// lookup a type in a scope.
14392///
14393/// This is really slow as it walks the member types of the scope in
14394/// sequence to find the type with a given name.
14395///
14396/// If possible, users should prefer looking up types from the
14397/// enclosing translation unit or even ABI corpus because both the
14398/// translation unit and the corpus have a map of type, indexed by
14399/// their name. Looking up a type from those maps is thus much
14400/// faster.
14401///
14402/// @param type the type to look for.
14403///
14404/// @param scope the top-most scope into which to look for @p type.
14405///
14406/// @return the scope found in @p scope, or NULL if it wasn't found.
14407static const type_base_sptr
14408lookup_type_in_scope(const type_base_sptr type,
14409 scope_decl_sptr scope)
14410{
14411 if (!type || is_function_type(type))
14412 return type_base_sptr();
14413
14414 decl_base_sptr type_decl = get_type_declaration(type);
14415 ABG_ASSERT(type_decl);
14416 vector<scope_decl_sptr> access_path;
14417 for (auto s = type_decl->get_scope();
14418 s != nullptr;
14419 s = s->get_scope())
14420 {
14421 access_path.push_back(s);
14422 if (is_global_scope(s))
14423 break;
14424 }
14425 return lookup_type_in_scope(*type, access_path, scope);
14426}
14427
14428/// Lookup a type from a translation unit by walking the scopes of the
14429/// translation unit in sequence and looking into them.
14430///
14431/// This is really slow as it walks the member types of the scopes in
14432/// sequence to find the type with a given name.
14433///
14434/// If possible, users should prefer looking up types from the
14435/// translation unit or even ABI corpus in a more direct way, by using
14436/// the lookup_type() functins.
14437///
14438///
14439/// This is because both the translation unit and the corpus have a
14440/// map of types, indexed by their name. Looking up a type from those
14441/// maps is thus much faster. @param fqn the components of the fully
14442/// qualified name of the node to look up.
14443///
14444/// @param tu the translation unit to perform lookup from.
14445///
14446/// @return the declaration of the IR node found, NULL otherwise.
14447const type_base_sptr
14448lookup_type_through_scopes(const type_base_sptr type,
14449 const translation_unit& tu)
14450{
14451 if (function_type_sptr fn_type = is_function_type(type))
14452 return lookup_function_type(fn_type, tu);
14453 return lookup_type_in_scope(type, tu.get_global_scope());
14454}
14455
14456/// lookup a var_decl in a scope.
14457///
14458/// @param comps the components of the fully qualified name of the
14459/// var_decl to lookup.
14460///
14461/// @param skope the scope to look into.
14462decl_base_sptr
14463lookup_var_decl_in_scope(const std::list<string>& comps, scope_decl_sptr skope)
14464{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
14465
14466/// Lookup an IR node from a translation unit.
14467///
14468/// @tparam NodeKind the type of the IR node to lookup from the
14469/// translation unit.
14470///
14471/// @param fqn the components of the fully qualified name of the node
14472/// to look up.
14473///
14474/// @param tu the translation unit to perform lookup from.
14475///
14476/// @return the declaration of the IR node found, NULL otherwise.
14477template<typename NodeKind>
14478static const type_or_decl_base_sptr
14479lookup_node_in_translation_unit(const list<string>& fqn,
14480 const translation_unit& tu)
14481{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
14482
14483/// Lookup a type from a translation unit by walking its scopes in
14484/// sequence and by looking into them.
14485///
14486/// This is much slower than using the lookup_type() function.
14487///
14488/// @param fqn the components of the fully qualified name of the node
14489/// to look up.
14490///
14491/// @param tu the translation unit to perform lookup from.
14492///
14493/// @return the declaration of the IR node found, NULL otherwise.
14494type_base_sptr
14495lookup_type_through_scopes(const list<string>& fqn,
14496 const translation_unit& tu)
14497{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
14498
14499
14500/// Lookup a class type from a translation unit by walking its scopes
14501/// in sequence and by looking into them.
14502///
14503/// This is much slower than using the lookup_class_type() function
14504/// because it walks all the scopes of the translation unit in
14505/// sequence and lookup the types to find one that has a given name.
14506///
14507/// @param fqn the components of the fully qualified name of the class
14508/// type node to look up.
14509///
14510/// @param tu the translation unit to perform lookup from.
14511///
14512/// @return the declaration of the class type IR node found, NULL
14513/// otherwise.
14515lookup_class_type_through_scopes(const list<string>& fqn,
14516 const translation_unit& tu)
14517{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
14518
14519/// Lookup a basic type from all the translation units of a given
14520/// corpus.
14521///
14522/// @param fqn the components of the fully qualified name of the basic
14523/// type node to look up.
14524///
14525/// @param tu the translation unit to perform lookup from.
14526///
14527/// @return the declaration of the basic type IR node found, NULL
14528/// otherwise.
14529static type_decl_sptr
14530lookup_basic_type_through_translation_units(const interned_string& type_name,
14531 const corpus& abi_corpus)
14532{
14533 type_decl_sptr result;
14534
14535 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14536 for (translation_units::const_iterator tu =
14537 abi_corpus.get_translation_units().begin();
14538 tu != abi_corpus.get_translation_units().end();
14539 ++tu)
14540 if ((result = lookup_basic_type(type_name, **tu)))
14541 break;
14542
14543 return result;
14544}
14545
14546/// Lookup a union type from all the translation units of a given
14547/// corpus.
14548///
14549/// @param fqn the components of the fully qualified name of the union
14550/// type node to look up.
14551///
14552/// @param tu the translation unit to perform lookup from.
14553///
14554/// @return the declaration of the union type IR node found, NULL
14555/// otherwise.
14556static union_decl_sptr
14557lookup_union_type_through_translation_units(const interned_string& type_name,
14558 const corpus & abi_corpus)
14559{
14560 union_decl_sptr result;
14561
14562 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14563 for (translation_units::const_iterator tu =
14564 abi_corpus.get_translation_units().begin();
14565 tu != abi_corpus.get_translation_units().end();
14566 ++tu)
14567 if ((result = lookup_union_type(type_name, **tu)))
14568 break;
14569
14570 return result;
14571}
14572
14573/// Lookup an enum type from all the translation units of a given
14574/// corpus.
14575///
14576/// @param fqn the components of the fully qualified name of the enum
14577/// type node to look up.
14578///
14579/// @param tu the translation unit to perform lookup from.
14580///
14581/// @return the declaration of the enum type IR node found, NULL
14582/// otherwise.
14584lookup_enum_type_through_translation_units(const interned_string& type_name,
14585 const corpus & abi_corpus)
14586{
14587 enum_type_decl_sptr result;
14588
14589 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14590 for (translation_units::const_iterator tu =
14591 abi_corpus.get_translation_units().begin();
14592 tu != abi_corpus.get_translation_units().end();
14593 ++tu)
14594 if ((result = lookup_enum_type(type_name, **tu)))
14595 break;
14596
14597 return result;
14598}
14599
14600/// Lookup a typedef type definition in all the translation units of a
14601/// given ABI corpus.
14602///
14603/// @param @param qn the fully qualified name of the typedef type to lookup.
14604///
14605/// @param abi_corpus the ABI corpus which to look the type up in.
14606///
14607/// @return the type definition if any was found, or a NULL pointer.
14608static typedef_decl_sptr
14609lookup_typedef_type_through_translation_units(const interned_string& type_name,
14610 const corpus & abi_corpus)
14611{
14612 typedef_decl_sptr result;
14613
14614 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14615 for (translation_units::const_iterator tu =
14616 abi_corpus.get_translation_units().begin();
14617 tu != abi_corpus.get_translation_units().end();
14618 ++tu)
14619 if ((result = lookup_typedef_type(type_name, **tu)))
14620 break;
14621
14622 return result;
14623}
14624
14625/// Lookup a qualified type definition in all the translation units of a
14626/// given ABI corpus.
14627///
14628/// @param @param qn the fully qualified name of the qualified type to
14629/// lookup.
14630///
14631/// @param abi_corpus the ABI corpus which to look the type up in.
14632///
14633/// @return the type definition if any was found, or a NULL pointer.
14634static qualified_type_def_sptr
14635lookup_qualified_type_through_translation_units(const interned_string& t_name,
14636 const corpus & abi_corpus)
14637{
14638 qualified_type_def_sptr result;
14639
14640 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14641 for (translation_units::const_iterator tu =
14642 abi_corpus.get_translation_units().begin();
14643 tu != abi_corpus.get_translation_units().end();
14644 ++tu)
14645 if ((result = lookup_qualified_type(t_name, **tu)))
14646 break;
14647
14648 return result;
14649}
14650
14651/// Lookup a pointer type definition in all the translation units of a
14652/// given ABI corpus.
14653///
14654/// @param @param qn the fully qualified name of the pointer type to
14655/// lookup.
14656///
14657/// @param abi_corpus the ABI corpus which to look the type up in.
14658///
14659/// @return the type definition if any was found, or a NULL pointer.
14661lookup_pointer_type_through_translation_units(const interned_string& type_name,
14662 const corpus & abi_corpus)
14663{
14664 pointer_type_def_sptr result;
14665
14666 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14667 for (translation_units::const_iterator tu =
14668 abi_corpus.get_translation_units().begin();
14669 tu != abi_corpus.get_translation_units().end();
14670 ++tu)
14671 if ((result = lookup_pointer_type(type_name, **tu)))
14672 break;
14673
14674 return result;
14675}
14676
14677/// Lookup a reference type definition in all the translation units of a
14678/// given ABI corpus.
14679///
14680/// @param @param qn the fully qualified name of the reference type to
14681/// lookup.
14682///
14683/// @param abi_corpus the ABI corpus which to look the type up in.
14684///
14685/// @return the type definition if any was found, or a NULL pointer.
14687lookup_reference_type_through_translation_units(const interned_string& t_name,
14688 const corpus & abi_corpus)
14689{
14691
14692 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14693 for (translation_units::const_iterator tu =
14694 abi_corpus.get_translation_units().begin();
14695 tu != abi_corpus.get_translation_units().end();
14696 ++tu)
14697 if ((result = lookup_reference_type(t_name, **tu)))
14698 break;
14699
14700 return result;
14701}
14702
14703/// Lookup a array type definition in all the translation units of a
14704/// given ABI corpus.
14705///
14706/// @param @param qn the fully qualified name of the array type to
14707/// lookup.
14708///
14709/// @param abi_corpus the ABI corpus which to look the type up in.
14710///
14711/// @return the type definition if any was found, or a NULL pointer.
14713lookup_array_type_through_translation_units(const interned_string& type_name,
14714 const corpus & abi_corpus)
14715{
14716 array_type_def_sptr result;
14717
14718 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14719 for (translation_units::const_iterator tu =
14720 abi_corpus.get_translation_units().begin();
14721 tu != abi_corpus.get_translation_units().end();
14722 ++tu)
14723 if ((result = lookup_array_type(type_name, **tu)))
14724 break;
14725
14726 return result;
14727}
14728
14729/// Lookup a function type definition in all the translation units of
14730/// a given ABI corpus.
14731///
14732/// @param @param qn the fully qualified name of the function type to
14733/// lookup.
14734///
14735/// @param abi_corpus the ABI corpus which to look the type up in.
14736///
14737/// @return the type definition if any was found, or a NULL pointer.
14738static function_type_sptr
14739lookup_function_type_through_translation_units(const interned_string& type_name,
14740 const corpus & abi_corpus)
14741{
14742 function_type_sptr result;
14743
14744 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14745 for (translation_units::const_iterator tu =
14746 abi_corpus.get_translation_units().begin();
14747 tu != abi_corpus.get_translation_units().end();
14748 ++tu)
14749 if ((result = lookup_function_type(type_name, **tu)))
14750 break;
14751
14752 return result;
14753}
14754
14755/// Lookup a type definition in all the translation units of a given
14756/// ABI corpus.
14757///
14758/// @param @param qn the fully qualified name of the type to lookup.
14759///
14760/// @param abi_corpus the ABI corpus which to look the type up in.
14761///
14762/// @return the type definition if any was found, or a NULL pointer.
14763type_base_sptr
14765 const corpus& abi_corpus)
14766{
14767 type_base_sptr result;
14768
14769 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14770 for (translation_units::const_iterator tu =
14771 abi_corpus.get_translation_units().begin();
14772 tu != abi_corpus.get_translation_units().end();
14773 ++tu)
14774 if ((result = lookup_type(qn, **tu)))
14775 break;
14776
14777 return result;
14778}
14779
14780/// Lookup a type from a given translation unit present in a give corpus.
14781///
14782/// @param type_name the name of the type to look for.
14783///
14784/// @parm tu_path the path of the translation unit to consider.
14785///
14786/// @param corp the corpus to consider.
14787///
14788/// @return the resulting type, if any.
14789type_base_sptr
14791 const string& tu_path,
14792 const corpus& corp)
14793{
14794 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
14795 if (i == corp.priv_->path_tu_map.end())
14796 return type_base_sptr();
14797
14798 translation_unit_sptr tu = i->second;
14799 ABG_ASSERT(tu);
14800
14801 type_base_sptr t = lookup_type(type_name, *tu);
14802 return t;
14803}
14804
14805/// Look into an ABI corpus for a function type.
14806///
14807/// @param fn_type the function type to be looked for in the ABI
14808/// corpus.
14809///
14810/// @param corpus the ABI corpus into which to look for the function
14811/// type.
14812///
14813/// @return the function type found in the corpus.
14816 const corpus& corpus)
14817{
14818 ABG_ASSERT(fn_t);
14819
14820 function_type_sptr result;
14821
14822 lock_guard<recursive_mutex> lock(corpus.priv_->get_mutex());
14823 if ((result = lookup_function_type(fn_t, corpus)))
14824 return result;
14825
14826 for (translation_units::const_iterator i =
14827 corpus.get_translation_units().begin();
14828 i != corpus.get_translation_units().end();
14829 ++i)
14831 **i)))
14832 return result;
14833
14834 return result;
14835}
14836
14837/// Look into a given corpus to find a type which has the same
14838/// qualified name as a giventype.
14839///
14840/// If the per-corpus type map is non-empty (because the corpus allows
14841/// the One Definition Rule) then the type islooked up in that
14842/// per-corpus type map. Otherwise, the type is looked-up in each
14843/// translation unit.
14844///
14845/// @param t the type which has the same qualified name as the type we
14846/// are looking for.
14847///
14848/// @param corp the ABI corpus to look into for the type.
14850lookup_basic_type(const type_decl& t, const corpus& corp)
14851{return lookup_basic_type(t.get_name(), corp);}
14852
14853/// Look into a given corpus to find a basic type which has a given
14854/// qualified name.
14855///
14856/// If the per-corpus type map is non-empty (because the corpus allows
14857/// the One Definition Rule) then the type islooked up in that
14858/// per-corpus type map. Otherwise, the type is looked-up in each
14859/// translation unit.
14860///
14861/// @param qualified_name the qualified name of the basic type to look
14862/// for.
14863///
14864/// @param corp the corpus to look into.
14866lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
14867{
14869 type_decl_sptr result;
14870
14871 if (!m.empty())
14872 result = lookup_type_in_map<type_decl>(qualified_name, m);
14873 else
14874 result = lookup_basic_type_through_translation_units(qualified_name, corp);
14875
14876 return result;
14877}
14878
14879/// Lookup a @ref type_decl type from a given corpus, by its location.
14880///
14881/// @param loc the location to consider.
14882///
14883/// @param corp the corpus to consider.
14884///
14885/// @return the resulting basic type, if any.
14888 const corpus &corp)
14889{
14892 type_decl_sptr result;
14893
14894 result = lookup_type_in_map<type_decl>(loc, m);
14895
14896 return result;
14897}
14898
14899/// Lookup a @ref type_decl type from a given corpus, by its location.
14900///
14901/// @param loc the location to consider.
14902///
14903/// @param corp the corpus to consider.
14904///
14905/// @return the resulting basic type, if any.
14907lookup_basic_type_per_location(const string &loc, const corpus &corp)
14908{
14909 const environment& env = corp.get_environment();
14910 return lookup_basic_type_per_location(env.intern(loc), corp);
14911}
14912
14913/// Look into a given corpus to find a basic type which has a given
14914/// qualified name.
14915///
14916/// If the per-corpus type map is non-empty (because the corpus allows
14917/// the One Definition Rule) then the type islooked up in that
14918/// per-corpus type map. Otherwise, the type is looked-up in each
14919/// translation unit.
14920///
14921/// @param qualified_name the qualified name of the basic type to look
14922/// for.
14923///
14924/// @param corp the corpus to look into.
14926lookup_basic_type(const string& qualified_name, const corpus& corp)
14927{
14928 return lookup_basic_type(corp.get_environment().intern(qualified_name),
14929 corp);
14930}
14931
14932/// Look into a given corpus to find a class type which has the same
14933/// qualified name as a given type.
14934///
14935/// If the per-corpus type map is non-empty (because the corpus allows
14936/// the One Definition Rule) then the type islooked up in that
14937/// per-corpus type map. Otherwise, the type is looked-up in each
14938/// translation unit.
14939///
14940/// @param t the class decl type which has the same qualified name as
14941/// the type we are looking for.
14942///
14943/// @param corp the corpus to look into.
14946{
14948 return lookup_class_type(s, corp);
14949}
14950
14951/// Look into a given corpus to find a class type which has a given
14952/// qualified name.
14953///
14954/// If the per-corpus type map is non-empty (because the corpus allows
14955/// the One Definition Rule) then the type islooked up in that
14956/// per-corpus type map. Otherwise, the type is looked-up in each
14957/// translation unit.
14958///
14959/// @param qualified_name the qualified name of the type to look for.
14960///
14961/// @param corp the corpus to look into.
14963lookup_class_type(const string& qualified_name, const corpus& corp)
14964{
14965 interned_string s = corp.get_environment().intern(qualified_name);
14966 return lookup_class_type(s, corp);
14967}
14968
14969/// Look into a given corpus to find a class type which has a given
14970/// qualified name.
14971///
14972/// If the per-corpus type map is non-empty (because the corpus allows
14973/// the One Definition Rule) then the type islooked up in that
14974/// per-corpus type map. Otherwise, the type is looked-up in each
14975/// translation unit.
14976///
14977/// @param qualified_name the qualified name of the type to look for.
14978///
14979/// @param corp the corpus to look into.
14981lookup_class_type(const interned_string& qualified_name, const corpus& corp)
14982{
14984
14985 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
14986
14987 return result;
14988}
14989
14990/// Look into a given corpus to find the class type*s* that have a
14991/// given qualified name.
14992///
14993/// @param qualified_name the qualified name of the type to look for.
14994///
14995/// @param corp the corpus to look into.
14996///
14997/// @return the vector of class types named @p qualified_name.
14999lookup_class_types(const interned_string& qualified_name, const corpus& corp)
15000{
15002
15003 return lookup_types_in_map(qualified_name, m);
15004}
15005
15006/// Look into a given corpus to find the class type*s* that have a
15007/// given qualified name.
15008///
15009/// @param qualified_name the qualified name of the type to look for.
15010///
15011/// @param corp the corpus to look into.
15012///
15013/// @return the vector of class types named @p qualified_name.
15015lookup_class_types(const char* qualified_name, const corpus& corp)
15016{
15017 if (!qualified_name)
15018 return nullptr;
15019
15020 interned_string qname = corp.get_environment().intern(qualified_name);
15021 return lookup_class_types(qname, corp);
15022}
15023
15024/// Look into a given corpus to find the class type*s* that have a
15025/// given qualified name and that are declaration-only.
15026///
15027/// @param qualified_name the qualified name of the type to look for.
15028///
15029/// @param corp the corpus to look into.
15030///
15031/// @param result the vector of decl-only class types named @p
15032/// qualified_name. This is populated iff the function returns true.
15033///
15034/// @return true iff @p result was populated with the decl-only
15035/// classes named @p qualified_name.
15036bool
15038 const corpus& corp,
15039 type_base_wptrs_type& result)
15040{
15042
15043 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
15044 if (!v)
15045 return false;
15046
15047 for (auto type : *v)
15048 {
15049 type_base_sptr t(type);
15051 if (c->get_is_declaration_only()
15052 && !c->get_definition_of_declaration())
15053 result.push_back(type);
15054 }
15055
15056 return !result.empty();
15057}
15058
15059/// Look into a given corpus to find the union type*s* that have a
15060/// given qualified name.
15061///
15062/// @param qualified_name the qualified name of the type to look for.
15063///
15064/// @param corp the corpus to look into.
15065///
15066/// @return the vector of union types named @p qualified_name.
15068lookup_union_types(const interned_string& qualified_name, const corpus& corp)
15069{
15071
15072 return lookup_types_in_map(qualified_name, m);
15073}
15074
15075/// Look into a given corpus to find the class type*s* that have a
15076/// given qualified name.
15077///
15078/// @param qualified_name the qualified name of the type to look for.
15079///
15080/// @param corp the corpus to look into.
15081///
15082/// @return the vector of class types which name is @p qualified_name.
15084lookup_class_types(const string& qualified_name, const corpus& corp)
15085{
15086 interned_string s = corp.get_environment().intern(qualified_name);
15087 return lookup_class_types(s, corp);
15088}
15089
15090/// Look into a given corpus to find the union types that have a given
15091/// qualified name.
15092///
15093/// @param qualified_name the qualified name of the type to look for.
15094///
15095/// @param corp the corpus to look into.
15096///
15097/// @return the vector of union types which name is @p qualified_name.
15099lookup_union_types(const string& qualified_name, const corpus& corp)
15100{
15101 interned_string s = corp.get_environment().intern(qualified_name);
15102 return lookup_union_types(s, corp);
15103}
15104
15105/// Look up a @ref class_decl from a given corpus by its location.
15106///
15107/// @param loc the location to consider.
15108///
15109/// @param corp the corpus to consider.
15110///
15111/// @return the resulting class decl, if any.
15114 const corpus& corp)
15115{
15118 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
15119
15120 return result;
15121}
15122
15123/// Look up a @ref class_decl from a given corpus by its location.
15124///
15125/// @param loc the location to consider.
15126///
15127/// @param corp the corpus to consider.
15128///
15129/// @return the resulting class decl, if any.
15131lookup_class_type_per_location(const string &loc, const corpus &corp)
15132{
15133 const environment& env = corp.get_environment();
15134 return lookup_class_type_per_location(env.intern(loc), corp);
15135}
15136
15137/// Look into a given corpus to find a union type which has a given
15138/// qualified name.
15139///
15140/// If the per-corpus type map is non-empty (because the corpus allows
15141/// the One Definition Rule) then the type islooked up in that
15142/// per-corpus type map. Otherwise, the type is looked-up in each
15143/// translation unit.
15144///
15145/// @param qualified_name the qualified name of the type to look for.
15146///
15147/// @param corp the corpus to look into.
15148union_decl_sptr
15149lookup_union_type(const interned_string& type_name, const corpus& corp)
15150{
15152
15153 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
15154 if (!result)
15155 result = lookup_union_type_through_translation_units(type_name, corp);
15156
15157 return result;
15158}
15159
15160/// Look into a given corpus to find a union type which has a given
15161/// qualified name.
15162///
15163/// If the per-corpus type map is non-empty (because the corpus allows
15164/// the One Definition Rule) then the type islooked up in that
15165/// per-corpus type map. Otherwise, the type is looked-up in each
15166/// translation unit.
15167///
15168/// @param qualified_name the qualified name of the type to look for.
15169///
15170/// @param corp the corpus to look into.
15171union_decl_sptr
15172lookup_union_type(const string& type_name, const corpus& corp)
15173{
15174 interned_string s = corp.get_environment().intern(type_name);
15175 return lookup_union_type(s, corp);
15176}
15177
15178/// Look into a given corpus to find an enum type which has the same
15179/// qualified name as a given enum type.
15180///
15181/// If the per-corpus type map is non-empty (because the corpus allows
15182/// the One Definition Rule) then the type islooked up in that
15183/// per-corpus type map. Otherwise, the type is looked-up in each
15184/// translation unit.
15185///
15186/// @param t the enum type which has the same qualified name as the
15187/// type we are looking for.
15188///
15189/// @param corp the corpus to look into.
15192{
15194 return lookup_enum_type(s, corp);
15195}
15196
15197/// Look into a given corpus to find an enum type which has a given
15198/// qualified name.
15199///
15200/// If the per-corpus type map is non-empty (because the corpus allows
15201/// the One Definition Rule) then the type islooked up in that
15202/// per-corpus type map. Otherwise, the type is looked-up in each
15203/// translation unit.
15204///
15205/// @param qualified_name the qualified name of the enum type to look
15206/// for.
15207///
15208/// @param corp the corpus to look into.
15210lookup_enum_type(const string& qualified_name, const corpus& corp)
15211{
15212 interned_string s = corp.get_environment().intern(qualified_name);
15213 return lookup_enum_type(s, corp);
15214}
15215
15216/// Look into a given corpus to find an enum type which has a given
15217/// qualified name.
15218///
15219/// If the per-corpus type map is non-empty (because the corpus allows
15220/// the One Definition Rule) then the type islooked up in that
15221/// per-corpus type map. Otherwise, the type is looked-up in each
15222/// translation unit.
15223///
15224/// @param qualified_name the qualified name of the enum type to look
15225/// for.
15226///
15227/// @param corp the corpus to look into.
15229lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
15230{
15232
15233 enum_type_decl_sptr result =
15234 lookup_type_in_map<enum_type_decl>(qualified_name, m);
15235 if (!result)
15236 result = lookup_enum_type_through_translation_units(qualified_name, corp);
15237
15238 return result;
15239}
15240
15241/// Look into a given corpus to find the enum type*s* that have a
15242/// given qualified name.
15243///
15244/// @param qualified_name the qualified name of the type to look for.
15245///
15246/// @param corp the corpus to look into.
15247///
15248/// @return the vector of enum types that which name is @p qualified_name.
15250lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
15251{
15253
15254 return lookup_types_in_map(qualified_name, m);
15255}
15256
15257/// Look into a given corpus to find the enum type*s* that have a
15258/// given qualified name.
15259///
15260/// @param qualified_name the qualified name of the type to look for.
15261///
15262/// @param corp the corpus to look into.
15263///
15264/// @return the vector of enum types that which name is @p qualified_name.
15266lookup_enum_types(const string& qualified_name, const corpus& corp)
15267{
15268 interned_string s = corp.get_environment().intern(qualified_name);
15269 return lookup_enum_types(s, corp);
15270}
15271
15272/// Look into a given corpus to find the enum type*s* that have a
15273/// given qualified name.
15274///
15275/// @param qualified_name the qualified name of the type to look for.
15276///
15277/// @param corp the corpus to look into.
15278///
15279/// @return the vector of enum types that which name is @p qualified_name.
15281lookup_enum_types(char* qualified_name, const corpus& corp)
15282{
15283 if (!qualified_name)
15284 return nullptr;
15285
15286 string qname(qualified_name);
15287 return lookup_enum_types(qname, corp);
15288}
15289
15290/// Look up an @ref enum_type_decl from a given corpus, by its location.
15291///
15292/// @param loc the location to consider.
15293///
15294/// @param corp the corpus to look the type from.
15295///
15296/// @return the resulting enum type, if any.
15299{
15302 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
15303
15304 return result;
15305}
15306
15307/// Look up an @ref enum_type_decl from a given corpus, by its location.
15308///
15309/// @param loc the location to consider.
15310///
15311/// @param corp the corpus to look the type from.
15312///
15313/// @return the resulting enum type, if any.
15315lookup_enum_type_per_location(const string &loc, const corpus &corp)
15316{
15317 const environment& env = corp.get_environment();
15318 return lookup_enum_type_per_location(env.intern(loc), corp);
15319}
15320
15321/// Look into a given corpus to find a typedef type which has the
15322/// same qualified name as a given typedef type.
15323///
15324/// If the per-corpus type map is non-empty (because the corpus allows
15325/// the One Definition Rule) then the type islooked up in that
15326/// per-corpus type map. Otherwise, the type is looked-up in each
15327/// translation unit.
15328///
15329/// @param t the typedef type which has the same qualified name as the
15330/// typedef type we are looking for.
15331///
15332/// @param corp the corpus to look into.
15335{
15337 return lookup_typedef_type(s, corp);
15338}
15339
15340/// Look into a given corpus to find a typedef type which has the
15341/// same qualified name as a given typedef type.
15342///
15343/// If the per-corpus type map is non-empty (because the corpus allows
15344/// the One Definition Rule) then the type islooked up in that
15345/// per-corpus type map. Otherwise, the type is looked-up in each
15346/// translation unit.
15347///
15348/// @param t the typedef type which has the same qualified name as the
15349/// typedef type we are looking for.
15350///
15351/// @param corp the corpus to look into.
15353lookup_typedef_type(const string& qualified_name, const corpus& corp)
15354{
15355 interned_string s = corp.get_environment().intern(qualified_name);
15356 return lookup_typedef_type(s, corp);
15357}
15358
15359/// Look into a given corpus to find a typedef type which has a
15360/// given qualified name.
15361///
15362/// If the per-corpus type map is non-empty (because the corpus allows
15363/// the One Definition Rule) then the type islooked up in that
15364/// per-corpus type map. Otherwise, the type is looked-up in each
15365/// translation unit.
15366///
15367/// @param qualified_name the qualified name of the typedef type to
15368/// look for.
15369///
15370/// @param corp the corpus to look into.
15372lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
15373{
15375
15376 typedef_decl_sptr result =
15377 lookup_type_in_map<typedef_decl>(qualified_name, m);
15378 if (!result)
15379 result = lookup_typedef_type_through_translation_units(qualified_name,
15380 corp);
15381
15382 return result;
15383}
15384
15386lookup_typedef_types(const string& name, const corpus& corp)
15387{
15389 interned_string n = corp.get_environment().intern(name);
15390 return lookup_types_in_map(n, m);
15391}
15392
15394lookup_typedef_types(char* name, const corpus& corp)
15395{
15396 if (!name)
15397 return nullptr;
15398
15399 string n(name);
15400 return lookup_typedef_types(n, corp);
15401}
15402
15403/// Lookup a @ref typedef_decl from a corpus, by its location.
15404///
15405/// @param loc the location to consider.
15406///
15407/// @param corp the corpus to consider.
15408///
15409/// @return the typedef_decl found, if any.
15412{
15415 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
15416
15417 return result;
15418}
15419
15420/// Lookup a @ref typedef_decl from a corpus, by its location.
15421///
15422/// @param loc the location to consider.
15423///
15424/// @param corp the corpus to consider.
15425///
15426/// @return the typedef_decl found, if any.
15428lookup_typedef_type_per_location(const string &loc, const corpus &corp)
15429{
15430 const environment& env = corp.get_environment();
15431 return lookup_typedef_type_per_location(env.intern(loc), corp);
15432}
15433
15434/// Look into a corpus to find a class, union or typedef type which
15435/// has a given qualified name.
15436///
15437/// If the per-corpus type map is non-empty (because the corpus allows
15438/// the One Definition Rule) then the type islooked up in that
15439/// per-corpus type map. Otherwise, the type is looked-up in each
15440/// translation unit.
15441///
15442/// @param qualified_name the name of the type to find.
15443///
15444/// @param corp the corpus to look into.
15445///
15446/// @return the typedef or class type found.
15447type_base_sptr
15448lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
15449{
15450 type_base_sptr result = lookup_type<class_decl>(qualified_name, corp);
15451 if (!result)
15452 result = lookup_type<union_decl>(qualified_name, corp);
15453
15454 if (!result)
15455 result = lookup_type<typedef_decl>(qualified_name, corp);
15456 return result;
15457}
15458
15459/// Look into a corpus to find a class, typedef or enum type which has
15460/// a given qualified name.
15461///
15462/// If the per-corpus type map is non-empty (because the corpus allows
15463/// the One Definition Rule) then the type islooked up in that
15464/// per-corpus type map. Otherwise, the type is looked-up in each
15465/// translation unit.
15466///
15467/// @param qualified_name the qualified name of the type to look for.
15468///
15469/// @param corp the corpus to look into.
15470///
15471/// @return the typedef, class or enum type found.
15472type_base_sptr
15473lookup_class_typedef_or_enum_type(const string& qualified_name,
15474 const corpus& corp)
15475{
15476 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
15477 if (!result)
15478 result = lookup_enum_type(qualified_name, corp);
15479
15480 return result;
15481}
15482
15483/// Look into a given corpus to find a qualified type which has the
15484/// same qualified name as a given type.
15485///
15486/// @param t the type which has the same qualified name as the
15487/// qualified type we are looking for.
15488///
15489/// @param corp the corpus to look into.
15490///
15491/// @return the qualified type found.
15492qualified_type_def_sptr
15494{
15496 return lookup_qualified_type(s, corp);
15497}
15498
15499/// Look into a given corpus to find a qualified type which has a
15500/// given qualified name.
15501///
15502/// @param qualified_name the qualified name of the type to look for.
15503///
15504/// @param corp the corpus to look into.
15505///
15506/// @return the type found.
15507qualified_type_def_sptr
15508lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
15509{
15511 corp.get_types().qualified_types();
15512
15513 qualified_type_def_sptr result =
15514 lookup_type_in_map<qualified_type_def>(qualified_name, m);
15515
15516 if (!result)
15517 result = lookup_qualified_type_through_translation_units(qualified_name,
15518 corp);
15519
15520 return result;
15521}
15522
15523/// Look into a given corpus to find a pointer type which has the same
15524/// qualified name as a given pointer type.
15525///
15526/// @param t the pointer type which has the same qualified name as the
15527/// type we are looking for.
15528///
15529/// @param corp the corpus to look into.
15530///
15531/// @return the pointer type found.
15534{
15536 return lookup_pointer_type(s, corp);
15537}
15538
15539/// Look into a given corpus to find a pointer type which has a given
15540/// qualified name.
15541///
15542/// If the per-corpus type map is non-empty (because the corpus allows
15543/// the One Definition Rule) then the type islooked up in that
15544/// per-corpus type map. Otherwise, the type is looked-up in each
15545/// translation unit.
15546///
15547/// @param qualified_name the qualified name of the pointer type to
15548/// look for.
15549///
15550/// @param corp the corpus to look into.
15551///
15552/// @return the pointer type found.
15554lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
15555{
15557
15558 pointer_type_def_sptr result =
15559 lookup_type_in_map<pointer_type_def>(qualified_name, m);
15560 if (!result)
15561 result = lookup_pointer_type_through_translation_units(qualified_name,
15562 corp);
15563
15564 return result;
15565}
15566
15567/// Look into a given corpus to find a reference type which has the
15568/// same qualified name as a given reference type.
15569///
15570/// If the per-corpus type map is non-empty (because the corpus allows
15571/// the One Definition Rule) then the type islooked up in that
15572/// per-corpus type map. Otherwise, the type is looked-up in each
15573/// translation unit.
15574///
15575/// @param t the reference type which has the same qualified name as
15576/// the reference type we are looking for.
15577///
15578/// @param corp the corpus to look into.
15579///
15580/// @return the reference type found.
15583{
15585 return lookup_reference_type(s, corp);
15586}
15587
15588/// Look into a given corpus to find a reference type which has a
15589/// given qualified name.
15590///
15591/// If the per-corpus type map is non-empty (because the corpus allows
15592/// the One Definition Rule) then the type islooked up in that
15593/// per-corpus type map. Otherwise, the type is looked-up in each
15594/// translation unit.
15595///
15596/// @param qualified_name the qualified name of the reference type to
15597/// look for.
15598///
15599/// @param corp the corpus to look into.
15600///
15601/// @return the reference type found.
15603lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
15604{
15606 corp.get_types().reference_types();
15607
15609 lookup_type_in_map<reference_type_def>(qualified_name, m);
15610 if (!result)
15611 result = lookup_reference_type_through_translation_units(qualified_name,
15612 corp);
15613
15614 return result;
15615}
15616
15617/// Look into a given corpus to find an array type which has a given
15618/// qualified name.
15619///
15620/// If the per-corpus type map is non-empty (because the corpus allows
15621/// the One Definition Rule) then the type islooked up in that
15622/// per-corpus type map. Otherwise, the type is looked-up in each
15623/// translation unit.
15624///
15625/// @param qualified_name the qualified name of the array type to look
15626/// for.
15627///
15628/// @param corp the corpus to look into.
15629///
15630/// @return the array type found.
15633{
15635 return lookup_array_type(s, corp);
15636}
15637
15638/// Look into a given corpus to find an array type which has the same
15639/// qualified name as a given array type.
15640///
15641/// If the per-corpus type map is non-empty (because the corpus allows
15642/// the One Definition Rule) then the type islooked up in that
15643/// per-corpus type map. Otherwise, the type is looked-up in each
15644/// translation unit.
15645///
15646/// @param t the type which has the same qualified name as the type we
15647/// are looking for.
15648///
15649/// @param corp the corpus to look into.
15650///
15651/// @return the type found.
15653lookup_array_type(const interned_string& qualified_name, const corpus& corp)
15654{
15656
15657 array_type_def_sptr result =
15658 lookup_type_in_map<array_type_def>(qualified_name, m);
15659 if (!result)
15660 result = lookup_array_type_through_translation_units(qualified_name, corp);
15661
15662 return result;
15663}
15664
15665/// Look into a given corpus to find a function type which has the same
15666/// qualified name as a given function type.
15667///
15668/// If the per-corpus type map is non-empty (because the corpus allows
15669/// the One Definition Rule) then the type islooked up in that
15670/// per-corpus type map. Otherwise, the type is looked-up in each
15671/// translation unit.
15672///
15673/// @param t the function type which has the same qualified name as
15674/// the function type we are looking for.
15675///
15676/// @param corp the corpus to look into.
15677///
15678/// @return the function type found.
15681{
15682 interned_string type_name = get_type_name(t);
15683 return lookup_function_type(type_name, corp);
15684}
15685
15686/// Look into a given corpus to find a function type which has the same
15687/// qualified name as a given function type.
15688///
15689/// If the per-corpus type map is non-empty (because the corpus allows
15690/// the One Definition Rule) then the type islooked up in that
15691/// per-corpus type map. Otherwise, the type is looked-up in each
15692/// translation unit.
15693///
15694/// @param t the function type which has the same qualified name as
15695/// the function type we are looking for.
15696///
15697/// @param corp the corpus to look into.
15698///
15699/// @return the function type found.
15702 const corpus& corpus)
15703{
15704 if (fn_t)
15705 return lookup_function_type(*fn_t, corpus);
15706 return function_type_sptr();
15707}
15708
15709/// Look into a given corpus to find a function type which has a given
15710/// qualified name.
15711///
15712/// If the per-corpus type map is non-empty (because the corpus allows
15713/// the One Definition Rule) then the type islooked up in that
15714/// per-corpus type map. Otherwise, the type is looked-up in each
15715/// translation unit.
15716///
15717/// @param qualified_name the qualified name of the function type to
15718/// look for.
15719///
15720/// @param corp the corpus to look into.
15721///
15722/// @return the function type found.
15724lookup_function_type(const interned_string& qualified_name, const corpus& corp)
15725{
15727
15728 function_type_sptr result =
15729 lookup_type_in_map<function_type>(qualified_name, m);
15730 if (!result)
15731 result = lookup_function_type_through_translation_units(qualified_name,
15732 corp);
15733
15734 return result;
15735}
15736
15737/// Look into a given corpus to find a type which has a given
15738/// qualified name.
15739///
15740/// If the per-corpus type map is non-empty (because the corpus allows
15741/// the One Definition Rule) then the type islooked up in that
15742/// per-corpus type map. Otherwise, the type is looked-up in each
15743/// translation unit.
15744///
15745/// @param qualified_name the qualified name of the function type to
15746/// look for.
15747///
15748/// @param corp the corpus to look into.
15749///
15750/// @return the function type found.
15751type_base_sptr
15752lookup_type(const interned_string& n, const corpus& corp)
15753{
15754 type_base_sptr result;
15755
15756 ((result = lookup_basic_type(n, corp))
15757 || (result = lookup_class_type(n, corp))
15758 || (result = lookup_union_type(n, corp))
15759 || (result = lookup_enum_type(n, corp))
15760 || (result = lookup_typedef_type(n, corp))
15761 || (result = lookup_qualified_type(n, corp))
15762 || (result = lookup_pointer_type(n, corp))
15763 || (result = lookup_reference_type(n, corp))
15764 || (result = lookup_array_type(n, corp))
15765 || (result= lookup_function_type(n, corp)));
15766
15767 return result;
15768}
15769
15770type_base_sptr
15771lookup_type(const string& name, const corpus& corp)
15772{
15773 interned_string n = corp.get_environment().intern(name);
15774 return lookup_type(n, corp);
15775}
15776
15777type_base_sptr
15778lookup_type(char* name, const corpus& corp)
15779{
15780 if (!name)
15781 return nullptr;
15782 string n(name);
15783 interned_string i = corp.get_environment().intern(n);
15784 return lookup_type(i, corp);
15785}
15786
15787/// Lookup a type from a corpus, by its location.
15788///
15789/// @param loc the location to consider.
15790///
15791/// @param corp the corpus to look the type from.
15792///
15793/// @return the resulting type, if any found.
15794type_base_sptr
15796{
15797 // TODO: finish this.
15798
15799 //TODO: when we fully support types indexed by their location, this
15800 //function should return a vector of types because at each location,
15801 //there can be several types that are defined (yay, C and C++,
15802 //*sigh*).
15803
15804 type_base_sptr result;
15805 ((result = lookup_basic_type_per_location(loc, corp))
15806 || (result = lookup_class_type_per_location(loc, corp))
15807 || (result = lookup_union_type_per_location(loc, corp))
15808 || (result = lookup_enum_type_per_location(loc, corp))
15809 || (result = lookup_typedef_type_per_location(loc, corp)));
15810
15811 return result;
15812}
15813
15814/// Look into a given corpus to find a type
15815///
15816/// If the per-corpus type map is non-empty (because the corpus allows
15817/// the One Definition Rule) then the type islooked up in that
15818/// per-corpus type map. Otherwise, the type is looked-up in each
15819/// translation unit.
15820///
15821/// @param qualified_name the qualified name of the function type to
15822/// look for.
15823///
15824/// @param corp the corpus to look into.
15825///
15826/// @return the function type found.
15827type_base_sptr
15828lookup_type(const type_base&t, const corpus& corp)
15829{
15831 return lookup_type(n, corp);
15832}
15833
15834/// Look into a given corpus to find a type
15835///
15836/// If the per-corpus type map is non-empty (because the corpus allows
15837/// the One Definition Rule) then the type islooked up in that
15838/// per-corpus type map. Otherwise, the type is looked-up in each
15839/// translation unit.
15840///
15841/// @param qualified_name the qualified name of the function type to
15842/// look for.
15843///
15844/// @param corp the corpus to look into.
15845///
15846/// @return the function type found.
15847type_base_sptr
15848lookup_type(const type_base_sptr&t, const corpus& corp)
15849{
15850 if (t)
15851 return lookup_type(*t, corp);
15852 return type_base_sptr();
15853}
15854
15855template<typename TypeKind>
15856bool
15857update_type_lookup_map(istring_type_base_wptrs_map_type& types_map,
15858 interned_string key,
15859 const shared_ptr<TypeKind> type,
15860 recursive_mutex& mutex)
15861{
15862 bool result = false;
15863
15864 lock_guard<recursive_mutex> lock(mutex);
15865 istring_type_base_wptrs_map_type::iterator i = types_map.find(key);
15866
15867 if (i == types_map.end())
15868 {
15869 types_map[key].push_back(type);
15870 result = true;
15871 }
15872 else
15873 i->second.push_back(type);
15874
15875 return result;
15876}
15877
15878/// Update the map that associates a fully qualified name of a given
15879/// type to that type.
15880///
15881///
15882/// @param type the type we are considering.
15883///
15884/// @param types_map the map to update. It's a map that assciates a
15885/// fully qualified name of a type to the type itself.
15886///
15887/// @param use_type_name_as_key if true, use the name of the type as
15888/// the key to look it up later. If false, then use the location of
15889/// the type as a key to look it up later.
15890///
15891/// @return true iff the type was added to the map.
15892template<typename TypeKind>
15893bool
15894maybe_update_types_lookup_map(const shared_ptr<TypeKind> type,
15896 recursive_mutex& mutex,
15897 bool use_type_name_as_key = true)
15898{
15900
15901 if (use_type_name_as_key)
15902 s = get_type_name(type);
15903 else if (location l = get_location(type))
15904 {
15905 string str = l.expand();
15906 s = type->get_environment().intern(str);
15907 }
15908
15909 s = get_type_name(type);
15910 bool result = false;
15911 result |= update_type_lookup_map(types_map, s, type, mutex);
15912 string repr = abigail::ir::get_pretty_representation(type, /*internal=*/false);
15913 s = type->get_environment().intern(repr);
15914 result |= update_type_lookup_map(types_map, s, type, mutex);
15915
15916 return result;
15917}
15918
15919/// This is the specialization for type @ref class_decl of the
15920/// function template:
15921///
15922/// maybe_update_types_lookup_map<T>(scope_decl*,
15923/// const shared_ptr<T>&,
15924/// istring_type_base_wptrs_map_type&)
15925///
15926/// @param class_type the type to consider.
15927///
15928/// @param types_map the type map to update.
15929///
15930/// @return true iff the type was added to the map.
15931template<>
15932bool
15935 recursive_mutex& mutex,
15936 bool use_type_name_as_key)
15937{
15938 class_decl_sptr type = class_type;
15939
15940 bool update_qname_map = true;
15941 if (type->get_is_declaration_only())
15942 {
15943 // Let's try to look through decl-only classes to get their
15944 // definition. But if the class doesn't have a definition then
15945 // we'll keep it.
15946 if (class_decl_sptr def =
15947 is_class_type(class_type->get_definition_of_declaration()))
15948 type = def;
15949 }
15950
15951 if (!update_qname_map)
15952 return false;
15953
15955 if (use_type_name_as_key)
15956 {
15957 string qname = type->get_qualified_name();
15958 s = type->get_environment().intern(qname);
15959 }
15960 else if (location l = type->get_location())
15961 {
15962 string str = l.expand();
15963 s = type->get_environment().intern(str);
15964 }
15965
15966 return update_type_lookup_map(map, s, type, mutex);
15967}
15968
15969/// This is the specialization for type @ref function_type of the
15970/// function template:
15971///
15972/// maybe_update_types_lookup_map<T>(scope_decl*,
15973/// const shared_ptr<T>&,
15974/// istring_type_base_wptrs_map_type&)
15975///
15976/// @param scope the scope of the type to consider.
15977///
15978/// @param class_type the type to consider.
15979///
15980/// @param types_map the type map to update.
15981///
15982/// @return true iff the type was added to the map.
15983template<>
15984bool
15986(const function_type_sptr type,
15988 recursive_mutex& mutex,
15989 bool /*use_type_name_as_key*/)
15990{
15992 return update_type_lookup_map(types_map, s, type, mutex);
15993}
15994
15995/// Update the map that associates the fully qualified name of a type
15996/// type with the type itself.
15997///
15998/// The per-translation unit type map is updated.
15999///
16000/// The per-corpus type map is updated as well.
16001///
16002/// @param type the type to update in the map.
16003template <typename TypeArtifact>
16004void
16005maybe_update_types_lookup_map(const shared_ptr<TypeArtifact> type)
16006{
16007 if (translation_unit *tu = type->get_translation_unit())
16008 if (auto m = tu->get_types().get_type_map(typeid(*type.get())))
16009 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16010 tu->priv_->types_mutex_);
16011
16012 if (corpus *c = type->get_corpus())
16013 {
16014 if (auto m = c->priv_->get_types().get_type_map(typeid(*type.get())))
16015 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16016 c->priv_->get_mutex());
16017
16018 if (auto m = c->get_type_per_loc_map().get_type_map(typeid(*type.get())))
16019 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16020 c->priv_->get_mutex(),
16021 /*use_type_name_as_key*/false);
16022
16023 if (corpus *g = c->get_group())
16024 {
16025 if (auto m = g->priv_->get_types().get_type_map(typeid(*type.get())))
16026 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16027 c->priv_->get_mutex());
16028
16029 if (auto m = g->get_type_per_loc_map().get_type_map(typeid(*type.get())))
16030 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16031 c->priv_->get_mutex(),
16032 /*use_type_name_as_key*/false);
16033 }
16034 }
16035}
16036
16037/// Update the map that associates the fully qualified name of a type
16038/// declaration with the type itself.
16039///
16040/// @param decl the declaration of the type to consider.
16041void
16042maybe_update_types_lookup_map(const decl_base_sptr decl)
16043{
16044 type_base_sptr type = is_type(decl);
16045 if (!type)
16046 return;
16047
16048 maybe_update_types_lookup_map<type_base>(type);
16049}
16050
16051//--------------------------------
16052// </type and decls lookup stuff>
16053// ------------------------------
16054
16055/// In a translation unit, lookup a given type or synthesize it if
16056/// it's a qualified type.
16057///
16058/// So this function first looks the type up in the translation unit.
16059/// If it's found, then OK, it's returned. Otherwise, if it's a
16060/// qualified, reference or pointer or function type (a composite
16061/// type), lookup the underlying type, synthesize the type we want
16062/// from it and return it.
16063///
16064/// If the underlying types is not not found, then give up and return
16065/// nil.
16066///
16067/// @return the type that was found or the synthesized type.
16068type_base_sptr
16069synthesize_type_from_translation_unit(const type_base_sptr& type,
16070 translation_unit& tu)
16071{
16072 type_base_sptr result;
16073
16074 result = lookup_type(type, tu);
16075
16076 if (!result)
16077 {
16078 if (qualified_type_def_sptr qual = is_qualified_type(type))
16079 {
16080 type_base_sptr underlying_type =
16081 synthesize_type_from_translation_unit(qual->get_underlying_type(),
16082 tu);
16083 if (underlying_type)
16084 {
16085 result.reset(new qualified_type_def(underlying_type,
16086 qual->get_cv_quals(),
16087 qual->get_location()));
16088 }
16089 }
16090 else if (pointer_type_def_sptr p = is_pointer_type(type))
16091 {
16092 type_base_sptr pointed_to_type =
16093 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
16094 tu);
16095 if (pointed_to_type)
16096 {
16097 result.reset(new pointer_type_def(pointed_to_type,
16098 p->get_size_in_bits(),
16099 p->get_alignment_in_bits(),
16100 p->get_location()));
16101 }
16102 }
16103 else if (reference_type_def_sptr r = is_reference_type(type))
16104 {
16105 type_base_sptr pointed_to_type =
16106 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
16107 if (pointed_to_type)
16108 {
16109 result.reset(new reference_type_def(pointed_to_type,
16110 r->is_lvalue(),
16111 r->get_size_in_bits(),
16112 r->get_alignment_in_bits(),
16113 r->get_location()));
16114 }
16115 }
16116 else if (function_type_sptr f = is_function_type(type))
16118
16119 if (result)
16120 {
16123 }
16124 }
16125
16126 if (result)
16127 tu.priv_->synthesized_types_.push_back(result);
16128
16129 return result;
16130}
16131
16132/// In a translation unit, lookup the sub-types that make up a given
16133/// function type and if the sub-types are all found, synthesize and
16134/// return a function_type with them.
16135///
16136/// This function is like lookup_function_type_in_translation_unit()
16137/// execept that it constructs the function type from the sub-types
16138/// found in the translation, rather than just looking for the
16139/// function types held by the translation unit. This can be useful
16140/// if the translation unit doesnt hold the function type we are
16141/// looking for (i.e, lookup_function_type_in_translation_unit()
16142/// returned NULL) but we still want to see if the sub-types of the
16143/// function types are present in the translation unit.
16144///
16145/// @param fn_type the function type to consider.
16146///
16147/// @param tu the translation unit to look into.
16148///
16149/// @return the resulting synthesized function type if all its
16150/// sub-types have been found, NULL otherwise.
16153 translation_unit& tu)
16154{
16156
16157 const environment& env = tu.get_environment();
16158
16159 type_base_sptr return_type = fn_type.get_return_type();
16160 type_base_sptr result_return_type;
16161 if (!return_type || env.is_void_type(return_type))
16162 result_return_type = env.get_void_type();
16163 else
16164 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
16165 if (!result_return_type)
16166 return nil;
16167
16169 type_base_sptr parm_type;
16171 for (function_type::parameters::const_iterator i =
16172 fn_type.get_parameters().begin();
16173 i != fn_type.get_parameters().end();
16174 ++i)
16175 {
16176 type_base_sptr t = (*i)->get_type();
16177 parm_type = synthesize_type_from_translation_unit(t, tu);
16178 if (!parm_type)
16179 return nil;
16180 parm.reset(new function_decl::parameter(parm_type,
16181 (*i)->get_index(),
16182 (*i)->get_name(),
16183 (*i)->get_location(),
16184 (*i)->get_variadic_marker(),
16185 (*i)->get_is_artificial()));
16186 parms.push_back(parm);
16187 }
16188
16189 class_or_union_sptr class_type;
16190 const method_type* method = is_method_type(&fn_type);
16191 if (method)
16192 {
16193 class_type = is_class_or_union_type
16195 ABG_ASSERT(class_type);
16196 }
16197
16198 function_type_sptr result_fn_type;
16199
16200 if (class_type)
16201 result_fn_type.reset(new method_type(result_return_type,
16202 class_type,
16203 parms,
16204 method->get_is_const(),
16205 fn_type.get_size_in_bits(),
16206 fn_type.get_alignment_in_bits()));
16207 else
16208 result_fn_type.reset(new function_type(result_return_type,
16209 parms,
16210 fn_type.get_size_in_bits(),
16211 fn_type.get_alignment_in_bits()));
16212
16213 tu.priv_->synthesized_types_.push_back(result_fn_type);
16214 tu.bind_function_type_life_time(result_fn_type);
16215
16216 homonym_type_group_sptr group = fn_type.type_base::priv_->group.lock();
16217 hash_and_canonicalize_type(result_fn_type);
16218 return result_fn_type;
16219}
16220
16221/// Demangle a C++ mangled name and return the resulting string
16222///
16223/// @param mangled_name the C++ mangled name to demangle.
16224///
16225/// @return the resulting mangled name.
16226string
16227demangle_cplus_mangled_name(const string& mangled_name)
16228{
16229 if (mangled_name.empty())
16230 return "";
16231
16232 size_t l = 0;
16233 int status = 0;
16234 char * str = abi::__cxa_demangle(mangled_name.c_str(),
16235 NULL, &l, &status);
16236 string demangled_name = mangled_name;
16237 if (str)
16238 {
16239 ABG_ASSERT(status == 0);
16240 demangled_name = str;
16241 free(str);
16242 str = 0;
16243 }
16244 return demangled_name;
16245}
16246
16247/// Return either the type given in parameter if it's non-null, or the
16248/// void type.
16249///
16250/// @param t the type to consider.
16251///
16252/// @param env the environment to use. If NULL, just abort the
16253/// process.
16254///
16255/// @return either @p t if it is non-null, or the void type.
16256type_base_sptr
16257type_or_void(const type_base_sptr t, const environment& env)
16258{
16259 type_base_sptr r;
16260
16261 if (t)
16262 r = t;
16263 else
16264 r = type_base_sptr(env.get_void_type());
16265
16266 return r;
16267}
16268
16269global_scope::~global_scope()
16270{
16271}
16272
16273/// Test if two decls have at least of naming typedef with the same
16274/// name in common.
16275///
16276/// @param d1 the first decl to consider.
16277///
16278/// @param d2 the second decl to consider.
16279///
16280/// @return iff the two decls have at least one naming typedef with the
16281/// same name in common.
16282static bool
16283decls_have_naming_typedefs_same_name(decl_base& d1, decl_base& d2)
16284{
16285 for (auto typedef1 : d1.get_naming_typedefs())
16286 for (auto typedef2 : d2.get_naming_typedefs())
16287 if (typedef1->get_name() == typedef2->get_name())
16288 return true;
16289
16290 return false;
16291}
16292
16293/// Test if two types are eligible to the "Linux Kernel Fast Type
16294/// Comparison Optimization", a.k.a LKFTCO.
16295///
16296/// Two types T1 and T2 (who are presumably of the same name and kind)
16297/// are eligible to the LKFTCO if they fulfill the following criteria/
16298///
16299/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
16300/// either class, union or enums.
16301///
16302/// 2/ They are defined in the same translation unit.
16303///
16304/// @param t1 the first type to consider.
16305///
16306/// @param t2 the second type to consider.
16307///
16308/// @return true iff t1 and t2 are eligible to the LKFTCO.
16309static bool
16310types_defined_same_linux_kernel_corpus_public(const type_base& t1,
16311 const type_base& t2)
16312{
16313 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
16314 string t1_file_path, t2_file_path;
16315
16316 /// If the t1 (and t2) are classes/unions/enums from the same linux
16317 /// kernel corpus, let's move on. Otherwise bail out.
16318 if (!(t1_corpus && t2_corpus
16319 && t1_corpus == t2_corpus
16320 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
16321 && (is_class_or_union_type(&t1)
16322 || is_enum_type(&t1))))
16323 return false;
16324
16325 class_or_union *c1 = 0, *c2 = 0;
16326 c1 = is_class_or_union_type(&t1);
16327 c2 = is_class_or_union_type(&t2);
16328
16329 // Two anonymous class types with no naming typedefs cannot be
16330 // eligible to this optimization.
16331 if ((c1 && c1->get_is_anonymous() && c1->get_naming_typedefs().empty())
16332 || (c2 && c2->get_is_anonymous() && c2->get_naming_typedefs().empty()))
16333 return false;
16334
16335 // Two anonymous classes with naming typedefs should have the same
16336 // typedef name.
16337 if (c1
16338 && c2
16339 && c1->get_is_anonymous() && !c1->get_naming_typedefs().empty()
16340 && c2->get_is_anonymous() && !c2->get_naming_typedefs().empty())
16341 if (!decls_have_naming_typedefs_same_name(*c1, *c2))
16342 return false;
16343
16344 // Two anonymous enum types cannot be eligible to this optimization.
16345 if (const enum_type_decl *e1 = is_enum_type(&t1))
16346 if (const enum_type_decl *e2 = is_enum_type(&t2))
16347 if (e1->get_is_anonymous() || e2->get_is_anonymous())
16348 return false;
16349
16350 // Look through declaration-only types. That is, get the associated
16351 // definition type.
16354
16355 if (c1 && c2)
16356 {
16357 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
16358 {
16359 if (c1->get_environment().decl_only_class_equals_definition())
16360 // At least one of classes/union is declaration-only.
16361 // Because we are in a context in which a declaration-only
16362 // class/union is equal to all definitions of that
16363 // class/union, we can assume that the two types are
16364 // equal.
16365 return true;
16366 }
16367 }
16368
16369 if (t1.get_size_in_bits() != t2.get_size_in_bits())
16370 return false;
16371
16372 hash_t h1 = peek_hash_value(t1);
16373 hash_t h2 = peek_hash_value(t2);
16374 if (h1 != h2)
16375 return false;
16376
16377 // Look at the file names of the locations of t1 and t2. If they
16378 // are equal, then t1 and t2 are defined in the same file.
16379 {
16380 location l;
16381
16382 if (c1)
16383 l = c1->get_location();
16384 else
16385 l = dynamic_cast<const decl_base&>(t1).get_location();
16386
16387 unsigned line = 0, col = 0;
16388 if (l)
16389 l.expand(t1_file_path, line, col);
16390 if (c2)
16391 l = c2->get_location();
16392 else
16393 l = dynamic_cast<const decl_base&>(t2).get_location();
16394 if (l)
16395 l.expand(t2_file_path, line, col);
16396 }
16397
16398 if (t1_file_path.empty() || t2_file_path.empty())
16399 return false;
16400
16401 if (t1_file_path == t2_file_path)
16402 return true;
16403
16404 return false;
16405}
16406
16407
16408/// Compare a type T against a canonical type.
16409///
16410/// This function is called during the canonicalization process of the
16411/// type T. T is called the "candidate type" because it's in the
16412/// process of being canonicalized. Meaning, it's going to be
16413/// compared to a canonical type C. If T equals C, then the canonical
16414/// type of T is C.
16415///
16416/// The purpose of this function is to allow the debugging of the
16417/// canonicalization of T, if that debugging is activated by
16418/// configuring the libabigail package with
16419/// --enable-debug-type-canonicalization and by running "abidw
16420/// --debug-tc". In that case, T is going to be compared to C twice:
16421/// once with canonical equality and once with structural equality.
16422/// The two comparisons must be equal. Otherwise, the
16423/// canonicalization process is said to be faulty and this function
16424/// aborts.
16425///
16426/// This is a sub-routine of homonym_type_group::get_canonical_type_for.
16427///
16428/// @param canonical_type the canonical type to compare the candidate
16429/// type against.
16430///
16431/// @param candidate_type the candidate type to compare against the
16432/// canonical type.
16433///
16434/// @return true iff @p canonical_type equals @p candidate_type.
16435///
16436static bool
16437compare_types_during_canonicalization(const type_base& canonical_type,
16438 const type_base& candidate_type)
16439{
16440#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
16441 const environment& env = canonical_type.get_environment();
16442 if (env.debug_type_canonicalization_is_on())
16443 {
16444 bool canonical_equality = false, structural_equality = false;
16445 env.priv_->allow_type_comparison_results_caching(false);
16446 env.priv_->use_canonical_type_comparison_ = false;
16447 structural_equality = canonical_type == candidate_type;
16448 env.priv_->use_canonical_type_comparison_ = true;
16449 canonical_equality = canonical_type == candidate_type;
16450 env.priv_->allow_type_comparison_results_caching(true);
16451 if (canonical_equality != structural_equality)
16452 {
16453 std::cerr << "structural & canonical equality different for type: "
16454 << canonical_type.get_pretty_representation(true, true)
16455 << std::endl;
16457 }
16458 return structural_equality;
16459 }
16460#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
16461 return canonical_type == candidate_type;
16462}
16463
16464/// Compare a canonical type against a candidate canonical type.
16465///
16466/// This is ultimately a sub-routine of the
16467/// homonym_type_group::get_canonical_type_for().
16468///
16469/// The goal of this function is to ease debugging because it can be
16470/// called from within homonym_type_group::get_canonical_type_for() from the
16471/// prompt of the debugger (with some breakpoint appropriately set) to
16472/// debug the comparison that happens during type canonicalization,
16473/// between a candidate type being canonicalized, and an existing
16474/// canonical type that is registered in the system, in as returned by
16475/// environment::get_canonical_types()
16476///
16477/// @param canonical_type the canonical type to consider.
16478///
16479/// @param candidate_type the candidate type that is being
16480/// canonicalized, and thus compared to @p canonical_type.
16481///
16482/// @return true iff @p canonical_type compares equal to @p
16483/// candidate_type.
16484bool
16486 const type_base& candidate_type)
16487{
16488 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
16489 candidate_type)
16490 || compare_types_during_canonicalization(canonical_type,
16491 candidate_type));
16492
16493 if (equal)
16494 {
16495 hash_t h1 = peek_hash_value(canonical_type);
16496 hash_t h2 = peek_hash_value(candidate_type);
16497 ABG_ASSERT(h1 == h2);
16498 }
16499 return equal;
16500}
16501
16502/// Compare a canonical type against a candidate canonical type.
16503///
16504/// This is ultimately a sub-routine of the
16505/// homonym_type_group::get_canonical_type_for().
16506///
16507/// The goal of this function is to ease debugging because it can be
16508/// called from within homonym_type_group::get_canonical_type_for() from the
16509/// prompt of the debugger (with some breakpoint appropriately set) to
16510/// debug the comparison that happens during type canonicalization,
16511/// between a candidate type being canonicalized, and an existing
16512/// canonical type that is registered in the system, in as returned by
16513/// environment::get_canonical_types()
16514///
16515/// @param canonical_type the canonical type to consider.
16516///
16517/// @param candidate_type the candidate type that is being
16518/// canonicalized, and thus compared to @p canonical_type.
16519///
16520/// @return true iff @p canonical_type compares equal to @p
16521/// candidate_type.
16522bool
16524 const type_base* candidate_type)
16525{
16526 return compare_canonical_type_against_candidate(*canonical_type,
16527 *candidate_type);
16528}
16529
16530/// Compare a canonical type against a candidate canonical type.
16531///
16532/// This is ultimately a sub-routine of the
16533/// homonym_type_group::get_canonical_type_for().
16534///
16535/// The goal of this function is to ease debugging because it can be
16536/// called from within homonym_type_group::get_canonical_type_for() from the
16537/// prompt of the debugger (with some breakpoint appropriately set) to
16538/// debug the comparison that happens during type canonicalization,
16539/// between a candidate type being canonicalized, and an existing
16540/// canonical type that is registered in the system, in as returned by
16541/// environment::get_canonical_types()
16542///
16543/// @param canonical_type the canonical type to consider.
16544///
16545/// @param candidate_type the candidate type that is being
16546/// canonicalized, and thus compared to @p canonical_type.
16547///
16548/// @return true iff @p canonical_type compares equal to @p
16549/// candidate_type.
16550bool
16551compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
16552 const type_base_sptr& candidate_type)
16553{
16554 return compare_canonical_type_against_candidate(canonical_type.get(),
16555 candidate_type.get());
16556}
16557
16558/// Test if a candidate for type canonicalization coming from ABIXML
16559/// matches a canonical type by first looking at their hash values.
16560///
16561/// If the two hash values are equal then the candidate is
16562/// structurally compared to the canonical type. If the two hashes
16563/// are different then the two types are considered different and the
16564/// function returns nullptr.
16565///
16566/// If the candidate doesn't come from ABIXML then the function
16567/// returns nullptr.
16568///
16569/// @param cncls the vector of canonical types to consider.
16570///
16571/// @param type the candidate to consider for canonicalization.
16572///
16573/// @return the canonical type from @p cncls that matches the
16574/// candidate @p type.
16575type_base_sptr
16576candidate_matches_a_canonical_type_hash(const list<type_base_sptr>& cncls,
16577 type_base& type)
16578{
16579 if (type.get_corpus()
16580 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
16581 && peek_hash_value(type))
16582 {
16583 // The candidate type comes from ABIXML and does have a stashed
16584 // hash value coming from the ABIXML.
16585
16586 // Let's see if we find a potential canonical type whose hash
16587 // matches the stashed hash and whose canonical type index
16588 // matches it too.
16589 for (const auto& c : cncls)
16590 if (peek_hash_value(type) == peek_hash_value(*c))
16592 {
16593 // We found a potential canonical type which hash matches the
16594 // stashed hash of the candidate type. Let's compare them to
16595 // see if they match.
16597 return c;
16598#ifdef WITH_DEBUG_SELF_COMPARISON
16599 else
16600 {
16601 if (type.get_environment().self_comparison_debug_is_on())
16602 {
16603 std::cerr << "error: wrong canonical type comparison result despite types "
16604 << "having the same hash value: "
16605 << " type:" << std::hex << &type
16606 << ", canonical type candidate:" << std::hex << c
16607 << " hash value: '" << std::hex << *peek_hash_value(type)
16608 << "' string repr: " << type.get_pretty_representation()
16609 << std::endl;
16610 }
16611 }
16612#endif
16613 }
16614
16615 // Let's do the same things, but just considering hash values.
16616 for (const auto& c : reverse(cncls))
16617 // We walk the canonical types in the reverse order to comply
16618 // with what we are doing in
16619 // homonym_type_group::get_canonical_type_for.
16620 if (peek_hash_value(type) == peek_hash_value(*c))
16621 // We found a potential canonical type which hash matches the
16622 // stashed hash of the candidate type. Let's compare them to
16623 // see if they match.
16625 return c;
16626 }
16627
16628 return nullptr;
16629}
16630
16631/// Test if we should attempt to compute a hash value for a given
16632/// type.
16633///
16634/// For now this function returns true only for types originating from
16635/// ELF. For types originating from ABIXML, for instance, the
16636/// function return false, meaning that types originating from ABIXML
16637/// should NOT be hashed.
16638///
16639/// @param t the type to consider.
16640///
16641/// @return true iff @p type should be considered for hashing.
16642bool
16644{
16645 if (t.get_corpus()
16646 && (t.get_corpus()->get_origin() & corpus::ELF_ORIGIN))
16647 return true;
16648 return false;
16649}
16650
16651/// Compute the canonical type index of a recently designated
16652/// canonical type.
16653///
16654/// The canonical type index is the index of a given canonical type in
16655/// the imaginary vector made of the other canonical types which have
16656/// the following properties:
16657///
16658/// 1/ They all have the same internal pretty representation as
16659/// returned by
16660/// canonical_type::get_cached_pretty_representation(/*internal=*/true).
16661/// We call a vector of canonincal types with property "vector of
16662/// adjacent canonical types".
16663///
16664/// 2/ They all have the same hash value.
16665///
16666/// This function thus takes in parameter a vector of canonical types
16667/// that satisfy property 1 and a the canonical type for which we want
16668/// the canonical type index.
16669///
16670/// @param adjacent_canonical_types a vector of canonical types that
16671/// have the same internal pretty representation aka "adjacent
16672/// canonical types".
16673///
16674/// @param canonical_type the canonical type for which we want to
16675/// compute the canonical type index.
16676///
16677/// @param resulting_index output parameter that is set by the
16678/// function to the resulting canonical index, iff the function
16679/// returns true.
16680///
16681/// @return true iff the function could compute the canonical index
16682/// and set it into @p resulting_index.
16683bool
16684compute_canonical_type_index(const list<type_base_sptr>& adjacent_canonical_types,
16685 const type_base_sptr canonical_type,
16686 int& resulting_index)
16687{
16688 if (!canonical_type)
16689 return false;
16690
16691 int result = 0;
16692 bool found = false;
16693 hash_t reference_hash = peek_hash_value(*canonical_type);
16694 if (!reference_hash)
16695 return false;
16696
16697 for (auto ctype : adjacent_canonical_types)
16698 {
16699 hash_t h = peek_hash_value(*ctype);
16700 if (*h == *reference_hash)
16701 {
16702 ++result;
16703 found = true;
16704 }
16705 }
16706
16707 if (found)
16708 {
16709 resulting_index = result;
16710 return true;
16711 }
16712
16713 return false;
16714}
16715
16716/// This method is invoked automatically right after the current
16717/// instance of @ref class_decl has been canonicalized.
16718void
16721
16722/// This is a subroutine of the canonicalize() function.
16723///
16724/// When the canonical type C of type T has just been computed, there
16725/// can be cases where T has member functions that C doesn't have.
16726///
16727/// This is possible because non virtual member functions are not
16728/// taken in account when comparing two types.
16729///
16730/// In that case, this function updates C so that it contains the
16731/// member functions.
16732///
16733/// There can also be cases where C has a method M which is not linked
16734/// to any underlying symbol, whereas in T, M is to link to an
16735/// underlying symbol. In that case, this function updates M in C so
16736/// that it's linked to the same underlying symbol as for M in T.
16737void
16738maybe_adjust_canonical_type(const type_base_sptr& canonical,
16739 const type_base_sptr& type)
16740{
16741 if (canonical.get() == type.get())
16742 return;
16743
16744 class_or_union_sptr cou = is_class_or_union_type(canonical);
16746
16747 if (cou)
16748 {
16749 lock_guard<recursive_mutex> lock(cou->get_mutex());
16750 // Ensure that the canonical type has the union of the member
16751 // functions, variables, and member types of the types that are
16752 // in its class of equivalence. This way, just emitting a
16753 // canonical type (in the ABIXML format, for instance) is enough
16754 // to capture the member functions and variables of all the
16755 // types that are in its class of equivalence.
16756 //
16757 // NOTE: This is done after type canonicalization is done.
16759 /*copy_virtual_mem_fns=*/true);
16761 copy_missing_naming_typedef(is_decl(canonical), is_decl(type));
16763
16764 class_or_union_sptr clazz = is_class_or_union_type(type);
16765 clazz = look_through_decl_only_class(clazz);
16766 }
16767
16768 class_decl_sptr canonical_class = is_class_type(cou);
16769
16770 if (class_decl_sptr cl = is_class_type(type))
16771 {
16773 if (canonical_class
16774 && canonical_class.get() != cl.get()
16775 && canonical_class->get_corpus() == cl->get_corpus())
16776 {
16777 // Set symbols of member functions that might be missing
16778 // theirs.
16779 auto mem_fns = cl->get_member_functions_copy();
16780 for (auto mem_fn : mem_fns)
16781 if (mem_fn->get_symbol())
16782 {
16783 string n = mem_fn->get_linkage_name();
16784 if (n.empty())
16785 n = mem_fn->get_name();
16786
16787 {
16788 lock_guard<recursive_mutex> lock(canonical_class->get_mutex());
16789 method_decl *m = canonical_class->find_member_function(n);
16790 if (!m)
16791 {
16792 if (!mem_fn->get_linkage_name().empty())
16793 {
16795 m = canonical_class->find_member_function(n);
16796 }
16797 }
16798 if (m)
16799 {
16800 elf_symbol_sptr s1 = mem_fn->get_symbol();
16801 if (s1 && !m->get_symbol())
16802 // Method 'm' in the canonical type is not
16803 // linked to the underlying symbol of '*i'.
16804 // Let's link it now.
16805 m->set_symbol(s1);
16806 }
16807 else
16808 if (!is_anonymous_type(cl)
16809 && canonical_class->get_corpus()
16810 && cl->get_corpus()
16811 && (cl->get_corpus() == canonical_class->get_corpus()))
16812 // There is a member function defined and publicly
16813 // exported in the other class and the canonical
16814 // class doesn't have that member function. This
16815 // should not have happened! For instance, the
16816 // DWARF reader does merge the member functions of
16817 // classes having the same name so that all of them
16818 // end-up having the same member functions. What's
16819 // going on here?
16821 }
16822 }
16823
16824 // Set symbols of static data members that might be missing
16825 // theirs.
16826 auto data_members = cl->get_data_members_copy();
16827 for (auto data_member : data_members)
16828 {
16829 if (!get_member_is_static(data_member))
16830 continue;
16831 elf_symbol_sptr sym = data_member->get_symbol();
16832 if (!sym)
16833 continue;
16834
16835 auto canonical_data_member =
16836 canonical_class->find_data_member(data_member->get_name());
16837 if (!canonical_data_member)
16838 continue;
16839
16840 if (!canonical_data_member->get_symbol())
16841 canonical_data_member->set_symbol(sym);
16842 }
16843 }
16844 }
16845
16846 // Make sure the virtual member functions with exported symbols are
16847 // all added to the set of exported functions of the corpus.
16848
16849 // If we are looking at a non-canonicalized class (for instance, a
16850 // decl-only class that has virtual member functions), let's pretend
16851 // it does have a canonical class so that we can perform the
16852 // necessary virtual member function adjustments
16853 if (class_decl_sptr cl = is_class_type(type))
16855 {
16856 ABG_ASSERT(!canonical_class);
16857 canonical_class = cl;
16858 }
16859
16860 if (canonical_class)
16861 {
16862 lock_guard<recursive_mutex> lock(canonical_class->get_mutex());
16863
16864 if (auto abi_corpus = canonical_class->get_corpus())
16865 {
16866 for (auto fn : canonical_class->get_member_functions())
16867 {
16868 if (elf_symbol_sptr sym = fn->get_symbol())
16869 {
16870 if (sym->is_defined() && sym->is_public())
16871 {
16872 fn->set_is_in_public_symbol_table(true);
16873 auto b = abi_corpus->get_exported_decls_builder();
16874 b->maybe_add_fn_to_exported_fns(fn.get(),
16875 /*do_update=*/true);
16876 }
16877 else if (!sym->is_defined())
16878 {
16879 lock_guard<recursive_mutex> lock(abi_corpus->priv_->mutex_);
16880 abi_corpus->get_undefined_functions().insert(fn.get());
16881 }
16882 }
16883 }
16884 }
16885 }
16886
16887 // If an artificial function type equals a non-artfificial one in
16888 // the system, then the canonical type of both should be deemed
16889 // non-artificial. This is important because only non-artificial
16890 // canonical function types are emitted out into abixml, so if don't
16891 // do this we risk missing to emit some function types.
16892 if (is_function_type(type))
16893 if (type->get_is_artificial() != canonical->get_is_artificial())
16894 canonical->set_is_artificial(false);
16895
16896 type->on_canonical_type_set();
16897}
16898
16899/// Compute the canonical type of a given type.
16900///
16901/// It means that after invoking this function, comparing the instance
16902/// instance @ref type_base and another one (on which
16903/// type_base::enable_canonical_equality() would have been invoked as
16904/// well) is performed by just comparing the pointer values of the
16905/// canonical types of both types. That equality comparison is
16906/// supposedly faster than structural comparison of the types.
16907///
16908/// @param t a smart pointer to the instance of @ref type_base for
16909/// which to compute the canonical type. After this call,
16910/// t->get_canonical_type() will return the newly computed canonical
16911/// type.
16912///
16913/// @param group the @ref homonym_type_group the type @p t belongs to.
16914/// Read the README-type-canonicalization.txt file to learn more.
16915///
16916/// @param do_log if true then logs are emitted about canonicalization
16917/// progress.
16918///
16919/// @param show_stats if true and if @p do_log is true as well, then
16920/// more detailed logs are emitted about canonicalization.
16921///
16922/// @return the canonical type computed for @p t.
16923type_base_sptr
16924canonicalize(type_base_sptr t,
16926 bool do_log, bool show_stats)
16927{
16928 if (!t)
16929 return t;
16930
16931 if (t->get_canonical_type())
16932 return t->get_canonical_type();
16933
16934 ABG_ASSERT(group);
16935
16936 if (do_log && show_stats)
16937 std::cerr << "Canonicalization of type '"
16938 << t->get_pretty_representation(true, true)
16939 << "/@#" << std::hex << t.get() << ": ";
16940
16942
16943 if (do_log && show_stats)
16944 tmr.start();
16945
16946 type_base_sptr canonical = group->get_canonical_type_for(t, group);
16947
16948 if (do_log && show_stats)
16949 tmr.stop();
16950
16951 if (do_log && show_stats)
16952 std::cerr << tmr << "\n";
16953
16954 {
16955 lock_guard<recursive_mutex> lock(t->priv_->mutex);
16956 t->priv_->canonical_type = canonical;
16957 }
16958
16959 if (canonical)
16960 {
16961 if (!t->priv_->canonical_type_index)
16962 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
16963 hash_t h1 = peek_hash_value(*t);
16964 hash_t h2 = peek_hash_value(*canonical);
16965 ABG_ASSERT(h1 == h2);
16966 }
16967 {
16968 lock_guard<recursive_mutex> lock(t->priv_->mutex);
16969 t->priv_->naked_canonical_type = canonical.get();
16970 }
16971
16972 if (class_decl_sptr cl = is_class_type(t))
16973 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
16974 if ((canonical = d->get_canonical_type()))
16975 {
16976 d->priv_->canonical_type = canonical;
16977 d->priv_->naked_canonical_type = canonical.get();
16978 }
16979
16980 if (canonical)
16981 {
16982 if (decl_base_sptr d = is_decl_slow(canonical))
16983 {
16984 auto scope = d->get_scope();
16985 // Add the canonical type to the set of canonical types
16986 // belonging to its scope.
16987 if (scope)
16988 {
16989 if (is_type(scope))
16990 // The scope in question is itself a type (e.g, a class
16991 // or union). Let's call that type ST. We want to add
16992 // 'canonical' to the set of canonical types belonging
16993 // to ST.
16994 if (type_base_sptr c = is_type(scope)->get_canonical_type())
16995 // We want to add 'canonical' to the set of
16996 // canonical types belonging to the canonical type
16997 // of ST. That way, just looking at the canonical
16998 // type of ST is enough to get the types that belong
16999 // to the scope of the class of equivalence of ST.
17000 scope = is_scope_decl(is_decl(c));
17001 {
17002 lock_guard<recursive_mutex> lock(scope->get_mutex());
17003 scope->get_canonical_types().insert(canonical);
17004 scope->priv_->sorted_canonical_types_.clear();
17005 }
17006 }
17007 // else, if the type doesn't have a scope, it's not meant to be
17008 // emitted. This can be the case for the result of the
17009 // function strip_typedef, for instance.
17010 }
17011 }
17012
17013 return canonical;
17014}
17015
17016/// Hash and canonicalize a type.
17017///
17018/// @param t the type to hash and then canonicalize.
17019///
17020/// @return the new canonical type of @p t.
17021type_base_sptr
17023{
17024 if (!t)
17025 return nullptr;
17026
17027 t->hash_value();
17028 auto& env = t->get_environment();
17029 auto group = env.priv_->types_partition_.get_or_create_type_group(t);
17030 return canonicalize(t, group);
17031}
17032
17033/// Canonicalize types coming from a vector of homonym_type_group_sptr
17034/// in //.
17035///
17036/// Each set of types that are in a given group are canonicalized in
17037/// a separate thread.
17038///
17039/// @param groups the vector of type groups to canonicalize.
17040///
17041/// @param do_log when set to true, emit logs about progress and
17042/// timing.
17043///
17044/// @param show_stas when set to true, emit details stats about type
17045/// canonicalization and whatnot.
17046void
17047canonicalize_homonym_type_groups(const vector<homonym_type_group_sptr>& groups,
17048 bool do_log, bool show_stats)
17049{
17050 if (groups.empty())
17051 return;
17052
17054
17055 size_t num_workers = std::min(environment::get_number_of_threads_to_use(),
17056 groups.size());
17057
17058 if (do_log)
17059 {
17060 std::cerr << "Types are broken into " << groups.size() << " groups ...\n";
17061 std::cerr << "Going to use " << num_workers << " threads to canonicalize them ...\n";
17062 tmr.start();
17063 }
17064
17065 queue task_queue(num_workers);
17066
17067 // canonicalize types within each type group in parallel.
17068 for (auto type_group : groups)
17069 {
17070 c14n_task_sptr t(new c14n_task(type_group, do_log, show_stats));
17071 ABG_ASSERT(task_queue.schedule_task(t));
17072 }
17073
17074 // Wait for all worker threads to finish their job and wind down.
17075 task_queue.wait_for_workers_to_complete();
17076
17077 const vector<task_sptr>& completed_tasks =
17078 task_queue.get_completed_tasks();
17079
17080 if (do_log)
17081 {
17082 tmr.stop();
17083 std::cerr << "Canonicalizing of types DONE in: " << tmr << "\n\n";
17084
17085 if (show_stats)
17086 {
17087 std::cerr << "Details about homonym type groups c14n ...\n";
17088 for (auto task : completed_tasks)
17089 {
17090 c14n_task_sptr t = dynamic_pointer_cast<c14n_task>(task);
17091 ABG_ASSERT(t);
17092 std::cerr << t->log_message << std::endl;
17093 }
17094 std::cerr << "Details about homonym type groups c14n DONE\n";
17095 }
17096 }
17097}
17098
17099/// Set the definition of this declaration-only @ref decl_base.
17100///
17101/// @param d the new definition to set.
17102void
17104{
17106 priv_->definition_of_declaration_ = d;
17107 if (type_base *t = is_type(this))
17108 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
17109 t->priv_->canonical_type = canonical_type;
17110
17111 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
17112}
17113
17114/// The constructor of @ref type_base.
17115///
17116/// @param s the size of the type, in bits.
17117///
17118/// @param a the alignment of the type, in bits.
17119type_base::type_base(const environment& e, size_t s, size_t a)
17120 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
17121 priv_(new priv(s, a))
17122{}
17123
17124/// Return the hash value of the current IR node.
17125///
17126/// Note that upon the first invocation, this member functions
17127/// computes the hash value and returns it. Subsequent invocations
17128/// just return the hash value that was previously calculated.
17129///
17130/// @return the hash value of the current IR node.
17131hash_t
17133{
17134 type_base::hash do_hash;
17135 return do_hash(this);
17136}
17137
17138/// Getter of the canonical type of the current instance of @ref
17139/// type_base.
17140///
17141/// @return a smart pointer to the canonical type of the current
17142/// intance of @ref type_base, or an empty smart pointer if the
17143/// current instance of @ref type_base doesn't have any canonical
17144/// type.
17145type_base_sptr
17147{
17148 lock_guard<recursive_mutex> lock(priv_->mutex);
17149 return priv_->canonical_type.lock();
17150}
17151
17152/// Getter of the canonical type pointer.
17153///
17154/// Note that this function doesn't return a smart pointer, but rather
17155/// the underlying pointer managed by the smart pointer. So it's as
17156/// fast as possible. This getter is to be used in code paths that
17157/// are proven to be performance hot spots; especially, when comparing
17158/// sensitive types like class, function, pointers and reference
17159/// types. Those are compared extremely frequently and thus, their
17160/// accessing the canonical type must be fast.
17161///
17162/// @return the canonical type pointer, not managed by a smart
17163/// pointer.
17164type_base*
17166{
17167 lock_guard<recursive_mutex> lock(priv_->mutex);
17168 return priv_->naked_canonical_type;
17169}
17170
17171/// Compares two instances of @ref type_base.
17172///
17173/// If the two intances are different, set a bitfield to give some
17174/// insight about the kind of differences there are.
17175///
17176/// @param l the first artifact of the comparison.
17177///
17178/// @param r the second artifact of the comparison.
17179///
17180/// @param k a pointer to a bitfield that gives information about the
17181/// kind of changes there are between @p l and @p r. This one is set
17182/// iff @p is non-null and if the function returns false.
17183///
17184/// Please note that setting k to a non-null value does have a
17185/// negative performance impact because even if @p l and @p r are not
17186/// equal, the function keeps up the comparison in order to determine
17187/// the different kinds of ways in which they are different.
17188///
17189/// @return true if @p l equals @p r, false otherwise.
17190bool
17191equals(const type_base& l, const type_base& r, change_kind* k)
17192{
17193 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
17195 if (!result)
17196 if (k)
17198
17199 ABG_RETURN(result);
17200}
17201
17202/// Return true iff both type declarations are equal.
17203///
17204/// Note that this doesn't test if the scopes of both types are equal.
17205bool
17207{return equals(*this, other, 0);}
17208
17209/// Inequality operator.
17210///
17211///@param other the instance of @ref type_base to compare the current
17212/// instance against.
17213///
17214/// @return true iff the current instance is different from @p other.
17215bool
17217{return !operator==(other);}
17218
17219/// Setter for the size of the type.
17220///
17221/// @param s the new size -- in bits.
17222void
17224{
17225 lock_guard<recursive_mutex> lock(priv_->mutex);
17226 priv_->size_in_bits = s;
17227}
17228
17229/// Getter for the size of the type.
17230///
17231/// @return the size in bits of the type.
17232size_t
17234{
17235 lock_guard<recursive_mutex> lock(priv_->mutex);
17236 return priv_->size_in_bits;
17237}
17238
17239/// Setter for the alignment of the type.
17240///
17241/// @param a the new alignment -- in bits.
17242void
17244{
17245 lock_guard<recursive_mutex> lock(priv_->mutex);
17246 priv_->alignment_in_bits = a;
17247}
17248
17249/// Getter for the alignment of the type.
17250///
17251/// @return the alignment of the type in bits.
17252size_t
17254{
17255 lock_guard<recursive_mutex> lock(priv_->mutex);
17256 return priv_->alignment_in_bits;
17257}
17258
17259/// Default implementation of traversal for types. This function does
17260/// nothing. It must be implemented by every single new type that is
17261/// written.
17262///
17263/// Please look at e.g, class_decl::traverse() for an example of how
17264/// to implement this.
17265///
17266/// @param v the visitor used to visit the type.
17267bool
17269{
17270 if (v.type_node_has_been_visited(this))
17271 return true;
17272
17273 v.visit_begin(this);
17274 bool result = v.visit_end(this);
17276
17277 return result;
17278}
17279
17280type_base::~type_base()
17281{delete priv_;}
17282
17283// </type_base definitions>
17284
17285// <real_type definitions>
17286
17287/// Bitwise OR operator for real_type::modifiers_type.
17288///
17289/// @param l the left-hand side operand.
17290///
17291/// @param r the right-hand side operand.
17292///
17293/// @return the result of the bitwise OR.
17296{
17297 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
17298 |
17299 static_cast<unsigned>(r));
17300}
17301
17302/// Bitwise AND operator for real_type::modifiers_type.
17303///
17304/// @param l the left-hand side operand.
17305///
17306/// @param r the right-hand side operand.
17307///
17308/// @return the result of the bitwise AND.
17311{
17312 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
17313 &
17314 static_cast<unsigned>(r));
17315}
17316
17317/// Bitwise one's complement operator for real_type::modifiers_type.
17318///
17319/// @param l the left-hand side operand.
17320///
17321/// @param r the right-hand side operand.
17322///
17323/// @return the result of the bitwise one's complement operator.
17326{
17327 return static_cast<real_type::modifiers_type>(~static_cast<unsigned>(l));
17328}
17329
17330/// Bitwise |= operator for real_type::modifiers_type.
17331///
17332/// @param l the left-hand side operand.
17333///
17334/// @param r the right-hand side operand.
17335///
17336/// @return the result of the bitwise |=.
17339{
17340 l = l | r;
17341 return l;
17342}
17343
17344/// Bitwise &= operator for real_type::modifiers_type.
17345///
17346/// @param l the left-hand side operand.
17347///
17348/// @param r the right-hand side operand.
17349///
17350/// @return the result of the bitwise &=.
17353{
17354 l = l & r;
17355 return l;
17356}
17357
17358/// Parse a word containing one real type modifier.
17359///
17360/// A word is considered to be a string of characters that doesn't
17361/// contain any white space.
17362///
17363/// @param word the word to parse. It is considered to be a string of
17364/// characters that doesn't contain any white space.
17365///
17366/// @param modifiers out parameter. It's set by this function to the
17367/// parsed modifier iff the function returned true.
17368///
17369/// @return true iff @word was successfully parsed.
17370static bool
17371parse_real_type_modifier(const string& word,
17372 real_type::modifiers_type &modifiers)
17373{
17374 if (word == "signed")
17375 modifiers |= real_type::SIGNED_MODIFIER;
17376 else if (word == "unsigned")
17377 modifiers |= real_type::UNSIGNED_MODIFIER;
17378 else if (word == "short")
17379 modifiers |= real_type::SHORT_MODIFIER;
17380 else if (word == "long")
17381 modifiers |= real_type::LONG_MODIFIER;
17382 else if (word == "long long")
17383 modifiers |= real_type::LONG_LONG_MODIFIER;
17384 else
17385 return false;
17386
17387 return true;
17388}
17389
17390/// Parse a base type of a real type from a string.
17391///
17392/// @param type_name the type name to parse.
17393///
17394/// @param base out parameter. This is set to the resulting base type
17395/// parsed, iff the function returned true.
17396///
17397/// @return true iff the function could successfully parse the base
17398/// type.
17399static bool
17400parse_base_real_type(const string& type_name,
17402{
17403 if (type_name == "int")
17405 else if (type_name == "char")
17407 else if (type_name == "bool" || type_name == "_Bool")
17409 else if (type_name == "double")
17411 else if (type_name =="float")
17413 else if (type_name == "char16_t")
17415 else if (type_name == "char32_t")
17417 else if (type_name == "wchar_t")
17419 else if (type_name == "__ARRAY_SIZE_TYPE__")
17421 else if (type_name == "sizetype")
17422 base = real_type::SIZE_BASE_TYPE;
17423 else if (type_name == "ssizetype")
17424 base = real_type::SSIZE_BASE_TYPE;
17425 else if (type_name == "bitsizetype")
17426 base = real_type::BIT_SIZE_BASE_TYPE;
17427 else if (type_name == "sbitsizetype")
17428 base = real_type::SBIT_SIZE_BASE_TYPE;
17429 else
17430 return false;
17431
17432 return true;
17433}
17434
17435/// Parse a real type from a string.
17436///
17437/// @param type_name the string containing the real type to parse.
17438///
17439/// @param base out parameter. Is set by this function to the base
17440/// type of the real type, iff the function returned true.
17441///
17442/// @param modifiers out parameter If set by this function to the
17443/// modifier of the real type, iff the function returned true.
17444///
17445/// @return true iff the function could parse a real type from @p
17446/// type_name.
17447static bool
17448parse_real_type(const string& type_name,
17450 real_type::modifiers_type& modifiers)
17451{
17452 string input = type_name;
17453 string::size_type len = input.length();
17454 string::size_type cur_pos = 0, prev_pos = 0;
17455 string cur_word, prev_word;
17456 bool ok = false;
17457
17458 while (cur_pos < len)
17459 {
17460 if (cur_pos < len && isspace(input[cur_pos]))
17461 do
17462 ++cur_pos;
17463 while (cur_pos < len && isspace(input[cur_pos]));
17464
17465 prev_pos = cur_pos;
17466 cur_pos = input.find(' ', prev_pos);
17467 prev_word = cur_word;
17468 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
17469
17470 if (cur_pos < len
17471 && cur_word == "long"
17472 && prev_word != "long")
17473 {
17474 if (cur_pos < len && isspace(input[cur_pos]))
17475 do
17476 ++cur_pos;
17477 while (cur_pos < len && isspace(input[cur_pos]));
17478 prev_pos = cur_pos;
17479
17480 cur_pos = input.find(' ', prev_pos);
17481 string saved_prev_word = prev_word;
17482 prev_word = cur_word;
17483 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
17484 if (cur_word == "long")
17485 cur_word = "long long";
17486 else
17487 {
17488 cur_pos = prev_pos;
17489 cur_word = prev_word;
17490 prev_word = saved_prev_word;
17491 }
17492 }
17493
17494 if (!parse_real_type_modifier(cur_word, modifiers))
17495 {
17496 if (!parse_base_real_type(cur_word, base))
17497 return false;
17498 else
17499 ok = true;
17500 }
17501 else
17502 ok = true;
17503 }
17504
17505 return ok;
17506}
17507
17508/// Parse a real type from a string.
17509///
17510/// @param str the string containing the real type to parse.
17511///
17512///@param type the resulting @ref real_type. Is set to the result
17513///of the parse, iff the function returns true.
17514///
17515/// @return true iff the function could parse a real type from @p
17516/// str.
17517bool
17518parse_real_type(const string& str, real_type& type)
17519{
17521 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
17522
17523 if (!parse_real_type(str, base_type, modifiers))
17524 return false;
17525
17526 // So this is a real type.
17527 real_type int_type(base_type, modifiers);
17528 type = int_type;
17529 return true;
17530}
17531
17532/// Default constructor of the @ref real_type.
17534 : base_(INT_BASE_TYPE),
17535 modifiers_(NO_MODIFIER)
17536{}
17537
17538/// Constructor of the @ref real_type.
17539///
17540/// @param b the base type of the real type.
17541///
17542/// @param m the modifiers of the real type.
17544 : base_(b), modifiers_(m)
17545{}
17546
17547/// Constructor of the @ref real_type.
17548///
17549/// @param the name of the real type to parse to initialize the
17550/// current instance of @ref real_type.
17551real_type::real_type(const string& type_name)
17552 : base_(INT_BASE_TYPE),
17553 modifiers_(NO_MODIFIER)
17554{
17555 bool could_parse = parse_real_type(type_name, base_, modifiers_);
17556 ABG_ASSERT(could_parse);
17557}
17558
17559/// Getter of the base type of the @ref real_type.
17560///
17561/// @return the base type of the @ref real_type.
17564{return base_;}
17565
17566/// Getter of the modifiers bitmap of the @ref real_type.
17567///
17568/// @return the modifiers bitmap of the @ref real_type.
17571{return modifiers_;}
17572
17573/// Setter of the modifiers bitmap of the @ref real_type.
17574///
17575/// @param m the new modifiers.
17576void
17578{modifiers_ = m;}
17579
17580/// Equality operator for the @ref real_type.
17581///
17582/// @param other the other real type to compare against.
17583///
17584/// @return true iff @p other equals the current instance of @ref
17585/// real_type.
17586bool
17588{return base_ == other.base_ && modifiers_ == other.modifiers_;}
17589
17590/// Return the string representation of the current instance of @ref
17591/// real_type.
17592///
17593/// @param internal if true the string representation is to be used
17594/// for internal purposes. In general, it means it's for type
17595/// canonicalization purposes.
17596///
17597/// @return the string representation of the current instance of @ref
17598/// real_type.
17599string
17600real_type::to_string(bool internal) const
17601{
17602 string result;
17603
17604 // Look at modifiers ...
17605 if (modifiers_ & SIGNED_MODIFIER)
17606 result += "signed ";
17607 if (modifiers_ & UNSIGNED_MODIFIER)
17608 result += "unsigned ";
17609 if (!internal)
17610 {
17611 // For canonicalization purposes, we won't emit the "short, long, or
17612 // long long" modifiers. This is because on some platforms, "long
17613 // int" and "long long int" might have the same size. In those
17614 // cases, we want the two types to be equivalent if they have the
17615 // same size. If they don't have the same internal string
17616 // representation, they'd automatically have different canonical
17617 // types and thus be canonically different.
17618 if (modifiers_ & SHORT_MODIFIER)
17619 result += "short ";
17620 if (modifiers_ & LONG_MODIFIER)
17621 result += "long ";
17622 if (modifiers_ & LONG_LONG_MODIFIER)
17623 result += "long long ";
17624 }
17625
17626 // ... and look at base types.
17627 if (base_ == INT_BASE_TYPE)
17628 result += "int";
17629 else if (base_ == CHAR_BASE_TYPE)
17630 result += "char";
17631 else if (base_ == BOOL_BASE_TYPE)
17632 result += "bool";
17633 else if (base_ == DOUBLE_BASE_TYPE)
17634 result += "double";
17635 else if (base_ == FLOAT_BASE_TYPE)
17636 result += "float";
17637 else if (base_ == CHAR16_T_BASE_TYPE)
17638 result += "char16_t";
17639 else if (base_ == CHAR32_T_BASE_TYPE)
17640 result += "char32_t";
17641 else if (base_ == WCHAR_T_BASE_TYPE)
17642 result += "wchar_t";
17643 else if (base_ == ARRAY_SIZE_BASE_TYPE)
17644 result += "__ARRAY_SIZE_TYPE__";
17645 else if (base_ == SIZE_BASE_TYPE)
17646 result += "sizetype";
17647 else if (base_ == SSIZE_BASE_TYPE)
17648 result += "ssizetype";
17649 else if (base_ == BIT_SIZE_BASE_TYPE)
17650 result += "bitsizetype";
17651 else if (base_ == SBIT_SIZE_BASE_TYPE)
17652 result += "sbitsizetype";
17653 return result;
17654}
17655
17656/// Convert the current instance of @ref real_type into its string
17657/// representation.
17658///
17659/// @return the string representation of the current instance of @ref
17660/// real_type.
17661real_type::operator string() const
17662{return to_string();}
17663
17664// </real_type definitions>
17665
17666//<type_decl definitions>
17667
17668/// Constructor.
17669///
17670/// @param env the environment we are operating from.
17671///
17672/// @param name the name of the type declaration.
17673///
17674/// @param size_in_bits the size of the current type_decl, in bits.
17675///
17676/// @param alignment_in_bits the alignment of the current typ, in
17677/// bits.
17678///
17679/// @param locus the source location of the current type declaration.
17680///
17681/// @param linkage_name the linkage_name of the current type declaration.
17682///
17683/// @param vis the visibility of the type declaration.
17684type_decl::type_decl(const environment& env,
17685 const string& name,
17686 size_t size_in_bits,
17687 size_t alignment_in_bits,
17688 const location& locus,
17689 const string& linkage_name,
17690 visibility vis)
17691
17692 : type_or_decl_base(env,
17693 BASIC_TYPE
17694 | ABSTRACT_TYPE_BASE
17695 | ABSTRACT_DECL_BASE),
17696 decl_base(env, name, locus, linkage_name, vis),
17697 type_base(env, size_in_bits, alignment_in_bits)
17698{
17700
17702 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
17703 real_type int_type(base_type, modifiers);
17704 if (parse_real_type(name, int_type))
17705 {
17706 // Convert the real_type into its canonical string
17707 // representation.
17708 string real_type_name = int_type;
17709
17710 // Set the name of this type_decl to the canonical string
17711 // representation above
17712 set_name(real_type_name);
17714
17715 if (!get_linkage_name().empty())
17716 set_linkage_name(real_type_name);
17717 }
17718}
17719
17720/// Return the hash value of the current IR node.
17721///
17722/// Note that upon the first invocation, this member functions
17723/// computes the hash value and returns it. Subsequent invocations
17724/// just return the hash value that was previously calculated.
17725///
17726/// @return the hash value of the current IR node.
17727hash_t
17729{
17731 return h;
17732}
17733
17734/// Compares two instances of @ref type_decl.
17735///
17736/// If the two intances are different, set a bitfield to give some
17737/// insight about the kind of differences there are.
17738///
17739/// @param l the first artifact of the comparison.
17740///
17741/// @param r the second artifact of the comparison.
17742///
17743/// @param k a pointer to a bitfield that gives information about the
17744/// kind of changes there are between @p l and @p r. This one is set
17745/// iff @p k is non-null and the function returns false.
17746///
17747/// Please note that setting k to a non-null value does have a
17748/// negative performance impact because even if @p l and @p r are not
17749/// equal, the function keeps up the comparison in order to determine
17750/// the different kinds of ways in which they are different.
17751///
17752/// @return true if @p l equals @p r, false otherwise.
17753bool
17754equals(const type_decl& l, const type_decl& r, change_kind* k)
17755{
17756 bool result = false;
17757
17758 // Consider the types as decls to compare their decls-related
17759 // properties.
17760 result = equals(static_cast<const decl_base&>(l),
17761 static_cast<const decl_base&>(r),
17762 k);
17763 if (!k && !result)
17764 ABG_RETURN_FALSE;
17765
17766 // Now consider the types a "types' to compare their size-related
17767 // properties.
17768 result &= equals(static_cast<const type_base&>(l),
17769 static_cast<const type_base&>(r),
17770 k);
17771 ABG_RETURN(result);
17772}
17773
17774/// Return true if both types equals.
17775///
17776/// This operator re-uses the overload that takes a decl_base.
17777///
17778/// Note that this does not check the scopes of any of the types.
17779///
17780/// @param o the other type_decl to check agains.
17781bool
17783{
17784 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17785 if (!other)
17786 return false;
17787 return *this == *other;
17788}
17789
17790/// Return true if both types equals.
17791///
17792/// Note that this does not check the scopes of any of the types.
17793///
17794/// @param o the other type_decl to check against.
17795bool
17797{
17798 const type_decl* other = dynamic_cast<const type_decl*>(&o);
17799 if (!other)
17800 return false;
17801 return try_canonical_compare(this, other);
17802}
17803
17804/// Return true if both types equals.
17805///
17806/// Note that this does not check the scopes of any of the types.
17807///
17808/// @param o the other type_decl to check against.
17809///
17810/// @return true iff the current isntance equals @p o
17811bool
17813{
17814 const decl_base& other = o;
17815 return *this == other;
17816}
17817
17818/// Return true if both types equals.
17819///
17820/// Note that this does not check the scopes of any of the types.
17821///
17822/// @param o the other type_decl to check against.
17823///
17824/// @return true iff the current isntance equals @p o
17825bool
17827{return !operator==(o);}
17828
17829/// Return true if both types equals.
17830///
17831/// Note that this does not check the scopes of any of the types.
17832///
17833/// @param o the other type_decl to check against.
17834///
17835/// @return true iff the current isntance equals @p o
17836bool
17838{return !operator==(o);}
17839
17840/// Inequality operator.
17841///
17842/// @param o the other type to compare against.
17843///
17844/// @return true iff the current instance is different from @p o.
17845bool
17847{return !operator==(o);}
17848
17849/// Equality operator for @ref type_decl_sptr.
17850///
17851/// @param l the first operand to compare.
17852///
17853/// @param r the second operand to compare.
17854///
17855/// @return true iff @p l equals @p r.
17856bool
17858{
17859 if (!!l != !!r)
17860 return false;
17861 if (l.get() == r.get())
17862 return true;
17863 return *l == *r;
17864}
17865
17866/// Inequality operator for @ref type_decl_sptr.
17867///
17868/// @param l the first operand to compare.
17869///
17870/// @param r the second operand to compare.
17871///
17872/// @return true iff @p l is different from @p r.
17873bool
17875{return !operator==(l, r);}
17876
17877/// Implementation for the virtual qualified name builder for @ref
17878/// type_decl.
17879///
17880/// @param qualified_name the output parameter to hold the resulting
17881/// qualified name.
17882///
17883/// @param internal set to true if the call is intended for an
17884/// internal use (for technical use inside the library itself), false
17885/// otherwise. If you don't know what this is for, then set it to
17886/// false.
17887void
17889 bool internal) const
17890{qualified_name = get_qualified_name(internal);}
17891
17892/// Implementation for the virtual qualified name builder for @ref
17893/// type_decl.
17894///
17895/// @param qualified_name the output parameter to hold the resulting
17896/// qualified name.
17897///
17898/// @param internal set to true if the call is intended for an
17899/// internal use (for technical use inside the library itself), false
17900/// otherwise. If you don't know what this is for, then set it to
17901/// false.
17902const interned_string&
17904{
17905 const environment& env = get_environment();
17906
17907
17908 if (internal)
17909 if (is_real_type(this))
17910 {
17912 {
17913 if (decl_base::priv_->internal_qualified_name_.empty())
17914 decl_base::priv_->internal_qualified_name_ =
17915 env.intern(get_internal_real_type_name(this));
17916 return decl_base::priv_->internal_qualified_name_;
17917 }
17918 else
17919 {
17920 decl_base::priv_->temporary_internal_qualified_name_ =
17921 env.intern(get_internal_real_type_name(this));
17922 return decl_base::priv_->temporary_internal_qualified_name_;
17923 }
17924 }
17925
17926 return decl_base::get_qualified_name(/*internal=*/false);
17927}
17928
17929/// Get the pretty representation of the current instance of @ref
17930/// type_decl.
17931///
17932/// @param internal set to true if the call is intended to get a
17933/// representation of the decl (or type) for the purpose of canonical
17934/// type comparison. This is mainly used in the function
17935/// homonym_type_group::get_canonical_type_for().
17936///
17937/// In other words if the argument for this parameter is true then the
17938/// call is meant for internal use (for technical use inside the
17939/// library itself), false otherwise. If you don't know what this is
17940/// for, then set it to false.
17941///
17942/// @param qualified_name if true, names emitted in the pretty
17943/// representation are fully qualified.
17944///
17945/// @return the pretty representatin of the @ref type_decl.
17946string
17948 bool qualified_name) const
17949{
17950 if (internal)
17951 if (is_real_type(this))
17952 return get_internal_real_type_name(this);
17953
17954 if (qualified_name)
17955 return get_qualified_name(internal);
17956 return get_name();
17957}
17958
17959/// This implements the ir_traversable_base::traverse pure virtual
17960/// function.
17961///
17962/// @param v the visitor used on the current instance.
17963///
17964/// @return true if the entire IR node tree got traversed, false
17965/// otherwise.
17966bool
17968{
17969 if (v.type_node_has_been_visited(this))
17970 return true;
17971
17972 v.visit_begin(this);
17973 bool result = v.visit_end(this);
17975
17976 return result;
17977}
17978
17979type_decl::~type_decl()
17980{}
17981//</type_decl definitions>
17982
17983// <scope_type_decl definitions>
17984
17985/// Constructor.
17986///
17987/// @param env the environment we are operating from.
17988///
17989/// @param name the name of the type.
17990///
17991/// @param size_in_bits the size of the type, in bits.
17992///
17993/// @param alignment_in_bits the alignment of the type, in bits.
17994///
17995/// @param locus the source location where the type is defined.
17996///
17997/// @param vis the visibility of the type.
17998scope_type_decl::scope_type_decl(const environment& env,
17999 const string& name,
18000 size_t size_in_bits,
18001 size_t alignment_in_bits,
18002 const location& locus,
18003 visibility vis)
18004 : type_or_decl_base(env,
18005 ABSTRACT_SCOPE_TYPE_DECL
18006 | ABSTRACT_TYPE_BASE
18007 | ABSTRACT_DECL_BASE),
18008 decl_base(env, name, locus, "", vis),
18009 type_base(env, size_in_bits, alignment_in_bits),
18010 scope_decl(env, name, locus)
18011{}
18012
18013/// Compares two instances of @ref scope_type_decl.
18014///
18015/// If the two intances are different, set a bitfield to give some
18016/// insight about the kind of differences there are.
18017///
18018/// @param l the first artifact of the comparison.
18019///
18020/// @param r the second artifact of the comparison.
18021///
18022/// @param k a pointer to a bitfield that gives information about the
18023/// kind of changes there are between @p l and @p r. This one is set
18024/// iff @p k is non-null and the function returns false.
18025///
18026/// Please note that setting k to a non-null value does have a
18027/// negative performance impact because even if @p l and @p r are not
18028/// equal, the function keeps up the comparison in order to determine
18029/// the different kinds of ways in which they are different.
18030///
18031/// @return true if @p l equals @p r, false otherwise.
18032bool
18034{
18035 bool result = equals(static_cast<const scope_decl&>(l),
18036 static_cast<const scope_decl&>(r),
18037 k);
18038
18039 if (!k && !result)
18040 ABG_RETURN_FALSE;
18041
18042 result &= equals(static_cast<const type_base&>(l),
18043 static_cast<const type_base&>(r),
18044 k);
18045
18046 ABG_RETURN(result);
18047}
18048
18049/// Equality operator between two scope_type_decl.
18050///
18051/// Note that this function does not consider the scope of the scope
18052/// types themselves.
18053///
18054/// @return true iff both scope types are equal.
18055bool
18057{
18058 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
18059 if (!other)
18060 return false;
18061 return try_canonical_compare(this, other);
18062}
18063
18064/// Equality operator between two scope_type_decl.
18065///
18066/// This re-uses the equality operator that takes a decl_base.
18067///
18068/// @param o the other scope_type_decl to compare against.
18069///
18070/// @return true iff both scope types are equal.
18071bool
18073{
18074 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18075 if (!other)
18076 return false;
18077
18078 return *this == *other;
18079}
18080
18081/// Traverses an instance of @ref scope_type_decl, visiting all the
18082/// sub-types and decls that it might contain.
18083///
18084/// @param v the visitor that is used to visit every IR sub-node of
18085/// the current node.
18086///
18087/// @return true if either
18088/// - all the children nodes of the current IR node were traversed
18089/// and the calling code should keep going with the traversing.
18090/// - or the current IR node is already being traversed.
18091/// Otherwise, returning false means that the calling code should not
18092/// keep traversing the tree.
18093bool
18095{
18096 if (visiting())
18097 return true;
18098
18099 if (v.type_node_has_been_visited(this))
18100 return true;
18101
18102 if (v.visit_begin(this))
18103 {
18104 visiting(true);
18105 for (auto i = get_member_decls().begin();
18106 i != get_member_decls ().end();
18107 ++i)
18108 if (!(*i)->traverse(v))
18109 break;
18110 visiting(false);
18111 }
18112
18113 bool result = v.visit_end(this);
18115
18116 return result;
18117}
18118
18119scope_type_decl::~scope_type_decl()
18120{}
18121// </scope_type_decl definitions>
18122
18123// <namespace_decl>
18124
18125/// Constructor.
18126///
18127/// @param the environment we are operatin from.
18128///
18129/// @param name the name of the namespace.
18130///
18131/// @param locus the source location where the namespace is defined.
18132///
18133/// @param vis the visibility of the namespace.
18135 const string& name,
18136 const location& locus,
18137 visibility vis)
18138 // We need to call the constructor of decl_base directly here
18139 // because it is virtually inherited by scope_decl. Note that we
18140 // just implicitely call the default constructor for scope_decl
18141 // here, as what we really want is to initialize the decl_base
18142 // subobject. Wow, virtual inheritance is useful, but setting it
18143 // up is ugly.
18144 : type_or_decl_base(env,
18145 NAMESPACE_DECL
18146 | ABSTRACT_DECL_BASE
18147 | ABSTRACT_SCOPE_DECL),
18148 decl_base(env, name, locus, "", vis),
18149 scope_decl(env, name, locus)
18150{
18152}
18153
18154/// Build and return a copy of the pretty representation of the
18155/// namespace.
18156///
18157/// @param internal set to true if the call is intended to get a
18158/// representation of the decl (or type) for the purpose of canonical
18159/// type comparison. This is mainly used in the function
18160/// homonym_type_group::get_canonical_type_for().
18161///
18162/// In other words if the argument for this parameter is true then the
18163/// call is meant for internal use (for technical use inside the
18164/// library itself), false otherwise. If you don't know what this is
18165/// for, then set it to false.
18166///
18167/// @param qualified_name if true, names emitted in the pretty
18168/// representation are fully qualified.
18169///
18170/// @return a copy of the pretty representation of the namespace.
18171string
18173 bool qualified_name) const
18174{
18175 string r =
18176 "namespace " + scope_decl::get_pretty_representation(internal,
18177 qualified_name);
18178 return r;
18179}
18180
18181/// Return true iff both namespaces and their members are equal.
18182///
18183/// Note that this function does not check if the scope of these
18184/// namespaces are equal.
18185bool
18187{
18188 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
18189 if (!other)
18190 return false;
18191 return scope_decl::operator==(*other);
18192}
18193
18194/// Test if the current namespace_decl is empty or contains empty
18195/// namespaces itself.
18196///
18197/// @return true iff the current namespace_decl is empty or contains
18198/// empty itself.
18199bool
18201{
18202 if (is_empty())
18203 return true;
18204
18205 for (declarations::const_iterator i = get_member_decls().begin();
18206 i != get_member_decls().end();
18207 ++i)
18208 {
18209 if (!is_namespace(*i))
18210 return false;
18211
18213 ABG_ASSERT(ns);
18214
18215 if (!ns->is_empty_or_has_empty_sub_namespaces())
18216 return false;
18217 }
18218
18219 return true;
18220}
18221
18222/// This implements the ir_traversable_base::traverse pure virtual
18223/// function.
18224///
18225/// @param v the visitor used on the current instance and on its
18226/// member nodes.
18227///
18228/// @return true if the entire IR node tree got traversed, false
18229/// otherwise.
18230bool
18232{
18233 if (visiting())
18234 return true;
18235
18236 if (v.visit_begin(this))
18237 {
18238 visiting(true);
18240 for (auto m : decls)
18241 {
18243 dynamic_pointer_cast<ir_traversable_base>(m);
18244 if (t)
18245 if (!t->traverse (v))
18246 break;
18247 }
18248 visiting(false);
18249 }
18250 return v.visit_end(this);
18251}
18252
18253namespace_decl::~namespace_decl()
18254{
18255}
18256
18257// </namespace_decl>
18258
18259// <qualified_type_def>
18260
18261/// Type of the private data of qualified_type_def.
18262class qualified_type_def::priv
18263{
18264 friend class qualified_type_def;
18265
18266 mutex mutex_;
18267 qualified_type_def::CV cv_quals_;
18268 // Before the type is canonicalized, this is used as a temporary
18269 // internal name.
18270 interned_string temporary_internal_name_;
18271 // Once the type is canonicalized, this is used as the internal
18272 // name.
18273 interned_string internal_name_;
18274 type_base_wptr underlying_type_;
18275
18276 priv()
18277 : cv_quals_(CV_NONE)
18278 {}
18279
18280 priv(qualified_type_def::CV quals,
18281 type_base_sptr t)
18282 : cv_quals_(quals),
18283 underlying_type_(t)
18284 {}
18285
18286 priv(qualified_type_def::CV quals)
18287 : cv_quals_(quals)
18288 {}
18289};// end class qualified_type_def::priv
18290
18291/// Build the name of the current instance of qualified type.
18292///
18293/// @param fully_qualified if true, build a fully qualified name.
18294///
18295/// @param internal set to true if the call is intended for an
18296/// internal use (for technical use inside the library itself), false
18297/// otherwise. If you don't know what this is for, then set it to
18298/// false.
18299///
18300/// @return a copy of the newly-built name.
18301string
18302qualified_type_def::build_name(bool fully_qualified, bool internal) const
18303{
18304 type_base_sptr t = get_underlying_type();
18305 if (!t)
18306 // The qualified type might temporarily have no underlying type,
18307 // especially during the construction of the type, while the
18308 // underlying type is not yet constructed. In that case, let's do
18309 // like if the underlying type is the 'void' type.
18311
18313 fully_qualified,
18314 internal);
18315}
18316
18317/// This function is automatically invoked whenever an instance of
18318/// this type is canonicalized.
18319///
18320/// It's an overload of the virtual type_base::on_canonical_type_set.
18321///
18322/// We put here what is thus meant to be executed only at the point of
18323/// type canonicalization.
18324void
18327
18328/// Constructor of the qualified_type_def
18329///
18330/// @param type the underlying type
18331///
18332/// @param quals a bitfield representing the const/volatile qualifiers
18333///
18334/// @param locus the location of the qualified type definition
18335qualified_type_def::qualified_type_def(type_base_sptr type,
18336 CV quals,
18337 const location& locus)
18338 : type_or_decl_base(type->get_environment(),
18339 QUALIFIED_TYPE
18340 | ABSTRACT_TYPE_BASE
18341 | ABSTRACT_DECL_BASE),
18342 type_base(type->get_environment(), type->get_size_in_bits(),
18343 type->get_alignment_in_bits()),
18344 decl_base(type->get_environment(), "", locus, "",
18345 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
18346 priv_(new priv(quals, type))
18347{
18349 interned_string name = type->get_environment().intern(build_name(false));
18350 set_name(name);
18351}
18352
18353/// Constructor of the qualified_type_def
18354///
18355/// @param env the environment of the type.
18356///
18357/// @param quals a bitfield representing the const/volatile qualifiers
18358///
18359/// @param locus the location of the qualified type definition
18360qualified_type_def::qualified_type_def(const environment& env,
18361 CV quals,
18362 const location& locus)
18363 : type_or_decl_base(env,
18364 QUALIFIED_TYPE
18365 | ABSTRACT_TYPE_BASE
18366 | ABSTRACT_DECL_BASE),
18367 type_base(env, /*size_in_bits=*/0,
18368 /*alignment_in_bits=*/0),
18369 decl_base(env, "", locus, ""),
18370 priv_(new priv(quals))
18371{
18373 // We don't yet have an underlying type. So for naming purpose,
18374 // let's temporarily pretend the underlying type is 'void'.
18375 interned_string name = env.intern("void");
18376 set_name(name);
18377}
18378
18379/// Return the hash value of the current IR node.
18380///
18381/// Note that upon the first invocation, this member functions
18382/// computes the hash value and returns it. Subsequent invocations
18383/// just return the hash value that was previously calculated.
18384///
18385/// @return the hash value of the current IR node.
18386hash_t
18388{
18390 return h;
18391}
18392
18393/// Get the size of the qualified type def.
18394///
18395/// This is an overload for type_base::get_size_in_bits().
18396///
18397/// @return the size of the qualified type.
18398size_t
18400{
18401 size_t s = 0;
18402 if (type_base_sptr ut = get_underlying_type())
18403 {
18404 // We do have the underlying type properly set, so let's make
18405 // the size of the qualified type match the size of its
18406 // underlying type.
18407 s = ut->get_size_in_bits();
18408 if (s != type_base::get_size_in_bits())
18409 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
18410 }
18412}
18413
18414/// Compares two instances of @ref qualified_type_def.
18415///
18416/// If the two intances are different, set a bitfield to give some
18417/// insight about the kind of differences there are.
18418///
18419/// @param l the first artifact of the comparison.
18420///
18421/// @param r the second artifact of the comparison.
18422///
18423/// @param k a pointer to a bitfield that gives information about the
18424/// kind of changes there are between @p l and @p r. This one is set
18425/// iff @p k is non-null and the function returns false.
18426///
18427/// Please note that setting k to a non-null value does have a
18428/// negative performance impact because even if @p l and @p r are not
18429/// equal, the function keeps up the comparison in order to determine
18430/// the different kinds of ways in which they are different.
18431///
18432/// @return true if @p l equals @p r, false otherwise.
18433bool
18435{
18436 bool result = true;
18437 if (l.get_cv_quals() != r.get_cv_quals())
18438 {
18439 result = false;
18440 if (k)
18442 else
18443 ABG_RETURN_FALSE;
18444 }
18445
18447 {
18448 result = false;
18449 if (k)
18450 {
18452 r.get_underlying_type().get()))
18453 // Underlying type changes in which the structure of the
18454 // type changed are considered local changes to the
18455 // qualified type.
18457 else
18458 *k |= SUBTYPE_CHANGE_KIND;
18459 }
18460 else
18461 // okay strictly speaking this is not necessary, but I am
18462 // putting it here to maintenance; that is, so that adding
18463 // subsequent clauses needed to compare two qualified types
18464 // later still works.
18465 ABG_RETURN_FALSE;
18466 }
18467
18468 ABG_RETURN(result);
18469}
18470
18471/// Equality operator for qualified types.
18472///
18473/// Note that this function does not check for equality of the scopes.
18474///
18475///@param o the other qualified type to compare against.
18476///
18477/// @return true iff both qualified types are equal.
18478bool
18480{
18481 const qualified_type_def* other =
18482 dynamic_cast<const qualified_type_def*>(&o);
18483 if (!other)
18484 return false;
18485 return try_canonical_compare(this, other);
18486}
18487
18488/// Equality operator for qualified types.
18489///
18490/// Note that this function does not check for equality of the scopes.
18491/// Also, this re-uses the equality operator above that takes a
18492/// decl_base.
18493///
18494///@param o the other qualified type to compare against.
18495///
18496/// @return true iff both qualified types are equal.
18497bool
18499{
18500 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18501 if (!other)
18502 return false;
18503 return *this == *other;
18504}
18505
18506/// Equality operator for qualified types.
18507///
18508/// Note that this function does not check for equality of the scopes.
18509/// Also, this re-uses the equality operator above that takes a
18510/// decl_base.
18511///
18512///@param o the other qualified type to compare against.
18513///
18514/// @return true iff both qualified types are equal.
18515bool
18517{
18518 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18519 if (!other)
18520 return false;
18521 return *this == *other;
18522}
18523
18524/// Implementation for the virtual qualified name builder for @ref
18525/// qualified_type_def.
18526///
18527/// @param qualified_name the output parameter to hold the resulting
18528/// qualified name.
18529///
18530/// @param internal set to true if the call is intended for an
18531/// internal use (for technical use inside the library itself), false
18532/// otherwise. If you don't know what this is for, then set it to
18533/// false.
18534void
18536 bool internal) const
18537{qualified_name = get_qualified_name(internal);}
18538
18539/// Implementation of the virtual qualified name builder/getter.
18540///
18541/// @param internal set to true if the call is intended for an
18542/// internal use (for technical use inside the library itself), false
18543/// otherwise. If you don't know what this is for, then set it to
18544/// false.
18545///
18546/// @return the resulting qualified name.
18547const interned_string&
18549{
18550 const environment& env = get_environment();
18551
18552
18553 if (!get_canonical_type())
18554 {
18555 // The type hasn't been canonicalized yet. We want to return a
18556 // temporary name that is not cached because the structure of
18557 // this type (and so its name) can change until its
18558 // canonicalized.
18559 if (internal)
18560 {
18561 // We are asked to return a temporary *internal* name.
18562 // Lets compute it and return a reference to where it's
18563 // stored.
18564 priv_->temporary_internal_name_ =
18565 env.intern(build_name(true, /*internal=*/true));
18566 return priv_->temporary_internal_name_;
18567 }
18568 else
18569 {
18570 // We are asked to return a temporary non-internal name.
18572 (env.intern(build_name(true, /*internal=*/false)));
18574 }
18575 }
18576 else
18577 {
18578 // The type has already been canonicalized. We want to return
18579 // the definitive name and cache it.
18580 if (internal)
18581 {
18582 if (priv_->internal_name_.empty())
18583 priv_->internal_name_ =
18584 env.intern(build_name(/*qualified=*/true,
18585 /*internal=*/true));
18586 return priv_->internal_name_;
18587 }
18588 else
18589 {
18590 if (peek_qualified_name().empty())
18592 (env.intern(build_name(/*qualified=*/true,
18593 /*internal=*/false)));
18594 return peek_qualified_name();
18595 }
18596 }
18597}
18598
18599/// This implements the ir_traversable_base::traverse pure virtual
18600/// function.
18601///
18602/// @param v the visitor used on the current instance.
18603///
18604/// @return true if the entire IR node tree got traversed, false
18605/// otherwise.
18606bool
18608{
18609 if (v.type_node_has_been_visited(this))
18610 return true;
18611
18612 if (visiting())
18613 return true;
18614
18615 if (v.visit_begin(this))
18616 {
18617 visiting(true);
18618 if (type_base_sptr t = get_underlying_type())
18619 t->traverse(v);
18620 visiting(false);
18621 }
18622 bool result = v.visit_end(this);
18624 return result;
18625}
18626
18627qualified_type_def::~qualified_type_def()
18628{
18629}
18630
18631/// Getter of the const/volatile qualifier bit field
18634{
18635 lock_guard<mutex> lock(priv_->mutex_);
18636 return priv_->cv_quals_;
18637}
18638
18639/// Setter of the const/value qualifiers bit field
18640void
18642{
18643 lock_guard<mutex> lock(priv_->mutex_);
18644 priv_->cv_quals_ = cv_quals;
18645}
18646
18647/// Compute and return the string prefix or suffix representing the
18648/// qualifiers hold by the current instance of @ref
18649/// qualified_type_def.
18650///
18651/// @return the newly-built cv string.
18652string
18655
18656/// Getter of the underlying type
18657type_base_sptr
18659{
18660 lock_guard<mutex> lock(priv_->mutex_);
18661 return priv_->underlying_type_.lock();
18662}
18663
18664/// Setter of the underlying type.
18665///
18666/// @param t the new underlying type.
18667void
18669{
18670 {
18671 lock_guard<mutex> lock(priv_->mutex_);
18672 ABG_ASSERT(t);
18673 priv_->underlying_type_ = t;
18674 // Now we need to update other properties that depend on the new
18675 // underlying type.
18676 set_size_in_bits(t->get_size_in_bits());
18677 set_alignment_in_bits(t->get_alignment_in_bits());
18678 }
18679
18681 set_name(name);
18682 if (auto s = get_scope())
18683 {
18684 // Now that the name has been updated, we need to update the
18685 // lookup maps accordingly.
18686 scope_decl::declarations::iterator i;
18687 if (s->find_iterator_for_member(this, i))
18689 else
18691 }
18692}
18693
18694/// Non-member equality operator for @ref qualified_type_def
18695///
18696/// @param l the left-hand side of the equality operator
18697///
18698/// @param r the right-hand side of the equality operator
18699///
18700/// @return true iff @p l and @p r equals.
18701bool
18702operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
18703{
18704 if (l.get() == r.get())
18705 return true;
18706 if (!!l != !!r)
18707 return false;
18708
18709 return *l == *r;
18710}
18711
18712/// Non-member inequality operator for @ref qualified_type_def
18713///
18714/// @param l the left-hand side of the equality operator
18715///
18716/// @param r the right-hand side of the equality operator
18717///
18718/// @return true iff @p l and @p r equals.
18719bool
18720operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
18721{return ! operator==(l, r);}
18722
18723/// Overloaded bitwise OR operator for cv qualifiers.
18726{
18727 return static_cast<qualified_type_def::CV>
18728 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
18729}
18730
18731/// Overloaded bitwise |= operator for cv qualifiers.
18734{
18735 l = l | r;
18736 return l;
18737}
18738
18739/// Overloaded bitwise &= operator for cv qualifiers.
18742{
18743 l = l & r;
18744 return l;
18745}
18746
18747/// Overloaded bitwise AND operator for CV qualifiers.
18750{
18751 return static_cast<qualified_type_def::CV>
18752 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
18753}
18754
18755/// Overloaded bitwise inverting operator for CV qualifiers.
18758{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
18759
18760/// Streaming operator for qualified_type_decl::CV
18761///
18762/// @param o the output stream to serialize the cv qualifier to.
18763///
18764/// @param cv the cv qualifier to serialize.
18765///
18766/// @return the output stream used.
18767std::ostream&
18768operator<<(std::ostream& o, qualified_type_def::CV cv)
18769{
18770 string str;
18771
18772 switch (cv)
18773 {
18774 case qualified_type_def::CV_NONE:
18775 str = "none";
18776 break;
18777 case qualified_type_def::CV_CONST:
18778 str = "const";
18779 break;
18780 case qualified_type_def::CV_VOLATILE:
18781 str = "volatile";
18782 break;
18783 case qualified_type_def::CV_RESTRICT:
18784 str = "restrict";
18785 break;
18786 }
18787
18788 o << str;
18789 return o;
18790}
18791
18792// </qualified_type_def>
18793
18794//<pointer_type_def definitions>
18795
18796/// Private data structure of the @ref pointer_type_def.
18797struct pointer_type_def::priv
18798{
18799 type_base_wptr pointed_to_type_;
18800 type_base* naked_pointed_to_type_;
18801 interned_string internal_qualified_name_;
18802 interned_string temp_internal_qualified_name_;
18803
18804 priv(const type_base_sptr& t)
18805 : pointed_to_type_(type_or_void(t, t->get_environment())),
18806 naked_pointed_to_type_(t.get())
18807 {}
18808
18809 priv()
18810 : naked_pointed_to_type_()
18811 {}
18812}; //end struct pointer_type_def
18813
18814/// This function is automatically invoked whenever an instance of
18815/// this type is canonicalized.
18816///
18817/// It's an overload of the virtual type_base::on_canonical_type_set.
18818///
18819/// We put here what is thus meant to be executed only at the point of
18820/// type canonicalization.
18821void
18824
18825
18826///Constructor of @ref pointer_type_def.
18827///
18828/// @param pointed_to the pointed-to type.
18829///
18830/// @param size_in_bits the size of the type, in bits.
18831///
18832/// @param align_in_bits the alignment of the type, in bits.
18833///
18834/// @param locus the source location where the type was defined.
18835pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
18836 size_t size_in_bits,
18837 size_t align_in_bits,
18838 const location& locus)
18839 : type_or_decl_base(pointed_to->get_environment(),
18840 POINTER_TYPE
18841 | ABSTRACT_TYPE_BASE
18842 | ABSTRACT_DECL_BASE),
18843 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18844 decl_base(pointed_to->get_environment(), "", locus, ""),
18845 priv_(new priv(pointed_to))
18846{
18848 try
18849 {
18850 ABG_ASSERT(pointed_to);
18851 const environment& env = pointed_to->get_environment();
18852 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18853 string name = (pto ? pto->get_name() : string("void")) + "*";
18854 set_name(env.intern(name));
18855 if (pto)
18856 set_visibility(pto->get_visibility());
18857 }
18858 catch (...)
18859 {}
18860}
18861
18862///Constructor of @ref pointer_type_def.
18863///
18864/// @param env the environment of the type.
18865///
18866/// @param size_in_bits the size of the type, in bits.
18867///
18868/// @param align_in_bits the alignment of the type, in bits.
18869///
18870/// @param locus the source location where the type was defined.
18871pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
18872 size_t alignment_in_bits,
18873 const location& locus)
18874 : type_or_decl_base(env,
18875 POINTER_TYPE
18876 | ABSTRACT_TYPE_BASE
18877 | ABSTRACT_DECL_BASE),
18878 type_base(env, size_in_bits, alignment_in_bits),
18879 decl_base(env, "", locus, ""),
18880 priv_(new priv())
18881{
18883 string name = string("void") + "*";
18884 set_name(env.intern(name));
18885}
18886
18887/// Return the hash value of the current IR node.
18888///
18889/// Note that upon the first invocation, this member functions
18890/// computes the hash value and returns it. Subsequent invocations
18891/// just return the hash value that was previously calculated.
18892///
18893/// @return the hash value of the current IR node.
18894hash_t
18896{
18898 return h;
18899}
18900
18901/// Set the pointed-to type of the pointer.
18902///
18903/// @param t the new pointed-to type.
18904void
18906{
18907 ABG_ASSERT(t);
18908 priv_->pointed_to_type_ = t;
18909 priv_->naked_pointed_to_type_ = t.get();
18910
18911 try
18912 {
18913 const environment& env = t->get_environment();
18914 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
18915 string name = (pto ? pto->get_name() : string("void")) + "*";
18916 set_name(env.intern(name));
18917 if (pto)
18918 set_visibility(pto->get_visibility());
18919 }
18920 catch (...)
18921 {}
18922}
18923
18924/// Compares two instances of @ref pointer_type_def.
18925///
18926/// If the two intances are different, set a bitfield to give some
18927/// insight about the kind of differences there are.
18928///
18929/// @param l the first artifact of the comparison.
18930///
18931/// @param r the second artifact of the comparison.
18932///
18933/// @param k a pointer to a bitfield that gives information about the
18934/// kind of changes there are between @p l and @p r. This one is set
18935/// iff @p k is non-null and the function returns false.
18936///
18937/// Please note that setting k to a non-null value does have a
18938/// negative performance impact because even if @p l and @p r are not
18939/// equal, the function keeps up the comparison in order to determine
18940/// the different kinds of ways in which they are different.
18941///
18942/// @return true if @p l equals @p r, false otherwise.
18943bool
18945{
18946 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18947 bool result = p1 == p2;
18948
18949 if (!result)
18950 if (k)
18951 {
18952 if (!types_have_similar_structure(&l, &r))
18953 // pointed-to type changes in which the structure of the
18954 // type changed are considered local changes to the pointer
18955 // type.
18957 *k |= SUBTYPE_CHANGE_KIND;
18958 }
18959
18960 ABG_RETURN(result);
18961}
18962
18963/// Return true iff both instances of pointer_type_def are equal.
18964///
18965/// Note that this function does not check for the scopes of the this
18966/// types.
18967bool
18969{
18970 const pointer_type_def* other = is_pointer_type(&o);
18971 if (!other)
18972 return false;
18973 return try_canonical_compare(this, other);
18974}
18975
18976/// Return true iff both instances of pointer_type_def are equal.
18977///
18978/// Note that this function does not check for the scopes of the
18979/// types.
18980///
18981/// @param other the other type to compare against.
18982///
18983/// @return true iff @p other equals the current instance.
18984bool
18986{
18987 const decl_base* o = is_decl(&other);
18988 if (!o)
18989 return false;
18990 return *this == *o;
18991}
18992
18993/// Return true iff both instances of pointer_type_def are equal.
18994///
18995/// Note that this function does not check for the scopes of the
18996/// types.
18997///
18998/// @param other the other type to compare against.
18999///
19000/// @return true iff @p other equals the current instance.
19001bool
19003{
19004 const decl_base& o = other;
19005 return *this == o;
19006}
19007
19008/// Getter of the pointed-to type.
19009///
19010/// @return the pointed-to type.
19011const type_base_sptr
19013{return priv_->pointed_to_type_.lock();}
19014
19015/// Getter of a naked pointer to the pointed-to type.
19016///
19017/// @return a naked pointed to the pointed-to type.
19018type_base*
19020{return priv_->naked_pointed_to_type_;}
19021
19022/// Build and return the qualified name of the current instance of
19023/// @ref pointer_type_def.
19024///
19025/// @param qn output parameter. The resulting qualified name.
19026///
19027/// @param internal set to true if the call is intended for an
19028/// internal use (for technical use inside the library itself), false
19029/// otherwise. If you don't know what this is for, then set it to
19030/// false.
19031void
19033{qn = get_qualified_name(internal);}
19034
19035/// Build, cache and return the qualified name of the current instance
19036/// of @ref pointer_type_def. Subsequent invocations of this function
19037/// return the cached value.
19038///
19039/// Note that this function should work even if the underlying type is
19040/// momentarily empty.
19041///
19042/// @param internal set to true if the call is intended for an
19043/// internal use (for technical use inside the library itself), false
19044/// otherwise. If you don't know what this is for, then set it to
19045/// false.
19046///
19047/// @return the resulting qualified name.
19048const interned_string&
19050{
19051 type_base* pointed_to_type = get_naked_pointed_to_type();
19052 pointed_to_type = look_through_decl_only_type(pointed_to_type);
19053
19054 if (internal)
19055 {
19056 if (get_canonical_type())
19057 {
19058 if (priv_->internal_qualified_name_.empty())
19059 if (pointed_to_type)
19060 priv_->internal_qualified_name_ =
19061 pointer_declaration_name(this,
19062 /*variable_name=*/"",
19063 /*qualified_name=*/
19064 is_typedef(pointed_to_type)
19065 ? false
19066 : true,
19067 /*internal=*/true);
19068 return priv_->internal_qualified_name_;
19069 }
19070 else
19071 {
19072 // As the type hasn't yet been canonicalized, its structure
19073 // (and so its name) can change. So let's invalidate the
19074 // cache where we store its name at each invocation of this
19075 // function.
19076 priv_->temp_internal_qualified_name_ =
19077 pointer_declaration_name(this,
19078 /*variable_name=*/"",
19079 /*qualified_name=*/
19080 is_typedef(pointed_to_type)
19081 ? false
19082 : true,
19083 /*internal=*/true);
19084 return priv_->temp_internal_qualified_name_;
19085 }
19086 }
19087 else
19088 {
19090 {
19093 (pointer_declaration_name(this,
19094 /*variable_name=*/"",
19095 /*qualified_name=*/true,
19096 /*internal=*/false));
19098 }
19099 else
19100 {
19101 // As the type hasn't yet been canonicalized, its structure
19102 // (and so its name) can change. So let's invalidate the
19103 // cache where we store its name at each invocation of this
19104 // function.
19105 if (pointed_to_type)
19107 (pointer_declaration_name(this,
19108 /*variable_name=*/"",
19109 /*qualified_name=*/true,
19110 /*internal=*/false));
19112 }
19113 }
19114}
19115
19116/// This implements the ir_traversable_base::traverse pure virtual
19117/// function.
19118///
19119/// @param v the visitor used on the current instance.
19120///
19121/// @return true if the entire IR node tree got traversed, false
19122/// otherwise.
19123bool
19125{
19126 if (v.type_node_has_been_visited(this))
19127 return true;
19128
19129 if (visiting())
19130 return true;
19131
19132 if (v.visit_begin(this))
19133 {
19134 visiting(true);
19135 if (type_base_sptr t = get_pointed_to_type())
19136 t->traverse(v);
19137 visiting(false);
19138 }
19139
19140 bool result = v.visit_end(this);
19142 return result;
19143}
19144
19145pointer_type_def::~pointer_type_def()
19146{}
19147
19148/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
19149/// equality; that is, make it compare the pointed to objects too.
19150///
19151/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
19152/// of the equality.
19153///
19154/// @param r the shared_ptr of @ref pointer_type_def on
19155/// right-hand-side of the equality.
19156///
19157/// @return true if the @ref pointer_type_def pointed to by the
19158/// shared_ptrs are equal, false otherwise.
19159bool
19161{
19162 if (l.get() == r.get())
19163 return true;
19164 if (!!l != !!r)
19165 return false;
19166
19167 return *l == *r;
19168}
19169
19170/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
19171/// equality; that is, make it compare the pointed to objects too.
19172///
19173/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
19174/// of the equality.
19175///
19176/// @param r the shared_ptr of @ref pointer_type_def on
19177/// right-hand-side of the equality.
19178///
19179/// @return true iff the @ref pointer_type_def pointed to by the
19180/// shared_ptrs are different.
19181bool
19183{return !operator==(l, r);}
19184
19185// </pointer_type_def definitions>
19186
19187// <reference_type_def definitions>
19188
19189/// Private data structure of the @ref reference_type_def type.
19190struct reference_type_def::priv
19191{
19192
19193 type_base_wptr pointed_to_type_;
19194 bool is_lvalue_;
19195 interned_string internal_qualified_name_;
19196 interned_string temp_internal_qualified_name_;
19197
19198 priv(const type_base_sptr& t, bool is_lvalue)
19199 : pointed_to_type_(type_or_void(t, t->get_environment())),
19200 is_lvalue_(is_lvalue)
19201 {}
19202
19203 priv(bool is_lvalue)
19204 : is_lvalue_(is_lvalue)
19205 {}
19206
19207 priv() = delete;
19208};
19209
19210/// This function is automatically invoked whenever an instance of
19211/// this type is canonicalized.
19212///
19213/// It's an overload of the virtual type_base::on_canonical_type_set.
19214///
19215/// We put here what is thus meant to be executed only at the point of
19216/// type canonicalization.
19217void
19220
19221/// Constructor of the reference_type_def type.
19222///
19223/// @param pointed_to the pointed to type.
19224///
19225/// @param lvalue wether the reference is an lvalue reference. If
19226/// false, the reference is an rvalue one.
19227///
19228/// @param size_in_bits the size of the type, in bits.
19229///
19230/// @param align_in_bits the alignment of the type, in bits.
19231///
19232/// @param locus the source location of the type.
19233reference_type_def::reference_type_def(const type_base_sptr pointed_to,
19234 bool lvalue,
19235 size_t size_in_bits,
19236 size_t align_in_bits,
19237 const location& locus)
19238 : type_or_decl_base(pointed_to->get_environment(),
19239 REFERENCE_TYPE
19240 | ABSTRACT_TYPE_BASE
19241 | ABSTRACT_DECL_BASE),
19242 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
19243 decl_base(pointed_to->get_environment(), "", locus, ""),
19244 priv_(new priv(pointed_to, lvalue))
19245{
19247
19248 try
19249 {
19250 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
19251 string name;
19252 if (pto)
19253 {
19254 set_visibility(pto->get_visibility());
19255 name = string(pto->get_name()) + "&";
19256 }
19257 else
19258 name = string(get_type_name(is_function_type(pointed_to),
19259 /*qualified_name=*/true)) + "&";
19260
19261 if (!is_lvalue())
19262 name += "&";
19263 const environment& env = pointed_to->get_environment();
19264 set_name(env.intern(name));
19265 }
19266 catch (...)
19267 {}
19268}
19269
19270/// Constructor of the reference_type_def type.
19271///
19272/// This one creates a type that has no pointed-to type, temporarily.
19273/// This is useful for cases where the underlying type is not yet
19274/// available. It can be set later using
19275/// reference_type_def::set_pointed_to_type().
19276///
19277/// @param env the environment of the type.
19278///
19279/// @param lvalue wether the reference is an lvalue reference. If
19280/// false, the reference is an rvalue one.
19281///
19282/// @param size_in_bits the size of the type, in bits.
19283///
19284/// @param align_in_bits the alignment of the type, in bits.
19285///
19286/// @param locus the source location of the type.
19287reference_type_def::reference_type_def(const environment& env, bool lvalue,
19288 size_t size_in_bits,
19289 size_t alignment_in_bits,
19290 const location& locus)
19291 : type_or_decl_base(env,
19292 REFERENCE_TYPE
19293 | ABSTRACT_TYPE_BASE
19294 | ABSTRACT_DECL_BASE),
19295 type_base(env, size_in_bits, alignment_in_bits),
19296 decl_base(env, "", locus, ""),
19297 priv_(new priv(lvalue))
19298{
19300 string name = "void&";
19301 if (!is_lvalue())
19302 name += "&";
19303
19304 set_name(env.intern(name));
19305 priv_->pointed_to_type_ = env.get_void_type();
19306}
19307
19308/// Return the hash value of the current IR node.
19309///
19310/// Note that upon the first invocation, this member functions
19311/// computes the hash value and returns it. Subsequent invocations
19312/// just return the hash value that was previously calculated.
19313///
19314/// @return the hash value of the current IR node.
19315hash_t
19317{
19319 return h;
19320}
19321
19322/// Setter of the pointed_to type of the current reference type.
19323///
19324/// @param pointed_to the new pointed to type.
19325void
19326reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
19327{
19328 ABG_ASSERT(pointed_to_type);
19329 priv_->pointed_to_type_ = pointed_to_type;
19330
19331 decl_base_sptr pto;
19332 try
19333 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
19334 catch (...)
19335 {}
19336
19337 if (pto)
19338 {
19339 set_visibility(pto->get_visibility());
19340 string name = string(pto->get_name()) + "&";
19341 if (!is_lvalue())
19342 name += "&";
19343 const environment& env = pto->get_environment();
19344 set_name(env.intern(name));
19345 }
19346}
19347
19348/// Compares two instances of @ref reference_type_def.
19349///
19350/// If the two intances are different, set a bitfield to give some
19351/// insight about the kind of differences there are.
19352///
19353/// @param l the first artifact of the comparison.
19354///
19355/// @param r the second artifact of the comparison.
19356///
19357/// @param k a pointer to a bitfield that gives information about the
19358/// kind of changes there are between @p l and @p r. This one is set
19359/// iff @p k is non-null and the function returns false.
19360///
19361/// Please note that setting k to a non-null value does have a
19362/// negative performance impact because even if @p l and @p r are not
19363/// equal, the function keeps up the comparison in order to determine
19364/// the different kinds of ways in which they are different.
19365///
19366/// @return true if @p l equals @p r, false otherwise.
19367bool
19369{
19370 if (l.is_lvalue() != r.is_lvalue())
19371 {
19372 if (k)
19374 ABG_RETURN_FALSE;
19375 }
19376 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
19377 bool result = p1 == p2;
19378 if (!result)
19379 if (k)
19380 {
19381 if (!types_have_similar_structure(&l, &r))
19383 *k |= SUBTYPE_CHANGE_KIND;
19384 }
19385 ABG_RETURN(result);
19386}
19387
19388/// Equality operator of the @ref reference_type_def type.
19389///
19390/// @param o the other instance of @ref reference_type_def to compare
19391/// against.
19392///
19393/// @return true iff the two instances are equal.
19394bool
19396{
19397 const reference_type_def* other =
19398 dynamic_cast<const reference_type_def*>(&o);
19399 if (!other)
19400 return false;
19401 return try_canonical_compare(this, other);
19402}
19403
19404/// Equality operator of the @ref reference_type_def type.
19405///
19406/// @param o the other instance of @ref reference_type_def to compare
19407/// against.
19408///
19409/// @return true iff the two instances are equal.
19410bool
19412{
19413 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19414 if (!other)
19415 return false;
19416 return *this == *other;
19417}
19418
19419/// Equality operator of the @ref reference_type_def type.
19420///
19421/// @param o the other instance of @ref reference_type_def to compare
19422/// against.
19423///
19424/// @return true iff the two instances are equal.
19425bool
19427{
19428 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19429 if (!other)
19430 return false;
19431 return *this == *other;
19432}
19433
19434type_base_sptr
19435reference_type_def::get_pointed_to_type() const
19436{return priv_->pointed_to_type_.lock();}
19437
19438bool
19439reference_type_def::is_lvalue() const
19440{return priv_->is_lvalue_;}
19441
19442/// Build and return the qualified name of the current instance of the
19443/// @ref reference_type_def.
19444///
19445/// @param qn output parameter. Is set to the newly-built qualified
19446/// name of the current instance of @ref reference_type_def.
19447///
19448/// @param internal set to true if the call is intended for an
19449/// internal use (for technical use inside the library itself), false
19450/// otherwise. If you don't know what this is for, then set it to
19451/// false.
19452void
19454{qn = get_qualified_name(internal);}
19455
19456/// Build, cache and return the qualified name of the current instance
19457/// of the @ref reference_type_def. Subsequent invocations of this
19458/// function return the cached value.
19459///
19460/// @param internal set to true if the call is intended for an
19461/// internal use (for technical use inside the library itself), false
19462/// otherwise. If you don't know what this is for, then set it to
19463/// false.
19464///
19465/// @return the newly-built qualified name of the current instance of
19466/// @ref reference_type_def.
19467const interned_string&
19469{
19470 type_base_sptr pointed_to_type = get_pointed_to_type();
19471 pointed_to_type = look_through_decl_only_type(pointed_to_type);
19472
19473 if (internal)
19474 {
19475 if (get_canonical_type())
19476 {
19477 if (priv_->internal_qualified_name_.empty())
19478 if (pointed_to_type)
19479 priv_->internal_qualified_name_ =
19480 get_name_of_reference_to_type(*pointed_to_type,
19481 is_lvalue(),
19482 /*qualified_name=*/
19483 is_typedef(pointed_to_type)
19484 ? false
19485 : true,
19486 /*internal=*/true);
19487 return priv_->internal_qualified_name_;
19488 }
19489 else
19490 {
19491 // As the type hasn't yet been canonicalized, its structure
19492 // (and so its name) can change. So let's invalidate the
19493 // cache where we store its name at each invocation of this
19494 // function.
19495 priv_->temp_internal_qualified_name_ =
19496 get_name_of_reference_to_type(*pointed_to_type,
19497 is_lvalue(),
19498 /*qualified_name=*/
19499 is_typedef(pointed_to_type)
19500 ? false
19501 : true,
19502 /*internal=*/true);
19503 return priv_->temp_internal_qualified_name_;
19504 }
19505 }
19506 else
19507 {
19509 {
19511 (get_name_of_reference_to_type(*pointed_to_type,
19512 is_lvalue(),
19513 /*qualified_name=*/true,
19514 /*internal=*/false));
19516 }
19517 else
19518 {
19519 // As the type hasn't yet been canonicalized, its structure
19520 // (and so its name) can change. So let's invalidate the
19521 // cache where we store its name at each invocation of this
19522 // function.
19523 if (pointed_to_type)
19525 (get_name_of_reference_to_type(*pointed_to_type,
19526 is_lvalue(),
19527 /*qualified_name=*/true,
19528 /*internal=*/false));
19530 }
19531 }
19532}
19533
19534/// Get the pretty representation of the current instance of @ref
19535/// reference_type_def.
19536///
19537/// @param internal set to true if the call is intended to get a
19538/// representation of the decl (or type) for the purpose of canonical
19539/// type comparison. This is mainly used in the function
19540/// homonym_type_group::get_canonical_type_for().
19541///
19542/// In other words if the argument for this parameter is true then the
19543/// call is meant for internal use (for technical use inside the
19544/// library itself), false otherwise. If you don't know what this is
19545/// for, then set it to false.
19546///
19547/// @param qualified_name if true, names emitted in the pretty
19548/// representation are fully qualified.
19549///
19550/// @return the pretty representatin of the @ref reference_type_def.
19551string
19553 bool qualified_name) const
19554{
19555 string result =
19557 (get_pointed_to_type()),
19558 is_lvalue(),
19559 qualified_name,
19560 internal);
19561
19562 return result;
19563}
19564
19565/// This implements the ir_traversable_base::traverse pure virtual
19566/// function.
19567///
19568/// @param v the visitor used on the current instance.
19569///
19570/// @return true if the entire IR node tree got traversed, false
19571/// otherwise.
19572bool
19574{
19575 if (v.type_node_has_been_visited(this))
19576 return true;
19577
19578 if (visiting())
19579 return true;
19580
19581 if (v.visit_begin(this))
19582 {
19583 visiting(true);
19584 if (type_base_sptr t = get_pointed_to_type())
19585 t->traverse(v);
19586 visiting(false);
19587 }
19588
19589 bool result = v.visit_end(this);
19591 return result;
19592}
19593
19594reference_type_def::~reference_type_def()
19595{}
19596
19597/// Turn equality of shared_ptr of @ref reference_type_def into a deep
19598/// equality; that is, make it compare the pointed to objects too.
19599///
19600/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
19601/// of the equality.
19602///
19603/// @param r the shared_ptr of @ref reference_type_def on
19604/// right-hand-side of the equality.
19605///
19606/// @return true if the @ref reference_type_def pointed to by the
19607/// shared_ptrs are equal, false otherwise.
19608bool
19610{
19611 if (l.get() == r.get())
19612 return true;
19613 if (!!l != !!r)
19614 return false;
19615
19616 return *l == *r;
19617}
19618
19619/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
19620/// equality; that is, make it compare the pointed to objects too.
19621///
19622/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
19623/// of the equality.
19624///
19625/// @param r the shared_ptr of @ref reference_type_def on
19626/// right-hand-side of the equality.
19627///
19628/// @return true iff the @ref reference_type_def pointed to by the
19629/// shared_ptrs are different.
19630bool
19633
19634// </reference_type_def definitions>
19635
19636// <ptr_to_mbr_type definitions>
19637
19638/// The private data type of @ref ptr_to_mbr_type.
19639struct ptr_to_mbr_type::priv
19640{
19641 // The type of the data member this pointer-to-member-type
19642 // designates.
19643 type_base_sptr dm_type_;
19644 // The class (or typedef to potentially qualified class) containing
19645 // the data member this pointer-to-member-type designates.
19646 type_base_sptr containing_type_;
19647 interned_string internal_qualified_name_;
19648 interned_string temp_internal_qualified_name_;
19649
19650 priv()
19651 {}
19652
19653 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
19654 : dm_type_(dm_type),
19655 containing_type_(containing_type)
19656 {}
19657};// end struct ptr_to_mbr_type::priv
19658
19659/// A constructor for a @ref ptr_to_mbr_type type.
19660///
19661/// @param env the environment to construct the @ref ptr_to_mbr_type in.
19662///
19663/// @param member_type the member type of the of the @ref
19664/// ptr_to_mbr_type to construct.
19665///
19666/// @param containing_type the containing type of the @ref
19667/// ptr_to_mbr_type to construct.
19668///
19669/// @param size_in_bits the size (in bits) of the resulting type.
19670///
19671/// @param alignment_in_bits the alignment (in bits) of the resulting
19672/// type.
19673///
19674/// @param locus the source location of the definition of the
19675/// resulting type.
19676ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
19677 const type_base_sptr& member_type,
19678 const type_base_sptr& containing_type,
19679 size_t size_in_bits,
19680 size_t alignment_in_bits,
19681 const location& locus)
19682 : type_or_decl_base(env,
19683 POINTER_TO_MEMBER_TYPE
19684 | ABSTRACT_TYPE_BASE
19685 | ABSTRACT_DECL_BASE),
19686 type_base(env, size_in_bits, alignment_in_bits),
19687 decl_base(env, "", locus, ""),
19688 priv_(new priv(member_type, containing_type))
19689{
19691 ABG_ASSERT(member_type);
19692 ABG_ASSERT(containing_type);
19693 set_is_anonymous(false);
19694}
19695
19696/// Getter of the name of the current ptr-to-mbr-type.
19697///
19698/// This just returns the qualified name.
19699///
19700/// @return the (qualified) name of the the type.
19701const interned_string&
19703{
19704 return get_qualified_name(/*internal=*/false);
19705}
19706
19707/// Return the hash value of the current IR node.
19708///
19709/// Note that upon the first invocation, this member functions
19710/// computes the hash value and returns it. Subsequent invocations
19711/// just return the hash value that was previously calculated.
19712///
19713/// @return the hash value of the current IR node.
19714hash_t
19716{
19718 return h;
19719}
19720
19721/// Getter of the member type of the current @ref ptr_to_mbr_type.
19722///
19723/// @return the type of the member referred to by the current
19724/// @ptr_to_mbr_type.
19725const type_base_sptr&
19727{return priv_->dm_type_;}
19728
19729/// Getter of the type containing the member pointed-to by the current
19730/// @ref ptr_to_mbr_type.
19731///
19732/// @return the type containing the member pointed-to by the current
19733/// @ref ptr_to_mbr_type.
19734const type_base_sptr&
19736{return priv_->containing_type_;}
19737
19738/// Equality operator for the current @ref ptr_to_mbr_type.
19739///
19740///@param o the other instance of @ref ptr_to_mbr_type to compare the
19741///current instance to.
19742///
19743/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
19744bool
19746{
19747 const ptr_to_mbr_type* other =
19748 dynamic_cast<const ptr_to_mbr_type*>(&o);
19749 if (!other)
19750 return false;
19751 return try_canonical_compare(this, other);
19752}
19753
19754/// Equality operator for the current @ref ptr_to_mbr_type.
19755///
19756///@param o the other instance of @ref ptr_to_mbr_type to compare the
19757///current instance to.
19758///
19759/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
19760bool
19762{
19763 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19764 if (!other)
19765 return false;
19766 return *this == *other;
19767}
19768
19769/// Equality operator for the current @ref ptr_to_mbr_type.
19770///
19771///@param o the other instance of @ref ptr_to_mbr_type to compare the
19772///current instance to.
19773///
19774/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
19775bool
19777{
19778 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19779 if (!other)
19780 return false;
19781 return *this == *other;
19782}
19783
19784/// Get the qualified name for the current @ref ptr_to_mbr_type.
19785///
19786/// @param qualified_name out parameter. This is set to the name of
19787/// the current @ref ptr_to_mbr_type.
19788///
19789/// @param internal if this is true, then the qualified name is for
19790/// the purpose of type canoicalization.
19791void
19793 bool internal) const
19794{qualified_name = get_qualified_name(internal);}
19795
19796/// Get the qualified name for the current @ref ptr_to_mbr_type.
19797///
19798/// @param internal if this is true, then the qualified name is for
19799/// the purpose of type canoicalization.
19800///
19801/// @return the qualified name for the current @ref ptr_to_mbr_type.
19802const interned_string&
19804{
19805 type_base_sptr member_type = get_member_type();
19806 type_base_sptr containing_type = get_containing_type();
19807
19808 if (internal)
19809 {
19810 if (get_canonical_type())
19811 {
19812 if (priv_->internal_qualified_name_.empty())
19813 priv_->internal_qualified_name_ =
19814 ptr_to_mbr_declaration_name(this, "",
19815 /*qualified=*/true,
19816 internal);
19817 return priv_->internal_qualified_name_;
19818 }
19819 else
19820 {
19821 priv_->temp_internal_qualified_name_ =
19822 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
19823 return priv_->temp_internal_qualified_name_;
19824 }
19825 }
19826 else
19827 {
19829 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
19830 /*internal=*/false));
19832 }
19833}
19834
19835/// This implements the ir_traversable_base::traverse pure virtual
19836/// function for @ref ptr_to_mbr_type.
19837///
19838/// @param v the visitor used on the current instance.
19839///
19840/// @return true if the entire IR node tree got traversed, false
19841/// otherwise.
19842bool
19844{
19845 if (v.type_node_has_been_visited(this))
19846 return true;
19847
19848 if (visiting())
19849 return true;
19850
19851 if (v.visit_begin(this))
19852 {
19853 visiting(true);
19854 if (type_base_sptr t = get_member_type())
19855 t->traverse(v);
19856
19857 if (type_base_sptr t = get_containing_type())
19858 t->traverse(v);
19859 visiting(false);
19860 }
19861
19862 bool result = v.visit_end(this);
19864 return result;
19865}
19866
19867/// Desctructor for @ref ptr_to_mbr_type.
19870
19871
19872/// Compares two instances of @ref ptr_to_mbr_type.
19873///
19874/// If the two intances are different, set a bitfield to give some
19875/// insight about the kind of differences there are.
19876///
19877/// @param l the first artifact of the comparison.
19878///
19879/// @param r the second artifact of the comparison.
19880///
19881/// @param k a pointer to a bitfield that gives information about the
19882/// kind of changes there are between @p l and @p r. This one is set
19883/// iff @p k is non-null and the function returns false.
19884///
19885/// Please note that setting k to a non-null value does have a
19886/// negative performance impact because even if @p l and @p r are not
19887/// equal, the function keeps up the comparison in order to determine
19888/// the different kinds of ways in which they are different.
19889///
19890/// @return true if @p l equals @p r, false otherwise.
19891bool
19893{
19894 bool result = true;
19895
19896 if (!(l.decl_base::operator==(r)))
19897 {
19898 result = false;
19899 if (k)
19901 else
19902 result = false;
19903 }
19904
19905 if (l.get_member_type() != r.get_member_type())
19906 {
19907 if (k)
19908 {
19909 if (!types_have_similar_structure(&l, &r))
19911 *k |= SUBTYPE_CHANGE_KIND;
19912 }
19913 result = false;
19914 }
19915
19917 {
19918 if (k)
19919 {
19920 if (!types_have_similar_structure(&l, &r))
19922 *k |= SUBTYPE_CHANGE_KIND;
19923 }
19924 result = false;
19925 }
19926
19927 ABG_RETURN(result);
19928}
19929
19930// </ptr_to_mbr_type definitions>
19931
19932// <array_type_def definitions>
19933
19934// <array_type_def::subrange_type>
19935array_type_def::subrange_type::~subrange_type() = default;
19936
19937// <array_type_def::subrante_type::bound_value>
19938
19939/// Default constructor of the @ref
19940/// array_type_def::subrange_type::bound_value class.
19941///
19942/// Constructs an unsigned bound_value of value zero.
19944 : s_(UNSIGNED_SIGNEDNESS)
19945{
19946 v_.unsigned_ = 0;
19947}
19948
19949/// Initialize an unsigned bound_value with a given value.
19950///
19951/// @param v the initial bound value.
19953 : s_(UNSIGNED_SIGNEDNESS)
19954{
19955 v_.unsigned_ = v;
19956}
19957
19958/// Initialize a signed bound_value with a given value.
19959///
19960/// @param v the initial bound value.
19962 : s_(SIGNED_SIGNEDNESS)
19963{
19964 v_.signed_ = v;
19965}
19966
19967/// Getter of the signedness (unsigned VS signed) of the bound value.
19968///
19969/// @return the signedness of the bound value.
19970enum array_type_def::subrange_type::bound_value::signedness
19973
19974/// Setter of the signedness (unsigned VS signed) of the bound value.
19975///
19976/// @param s the new signedness of the bound value.
19977void
19980
19981/// Getter of the bound value as a signed value.
19982///
19983/// @return the bound value as signed.
19984int64_t
19988
19989/// Getter of the bound value as an unsigned value.
19990///
19991/// @return the bound value as unsigned.
19992uint64_t
19995
19996/// Setter of the bound value as unsigned.
19997///
19998/// @param v the new unsigned value.
19999void
20001{
20002 s_ = UNSIGNED_SIGNEDNESS;
20003 v_.unsigned_ = v;
20004}
20005
20006/// Setter of the bound value as signed.
20007///
20008/// @param v the new signed value.
20009void
20011{
20012 s_ = SIGNED_SIGNEDNESS;
20013 v_.signed_ = v;
20014}
20015
20016/// Equality operator of the bound value.
20017///
20018/// @param v the other bound value to compare with.
20019///
20020/// @return true iff the current bound value equals @p v.
20021bool
20023{
20024 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
20025}
20026
20027// </array_type_def::subrante_type::bound_value>
20028
20029struct array_type_def::subrange_type::priv
20030{
20031 bound_value lower_bound_;
20032 bound_value upper_bound_;
20033 type_base_wptr underlying_type_;
20035 bool infinite_;
20036
20037 priv(bound_value ub,
20038 translation_unit::language l = translation_unit::LANG_C11)
20039 : upper_bound_(ub), language_(l), infinite_(false)
20040 {}
20041
20042 priv(bound_value lb, bound_value ub,
20043 translation_unit::language l = translation_unit::LANG_C11)
20044 : lower_bound_(lb), upper_bound_(ub),
20045 language_(l), infinite_(false)
20046 {}
20047
20048 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
20049 translation_unit::language l = translation_unit::LANG_C11)
20050 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
20051 language_(l), infinite_(false)
20052 {}
20053};
20054
20055/// Constructor of an array_type_def::subrange_type type.
20056///
20057/// @param env the environment this type was created from.
20058///
20059/// @param name the name of the subrange type.
20060///
20061/// @param lower_bound the lower bound of the array. This is
20062/// generally zero (at least for C and C++).
20063///
20064/// @param upper_bound the upper bound of the array.
20065///
20066/// @param underlying_type the underlying type of the subrange type.
20067///
20068/// @param loc the source location where the type is defined.
20069array_type_def::subrange_type::subrange_type(const environment& env,
20070 const string& name,
20071 bound_value lower_bound,
20072 bound_value upper_bound,
20073 const type_base_sptr& utype,
20074 const location& loc,
20076 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
20077 type_base(env,
20078 utype
20079 ? utype->get_size_in_bits()
20080 : 0,
20081 0),
20082 decl_base(env, name, loc, ""),
20083 priv_(new priv(lower_bound, upper_bound, utype, l))
20084{
20086}
20087
20088/// Constructor of the array_type_def::subrange_type type.
20089///
20090/// @param env the environment this type is being created in.
20091///
20092/// @param name the name of the subrange type.
20093///
20094/// @param lower_bound the lower bound of the array. This is
20095/// generally zero (at least for C and C++).
20096///
20097/// @param upper_bound the upper bound of the array.
20098///
20099/// @param loc the source location where the type is defined.
20100///
20101/// @param l the language that generated this subrange.
20102array_type_def::subrange_type::subrange_type(const environment& env,
20103 const string& name,
20104 bound_value lower_bound,
20105 bound_value upper_bound,
20106 const location& loc,
20108 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
20109 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
20110 decl_base(env, name, loc, ""),
20111 priv_(new priv(lower_bound, upper_bound, l))
20112{
20114}
20115
20116/// Constructor of the array_type_def::subrange_type type.
20117///
20118/// @param env the environment this type is being created from.
20119///
20120/// @param name of the name of type.
20121///
20122/// @param upper_bound the upper bound of the array. The lower bound
20123/// is considered to be zero.
20124///
20125/// @param loc the source location of the type.
20126///
20127/// @param the language that generated this type.
20128array_type_def::subrange_type::subrange_type(const environment& env,
20129 const string& name,
20130 bound_value upper_bound,
20131 const location& loc,
20133 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
20134 type_base(env, upper_bound.get_unsigned_value(), 0),
20135 decl_base(env, name, loc, ""),
20136 priv_(new priv(upper_bound, l))
20137{
20139}
20140
20141/// Return the hash value of the current IR node.
20142///
20143/// Note that upon the first invocation, this member functions
20144/// computes the hash value and returns it. Subsequent invocations
20145/// just return the hash value that was previously calculated.
20146///
20147/// @return the hash value of the current IR node.
20148hash_t
20150{
20152 return h;
20153}
20154
20155/// Getter of the underlying type of the subrange, that is, the type
20156/// that defines the range.
20157///
20158/// @return the underlying type.
20159type_base_sptr
20161{return priv_->underlying_type_.lock();}
20162
20163/// Setter of the underlying type of the subrange, that is, the type
20164/// that defines the range.
20165///
20166/// @param u the new underlying type.
20167void
20169{
20170 ABG_ASSERT(priv_->underlying_type_.expired());
20171 priv_->underlying_type_ = u;
20172 if (u)
20173 set_size_in_bits(u->get_size_in_bits());
20174}
20175
20176/// Getter of the upper bound of the subrange type.
20177///
20178/// @return the upper bound of the subrange type.
20179int64_t
20181{return priv_->upper_bound_.get_signed_value();}
20182
20183/// Getter of the lower bound of the subrange type.
20184///
20185/// @return the lower bound of the subrange type.
20186int64_t
20188{return priv_->lower_bound_.get_signed_value();}
20189
20190/// Setter of the upper bound of the subrange type.
20191///
20192/// @param ub the new value of the upper bound.
20193void
20195{priv_->upper_bound_ = ub;}
20196
20197/// Setter of the lower bound.
20198///
20199/// @param lb the new value of the lower bound.
20200void
20202{priv_->lower_bound_ = lb;}
20203
20204/// Getter of the length of the subrange type.
20205///
20206/// Note that a length of zero means the array has an infinite (or
20207/// rather a non-known) size.
20208///
20209/// @return the length of the subrange type.
20210uint64_t
20212{
20213 if (is_non_finite())
20214 return 0;
20215
20216 // A subrange can have an upper bound that is lower than its lower
20217 // bound. This is possible in Ada for instance. In that case, the
20218 // length of the subrange is considered to be zero.
20219 if (get_upper_bound() >= get_lower_bound())
20220 return get_upper_bound() - get_lower_bound() + 1;
20221 return 0;
20222}
20223
20224/// Test if the length of the subrange type is infinite.
20225///
20226/// @return true iff the length of the subrange type is infinite.
20227bool
20229{return priv_->infinite_;}
20230
20231/// Set the infinite-ness status of the subrange type.
20232///
20233/// @param f true iff the length of the subrange type should be set to
20234/// being infinite.
20235void
20237{priv_->infinite_ = f;}
20238
20239/// Getter of the language that generated this type.
20240///
20241/// @return the language of this type.
20244{return priv_->language_;}
20245
20246/// Return a string representation of the sub range.
20247///
20248/// @return the string representation of the sub range.
20249string
20251{
20252 std::ostringstream o;
20253
20255 {
20256 type_base_sptr underlying_type = get_underlying_type();
20257 if (underlying_type)
20258 o << ir::get_pretty_representation(underlying_type, false) << " ";
20259 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
20260 }
20261 else if (is_non_finite())
20262 o << "[]";
20263 else
20264 o << "[" << get_length() << "]";
20265
20266 return o.str();
20267}
20268
20269/// Return a string representation of a vector of subranges
20270///
20271/// @return the string representation of a vector of sub ranges.
20272string
20274{
20275 if (v.empty())
20276 return "[]";
20277
20278 string r;
20279 for (vector<subrange_sptr>::const_iterator i = v.begin();
20280 i != v.end();
20281 ++i)
20282 r += (*i)->as_string();
20283
20284 return r;
20285}
20286
20287/// Compares two isntances of @ref array_type_def::subrange_type.
20288///
20289/// If the two intances are different, set a bitfield to give some
20290/// insight about the kind of differences there are.
20291///
20292/// @param l the first artifact of the comparison.
20293///
20294/// @param r the second artifact of the comparison.
20295///
20296/// @param k a pointer to a bitfield that gives information about the
20297/// kind of changes there are between @p l and @p r. This one is set
20298/// iff @p k is non-null and the function returns false.
20299///
20300/// Please note that setting k to a non-null value does have a
20301/// negative performance impact because even if @p l and @p r are not
20302/// equal, the function keeps up the comparison in order to determine
20303/// the different kinds of ways in which they are different.
20304///
20305/// @return true if @p l equals @p r, false otherwise.
20306bool
20309 change_kind* k)
20310{
20311 bool result = true;
20312
20313 if (l.get_lower_bound() != r.get_lower_bound()
20314 || l.get_upper_bound() != r.get_upper_bound()
20315 || l.get_name() != r.get_name())
20316 {
20317 result = false;
20318 if (k)
20320 else
20321 ABG_RETURN(result);
20322 }
20323
20324 if (l.get_underlying_type()
20325 && r.get_underlying_type()
20326 && (*l.get_underlying_type() != *r.get_underlying_type()))
20327 {
20328 result = false;
20329 if (k)
20330 *k |= SUBTYPE_CHANGE_KIND;
20331 else
20332 ABG_RETURN(result);
20333 }
20334
20335 ABG_RETURN(result);
20336}
20337
20338/// Equality operator.
20339///
20340/// @param o the other subrange to test against.
20341///
20342/// @return true iff @p o equals the current instance of
20343/// array_type_def::subrange_type.
20344bool
20346{
20347 const subrange_type* other =
20348 dynamic_cast<const subrange_type*>(&o);
20349 if (!other)
20350 return false;
20351 return try_canonical_compare(this, other);
20352}
20353
20354/// Equality operator.
20355///
20356/// @param o the other subrange to test against.
20357///
20358/// @return true iff @p o equals the current instance of
20359/// array_type_def::subrange_type.
20360bool
20362{
20363 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20364 if (!other)
20365 return false;
20366 return *this == *other;
20367}
20368
20369/// Equality operator.
20370///
20371/// @param o the other subrange to test against.
20372///
20373/// @return true iff @p o equals the current instance of
20374/// array_type_def::subrange_type.
20375bool
20377{
20378 const type_base &t = o;
20379 return operator==(t);
20380}
20381
20382/// Equality operator.
20383///
20384/// @param o the other subrange to test against.
20385///
20386/// @return true iff @p o equals the current instance of
20387/// array_type_def::subrange_type.
20388bool
20391
20392/// Equality operator.
20393///
20394/// @param o the other subrange to test against.
20395///
20396/// @return true iff @p o equals the current instance of
20397/// array_type_def::subrange_type.
20398bool
20401
20402/// Inequality operator.
20403///
20404/// @param o the other subrange to test against.
20405///
20406/// @return true iff @p o is different from the current instance of
20407/// array_type_def::subrange_type.
20408bool
20411
20412/// Build a pretty representation for an
20413/// array_type_def::subrange_type.
20414///
20415/// @param internal set to true if the call is intended to get a
20416/// representation of the decl (or type) for the purpose of canonical
20417/// type comparison. This is mainly used in the function
20418/// homonym_type_group::get_canonical_type_for().
20419///
20420/// In other words if the argument for this parameter is true then the
20421/// call is meant for internal use (for technical use inside the
20422/// library itself), false otherwise. If you don't know what this is
20423/// for, then set it to false.
20424///
20425/// @return a copy of the pretty representation of the current
20426/// instance of typedef_decl.
20427string
20429{
20430 string name = get_name();
20431 string repr;
20432
20433 if (name.empty())
20434 repr += "<anonymous range>";
20435 else
20436 repr += "<range " + get_name() + ">";
20437 repr += as_string();
20438
20439 return repr;
20440}
20441
20442/// This implements the ir_traversable_base::traverse pure virtual
20443/// function.
20444///
20445/// @param v the visitor used on the current instance.
20446///
20447/// @return true if the entire IR node tree got traversed, false
20448/// otherwise.
20449bool
20451{
20452 if (v.type_node_has_been_visited(this))
20453 return true;
20454
20455 if (v.visit_begin(this))
20456 {
20457 visiting(true);
20458 if (type_base_sptr u = get_underlying_type())
20459 u->traverse(v);
20460 visiting(false);
20461 }
20462
20463 bool result = v.visit_end(this);
20465 return result;
20466}
20467
20468// </array_type_def::subrange_type>
20469
20470struct array_type_def::priv
20471{
20472 type_base_wptr element_type_;
20473 subranges_type subranges_;
20474 interned_string temp_internal_qualified_name_;
20475 interned_string internal_qualified_name_;
20476
20477 priv(type_base_sptr t)
20478 : element_type_(t)
20479 {}
20480
20481 priv(type_base_sptr t, subranges_type subs)
20482 : element_type_(t), subranges_(subs)
20483 {}
20484
20485 priv()
20486 {}
20487};
20488
20489/// Constructor for the type array_type_def
20490///
20491/// Note how the constructor expects a vector of subrange
20492/// objects. Parsing of the array information always entails
20493/// parsing the subrange info as well, thus the class subrange_type
20494/// is defined inside class array_type_def and also parsed
20495/// simultaneously.
20496///
20497/// @param e_type the type of the elements contained in the array
20498///
20499/// @param subs a vector of the array's subranges(dimensions)
20500///
20501/// @param locus the source location of the array type definition.
20502array_type_def::array_type_def(const type_base_sptr e_type,
20503 const std::vector<subrange_sptr>& subs,
20504 const location& locus)
20506 ARRAY_TYPE
20507 | ABSTRACT_TYPE_BASE
20508 | ABSTRACT_DECL_BASE),
20509 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
20510 decl_base(e_type->get_environment(), locus),
20511 priv_(new priv(e_type))
20512{
20514 append_subranges(subs);
20515}
20516
20517/// Constructor for the type array_type_def
20518///
20519/// This constructor builds a temporary array that has no element type
20520/// associated. Later when the element type is available, it be set
20521/// with the array_type_def::set_element_type() member function.
20522///
20523/// Note how the constructor expects a vector of subrange
20524/// objects. Parsing of the array information always entails
20525/// parsing the subrange info as well, thus the class subrange_type
20526/// is defined inside class array_type_def and also parsed
20527/// simultaneously.
20528///
20529/// @param env the environment of the array type.
20530///
20531/// @param subs a vector of the array's subranges(dimensions)
20532///
20533/// @param locus the source location of the array type definition.
20534array_type_def::array_type_def(const environment& env,
20535 const std::vector<subrange_sptr>& subs,
20536 const location& locus)
20537 : type_or_decl_base(env,
20538 ARRAY_TYPE
20539 | ABSTRACT_TYPE_BASE
20540 | ABSTRACT_DECL_BASE),
20541 type_base(env, 0, 0),
20542 decl_base(env, locus),
20543 priv_(new priv)
20544{
20546 append_subranges(subs);
20547}
20548
20549/// Return the hash value of the current IR node.
20550///
20551/// Note that upon the first invocation, this member functions
20552/// computes the hash value and returns it. Subsequent invocations
20553/// just return the hash value that was previously calculated.
20554///
20555/// @return the hash value of the current IR node.
20556hash_t
20558{
20560 return h;
20561}
20562
20563/// Update the size of the array.
20564///
20565/// This function computes the size of the array and sets it using
20566/// type_base::set_size_in_bits().
20567void
20568array_type_def::update_size()
20569{
20570 type_base_sptr e = get_element_type();
20571 if (e)
20572 {
20573 size_t s = e->get_size_in_bits();
20574 if (s)
20575 {
20576 for (const auto &sub : get_subranges())
20577 s *= sub->get_length();
20579 }
20580 set_alignment_in_bits(e->get_alignment_in_bits());
20581 }
20582}
20583
20584string
20585array_type_def::get_subrange_representation() const
20586{
20588 return r;
20589}
20590
20591/// Get the pretty representation of the current instance of @ref
20592/// array_type_def.
20593///
20594/// @param internal set to true if the call is intended to get a
20595/// representation of the decl (or type) for the purpose of canonical
20596/// type comparison. This is mainly used in the function
20597/// homonym_type_group::get_canonical_type_for().
20598///
20599/// In other words if the argument for this parameter is true then the
20600/// call is meant for internal use (for technical use inside the
20601/// library itself), false otherwise. If you don't know what this is
20602/// for, then set it to false.
20603/// @param internal set to true if the call is intended for an
20604/// internal use (for technical use inside the library itself), false
20605/// otherwise. If you don't know what this is for, then set it to
20606/// false.
20607///
20608/// @return the pretty representation of the ABI artifact.
20609string
20611 bool qualified_name) const
20612{
20613 return array_declaration_name(this, /*variable_name=*/"",
20614 qualified_name, internal);
20615}
20616
20617/// Compares two instances of @ref array_type_def.
20618///
20619/// If the two intances are different, set a bitfield to give some
20620/// insight about the kind of differences there are.
20621///
20622/// @param l the first artifact of the comparison.
20623///
20624/// @param r the second artifact of the comparison.
20625///
20626/// @param k a pointer to a bitfield that gives information about the
20627/// kind of changes there are between @p l and @p r. This one is set
20628/// iff @p k is non-null and the function returns false.
20629///
20630/// Please note that setting k to a non-null value does have a
20631/// negative performance impact because even if @p l and @p r are not
20632/// equal, the function keeps up the comparison in order to determine
20633/// the different kinds of ways in which they are different.
20634///
20635/// @return true if @p l equals @p r, false otherwise.
20636bool
20638{
20639 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
20640 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
20641
20642 bool result = true;
20643 if (this_subs.size() != other_subs.size())
20644 {
20645 result = false;
20646 if (k)
20648 else
20649 ABG_RETURN_FALSE;
20650 }
20651
20652 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
20653 for (i = this_subs.begin(), j = other_subs.begin();
20654 i != this_subs.end() && j != other_subs.end();
20655 ++i, ++j)
20656 if (**i != **j)
20657 {
20658 result = false;
20659 if (k)
20660 {
20662 break;
20663 }
20664 else
20665 ABG_RETURN_FALSE;
20666 }
20667
20668 // Compare the element types modulo the typedefs they might have
20669 if (l.get_element_type() != r.get_element_type())
20670 {
20671 result = false;
20672 if (k)
20673 *k |= SUBTYPE_CHANGE_KIND;
20674 else
20675 ABG_RETURN_FALSE;
20676 }
20677
20678 ABG_RETURN(result);
20679}
20680
20681/// Test if two array types are equals modulo CV qualifiers.
20682///
20683/// @param l the first array of the comparison.
20684///
20685/// @param r the second array of the comparison.
20686///
20687/// @return true iff @p l equals @p r or, if they are different, the
20688/// difference between the too is just a matter of CV qualifiers.
20689bool
20691{
20692 if (l == r)
20693 return true;
20694
20695 if (!l || !r)
20696 ABG_RETURN_FALSE;
20697
20700
20701 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
20702 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
20703
20704 if (this_subs.size() != other_subs.size())
20705 ABG_RETURN_FALSE;
20706
20707 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
20708 for (i = this_subs.begin(), j = other_subs.begin();
20709 i != this_subs.end() && j != other_subs.end();
20710 ++i, ++j)
20711 if (**i != **j)
20712 ABG_RETURN_FALSE;
20713
20714 type_base *first_element_type =
20716 type_base *second_element_type =
20718
20719 if (*first_element_type != *second_element_type)
20720 ABG_RETURN_FALSE;
20721
20722 return true;
20723}
20724
20725/// Test if two array types are equals modulo CV qualifiers.
20726///
20727/// @param l the first array of the comparison.
20728///
20729/// @param r the second array of the comparison.
20730///
20731/// @return true iff @p l equals @p r or, if they are different, the
20732/// difference between the too is just a matter of CV qualifiers.
20733bool
20735 const array_type_def_sptr& r)
20736{return equals_modulo_cv_qualifier(l.get(), r.get());}
20737
20738/// Test if two pointer types are equals modulo CV qualifiers.
20739///
20740/// @param l the first pointer of the comparison.
20741///
20742/// @param r the second pointer of the comparison.
20743///
20744/// @return true iff @p l equals @p r or, if they are different, the
20745/// difference between the too is just a matter of CV qualifiers.
20746bool
20748{
20749 if (l == r)
20750 return true;
20751
20752 if (!l || !r)
20753 ABG_RETURN_FALSE;
20754
20755 type_base_sptr l_ptt = l->get_pointed_to_type(),
20756 r_ptt = r->get_pointed_to_type();
20757
20758 do
20759 {
20760 l_ptt = peel_qualified_or_typedef_type(l_ptt);
20761 r_ptt = peel_qualified_or_typedef_type(r_ptt);
20762
20763 l_ptt = is_pointer_type(l_ptt)
20765 : l_ptt;
20766
20767 r_ptt = is_pointer_type(r_ptt)
20769 : r_ptt;
20770 } while (is_pointer_type(l_ptt) && is_pointer_type(r_ptt));
20771
20772 l_ptt = peel_qualified_or_typedef_type(l_ptt);
20773 r_ptt = peel_qualified_or_typedef_type(r_ptt);
20774
20775 return *l_ptt == *r_ptt;
20776}
20777
20778/// Test if two pointer types are equals modulo CV qualifiers.
20779///
20780/// @param l the first pointer of the comparison.
20781///
20782/// @param r the second pointer of the comparison.
20783///
20784/// @return true iff @p l equals @p r or, if they are different, the
20785/// difference between the too is just a matter of CV qualifiers.
20786bool
20790
20791/// Get the language of the array.
20792///
20793/// @return the language of the array.
20796{
20797 const std::vector<subrange_sptr>& subranges =
20798 get_subranges();
20799
20800 if (subranges.empty())
20801 return translation_unit::LANG_C11;
20802 return subranges.front()->get_language();
20803}
20804
20805bool
20807{
20808 const array_type_def* other =
20809 dynamic_cast<const array_type_def*>(&o);
20810 if (!other)
20811 return false;
20812 return try_canonical_compare(this, other);
20813}
20814
20815bool
20817{
20818 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20819 if (!other)
20820 return false;
20821 return *this == *other;
20822}
20823
20824/// Getter of the type of an array element.
20825///
20826/// @return the type of an array element.
20827const type_base_sptr
20829{return priv_->element_type_.lock();}
20830
20831/// Setter of the type of array element.
20832///
20833/// Beware that after using this function, one might want to
20834/// re-compute the canonical type of the array, if one has already
20835/// been computed.
20836///
20837/// The intended use of this method is to permit in-place adjustment
20838/// of the element type's qualifiers. In particular, the size of the
20839/// element type should not be changed.
20840///
20841/// @param element_type the new element type to set.
20842void
20843array_type_def::set_element_type(const type_base_sptr& element_type)
20844{
20845 priv_->element_type_ = element_type;
20846 update_size();
20848}
20849
20850/// Append subranges from the vector @param subs to the current
20851/// vector of subranges.
20852void
20853array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
20854{
20855
20856 for (const auto &sub : subs)
20857 priv_->subranges_.push_back(sub);
20858
20859 update_size();
20861}
20862
20863/// @return true if one of the sub-ranges of the array is infinite, or
20864/// if the array has no sub-range at all, also meaning that the size
20865/// of the array is infinite.
20866bool
20868{
20869 if (priv_->subranges_.empty())
20870 return true;
20871
20872 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
20873 priv_->subranges_.begin();
20874 i != priv_->subranges_.end();
20875 ++i)
20876 if ((*i)->is_non_finite())
20877 return true;
20878
20879 return false;
20880}
20881
20882int
20883array_type_def::get_dimension_count() const
20884{return priv_->subranges_.size();}
20885
20886/// Build and return the qualified name of the current instance of the
20887/// @ref array_type_def.
20888///
20889/// @param qn output parameter. Is set to the newly-built qualified
20890/// name of the current instance of @ref array_type_def.
20891///
20892/// @param internal set to true if the call is intended for an
20893/// internal use (for technical use inside the library itself), false
20894/// otherwise. If you don't know what this is for, then set it to
20895/// false.
20896void
20898{qn = get_qualified_name(internal);}
20899
20900/// Compute the qualified name of the array.
20901///
20902/// @param internal set to true if the call is intended for an
20903/// internal use (for technical use inside the library itself), false
20904/// otherwise. If you don't know what this is for, then set it to
20905/// false.
20906///
20907/// @return the resulting qualified name.
20908const interned_string&
20910{
20911 if (internal)
20912 {
20913 if (get_canonical_type())
20914 {
20915 if (priv_->internal_qualified_name_.empty())
20916 priv_->internal_qualified_name_ =
20917 array_declaration_name(this, /*variable_name=*/"",
20918 /*qualified=*/false,
20919 /*internal=*/true);
20920 return priv_->internal_qualified_name_;
20921 }
20922 else
20923 {
20924 priv_->temp_internal_qualified_name_ =
20925 array_declaration_name(this, /*variable_name=*/"",
20926 /*qualified*/false, /*internal*/true);
20927 return priv_->temp_internal_qualified_name_;
20928 }
20929 }
20930 else
20931 {
20932 if (get_canonical_type())
20933 {
20934 if (decl_base::peek_qualified_name().empty())
20935 set_qualified_name(array_declaration_name(this,
20936 /*variable_name=*/"",
20937 /*qualified=*/false,
20938 /*internal=*/false));
20940 }
20941 else
20942 {
20944 (array_declaration_name(this, /*variable_name=*/"",
20945 /*qualified=*/false,
20946 /*internal=*/false));
20948 }
20949 }
20950}
20951
20952/// This implements the ir_traversable_base::traverse pure virtual
20953/// function.
20954///
20955/// @param v the visitor used on the current instance.
20956///
20957/// @return true if the entire IR node tree got traversed, false
20958/// otherwise.
20959bool
20961{
20962 if (v.type_node_has_been_visited(this))
20963 return true;
20964
20965 if (visiting())
20966 return true;
20967
20968 if (v.visit_begin(this))
20969 {
20970 visiting(true);
20971 if (type_base_sptr t = get_element_type())
20972 t->traverse(v);
20973
20974 for (type_base_sptr subrange : get_subranges())
20975 subrange->traverse(v);
20976
20977 visiting(false);
20978 }
20979
20980 bool result = v.visit_end(this);
20982 return result;
20983}
20984
20985const location&
20986array_type_def::get_location() const
20987{return decl_base::get_location();}
20988
20989/// Get the array's subranges
20990const std::vector<array_type_def::subrange_sptr>&
20992{return priv_->subranges_;}
20993
20994array_type_def::~array_type_def()
20995{}
20996
20997// </array_type_def definitions>
20998
20999// <enum_type_decl definitions>
21000
21001class enum_type_decl::priv
21002{
21003 recursive_mutex mutex_;
21004 type_base_sptr underlying_type_;
21005 enumerators enumerators_;
21006 mutable enumerators sorted_enumerators_;
21007
21008 friend class enum_type_decl;
21009
21010 priv();
21011
21012public:
21013 priv(type_base_sptr underlying_type,
21015 : underlying_type_(underlying_type),
21016 enumerators_(enumerators)
21017 {}
21018}; // end class enum_type_decl::priv
21019
21020/// Constructor.
21021///
21022/// @param name the name of the type declaration.
21023///
21024/// @param locus the source location where the type was defined.
21025///
21026/// @param underlying_type the underlying type of the enum.
21027///
21028/// @param enums the enumerators of this enum type.
21029///
21030/// @param linkage_name the linkage name of the enum.
21031///
21032/// @param vis the visibility of the enum type.
21033enum_type_decl::enum_type_decl(const string& name,
21034 const location& locus,
21035 type_base_sptr underlying_type,
21036 enumerators& enums,
21037 const string& linkage_name,
21038 visibility vis)
21039 : type_or_decl_base(underlying_type->get_environment(),
21040 ENUM_TYPE
21041 | ABSTRACT_TYPE_BASE
21042 | ABSTRACT_DECL_BASE),
21043 type_base(underlying_type->get_environment(),
21044 underlying_type->get_size_in_bits(),
21045 underlying_type->get_alignment_in_bits()),
21046 decl_base(underlying_type->get_environment(),
21047 name, locus, linkage_name, vis),
21048 priv_(new priv(underlying_type, enums))
21049{
21051 for (enumerators::iterator e = get_enumerators().begin();
21052 e != get_enumerators().end();
21053 ++e)
21054 e->set_enum_type(this);
21055}
21056
21057/// Return the hash value of the current IR node.
21058///
21059/// Note that upon the first invocation, this member functions
21060/// computes the hash value and returns it. Subsequent invocations
21061/// just return the hash value that was previously calculated.
21062///
21063/// @return the hash value of the current IR node.
21064hash_t
21066{
21068 return h;
21069}
21070
21071/// Return the underlying type of the enum.
21072type_base_sptr
21074{return priv_->underlying_type_;}
21075
21076/// @return the list of enumerators of the enum.
21079{return priv_->enumerators_;}
21080
21081/// @return the list of enumerators of the enum.
21084{return priv_->enumerators_;}
21085
21086/// Get the lexicographically sorted vector of enumerators.
21087///
21088/// @return the lexicographically sorted vector of enumerators.
21091{
21092 lock_guard<recursive_mutex> lock(priv_->mutex_);
21093 if (priv_->sorted_enumerators_.empty())
21094 {
21095 for (auto e = get_enumerators().rbegin();
21096 e != get_enumerators().rend();
21097 ++e)
21098 priv_->sorted_enumerators_.push_back(*e);
21099
21100 std::sort(priv_->sorted_enumerators_.begin(),
21101 priv_->sorted_enumerators_.end(),
21102 [](const enum_type_decl::enumerator& l,
21104 {
21105 if (l.get_name() == r.get_name())
21106 return l.get_value() < r.get_value();
21107 return (l.get_name() < r.get_name());
21108 });
21109 }
21110
21111 return priv_->sorted_enumerators_;
21112}
21113
21114/// Find an enumerator by its value.
21115///
21116/// @param value the enumerator value to look for.
21117///
21118/// @param result output parameter. This is set to the enumerator
21119/// which value is @p value, if found. This is set iff the function
21120/// returns true.
21121///
21122/// @return true iff an enumerator with value @p value was found and
21123/// returned by argument via @p result.
21124bool
21126 enum_type_decl:: enumerator& result)
21127{
21128 lock_guard<recursive_mutex> lock(priv_->mutex_);
21129 for (auto& e : get_enumerators())
21130 if (e.get_value() == value)
21131 {
21132 result = e;
21133 return true;
21134 }
21135
21136 return false;
21137}
21138
21139/// Find an enumerator by its name
21140///
21141/// @param name the enumerator name to look for.
21142///
21143/// @param result output parameter. This is set to the enumerator
21144/// which name is @p name, if found. This is set iff the function
21145/// returns true.
21146///
21147/// @return true iff an enumerator with name @p name was found and
21148/// returned by argument via @p result.
21149bool
21152{
21153 lock_guard<recursive_mutex> lock(priv_->mutex_);
21154 for (auto& e : get_enumerators())
21155 if (e.get_name() == name)
21156 {
21157 result = e;
21158 return true;
21159 }
21160
21161 return false;
21162}
21163
21164/// Get the pretty representation of the current instance of @ref
21165/// enum_type_decl.
21166///
21167/// @param internal set to true if the call is intended to get a
21168/// representation of the decl (or type) for the purpose of canonical
21169/// type comparison. This is mainly used in the function
21170/// homonym_type_group::get_canonical_type_for().
21171///
21172/// In other words if the argument for this parameter is true then the
21173/// call is meant for internal use (for technical use inside the
21174/// library itself), false otherwise. If you don't know what this is
21175/// for, then set it to false.
21176///
21177/// @param qualified_name if true, names emitted in the pretty
21178/// representation are fully qualified.
21179///
21180/// @return the pretty representation of the enum type.
21181string
21183 bool qualified_name) const
21184{
21185 string r = "enum ";
21186
21187 if (internal && get_is_anonymous())
21188 r += get_type_name(this, qualified_name, /*internal=*/true);
21189 else if (get_is_anonymous())
21190 {
21191 string repr = get_enum_flat_representation(*this, "",
21192 /*one_line=*/true,
21193 qualified_name);
21194 if (qualified_name && !get_qualified_parent_name().empty())
21195 repr = get_qualified_parent_name() + "::" + repr;
21196 r += repr;
21197 }
21198 else
21200 qualified_name);
21201 return r;
21202}
21203
21204/// This implements the ir_traversable_base::traverse pure virtual
21205/// function.
21206///
21207/// @param v the visitor used on the current instance.
21208///
21209/// @return true if the entire IR node tree got traversed, false
21210/// otherwise.
21211bool
21213{
21214 if (v.type_node_has_been_visited(this))
21215 return true;
21216
21217 if (visiting())
21218 return true;
21219
21220 if (v.visit_begin(this))
21221 {
21222 visiting(true);
21223 if (type_base_sptr t = get_underlying_type())
21224 t->traverse(v);
21225 visiting(false);
21226 }
21227
21228 bool result = v.visit_end(this);
21230 return result;
21231}
21232
21233/// Destructor for the enum type declaration.
21236
21237/// Test if a given enumerator is found present in an enum.
21238///
21239/// This is a subroutine of the equals function for enums.
21240///
21241/// @param enr the enumerator to consider.
21242///
21243/// @param enom the enum to consider.
21244///
21245/// @return true iff the enumerator @p enr is present in the enum @p
21246/// enom.
21247bool
21249 const enum_type_decl &enom)
21250{
21251 for (const auto &e : enom.get_enumerators())
21252 if (e == enr)
21253 return true;
21254 return false;
21255}
21256
21257/// Check if two enumerators values are equal.
21258///
21259/// This function doesn't check if the names of the enumerators are
21260/// equal or not.
21261///
21262/// @param enr the first enumerator to consider.
21263///
21264/// @param enl the second enumerator to consider.
21265///
21266/// @return true iff @p enr has the same value as @p enl.
21267static bool
21268enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
21269 const enum_type_decl::enumerator &enl)
21270{return enr.get_value() == enl.get_value();}
21271
21272/// Detect if a given enumerator value is present in an enum.
21273///
21274/// This function looks inside the enumerators of a given enum and
21275/// detect if the enum contains at least one enumerator or a given
21276/// value. The function also detects if the enumerator value we are
21277/// looking at is present in the enum with a different name. An
21278/// enumerator with the same value but with a different name is named
21279/// a "redundant enumerator". The function returns the set of
21280/// enumerators that are redundant with the value we are looking at.
21281///
21282/// @param enr the enumerator to consider.
21283///
21284/// @param enom the enum to consider.
21285///
21286/// @param redundant_enrs if the function returns true, then this
21287/// vector is filled with enumerators that are redundant with the
21288/// value of @p enr.
21289///
21290/// @return true iff the function detects that @p enom contains
21291/// enumerators with the same value as @p enr.
21292static bool
21293is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
21294 const enum_type_decl &enom,
21295 vector<enum_type_decl::enumerator>& redundant_enrs)
21296{
21297 bool found = false;
21298 for (const auto &e : enom.get_enumerators())
21299 if (enumerators_values_are_equal(e, enr))
21300 {
21301 found = true;
21302 if (e != enr)
21303 redundant_enrs.push_back(e);
21304 }
21305
21306 return found;
21307}
21308
21309/// Check if an enumerator value is redundant in a given enum.
21310///
21311/// Given an enumerator value, this function detects if an enum
21312/// contains at least one enumerator with the the same value but with
21313/// a different name.
21314///
21315/// @param enr the enumerator to consider.
21316///
21317/// @param enom the enum to consider.
21318///
21319/// @return true iff @p enr is a redundant enumerator in enom.
21320static bool
21321is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
21322 const enum_type_decl &enom)
21323{
21324 vector<enum_type_decl::enumerator> redundant_enrs;
21325 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
21326 {
21327 if (!redundant_enrs.empty())
21328 return true;
21329 }
21330 return false;
21331}
21332
21333/// Compares two instances of @ref enum_type_decl.
21334///
21335/// If the two intances are different, set a bitfield to give some
21336/// insight about the kind of differences there are.
21337///
21338/// @param l the first artifact of the comparison.
21339///
21340/// @param r the second artifact of the comparison.
21341///
21342/// @param k a pointer to a bitfield that gives information about the
21343/// kind of changes there are between @p l and @p r. This one is set
21344/// iff @p k is non-null and the function returns false.
21345///
21346/// Please note that setting k to a non-null value does have a
21347/// negative performance impact because even if @p l and @p r are not
21348/// equal, the function keeps up the comparison in order to determine
21349/// the different kinds of ways in which they are different.
21350///
21351/// @param name if this is true, then the function considers the name
21352/// when comparing the two enums. Otherwise, the name is ignored.
21353///
21354/// @return true if @p l equals @p r, false otherwise.
21355bool
21357 const enum_type_decl& r,
21358 change_kind* k, bool name)
21359{
21360 bool result = true;
21361
21362 //
21363 // Look through decl-only-enum.
21364 //
21365
21366 const enum_type_decl *def1 =
21369 : &l;
21370
21371 const enum_type_decl *def2 =
21374 : &r;
21375
21376 if (!!def1 != !!def2)
21377 {
21378 // One enum is decl-only while the other is not.
21379 // So the two enums are different.
21380 result = false;
21381 if (k)
21382 *k |= SUBTYPE_CHANGE_KIND;
21383 else
21384 ABG_RETURN_FALSE;
21385 }
21386
21387 //
21388 // At this point, both enums have the same state of decl-only-ness.
21389 // So we can compare oranges to oranges.
21390 //
21391
21392 if (!def1)
21393 def1 = &l;
21394 if (!def2)
21395 def2 = &r;
21396
21397 if (def1->get_underlying_type() != def2->get_underlying_type())
21398 {
21399 result = false;
21400 if (k)
21401 *k |= SUBTYPE_CHANGE_KIND;
21402 else
21403 ABG_RETURN_FALSE;
21404 }
21405
21406 if (!(equals(static_cast<const decl_base&>(*def1),
21407 static_cast<const decl_base&>(*def2),
21408 nullptr, name, name)
21409 && def1->type_base::operator==(*def2)))
21410 {
21411 result = false;
21412 if (k)
21413 {
21414 if (!def1->decl_base::operator==(*def2))
21416 if (!def1->type_base::operator==(*def2))
21418 }
21419 else
21420 ABG_RETURN_FALSE;
21421 }
21422
21423 // Now compare the enumerators.
21424
21425 // First in a naive (but potentially fast) way in case both enums
21426 // are equal in a naive manner.
21427
21428 if (def1->get_enumerators().size() == def2->get_enumerators().size())
21429 {
21430 bool equals = true;
21431 for (auto e1 = def1->get_enumerators().begin(),
21432 e2 = def2->get_enumerators().begin();
21433 (e1 != def1->get_enumerators().end()
21434 && e2 != def2->get_enumerators().end());
21435 ++e1, ++e2)
21436 {
21437 if (*e1 != *e2)
21438 {
21439 equals = false;
21440 break;
21441 }
21442 }
21443 if (equals)
21444 ABG_RETURN(result);
21445 }
21446
21447 // If the two enums where not naively equals, let's try a more
21448 // clever (and slow) way.
21449
21450 // Note that the order of declaration
21451 // of enumerators should not matter in the comparison.
21452 //
21453 // Also if an enumerator value is redundant, that shouldn't impact
21454 // the comparison.
21455 //
21456 // In that case, note that the two enums below are considered equal:
21457 //
21458 // enum foo
21459 // {
21460 // e0 = 0;
21461 // e1 = 1;
21462 // e2 = 2;
21463 // };
21464 //
21465 // enum foo
21466 // {
21467 // e0 = 0;
21468 // e1 = 1;
21469 // e2 = 2;
21470 // e_added = 1; // <-- this value is redundant with the value
21471 // // of the enumerator e1.
21472 // };
21473 //
21474 // Note however that in the case below, the enums are different.
21475 //
21476 // enum foo
21477 // {
21478 // e0 = 0;
21479 // e1 = 1;
21480 // };
21481 //
21482 // enum foo
21483 // {
21484 // e0 = 0;
21485 // e2 = 1; // <-- this enum value is present in the first version
21486 // // of foo, but is not redundant with any enumerator
21487 // // in the second version of of enum foo.
21488 // };
21489 //
21490 // These two enums are considered equal.
21491
21492 for(const auto &e : def1->get_enumerators())
21493 if (!is_enumerator_present_in_enum(e, *def2)
21494 && (!is_enumerator_value_redundant(e, *def2)
21495 || !is_enumerator_value_redundant(e, *def1)))
21496 {
21497 result = false;
21498 if (k)
21499 {
21501 break;
21502 }
21503 else
21504 ABG_RETURN_FALSE;
21505 }
21506
21507 for(const auto &e : def2->get_enumerators())
21508 if (!is_enumerator_present_in_enum(e, *def1)
21509 && (!is_enumerator_value_redundant(e, *def1)
21510 || !is_enumerator_value_redundant(e, *def2)))
21511 {
21512 result = false;
21513 if (k)
21514 {
21516 break;
21517 }
21518 else
21519 ABG_RETURN_FALSE;
21520 }
21521
21522 ABG_RETURN(result);
21523}
21524
21525/// Test if two enums are equal modulo their names.
21526/// That is, the test compares the two enums as if they didn't have
21527/// any linkage name or qualified name.
21528///
21529/// @param l the first enum to consider.
21530///
21531/// @param r the second enum to consider.
21532///
21533/// @param k a pointer to a bitfield that gives information about the
21534/// kind of changes there are between @p l and @p r. This one is set
21535/// iff @p k is non-null and the function returns false.
21536///
21537/// @return true iff @p l equals @p r modulo their names.
21538bool
21540 const enum_type_decl& r,
21541 change_kind* k)
21542{
21543 bool result = equals(l, r, k, /*name=*/false);
21544
21545 return result;
21546}
21547
21548/// Equality operator.
21549///
21550/// @param o the other enum to test against.
21551///
21552/// @return true iff @p o equals the current instance of enum type
21553/// decl.
21554bool
21556{
21557 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
21558 if (!op)
21559 return false;
21560 return try_canonical_compare(this, op);
21561}
21562
21563/// Equality operator.
21564///
21565/// @param o the other enum to test against.
21566///
21567/// @return true iff @p o is equals the current instance of enum type
21568/// decl.
21569bool
21571{
21572 const decl_base* other = dynamic_cast<const decl_base*>(&o);
21573 if (!other)
21574 return false;
21575 return *this == *other;
21576}
21577
21578/// Equality operator for @ref enum_type_decl_sptr.
21579///
21580/// @param l the first operand to compare.
21581///
21582/// @param r the second operand to compare.
21583///
21584/// @return true iff @p l equals @p r.
21585bool
21587{
21588 if (!!l != !!r)
21589 return false;
21590 if (l.get() == r.get())
21591 return true;
21592 decl_base_sptr o = r;
21593 return *l == *o;
21594}
21595
21596/// Inequality operator for @ref enum_type_decl_sptr.
21597///
21598/// @param l the first operand to compare.
21599///
21600/// @param r the second operand to compare.
21601///
21602/// @return true iff @p l equals @p r.
21603bool
21605{return !operator==(l, r);}
21606
21607/// The type of the private data of an @ref
21608/// enum_type_decl::enumerator.
21609class enum_type_decl::enumerator::priv
21610{
21611 string name_;
21612 int64_t value_;
21613 string qualified_name_;
21614 enum_type_decl* enum_type_;
21615
21616 friend class enum_type_decl::enumerator;
21617
21618public:
21619
21620 priv()
21621 : enum_type_()
21622 {}
21623
21624 priv(const string& name,
21625 int64_t value,
21626 enum_type_decl* e = 0)
21627 : name_(name),
21628 value_(value),
21629 enum_type_(e)
21630 {}
21631}; // end class enum_type_def::enumerator::priv
21632
21633/// Default constructor of the @ref enum_type_decl::enumerator type.
21635 : priv_(new priv)
21636{}
21637
21638enum_type_decl::enumerator::~enumerator() = default;
21639
21640/// Constructor of the @ref enum_type_decl::enumerator type.
21641///
21642/// @param env the environment we are operating from.
21643///
21644/// @param name the name of the enumerator.
21645///
21646/// @param value the value of the enumerator.
21648 int64_t value)
21649 : priv_(new priv(name, value))
21650{}
21651
21652/// Copy constructor of the @ref enum_type_decl::enumerator type.
21653///
21654/// @param other enumerator to copy.
21656 : priv_(new priv(other.get_name(),
21657 other.get_value(),
21658 other.get_enum_type()))
21659{}
21660
21661/// Assignment operator of the @ref enum_type_decl::enumerator type.
21662///
21663/// @param o
21666{
21667 priv_->name_ = o.get_name();
21668 priv_->value_ = o.get_value();
21669 priv_->enum_type_ = o.get_enum_type();
21670 return *this;
21671}
21672
21673/// Equality operator
21674///
21675/// @param other the enumerator to compare to the current
21676/// instance of enum_type_decl::enumerator.
21677///
21678/// @return true if @p other equals the current instance of
21679/// enum_type_decl::enumerator.
21680bool
21682{
21683 bool names_equal = true;
21684 names_equal = (get_name() == other.get_name());
21685 return names_equal && (get_value() == other.get_value());
21686}
21687
21688/// Inequality operator.
21689///
21690/// @param other the other instance to compare against.
21691///
21692/// @return true iff @p other is different from the current instance.
21693bool
21695{return !operator==(other);}
21696
21697/// Getter for the name of the current instance of
21698/// enum_type_decl::enumerator.
21699///
21700/// @return a reference to the name of the current instance of
21701/// enum_type_decl::enumerator.
21702const string&
21704{return priv_->name_;}
21705
21706/// Getter for the qualified name of the current instance of
21707/// enum_type_decl::enumerator. The first invocation of the method
21708/// builds the qualified name, caches it and return a reference to the
21709/// cached qualified name. Subsequent invocations just return the
21710/// cached value.
21711///
21712/// @param internal set to true if the call is intended for an
21713/// internal use (for technical use inside the library itself), false
21714/// otherwise. If you don't know what this is for, then set it to
21715/// false.
21716///
21717/// @return the qualified name of the current instance of
21718/// enum_type_decl::enumerator.
21719const string&
21721{
21722 if (priv_->qualified_name_.empty())
21723 {
21724 priv_->qualified_name_ =
21725 get_enum_type()->get_qualified_name(internal)
21726 + "::"
21727 + get_name();
21728 }
21729 return priv_->qualified_name_;
21730}
21731
21732/// Setter for the name of @ref enum_type_decl::enumerator.
21733///
21734/// @param n the new name.
21735void
21737{priv_->name_ = n;}
21738
21739/// Getter for the value of @ref enum_type_decl::enumerator.
21740///
21741/// @return the value of the current instance of
21742/// enum_type_decl::enumerator.
21743int64_t
21745{return priv_->value_;}
21746
21747/// Setter for the value of @ref enum_type_decl::enumerator.
21748///
21749/// @param v the new value of the enum_type_decl::enumerator.
21750void
21752{priv_->value_= v;}
21753
21754/// Getter for the enum type that this enumerator is for.
21755///
21756/// @return the enum type that this enumerator is for.
21759{return priv_->enum_type_;}
21760
21761/// Setter for the enum type that this enumerator is for.
21762///
21763/// @param e the new enum type.
21764void
21767// </enum_type_decl definitions>
21768
21769// <typedef_decl definitions>
21770
21771/// Private data structure of the @ref typedef_decl.
21772struct typedef_decl::priv
21773{
21774 type_base_wptr underlying_type_;
21775
21776 priv(const type_base_sptr& t)
21777 : underlying_type_(t)
21778 {}
21779}; // end struct typedef_decl::priv
21780
21781/// Constructor of the typedef_decl type.
21782///
21783/// @param name the name of the typedef.
21784///
21785/// @param underlying_type the underlying type of the typedef.
21786///
21787/// @param locus the source location of the typedef declaration.
21788///
21789/// @param linkage_name the mangled name of the typedef.
21790///
21791/// @param vis the visibility of the typedef type.
21792typedef_decl::typedef_decl(const string& name,
21793 const type_base_sptr underlying_type,
21794 const location& locus,
21795 const string& linkage_name,
21796 visibility vis)
21797 : type_or_decl_base(underlying_type->get_environment(),
21798 TYPEDEF_TYPE
21799 | ABSTRACT_TYPE_BASE
21800 | ABSTRACT_DECL_BASE),
21801 type_base(underlying_type->get_environment(),
21802 underlying_type->get_size_in_bits(),
21803 underlying_type->get_alignment_in_bits()),
21804 decl_base(underlying_type->get_environment(),
21805 name, locus, linkage_name, vis),
21806 priv_(new priv(underlying_type))
21807{
21809}
21810
21811/// Constructor of the typedef_decl type.
21812///
21813/// @param name the name of the typedef.
21814///
21815/// @param env the environment of the current typedef.
21816///
21817/// @param locus the source location of the typedef declaration.
21818///
21819/// @param mangled_name the mangled name of the typedef.
21820///
21821/// @param vis the visibility of the typedef type.
21822typedef_decl::typedef_decl(const string& name,
21823 const environment& env,
21824 const location& locus,
21825 const string& mangled_name,
21826 visibility vis)
21827 : type_or_decl_base(env,
21828 TYPEDEF_TYPE
21829 | ABSTRACT_TYPE_BASE
21830 | ABSTRACT_DECL_BASE),
21831 type_base(env, /*size_in_bits=*/0,
21832 /*alignment_in_bits=*/0),
21833 decl_base(env, name, locus, mangled_name, vis),
21834 priv_(new priv(nullptr))
21835{
21837}
21838
21839/// Return the hash value of the current IR node.
21840///
21841/// Note that upon the first invocation, this member functions
21842/// computes the hash value and returns it. Subsequent invocations
21843/// just return the hash value that was previously calculated.
21844///
21845/// @return the hash value of the current IR node.
21846hash_t
21848{
21850 return h;
21851}
21852
21853/// Return the size of the typedef.
21854///
21855/// This function looks at the size of the underlying type and ensures
21856/// that it's the same as the size of the typedef.
21857///
21858/// @return the size of the typedef.
21859size_t
21861{
21862 if (!get_underlying_type())
21863 return 0;
21864
21865 size_t s = type_base::get_size_in_bits();
21866 type_base_sptr u = get_underlying_type();
21867
21868 type_base_sptr t = peel_typedef_type(u);
21869 ABG_ASSERT(t);
21870
21871 if (is_typedef(t))
21872 return 0;
21873
21874 s = t->get_size_in_bits();
21875
21876 if (s != type_base::get_size_in_bits())
21877 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
21878
21879 return s;
21880}
21881
21882/// Return the alignment of the typedef.
21883///
21884/// This function looks at the alignment of the underlying type and
21885/// ensures that it's the same as the alignment of the typedef.
21886///
21887/// @return the size of the typedef.
21888size_t
21890{
21891 if (!get_underlying_type())
21892 return 0;
21893
21895 type_base_sptr u = get_underlying_type();
21896 if (is_typedef(u))
21897 return a;
21898 if (type_base_sptr t = peel_typedef_type(u))
21899 a = t->get_alignment_in_bits();
21900 else
21901 a = get_underlying_type()->get_alignment_in_bits();
21903 const_cast<typedef_decl*>(this)->set_alignment_in_bits(a);
21904 return a;
21905}
21906
21907/// Compares two instances of @ref typedef_decl.
21908///
21909/// If the two intances are different, set a bitfield to give some
21910/// insight about the kind of differences there are.
21911///
21912/// This function does NOT take the name of the typedefs into account.
21913/// It only takes the underlying type of the typedef into account.
21914///
21915/// @param l the first artifact of the comparison.
21916///
21917/// @param r the second artifact of the comparison.
21918///
21919/// @param k a pointer to a bitfield that gives information about the
21920/// kind of changes there are between @p l and @p r. This one is set
21921/// iff @p k is non-null and the function returns false.
21922///
21923/// Please note that setting k to a non-null value does have a
21924/// negative performance impact because even if @p l and @p r are not
21925/// equal, the function keeps up the comparison in order to determine
21926/// the different kinds of ways in which they are different.
21927///
21928/// @return true if @p l equals @p r, false otherwise.
21929bool
21931{
21932 bool result = true;
21933
21934 // No need to go further if the types have different names or
21935 // different size / alignment. This is useful to tell member
21936 // typedefs appart.
21937 if (!(l.decl_base::operator==(r)))
21938 {
21939 result = false;
21940 if (k)
21942 else
21943 ABG_RETURN_FALSE;
21944 }
21945
21946 if ((!!l.get_underlying_type() != !!r.get_underlying_type())
21949 {
21950 // Changes to the underlying type of a typedef are considered
21951 // local, a bit like for pointers.
21952 result = false;
21953 if (k)
21955 else
21956 ABG_RETURN_FALSE;
21957 }
21958
21959 ABG_RETURN(result);
21960}
21961
21962/// Equality operator
21963///
21964/// @param o the other typedef_decl to test against.
21965bool
21967{
21968 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
21969 if (!other)
21970 return false;
21971 return try_canonical_compare(this, other);
21972}
21973
21974/// Equality operator
21975///
21976/// @param o the other typedef_decl to test against.
21977///
21978/// @return true if the current instance of @ref typedef_decl equals
21979/// @p o.
21980bool
21982{
21983 const decl_base* other = dynamic_cast<const decl_base*>(&o);
21984 if (!other)
21985 return false;
21986 return *this == *other;
21987}
21988
21989/// Build a pretty representation for a typedef_decl.
21990///
21991/// @param internal set to true if the call is intended to get a
21992/// representation of the decl (or type) for the purpose of canonical
21993/// type comparison. This is mainly used in the function
21994/// homonym_type_group::get_canonical_type_for().
21995///
21996/// In other words if the argument for this parameter is true then the
21997/// call is meant for internal use (for technical use inside the
21998/// library itself), false otherwise. If you don't know what this is
21999/// for, then set it to false.
22000
22001/// @param qualified_name if true, names emitted in the pretty
22002/// representation are fully qualified.
22003///
22004/// @return a copy of the pretty representation of the current
22005/// instance of typedef_decl.
22006string
22008 bool qualified_name) const
22009{
22010 string result = "typedef ";
22011 if (qualified_name)
22012 result += get_qualified_name(internal);
22013 else
22014 result += get_name();
22015
22016 return result;
22017}
22018
22019/// Getter of the underlying type of the typedef.
22020///
22021/// @return the underlying_type.
22022type_base_sptr
22024{return priv_->underlying_type_.lock();}
22025
22026/// Setter ofthe underlying type of the typedef.
22027///
22028/// @param t the new underlying type of the typedef.
22029void
22031{
22032 priv_->underlying_type_ = t;
22033 set_size_in_bits(t->get_size_in_bits());
22034 set_alignment_in_bits(t->get_alignment_in_bits());
22035}
22036
22037/// Implementation of the virtual "get_qualified_name" method.
22038///
22039/// @param qualified_name the resuling qualified name of the typedef type.
22040///
22041/// @param internal if true, then it means the qualified name is for
22042/// "internal" purposes, meaning mainly for type canonicalization
22043/// purposes.
22044void
22046 bool internal) const
22047{qualified_name = get_qualified_name(internal);}
22048
22049/// Implementation of the virtual "get_qualified_name" method.
22050///
22051/// @param internal if true, then it means the qualified name is for
22052/// "internal" purposes, meaning mainly for type canonicalization
22053/// purposes.
22054///
22055/// @return the qualified name.
22056const interned_string&
22058{
22059 // Note that the qualified name has been already set by
22060 // qualified_name_setter::do_update, which is invoked by
22061 // update_qualified_name. The latter is itself invoked whenever the
22062 // typedef is added to its scope, in scope_decl::add_member_decl.
22063 if (internal)
22064 return decl_base::priv_->internal_qualified_name_;
22065 else
22066 return decl_base::priv_->qualified_name_;
22067}
22068
22069/// This implements the ir_traversable_base::traverse pure virtual
22070/// function.
22071///
22072/// @param v the visitor used on the current instance.
22073///
22074/// @return true if the entire IR node tree got traversed, false
22075/// otherwise.
22076bool
22078{
22079 if (v.type_node_has_been_visited(this))
22080 return true;
22081
22082 if (visiting())
22083 return true;
22084
22085 if (v.visit_begin(this))
22086 {
22087 visiting(true);
22088 if (type_base_sptr t = get_underlying_type())
22089 t->traverse(v);
22090
22091 if (scope_decl_sptr s = get_scope())
22092 if (type_base_sptr t = is_type(s))
22093 t->traverse(v);
22094
22095 visiting(false);
22096 }
22097
22098 bool result = v.visit_end(this);
22100 return result;
22101}
22102
22103typedef_decl::~typedef_decl()
22104{}
22105// </typedef_decl definitions>
22106
22107// <var_decl definitions>
22108
22109struct var_decl::priv
22110{
22111 type_base_wptr type_;
22112 type_base* naked_type_;
22113 decl_base::binding binding_;
22114 elf_symbol_sptr symbol_;
22115 interned_string id_;
22116
22117 priv()
22118 : naked_type_(),
22119 binding_(decl_base::BINDING_GLOBAL)
22120 {}
22121
22122 priv(type_base_sptr t,
22124 : type_(t),
22125 naked_type_(t.get()),
22126 binding_(b)
22127 {}
22128
22129 /// Setter of the type of the variable.
22130 ///
22131 /// @param t the new variable type.
22132 void
22133 set_type(type_base_sptr t)
22134 {
22135 type_ = t;
22136 naked_type_ = t.get();
22137 }
22138}; // end struct var_decl::priv
22139
22140/// Constructor of the @ref var_decl type.
22141///
22142/// @param name the name of the variable declaration
22143///
22144/// @param type the type of the variable declaration
22145///
22146/// @param locus the source location where the variable was defined.
22147///
22148/// @param linkage_name the linkage name of the variable.
22149///
22150/// @param vis the visibility of of the variable.
22151///
22152/// @param bind the binding kind of the variable.
22153var_decl::var_decl(const string& name,
22154 type_base_sptr type,
22155 const location& locus,
22156 const string& linkage_name,
22157 visibility vis,
22158 binding bind)
22159 : type_or_decl_base(type->get_environment(),
22160 VAR_DECL | ABSTRACT_DECL_BASE),
22161 decl_base(type->get_environment(), name, locus, linkage_name, vis),
22162 priv_(new priv(type, bind))
22163{
22165}
22166
22167/// Getter of the type of the variable.
22168///
22169/// @return the type of the variable.
22170const type_base_sptr
22172{return priv_->type_.lock();}
22173
22174/// Setter of the type of the variable.
22175///
22176/// @param the new type of the variable.
22177void
22178var_decl::set_type(type_base_sptr& t)
22179{priv_->set_type(t);}
22180
22181/// Getter of the type of the variable.
22182///
22183/// This getter returns a bare pointer, as opposed to a smart pointer.
22184/// It's to be used on performance sensitive code paths identified by
22185/// careful profiling.
22186///
22187/// @return the type of the variable, as a bare pointer.
22188const type_base*
22190{return priv_->naked_type_;}
22191
22192/// Getter of the binding of the variable.
22193///
22194/// @return the biding of the variable.
22197{return priv_->binding_;}
22198
22199/// Setter of the binding of the variable.
22200///
22201/// @param b the new binding value.
22202void
22204{priv_->binding_ = b;}
22205
22206/// Sets the underlying ELF symbol for the current variable.
22207///
22208/// And underlyin$g ELF symbol for the current variable might exist
22209/// only if the corpus that this variable originates from was
22210/// constructed from an ELF binary file.
22211///
22212/// Note that comparing two variables that have underlying ELF symbols
22213/// involves comparing their underlying elf symbols. The decl name
22214/// for the variable thus becomes irrelevant in the comparison.
22215///
22216/// @param sym the new ELF symbol for this variable decl.
22217void
22219{
22220 priv_->symbol_ = sym;
22221 // The variable id cache that depends on the symbol must be
22222 // invalidated because the symbol changed.
22223 priv_->id_ = get_environment().intern("");
22224}
22225
22226/// Gets the the underlying ELF symbol for the current variable,
22227/// that was set using var_decl::set_symbol(). Please read the
22228/// documentation for that member function for more information about
22229/// "underlying ELF symbols".
22230///
22231/// @return sym the underlying ELF symbol for this variable decl, if
22232/// one exists.
22233const elf_symbol_sptr
22235{return priv_->symbol_;}
22236
22237/// Create a new var_decl that is a clone of the current one.
22238///
22239/// @return the cloned var_decl.
22242{
22244 get_type(),
22245 get_location(),
22248 get_binding()));
22249
22250 v->set_symbol(get_symbol());
22251
22252 if (is_member_decl(*this))
22253 {
22254 auto scope = is_class_or_union_type(get_scope());
22257 get_member_is_static(*this),
22258 get_data_member_offset(*this));
22259 }
22260 else
22262
22263 return v;
22264}
22265/// Setter of the scope of the current var_decl.
22266///
22267/// Note that the decl won't hold a reference on the scope. It's
22268/// rather the scope that holds a reference on its members.
22269///
22270/// @param scope the new scope.
22271void
22272var_decl::set_scope(scope_decl_sptr scope)
22273{
22274 if (!get_context_rel())
22275 set_context_rel(new dm_context_rel(scope));
22276 else
22277 get_context_rel()->set_scope(scope);
22278}
22279
22280/// Compares two instances of @ref var_decl without taking their type
22281/// into account.
22282///
22283/// If the two intances are different modulo their type, set a
22284/// bitfield to give some insight about the kind of differences there
22285/// are.
22286///
22287/// @param l the first artifact of the comparison.
22288///
22289/// @param r the second artifact of the comparison.
22290///
22291/// @param k a pointer to a bitfield that gives information about the
22292/// kind of changes there are between @p l and @p r. This one is set
22293/// iff @p k is non-null and the function returns false.
22294///
22295/// Please note that setting k to a non-null value does have a
22296/// negative performance impact because even if @p l and @p r are not
22297/// equal, the function keeps up the comparison in order to determine
22298/// the different kinds of ways in which they are different.
22299///
22300/// @return true if @p l equals @p r, false otherwise.
22301bool
22303{
22304 bool result = true;
22305
22306 // If there are underlying elf symbols for these variables,
22307 // compare them. And then compare the other parts.
22308 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
22309 if (!!s0 != !!s1)
22310 {
22311 result = false;
22312 if (k)
22314 else
22315 ABG_RETURN_FALSE;
22316 }
22317 else if (s0 && !textually_equals(*s0, *s1, k))
22318 {
22319 result = false;
22320 if (!k)
22321 ABG_RETURN_FALSE;
22322 }
22323 bool symbols_are_equal = (s0 && s1 && result);
22324
22325 if (symbols_are_equal)
22326 {
22327 // The variables have underlying elf symbols that are equal, so
22328 // now, let's compare the decl_base part of the variables w/o
22329 // considering their decl names.
22330 bool decl_bases_different =
22331 !equals(static_cast<const decl_base&>(l),
22332 static_cast<const decl_base&>(r),
22333 nullptr, /*qualified_name=*/false,
22334 /*linkage_name=*/false);
22335
22336 if (decl_bases_different)
22337 {
22338 result = false;
22339 if (k)
22341 else
22342 ABG_RETURN_FALSE;
22343 }
22344 }
22345 else
22346 if (!l.decl_base::operator==(r))
22347 {
22348 result = false;
22349 if (k)
22351 else
22352 ABG_RETURN_FALSE;
22353 }
22354
22355 const dm_context_rel* c0 =
22356 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
22357 const dm_context_rel* c1 =
22358 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
22359 ABG_ASSERT(c0 && c1);
22360
22361 if (*c0 != *c1)
22362 {
22363 result = false;
22364 if (k)
22366 else
22367 ABG_RETURN_FALSE;
22368 }
22369
22370 ABG_RETURN(result);
22371}
22372
22373/// Compares two instances of @ref var_decl.
22374///
22375/// If the two intances are different, set a bitfield to give some
22376/// insight about the kind of differences there are.
22377///
22378/// @param l the first artifact of the comparison.
22379///
22380/// @param r the second artifact of the comparison.
22381///
22382/// @param k a pointer to a bitfield that gives information about the
22383/// kind of changes there are between @p l and @p r. This one is set
22384/// iff @p k is non-null and the function returns false.
22385///
22386/// Please note that setting k to a non-null value does have a
22387/// negative performance impact because even if @p l and @p r are not
22388/// equal, the function keeps up the comparison in order to determine
22389/// the different kinds of ways in which they are different.
22390///
22391/// @return true if @p l equals @p r, false otherwise.
22392bool
22393equals(const var_decl& l, const var_decl& r, change_kind* k)
22394{
22395 bool result = true;
22396
22397 // First test types of variables. This should be fast because in
22398 // the general case, most types should be canonicalized.
22399 if (*l.get_naked_type() != *r.get_naked_type())
22400 {
22401 result = false;
22402 if (k)
22403 {
22405 r.get_naked_type()))
22406 *k |= (LOCAL_TYPE_CHANGE_KIND);
22407 else
22408 *k |= SUBTYPE_CHANGE_KIND;
22409 }
22410 else
22411 ABG_RETURN_FALSE;
22412 }
22413
22414 result &= var_equals_modulo_types(l, r, k);
22415
22416 ABG_RETURN(result);
22417}
22418
22419/// Comparison operator of @ref var_decl.
22420///
22421/// @param o the instance of @ref var_decl to compare against.
22422///
22423/// @return true iff the current instance of @ref var_decl equals @p o.
22424bool
22426{
22427 const var_decl* other = dynamic_cast<const var_decl*>(&o);
22428 if (!other)
22429 return false;
22430
22431 return equals(*this, *other, 0);
22432}
22433
22434/// Return an ID that tries to uniquely identify the variable inside a
22435/// program or a library.
22436///
22437/// So if the variable has an underlying elf symbol, the ID is the
22438/// concatenation of the symbol name and its version. Otherwise, the
22439/// ID is the linkage name if its non-null. Otherwise, it's the
22440/// pretty representation of the variable.
22441///
22442/// @return the ID.
22445{
22446 if (priv_->id_.empty())
22447 {
22448 string repr = get_name();
22449 string sym_str;
22450 if (elf_symbol_sptr s = get_symbol())
22451 sym_str = s->get_id_string();
22452 else if (!get_linkage_name().empty())
22453 sym_str = get_linkage_name();
22454
22455 const environment& env = get_type()->get_environment();
22456 interned_string id = env.intern(repr);
22457 if (!sym_str.empty())
22458 id = env.intern(id + "{" + sym_str + "}");
22459
22460 if (get_type() && get_type()->get_naked_canonical_type())
22461 priv_->id_ = id;
22462 else
22463 return id;
22464 }
22465 return priv_->id_;
22466}
22467
22468/// Get the qualified name of a given variable or data member.
22469///
22470///
22471/// Note that if the current instance of @ref var_decl is an anonymous
22472/// data member, then the qualified name is actually the flat
22473/// representation (the definition) of the type of the anonymous data
22474/// member. We chose the flat representation because otherwise, the
22475/// name of an *anonymous* data member is empty, by construction, e.g:
22476///
22477/// struct foo {
22478/// int a;
22479/// union {
22480/// char b;
22481/// char c;
22482/// }; // <---- this data member is anonymous.
22483/// int d;
22484/// }
22485///
22486/// The string returned for the anonymous member here is going to be:
22487///
22488/// "union {char b; char c}"
22489///
22490/// @param internal if true then this is for a purpose to the library,
22491/// otherwise, it's for being displayed to users.
22492///
22493/// @return the resulting qualified name.
22494const interned_string&
22496{
22497 if (is_anonymous_data_member(this)
22498 && decl_base::get_qualified_name().empty())
22499 {
22500 // Display the anonymous data member in a way that makes sense.
22501 string r = get_pretty_representation(internal);
22503 }
22504
22505 return decl_base::get_qualified_name(internal);
22506}
22507
22508/// Build and return the pretty representation of this variable.
22509///
22510/// @param internal set to true if the call is intended to get a
22511/// representation of the decl (or type) for the purpose of canonical
22512/// type comparison. This is mainly used in the function
22513/// homonym_type_group::get_canonical_type_for().
22514///
22515/// In other words if the argument for this parameter is true then the
22516/// call is meant for internal use (for technical use inside the
22517/// library itself), false otherwise. If you don't know what this is
22518/// for, then set it to false.
22519///
22520/// @param qualified_name if true, names emitted in the pretty
22521/// representation are fully qualified.
22522///
22523/// @return a copy of the pretty representation of this variable.
22524string
22525var_decl::get_pretty_representation(bool internal, bool qualified_name) const
22526{
22527 string result;
22528
22529 if (is_member_decl(this) && get_member_is_static(this))
22530 result = "static ";
22531
22532 // Detect if the current instance of var_decl is a member of
22533 // an anonymous class or union.
22534 bool member_of_anonymous_class = false;
22535 if (class_or_union_sptr scope = is_at_class_scope(this))
22536 if (scope->get_is_anonymous())
22537 member_of_anonymous_class = true;
22538
22539 type_base_sptr type = get_type();
22540 if (is_array_type(type, /*look_through_qualifiers=*/true)
22541 || is_pointer_type(type, /*look_through_qualifiers=*/true)
22542 || is_reference_type(type, /*look_through_qualifiers=*/true)
22543 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
22544 {
22545 string name;
22546 if (member_of_anonymous_class || !qualified_name)
22547 name = get_name();
22548 else
22549 name = get_qualified_name(internal);
22550
22551 if (qualified_type_def_sptr q = is_qualified_type(type))
22552 {
22553 string quals_repr =
22554 get_string_representation_of_cv_quals(q->get_cv_quals());
22555 if (!quals_repr.empty())
22556 name = quals_repr + " " + name;
22557 type = peel_qualified_type(type);
22558 }
22559
22560 name = string(" ") + name;
22561 if (array_type_def_sptr t = is_array_type(type))
22562 result += array_declaration_name(t, name, qualified_name, internal);
22563 else if (pointer_type_def_sptr t = is_pointer_type(type))
22564 result += pointer_declaration_name(t, name, qualified_name, internal);
22565 else if (reference_type_def_sptr t = is_reference_type(type))
22566 result += pointer_declaration_name(t, name, qualified_name, internal);
22567 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
22568 result += ptr_to_mbr_declaration_name(t, name,
22569 qualified_name,
22570 internal);
22571 }
22572 else
22573 {
22574 if (/*The current var_decl is to be used as an anonymous data
22575 member. */
22576 get_name().empty())
22577 {
22578 // Display the anonymous data member in a way that
22579 // makes sense.
22580 result +=
22583 "", /*one_line=*/true, internal);
22584 }
22585 else if (data_member_has_anonymous_type(this))
22586 {
22589 "", /*one_line=*/true, internal);
22590 result += " ";
22591 if (!internal
22592 && (member_of_anonymous_class || !qualified_name))
22593 // It doesn't make sense to name the member of an
22594 // anonymous class or union like:
22595 // "__anonymous__::data_member_name". So let's just use
22596 // its non-qualified name.
22597 result += get_name();
22598 else
22599 result += get_qualified_name(internal);
22600 }
22601 else
22602 {
22603 result +=
22605 + " ";
22606
22607 if (!internal
22608 && (member_of_anonymous_class || !qualified_name))
22609 // It doesn't make sense to name the member of an
22610 // anonymous class or union like:
22611 // "__anonymous__::data_member_name". So let's just use
22612 // its non-qualified name.
22613 result += get_name();
22614 else
22615 result += get_qualified_name(internal);
22616 }
22617 }
22618 return result;
22619}
22620
22621/// Get a name that is valid even for an anonymous data member.
22622///
22623/// If the current @ref var_decl is an anonymous data member, then
22624/// return its pretty representation. As of now, that pretty
22625/// representation is actually its flat representation as returned by
22626/// get_class_or_union_flat_representation().
22627///
22628/// Otherwise, just return the name of the current @ref var_decl.
22629///
22630/// @param qualified if true, return the qualified name. This doesn't
22631/// have an effet if the current @ref var_decl represents an anonymous
22632/// data member.
22633string
22635{
22636 string name;
22637 if (is_anonymous_data_member(this))
22638 // This function is used in the comparison engine to determine
22639 // which anonymous data member was deleted. So it's not involved
22640 // in type comparison or canonicalization. We don't want to use
22641 // the 'internal' version of the pretty presentation.
22642 name = get_pretty_representation(/*internal=*/false, qualified);
22643 else
22644 name = get_name();
22645
22646 return name;
22647}
22648
22649/// This implements the ir_traversable_base::traverse pure virtual
22650/// function.
22651///
22652/// @param v the visitor used on the current instance.
22653///
22654/// @return true if the entire IR node tree got traversed, false
22655/// otherwise.
22656bool
22658{
22659 if (visiting())
22660 return true;
22661
22662 if (v.visit_begin(this))
22663 {
22664 visiting(true);
22665 if (type_base_sptr t = get_type())
22666 t->traverse(v);
22667 visiting(false);
22668 }
22669 return v.visit_end(this);
22670}
22671
22672var_decl::~var_decl()
22673{}
22674
22675// </var_decl definitions>
22676
22677thread_local fn_set_type function_type::priv::left_fn_types_being_compared_;
22678thread_local fn_set_type function_type::priv::right_fn_types_being_compared_;
22679thread_local fn_set_type function_type::priv::fn_types_being_printed_;
22680
22681/// This function is automatically invoked whenever an instance of
22682/// this type is canonicalized.
22683///
22684/// It's an overload of the virtual type_base::on_canonical_type_set.
22685///
22686/// We put here what is thus meant to be executed only at the point of
22687/// type canonicalization.
22688void
22690{
22691 lock_guard<recursive_mutex> lock(get_mutex());
22692 priv_->cached_name_.clear();
22693 priv_->internal_cached_name_.clear();
22694}
22695
22696/// The most straightforward constructor for the function_type class.
22697///
22698/// @param return_type the return type of the function type.
22699///
22700/// @param parms the list of parameters of the function type.
22701/// Stricto sensu, we just need a list of types; we are using a list
22702/// of parameters (where each parameter also carries the name of the
22703/// parameter and its source location) to try and provide better
22704/// diagnostics whenever it makes sense. If it appears that this
22705/// wasts too many resources, we can fall back to taking just a
22706/// vector of types here.
22707///
22708/// @param size_in_bits the size of this type, in bits.
22709///
22710/// @param alignment_in_bits the alignment of this type, in bits.
22711///
22712/// @param size_in_bits the size of this type.
22713function_type::function_type(type_base_sptr return_type,
22714 const parameters& parms,
22715 size_t size_in_bits,
22716 size_t alignment_in_bits)
22717 : type_or_decl_base(return_type->get_environment(),
22718 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
22719 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
22720 priv_(new priv(parms, return_type))
22721{
22723
22724 for (parameters::size_type i = 0, j = 1;
22725 i < priv_->parms_.size();
22726 ++i, ++j)
22727 {
22728 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22729 // If the first parameter is artificial, then it certainly
22730 // means that this is a member function, and the first
22731 // parameter is the implicit this pointer. In that case, set
22732 // the index of that implicit parameter to zero. Otherwise,
22733 // the index of the first parameter starts at one.
22734 j = 0;
22735 priv_->parms_[i]->set_index(j);
22736 }
22737}
22738
22739/// A constructor for a function_type that takes no parameters.
22740///
22741/// @param return_type the return type of this function_type.
22742///
22743/// @param size_in_bits the size of this type, in bits.
22744///
22745/// @param alignment_in_bits the alignment of this type, in bits.
22746function_type::function_type(type_base_sptr return_type,
22747 size_t size_in_bits, size_t alignment_in_bits)
22748 : type_or_decl_base(return_type->get_environment(),
22749 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
22750 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
22751 priv_(new priv(return_type))
22752{
22754}
22755
22756/// A constructor for a function_type that takes no parameter and
22757/// that has no return_type yet. These missing parts can (and must)
22758/// be added later.
22759///
22760/// @param env the environment we are operating from.
22761///
22762/// @param size_in_bits the size of this type, in bits.
22763///
22764/// @param alignment_in_bits the alignment of this type, in bits.
22765function_type::function_type(const environment& env,
22766 size_t size_in_bits,
22767 size_t alignment_in_bits)
22768 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
22769 type_base(env, size_in_bits, alignment_in_bits),
22770 priv_(new priv)
22771{
22773}
22774
22775/// Return the hash value of the current IR node.
22776///
22777/// Note that upon the first invocation, this member functions
22778/// computes the hash value and returns it. Subsequent invocations
22779/// just return the hash value that was previously calculated.
22780///
22781/// @return the hash value of the current IR node.
22782hash_t
22784{
22786 return h;
22787}
22788
22789/// Getter for the return type of the current instance of @ref
22790/// function_type.
22791///
22792/// @return the return type.
22793type_base_sptr
22795{
22796 lock_guard<recursive_mutex> lock(get_mutex());
22797 return priv_->return_type_.lock();
22798}
22799
22800/// Setter of the return type of the current instance of @ref
22801/// function_type.
22802///
22803/// @param t the new return type to set.
22804void
22806{
22807 lock_guard<recursive_mutex> lock(get_mutex());
22808 priv_->return_type_ = t;
22809}
22810
22811/// Test if a the function type has empty parameters in a thread-safe manner.
22812///
22813/// @return true iff the function has no parameters.
22814bool
22816{
22817 bool is_empty = false;
22818 {
22819 lock_guard<recursive_mutex> lock(get_mutex());
22820 is_empty = priv_->parms_.empty();
22821 }
22822 return is_empty;
22823}
22824
22825/// The number of parameters of the function type in a thread-safe manner.
22826///
22827/// @return the number of parameters.
22828unsigned
22830{
22831 unsigned size = 0;
22832 {
22833 lock_guard<recursive_mutex> lock(get_mutex());
22834 size = priv_->parms_.size();
22835 }
22836 return size;
22837}
22838/// Getter for the set of parameters of the current intance of @ref
22839/// function_type.
22840///
22841/// @return the parameters of the current instance of @ref
22842/// function_type.
22845{return priv_->parms_;}
22846
22847/// Get the Ith parameter of the vector of parameters of the current
22848/// instance of @ref function_type.
22849///
22850/// Note that the first parameter is at index 0. That parameter is
22851/// the first parameter that comes after the possible implicit "this"
22852/// parameter, when the current instance @ref function_type is for a
22853/// member function. Otherwise, if the current instance of @ref
22854/// function_type is for a non-member function, the parameter at index
22855/// 0 is the first parameter of the function.
22856///
22857///
22858/// @param i the index of the parameter to return. If i is greater
22859/// than the index of the last parameter, then this function returns
22860/// an empty parameter (smart) pointer.
22861///
22862/// @return the @p i th parameter that is not implicit.
22865{
22866 lock_guard<recursive_mutex> lock(get_mutex());
22867 parameter_sptr result;
22868 if (dynamic_cast<const method_type*>(this))
22869 {
22870 if (i + 1 < get_parameters().size())
22871 {
22872 result = get_parameters()[i + 1];
22873 }
22874 }
22875 else
22876 {
22877 if (i < get_parameters().size())
22878 result = get_parameters()[i];
22879 }
22880 return result;
22881}
22882
22883/// Get the function parameter at a given index, starting from zero.
22884///
22885/// @param i the index of the function parameter to get.
22886///
22887/// @return the function parameter at index @p i.
22890{
22891 parameter_sptr parm;
22892 {
22893 lock_guard<recursive_mutex> lock(get_mutex());
22894 if (i < priv_->parms_.size())
22895 parm = priv_->parms_[i];
22896 }
22897 return parm;
22898}
22899
22900/// Setter for the parameters of the current instance of @ref
22901/// function_type.
22902///
22903/// @param p the new vector of parameters to set.
22904void
22906{
22907 lock_guard<recursive_mutex> lock(get_mutex());
22908 priv_->parms_ = p;
22909 for (parameters::size_type i = 0, j = 1;
22910 i < priv_->parms_.size();
22911 ++i, ++j)
22912 {
22913 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22914 // If the first parameter is artificial, then it certainly
22915 // means that this is a member function, and the first
22916 // parameter is the implicit this pointer. In that case, set
22917 // the index of that implicit parameter to zero. Otherwise,
22918 // the index of the first parameter starts at one.
22919 j = 0;
22920 priv_->parms_[i]->set_index(j);
22921 }
22922}
22923
22924/// Append a new parameter to the vector of parameters of the current
22925/// instance of @ref function_type.
22926///
22927/// @param parm the parameter to append.
22928void
22930{
22931 lock_guard<recursive_mutex> lock(get_mutex());
22932 parm->set_index(priv_->parms_.size());
22933 priv_->parms_.push_back(parm);
22934}
22935
22936/// Test if the current instance of @ref function_type is for a
22937/// variadic function.
22938///
22939/// A variadic function is a function that takes a variable number of
22940/// arguments.
22941///
22942/// @return true iff the current instance of @ref function_type is for
22943/// a variadic function.
22944bool
22946{
22947 lock_guard<recursive_mutex> lock(get_mutex());
22948 return (!priv_->parms_.empty()
22949 && priv_->parms_.back()->get_variadic_marker());
22950}
22951
22952/// Compare two function types.
22953///
22954/// In case these function types are actually method types, this
22955/// function avoids comparing two parameters (of the function types)
22956/// if the types of the parameters are actually the types of the
22957/// classes of the method types. This prevents infinite recursion
22958/// during the comparison of two classes that are structurally
22959/// identical.
22960///
22961/// This is a subroutine of the equality operator of function_type.
22962///
22963/// @param lhs the first function type to consider
22964///
22965/// @param rhs the second function type to consider
22966///
22967/// @param k a pointer to a bitfield set by the function to give
22968/// information about the kind of changes carried by @p lhs and @p
22969/// rhs. It is set iff @p k is non-null and the function returns
22970/// false.
22971///
22972/// Please note that setting k to a non-null value does have a
22973/// negative performance impact because even if @p l and @p r are not
22974/// equal, the function keeps up the comparison in order to determine
22975/// the different kinds of ways in which they are different.
22976///
22977///@return true if lhs == rhs, false otherwise.
22978bool
22980{
22981#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
22982
22984
22985 {
22986 // First of all, let's see if these two function types haven't
22987 // already been compared. If so, and if the result of the
22988 // comparison has been cached, let's just re-use it, rather than
22989 // comparing them all over again.
22990 bool cached_result = false;
22991 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
22992 cached_result))
22993 ABG_RETURN(cached_result);
22994 }
22995
22997
22998 bool result = true;
22999
23000 if (!l.type_base::operator==(r))
23001 {
23002 result = false;
23003 if (k)
23005 else
23006 RETURN(result);
23007 }
23008
23009 class_or_union* l_class = nullptr, *r_class = nullptr;
23010 const method_type* l_method_type = dynamic_cast<const method_type*>(&l),
23011 *r_method_type = dynamic_cast<const method_type*>(&r);
23012
23013 if (l_method_type && r_method_type)
23014 if (l_method_type->get_is_static() != r_method_type->get_is_static())
23015 {
23016 result = false;
23017 if (k)
23018 *k |= SUBTYPE_CHANGE_KIND;
23019 else
23020 RETURN(result);
23021 }
23022
23023 if (l_method_type)
23024 l_class = l_method_type->get_class_type().get();
23025
23026 if (r_method_type)
23027 r_class = r_method_type->get_class_type().get();
23028
23029 // Compare the names of the class of the method
23030
23031 if (!!l_class != !!r_class
23032 || (l_class
23033 && (l_class->get_qualified_name()
23034 != r_class->get_qualified_name())))
23035 {
23036 result = false;
23037 if (k)
23038 *k |= SUBTYPE_CHANGE_KIND;
23039 else
23040 RETURN(result);
23041 }
23042
23043 // Then compare the return type; Beware if it's t's a class type
23044 // that is the same as the method class name; we can recurse for
23045 // ever in that case.
23046
23047 decl_base* l_return_type_decl =
23049 decl_base* r_return_type_decl =
23051 bool compare_result_types = true;
23052 string l_rt_name = l_return_type_decl
23053 ? l_return_type_decl->get_qualified_name()
23054 : string();
23055 string r_rt_name = r_return_type_decl
23056 ? r_return_type_decl->get_qualified_name()
23057 : string();
23058
23059 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
23060 ||
23061 (r_class && (r_class->get_qualified_name() == r_rt_name)))
23062 compare_result_types = false;
23063
23064 if (compare_result_types)
23065 {
23066 // Let's not consider typedefs when comparing return types to
23067 // avoid spurious changes.
23068 //
23069 // TODO: We should also do this for parameter types, or rather,
23070 // we should teach the equality operators in the IR, at some
23071 // point, to peel typedefs off.
23072 if (l.get_return_type() != r.get_return_type())
23073 {
23074 result = false;
23075 if (k)
23076 {
23078 r.get_return_type()))
23080 else
23081 *k |= SUBTYPE_CHANGE_KIND;
23082 }
23083 else
23084 RETURN(result);
23085 }
23086 }
23087 else
23088 if (l_rt_name != r_rt_name)
23089 {
23090 result = false;
23091 if (k)
23092 *k |= SUBTYPE_CHANGE_KIND;
23093 else
23094 RETURN(result);
23095 }
23096
23097 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
23098 for (i = l.get_first_parm(), j = r.get_first_parm();
23099 i != l.get_parameters().end() && j != r.get_parameters().end();
23100 ++i, ++j)
23101 {
23102 if (**i != **j)
23103 {
23104 result = false;
23105 if (k)
23106 {
23107 if (!types_have_similar_structure((*i)->get_type(),
23108 (*j)->get_type()))
23110 else
23111 *k |= SUBTYPE_CHANGE_KIND;
23112 }
23113 else
23114 RETURN(result);
23115 }
23116 }
23117
23118 if ((i != l.get_parameters().end()
23119 || j != r.get_parameters().end()))
23120 {
23121 result = false;
23122 if (k)
23124 else
23125 RETURN(result);
23126 }
23127
23128 RETURN(result);
23129#undef RETURN
23130}
23131
23132/// Get the first parameter of the function.
23133///
23134/// If the function is a non-static member function, the parameter
23135/// returned is the first one following the implicit 'this' parameter.
23136///
23137/// @return the first non implicit parameter of the function.
23138function_type::parameters::const_iterator
23140{
23141 if (get_parameters().empty())
23142 return get_parameters().end();
23143
23144 bool is_method = dynamic_cast<const method_type*>(this);
23145
23146 parameters::const_iterator i = get_parameters().begin();
23147
23148 if (is_method && (*i)->get_is_artificial())
23149 ++i;
23150
23151 return i;
23152}
23153
23154/// Get the first parameter of the function that is not
23155/// compiler-generated.
23156///
23157/// If the function is a non-static member function, the parameter
23158/// returned is the first one following the implicit 'this' parameter,
23159/// that is defined by the code of the user.
23160///
23161/// @return the first non-implicit non-artificial parameter of the
23162/// function. If the function has no non-implicit non-artificial
23163/// parameter then returns function_type::get_parameters().end();
23164function_type::parameters::const_iterator
23166{
23167 if (get_parameters().empty())
23168 return get_parameters().end();
23169
23170 bool is_method = dynamic_cast<const method_type*>(this);
23171 parameters::const_iterator i = get_parameters().begin();
23172
23173 if (is_method)
23174 for (; i != get_parameters().end(); ++i)
23175 if (!(*i)->get_is_artificial())
23176 return i;
23177
23178 return i;
23179}
23180
23181/// Get the first parameter of the function.
23182///
23183/// Note that if the function is a non-static member function, the
23184/// parameter returned is the implicit 'this' parameter.
23185///
23186/// @return the first parameter of the function.
23187function_type::parameters::const_iterator
23189{return get_parameters().begin();}
23190
23191/// Get the name of the current @ref function_type.
23192///
23193/// The name is retrieved from a cache. If the cache is empty, this
23194/// function computes the name of the type, stores it in the cache and
23195/// returns it. Subsequent invocation of the function are going to
23196/// just hit the cache.
23197///
23198/// Note that if the type is *NOT* canonicalized then function type
23199/// name is never cached.
23200///
23201/// @param internal if true then it means the function type name is
23202/// going to be used for purposes that are internal to libabigail
23203/// itself. If you don't know what this is then you probably should
23204/// set this parameter to 'false'.
23205///
23206/// @return the name of the function type.
23207const interned_string&
23209{
23210 if (internal)
23211 {
23213 {
23214 if (priv_->internal_cached_name_.empty())
23215 priv_->internal_cached_name_ =
23216 get_function_type_name(this, /*internal=*/true);
23217 return priv_->internal_cached_name_;
23218 }
23219 else
23220 {
23221 priv_->temp_internal_cached_name_ =
23222 get_function_type_name(this, /*internal=*/true);
23223 return priv_->temp_internal_cached_name_;
23224 }
23225 }
23226 else
23227 {
23229 {
23230 if (priv_->cached_name_.empty())
23231 priv_->cached_name_ =
23232 get_function_type_name(this, /*internal=*/false);
23233 return priv_->cached_name_;
23234 }
23235 else
23236 {
23237 priv_->temp_cached_name_ =
23238 get_function_type_name(this, /*internal=*/false);
23239 return priv_->temp_cached_name_;
23240 }
23241 }
23242}
23243
23244/// Equality operator for function_type.
23245///
23246/// @param o the other function_type to compare against.
23247///
23248/// @return true iff the two function_type are equal.
23249bool
23251{
23252 const function_type* o = dynamic_cast<const function_type*>(&other);
23253 if (!o)
23254 return false;
23255 return try_canonical_compare(this, o);
23256}
23257
23258/// Return a copy of the pretty representation of the current @ref
23259/// function_type.
23260///
23261/// @param internal set to true if the call is intended to get a
23262/// representation of the decl (or type) for the purpose of canonical
23263/// type comparison. This is mainly used in the function
23264/// homonym_type_group::get_canonical_type_for().
23265///
23266/// In other words if the argument for this parameter is true then the
23267/// call is meant for internal use (for technical use inside the
23268/// library itself), false otherwise. If you don't know what this is
23269/// for, then set it to false.
23270///
23271/// @return a copy of the pretty representation of the current @ref
23272/// function_type.
23273string
23275 bool /*qualified_name*/) const
23276{return ir::get_pretty_representation(this, internal);}
23277
23278/// Traverses an instance of @ref function_type, visiting all the
23279/// sub-types and decls that it might contain.
23280///
23281/// @param v the visitor that is used to visit every IR sub-node of
23282/// the current node.
23283///
23284/// @return true if either
23285/// - all the children nodes of the current IR node were traversed
23286/// and the calling code should keep going with the traversing.
23287/// - or the current IR node is already being traversed.
23288/// Otherwise, returning false means that the calling code should not
23289/// keep traversing the tree.
23290bool
23292{
23293 // TODO: should we allow the walker to avoid visiting function type
23294 // twice? I think that if we do, then ir_node_visitor needs an
23295 // option to specifically disallow this feature for function types.
23296
23297 if (visiting())
23298 return true;
23299
23300 if (v.visit_begin(this))
23301 {
23302 visiting(true);
23303 bool keep_going = true;
23304
23305 if (type_base_sptr t = get_return_type())
23306 {
23307 if (!t->traverse(v))
23308 keep_going = false;
23309 }
23310
23311 if (keep_going)
23312 for (parameters::const_iterator i = get_parameters().begin();
23313 i != get_parameters().end();
23314 ++i)
23315 if (type_base_sptr parm_type = (*i)->get_type())
23316 if (!parm_type->traverse(v))
23317 break;
23318
23319 visiting(false);
23320 }
23321 return v.visit_end(this);
23322}
23323
23324function_type::~function_type()
23325{}
23326// </function_type>
23327
23328// <method_type>
23329
23330struct method_type::priv
23331{
23332 std::recursive_mutex mutex_;
23333 class_or_union_wptr class_type_;
23334 bool is_const;
23335 bool is_static;
23336
23337 priv()
23338 : is_const(false),
23339 is_static(false)
23340 {}
23341}; // end struct method_type::priv
23342
23343/// Constructor for instances of method_type.
23344///
23345/// Instances of method_decl must be of type method_type.
23346///
23347/// @param return_type the type of the return value of the method.
23348///
23349/// @param class_type the base type of the method type. That is, the
23350/// type of the class the method belongs to.
23351///
23352/// @param p the vector of the parameters of the method.
23353///
23354/// @param is_const whether this method type is for a const method.
23355/// Note that const-ness is a property of the method *type* and of the
23356/// relationship between a method *declaration* and its scope.
23357///
23358/// @param size_in_bits the size of an instance of method_type,
23359/// expressed in bits.
23360///
23361/// @param alignment_in_bits the alignment of an instance of
23362/// method_type, expressed in bits.
23363method_type::method_type (type_base_sptr return_type,
23364 class_or_union_sptr class_type,
23365 const std::vector<function_decl::parameter_sptr>& p,
23366 bool is_const,
23367 size_t size_in_bits,
23368 size_t alignment_in_bits)
23369 : type_or_decl_base(class_type->get_environment(),
23370 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
23371 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
23372 function_type(return_type, p, size_in_bits, alignment_in_bits),
23373 priv_(new priv)
23374{
23376 set_class_type(class_type);
23377 set_is_const(is_const);
23378}
23379
23380/// Constructor of instances of method_type.
23381///
23382///Instances of method_decl must be of type method_type.
23383///
23384/// @param return_type the type of the return value of the method.
23385///
23386/// @param class_type the type of the class the method belongs to.
23387/// The actual (dynamic) type of class_type must be a pointer
23388/// class_type. We are setting it to pointer to type_base here to
23389/// help client code that is compiled without rtti and thus cannot
23390/// perform dynamic casts.
23391///
23392/// @param p the vector of the parameters of the method type.
23393///
23394/// @param is_const whether this method type is for a const method.
23395/// Note that const-ness is a property of the method *type* and of the
23396/// relationship between a method *declaration* and its scope.
23397///
23398/// @param size_in_bits the size of an instance of method_type,
23399/// expressed in bits.
23400///
23401/// @param alignment_in_bits the alignment of an instance of
23402/// method_type, expressed in bits.
23403method_type::method_type(type_base_sptr return_type,
23404 type_base_sptr class_type,
23405 const std::vector<function_decl::parameter_sptr>& p,
23406 bool is_const,
23407 size_t size_in_bits,
23408 size_t alignment_in_bits)
23409 : type_or_decl_base(class_type->get_environment(),
23410 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
23411 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
23412 function_type(return_type, p, size_in_bits, alignment_in_bits),
23413 priv_(new priv)
23414{
23416 set_class_type(is_class_type(class_type));
23417 set_is_const(is_const);
23418}
23419
23420/// Constructor of the qualified_type_def
23421///
23422/// @param env the environment we are operating from.
23423///
23424/// @param size_in_bits the size of the type, expressed in bits.
23425///
23426/// @param alignment_in_bits the alignment of the type, expressed in bits
23427method_type::method_type(const environment& env,
23428 size_t size_in_bits,
23429 size_t alignment_in_bits)
23430 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
23431 type_base(env, size_in_bits, alignment_in_bits),
23432 function_type(env, size_in_bits, alignment_in_bits),
23433 priv_(new priv)
23434{
23436}
23437
23438/// Constructor of instances of method_type.
23439///
23440/// When constructed with this constructor, and instane of method_type
23441/// must set a return type using method_type::set_return_type
23442///
23443/// @param class_typ the base type of the method type. That is, the
23444/// type of the class (or union) the method belongs to.
23445///
23446/// @param size_in_bits the size of an instance of method_type,
23447/// expressed in bits.
23448///
23449/// @param alignment_in_bits the alignment of an instance of
23450/// method_type, expressed in bits.
23451method_type::method_type(class_or_union_sptr class_type,
23452 bool is_const,
23453 size_t size_in_bits,
23454 size_t alignment_in_bits)
23455 : type_or_decl_base(class_type->get_environment(),
23456 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
23457 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
23458 function_type(class_type->get_environment(),
23459 size_in_bits,
23460 alignment_in_bits),
23461 priv_(new priv)
23462{
23464 set_class_type(class_type);
23465 set_is_const(is_const);
23466}
23467
23468/// Return the hash value of the current IR node.
23469///
23470/// Note that upon the first invocation, this member functions
23471/// computes the hash value and returns it. Subsequent invocations
23472/// just return the hash value that was previously calculated.
23473///
23474/// @return the hash value of the current IR node.
23475hash_t
23477{
23479 return h;
23480}
23481
23482/// Get the class type this method belongs to.
23483///
23484/// @return the class type.
23485class_or_union_sptr
23487{
23488 lock_guard<recursive_mutex> lock(priv_->mutex_);
23489 return class_or_union_sptr(priv_->class_type_);
23490}
23491
23492/// Sets the class type of the current instance of method_type.
23493///
23494/// The class type is the type of the class the method belongs to.
23495///
23496/// @param t the new class type to set.
23497void
23498method_type::set_class_type(const class_or_union_sptr& t)
23499{
23500 if (!t)
23501 return;
23502
23503 lock_guard<recursive_mutex> lock(priv_->mutex_);
23504 priv_->class_type_ = t;
23505}
23506
23507/// Return a copy of the pretty representation of the current @ref
23508/// method_type.
23509///
23510/// @param internal set to true if the call is intended to get a
23511/// representation of the decl (or type) for the purpose of canonical
23512/// type comparison. This is mainly used in the function
23513/// homonym_type_group::get_canonical_type_for().
23514///
23515/// In other words if the argument for this parameter is true then the
23516/// call is meant for internal use (for technical use inside the
23517/// library itself), false otherwise. If you don't know what this is
23518/// for, then set it to false.
23519///
23520/// @return a copy of the pretty representation of the current @ref
23521/// method_type.
23522string
23524 bool /*qualified_name*/) const
23525{
23526 return ir::get_pretty_representation(*this, internal);
23527}
23528
23529/// Setter of the "is-const" property of @ref method_type.
23530///
23531/// @param the new value of the "is-const" property.
23532void
23534{
23535 lock_guard<recursive_mutex> lock(priv_->mutex_);
23536 priv_->is_const = f;
23537}
23538
23539/// Getter of the "is-const" property of @ref method_type.
23540///
23541/// @return true iff the "is-const" property was set.
23542bool
23544{
23545 lock_guard<recursive_mutex> lock(priv_->mutex_);
23546 return priv_->is_const;
23547}
23548
23549/// Setter of the "is-static" property of @ref method_type.
23550///
23551/// @param f the new argument of the "is-static" propety.
23552void
23554{
23555 lock_guard<recursive_mutex> lock(priv_->mutex_);
23556 priv_->is_static = f;
23557}
23558
23559/// Fetter of the "is-static" property of @ref method_type.
23560///
23561/// @return the argument of the "is-static" propety.
23562bool
23564{
23565 lock_guard<recursive_mutex> lock(priv_->mutex_);
23566 return priv_->is_static;
23567}
23568
23569/// Test if the current method type is for a static method or not.
23570///
23571/// This is a slow method that has to be called only once to set
23572/// method_type::set_is_static, so that we can subsequently call
23573/// method_type::get_is_static instead.
23574///
23575/// @return true iff the current
23576/// method_type denotes a the type of a static method.
23577bool
23579{
23580 lock_guard<recursive_mutex> lock(get_mutex());
23581 // Let's see if the first parameter is artificial and is a pointer
23582 // to an instance of the same class type as the current class.
23584 if (!get_parameters().empty())
23585 first_parm = get_parameters()[0];
23586 if (!first_parm)
23587 return true;
23588 if (!first_parm->get_is_artificial())
23589 return true;
23590
23591 type_base_sptr this_ptr_type = first_parm->get_type();
23592 // Sometimes, the type of the "this" pointer is "const class_type*
23593 // const". Meaning that the "this pointer" itself is const
23594 // qualified. So let's get the underlying non-qualified pointer.
23595 this_ptr_type = peel_qualified_type(this_ptr_type);
23596 if (!is_pointer_type(this_ptr_type))
23597 return true;
23598
23599 type_base_sptr candidate_class_type =
23600 is_pointer_type(this_ptr_type)->get_pointed_to_type();
23601 candidate_class_type = peel_qualified_type(candidate_class_type);
23602 if (is_class_or_union_type(candidate_class_type)
23603 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
23604 // At this point, we are sure we are looking at a *non-static*
23605 // method.
23606 return false;
23607
23608 return true;
23609}
23610
23611/// Traverses an instance of @ref method_type, visiting all the
23612/// sub-types and decls that it might contain.
23613///
23614/// @param v the visitor that is used to visit every IR sub-node of
23615/// the current node.
23616///
23617/// @return true if either
23618/// - all the children nodes of the current IR node were traversed
23619/// and the calling code should keep going with the traversing.
23620/// - or the current IR node is already being traversed.
23621/// Otherwise, returning false means that the calling code should not
23622/// keep traversing the tree.
23623bool
23625{
23626 // TODO: should we allow the walker to avoid visiting method type
23627 // twice? I think that if we do, then ir_node_visitor needs an
23628 // option to specifically disallow this feature for method types.
23629
23630 if (visiting())
23631 return true;
23632
23633 if (v.visit_begin(this))
23634 {
23635 visiting(true);
23636 bool keep_going = true;
23637
23638 if (type_base_sptr t = get_return_type())
23639 {
23640 if (!t->traverse(v))
23641 keep_going = false;
23642 }
23643
23644 if (keep_going)
23645 for (parameters::const_iterator i = get_parameters().begin();
23646 i != get_parameters().end();
23647 ++i)
23648 if (type_base_sptr parm_type = (*i)->get_type())
23649 if (!parm_type->traverse(v))
23650 {
23651 keep_going = false;
23652 break;
23653 }
23654
23655 if (keep_going)
23656 if (class_or_union_sptr t = get_class_type())
23657 {
23658 if (!traverse(v))
23659 keep_going = false;
23660 }
23661
23662 visiting(false);
23663 }
23664 return v.visit_end(this);
23665}
23666
23667/// The destructor of method_type
23670
23671// </method_type>
23672
23673// <function_decl definitions>
23674
23675struct function_decl::priv
23676{
23677 recursive_mutex mutex_;
23678 bool declared_inline_;
23679 decl_base::binding binding_;
23680 function_type_wptr type_;
23681 function_type* naked_type_;
23682 elf_symbol_sptr symbol_;
23683
23684 priv()
23685 : declared_inline_(false),
23686 binding_(decl_base::BINDING_GLOBAL),
23687 naked_type_()
23688 {}
23689
23690 priv(function_type_sptr t,
23691 bool declared_inline,
23693 : declared_inline_(declared_inline),
23694 binding_(binding),
23695 type_(t),
23696 naked_type_(t.get())
23697 {}
23698
23699 priv(function_type_sptr t,
23700 bool declared_inline,
23703 : declared_inline_(declared_inline),
23704 binding_(binding),
23705 type_(t),
23706 naked_type_(t.get()),
23707 symbol_(s)
23708 {}
23709}; // end sruct function_decl::priv
23710
23711/// Constructor of the @ref function_decl.
23712///
23713/// @param name the name of the function.
23714///
23715/// @param function_type the type of the function.
23716///
23717/// @param declared_inline wether the function is declared inline.
23718///
23719/// @param locus the source location of the function.
23720///
23721/// @param mangled_name the linkage name of the function.
23722///
23723/// @param vis the visibility of the function.
23724///
23725/// @param bind the binding of the function.
23728 bool declared_inline,
23729 const location& locus,
23730 const string& mangled_name,
23731 visibility vis,
23732 binding bind)
23733 : type_or_decl_base(function_type->get_environment(),
23734 FUNCTION_DECL | ABSTRACT_DECL_BASE),
23735 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
23736 scope_decl(function_type->get_environment(), "", locus),
23737 priv_(new priv(function_type, declared_inline, bind))
23738{
23740}
23741
23742/// Constructor of the function_decl type.
23743///
23744/// This flavour of constructor is for when the pointer to the
23745/// instance of function_type that the client code has is presented as
23746/// a pointer to type_base. In that case, this constructor saves the
23747/// client code from doing a dynamic_cast to get the function_type
23748/// pointer.
23749///
23750/// @param name the name of the function declaration.
23751///
23752/// @param fn_type the type of the function declaration. The dynamic
23753/// type of this parameter should be 'pointer to function_type'
23754///
23755/// @param declared_inline whether this function was declared inline
23756///
23757/// @param locus the source location of the function declaration.
23758///
23759/// @param linkage_name the mangled name of the function declaration.
23760///
23761/// @param vis the visibility of the function declaration.
23762///
23763/// @param bind the kind of the binding of the function
23764/// declaration.
23766 type_base_sptr fn_type,
23767 bool declared_inline,
23768 const location& locus,
23769 const string& linkage_name,
23770 visibility vis,
23771 binding bind)
23772 : type_or_decl_base(fn_type->get_environment(),
23773 FUNCTION_DECL | ABSTRACT_DECL_BASE),
23774 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
23775 scope_decl(fn_type->get_environment(), "", locus),
23776 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
23777 declared_inline,
23778 bind))
23779{
23781}
23782
23783/// Get the pretty representation of the current instance of @ref function_decl.
23784///
23785/// @param internal set to true if the call is intended to get a
23786/// representation of the decl (or type) for the purpose of canonical
23787/// type comparison. This is mainly used in the function
23788/// homonym_type_group::get_canonical_type_for().
23789///
23790/// In other words if the argument for this parameter is true then the
23791/// call is meant for internal use (for technical use inside the
23792/// library itself), false otherwise. If you don't know what this is
23793/// for, then set it to false.
23794///
23795/// @return the pretty representation for a function.
23796string
23798 bool qualified_name) const
23799{
23800 const method_decl* mem_fn =
23801 dynamic_cast<const method_decl*>(this);
23802
23803 string fn_prefix = mem_fn ? "method ": "function ";
23804 string result;
23805
23806 if (mem_fn
23807 && is_member_function(mem_fn)
23809 fn_prefix += "virtual ";
23810
23811 decl_base_sptr return_type;
23812 if ((mem_fn
23813 && is_member_function(mem_fn)
23814 && (get_member_function_is_dtor(*mem_fn)
23815 || get_member_function_is_ctor(*mem_fn))))
23816 /*cdtors do not have return types. */;
23817 else
23818 return_type = mem_fn
23819 ? get_type_declaration(mem_fn->get_type()->get_return_type())
23821
23822 result = get_pretty_representation_of_declarator(internal);
23823 if (return_type)
23824 {
23825 if (is_npaf_type(is_type(return_type))
23826 || !(is_pointer_to_function_type(is_type(return_type))
23827 || is_pointer_to_array_type(is_type(return_type))))
23828 result = get_type_name(is_type(return_type).get(), qualified_name,
23829 internal) + " " + result;
23830 else if (pointer_type_def_sptr p =
23832 result = add_outer_pointer_to_fn_type_expr(p, result,
23833 /*qualified=*/true,
23834 internal);
23835 else if(pointer_type_def_sptr p =
23836 is_pointer_to_array_type(is_type(return_type)))
23837 result = add_outer_pointer_to_array_type_expr(p, result,
23838 qualified_name,
23839 internal);
23840 else
23842 }
23843
23844 return fn_prefix + result;
23845}
23846
23847/// Compute and return the pretty representation for the part of the
23848/// function declaration that starts at the declarator. That is, the
23849/// return type and the other specifiers of the beginning of the
23850/// function's declaration ar omitted.
23851///
23852/// @param internal set to true if the call is intended to get a
23853/// representation of the decl (or type) for the purpose of canonical
23854/// type comparison. This is mainly used in the function
23855/// homonym_type_group::get_canonical_type_for().
23856///
23857/// In other words if the argument for this parameter is true then the
23858/// call is meant for internal use (for technical use inside the
23859/// library itself), false otherwise. If you don't know what this is
23860/// for, then set it to false.
23861///
23862/// @return the pretty representation for the part of the function
23863/// declaration that starts at the declarator.
23864string
23866{
23867 const method_decl* mem_fn =
23868 dynamic_cast<const method_decl*>(this);
23869
23870 string result;
23871
23872 if (mem_fn)
23873 {
23874 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
23875 + "::" + mem_fn->get_name();
23876 }
23877 else
23878 result += get_qualified_name();
23879
23880 std::ostringstream fn_parms;
23881 stream_pretty_representation_of_fn_parms(*get_type(),
23882 fn_parms,
23883 /*qualified=*/true,
23884 internal);
23885 result += fn_parms.str();
23886
23887 if (mem_fn
23888 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
23889 || is_method_type(mem_fn->get_type())->get_is_const()))
23890 result += " const";
23891
23892 return result;
23893}
23894
23895/// Getter for the first non-implicit parameter of a function decl.
23896///
23897/// If the function is a non-static member function, the parameter
23898/// returned is the first one following the implicit 'this' parameter.
23899///
23900/// @return the first non implicit parm.
23901function_decl::parameters::const_iterator
23903{
23904 lock_guard<recursive_mutex> lock(priv_->mutex_);
23905
23906 if (get_parameters().empty())
23907 return get_parameters().end();
23908
23909 bool is_method = dynamic_cast<const method_decl*>(this);
23910
23911 parameters::const_iterator i = get_parameters().begin();
23912 if (is_method)
23913 ++i;
23914
23915 return i;
23916}
23917
23918/// Get the first parameter of the function that is not
23919/// compiler-generated.
23920///
23921/// If the function is a non-static member function, the parameter
23922/// returned is the first one following the implicit 'this' parameter,
23923/// that is defined by the code of the user.
23924///
23925/// @return the first non-implicit non-artificial parameter of the
23926/// function. If the function has no non-implicit non-artificial
23927/// parameter then returns function_decl::get_parameters().end();
23928function_decl::parameters::const_iterator
23930{
23931 lock_guard<recursive_mutex> lock(priv_->mutex_);
23932
23933 if (get_parameters().empty())
23934 return get_parameters().end();
23935
23936 bool is_method = dynamic_cast<const method_type*>(this);
23937 parameters::const_iterator i = get_parameters().begin();
23938
23939 if (is_method)
23940 for (; i != get_parameters().end(); ++i)
23941 if (!(*i)->get_is_artificial())
23942 return i;
23943
23944 return i;
23945}
23946
23947/// Return the type of the current instance of @ref function_decl.
23948///
23949/// It's either a function_type or method_type.
23950/// @return the type of the current instance of @ref function_decl.
23953{
23954 return priv_->type_.lock();
23955}
23956
23957/// Fast getter of the type of the current instance of @ref function_decl.
23958///
23959/// Note that this function returns the underlying pointer managed by
23960/// the smart pointer returned by function_decl::get_type(). It's
23961/// faster than function_decl::get_type(). This getter is to be used
23962/// in code paths that are proven to be performance hot spots;
23963/// especially (for instance) when comparing function types. Those
23964/// are compared extremely frequently when libabigail is used to
23965/// handle huge binaries with a lot of functions.
23966///
23967/// @return the type of the current instance of @ref function_decl.
23968const function_type*
23970{
23971 lock_guard<recursive_mutex> lock(priv_->mutex_);
23972 return priv_->naked_type_;
23973}
23974
23975void
23976function_decl::set_type(const function_type_sptr& fn_type)
23977{
23978 lock_guard<recursive_mutex> lock(priv_->mutex_);
23979 priv_->type_ = fn_type;
23980 priv_->naked_type_ = fn_type.get();
23981}
23982
23983/// This sets the underlying ELF symbol for the current function decl.
23984///
23985/// And underlyin$g ELF symbol for the current function decl might
23986/// exist only if the corpus that this function decl originates from
23987/// was constructed from an ELF binary file.
23988///
23989/// Note that comparing two function decls that have underlying ELF
23990/// symbols involves comparing their underlying elf symbols. The decl
23991/// name for the function thus becomes irrelevant in the comparison.
23992///
23993/// @param sym the new ELF symbol for this function decl.
23994void
23996{
23997 lock_guard<recursive_mutex> lock(priv_->mutex_);
23998
23999 priv_->symbol_ = sym;
24000 // The function id cache that depends on the symbol must be
24001 // invalidated because the symbol changed.
24002 type_or_decl_base::priv_->id_ = get_environment().intern("");
24003}
24004
24005/// Gets the the underlying ELF symbol for the current variable,
24006/// that was set using function_decl::set_symbol(). Please read the
24007/// documentation for that member function for more information about
24008/// "underlying ELF symbols".
24009///
24010/// @return sym the underlying ELF symbol for this function decl, if
24011/// one exists.
24012const elf_symbol_sptr
24014{
24015 lock_guard<recursive_mutex> lock(priv_->mutex_);
24016 return priv_->symbol_;
24017}
24018
24019/// Test if the function was declared inline.
24020///
24021/// @return true iff the function was declared inline.
24022bool
24024{
24025 lock_guard<recursive_mutex> lock(priv_->mutex_);
24026 return priv_->declared_inline_;
24027}
24028
24029/// Set the property of the function being declared inline.
24030///
24031/// @param value true iff the function was declared inline.
24032void
24034{
24035 lock_guard<recursive_mutex> lock(priv_->mutex_);
24036 priv_->declared_inline_ = value;
24037}
24038
24040function_decl::get_binding() const
24041{
24042 lock_guard<recursive_mutex> lock(priv_->mutex_);
24043 return priv_->binding_;
24044}
24045
24046/// @return the return type of the current instance of function_decl.
24047const shared_ptr<type_base>
24049{return get_type()->get_return_type();}
24050
24051/// @return the parameters of the function.
24052const std::vector<shared_ptr<function_decl::parameter> >&
24054{
24055 lock_guard<recursive_mutex> lock(priv_->mutex_);
24056 return get_type()->get_parameters();
24057}
24058
24059/// Append a parameter to the type of this function.
24060///
24061/// @param parm the parameter to append.
24062void
24063function_decl::append_parameter(shared_ptr<parameter> parm)
24064{
24065 lock_guard<recursive_mutex> lock(priv_->mutex_);
24066 get_type()->append_parameter(parm);
24067}
24068
24069/// Append a vector of parameters to the type of this function.
24070///
24071/// @param parms the vector of parameters to append.
24072void
24073function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
24074{
24075 lock_guard<recursive_mutex> lock(priv_->mutex_);
24076 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
24077 i != parms.end();
24078 ++i)
24079 get_type()->append_parameter(*i);
24080}
24081
24082/// Create a new instance of function_decl that is a clone of the
24083/// current one.
24084///
24085/// @return the new clone.
24088{
24090 if (is_member_function(*this))
24091 {
24092 method_decl_sptr
24093 m(new method_decl(get_name(),
24094 get_type(),
24096 get_location(),
24099 get_binding()));
24100 class_or_union_sptr scope = is_class_or_union_type(get_scope());
24101 ABG_ASSERT(scope);
24105 get_member_is_static(*this),
24109 f = m;
24110 }
24111 else
24112 {
24113 f.reset(new function_decl(get_name(),
24114 get_type(),
24116 get_location(),
24119 get_binding()));
24121 }
24122 f->set_symbol(get_symbol());
24123
24124 return f;
24125}
24126
24127/// Compares two instances of @ref function_decl.
24128///
24129/// If the two intances are different, set a bitfield to give some
24130/// insight about the kind of differences there are.
24131///
24132/// @param l the first artifact of the comparison.
24133///
24134/// @param r the second artifact of the comparison.
24135///
24136/// @param k a pointer to a bitfield that gives information about the
24137/// kind of changes there are between @p l and @p r. This one is set
24138/// iff @p k is non-null and the function returns false.
24139///
24140/// Please note that setting k to a non-null value does have a
24141/// negative performance impact because even if @p l and @p r are not
24142/// equal, the function keeps up the comparison in order to determine
24143/// the different kinds of ways in which they are different.
24144///
24145/// @param linkage_name if this is true, then the function considers
24146/// the linkage name when comparing the two functions. Otherwise, the
24147/// linkage_name name is ignored.
24148///
24149/// @param elf_symbol if this is true, then the function considers the
24150/// elf_symbol when comparing the two functions. Otherwise, the
24151/// elf_symbol is ignored.
24152///
24153/// @return true if @p l equals @p r, false otherwise.
24154bool
24156 bool linkage_name, bool elf_symbol)
24157{
24158 bool result = true;
24159
24160 // Compare function types
24161 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
24162 if (t0 == t1 || *t0 == *t1)
24163 ; // the types are equal, let's move on to compare the other
24164 // properties of the functions.
24165 else
24166 {
24167 result = false;
24168 if (k)
24169 {
24170 if (!types_have_similar_structure(t0, t1))
24172 else
24173 *k |= SUBTYPE_CHANGE_KIND;
24174 }
24175 else
24176 ABG_RETURN_FALSE;
24177 }
24178
24179 bool symbols_are_equal = true;
24180 if (elf_symbol)
24181 {
24182 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
24183 if (!!s0 != !!s1)
24184 {
24185 result = false;
24186 if (k)
24188 else
24189 ABG_RETURN_FALSE;
24190 }
24191 else if (s0 && s0 != s1)
24192 {
24193 if (!elf_symbols_alias(s0, s1))
24194 {
24195 result = false;
24196 if (k)
24198 else
24199 ABG_RETURN_FALSE;
24200 }
24201 }
24202 symbols_are_equal = (s0 && s1 && result);
24203 }
24204
24205 if (symbols_are_equal)
24206 {
24207 bool decl_bases_different = false;
24208 // The functions have underlying elf symbols that are equal,
24209 // so now, let's compare the decl_base part of the functions
24210 // w/o considering their decl names.
24211
24212 decl_bases_different = !equals(static_cast<const decl_base&>(l),
24213 static_cast<const decl_base&>(r),
24214 nullptr,
24215 /*qualified_name=*/false,
24216 /*linkage_name=*/false);
24217
24218 if (decl_bases_different)
24219 {
24220 result = false;
24221 if (k)
24223 else
24224 ABG_RETURN_FALSE;
24225 }
24226 }
24227 else
24228 if (!equals(static_cast<const decl_base&>(l),
24229 static_cast<const decl_base&>(r),
24230 nullptr, /*qualified_name=*/true, linkage_name))
24231 {
24232 result = false;
24233 if (k)
24235 else
24236 ABG_RETURN_FALSE;
24237 }
24238
24239 // Compare the remaining properties. Note that we don't take into
24240 // account the fact that the function was declared inline or not as
24241 // that doesn't have any impact on the final ABI.
24242 if (l.get_binding() != r.get_binding())
24243 {
24244 result = false;
24245 if (k)
24247 else
24248 ABG_RETURN_FALSE;
24249 }
24250
24252 {
24253 result = false;
24254 if (k)
24256 else
24257 ABG_RETURN_FALSE;
24258 }
24259
24261 {
24274 {
24275 result = false;
24276 if (k)
24278 else
24279 ABG_RETURN_FALSE;
24280 }
24281 }
24282
24283 ABG_RETURN(result);
24284}
24285
24286/// Comparison operator for @ref function_decl.
24287///
24288/// @param other the other instance of @ref function_decl to compare
24289/// against.
24290///
24291/// @return true iff the current instance of @ref function_decl equals
24292/// @p other.
24293bool
24295{
24296 const function_decl* o = dynamic_cast<const function_decl*>(&other);
24297 if (!o)
24298 return false;
24299 return equals(*this, *o, 0);
24300}
24301
24302/// Return true iff the function takes a variable number of
24303/// parameters.
24304///
24305/// @return true if the function taks a variable number
24306/// of parameters.
24307bool
24309{
24310 return (!get_parameters().empty()
24311 && get_parameters().back()->get_variadic_marker());
24312}
24313
24314/// Return an ID that tries to uniquely identify the function inside a
24315/// program or a library, given a given ELF symbol.
24316///
24317/// The ID is the concatenation of the function's representation, its
24318/// symbol name and its version.
24319///
24320/// @param s the ELF symbol to use to construct the function ID.
24321///
24322/// @return the ID.
24325{
24326 const environment& env = get_type()->get_environment();
24327 std::ostringstream id;
24328 id << get_pretty_representation(/*internal=*/true, /*qualified_name*/true);
24329 if (s)
24330 {
24331 string virtual_member_suffix;
24332 if (is_method_decl(this))
24333 {
24334 method_decl* m = is_method_decl(this);
24335 ABG_ASSERT(m);
24337 {
24339 (m->get_type()->get_class_type(),
24340 /*look_through_decl_only=*/true))
24341 virtual_member_suffix += "/o";
24342 }
24343 }
24344
24345 // Let's use the full symbol name with its version as ID.
24346 id << "{" << s->get_id_string() << "}";
24347
24348 if (!virtual_member_suffix.empty())
24349 id << virtual_member_suffix;
24350 }
24351 else if (!get_linkage_name().empty())
24352 id << "#" << get_linkage_name() << "#";
24353
24354 interned_string result = env.intern(id.str());
24355
24356 return result;
24357}
24358
24359/// Return an ID that tries to uniquely identify the function inside a
24360/// program or a library.
24361///
24362/// So if the function has an underlying elf symbol, the ID is the
24363/// concatenation of the symbol name and its version. Otherwise, the
24364/// ID is the linkage name if its non-null. Otherwise, it's the
24365/// pretty representation of the function.
24366///
24367/// @return the ID.
24370{
24371 lock_guard<recursive_mutex> lock(priv_->mutex_);
24372 if (type_or_decl_base::priv_->id_.empty())
24373 type_or_decl_base::priv_->id_ = get_id(get_symbol());
24374
24375 return type_or_decl_base::priv_->id_;
24376
24377}
24378
24379/// Test if two function declarations are aliases.
24380///
24381/// Two functions declarations are aliases if their symbols are
24382/// aliases, in the ELF sense.
24383///
24384/// @param f1 the first function to consider.
24385///
24386/// @param f2 the second function to consider.
24387///
24388/// @return true iff @p f1 is an alias of @p f2
24389bool
24391{
24392 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
24393
24394 if (!s1 || !s2)
24395 return false;
24396
24397 return elf_symbols_alias(s1, s2);
24398}
24399
24400/// This implements the ir_traversable_base::traverse pure virtual
24401/// function.
24402///
24403/// @param v the visitor used on the current instance.
24404///
24405/// @return true if the entire IR node tree got traversed, false
24406/// otherwise.
24407bool
24409{
24410 if (visiting())
24411 return true;
24412
24413 if (v.visit_begin(this))
24414 {
24415 visiting(true);
24416
24417 if (type_base_sptr t = get_type())
24418 t->traverse(v);
24419
24420 visiting(false);
24421 }
24422 return v.visit_end(this);
24423}
24424
24425/// Destructor of the @ref function_decl type.
24427{delete priv_;}
24428
24429/// A deep comparison operator for a shared pointer to @ref function_decl
24430///
24431/// This function compares to shared pointers to @ref function_decl by
24432/// looking at the pointed-to instances of @ref function_dec
24433/// comparing them too. If the two pointed-to objects are equal then
24434/// this function returns true.
24435///
24436/// @param l the left-hand side argument of the equality operator.
24437///
24438/// @param r the right-hand side argument of the equality operator.
24439///
24440/// @return true iff @p l equals @p r.
24441bool
24443{
24444 if (l.get() == r.get())
24445 return true;
24446 if (!!l != !!r)
24447 return false;
24448
24449 return *l == *r;
24450}
24451
24452/// A deep inequality operator for smart pointers to functions.
24453///
24454/// @param l the left-hand side argument of the inequality operator.
24455///
24456/// @pram r the right-hand side argument of the inequality operator.
24457///
24458/// @return true iff @p is not equal to @p r.
24459bool
24461{return !operator==(l, r);}
24462
24463// <function_decl definitions>
24464
24465// <function_decl::parameter definitions>
24466
24467struct function_decl::parameter::priv
24468{
24469 recursive_mutex mutex_;
24470 type_base_wptr type_;
24471 unsigned index_;
24472 bool variadic_marker_;
24473
24474 priv()
24475 : index_(),
24476 variadic_marker_()
24477 {}
24478
24479 priv(type_base_sptr type,
24480 unsigned index,
24481 bool variadic_marker)
24482 : type_(type),
24483 index_(index),
24484 variadic_marker_(variadic_marker)
24485 {}
24486};// end struct function_decl::parameter::priv
24487
24488function_decl::parameter::parameter(const type_base_sptr type,
24489 unsigned index,
24490 const string& name,
24491 const location& loc,
24492 bool is_variadic)
24493 : type_or_decl_base(type->get_environment(),
24494 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
24495 decl_base(type->get_environment(), name, loc),
24496 priv_(new priv(type, index, is_variadic))
24497{
24498 runtime_type_instance(this);
24499}
24500
24501function_decl::parameter::parameter(const type_base_sptr type,
24502 unsigned index,
24503 const string& name,
24504 const location& loc,
24505 bool is_variadic,
24506 bool is_artificial)
24507 : type_or_decl_base(type->get_environment(),
24508 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
24509 decl_base(type->get_environment(), name, loc),
24510 priv_(new priv(type, index, is_variadic))
24511{
24512 runtime_type_instance(this);
24513 set_is_artificial(is_artificial);
24514}
24515
24516function_decl::parameter::parameter(const type_base_sptr type,
24517 const string& name,
24518 const location& loc,
24519 bool is_variadic,
24520 bool is_artificial)
24521 : type_or_decl_base(type->get_environment(),
24522 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
24523 decl_base(type->get_environment(), name, loc),
24524 priv_(new priv(type, 0, is_variadic))
24525{
24526 runtime_type_instance(this);
24527 set_is_artificial(is_artificial);
24528}
24529
24530function_decl::parameter::parameter(const type_base_sptr type,
24531 unsigned index,
24532 bool variad)
24533 : type_or_decl_base(type->get_environment(),
24534 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
24535 decl_base(type->get_environment(), "", location()),
24536 priv_(new priv(type, index, variad))
24537{
24538 runtime_type_instance(this);
24539}
24540
24541function_decl::parameter::~parameter() = default;
24542
24543const type_base_sptr
24544function_decl::parameter::get_type()const
24545{return priv_->type_.lock();}
24546
24547/// @return a copy of the type name of the parameter.
24548interned_string
24550{
24551 const environment& env = get_environment();
24552
24553 type_base_sptr t = get_type();
24554 string str;
24555 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
24556 str = "...";
24557 else
24558 {
24559 ABG_ASSERT(t);
24561 }
24562 return env.intern(str);
24563}
24564
24565/// @return a copy of the pretty representation of the type of the
24566/// parameter.
24567const string
24569{
24570 type_base_sptr t = get_type();
24571 string str;
24572 if (get_variadic_marker()
24573 || get_environment().is_variadic_parameter_type(t))
24574 str = "...";
24575 else
24576 {
24577 ABG_ASSERT(t);
24579 }
24580 return str;
24581}
24582
24583/// Get a name uniquely identifying the parameter in the function.
24584///
24585///@return the unique parm name id.
24588{
24589 const environment& env = get_environment();
24590
24591
24592 std::ostringstream o;
24593 o << "parameter-" << get_index();
24594
24595 return env.intern(o.str());
24596}
24597
24598unsigned
24599function_decl::parameter::get_index() const
24600{
24601 lock_guard<recursive_mutex> lock(priv_->mutex_);
24602 return priv_->index_;
24603}
24604
24605void
24606function_decl::parameter::set_index(unsigned i)
24607{
24608 lock_guard<recursive_mutex> lock(priv_->mutex_);
24609 priv_->index_ = i;
24610}
24611
24612
24613bool
24614function_decl::parameter::get_variadic_marker() const
24615{
24616 lock_guard<recursive_mutex> lock(priv_->mutex_);
24617 return priv_->variadic_marker_;
24618}
24619
24620/// Compares two instances of @ref function_decl::parameter.
24621///
24622/// If the two intances are different, set a bitfield to give some
24623/// insight about the kind of differences there are.
24624///
24625/// @param l the first artifact of the comparison.
24626///
24627/// @param r the second artifact of the comparison.
24628///
24629/// @param k a pointer to a bitfield that gives information about the
24630/// kind of changes there are between @p l and @p r. This one is set
24631/// iff @p k is non-null and the function returns false.
24632///
24633/// Please note that setting k to a non-null value does have a
24634/// negative performance impact because even if @p l and @p r are not
24635/// equal, the function keeps up the comparison in order to determine
24636/// the different kinds of ways in which they are different.
24637///
24638/// @return true if @p l equals @p r, false otherwise.
24639bool
24641 const function_decl::parameter& r,
24642 change_kind* k)
24643{
24644 bool result = true;
24645
24646 if ((l.get_variadic_marker() != r.get_variadic_marker())
24647 || (l.get_index() != r.get_index())
24648 || (!!l.get_type() != !!r.get_type()))
24649 {
24650 result = false;
24651 if (k)
24652 {
24653 if (l.get_index() != r.get_index())
24655 if (l.get_variadic_marker() != r.get_variadic_marker()
24656 || !!l.get_type() != !!r.get_type())
24658 }
24659 else
24660 ABG_RETURN_FALSE;
24661 }
24662
24663 type_base_sptr l_type = l.get_type();
24664 type_base_sptr r_type = r.get_type();
24665
24666 if (l_type != r_type)
24667 {
24668 result = false;
24669 if (k)
24670 {
24671 if (!types_have_similar_structure(l_type, r_type))
24673 else
24674 *k |= SUBTYPE_CHANGE_KIND;
24675 }
24676 else
24677 ABG_RETURN_FALSE;
24678 }
24679
24680 ABG_RETURN(result);
24681}
24682
24683bool
24684function_decl::parameter::operator==(const parameter& o) const
24685{return equals(*this, o, 0);}
24686
24687bool
24688function_decl::parameter::operator==(const decl_base& o) const
24689{
24690 const function_decl::parameter* p =
24691 dynamic_cast<const function_decl::parameter*>(&o);
24692 if (!p)
24693 return false;
24694 return function_decl::parameter::operator==(*p);
24695}
24696
24697/// Non-member equality operator for @ref function_decl::parameter.
24698///
24699/// @param l the left-hand side of the equality operator
24700///
24701/// @param r the right-hand side of the equality operator
24702///
24703/// @return true iff @p l and @p r equals.
24704bool
24707{
24708 if (!!l != !!r)
24709 return false;
24710 if (!l)
24711 return true;
24712 return *l == *r;
24713}
24714
24715/// Non-member inequality operator for @ref function_decl::parameter.
24716///
24717/// @param l the left-hand side of the equality operator
24718///
24719/// @param r the right-hand side of the equality operator
24720///
24721/// @return true iff @p l and @p r different.
24722bool
24726
24727/// Traverse the diff sub-tree under the current instance
24728/// function_decl.
24729///
24730/// @param v the visitor to invoke on each diff node of the sub-tree.
24731///
24732/// @return true if the traversing has to keep going on, false
24733/// otherwise.
24734bool
24736{
24737 if (visiting())
24738 return true;
24739
24740 if (v.visit_begin(this))
24741 {
24742 visiting(true);
24743 if (type_base_sptr t = get_type())
24744 t->traverse(v);
24745 visiting(false);
24746 }
24747 return v.visit_end(this);
24748}
24749
24750/// Compute the qualified name of the parameter.
24751///
24752/// @param internal set to true if the call is intended for an
24753/// internal use (for technical use inside the library itself), false
24754/// otherwise. If you don't know what this is for, then set it to
24755/// false.
24756///
24757/// @param qn the resulting qualified name.
24758void
24760 bool /*internal*/) const
24761{qualified_name = get_name();}
24762
24763/// Compute and return a copy of the pretty representation of the
24764/// current function parameter.
24765///
24766/// @param internal set to true if the call is intended to get a
24767/// representation of the decl (or type) for the purpose of canonical
24768/// type comparison. This is mainly used in the function
24769/// homonym_type_group::get_canonical_type_for().
24770///
24771/// In other words if the argument for this parameter is true then the
24772/// call is meant for internal use (for technical use inside the
24773/// library itself), false otherwise. If you don't know what this is
24774/// for, then set it to false.
24775///
24776/// @return a copy of the textual representation of the current
24777/// function parameter.
24778string
24780 bool qualified_name) const
24781{
24782 const environment& env = get_environment();
24783
24784 string type_repr;
24785 type_base_sptr t = get_type();
24786 if (!t)
24787 type_repr = "void";
24788 else if (env.is_variadic_parameter_type(t))
24789 type_repr = "...";
24790 else
24791 type_repr = ir::get_type_name(t, qualified_name, internal);
24792
24793 string result = type_repr;
24794 string parm_name = get_name_id();
24795
24796 if (!parm_name.empty())
24797 result += " " + parm_name;
24798
24799 return result;
24800}
24801
24802// </function_decl::parameter definitions>
24803
24804// <class_or_union definitions>
24805
24806/// A constructor for instances of @ref class_or_union.
24807///
24808/// @param env the environment we are operating from.
24809///
24810/// @param name the name of the class.
24811///
24812/// @param size_in_bits the size of an instance of @ref
24813/// class_or_union, expressed in bits
24814///
24815/// @param align_in_bits the alignment of an instance of @ref class_or_union,
24816/// expressed in bits.
24817///
24818/// @param locus the source location of declaration point this class.
24819///
24820/// @param vis the visibility of instances of @ref class_or_union.
24821class_or_union::class_or_union(const environment& env, const string& name,
24822 size_t size_in_bits, size_t align_in_bits,
24823 const location& locus, visibility vis)
24824 : type_or_decl_base(env,
24825 ABSTRACT_TYPE_BASE
24826 | ABSTRACT_DECL_BASE
24827 | ABSTRACT_SCOPE_TYPE_DECL
24828 | ABSTRACT_SCOPE_DECL),
24829 decl_base(env, name, locus, name, vis),
24830 type_base(env, size_in_bits, align_in_bits),
24831 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
24832 priv_(new priv)
24833{}
24834
24835/// Constructor of the @ref class_or_union type.
24836///
24837/// @param env the @ref environment we are operating from.
24838///
24839/// @param name the name of the @ref class_or_union.
24840///
24841/// @param is_declaration_only a boolean saying whether the instance
24842/// represents a declaration only, or not.
24843class_or_union::class_or_union(const environment& env, const string& name,
24844 bool is_declaration_only)
24845 : type_or_decl_base(env,
24846 ABSTRACT_TYPE_BASE
24847 | ABSTRACT_DECL_BASE
24848 | ABSTRACT_SCOPE_TYPE_DECL
24849 | ABSTRACT_SCOPE_DECL),
24850 decl_base(env, name, location(), name),
24851 type_base(env, 0, 0),
24852 scope_type_decl(env, name, 0, 0, location()),
24853 priv_(new priv)
24854{
24855 set_is_declaration_only(is_declaration_only);
24856}
24857
24858/// Return the hash value of the current IR node.
24859///
24860/// Note that upon the first invocation, this member functions
24861/// computes the hash value and returns it. Subsequent invocations
24862/// just return the hash value that was previously calculated.
24863///
24864/// @return the hash value of the current IR node.
24865hash_t
24867{
24868 class_or_union::hash do_hash;
24869 hash_t h = do_hash(this);
24870 return h;
24871}
24872
24873/// This implements the ir_traversable_base::traverse pure virtual
24874/// function.
24875///
24876/// @param v the visitor used on the member nodes of the translation
24877/// unit during the traversal.
24878///
24879/// @return true if the entire IR node tree got traversed, false
24880/// otherwise.
24881bool
24883{
24884 if (v.type_node_has_been_visited(this))
24885 return true;
24886
24887 if (visiting())
24888 return true;
24889
24890 if (v.visit_begin(this))
24891 {
24892 visiting(true);
24893 bool stop = false;
24894
24895 if (!stop)
24896 for (data_members::const_iterator i = get_data_members().begin();
24897 i != get_data_members().end();
24898 ++i)
24899 if (!(*i)->traverse(v))
24900 {
24901 stop = true;
24902 break;
24903 }
24904
24905 if (!stop)
24906 for (auto i= get_member_functions().begin();
24907 i != get_member_functions().end();
24908 ++i)
24909 if (!(*i)->traverse(v))
24910 {
24911 stop = true;
24912 break;
24913 }
24914
24915 if (!stop)
24917 for (auto member_type : get_sorted_member_types())
24918 if (!member_type->traverse(v))
24919 {
24920 stop = true;
24921 break;
24922 }
24923
24924 if (!stop)
24925 for (member_function_templates::const_iterator i =
24927 i != get_member_function_templates().end();
24928 ++i)
24929 if (!(*i)->traverse(v))
24930 {
24931 stop = true;
24932 break;
24933 }
24934
24935 if (!stop)
24936 for (member_class_templates::const_iterator i =
24938 i != get_member_class_templates().end();
24939 ++i)
24940 if (!(*i)->traverse(v))
24941 {
24942 stop = true;
24943 break;
24944 }
24945
24946 if (!stop)
24947 {
24948 if (scope_decl_sptr s = get_scope())
24949 if (type_base_sptr t = is_type(s))
24950 if (!t->traverse(v))
24951 stop = true;
24952 }
24953 visiting(false);
24954 }
24955
24956 bool result = v.visit_end(this);
24958 return result;
24959}
24960
24961/// Destrcutor of the @ref class_or_union type.
24963{delete priv_;}
24964
24965/// Add a member declaration to the current instance of class_or_union.
24966/// The member declaration can be either a member type, data member,
24967/// member function, or member template.
24968///
24969/// @param d the member declaration to add.
24970decl_base_sptr
24971add_member_decl(class_or_union_sptr cou, decl_base_sptr d)
24972{return insert_member_decl(cou, d);}
24973
24974/// Remove a given decl from the current @ref class_or_union scope.
24975///
24976/// Note that only type declarations are supported by this method for
24977/// now. Support for the other kinds of declaration is left as an
24978/// exercise for the interested reader of the code.
24979///
24980/// @param decl the declaration to remove from this @ref
24981/// class_or_union scope.
24982bool
24983remove_member_decl(class_or_union_sptr cou, decl_base_sptr decl)
24984{
24985 type_base_sptr t = is_type(decl);
24986
24987 // For now we want to support just removing types from classes. For
24988 // other kinds of IR node, we need more work.
24989 ABG_ASSERT(t);
24990
24991 return cou->remove_member_type(t);
24992}
24993
24994/// Fixup the members of the type of an anonymous data member.
24995///
24996/// Walk all data members of (the type of) a given anonymous data
24997/// member and set a particular property of the relationship between
24998/// each data member and its containing type.
24999///
25000/// That property records the fact that the data member belongs to the
25001/// anonymous data member we consider.
25002///
25003/// In the future, if there are other properties of this relationship
25004/// to set in this manner, they ought to be added here.
25005///
25006/// @param anon_dm the anonymous data member to consider.
25007void
25009{
25010 class_or_union * anon_dm_type =
25012 if (!anon_dm_type)
25013 return;
25014
25015 lock_guard<recursive_mutex> lock(anon_dm_type->get_mutex());
25016 for (class_or_union::data_members::const_iterator it =
25017 anon_dm_type->get_non_static_data_members().begin();
25018 it != anon_dm_type->get_non_static_data_members().end();
25019 ++it)
25020 {
25021 dm_context_rel *rel =
25022 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
25023 ABG_ASSERT(rel);
25024 rel->set_anonymous_data_member(anon_dm);
25025 }
25026}
25027
25028/// Getter of the alignment of the @ref class_or_union type.
25029///
25030/// If this @ref class_or_union is a declaration of a definition that
25031/// is elsewhere, then the size of the definition is returned.
25032///
25033/// @return the alignment of the @ref class_or_union type.
25034size_t
25043
25044/// Setter of the alignment of the class type.
25045///
25046/// If this class is a declaration of a definition that is elsewhere,
25047/// then the new alignment is set to the definition.
25048///
25049/// @param s the new alignment.
25050void
25059
25060/// Setter of the size of the @ref class_or_union type.
25061///
25062/// If this @ref class_or_union is a declaration of a definition that
25063/// is elsewhere, then the new size is set to the definition.
25064///
25065/// @param s the new size.
25066void
25075
25076/// Getter of the size of the @ref class_or_union type.
25077///
25078/// If this @ref class_or_union is a declaration of a definition that
25079/// is elsewhere, then the size of the definition is returned.
25080///
25081/// @return the size of the @ref class_or_union type.
25082size_t
25091
25092/// Get the number of anonymous member classes contained in this
25093/// class.
25094///
25095/// @return the number of anonymous member classes contained in this
25096/// class.
25097size_t
25099{
25100 int result = 0;
25101 for (member_types::const_iterator it = get_member_types().begin();
25102 it != get_member_types().end();
25103 ++it)
25104 if (class_decl_sptr t = is_class_type(*it))
25105 if (t->get_is_anonymous())
25106 ++result;
25107
25108 return result;
25109}
25110
25111/// Get the number of anonymous member unions contained in this class.
25112///
25113/// @return the number of anonymous member unions contained in this
25114/// class.
25115size_t
25117{
25118 int result = 0;
25119 for (member_types::const_iterator it = get_member_types().begin();
25120 it != get_member_types().end();
25121 ++it)
25122 if (union_decl_sptr t = is_union_type(*it))
25123 if (t->get_is_anonymous())
25124 ++result;
25125
25126 return result;
25127}
25128
25129/// Get the number of anonymous member enums contained in this class.
25130///
25131/// @return the number of anonymous member enums contained in this
25132/// class.
25133size_t
25135{
25136 int result = 0;
25137 for (member_types::const_iterator it = get_member_types().begin();
25138 it != get_member_types().end();
25139 ++it)
25140 if (enum_type_decl_sptr t = is_enum_type(*it))
25141 if (t->get_is_anonymous())
25142 ++result;
25143
25144 return result;
25145}
25146
25147/// Add a data member to the current instance of class_or_union.
25148///
25149/// @param v a var_decl to add as a data member. A proper
25150/// class_or_union::data_member is created from @p v and added to the
25151/// class_or_union. This var_decl should not have been already added
25152/// to a scope.
25153///
25154/// @param access the access specifier for the data member.
25155///
25156/// @param is_laid_out whether the data member was laid out. That is,
25157/// if its offset has been computed. In the pattern of a class
25158/// template for instance, this would be set to false.
25159///
25160/// @param is_static whether the data memer is static.
25161///
25162/// @param offset_in_bits if @p is_laid_out is true, this is the
25163/// offset of the data member, expressed (oh, surprise) in bits.
25164void
25165add_data_member(class_or_union_sptr cou,
25167 bool is_laid_out, bool is_static,
25168 size_t offset_in_bits)
25169{
25170 ABG_ASSERT(cou);
25171 ABG_ASSERT(!has_scope(v));
25172
25173 {
25174 lock_guard<recursive_mutex> lock(cou->get_mutex());
25175 cou->priv_->data_members_.push_back(v);
25176 }
25177 add_member_decl(static_pointer_cast<scope_decl>(cou), v);
25178 set_data_member_is_laid_out(v, is_laid_out);
25179 set_data_member_offset(v, offset_in_bits);
25180 set_member_access_specifier(v, access);
25181 set_member_is_static(v, is_static);
25182
25183 // Add the variable to the set of static or non-static data members,
25184 // if it's not already in there.
25185 bool is_already_in = false;
25186 if (is_static)
25187 {
25188 lock_guard<recursive_mutex> lock(cou->get_mutex());
25189 for (const auto& s_dm: cou->priv_->static_data_members_)
25190 {
25191 if (s_dm == v)
25192 {
25193 is_already_in = true;
25194 break;
25195 }
25196 }
25197 if (!is_already_in)
25198 cou->priv_->static_data_members_.push_back(v);
25199 }
25200 else
25201 {
25202 lock_guard<recursive_mutex> lock(cou->get_mutex());
25203 // If this is a non-static variable, add it to the set of
25204 // non-static variables, if it's not already in there.
25205 for (auto dm : cou->priv_->non_static_data_members_)
25206 if (dm == v)
25207 {
25208 is_already_in = true;
25209 break;
25210 }
25211
25212 if (!is_already_in)
25213 cou->priv_->non_static_data_members_.push_back(v);
25214 }
25215
25216 // If v is an anonymous data member, then fixup its data members.
25217 // For now, the only thing the fixup does is to make the data
25218 // members of the anonymous data member be aware of their containing
25219 // anonymous data member. That is helpful to compute the absolute
25220 // bit offset of each of the members of the anonymous data member.
25221 cou->maybe_fixup_members_of_anon_data_member(v);
25222}
25223
25224/// Get the data members of this @ref class_or_union.
25225///
25226/// @return a vector of the data members of this @ref class_or_union.
25229{return priv_->data_members_;}
25230
25231/// Get a copy of the the data members of this @ref class_or_union.
25232///
25233/// @return a vector of the data members of this @ref class_or_union.
25236{
25237 data_members result;
25238 {
25239 lock_guard<recursive_mutex> lock(get_mutex());
25240 result.reserve(priv_->data_members_.size());
25241 for (auto d : priv_->data_members_)
25242 result.push_back(d);
25243 }
25244 return result;
25245}
25246
25247/// Find a data member of a given name in the current @ref class_or_union.
25248///
25249/// @param name the name of the data member to find in the current
25250/// @ref class_or_union.
25251///
25252/// @return a pointer to the @ref var_decl that represents the data
25253/// member to find inside the current @ref class_or_union.
25254const var_decl_sptr
25255class_or_union::find_data_member(const string& name) const
25256{
25257 for (auto m : get_data_members())
25258 if (m->get_name() == name)
25259 return m;
25260
25261 // We haven't found a data member with the name 'name'. Let's look
25262 // closer again, this time in our anonymous data members.
25263 for (auto m : get_data_members())
25265 {
25266 class_or_union_sptr type = is_class_or_union_type(m->get_type());
25267 ABG_ASSERT(type);
25268 if (var_decl_sptr data_member = type->find_data_member(name))
25269 return data_member;
25270 }
25271
25272 return var_decl_sptr();
25273}
25274
25275/// Find an anonymous data member in the class.
25276///
25277/// @param v the anonymous data member to find.
25278///
25279/// @return the anonymous data member found, or nil if none was found.
25280const var_decl_sptr
25282{
25283 if (!v->get_name().empty())
25284 return var_decl_sptr();
25285
25286 lock_guard<recursive_mutex> lock(get_mutex());
25287 for (auto m : get_non_static_data_members())
25289 if (m->get_pretty_representation(/*internal=*/false, true)
25290 == v->get_pretty_representation(/*internal=*/false, true))
25291 return m;
25292
25293 return var_decl_sptr();
25294}
25295
25296/// Find a given data member.
25297///
25298/// This function takes a @ref var_decl as an argument. If it has a
25299/// non-empty name, then it tries to find a data member which has the
25300/// same name as the argument.
25301///
25302/// If it has an empty name, then the @ref var_decl is considered as
25303/// an anonymous data member. In that case, this function tries to
25304/// find an anonymous data member which type equals that of the @ref
25305/// var_decl argument.
25306///
25307/// @param v this carries either the name of the data member we need
25308/// to look for, or the type of the anonymous data member we are
25309/// looking for.
25310const var_decl_sptr
25312{
25313 if (!v)
25314 return var_decl_sptr();
25315
25316 if (v->get_name().empty())
25318
25319 return find_data_member(v->get_name());
25320}
25321
25322
25323/// Get the non-static data members of this @ref class_or_union.
25324///
25325/// @return a vector of the non-static data members of this @ref
25326/// class_or_union.
25329{
25330 lock_guard<recursive_mutex> lock(get_mutex());
25331 return priv_->non_static_data_members_;
25332}
25333
25334/// Get the static data memebers of this @ref class_or_union.
25335///
25336/// @return a vector of the static data members of this @ref
25337/// class_or_union.
25340{
25341 lock_guard<recursive_mutex> lock(get_mutex());
25342 return priv_->static_data_members_;
25343}
25344
25345/// A "less than" functor to sort a vector of instances of
25346/// method_decl.
25347struct member_function_less_than
25348{
25349 /// The less than operator. First, it sorts them by the name of
25350 /// their ELF symbol. If they don't have elf symbols, it sorts them
25351 /// by considering their pretty representation.
25352 ///
25353 /// @param f the first method to consider.
25354 ///
25355 /// @param s the second method to consider.
25356 ///
25357 /// @return true if method @p is less than method @s.
25358 bool
25359 operator()(const method_decl& f,
25360 const method_decl& s)
25361 {
25362 string fn, sn;
25363 // Try the linkage names (important for destructors).
25364 fn = f.get_linkage_name();
25365 sn = s.get_linkage_name();
25366 if (fn != sn) return fn < sn;
25367
25368 // If the functions have symbols, then compare their symbol-id
25369 // string.
25370 elf_symbol_sptr f_sym = f.get_symbol();
25371 elf_symbol_sptr s_sym = s.get_symbol();
25372 if ((!f_sym) != (!s_sym)) return !f_sym;
25373 if (f_sym && s_sym)
25374 {
25375 fn = f_sym->get_id_string();
25376 sn = s_sym->get_id_string();
25377 if (fn != sn) return fn < sn;
25378 }
25379
25380 // None of the functions have symbols or linkage names that
25381 // distinguish them, so compare their pretty representation.
25384 if (fn != sn) return fn < sn;
25385
25386 /// If it's just the file paths that are different then sort them
25387 /// too.
25388 string fn_filepath, sn_filepath;
25389 unsigned line = 0, column = 0;
25390 location fn_loc = f.get_location(), sn_loc = s.get_location();
25391 if (fn_loc)
25392 fn_loc.expand(fn_filepath, line, column);
25393 if (sn_loc)
25394 sn_loc.expand(sn_filepath, line, column);
25395 return fn_filepath < sn_filepath;
25396 }
25397
25398 /// The less than operator. First, it sorts the methods by their
25399 /// vtable index. If they have the same vtable index, it sorts them
25400 /// by the name of their ELF symbol. If they don't have elf
25401 /// symbols, it sorts them by considering their pretty
25402 /// representation.
25403 ///
25404 /// Note that this method expects to take virtual methods.
25405 ///
25406 /// @param f the first method to consider.
25407 ///
25408 /// @param s the second method to consider.
25409 bool
25410 operator()(const method_decl_sptr f,
25411 const method_decl_sptr s)
25412 {return operator()(*f, *s);}
25413}; // end struct member_function_less_than
25414
25415static void
25416sort_member_functions(class_decl::member_functions& mem_fns)
25417{
25418 member_function_less_than lt;
25419 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25420}
25421
25422/// Add a member function.
25423///
25424/// @param f the new member function to add.
25425///
25426/// @param a the access specifier to use for the new member function.
25427///
25428/// @param is_static whether the new member function is static.
25429///
25430/// @param is_ctor whether the new member function is a constructor.
25431///
25432/// @param is_dtor whether the new member function is a destructor.
25433///
25434/// @param is_const whether the new member function is const.
25435void
25436add_member_function(class_or_union_sptr cou,
25437 method_decl_sptr f,
25439 bool is_static, bool is_ctor,
25440 bool is_dtor, bool is_const)
25441{
25442 ABG_ASSERT(cou);
25443 ABG_ASSERT(!has_scope(f));
25444
25445 add_member_decl(static_pointer_cast<scope_decl>(cou), f);
25446
25447 set_member_function_is_ctor(f, is_ctor);
25448 set_member_function_is_dtor(f, is_dtor);
25450 set_member_is_static(f, is_static);
25451 set_member_function_is_const(f, is_const);
25452
25453 {
25454 lock_guard<recursive_mutex> lock(cou->priv_->member_functions_mutex_);
25455 cou->priv_->member_functions_.push_back(f);
25456 cou->priv_->member_functions_sorted_ = false;
25457 }
25458
25459 // Update the map of linkage name -> member functions. It's useful,
25460 // so that class_or_union::find_member_function() can function.
25461 if (!f->get_linkage_name().empty())
25462 {
25463 {
25464 lock_guard<recursive_mutex> lock(cou->priv_->member_functions_mutex_);
25465 cou->priv_->mem_fns_map_[f->get_linkage_name()] = f;
25466 }
25467 string demangled_name =
25468 demangle_cplus_mangled_name(f->get_linkage_name());
25469 if (demangled_name != f->get_linkage_name())
25470 {
25471 lock_guard<recursive_mutex> lock(cou->priv_->member_functions_mutex_);
25472 cou->priv_->mem_fns_map_[demangled_name] = f;
25473 }
25474 }
25475 else
25476 {
25477 lock_guard<recursive_mutex> lock(cou->priv_->member_functions_mutex_);
25478 cou->priv_->mem_fns_map_[f->get_name()] = f;
25479 }
25480}
25481
25482/// Get the member functions of this @ref class_or_union.
25483///
25484/// @return a vector of the member functions of this @ref
25485/// class_or_union.
25488{
25489 lock_guard<recursive_mutex> lock(priv_->member_functions_mutex_);
25490 if (!priv_->member_functions_sorted_)
25491 {
25492 sort_member_functions(priv_->member_functions_);
25493 priv_->member_functions_sorted_ = true;
25494 }
25495 return priv_->member_functions_;
25496}
25497
25498/// Get a copy of the member functions of this @ref class_or_union.
25499///
25500/// @return a vector of the member functions of this @ref
25501/// class_or_union.
25504{
25505 member_functions result;
25506 {
25507 lock_guard<recursive_mutex> lock(priv_->member_functions_mutex_);
25508 result.reserve(priv_->member_functions_.size());
25509 for (auto f : get_member_functions())
25510 result.push_back(f);
25511 }
25512 return result;
25513}
25514
25515/// Find a method, using its linkage name as a key.
25516///
25517/// @param linkage_name the linkage name of the method to find.
25518///
25519/// @return the method found, or nil if none was found.
25520const method_decl*
25521class_or_union::find_member_function(const string& linkage_name) const
25522{
25523 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
25524}
25525
25526/// Find a method, using its linkage name as a key.
25527///
25528/// @param linkage_name the linkage name of the method to find.
25529///
25530/// @return the method found, or nil if none was found.
25532class_or_union::find_member_function(const string& linkage_name)
25533{
25534 lock_guard<recursive_mutex> lock(priv_->member_functions_mutex_);
25535 string_mem_fn_sptr_map_type::const_iterator i =
25536 priv_->mem_fns_map_.find(linkage_name);
25537 if (i == priv_->mem_fns_map_.end())
25538 return 0;
25539 return i->second.get();
25540}
25541
25542/// Find a method, using its linkage name as a key.
25543///
25544/// @param linkage_name the linkage name of the method to find.
25545///
25546/// @return the method found, or nil if none was found.
25547method_decl_sptr
25549{
25550 lock_guard<recursive_mutex> lock(priv_->member_functions_mutex_);
25551 string_mem_fn_sptr_map_type::const_iterator i =
25552 priv_->mem_fns_map_.find(linkage_name);
25553 if (i == priv_->mem_fns_map_.end())
25554 return 0;
25555 return i->second;
25556}
25557
25558const method_decl*
25559class_or_union::find_member_function(const char* linkage_name) const
25560{
25561 if (!linkage_name)
25562 return nullptr;
25563 return find_member_function(string(linkage_name));
25564}
25565
25566/// Find a method (member function) using its signature (pretty
25567/// representation) as a key.
25568///
25569/// @param s the signature of the method.
25570///
25571/// @return the method found, or nil if none was found.
25572const method_decl*
25574{
25575 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
25576}
25577
25578/// Find a method (member function) using its signature (pretty
25579/// representation) as a key.
25580///
25581/// @param s the signature of the method.
25582///
25583/// @return the method found, or nil if none was found.
25586{
25587 lock_guard<recursive_mutex> lock(get_mutex());
25588 string_mem_fn_ptr_map_type::const_iterator i =
25589 priv_->signature_2_mem_fn_map_.find(s);
25590 if (i == priv_->signature_2_mem_fn_map_.end())
25591 return 0;
25592 return i->second;
25593}
25594
25595/// Get the member function templates of this class.
25596///
25597/// @return a vector of the member function templates of this class.
25598const member_function_templates&
25600{return priv_->member_function_templates_;}
25601
25602/// Get the member class templates of this class.
25603///
25604/// @return a vector of the member class templates of this class.
25605const member_class_templates&
25607{return priv_->member_class_templates_;}
25608
25609/// Append a member function template to the @ref class_or_union.
25610///
25611/// @param m the member function template to append.
25612void
25613add_member_function_template(class_or_union_sptr cou,
25614 member_function_template_sptr m)
25615{
25616 decl_base_sptr c = m->as_function_tdecl()->get_scope();
25617 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
25618 /// error message or something like a structured error.
25619 if (!c)
25620 {
25621 add_member_decl(static_pointer_cast<scope_decl>(cou),
25622 m->as_function_tdecl());
25623 cou->priv_->member_function_templates_.push_back(m);
25624 m->set_scope(cou);
25625 }
25626}
25627
25628/// Append a member class template to the @ref class_or_union.
25629///
25630/// @param m the member function template to append.
25631void
25632add_member_class_template(class_or_union_sptr cou,
25633 member_class_template_sptr m)
25634{
25635 scope_decl_sptr scope = m->as_class_tdecl()->get_scope();
25636 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
25637 /// error message or something like a structured error.
25638 if (!scope)
25639 {
25640 add_member_decl(static_pointer_cast<scope_decl>(cou),
25641 m->as_class_tdecl());
25642 cou->priv_->member_class_templates_.push_back(m);
25643 m->set_scope(cou);
25644 }
25645
25646
25647}
25648
25649///@return true iff the current instance has no member.
25650bool
25652{
25653 return (get_member_types().empty()
25654 && priv_->data_members_.empty()
25655 && priv_->member_functions_.empty()
25656 && priv_->member_function_templates_.empty()
25657 && priv_->member_class_templates_.empty());
25658}
25659
25660/// Insert a data member to this @ref class_or_union type.
25661///
25662/// @param d the data member to insert.
25663///
25664/// @return the decl @p that got inserted.
25665decl_base_sptr
25666insert_member_decl(class_or_union_sptr cou,
25667 decl_base_sptr d)
25668{
25669 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
25670 {
25671 add_data_member(cou, v, public_access,
25672 /*is_laid_out=*/false,
25673 /*is_static=*/true,
25674 /*offset_in_bits=*/0);
25675 d = v;
25676 }
25677 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
25678 add_member_function(cou, f, public_access,
25679 /*is_static=*/false,
25680 /*is_ctor=*/false,
25681 /*is_dtor=*/false,
25682 /*is_const=*/false);
25683 else if (member_function_template_sptr f =
25684 dynamic_pointer_cast<member_function_template>(d))
25686 else if (member_class_template_sptr c =
25687 dynamic_pointer_cast<member_class_template>(d))
25689 else
25690 add_member_decl(static_pointer_cast<scope_decl>(cou), d);
25691
25692 return d;
25693}
25694
25695/// Equality operator.
25696///
25697/// @param other the other @ref class_or_union to compare against.
25698///
25699/// @return true iff @p other equals the current @ref class_or_union.
25700bool
25702{
25703 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
25704 if (!op)
25705 return false;
25706
25707 // If this is a decl-only type (and thus with no canonical type),
25708 // use the canonical type of the definition, if any.
25709 const class_or_union *l = 0;
25711 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
25712 if (l == 0)
25713 l = this;
25714
25715 // Likewise for the other class.
25716 const class_or_union *r = 0;
25717 if (op->get_is_declaration_only())
25718 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
25719 if (r == 0)
25720 r = op;
25721
25722 return try_canonical_compare(l, r);
25723}
25724
25725/// Equality operator.
25726///
25727/// @param other the other @ref class_or_union to compare against.
25728///
25729/// @return true iff @p other equals the current @ref class_or_union.
25730bool
25732{
25733 const decl_base* o = dynamic_cast<const decl_base*>(&other);
25734 if (!o)
25735 return false;
25736 return *this == *o;
25737}
25738
25739/// Equality operator.
25740///
25741/// @param other the other @ref class_or_union to compare against.
25742///
25743/// @return true iff @p other equals the current @ref class_or_union.
25744bool
25746{
25747 const decl_base& o = other;
25749}
25750
25751/// Compares two instances of @ref class_or_union.
25752///
25753/// If the two intances are different, set a bitfield to give some
25754/// insight about the kind of differences there are.
25755///
25756/// @param l the first artifact of the comparison.
25757///
25758/// @param r the second artifact of the comparison.
25759///
25760/// @param k a pointer to a bitfield that gives information about the
25761/// kind of changes there are between @p l and @p r. This one is set
25762/// iff it's non-null and if the function returns false.
25763///
25764/// Please note that setting k to a non-null value does have a
25765/// negative performance impact because even if @p l and @p r are not
25766/// equal, the function keeps up the comparison in order to determine
25767/// the different kinds of ways in which they are different.
25768///
25769/// @return true if @p l equals @p r, false otherwise.
25770bool
25772{
25773 // if one of the classes is declaration-only, look through it to
25774 // get its definition.
25775 bool l_is_decl_only = l.get_is_declaration_only();
25776 bool r_is_decl_only = r.get_is_declaration_only();
25777 if (l_is_decl_only || r_is_decl_only)
25778 {
25779 const class_or_union* def1 = l_is_decl_only
25781 : &l;
25782
25783 const class_or_union* def2 = r_is_decl_only
25785 : &r;
25786
25787 if (!def1 || !def2)
25788 {
25789 if (!l.get_is_anonymous()
25790 && !r.get_is_anonymous()
25791 && l_is_decl_only && r_is_decl_only
25793 // The two decl-only classes differ from their size. A
25794 // true decl-only class should not have a size property to
25795 // begin with. This comes from a DWARF oddity and can
25796 // results in a false positive, so let's not consider that
25797 // change.
25798 return true;
25799
25803 {
25804 const interned_string& q1 = l.get_scoped_name();
25805 const interned_string& q2 = r.get_scoped_name();
25806 if (q1 == q2)
25807 // Not using RETURN(true) here, because that causes
25808 // performance issues. We don't need to do
25809 // l.priv_->unmark_as_being_compared({l,r}) here because
25810 // we haven't marked l or r as being compared yet, and
25811 // doing so has a peformance cost that shows up on
25812 // performance profiles for *big* libraries.
25813 return true;
25814 else
25815 {
25816 if (k)
25818 // Not using RETURN(true) here, because that causes
25819 // performance issues. We don't need to do
25820 // l.priv_->unmark_as_being_compared({l,r}) here because
25821 // we haven't marked l or r as being compared yet, and
25822 // doing so has a peformance cost that shows up on
25823 // performance profiles for *big* libraries.
25824 ABG_RETURN_FALSE;
25825 }
25826 }
25827 else // A decl-only class is considered different from a
25828 // class definition of the same name.
25829 {
25830 if (!!def1 != !!def2)
25831 {
25832 if (k)
25834 ABG_RETURN_FALSE;
25835 }
25836
25837 // both definitions are empty
25838 if (!(l.decl_base::operator==(r)
25839 && l.type_base::operator==(r)))
25840 {
25841 if (k)
25843 ABG_RETURN_FALSE;
25844 }
25845
25846 return true;
25847 }
25848 }
25849
25850 bool val = *def1 == *def2;
25851 if (!val)
25852 if (k)
25854 ABG_RETURN(val);
25855 }
25856
25857 // No need to go further if the classes have different names or
25858 // different size / alignment.
25859 if (!(l.decl_base::operator==(r)
25860 && l.type_base::operator==(r)
25861 && l.get_scoped_name() == r.get_scoped_name()))
25862 {
25863 if (k)
25865 ABG_RETURN_FALSE;
25866 }
25867
25868 if (types_defined_same_linux_kernel_corpus_public(l, r))
25869 return true;
25870
25871#define RETURN(value) return return_comparison_result(l, r, value);
25872
25873 //TODO: Maybe remove this (cycle detection and canonical type
25874 //propagation handling) from here and have it only in the equal
25875 //overload for class_decl and union_decl because this one ( the
25876 //equal overload for class_or_union) is just a sub-routine of these
25877 //two above.
25878
25880
25882
25883 bool result = true;
25884
25885 //compare data_members
25886 {
25887 if (l.get_non_static_data_members().size()
25888 != r.get_non_static_data_members().size())
25889 {
25890 result = false;
25891 if (k)
25893 else
25894 RETURN(result);
25895 }
25896
25897 for (class_or_union::data_members::const_iterator
25898 d0 = l.get_non_static_data_members().begin(),
25899 d1 = r.get_non_static_data_members().begin();
25900 (d0 != l.get_non_static_data_members().end()
25901 && d1 != r.get_non_static_data_members().end());
25902 ++d0, ++d1)
25903 if (**d0 != **d1)
25904 {
25905 result = false;
25906 if (k)
25907 {
25908 // Report any representation change as being local.
25909 if (!types_have_similar_structure((*d0)->get_type(),
25910 (*d1)->get_type())
25911 || (*d0)->get_type() == (*d1)->get_type())
25913 else
25914 *k |= SUBTYPE_CHANGE_KIND;
25915 }
25916 else
25917 RETURN(result);
25918 }
25919 }
25920
25921 // Do not compare member functions. DWARF does not necessarily
25922 // all the member functions, be they virtual or not, in all
25923 // translation units. So we cannot have a clear view of them, per
25924 // class
25925
25926 // compare member function templates
25927 {
25928 if (l.get_member_function_templates().size()
25929 != r.get_member_function_templates().size())
25930 {
25931 result = false;
25932 if (k)
25934 else
25935 RETURN(result);
25936 }
25937
25938 for (member_function_templates::const_iterator
25939 fn_tmpl_it0 = l.get_member_function_templates().begin(),
25940 fn_tmpl_it1 = r.get_member_function_templates().begin();
25941 fn_tmpl_it0 != l.get_member_function_templates().end()
25942 && fn_tmpl_it1 != r.get_member_function_templates().end();
25943 ++fn_tmpl_it0, ++fn_tmpl_it1)
25944 if (**fn_tmpl_it0 != **fn_tmpl_it1)
25945 {
25946 result = false;
25947 if (k)
25948 {
25950 break;
25951 }
25952 else
25953 RETURN(result);
25954 }
25955 }
25956
25957 // compare member class templates
25958 {
25959 if (l.get_member_class_templates().size()
25960 != r.get_member_class_templates().size())
25961 {
25962 result = false;
25963 if (k)
25965 else
25966 RETURN(result);
25967 }
25968
25969 for (member_class_templates::const_iterator
25970 cl_tmpl_it0 = l.get_member_class_templates().begin(),
25971 cl_tmpl_it1 = r.get_member_class_templates().begin();
25972 cl_tmpl_it0 != l.get_member_class_templates().end()
25973 && cl_tmpl_it1 != r.get_member_class_templates().end();
25974 ++cl_tmpl_it0, ++cl_tmpl_it1)
25975 if (**cl_tmpl_it0 != **cl_tmpl_it1)
25976 {
25977 result = false;
25978 if (k)
25979 {
25981 break;
25982 }
25983 else
25984 RETURN(result);
25985 }
25986 }
25987
25988 RETURN(result);
25989#undef RETURN
25990}
25991
25992/// Copy a method of a @ref class_or_union into a new @ref
25993/// class_or_union.
25994///
25995/// @param t the @ref class_or_union into which the method is to be copied.
25996///
25997/// @param method the method to copy into @p t.
25998///
25999/// @return the resulting newly copied method.
26000method_decl_sptr
26001copy_member_function(class_or_union_sptr t,
26002 const method_decl_sptr& method)
26003{return copy_member_function(t, method.get());}
26004
26005/// Copy a method of a @ref class_or_union into a new @ref
26006/// class_or_union.
26007///
26008/// @param t the @ref class_or_union into which the method is to be copied.
26009///
26010/// @param method the method to copy into @p t.
26011///
26012/// @return the resulting newly copied method.
26013method_decl_sptr
26014copy_member_function(class_or_union_sptr t, const method_decl* method)
26015{
26016 ABG_ASSERT(t);
26017 ABG_ASSERT(method);
26018
26020
26021 method_type_sptr old_type = method->get_type();
26022 ABG_ASSERT(old_type);
26023 method_type_sptr new_type(new method_type(old_type->get_return_type(),
26024 t,
26025 old_type->get_parameters(),
26026 old_type->get_is_const(),
26027 old_type->get_size_in_bits(),
26028 old_type->get_alignment_in_bits()));
26029 bind_function_type_life_time(new_type, t->get_translation_unit());
26030 if (offset_t offset = old_type->get_native_offset())
26031 new_type->set_native_offset(offset);
26032
26033 method_decl_sptr
26034 new_method(new method_decl(method->get_name(),
26035 new_type,
26036 method->is_declared_inline(),
26037 method->get_location(),
26038 method->get_linkage_name(),
26039 method->get_visibility(),
26040 method->get_binding()));
26041 new_method->set_symbol(method->get_symbol());
26042
26043 if (class_decl_sptr class_type = is_class_type(t))
26044 add_member_function(class_type, new_method,
26048 get_member_is_static(*method),
26052 else
26053 add_member_function(t, new_method,
26055 get_member_is_static(*method),
26059
26060 new_method->set_original_artefact(method);
26061 return new_method;
26062}
26063
26064/// Copy a data member of a @ref class_or_union into a new @ref
26065/// class_or_union.
26066///
26067/// @param t the @ref class_or_union into which the data member is to
26068/// be copied.
26069///
26070/// @param variable the data member to copy into @p t.
26071///
26072/// @return the resulting newly copied method.
26074copy_member_variable(class_or_union_sptr t, const var_decl* variable)
26075{
26076 ABG_ASSERT(variable);
26077 ABG_ASSERT(is_data_member(variable));
26078 ABG_ASSERT(t);
26079 ABG_ASSERT(!t->find_data_member(variable->get_name()));
26080
26081 type_base_sptr old_type = variable->get_type();
26082
26083 var_decl_sptr new_variable(new var_decl(variable->get_name(),
26084 old_type,
26085 variable->get_location(),
26086 variable->get_linkage_name(),
26087 variable->get_visibility(),
26088 variable->get_binding()));
26089
26090 size_t offset_in_bits = 0;
26091 if (get_data_member_is_laid_out(*variable))
26092 offset_in_bits = get_data_member_offset(*variable);
26093
26094 add_data_member(t, new_variable,
26095 get_member_access_specifier(*variable),
26096 get_data_member_is_laid_out(*variable),
26097 get_member_is_static(*variable),
26098 offset_in_bits);
26099
26100 new_variable->set_original_artefact(variable);
26101
26102 return new_variable;
26103}
26104
26105/// Copy a data member of a @ref class_or_union into a new @ref
26106/// class_or_union.
26107///
26108/// @param t the @ref class_or_union into which the data member is to
26109/// be copied.
26110///
26111/// @param variable the data member to copy into @p t.
26112///
26113/// @return the resulting newly copied method.
26115copy_member_variable(class_or_union_sptr t, const var_decl_sptr& variable)
26116{return copy_member_variable(t, variable.get());}
26117
26118/// Copy a data member of a @ref class_or_union into a new @ref
26119/// class_or_union.
26120///
26121/// @param t the @ref class_or_union into which the data member is to
26122/// be copied.
26123///
26124/// @param variable the data member to copy into @p t.
26125///
26126/// @return the resulting newly copied method.
26129{return copy_member_variable(static_pointer_cast<class_or_union>(t), variable);}
26130
26131/// Move a member type of a @ref scope_decl to another @ref
26132/// scope_decl.
26133///
26134/// @param member_type the member type to move.
26135///
26136/// @param new_scope the destination scope to move @p member_type to.
26137void
26138move_member_type(decl_base_sptr member_type,
26139 scope_decl_sptr new_scope)
26140{
26141 decl_base_sptr m = member_type;
26142 access_specifier a = no_access;
26143 if (is_member_decl(m))
26147 add_decl_to_scope(m, new_scope);
26148 if (is_member_decl(m))
26150}
26151
26152// </class_or_union definitions>
26153
26154// <class_decl definitions>
26155
26156static void
26157sort_virtual_member_functions(class_decl::member_functions& mem_fns);
26158
26159/// A constructor for instances of class_decl.
26160///
26161/// @param env the environment we are operating from.
26162///
26163/// @param name the name of the class.
26164///
26165/// @param size_in_bits the size of an instance of class_decl, expressed
26166/// in bits
26167///
26168/// @param align_in_bits the alignment of an instance of class_decl,
26169/// expressed in bits.
26170///
26171/// @param locus the source location of declaration point this class.
26172///
26173/// @param vis the visibility of instances of class_decl.
26174class_decl::class_decl(const environment& env, const string& name,
26175 size_t size_in_bits, size_t align_in_bits,
26176 bool is_struct, const location& locus,
26177 visibility vis)
26178 : type_or_decl_base(env,
26179 CLASS_TYPE
26180 | ABSTRACT_TYPE_BASE
26181 | ABSTRACT_DECL_BASE
26182 | ABSTRACT_SCOPE_TYPE_DECL
26183 | ABSTRACT_SCOPE_DECL),
26184 decl_base(env, name, locus, name, vis),
26185 type_base(env, size_in_bits, align_in_bits),
26186 class_or_union(env, name, size_in_bits, align_in_bits,
26187 locus, vis),
26188 priv_(new priv(is_struct))
26189{
26191}
26192
26193/// A constructor for instances of @ref class_decl.
26194///
26195/// @param env the environment we are operating from.
26196///
26197/// @param name the name of the class.
26198///
26199/// @param size_in_bits the size of an instance of class_decl, expressed
26200/// in bits
26201///
26202/// @param align_in_bits the alignment of an instance of class_decl,
26203/// expressed in bits.
26204///
26205/// @param locus the source location of declaration point this class.
26206///
26207/// @param vis the visibility of instances of class_decl.
26208///
26209/// @param is_anonymous whether the newly created instance is
26210/// anonymous.
26211class_decl:: class_decl(const environment& env, const string& name,
26212 size_t size_in_bits, size_t align_in_bits,
26213 bool is_struct, const location& locus,
26214 visibility vis, bool is_anonymous)
26215 : type_or_decl_base(env,
26216 CLASS_TYPE
26217 | ABSTRACT_TYPE_BASE
26218 | ABSTRACT_DECL_BASE
26219 | ABSTRACT_SCOPE_TYPE_DECL
26220 | ABSTRACT_SCOPE_DECL),
26221 decl_base(env, name, locus,
26222 // If the class is anonymous then by default it won't
26223 // have a linkage name. Also, the anonymous class does
26224 // have an internal-only unique name that is generally
26225 // not taken into account when comparing classes; such a
26226 // unique internal-only name, when used as a linkage
26227 // name might introduce spurious comparison false
26228 // negatives.
26229 /*linkage_name=*/ is_anonymous ? string() : name,
26230 vis),
26231 type_base(env, size_in_bits, align_in_bits),
26232 class_or_union(env, name, size_in_bits, align_in_bits,
26233 locus, vis),
26234 priv_(new priv(is_struct))
26235{
26237 set_is_anonymous(is_anonymous);
26238}
26239
26240/// A constuctor for instances of class_decl that represent a
26241/// declaration without definition.
26242///
26243/// @param env the environment we are operating from.
26244///
26245/// @param name the name of the class.
26246///
26247/// @param is_declaration_only a boolean saying whether the instance
26248/// represents a declaration only, or not.
26249class_decl::class_decl(const environment& env, const string& name,
26250 bool is_struct, bool is_declaration_only)
26251 : type_or_decl_base(env,
26252 CLASS_TYPE
26253 | ABSTRACT_TYPE_BASE
26254 | ABSTRACT_DECL_BASE
26255 | ABSTRACT_SCOPE_TYPE_DECL
26256 | ABSTRACT_SCOPE_DECL),
26257 decl_base(env, name, location(), name),
26258 type_base(env, 0, 0),
26259 class_or_union(env, name, is_declaration_only),
26260 priv_(new priv(is_struct))
26261{
26263}
26264
26265/// This method is invoked automatically right after the current
26266/// instance of @ref class_decl has been canonicalized.
26267///
26268/// Currently, the only thing it does is to sort the virtual member
26269/// functions vector.
26270void
26272{
26273 lock_guard<recursive_mutex> lock(get_mutex());
26275
26276 for (class_decl::virtual_mem_fn_map_type::iterator i =
26277 priv_->virtual_mem_fns_map_.begin();
26278 i != priv_->virtual_mem_fns_map_.end();
26279 ++i)
26280 sort_virtual_member_functions(i->second);
26281}
26282
26283/// Set the "is-struct" flag of the class.
26284///
26285/// @param f the new value of the flag.
26286void
26288{
26289 priv_->is_struct_ = f;
26290}
26291
26292/// Test if the class is a struct.
26293///
26294/// @return true iff the class is a struct.
26295bool
26297{return priv_->is_struct_;}
26298
26299/// Add a base specifier to this class.
26300///
26301/// @param b the new base specifier.
26302void
26304{
26305 lock_guard<recursive_mutex> lock(get_mutex());
26306 priv_->bases_.push_back(b);
26307 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
26308}
26309
26310/// Get the base specifiers for this class.
26311///
26312/// @return a vector of the base specifiers.
26315{return priv_->bases_;}
26316
26317/// Get a copy of the base specifiers for this class.
26318///
26319/// @return a vector of the base specifiers.
26322{
26323 base_specs result;
26324 {
26325 lock_guard<recursive_mutex> lock(get_mutex());
26326 result.reserve(priv_->bases_.size());
26327 for (auto b : priv_->bases_)
26328 result.push_back(b);
26329 }
26330 return result;
26331}
26332
26333/// Find a base class of a given qualified name for the current class.
26334///
26335/// @param qualified_name the qualified name of the base class to look for.
26336///
26337/// @return a pointer to the @ref class_decl that represents the base
26338/// class of name @p qualified_name, if found.
26340class_decl::find_base_class(const string& qualified_name) const
26341{
26342 lock_guard<recursive_mutex> lock(get_mutex());
26343 unordered_map<string, base_spec_sptr>::iterator i =
26344 priv_->bases_map_.find(qualified_name);
26345
26346 if (i != priv_->bases_map_.end())
26347 return i->second->get_base_class();
26348
26349 return class_decl_sptr();
26350}
26351
26352/// Get the virtual member functions of this class.
26353///
26354/// @param return a vector of the virtual member functions of this
26355/// class.
26358{return priv_->virtual_mem_fns_;}
26359
26360/// Get the map that associates a virtual table offset to the virtual
26361/// member functions with that virtual table offset.
26362///
26363/// Usually, there should be a 1:1 mapping between a given vtable
26364/// offset and virtual member functions of that vtable offset. But
26365/// because of some implementation details, there can be several C++
26366/// destructor functions that are *generated* by compilers, for a
26367/// given destructor that is defined in the source code. If the
26368/// destructor is virtual then those generated functions have some
26369/// DWARF attributes in common with the constructor that the user
26370/// actually defined in its source code. Among those attributes are
26371/// the vtable offset of the destructor.
26372///
26373/// @return the map that associates a virtual table offset to the
26374/// virtual member functions with that virtual table offset.
26377{return priv_->virtual_mem_fns_map_;}
26378
26379/// Sort the virtual member functions by their virtual index.
26380void
26382{
26383 lock_guard<recursive_mutex> lock(get_mutex());
26384 sort_virtual_member_functions(priv_->virtual_mem_fns_);
26385}
26386
26387/// Getter of the pretty representation of the current instance of
26388/// @ref class_decl.
26389///
26390/// @param internal set to true if the call is intended to get a
26391/// representation of the decl (or type) for the purpose of canonical
26392/// type comparison. This is mainly used in the function
26393/// homonym_type_group::get_canonical_type_for().
26394///
26395/// In other words if the argument for this parameter is true then the
26396/// call is meant for internal use (for technical use inside the
26397/// library itself), false otherwise. If you don't know what this is
26398/// for, then set it to false.
26399///
26400/// @param qualified_name if true, names emitted in the pretty
26401/// representation are fully qualified.
26402///
26403/// @return the pretty representaion for a class_decl.
26404string
26406 bool qualified_name) const
26407{
26408 string cl = "class ";
26409 if (!internal && is_struct())
26410 cl = "struct ";
26411
26412 // When computing the pretty representation for internal purposes,
26413 // if an anonymous class has the generic anonymous internal type
26414 // name that resembles "__anonymous_struct__", then return that one.
26415 // Otherwise, return the flat representation.
26416 if (get_is_anonymous())
26417 {
26418 if (internal && !get_name().empty())
26419 return cl + get_type_name(this, qualified_name, /*internal=*/true);
26420 string flat_repr = get_class_or_union_flat_representation(this, "",
26421 /*one_line=*/true,
26422 internal);
26423 if (qualified_name && !get_qualified_parent_name().empty())
26424 flat_repr = get_qualified_parent_name() + "::" + flat_repr;
26425
26426 return flat_repr;
26427 }
26428
26429 string result = cl;
26430 if (qualified_name)
26431 result += get_qualified_name(internal);
26432 else
26433 result += get_name();
26434
26435 return result;
26436}
26437
26438decl_base_sptr
26439insert_member_decl(class_decl_sptr klass, decl_base_sptr d)
26440{
26441 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
26442 add_member_function(klass, f, public_access,
26443 /*is_virtual=*/false,
26444 /*vtable_offset=*/0,
26445 /*is_static=*/false,
26446 /*is_ctor=*/false,
26447 /*is_dtor=*/false,
26448 /*is_const=*/false);
26449 else
26450 d = insert_member_decl(static_pointer_cast<class_or_union>(klass), d);
26451
26452 return d;
26453}
26454
26455/// The private data structure of class_decl::base_spec.
26456struct class_decl::base_spec::priv
26457{
26458 class_decl_wptr base_class_;
26459 long offset_in_bits_;
26460 bool is_virtual_;
26461
26462 priv(const class_decl_sptr& cl,
26463 long offset_in_bits,
26464 bool is_virtual)
26465 : base_class_(cl),
26466 offset_in_bits_(offset_in_bits),
26467 is_virtual_(is_virtual)
26468 {}
26469};
26470
26471/// Constructor for base_spec instances.
26472///
26473/// @param base the base class to consider
26474///
26475/// @param a the access specifier of the base class.
26476///
26477/// @param offset_in_bits if positive or null, represents the offset
26478/// of the base in the layout of its containing type.. If negative,
26479/// means that the current base is not laid out in its containing type.
26480///
26481/// @param is_virtual if true, means that the current base class is
26482/// virtual in it's containing type.
26483class_decl::base_spec::base_spec(const class_decl_sptr& base,
26485 long offset_in_bits,
26486 bool is_virtual)
26487 : type_or_decl_base(base->get_environment(),
26488 ABSTRACT_DECL_BASE),
26489 decl_base(base->get_environment(), base->get_name(), base->get_location(),
26490 base->get_linkage_name(), base->get_visibility()),
26491 member_base(a),
26492 priv_(new priv(base, offset_in_bits, is_virtual))
26493{
26495 set_qualified_name(base->get_qualified_name());
26496}
26497
26498/// Return the hash value of the current IR node.
26499///
26500/// Note that upon the first invocation, this member functions
26501/// computes the hash value and returns it. Subsequent invocations
26502/// just return the hash value that was previously calculated.
26503///
26504/// @return the hash value of the current IR node.
26505hash_t
26507{
26509 return h;
26510}
26511
26512/// Get the base class referred to by the current base class
26513/// specifier.
26514///
26515/// @return the base class.
26518{return priv_->base_class_.lock();}
26519
26520/// Getter of the "is-virtual" proprerty of the base class specifier.
26521///
26522/// @return true iff this specifies a virtual base class.
26523bool
26525{return priv_->is_virtual_;}
26526
26527/// Getter of the offset of the base.
26528///
26529/// @return the offset of the base.
26530long
26532{return priv_->offset_in_bits_;}
26533
26534/// Traverses an instance of @ref class_decl::base_spec, visiting all
26535/// the sub-types and decls that it might contain.
26536///
26537/// @param v the visitor that is used to visit every IR sub-node of
26538/// the current node.
26539///
26540/// @return true if either
26541/// - all the children nodes of the current IR node were traversed
26542/// and the calling code should keep going with the traversing.
26543/// - or the current IR node is already being traversed.
26544/// Otherwise, returning false means that the calling code should not
26545/// keep traversing the tree.
26546bool
26548{
26549 if (visiting())
26550 return true;
26551
26552 if (v.visit_begin(this))
26553 {
26554 visiting(true);
26555 get_base_class()->traverse(v);
26556 visiting(false);
26557 }
26558
26559 return v.visit_end(this);
26560}
26561
26562/// Constructor for base_spec instances.
26563///
26564/// Note that this constructor is for clients that don't support RTTI
26565/// and that have a base class of type_base, but of dynamic type
26566/// class_decl.
26567///
26568/// @param base the base class to consider. Must be a pointer to an
26569/// instance of class_decl
26570///
26571/// @param a the access specifier of the base class.
26572///
26573/// @param offset_in_bits if positive or null, represents the offset
26574/// of the base in the layout of its containing type.. If negative,
26575/// means that the current base is not laid out in its containing type.
26576///
26577/// @param is_virtual if true, means that the current base class is
26578/// virtual in it's containing type.
26579class_decl::base_spec::base_spec(const type_base_sptr& base,
26581 long offset_in_bits,
26582 bool is_virtual)
26584 ABSTRACT_DECL_BASE),
26589 member_base(a),
26590 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
26591 offset_in_bits,
26592 is_virtual))
26593{
26595}
26596
26597class_decl::base_spec::~base_spec() = default;
26598
26599/// Compares two instances of @ref class_decl::base_spec.
26600///
26601/// If the two intances are different, set a bitfield to give some
26602/// insight about the kind of differences there are.
26603///
26604/// @param l the first artifact of the comparison.
26605///
26606/// @param r the second artifact of the comparison.
26607///
26608/// @param k a pointer to a bitfield that gives information about the
26609/// kind of changes there are between @p l and @p r. This one is set
26610/// iff @p k is non-null and the function returns false.
26611///
26612/// Please note that setting k to a non-null value does have a
26613/// negative performance impact because even if @p l and @p r are not
26614/// equal, the function keeps up the comparison in order to determine
26615/// the different kinds of ways in which they are different.
26616///
26617/// @return true if @p l equals @p r, false otherwise.
26618bool
26620 const class_decl::base_spec& r,
26621 change_kind* k)
26622{
26623 if (!l.member_base::operator==(r))
26624 {
26625 if (k)
26627 ABG_RETURN_FALSE;
26628 }
26629
26630 ABG_RETURN((*l.get_base_class() == *r.get_base_class()));
26631}
26632
26633/// Comparison operator for @ref class_decl::base_spec.
26634///
26635/// @param other the instance of @ref class_decl::base_spec to compare
26636/// against.
26637///
26638/// @return true if the current instance of @ref class_decl::base_spec
26639/// equals @p other.
26640bool
26642{
26643 const class_decl::base_spec* o =
26644 dynamic_cast<const class_decl::base_spec*>(&other);
26645
26646 if (!o)
26647 return false;
26648
26649 return equals(*this, *o, 0);
26650}
26651
26652/// Comparison operator for @ref class_decl::base_spec.
26653///
26654/// @param other the instance of @ref class_decl::base_spec to compare
26655/// against.
26656///
26657/// @return true if the current instance of @ref class_decl::base_spec
26658/// equals @p other.
26659bool
26661{
26662 const class_decl::base_spec* o =
26663 dynamic_cast<const class_decl::base_spec*>(&other);
26664 if (!o)
26665 return false;
26666
26667 return operator==(static_cast<const decl_base&>(*o));
26668}
26669
26670/// A constructor for instances of method_decl.
26671///
26672/// @param name the name of the method.
26673///
26674/// @param type the type of the method.
26675///
26676/// @param declared_inline whether the method was
26677/// declared inline or not.
26678///
26679/// @param locus the source location of the method.
26680///
26681/// @param linkage_name the mangled name of the method.
26682///
26683/// @param vis the visibility of the method.
26684///
26685/// @param bind the binding of the method.
26686method_decl::method_decl(const string& name,
26687 method_type_sptr type,
26688 bool declared_inline,
26689 const location& locus,
26690 const string& linkage_name,
26691 visibility vis,
26692 binding bind)
26694 METHOD_DECL
26695 | ABSTRACT_DECL_BASE
26696 |FUNCTION_DECL),
26697 decl_base(type->get_environment(), name, locus, linkage_name, vis),
26698 scope_decl(type->get_environment(), "", locus),
26699 function_decl(name, static_pointer_cast<function_type>(type),
26700 declared_inline, locus, linkage_name, vis, bind)
26701{
26703 set_context_rel(new mem_fn_context_rel(0));
26704 set_member_function_is_const(*this, type->get_is_const());
26705}
26706
26707/// A constructor for instances of method_decl.
26708///
26709/// @param name the name of the method.
26710///
26711/// @param type the type of the method. Must be an instance of
26712/// method_type.
26713///
26714/// @param declared_inline whether the method was
26715/// declared inline or not.
26716///
26717/// @param locus the source location of the method.
26718///
26719/// @param linkage_name the mangled name of the method.
26720///
26721/// @param vis the visibility of the method.
26722///
26723/// @param bind the binding of the method.
26724method_decl::method_decl(const string& name,
26725 function_type_sptr type,
26726 bool declared_inline,
26727 const location& locus,
26728 const string& linkage_name,
26729 visibility vis,
26730 binding bind)
26731 : type_or_decl_base(type->get_environment(),
26732 METHOD_DECL
26733 | ABSTRACT_DECL_BASE
26734 | FUNCTION_DECL),
26735 decl_base(type->get_environment(), name, locus, linkage_name, vis),
26736 scope_decl(type->get_environment(), "", locus),
26737 function_decl(name, type, declared_inline, locus,
26738 linkage_name, vis, bind)
26739{
26741 set_context_rel(new mem_fn_context_rel(0));
26742}
26743
26744/// A constructor for instances of method_decl.
26745///
26746/// @param name the name of the method.
26747///
26748/// @param type the type of the method. Must be an instance of
26749/// method_type.
26750///
26751/// @param declared_inline whether the method was
26752/// declared inline or not.
26753///
26754/// @param locus the source location of the method.
26755///
26756/// @param linkage_name the mangled name of the method.
26757///
26758/// @param vis the visibility of the method.
26759///
26760/// @param bind the binding of the method.
26761method_decl::method_decl(const string& name,
26762 type_base_sptr type,
26763 bool declared_inline,
26764 const location& locus,
26765 const string& linkage_name,
26766 visibility vis,
26767 binding bind)
26768 : type_or_decl_base(type->get_environment(),
26769 METHOD_DECL
26770 | ABSTRACT_DECL_BASE
26771 | FUNCTION_DECL),
26772 decl_base(type->get_environment(), name, locus, linkage_name, vis),
26773 scope_decl(type->get_environment(), "", locus),
26774 function_decl(name, type, declared_inline, locus,
26775 linkage_name, vis, bind)
26776{
26778 set_context_rel(new mem_fn_context_rel(0));
26779}
26780
26781/// Set the linkage name of the method.
26782///
26783/// @param l the new linkage name of the method.
26784void
26786{
26787 string old_lname = get_linkage_name();
26789 class_or_union_sptr cl = is_class_or_union_type(get_scope());
26790 if (!cl)
26791 cl = is_class_or_union_type(t->get_class_type());
26792 ABG_ASSERT(cl);
26793
26795
26796 // Update the linkage_name -> member function map of the containing
26797 // class declaration.
26798 if (!get_scope())
26799 return;
26800
26801 lock_guard<recursive_mutex> lock(cl->priv_->member_functions_mutex_);
26802 if (!l.empty())
26803 {
26804 method_decl_sptr m(this, sptr_utils::noop_deleter());
26805 cl->priv_->mem_fns_map_[l] = m;
26806 }
26807
26808 if (!old_lname.empty() && l != old_lname)
26809 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
26810 cl->priv_->mem_fns_map_.erase(old_lname);
26811}
26812
26813method_decl::~method_decl()
26814{}
26815
26816const method_type_sptr
26818{
26819 method_type_sptr result;
26821 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
26822 return result;
26823}
26824
26825/// Set the containing class of a method_decl.
26826///
26827/// @param scope the new containing class_decl.
26828void
26829method_decl::set_scope(scope_decl_sptr scope)
26830{
26831 if (!get_context_rel())
26832 set_context_rel(new mem_fn_context_rel(scope));
26833 else
26834 get_context_rel()->set_scope(scope);
26835}
26836
26837/// Equality operator for @ref method_decl_sptr.
26838///
26839/// This is a deep equality operator, as it compares the @ref
26840/// method_decl that is pointed-to by the smart pointer.
26841///
26842/// @param l the left-hand side argument of the equality operator.
26843///
26844/// @param r the righ-hand side argument of the equality operator.
26845///
26846/// @return true iff @p l equals @p r.
26847bool
26848operator==(const method_decl_sptr& l, const method_decl_sptr& r)
26849{
26850 if (l.get() == r.get())
26851 return true;
26852 if (!!l != !!r)
26853 return false;
26854
26855 return *l == *r;
26856}
26857
26858/// Inequality operator for @ref method_decl_sptr.
26859///
26860/// This is a deep equality operator, as it compares the @ref
26861/// method_decl that is pointed-to by the smart pointer.
26862///
26863/// @param l the left-hand side argument of the equality operator.
26864///
26865/// @param r the righ-hand side argument of the equality operator.
26866///
26867/// @return true iff @p l differs from @p r.
26868bool
26869operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
26870{return !operator==(l, r);}
26871
26872/// Test if a function_decl is actually a method_decl.
26873///
26874///@param d the @ref function_decl to consider.
26875///
26876/// @return the method_decl sub-object of @p d if inherits
26877/// a method_decl type.
26880{
26881 return dynamic_cast<method_decl*>
26882 (const_cast<type_or_decl_base*>(d));
26883}
26884
26885/// Test if a function_decl is actually a method_decl.
26886///
26887///@param d the @ref function_decl to consider.
26888///
26889/// @return the method_decl sub-object of @p d if inherits
26890/// a method_decl type.
26894
26895/// Test if a function_decl is actually a method_decl.
26896///
26897///@param d the @ref function_decl to consider.
26898///
26899/// @return the method_decl sub-object of @p d if inherits
26900/// a method_decl type.
26901method_decl_sptr
26903{return dynamic_pointer_cast<method_decl>(d);}
26904
26905/// A "less than" functor to sort a vector of instances of
26906/// method_decl that are virtual.
26907struct virtual_member_function_less_than
26908{
26909 /// The less than operator. First, it sorts the methods by their
26910 /// vtable index. If they have the same vtable index, it sorts them
26911 /// by the name of their ELF symbol. If they don't have elf
26912 /// symbols, it sorts them by considering their pretty
26913 /// representation.
26914 ///
26915 /// Note that this method expects virtual methods.
26916 ///
26917 /// @param f the first method to consider.
26918 ///
26919 /// @param s the second method to consider.
26920 ///
26921 /// @return true if method @p is less than method @s.
26922 bool
26923 operator()(const method_decl& f,
26924 const method_decl& s)
26925 {
26928
26929 ssize_t f_offset = get_member_function_vtable_offset(f);
26930 ssize_t s_offset = get_member_function_vtable_offset(s);
26931 if (f_offset != s_offset) return f_offset < s_offset;
26932
26933 string fn, sn;
26934 // Try the linkage names (important for destructors).
26935 fn = f.get_linkage_name();
26936 sn = s.get_linkage_name();
26937 if (fn != sn) return fn < sn;
26938
26939 // If the functions have symbols, then compare their symbol-id
26940 // string.
26941 elf_symbol_sptr f_sym = f.get_symbol();
26942 elf_symbol_sptr s_sym = s.get_symbol();
26943 if ((!f_sym) != (!s_sym)) return !f_sym;
26944 if (f_sym && s_sym)
26945 {
26946 fn = f_sym->get_id_string();
26947 sn = s_sym->get_id_string();
26948 if (fn != sn) return fn < sn;
26949 }
26950
26951 // None of the functions have symbols or linkage names that
26952 // distinguish them, so compare their pretty representation.
26955 if (fn != sn) return fn < sn;
26956
26957 /// If it's just the file paths that are different then sort them
26958 /// too.
26959 string fn_filepath, sn_filepath;
26960 unsigned line = 0, column = 0;
26961 location fn_loc = f.get_location(), sn_loc = s.get_location();
26962 if (fn_loc)
26963 fn_loc.expand(fn_filepath, line, column);
26964 if (sn_loc)
26965 sn_loc.expand(sn_filepath, line, column);
26966 return fn_filepath < sn_filepath;
26967 }
26968
26969 /// The less than operator. First, it sorts the methods by their
26970 /// vtable index. If they have the same vtable index, it sorts them
26971 /// by the name of their ELF symbol. If they don't have elf
26972 /// symbols, it sorts them by considering their pretty
26973 /// representation.
26974 ///
26975 /// Note that this method expects to take virtual methods.
26976 ///
26977 /// @param f the first method to consider.
26978 ///
26979 /// @param s the second method to consider.
26980 bool
26981 operator()(const method_decl_sptr f,
26982 const method_decl_sptr s)
26983 {return operator()(*f, *s);}
26984}; // end struct virtual_member_function_less_than
26985
26986/// Sort a vector of instances of virtual member functions.
26987///
26988/// @param mem_fns the vector of member functions to sort.
26989static void
26990sort_virtual_member_functions(class_decl::member_functions& mem_fns)
26991{
26992 virtual_member_function_less_than lt;
26993 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
26994}
26995
26996/// Add a member function to the current instance of @ref class_or_union.
26997///
26998/// @param f a method_decl to add to the current class. This function
26999/// should not have been already added to a scope.
27000///
27001/// @param access the access specifier for the member function to add.
27002///
27003/// @param is_virtual if this is true then it means the function @p f
27004/// is a virtual function. That also means that the current instance
27005/// of @ref class_or_union is actually an instance of @ref class_decl.
27006///
27007/// @param vtable_offset the offset of the member function in the
27008/// virtual table. This parameter is taken into account only if @p
27009/// is_virtual is true.
27010///
27011/// @param is_static whether the member function is static.
27012///
27013/// @param is_ctor whether the member function is a constructor.
27014///
27015/// @param is_dtor whether the member function is a destructor.
27016///
27017/// @param is_const whether the member function is const.
27018void
27019add_member_function(class_or_union_sptr cou,
27020 method_decl_sptr f,
27022 bool is_virtual,
27023 size_t vtable_offset,
27024 bool is_static, bool is_ctor,
27025 bool is_dtor, bool is_const)
27026{
27027 add_member_function(cou, f, a, is_static, is_ctor,
27028 is_dtor, is_const);
27029
27030 if (class_decl_sptr klass = is_class_type(cou))
27031 {
27032 if (is_virtual)
27033 {
27034 set_member_function_virtuality(f, is_virtual, vtable_offset);
27035 lock_guard<recursive_mutex> lock(cou->get_mutex());
27036 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
27037 }
27038 }
27039}
27040
27041/// When a virtual member function has seen its virtualness set by
27042/// set_member_function_is_virtual(), this function ensures that the
27043/// member function is added to the specific vectors and maps of
27044/// virtual member function of its class.
27045///
27046/// @param method the method to fixup.
27047void
27048fixup_virtual_member_function(method_decl_sptr method)
27049{
27050 if (!method || !get_member_function_is_virtual(method))
27051 return;
27052
27053 class_decl_sptr klass = is_class_type(method->get_scope());
27054 ABG_ASSERT(klass);
27055
27056 class_decl::member_functions::const_iterator m;
27057 {
27058 lock_guard<recursive_mutex> lock(klass->get_mutex());
27059 for (m = klass->priv_->virtual_mem_fns_.begin();
27060 m != klass->priv_->virtual_mem_fns_.end();
27061 ++m)
27062 if (m->get() == method.get()
27063 || (*m)->get_linkage_name() == method->get_linkage_name())
27064 break;
27065 if (m == klass->priv_->virtual_mem_fns_.end())
27066 klass->priv_->virtual_mem_fns_.push_back(method);
27067 }
27068
27069 // Build or udpate the map that associates a vtable offset to the
27070 // number of virtual member functions that "point" to it.
27071 ssize_t voffset = get_member_function_vtable_offset(method);
27072 if (voffset == -1)
27073 return;
27074
27075 {
27076 lock_guard<recursive_mutex> lock(klass->get_mutex());
27077 class_decl::virtual_mem_fn_map_type::iterator i =
27078 klass->priv_->virtual_mem_fns_map_.find(voffset);
27079 if (i == klass->priv_->virtual_mem_fns_map_.end())
27080 {
27081 class_decl::member_functions virtual_mem_fns_at_voffset;
27082 virtual_mem_fns_at_voffset.push_back(method);
27083 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
27084 }
27085 else
27086 {
27087 for (m = i->second.begin() ; m != i->second.end(); ++m)
27088 if (m->get() == method.get()
27089 || (*m)->get_linkage_name() == method->get_linkage_name())
27090 break;
27091 if (m == i->second.end())
27092 i->second.push_back(method);
27093 }
27094 }
27095}
27096
27097/// Return true iff the class has no entity in its scope.
27098bool
27100{return priv_->bases_.empty() && has_no_member();}
27101
27102/// Test if the current instance of @ref class_decl has virtual member
27103/// functions.
27104///
27105/// @return true iff the current instance of @ref class_decl has
27106/// virtual member functions.
27107bool
27110
27111/// Test if the current instance of @ref class_decl has at least one
27112/// virtual base.
27113///
27114/// @return true iff the current instance of @ref class_decl has a
27115/// virtual member function.
27116bool
27118{
27119 for (base_specs::const_iterator b = get_base_specifiers().begin();
27120 b != get_base_specifiers().end();
27121 ++b)
27122 if ((*b)->get_is_virtual()
27123 || (*b)->get_base_class()->has_virtual_bases())
27124 return true;
27125
27126 return false;
27127}
27128
27129/// Test if the current instance has a vtable.
27130///
27131/// This is only valid for a C++ program.
27132///
27133/// Basically this function checks if the class has either virtual
27134/// functions, or virtual bases.
27135bool
27137{
27139 || has_virtual_bases())
27140 return true;
27141 return false;
27142}
27143
27144/// Get the highest vtable offset of all the virtual methods of the
27145/// class.
27146///
27147/// @return the highest vtable offset of all the virtual methods of
27148/// the class.
27149ssize_t
27151{
27152 lock_guard<recursive_mutex> lock(get_mutex());
27153 ssize_t offset = -1;
27154 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
27155 get_virtual_mem_fns_map().begin();
27156 e != get_virtual_mem_fns_map().end();
27157 ++e)
27158 if (e->first > offset)
27159 offset = e->first;
27160
27161 return offset;
27162}
27163
27164/// Return the hash value of the current IR node.
27165///
27166/// Note that upon the first invocation, this member functions
27167/// computes the hash value and returns it. Subsequent invocations
27168/// just return the hash value that was previously calculated.
27169///
27170/// @return the hash value of the current IR node.
27171hash_t
27173{
27175 return h;
27176}
27177
27178/// Test if two methods are equal without taking their symbol or
27179/// linkage name into account.
27180///
27181/// @param f the first method.
27182///
27183/// @param s the second method.
27184///
27185/// @return true iff @p f equals @p s without taking their linkage
27186/// name or symbol into account.
27187static bool
27188methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
27189 const method_decl_sptr& s)
27190{
27191 bool equal = equals(*f, *s, nullptr,
27192 /*linkage_name=*/false,
27193 /*elf_symbol=*/false);
27194 return equal;
27195}
27196
27197/// Test if a given method is equivalent to at least of other method
27198/// that is in a vector of methods.
27199///
27200/// Note that "equivalent" here means being equal without taking the
27201/// linkage name or the symbol of the methods into account.
27202///
27203/// This is a sub-routine of the 'equals' function that compares @ref
27204/// class_decl.
27205///
27206/// @param method the method to compare.
27207///
27208/// @param fns the vector of functions to compare @p method against.
27209///
27210/// @return true iff @p is equivalent to at least one method in @p
27211/// fns.
27212static bool
27213method_matches_at_least_one_in_vector(const method_decl_sptr& method,
27215{
27216 for (class_decl::member_functions::const_iterator i = fns.begin();
27217 i != fns.end();
27218 ++i)
27219 // Note that the comparison must be done in this order: method ==
27220 // *i This is to keep the consistency of the comparison. It's
27221 // important especially when doing type canonicalization. The
27222 // already canonicalize type is the left operand, and the type
27223 // being canonicalized is the right operand. This comes from the
27224 // code in homonym_type_group::get_canonical_type_for().
27225 if (methods_equal_modulo_elf_symbol(method, *i))
27226 return true;
27227
27228 return false;
27229}
27230
27231/// Test if the set of virtual methods of a left-hand class (in a
27232/// comparison) equals the virtual methods of the right-hand class,
27233/// modulo the virtual destructors. That is, if the left-hand class
27234/// has destructors that the right-hand class does not, and if
27235/// otherwise, all other virtual methods of the right-hand class equal
27236/// those of the left-hand class, then the function returns true.
27237///
27238/// If there is any other change in the virtual methods of the
27239/// left-hand class compared to the right-hand one, then the function
27240/// returns false.
27241///
27242/// @param l the left-hand class.
27243///
27244/// @param r the right-hand class.
27245///
27246/// @param k output parameter. If this pointer is non-null, then its
27247/// pointed-to value is set to the kind of change detected by the
27248/// function iff it returns false.
27249///
27250/// @return true iff virtual methods of @p f equal the virtual methods
27251/// of @p r, modulo the virtual destructors.
27252static bool
27253l_class_virt_methods_equal_r_modulo_dtors(const class_decl& l,
27254 const class_decl& r,
27255 change_kind* k)
27256{
27257 const class_decl::virtual_mem_fn_map_type& l_virt_map = l.get_virtual_mem_fns_map();
27258 const class_decl::virtual_mem_fn_map_type& r_virt_map = r.get_virtual_mem_fns_map();
27259
27260 for (auto& l_virt_entry : l_virt_map)
27261 {
27262 bool is_dtor = get_member_function_is_dtor(l_virt_entry.second.front());
27263 unsigned l_virt_mem_fn_offset = l_virt_entry.first;
27264 auto r_vfns_it = r_virt_map.find(l_virt_mem_fn_offset);
27265 auto& r_vfns = r_vfns_it->second;
27266
27267 if (r_vfns_it == r_virt_map.end())
27268 {
27269 if (!is_dtor)
27270 {
27271 if (k)
27273 return false;
27274 }
27275 }
27276 else
27277 for (auto method : l_virt_entry.second)
27278 if (!method_matches_at_least_one_in_vector(method, r_vfns))
27279 if (!is_dtor)
27280 {
27281 if (k)
27282 *k |= SUBTYPE_CHANGE_KIND;
27283 return false;
27284 }
27285 }
27286 return true;
27287}
27288
27289/// Test if the set of virtual methods of a left-hand class (in a
27290/// comparison) equals the virtual methods of the right-hand class,
27291/// modulo the virtual destructors. That is, if one of the classes
27292/// has virtual destructors that are not present on the other class,
27293/// and if otherwise, all other virtual methods of both classes are
27294/// equal, then the function returns true.
27295///
27296/// If there is any other change in the virtual methods, then the function
27297/// returns false.
27298///
27299/// @param l the left-hand class.
27300///
27301/// @param r the right-hand class.
27302///
27303/// @param k output parameter. If this pointer is non-null, then its
27304/// pointed-to value is set to the kind of change detected by the
27305/// function iff it returns false.
27306///
27307/// @return true iff virtual methods of @p f equal the virtual methods
27308/// of @p r, modulo the virtual destructors.
27309static bool
27310classes_virt_methods_are_equal_modulo_destructors(const class_decl& l,
27311 const class_decl& r,
27312 change_kind* k)
27313{
27314 if (l_class_virt_methods_equal_r_modulo_dtors(l, r, k)
27315 && l_class_virt_methods_equal_r_modulo_dtors(r, l, k))
27316 return true;
27317 return false;
27318}
27319
27320/// Compares two instances of @ref class_decl.
27321///
27322/// If the two intances are different, set a bitfield to give some
27323/// insight about the kind of differences there are.
27324///
27325/// @param l the first artifact of the comparison.
27326///
27327/// @param r the second artifact of the comparison.
27328///
27329/// @param k a pointer to a bitfield that gives information about the
27330/// kind of changes there are between @p l and @p r. This one is set
27331/// iff @p k is non-null and the function returns false.
27332///
27333/// Please note that setting k to a non-null value does have a
27334/// negative performance impact because even if @p l and @p r are not
27335/// equal, the function keeps up the comparison in order to determine
27336/// the different kinds of ways in which they are different.
27337///
27338/// @return true if @p l equals @p r, false otherwise.
27339bool
27341{
27342 {
27343 // First of all, let's see if these two types haven't already been
27344 // compared. If so, and if the result of the comparison has been
27345 // cached, let's just re-use it, rather than comparing them all
27346 // over again.
27347 bool result = false;
27348 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
27349 ABG_RETURN(result);
27350 }
27351
27352 // if one of the classes is declaration-only then we take a fast
27353 // path here.
27355 && l.get_virtual_mem_fns_map().empty())
27357 && r.get_virtual_mem_fns_map().empty()))
27358 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
27359 static_cast<const class_or_union&>(r),
27360 k));
27361
27362 bool result = true;
27363 if (!equals(static_cast<const class_or_union&>(l),
27364 static_cast<const class_or_union&>(r),
27365 k))
27366 {
27367 result = false;
27368 if (!k)
27369 ABG_RETURN(result);
27370 }
27371
27373
27375
27376#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
27377
27378 // Compare bases.
27379 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
27380 {
27381 result = false;
27382 if (k)
27384 else
27385 RETURN(result);
27386 }
27387
27388 for (class_decl::base_specs::const_iterator
27389 b0 = l.get_base_specifiers().begin(),
27390 b1 = r.get_base_specifiers().begin();
27391 (b0 != l.get_base_specifiers().end()
27392 && b1 != r.get_base_specifiers().end());
27393 ++b0, ++b1)
27394 if (*b0 != *b1)
27395 {
27396 result = false;
27397 if (k)
27398 {
27399 if (!types_have_similar_structure((*b0)->get_base_class().get(),
27400 (*b1)->get_base_class().get()))
27402 else
27403 *k |= SUBTYPE_CHANGE_KIND;
27404 break;
27405 }
27406 RETURN(result);
27407 }
27408
27409 // Compare virtual member functions
27410
27411 // We look at the map that associates a given vtable offset to a
27412 // vector of virtual member functions that point to that offset.
27413 //
27414 // This is because there are cases where several functions can
27415 // point to the same virtual table offset.
27416 //
27417 // This is usually the case for virtual destructors. Even though
27418 // there can be only one virtual destructor declared in source
27419 // code, there are actually potentially up to three generated
27420 // functions for that destructor. Some of these generated
27421 // functions can be clones of other functions that are among those
27422 // generated ones. In any cases, they all have the same
27423 // properties, including the vtable offset property.
27424
27425 // In some cases (coming from DWARF), two classes can be the same
27426 // modulo their /virtual/ destructors; that means, one class has all
27427 // its virtual destructors and the other one doesn't. This can be
27428 // due to some DWARF-isms. We recognize that here and say that the
27429 // two classes are the same. Their virtual destructors are going to
27430 // be merged later at type canonicalization time in
27431 // maybe_adjust_canonical_type.
27432 if (!classes_virt_methods_are_equal_modulo_destructors(l, r, k))
27433 result = false;
27434
27435 RETURN(result);
27436
27437#undef RETURN
27438}
27439
27440/// Copy a method of a class into a new class.
27441///
27442/// @param klass the class into which the method is to be copied.
27443///
27444/// @param method the method to copy into @p klass.
27445///
27446/// @return the resulting newly copied method.
27447method_decl_sptr
27448copy_member_function(class_decl_sptr clazz, const method_decl_sptr& f)
27449{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
27450
27451/// Copy a method of a class into a new class.
27452///
27453/// @param klass the class into which the method is to be copied.
27454///
27455/// @param method the method to copy into @p klass.
27456///
27457/// @return the resulting newly copied method.
27458method_decl_sptr
27460{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
27461
27462/// Comparison operator for @ref class_decl.
27463///
27464/// @param other the instance of @ref class_decl to compare against.
27465///
27466/// @return true iff the current instance of @ref class_decl equals @p
27467/// other.
27468bool
27470{
27471 const class_decl* op = is_class_type(&other);
27472 if (!op)
27473 {
27474 if (class_or_union* cou = is_class_or_union_type(&other))
27475 return class_or_union::operator==(*cou);
27476 return false;
27477 }
27478
27479 // If this is a decl-only type (and thus with no canonical type),
27480 // use the canonical type of the definition, if any.
27481 const class_decl *l = 0;
27483 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
27484 if (l == 0)
27485 l = this;
27486
27487 ABG_ASSERT(l);
27488
27489 // Likewise for the other type.
27490 const class_decl *r = 0;
27491 if (op->get_is_declaration_only())
27492 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
27493 if (r == 0)
27494 r = op;
27495
27496 ABG_ASSERT(r);
27497
27498 return try_canonical_compare(l, r);
27499}
27500
27501/// Equality operator for class_decl.
27502///
27503/// Re-uses the equality operator that takes a decl_base.
27504///
27505/// @param other the other class_decl to compare against.
27506///
27507/// @return true iff the current instance equals the other one.
27508bool
27510{
27511 const decl_base* o = is_decl(&other);
27512 if (!o)
27513 return false;
27514 return *this == *o;
27515}
27516
27517/// Equality operator for class_decl.
27518///
27519/// Re-uses the equality operator that takes a decl_base.
27520///
27521/// @param other the other class_decl to compare against.
27522///
27523/// @return true iff the current instance equals the other one.
27524bool
27526{
27527 const decl_base& o = other;
27528 return *this == o;
27529}
27530
27531/// Comparison operator for @ref class_decl.
27532///
27533/// @param other the instance of @ref class_decl to compare against.
27534///
27535/// @return true iff the current instance of @ref class_decl equals @p
27536/// other.
27537bool
27539{
27540 const decl_base& o = other;
27541 return *this == o;
27542}
27543
27544/// Turn equality of shared_ptr of class_decl into a deep equality;
27545/// that is, make it compare the pointed to objects too.
27546///
27547/// @param l the shared_ptr of class_decl on left-hand-side of the
27548/// equality.
27549///
27550/// @param r the shared_ptr of class_decl on right-hand-side of the
27551/// equality.
27552///
27553/// @return true if the class_decl pointed to by the shared_ptrs are
27554/// equal, false otherwise.
27555bool
27557{
27558 if (l.get() == r.get())
27559 return true;
27560 if (!!l != !!r)
27561 return false;
27562
27563 return *l == *r;
27564}
27565
27566/// Turn inequality of shared_ptr of class_decl into a deep equality;
27567/// that is, make it compare the pointed to objects too.
27568///
27569/// @param l the shared_ptr of class_decl on left-hand-side of the
27570/// equality.
27571///
27572/// @param r the shared_ptr of class_decl on right-hand-side of the
27573/// equality.
27574///
27575/// @return true if the class_decl pointed to by the shared_ptrs are
27576/// different, false otherwise.
27577bool
27579{return !operator==(l, r);}
27580
27581/// Turn equality of shared_ptr of class_or_union into a deep
27582/// equality; that is, make it compare the pointed to objects too.
27583///
27584/// @param l the left-hand-side operand of the operator
27585///
27586/// @param r the right-hand-side operand of the operator.
27587///
27588/// @return true iff @p l equals @p r.
27589bool
27590operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
27591{
27592 if (l.get() == r.get())
27593 return true;
27594 if (!!l != !!r)
27595 return false;
27596
27597 return *l == *r;
27598}
27599
27600/// Turn inequality of shared_ptr of class_or_union into a deep
27601/// equality; that is, make it compare the pointed to objects too.
27602///
27603/// @param l the left-hand-side operand of the operator
27604///
27605/// @param r the right-hand-side operand of the operator.
27606///
27607/// @return true iff @p l is different from @p r.
27608bool
27609operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
27610{return !operator==(l, r);}
27611
27612/// This implements the ir_traversable_base::traverse pure virtual
27613/// function.
27614///
27615/// @param v the visitor used on the current instance and on its
27616/// members.
27617///
27618/// @return true if the entire IR node tree got traversed, false
27619/// otherwise.
27620bool
27622{
27623 if (v.type_node_has_been_visited(this))
27624 return true;
27625
27626 if (visiting())
27627 return true;
27628
27629 if (v.visit_begin(this))
27630 {
27631 visiting(true);
27632 bool stop = false;
27633
27634 for (auto naming_typedef : get_naming_typedefs())
27635 naming_typedef->traverse(v);
27636
27637 for (const auto& base : get_base_specifiers_copy())
27638 {
27639 if (!base->traverse(v))
27640 {
27641 stop = true;
27642 break;
27643 }
27644 }
27645
27646 if (!stop)
27647 {
27648 for (auto var_sptr : get_data_members_copy())
27649 {
27650 if (!var_sptr->traverse(v))
27651 {
27652 stop = true;
27653 break;
27654 }
27655 }
27656 }
27657
27658 if (!stop)
27659 {
27660 for (const auto& fn : get_member_functions_copy())
27661 {
27662 if (!fn->traverse(v))
27663 {
27664 stop = true;
27665 break;
27666 }
27667 }
27668 }
27669
27670 if (!stop)
27671 {
27673 for (auto t : get_sorted_member_types_copy())
27674 if (!t->traverse(v))
27675 {
27676 stop = true;
27677 break;
27678 }
27679 }
27680
27681 if (!stop)
27682 for (member_function_templates::const_iterator i =
27684 i != get_member_function_templates().end();
27685 ++i)
27686 if (!(*i)->traverse(v))
27687 {
27688 stop = true;
27689 break;
27690 }
27691
27692 if (!stop)
27693 for (member_class_templates::const_iterator i =
27695 i != get_member_class_templates().end();
27696 ++i)
27697 if (!(*i)->traverse(v))
27698 {
27699 stop = true;
27700 break;
27701 }
27702 visiting(false);
27703 }
27704
27705 bool result = v.visit_end(this);
27707 return result;
27708}
27709
27710/// Destructor of the @ref class_decl type.
27712{delete priv_;}
27713
27714// <class context_rel> stuff
27715
27716struct context_rel::priv
27717{
27718 recursive_mutex mutex_;
27719 scope_decl_wptr scope_;
27720 enum access_specifier access_ = no_access;
27721 bool is_static_ = false;
27722};// end struct context_rel::priv
27723
27724context_rel::context_rel()
27725 : priv_(new priv)
27726{}
27727
27728context_rel::context_rel(scope_decl_sptr s)
27729 : priv_(new priv)
27730{
27731 priv_->scope_ = s;
27732}
27733
27734context_rel::context_rel(scope_decl_sptr s,
27736 bool f)
27737 : priv_(new priv)
27738{
27739 priv_->scope_ = s;
27740 priv_->access_ = a;
27741 priv_->is_static_ = f;
27742}
27743
27745context_rel::get_scope() const
27746{
27747 lock_guard<recursive_mutex> lock(priv_->mutex_);
27748 return priv_->scope_.lock();
27749}
27750
27752context_rel::get_access_specifier() const
27753{
27754 lock_guard<recursive_mutex> lock(priv_->mutex_);
27755 return priv_->access_;
27756}
27757
27758void
27759context_rel::set_access_specifier(access_specifier a)
27760{
27761 lock_guard<recursive_mutex> lock(priv_->mutex_);
27762 priv_->access_ = a;
27763}
27764
27765bool
27766context_rel::get_is_static() const
27767{
27768 lock_guard<recursive_mutex> lock(priv_->mutex_);
27769 return priv_->is_static_;
27770}
27771
27772void
27773context_rel::set_is_static(bool s)
27774{
27775 lock_guard<recursive_mutex> lock(priv_->mutex_);
27776 priv_->is_static_ = s;
27777}
27778
27779void
27780context_rel::set_scope(scope_decl_sptr s)
27781{
27782 lock_guard<recursive_mutex> lock(priv_->mutex_);
27783 priv_->scope_ = s;
27784}
27785
27786bool
27787context_rel::operator==(const context_rel& o)const
27788{
27789 lock_guard<recursive_mutex> lock(priv_->mutex_);
27790 return (priv_->is_static_ == o.priv_->is_static_);
27791}
27792
27793/// Inequality operator.
27794///
27795/// @param o the other instance of @ref context_rel to compare the
27796/// current instance against.
27797///
27798/// @return true iff the current instance of @ref context_rel is
27799/// different from @p o.
27800bool
27802{
27803 return !operator==(o);
27804}
27805
27806context_rel::~context_rel()
27807{}
27808
27809// </class context_rel>
27810
27811bool
27812member_base::operator==(const member_base& o) const
27813{
27815 && get_is_static() == o.get_is_static());
27816}
27817
27818/// Equality operator for smart pointers to @ref
27819/// class_decl::base_specs.
27820///
27821/// This compares the pointed-to objects.
27822///
27823/// @param l the first instance to consider.
27824///
27825/// @param r the second instance to consider.
27826///
27827/// @return true iff @p l equals @p r.
27828bool
27831{
27832 if (l.get() == r.get())
27833 return true;
27834 if (!!l != !!r)
27835 return false;
27836
27837 return *l == static_cast<const decl_base&>(*r);
27838}
27839
27840/// Inequality operator for smart pointers to @ref
27841/// class_decl::base_specs.
27842///
27843/// This compares the pointed-to objects.
27844///
27845/// @param l the first instance to consider.
27846///
27847/// @param r the second instance to consider.
27848///
27849/// @return true iff @p l is different from @p r.
27850bool
27853{return !operator==(l, r);}
27854
27855/// Test if an ABI artifact is a class base specifier.
27856///
27857/// @param tod the ABI artifact to consider.
27858///
27859/// @return a pointer to the @ref class_decl::base_spec sub-object of
27860/// @p tod iff it's a class base specifier.
27863{
27864 return dynamic_cast<class_decl::base_spec*>
27865 (const_cast<type_or_decl_base*>(tod));
27866}
27867
27868/// Test if an ABI artifact is a class base specifier.
27869///
27870/// @param tod the ABI artifact to consider.
27871///
27872/// @return a pointer to the @ref class_decl::base_spec sub-object of
27873/// @p tod iff it's a class base specifier.
27876{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
27877
27878bool
27879member_function_template::operator==(const member_base& other) const
27880{
27881 try
27882 {
27883 const member_function_template& o =
27884 dynamic_cast<const member_function_template&>(other);
27885
27886 if (!(is_constructor() == o.is_constructor()
27887 && is_const() == o.is_const()
27888 && member_base::operator==(o)))
27889 return false;
27890
27891 if (function_tdecl_sptr ftdecl = as_function_tdecl())
27892 {
27893 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
27894 if (other_ftdecl)
27895 return ftdecl->function_tdecl::operator==(*other_ftdecl);
27896 }
27897 }
27898 catch(...)
27899 {}
27900 return false;
27901}
27902
27903/// Equality operator for smart pointers to @ref
27904/// member_function_template. This is compares the
27905/// pointed-to instances.
27906///
27907/// @param l the first instance to consider.
27908///
27909/// @param r the second instance to consider.
27910///
27911/// @return true iff @p l equals @p r.
27912bool
27913operator==(const member_function_template_sptr& l,
27914 const member_function_template_sptr& r)
27915{
27916 if (l.get() == r.get())
27917 return true;
27918 if (!!l != !!r)
27919 return false;
27920
27921 return *l == *r;
27922}
27923
27924/// Inequality operator for smart pointers to @ref
27925/// member_function_template. This is compares the pointed-to
27926/// instances.
27927///
27928/// @param l the first instance to consider.
27929///
27930/// @param r the second instance to consider.
27931///
27932/// @return true iff @p l equals @p r.
27933bool
27934operator!=(const member_function_template_sptr& l,
27935 const member_function_template_sptr& r)
27936{return !operator==(l, r);}
27937
27938/// This implements the ir_traversable_base::traverse pure virtual
27939/// function.
27940///
27941/// @param v the visitor used on the current instance and on its
27942/// underlying function template.
27943///
27944/// @return true if the entire IR node tree got traversed, false
27945/// otherwise.
27946bool
27948{
27949 if (visiting())
27950 return true;
27951
27952 if (v.visit_begin(this))
27953 {
27954 visiting(true);
27955 if (function_tdecl_sptr f = as_function_tdecl())
27956 f->traverse(v);
27957 visiting(false);
27958 }
27959 return v.visit_end(this);
27960}
27961
27962/// Equality operator of the the @ref member_class_template class.
27963///
27964/// @param other the other @ref member_class_template to compare against.
27965///
27966/// @return true iff the current instance equals @p other.
27967bool
27969{
27970 try
27971 {
27972 const member_class_template& o =
27973 dynamic_cast<const member_class_template&>(other);
27974
27975 if (!member_base::operator==(o))
27976 return false;
27977
27978 return as_class_tdecl()->class_tdecl::operator==(o);
27979 }
27980 catch(...)
27981 {return false;}
27982}
27983
27984/// Equality operator of the the @ref member_class_template class.
27985///
27986/// @param other the other @ref member_class_template to compare against.
27987///
27988/// @return true iff the current instance equals @p other.
27989bool
27991{
27992 if (!decl_base::operator==(other))
27993 return false;
27994 return as_class_tdecl()->class_tdecl::operator==(other);
27995}
27996
27997/// Comparison operator for the @ref member_class_template
27998/// type.
27999///
28000/// @param other the other instance of @ref
28001/// member_class_template to compare against.
28002///
28003/// @return true iff the two instances are equal.
28004bool
28006{
28007 const decl_base* o = dynamic_cast<const decl_base*>(&other);
28008 return *this == *o;
28009}
28010
28011/// Comparison operator for the @ref member_class_template
28012/// type.
28013///
28014/// @param l the first argument of the operator.
28015///
28016/// @param r the second argument of the operator.
28017///
28018/// @return true iff the two instances are equal.
28019bool
28020operator==(const member_class_template_sptr& l,
28021 const member_class_template_sptr& r)
28022{
28023 if (l.get() == r.get())
28024 return true;
28025 if (!!l != !!r)
28026 return false;
28027
28028 return *l == *r;
28029}
28030
28031/// Inequality operator for the @ref member_class_template
28032/// type.
28033///
28034/// @param l the first argument of the operator.
28035///
28036/// @param r the second argument of the operator.
28037///
28038/// @return true iff the two instances are equal.
28039bool
28040operator!=(const member_class_template_sptr& l,
28041 const member_class_template_sptr& r)
28042{return !operator==(l, r);}
28043
28044/// This implements the ir_traversable_base::traverse pure virtual
28045/// function.
28046///
28047/// @param v the visitor used on the current instance and on the class
28048/// pattern of the template.
28049///
28050/// @return true if the entire IR node tree got traversed, false
28051/// otherwise.
28052bool
28054{
28055 if (visiting())
28056 return true;
28057
28058 if (v.visit_begin(this))
28059 {
28060 visiting(true);
28061 if (class_tdecl_sptr t = as_class_tdecl())
28062 t->traverse(v);
28063 visiting(false);
28064 }
28065 return v.visit_end(this);
28066}
28067
28068/// Streaming operator for class_decl::access_specifier.
28069///
28070/// @param o the output stream to serialize the access specifier to.
28071///
28072/// @param a the access specifier to serialize.
28073///
28074/// @return the output stream.
28075std::ostream&
28076operator<<(std::ostream& o, access_specifier a)
28077{
28078 string r;
28079
28080 switch (a)
28081 {
28082 case no_access:
28083 r = "none";
28084 break;
28085 case private_access:
28086 r = "private";
28087 break;
28088 case protected_access:
28089 r = "protected";
28090 break;
28091 case public_access:
28092 r= "public";
28093 break;
28094 };
28095 o << r;
28096 return o;
28097}
28098
28099/// Sets the static-ness property of a class member.
28100///
28101/// @param d the class member to set the static-ness property for.
28102/// Note that this must be a class member otherwise the function
28103/// aborts the current process.
28104///
28105/// @param s this must be true if the member is to be static, false
28106/// otherwise.
28107void
28109{
28111
28113 ABG_ASSERT(c);
28114
28115 c->set_is_static(s);
28116
28117 scope_decl_sptr scope = d.get_scope();
28118
28119 if (class_or_union_sptr cl = is_class_or_union_type(scope))
28120 {
28121 if (var_decl* v = is_var_decl(&d))
28122 {
28123 var_decl_sptr var;
28124 {
28125 lock_guard<recursive_mutex> lock(cl->get_mutex());
28126 // First, find v in the set of data members.
28127 for (const auto& dm : cl->get_data_members())
28128 if (dm->get_name() == v->get_name())
28129 {
28130 var = dm;
28131 break;
28132 }
28133 if (!var)
28134 return;
28135 }
28136
28137 if (s)
28138 {
28139 {
28140 lock_guard<recursive_mutex> lock(cl->get_mutex());
28141 // remove from the non-static data members
28142 for (class_decl::data_members::iterator i =
28143 cl->priv_->non_static_data_members_.begin();
28144 i != cl->priv_->non_static_data_members_.end();
28145 ++i)
28146 {
28147 if ((*i)->get_name() == v->get_name())
28148 {
28149 cl->priv_->non_static_data_members_.erase(i);
28150 break;
28151 }
28152 }
28153 }
28154
28155 {
28156 // If it's not in the static data members, then add it
28157 // there.
28158 lock_guard<recursive_mutex> lock(cl->get_mutex());
28159 bool already_in_static_dms = false;
28160 for (const auto& s_dm : cl->priv_->static_data_members_)
28161 if (s_dm->get_name() == v->get_name())
28162 {
28163 already_in_static_dms = true;
28164 break;
28165 }
28166 if (!already_in_static_dms)
28167 cl->priv_->static_data_members_.push_back(var);
28168 }
28169 }
28170 else // is non-static
28171 {
28172 {
28173 lock_guard<recursive_mutex> lock(cl->get_mutex());
28174 // Remove from the static data members.
28175 for (class_or_union::data_members::iterator i =
28176 cl->priv_->static_data_members_.begin();
28177 i != cl->priv_->static_data_members_.end();
28178 ++i)
28179 if ((*i)->get_name() == v->get_name())
28180 {
28181 cl->priv_->static_data_members_.erase(i);
28182 break;
28183 }
28184 }
28185
28186 // If it's not already in the non-static data members
28187 // then add it there.
28188 bool is_already_in_non_static_data_members = false;
28189 {
28190 lock_guard<recursive_mutex> lock(cl->get_mutex());
28191 for (const auto& ns_dm : cl->priv_->non_static_data_members_)
28192 if (ns_dm->get_name() == v->get_name())
28193 {
28194 is_already_in_non_static_data_members = true;
28195 break;
28196 }
28197 if (!is_already_in_non_static_data_members)
28198 cl->priv_->non_static_data_members_.push_back(var);
28199 }
28200 }
28201 }
28202 else if (method_decl* method = is_method_decl(&d))
28203 {
28204 method_type_sptr method_type = method->get_type();
28207 }
28208 }
28209}
28210
28211/// Sets the static-ness property of a class member.
28212///
28213/// @param d the class member to set the static-ness property for.
28214/// Note that this must be a class member otherwise the function
28215/// aborts the current process.
28216///
28217/// @param s this must be true if the member is to be static, false
28218/// otherwise.
28219void
28220set_member_is_static(const decl_base_sptr& d, bool s)
28221{set_member_is_static(*d, s);}
28222
28223// </class_decl>
28224
28225// <union_decl>
28226
28227/// Constructor for the @ref union_decl type.
28228///
28229/// @param env the @ref environment we are operating from.
28230///
28231/// @param name the name of the union type.
28232///
28233/// @param size_in_bits the size of the union, in bits.
28234///
28235/// @param locus the location of the type.
28236///
28237/// @param vis the visibility of instances of @ref union_decl.
28238union_decl::union_decl(const environment& env, const string& name,
28239 size_t size_in_bits, const location& locus,
28240 visibility vis)
28241 : type_or_decl_base(env,
28242 UNION_TYPE
28243 | ABSTRACT_TYPE_BASE
28244 | ABSTRACT_DECL_BASE
28245 | ABSTRACT_SCOPE_TYPE_DECL
28246 | ABSTRACT_SCOPE_DECL),
28247 decl_base(env, name, locus, name, vis),
28248 type_base(env, size_in_bits, 0),
28249 class_or_union(env, name, size_in_bits,
28250 0, locus, vis)
28251{
28253}
28254
28255/// Constructor for the @ref union_decl type.
28256///
28257/// @param env the @ref environment we are operating from.
28258///
28259/// @param name the name of the union type.
28260///
28261/// @param size_in_bits the size of the union, in bits.
28262///
28263/// @param locus the location of the type.
28264///
28265/// @param vis the visibility of instances of @ref union_decl.
28266///
28267/// @param is_anonymous whether the newly created instance is
28268/// anonymous.
28269union_decl::union_decl(const environment& env, const string& name,
28270 size_t size_in_bits, const location& locus,
28271 visibility vis, bool is_anonymous)
28272 : type_or_decl_base(env,
28273 UNION_TYPE
28274 | ABSTRACT_TYPE_BASE
28275 | ABSTRACT_DECL_BASE
28276 | ABSTRACT_SCOPE_TYPE_DECL
28277 | ABSTRACT_SCOPE_DECL),
28278 decl_base(env, name, locus,
28279 // If the class is anonymous then by default it won't
28280 // have a linkage name. Also, the anonymous class does
28281 // have an internal-only unique name that is generally
28282 // not taken into account when comparing classes; such a
28283 // unique internal-only name, when used as a linkage
28284 // name might introduce spurious comparison false
28285 // negatives.
28286 /*linkage_name=*/is_anonymous ? string() : name,
28287 vis),
28288 type_base(env, size_in_bits, 0),
28289 class_or_union(env, name, size_in_bits,
28290 0, locus, vis)
28291{
28293 set_is_anonymous(is_anonymous);
28294}
28295
28296/// Constructor for the @ref union_decl type.
28297///
28298/// @param env the @ref environment we are operating from.
28299///
28300/// @param name the name of the union type.
28301///
28302/// @param is_declaration_only a boolean saying whether the instance
28303/// represents a declaration only, or not.
28304union_decl::union_decl(const environment& env,
28305 const string& name,
28306 bool is_declaration_only)
28307 : type_or_decl_base(env,
28308 UNION_TYPE
28309 | ABSTRACT_TYPE_BASE
28310 | ABSTRACT_DECL_BASE
28311 | ABSTRACT_SCOPE_TYPE_DECL
28312 | ABSTRACT_SCOPE_DECL),
28313 decl_base(env, name, location(), name),
28314 type_base(env, 0, 0),
28315 class_or_union(env, name, is_declaration_only)
28316{
28318}
28319
28320/// Return the hash value of the current IR node.
28321///
28322/// Note that upon the first invocation, this member functions
28323/// computes the hash value and returns it. Subsequent invocations
28324/// just return the hash value that was previously calculated.
28325///
28326/// @return the hash value of the current IR node.
28327hash_t
28329{
28331 return h;
28332}
28333
28334/// Getter of the pretty representation of the current instance of
28335/// @ref union_decl.
28336///
28337/// @param internal set to true if the call is intended to get a
28338/// representation of the decl (or type) for the purpose of canonical
28339/// type comparison. This is mainly used in the function
28340/// homonym_type_group::get_canonical_type_for().
28341///
28342/// In other words if the argument for this parameter is true then the
28343/// call is meant for internal use (for technical use inside the
28344/// library itself), false otherwise. If you don't know what this is
28345/// for, then set it to false.
28346///
28347/// @param qualified_name if true, names emitted in the pretty
28348/// representation are fully qualified.
28349///
28350/// @return the pretty representaion for a union_decl.
28351string
28353 bool qualified_name) const
28354{
28355 string repr;
28356 if (get_is_anonymous())
28357 {
28358 if (internal && !get_name().empty())
28359 repr = string("union ") +
28360 get_type_name(this, qualified_name, /*internal=*/true);
28361 else
28363 /*one_line=*/true,
28364 internal);
28365 }
28366 else
28367 {
28368 repr = "union ";
28369 if (qualified_name)
28370 repr += get_qualified_name(internal);
28371 else
28372 repr += get_name();
28373 }
28374
28375 return repr;
28376}
28377
28378/// Comparison operator for @ref union_decl.
28379///
28380/// @param other the instance of @ref union_decl to compare against.
28381///
28382/// @return true iff the current instance of @ref union_decl equals @p
28383/// other.
28384bool
28386{
28387 const union_decl* op = dynamic_cast<const union_decl*>(&other);
28388 if (!op)
28389 return false;
28390 return try_canonical_compare(this, op);
28391}
28392
28393/// Equality operator for union_decl.
28394///
28395/// Re-uses the equality operator that takes a decl_base.
28396///
28397/// @param other the other union_decl to compare against.
28398///
28399/// @return true iff the current instance equals the other one.
28400bool
28402{
28403 const decl_base *o = dynamic_cast<const decl_base*>(&other);
28404 if (!o)
28405 return false;
28406 return *this == *o;
28407}
28408
28409/// Equality operator for union_decl.
28410///
28411/// Re-uses the equality operator that takes a decl_base.
28412///
28413/// @param other the other union_decl to compare against.
28414///
28415/// @return true iff the current instance equals the other one.
28416bool
28418{
28419 const decl_base *o = dynamic_cast<const decl_base*>(&other);
28420 return *this == *o;
28421}
28422
28423/// Comparison operator for @ref union_decl.
28424///
28425/// @param other the instance of @ref union_decl to compare against.
28426///
28427/// @return true iff the current instance of @ref union_decl equals @p
28428/// other.
28429bool
28431{
28432 const decl_base& o = other;
28433 return *this == o;
28434}
28435
28436/// This implements the ir_traversable_base::traverse pure virtual
28437/// function.
28438///
28439/// @param v the visitor used on the current instance and on its
28440/// members.
28441///
28442/// @return true if the entire IR node tree got traversed, false
28443/// otherwise.
28444bool
28446{
28447 if (v.type_node_has_been_visited(this))
28448 return true;
28449
28450 if (visiting())
28451 return true;
28452
28453 if (v.visit_begin(this))
28454 {
28455 visiting(true);
28456 bool stop = false;
28457
28458 if (!stop)
28459 {
28461 for (auto& d : dmems)
28462 if (!d->traverse(v))
28463 {
28464 stop = true;
28465 break;
28466 }
28467 }
28468
28469 if (!stop)
28470 for (member_functions::const_iterator i= get_member_functions().begin();
28471 i != get_member_functions().end();
28472 ++i)
28473 if (!(*i)->traverse(v))
28474 {
28475 stop = true;
28476 break;
28477 }
28478
28479 if (!stop)
28480 for (auto i = get_sorted_member_types().begin();
28481 i != get_sorted_member_types().end();
28482 ++i)
28483 if (!(*i)->traverse(v))
28484 {
28485 stop = true;
28486 break;
28487 }
28488
28489 if (!stop)
28490 for (member_function_templates::const_iterator i =
28492 i != get_member_function_templates().end();
28493 ++i)
28494 if (!(*i)->traverse(v))
28495 {
28496 stop = true;
28497 break;
28498 }
28499
28500 if (!stop)
28501 for (member_class_templates::const_iterator i =
28503 i != get_member_class_templates().end();
28504 ++i)
28505 if (!(*i)->traverse(v))
28506 {
28507 stop = true;
28508 break;
28509 }
28510 visiting(false);
28511 }
28512
28513 bool result = v.visit_end(this);
28515 return result;
28516}
28517
28518/// Destructor of the @ref union_decl type.
28521
28522/// Compares two instances of @ref union_decl.
28523///
28524/// If the two intances are different, set a bitfield to give some
28525/// insight about the kind of differences there are.
28526///
28527/// @param l the first artifact of the comparison.
28528///
28529/// @param r the second artifact of the comparison.
28530///
28531/// @param k a pointer to a bitfield that gives information about the
28532/// kind of changes there are between @p l and @p r. This one is set
28533/// iff @p k is non-null and the function returns false.
28534///
28535/// Please note that setting k to a non-null value does have a
28536/// negative performance impact because even if @p l and @p r are not
28537/// equal, the function keeps up the comparison in order to determine
28538/// the different kinds of ways in which they are different.
28539///
28540/// @return true if @p l equals @p r, false otherwise.
28541bool
28543{
28544
28546
28547 {
28548 // First of all, let's see if these two types haven't already been
28549 // compared. If so, and if the result of the comparison has been
28550 // cached, let's just re-use it, rather than comparing them all
28551 // over again.
28552 bool result = false;
28553 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
28554 ABG_RETURN(result);
28555 }
28556
28557 bool result = equals(static_cast<const class_or_union&>(l),
28558 static_cast<const class_or_union&>(r),
28559 k);
28560
28562}
28563
28564/// Copy a method of a @ref union_decl into a new @ref
28565/// union_decl.
28566///
28567/// @param t the @ref union_decl into which the method is to be copied.
28568///
28569/// @param method the method to copy into @p t.
28570///
28571/// @return the resulting newly copied method.
28572method_decl_sptr
28573copy_member_function(union_decl_sptr union_type,
28574 const method_decl_sptr& f)
28575{return copy_member_function(union_type, f.get());}
28576
28577/// Copy a method of a @ref union_decl into a new @ref
28578/// union_decl.
28579///
28580/// @param t the @ref union_decl into which the method is to be copied.
28581///
28582/// @param method the method to copy into @p t.
28583///
28584/// @return the resulting newly copied method.
28585method_decl_sptr
28586copy_member_function(union_decl_sptr union_type,
28587 const method_decl* f)
28588{
28589 const class_or_union_sptr t = union_type;
28590 return copy_member_function(t, f);
28591}
28592
28593/// Copy missing member functions from a source @ref class_decl to a
28594/// destination one.
28595///
28596/// If a function is present on the source @ref class_decl and not
28597/// on the destination one, then it's copied from the source class
28598/// to the destination one.
28599void
28600copy_missing_member_functions(class_or_union_sptr& dest_class,
28601 const class_or_union_sptr& src_class,
28602 bool copy_virtual_functions)
28603{
28604 class_or_union_sptr dest =
28606 class_or_union_sptr src =
28608
28609 if (dest && dest->get_corpus()
28610 && src && src->get_corpus()
28611 && dest->get_corpus() == src->get_corpus())
28612 {
28613 vector<method_decl_sptr> methods_to_copy;
28614
28615 for (auto& method : src->get_member_functions())
28616 {
28617 if (!copy_virtual_functions
28619 continue;
28620
28621 string n = method->get_linkage_name();
28622 if (n.empty())
28623 n = method->get_name();
28624 if (!dest->find_member_function(n))
28625 methods_to_copy.push_back(method);
28626 }
28627
28628 for (auto& method : methods_to_copy)
28629 {
28630 method_decl_sptr copied_method =
28631 copy_member_function(dest, method);
28632 ABG_ASSERT(copied_method);
28633 ABG_ASSERT(copied_method->get_linkage_name()
28634 == method->get_linkage_name());
28635 ABG_ASSERT(copied_method->get_name()
28636 == method->get_name());
28637
28638 auto copied_mtype = copied_method->get_type();
28639
28640 if (type_base_sptr method_type = copied_mtype)
28642 }
28643 }
28644}
28645
28646/// Copy missing data members from a source @ref class_decl to a
28647/// destination one.
28648///
28649/// If a data member is present on the source @ref class_decl and not
28650/// on the destination one, then it's copied from the source class
28651/// to the destination one.
28652///
28653/// @param dest_class the destination class type to copy the data
28654/// member to.
28655///
28656/// @param src_class the source class type to copy the data member
28657/// from.
28658void
28659copy_missing_member_variables(class_or_union_sptr& dest_class,
28660 const class_or_union_sptr& src_class)
28661{
28662 if (src_class)
28663 {
28664 for (auto& var : src_class->get_data_members())
28665 if (!var->get_name().empty())
28666 if (!dest_class->find_data_member(var->get_name()))
28667 {
28668 var_decl_sptr copied_data_member =
28669 copy_member_variable(dest_class, var);
28670 ABG_ASSERT(copied_data_member);
28671 }
28672 }
28673}
28674
28675/// Copy the naming typedef from a named type to an unnamed one.
28676///
28677/// @param type the destination the copy.
28678///
28679/// @param named_type the source of the copy.
28680///
28681/// @return the copied naming typedef or nullptr if none was copied.
28684 const decl_base_sptr named_type)
28685{
28686 if (!type
28687 || !is_type(type)
28688 || !named_type
28689 || named_type->get_naming_typedefs().empty())
28690 return nullptr;
28691
28692 typedef_decl_sptr naming_typedef;
28693 for (auto n : named_type->get_naming_typedefs())
28694 if (!type->has_naming_typedef(n))
28695 {
28696 naming_typedef = n;
28697 break;
28698 }
28699
28700 if (naming_typedef)
28701 {
28702 typedef_decl_sptr result(new typedef_decl(naming_typedef->get_name(),
28703 is_type(type),
28704 naming_typedef->get_location(),
28705 naming_typedef->get_linkage_name(),
28706 naming_typedef->get_visibility()));
28707 result->set_original_artefact(naming_typedef.get());
28708 add_decl_to_scope(result, type->get_scope());
28709 type->add_naming_typedef(result);
28710
28712 return result;
28713 }
28714
28715 return nullptr;
28716}
28717
28718/// Move a member type from its current class or union scope to a
28719/// destination class or union, if the member type is missing from the
28720/// destination.
28721///
28722/// The move is performed only if:
28723/// - Both artifacts belong to the same ABI corpus.
28724/// - The source member type belongs to a class or union scope.
28725/// - The destination class or union does not already have a member
28726/// type with the same name, or has one but with a different
28727/// canonical type.
28728///
28729/// @param dest_class_or_union the destination class or union to move
28730/// the member type into.
28731///
28732/// @param src_member_type the member type to potentially move into
28733/// @p dest_class_or_union.
28734///
28735/// @return the member type that was moved into @p dest_class_or_union,
28736/// or nullptr if no move was performed.
28737type_base_sptr
28738maybe_move_missing_member_type(class_or_union_sptr dest_class_or_union,
28739 type_base_sptr src_member_type)
28740{
28741 ABG_ASSERT(dest_class_or_union);
28742 ABG_ASSERT(src_member_type);
28743
28744 // The two artifacts must come from the same ABI.
28745 corpus *src_abi = src_member_type->get_corpus(),
28746 *dest_abi = dest_class_or_union->get_corpus();
28747 if (src_abi != dest_abi)
28748 return nullptr;
28749
28750 // The source artifact must belong to a class or union.
28751 decl_base_sptr decl_of_type = is_decl(src_member_type);
28752 class_or_union_sptr src_scope = is_class_type(decl_of_type->get_scope());
28753 if (!src_scope)
28754 return nullptr;
28755
28756 // Perform the move.
28757 type_base_sptr result;
28758 bool perform_the_move = false;
28759 type_base_sptr member_type =
28760 dest_class_or_union->find_member_type(decl_of_type->get_name());
28761 if (!member_type)
28762 perform_the_move = true;
28763 else if (typedef_decl_sptr t = is_typedef(member_type))
28764 {
28765 if (type_base* c1 = src_member_type->get_naked_canonical_type())
28766 if (type_base* c2 = t->get_naked_canonical_type())
28767 if (c1 != c2)
28768 perform_the_move = true;
28769 }
28770
28771 if (perform_the_move)
28772 {
28773 move_member_type(decl_of_type, dest_class_or_union);
28774 // A last sanity check.
28775 src_scope = is_class_type(decl_of_type->get_scope());
28776 ABG_ASSERT(dest_class_or_union.get() == src_scope.get());
28777 result = src_member_type;
28778 }
28779
28780 return result;
28781}
28782
28783/// Move member types that are present in @p src_class_or_union but
28784/// missing from @p dest_class_or_union into @p dest_class_or_union.
28785///
28786/// @param dest_class_or_union the class or union to move the missing
28787/// member types into.
28788///
28789/// @param src_class_or_union the class or union to look for member
28790/// types to move from.
28791void
28792move_missing_member_types(class_or_union_sptr dest_class_or_union,
28793 class_or_union_sptr src_class_or_union)
28794{
28795 if (dest_class_or_union && src_class_or_union)
28796 for (auto member_type : src_class_or_union->get_member_types())
28797 maybe_move_missing_member_type(dest_class_or_union, member_type);
28798}
28799
28800/// Turn equality of shared_ptr of union_decl into a deep equality;
28801/// that is, make it compare the pointed to objects too.
28802///
28803/// @param l the left-hand-side operand of the operator
28804///
28805/// @param r the right-hand-side operand of the operator.
28806///
28807/// @return true iff @p l equals @p r.
28808bool
28809operator==(const union_decl_sptr& l, const union_decl_sptr& r)
28810{
28811 if (l.get() == r.get())
28812 return true;
28813 if (!!l != !!r)
28814 return false;
28815
28816 return *l == *r;
28817}
28818
28819/// Turn inequality of shared_ptr of union_decl into a deep equality;
28820/// that is, make it compare the pointed to objects too.
28821///
28822/// @param l the left-hand-side operand of the operator
28823///
28824/// @param r the right-hand-side operand of the operator.
28825///
28826/// @return true iff @p l is different from @p r.
28827bool
28828operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
28829{return !operator==(l, r);}
28830// </union_decl>
28831
28832// <class mem_fn_context_rel> stuff
28833
28834struct mem_fn_context_rel::priv
28835{
28836 recursive_mutex mutex_;
28837 bool is_virtual_ = false;
28838 ssize_t vtable_offset_in_bits_ = -1;
28839 bool is_constructor_ = false;
28840 bool is_destructor_ = false;
28841 bool is_const_ = false;
28842};// end struct mem_fn_context_rel
28843
28844mem_fn_context_rel::mem_fn_context_rel()
28845 : context_rel(), priv_(new priv)
28846{
28847 priv_->is_virtual_ = false;
28848 priv_->vtable_offset_in_bits_ = -1;
28849 priv_->is_constructor_ = false;
28850 priv_->is_destructor_ = false;
28851 priv_->is_const_ = false;
28852}
28853
28854mem_fn_context_rel::mem_fn_context_rel(scope_decl_sptr s)
28855 : context_rel(s),
28856 priv_(new priv)
28857{
28858 priv_->is_virtual_ = false;
28859 priv_->vtable_offset_in_bits_ = -1;
28860 priv_->is_constructor_ = false;
28861 priv_->is_destructor_ = false;
28862 priv_->is_const_ = false;
28863}
28864
28865
28866mem_fn_context_rel::mem_fn_context_rel(scope_decl_sptr s,
28867 bool is_constructor,
28868 bool is_destructor,
28869 bool is_const,
28870 bool is_virtual,
28871 size_t vtable_offset_in_bits,
28872 access_specifier access,
28873 bool is_static)
28874 : context_rel(s, access, is_static),
28875 priv_(new priv)
28876{
28877 priv_->is_virtual_ = is_virtual;
28878 priv_->vtable_offset_in_bits_ = vtable_offset_in_bits;
28879 priv_->is_constructor_ = is_constructor;
28880 priv_->is_destructor_ = is_destructor;
28881 priv_->is_const_ = is_const;
28882}
28883
28884bool
28885mem_fn_context_rel::is_virtual() const
28886{
28887 lock_guard<recursive_mutex> lock(priv_->mutex_);
28888 return priv_->is_virtual_;
28889}
28890
28891void
28892mem_fn_context_rel::is_virtual(bool is_virtual)
28893{
28894 lock_guard<recursive_mutex> lock(priv_->mutex_);
28895 priv_->is_virtual_ = is_virtual;
28896}
28897
28898/// Getter for the vtable offset property.
28899///
28900/// This is the vtable offset of the member function of this
28901/// relation.
28902///
28903/// @return the vtable offset property of the relation.
28904size_t
28906{
28907 lock_guard<recursive_mutex> lock(priv_->mutex_);
28908 return priv_->vtable_offset_in_bits_;
28909}
28910
28911/// Setter for the vtable offset property.
28912///
28913/// This is the vtable offset of the member function of this
28914/// relation.
28915///
28916/// @partam s the new vtable offset.
28917void
28919{
28920 lock_guard<recursive_mutex> lock(priv_->mutex_);
28921 priv_->vtable_offset_in_bits_ = s;
28922}
28923
28924/// Getter for the 'is-constructor' property.
28925///
28926/// This tells if the member function of this relation is a
28927/// constructor.
28928///
28929/// @return the is-constructor property of the relation.
28930bool
28932{
28933 lock_guard<recursive_mutex> lock(priv_->mutex_);
28934 return priv_->is_constructor_;
28935}
28936
28937/// Setter for the 'is-constructor' property.
28938///
28939/// @param f the new value of the the property. Is true if this is
28940/// for a constructor, false otherwise.
28941void
28943{
28944 lock_guard<recursive_mutex> lock(priv_->mutex_);
28945 priv_->is_constructor_ = f;
28946}
28947
28948/// Getter for the 'is-destructor' property.
28949///
28950/// Tells if the member function of this relation is a destructor.
28951///
28952/// @return the is-destructor property of the relation;
28953bool
28955{
28956 lock_guard<recursive_mutex> lock(priv_->mutex_);
28957 return priv_->is_destructor_;
28958}
28959
28960/// Setter for the 'is-destructor' property.
28961///
28962/// @param f the new value of the property. Is true if this is for
28963/// a destructor, false otherwise.
28964void
28966{
28967 lock_guard<recursive_mutex> lock(priv_->mutex_);
28968 priv_->is_destructor_ = f;
28969}
28970
28971/// Getter for the 'is-const' property.
28972///
28973/// Tells if the member function of this relation is a const member
28974/// function.
28975///
28976/// @return the 'is-const' property of the relation.
28977bool
28979{
28980 lock_guard<recursive_mutex> lock(priv_->mutex_);
28981 return priv_->is_const_;
28982}
28983
28984/// Setter for the 'is-const' property.
28985///
28986/// @param f the new value of the property. Is true if this is for
28987/// a const entity, false otherwise.
28988void
28990{
28991 lock_guard<recursive_mutex> lock(priv_->mutex_);
28992 priv_->is_const_ = f;
28993}
28994
28995mem_fn_context_rel::~mem_fn_context_rel()
28996{
28997}
28998// </class mem_fn_context_rel>
28999
29000// <template_decl stuff>
29001
29002/// Data type of the private data of the @template_decl type.
29003class template_decl::priv
29004{
29005 friend class template_decl;
29006
29007 std::list<template_parameter_sptr> parms_;
29008public:
29009
29010 priv()
29011 {}
29012}; // end class template_decl::priv
29013
29014/// Add a new template parameter to the current instance of @ref
29015/// template_decl.
29016///
29017/// @param p the new template parameter to add.
29018void
29020{priv_->parms_.push_back(p);}
29021
29022/// Get the list of template parameters of the current instance of
29023/// @ref template_decl.
29024///
29025/// @return the list of template parameters.
29026const std::list<template_parameter_sptr>&
29028{return priv_->parms_;}
29029
29030/// Constructor.
29031///
29032/// @param env the environment we are operating from.
29033///
29034/// @param name the name of the template decl.
29035///
29036/// @param locus the source location where the template declaration is
29037/// defined.
29038///
29039/// @param vis the visibility of the template declaration.
29040template_decl::template_decl(const environment& env,
29041 const string& name,
29042 const location& locus,
29043 visibility vis)
29044 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
29045 decl_base(env, name, locus, /*mangled_name=*/"", vis),
29046 priv_(new priv)
29047{
29049}
29050
29051/// Destructor.
29054
29055/// Equality operator.
29056///
29057/// @param o the other instance to compare against.
29058///
29059/// @return true iff @p equals the current instance.
29060bool
29062{
29063 const template_decl* other = dynamic_cast<const template_decl*>(&o);
29064 if (!other)
29065 return false;
29066 return *this == *other;
29067}
29068
29069/// Equality operator.
29070///
29071/// @param o the other instance to compare against.
29072///
29073/// @return true iff @p equals the current instance.
29074bool
29076{
29077 try
29078 {
29079 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
29080 for (t0 = get_template_parameters().begin(),
29081 t1 = o.get_template_parameters().begin();
29082 (t0 != get_template_parameters().end()
29083 && t1 != o.get_template_parameters().end());
29084 ++t0, ++t1)
29085 {
29086 if (**t0 != **t1)
29087 return false;
29088 }
29089
29090 if (t0 != get_template_parameters().end()
29091 || t1 != o.get_template_parameters().end())
29092 return false;
29093
29094 return true;
29095 }
29096 catch(...)
29097 {return false;}
29098}
29099
29100// </template_decl stuff>
29101
29102//<template_parameter>
29103
29104/// The type of the private data of the @ref template_parameter type.
29105class template_parameter::priv
29106{
29107 friend class template_parameter;
29108
29109 unsigned index_;
29110 template_decl_wptr template_decl_;
29111 mutable bool hashing_started_;
29112 mutable bool comparison_started_;
29113
29114 priv();
29115
29116public:
29117
29118 priv(unsigned index, template_decl_sptr enclosing_template_decl)
29119 : index_(index),
29120 template_decl_(enclosing_template_decl),
29121 hashing_started_(),
29122 comparison_started_()
29123 {}
29124}; // end class template_parameter::priv
29125
29126template_parameter::template_parameter(unsigned index,
29127 template_decl_sptr enclosing_template)
29128 : priv_(new priv(index, enclosing_template))
29129 {}
29130
29131unsigned
29132template_parameter::get_index() const
29133{return priv_->index_;}
29134
29136template_parameter::get_enclosing_template_decl() const
29137{return priv_->template_decl_.lock();}
29138
29139
29140bool
29141template_parameter::operator==(const template_parameter& o) const
29142{
29143 if (get_index() != o.get_index())
29144 return false;
29145
29146 if (priv_->comparison_started_)
29147 return true;
29148
29149 bool result = false;
29150
29151 // Avoid inifite loops due to the fact that comparison the enclosing
29152 // template decl might lead to comparing this very same template
29153 // parameter with another one ...
29154 priv_->comparison_started_ = true;
29155
29156 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
29157 ;
29158 else if (get_enclosing_template_decl()
29159 && (*get_enclosing_template_decl()
29160 != *o.get_enclosing_template_decl()))
29161 ;
29162 else
29163 result = true;
29164
29165 priv_->comparison_started_ = false;
29166
29167 return result;
29168}
29169
29170/// Inequality operator.
29171///
29172/// @param other the other instance to compare against.
29173///
29174/// @return true iff the other instance is different from the current
29175/// one.
29176bool
29178{return !operator==(other);}
29179
29180/// Destructor.
29183
29184/// The type of the private data of the @ref type_tparameter type.
29185class type_tparameter::priv
29186{
29187 friend class type_tparameter;
29188}; // end class type_tparameter::priv
29189
29190/// Constructor of the @ref type_tparameter type.
29191///
29192/// @param index the index the type template parameter.
29193///
29194/// @param enclosing_tdecl the enclosing template declaration.
29195///
29196/// @param name the name of the template parameter.
29197///
29198/// @param locus the location of the declaration of this type template
29199/// parameter.
29200type_tparameter::type_tparameter(unsigned index,
29201 template_decl_sptr enclosing_tdecl,
29202 const string& name,
29203 const location& locus)
29204 : type_or_decl_base(enclosing_tdecl->get_environment(),
29205 ABSTRACT_DECL_BASE
29206 | ABSTRACT_TYPE_BASE
29207 | BASIC_TYPE),
29208 decl_base(enclosing_tdecl->get_environment(), name, locus),
29209 type_base(enclosing_tdecl->get_environment(), 0, 0),
29210 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
29211 template_parameter(index, enclosing_tdecl),
29212 priv_(new priv)
29213{
29215}
29216
29217/// Equality operator.
29218///
29219/// @param other the other template type parameter to compare against.
29220///
29221/// @return true iff @p other equals the current instance.
29222bool
29224{
29225 if (!type_decl::operator==(other))
29226 return false;
29227
29228 try
29229 {
29230 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
29231 return template_parameter::operator==(o);
29232 }
29233 catch (...)
29234 {return false;}
29235}
29236
29237/// Equality operator.
29238///
29239/// @param other the other template type parameter to compare against.
29240///
29241/// @return true iff @p other equals the current instance.
29242bool
29244{
29245 if (!type_decl::operator==(other))
29246 return false;
29247
29248 try
29249 {
29250 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
29251 return template_parameter::operator==(o);
29252 }
29253 catch (...)
29254 {return false;}
29255}
29256
29257/// Equality operator.
29258///
29259/// @param other the other template type parameter to compare against.
29260///
29261/// @return true iff @p other equals the current instance.
29262bool
29264{
29265 if (!decl_base::operator==(other))
29266 return false;
29267
29268 try
29269 {
29270 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
29271 return template_parameter::operator==(o);
29272 }
29273 catch (...)
29274 {return false;}
29275}
29276
29277/// Equality operator.
29278///
29279/// @param other the other template type parameter to compare against.
29280///
29281/// @return true iff @p other equals the current instance.
29282bool
29284{
29285 try
29286 {
29287 const type_base& o = dynamic_cast<const type_base&>(other);
29288 return *this == o;
29289 }
29290 catch(...)
29291 {return false;}
29292}
29293
29294/// Equality operator.
29295///
29296/// @param other the other template type parameter to compare against.
29297///
29298/// @return true iff @p other equals the current instance.
29299bool
29301{return *this == static_cast<const type_base&>(other);}
29302
29303type_tparameter::~type_tparameter()
29304{}
29305
29306/// The type of the private data of the @ref non_type_tparameter type.
29307class non_type_tparameter::priv
29308{
29309 friend class non_type_tparameter;
29310
29311 type_base_wptr type_;
29312
29313 priv();
29314
29315public:
29316
29317 priv(type_base_sptr type)
29318 : type_(type)
29319 {}
29320}; // end class non_type_tparameter::priv
29321
29322/// The constructor for the @ref non_type_tparameter type.
29323///
29324/// @param index the index of the template parameter.
29325///
29326/// @param enclosing_tdecl the enclosing template declaration that
29327/// holds this parameter parameter.
29328///
29329/// @param name the name of the template parameter.
29330///
29331/// @param type the type of the template parameter.
29332///
29333/// @param locus the location of the declaration of this template
29334/// parameter.
29335non_type_tparameter::non_type_tparameter(unsigned index,
29336 template_decl_sptr enclosing_tdecl,
29337 const string& name,
29338 type_base_sptr type,
29339 const location& locus)
29340 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
29341 decl_base(type->get_environment(), name, locus, ""),
29342 template_parameter(index, enclosing_tdecl),
29343 priv_(new priv(type))
29344{
29346}
29347
29348/// Getter for the type of the template parameter.
29349///
29350/// @return the type of the template parameter.
29351const type_base_sptr
29353{return priv_->type_.lock();}
29354
29355
29356bool
29358{
29359 if (!decl_base::operator==(other))
29360 return false;
29361
29362 try
29363 {
29364 const non_type_tparameter& o =
29365 dynamic_cast<const non_type_tparameter&>(other);
29366 return (template_parameter::operator==(o)
29367 && get_type() == o.get_type());
29368 }
29369 catch(...)
29370 {return false;}
29371}
29372
29373bool
29375{
29376 try
29377 {
29378 const decl_base& o = dynamic_cast<const decl_base&>(other);
29379 return *this == o;
29380 }
29381 catch(...)
29382 {return false;}
29383}
29384
29385non_type_tparameter::~non_type_tparameter()
29386{}
29387
29388// <template_tparameter stuff>
29389
29390/// Type of the private data of the @ref template_tparameter type.
29391class template_tparameter::priv
29392{
29393}; //end class template_tparameter::priv
29394
29395/// Constructor for the @ref template_tparameter.
29396///
29397/// @param index the index of the template parameter.
29398///
29399/// @param enclosing_tdecl the enclosing template declaration.
29400///
29401/// @param name the name of the template parameter.
29402///
29403/// @param locus the location of the declaration of the template
29404/// parameter.
29405template_tparameter::template_tparameter(unsigned index,
29406 template_decl_sptr enclosing_tdecl,
29407 const string& name,
29408 const location& locus)
29409 : type_or_decl_base(enclosing_tdecl->get_environment(),
29410 ABSTRACT_DECL_BASE
29411 | ABSTRACT_TYPE_BASE
29412 | BASIC_TYPE),
29413 decl_base(enclosing_tdecl->get_environment(), name, locus),
29414 type_base(enclosing_tdecl->get_environment(), 0, 0),
29415 type_decl(enclosing_tdecl->get_environment(), name,
29416 0, 0, locus, name, VISIBILITY_DEFAULT),
29417 type_tparameter(index, enclosing_tdecl, name, locus),
29418 template_decl(enclosing_tdecl->get_environment(), name, locus),
29419 priv_(new priv)
29420{
29422}
29423
29424/// Equality operator.
29425///
29426/// @param other the other template parameter to compare against.
29427///
29428/// @return true iff @p other equals the current instance.
29429bool
29431{
29432 try
29433 {
29434 const template_tparameter& o =
29435 dynamic_cast<const template_tparameter&>(other);
29436 return (type_tparameter::operator==(o)
29438 }
29439 catch(...)
29440 {return false;}
29441}
29442
29443/// Equality operator.
29444///
29445/// @param other the other template parameter to compare against.
29446///
29447/// @return true iff @p other equals the current instance.
29448bool
29450{
29451 try
29452 {
29453 const template_tparameter& o =
29454 dynamic_cast<const template_tparameter&>(other);
29455 return (type_tparameter::operator==(o)
29457 }
29458 catch(...)
29459 {return false;}
29460}
29461
29462bool
29464{
29465 try
29466 {
29467 const template_tparameter& other =
29468 dynamic_cast<const template_tparameter&>(o);
29469 return *this == static_cast<const type_base&>(other);
29470 }
29471 catch(...)
29472 {return false;}
29473}
29474
29475bool
29477{
29478 try
29479 {
29480 const template_tparameter& other =
29481 dynamic_cast<const template_tparameter&>(o);
29482 return type_base::operator==(other);
29483 }
29484 catch(...)
29485 {return false;}
29486}
29487
29488template_tparameter::~template_tparameter()
29489{}
29490
29491// </template_tparameter stuff>
29492
29493// <type_composition stuff>
29494
29495/// The type of the private data of the @ref type_composition type.
29496class type_composition::priv
29497{
29498 friend class type_composition;
29499
29500 type_base_wptr type_;
29501
29502 // Forbid this.
29503 priv();
29504
29505public:
29506
29507 priv(type_base_wptr type)
29508 : type_(type)
29509 {}
29510}; //end class type_composition::priv
29511
29512/// Constructor for the @ref type_composition type.
29513///
29514/// @param index the index of the template type composition.
29515///
29516/// @param tdecl the enclosing template parameter that owns the
29517/// composition.
29518///
29519/// @param t the resulting type.
29520type_composition::type_composition(unsigned index,
29521 template_decl_sptr tdecl,
29522 type_base_sptr t)
29523 : type_or_decl_base(tdecl->get_environment(),
29524 ABSTRACT_DECL_BASE),
29525 decl_base(tdecl->get_environment(), "", location()),
29526 template_parameter(index, tdecl),
29527 priv_(new priv(t))
29528{
29530}
29531
29532/// Getter for the resulting composed type.
29533///
29534/// @return the composed type.
29535const type_base_sptr
29537{return priv_->type_.lock();}
29538
29539/// Setter for the resulting composed type.
29540///
29541/// @param t the composed type.
29542void
29544{priv_->type_ = t;}
29545
29546type_composition::~type_composition()
29547{}
29548
29549// </type_composition stuff>
29550
29551//</template_parameter stuff>
29552
29553// <function_template>
29554
29555struct function_tdecl::priv
29556{
29557 friend class function_tdecl;
29558
29559 function_decl_sptr pattern_;
29560 binding binding_;
29561
29562 priv();
29563
29564public:
29565
29566 priv(function_decl_sptr pattern, binding bind)
29567 : pattern_(pattern), binding_(bind)
29568 {}
29569
29570 priv(binding bind)
29571 : binding_(bind)
29572 {}
29573}; // end struct function_tdecl::priv
29574
29575/// Constructor for a function template declaration.
29576///
29577/// @param env the environment we are operating from.
29578///
29579/// @param locus the location of the declaration.
29580///
29581/// @param vis the visibility of the declaration. This is the
29582/// visibility the functions instantiated from this template are going
29583/// to have.
29584///
29585/// @param bind the binding of the declaration. This is the binding
29586/// the functions instantiated from this template are going to have.
29587function_tdecl::function_tdecl(const environment& env,
29588 const location& locus,
29589 visibility vis,
29590 binding bind)
29591 : type_or_decl_base(env,
29592 ABSTRACT_DECL_BASE
29593 | TEMPLATE_DECL
29594 | ABSTRACT_SCOPE_DECL),
29595 decl_base(env, "", locus, "", vis),
29596 template_decl(env, "", locus, vis),
29597 scope_decl(env, "", locus),
29598 priv_(new priv(bind))
29599{
29601}
29602
29603/// Constructor for a function template declaration.
29604///
29605/// @param pattern the pattern of the template.
29606///
29607/// @param locus the location of the declaration.
29608///
29609/// @param vis the visibility of the declaration. This is the
29610/// visibility the functions instantiated from this template are going
29611/// to have.
29612///
29613/// @param bind the binding of the declaration. This is the binding
29614/// the functions instantiated from this template are going to have.
29615function_tdecl::function_tdecl(function_decl_sptr pattern,
29616 const location& locus,
29617 visibility vis,
29618 binding bind)
29619 : type_or_decl_base(pattern->get_environment(),
29620 ABSTRACT_DECL_BASE
29621 | TEMPLATE_DECL
29622 | ABSTRACT_SCOPE_DECL),
29623 decl_base(pattern->get_environment(), pattern->get_name(), locus,
29624 pattern->get_name(), vis),
29625 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
29626 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
29627 priv_(new priv(pattern, bind))
29628{
29630}
29631
29632/// Set a new pattern to the function template.
29633///
29634/// @param p the new pattern.
29635void
29637{
29638 ABG_ASSERT(ftdecl);
29639 add_decl_to_scope(p, ftdecl);
29640 ftdecl->priv_->pattern_ = p;
29641 ftdecl->set_name(p->get_name());
29642}
29643
29644/// Get the pattern of the function template.
29645///
29646/// @return the pattern.
29649{return priv_->pattern_;}
29650
29651/// Get the binding of the function template.
29652///
29653/// @return the binding
29656{return priv_->binding_;}
29657
29658/// Comparison operator for the @ref function_tdecl type.
29659///
29660/// @param other the other instance of @ref function_tdecl to compare against.
29661///
29662/// @return true iff the two instance are equal.
29663bool
29665{
29666 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
29667 if (o)
29668 return *this == *o;
29669 return false;
29670}
29671
29672/// Comparison operator for the @ref function_tdecl type.
29673///
29674/// @param other the other instance of @ref function_tdecl to compare against.
29675///
29676/// @return true iff the two instance are equal.
29677bool
29679{
29680 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
29681 if (o)
29682 return *this == *o;
29683 return false;
29684}
29685
29686/// Comparison operator for the @ref function_tdecl type.
29687///
29688/// @param o the other instance of @ref function_tdecl to compare against.
29689///
29690/// @return true iff the two instance are equal.
29691bool
29693{
29694 if (!(get_binding() == o.get_binding()
29695 && template_decl::operator==(o)
29696 && scope_decl::operator==(o)
29697 && !!get_pattern() == !!o.get_pattern()))
29698 return false;
29699
29700 if (get_pattern())
29701 return (*get_pattern() == *o.get_pattern());
29702
29703 return true;
29704}
29705
29706/// This implements the ir_traversable_base::traverse pure virtual
29707/// function.
29708///
29709/// @param v the visitor used on the current instance and on the
29710/// function pattern of the template.
29711///
29712/// @return true if the entire IR node tree got traversed, false
29713/// otherwise.
29714bool
29716{
29717 if (visiting())
29718 return true;
29719
29720 if (!v.visit_begin(this))
29721 {
29722 visiting(true);
29723 if (get_pattern())
29724 get_pattern()->traverse(v);
29725 visiting(false);
29726 }
29727 return v.visit_end(this);
29728}
29729
29730function_tdecl::~function_tdecl()
29731{}
29732
29733// </function_template>
29734
29735// <class template>
29736
29737/// Type of the private data of the the @ref class_tdecl type.
29738struct class_tdecl::priv
29739{
29740 friend class class_tdecl;
29741 class_decl_sptr pattern_;
29742
29743public:
29744
29745 priv()
29746 {}
29747
29748 priv(class_decl_sptr pattern)
29749 : pattern_(pattern)
29750 {}
29751}; // end class class_tdecl::priv
29752
29753/// Constructor for the @ref class_tdecl type.
29754///
29755/// @param env the environment we are operating from.
29756///
29757/// @param locus the location of the declaration of the class_tdecl
29758/// type.
29759///
29760/// @param vis the visibility of the instance of class instantiated
29761/// from this template.
29762class_tdecl::class_tdecl(const environment& env,
29763 const location& locus,
29764 visibility vis)
29765 : type_or_decl_base(env,
29766 ABSTRACT_DECL_BASE
29767 | TEMPLATE_DECL
29768 | ABSTRACT_SCOPE_DECL),
29769 decl_base(env, "", locus, "", vis),
29770 template_decl(env, "", locus, vis),
29771 scope_decl(env, "", locus),
29772 priv_(new priv)
29773{
29775}
29776
29777/// Constructor for the @ref class_tdecl type.
29778///
29779/// @param pattern The details of the class template. This must NOT be a
29780/// null pointer. If you really this to be null, please use the
29781/// constructor above instead.
29782///
29783/// @param locus the source location of the declaration of the type.
29784///
29785/// @param vis the visibility of the instances of class instantiated
29786/// from this template.
29787class_tdecl::class_tdecl(class_decl_sptr pattern,
29788 const location& locus,
29789 visibility vis)
29790 : type_or_decl_base(pattern->get_environment(),
29791 ABSTRACT_DECL_BASE
29792 | TEMPLATE_DECL
29793 | ABSTRACT_SCOPE_DECL),
29794 decl_base(pattern->get_environment(), pattern->get_name(),
29795 locus, pattern->get_name(), vis),
29796 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
29797 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
29798 priv_(new priv(pattern))
29799{
29801}
29802
29803/// Setter of the pattern of the template.
29804///
29805/// @param p the new template.
29806void
29808{
29809 ABG_ASSERT(ctdecl);
29810 add_decl_to_scope(p, ctdecl);
29811 ctdecl->priv_->pattern_ = p;
29812 ctdecl->set_name(p->get_name());
29813}
29814
29815/// Getter of the pattern of the template.
29816///
29817/// @return p the new template.
29820{return priv_->pattern_;}
29821
29822bool
29824{
29825 try
29826 {
29827 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
29828
29829 if (!(template_decl::operator==(o)
29830 && scope_decl::operator==(o)
29831 && !!get_pattern() == !!o.get_pattern()))
29832 return false;
29833
29834 if (!get_pattern() || !o.get_pattern())
29835 return true;
29836
29837 return get_pattern()->decl_base::operator==(*o.get_pattern());
29838 }
29839 catch(...) {}
29840 return false;
29841}
29842
29843bool
29845{
29846 try
29847 {
29848 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
29849 return *this == static_cast<const decl_base&>(o);
29850 }
29851 catch(...)
29852 {return false;}
29853}
29854
29855bool
29857{return *this == static_cast<const decl_base&>(o);}
29858
29859/// This implements the ir_traversable_base::traverse pure virtual
29860/// function.
29861///
29862/// @param v the visitor used on the current instance and on the class
29863/// pattern of the template.
29864///
29865/// @return true if the entire IR node tree got traversed, false
29866/// otherwise.
29867bool
29869{
29870 if (visiting())
29871 return true;
29872
29873 if (v.visit_begin(this))
29874 {
29875 visiting(true);
29876 if (class_decl_sptr pattern = get_pattern())
29877 pattern->traverse(v);
29878 visiting(false);
29879 }
29880 return v.visit_end(this);
29881}
29882
29883class_tdecl::~class_tdecl()
29884{}
29885
29886/// This visitor checks if a given type as non-canonicalized sub
29887/// types.
29888class non_canonicalized_subtype_detector : public ir::ir_node_visitor
29889{
29890 type_base* type_;
29891 type_base* has_non_canonical_type_;
29892
29893private:
29894 non_canonicalized_subtype_detector();
29895
29896public:
29897 non_canonicalized_subtype_detector(type_base* type)
29898 : type_(type),
29899 has_non_canonical_type_()
29900 {}
29901
29902 /// Return true if the visitor detected that there is a
29903 /// non-canonicalized sub-type.
29904 ///
29905 /// @return true if the visitor detected that there is a
29906 /// non-canonicalized sub-type.
29907 type_base*
29908 has_non_canonical_type() const
29909 {return has_non_canonical_type_;}
29910
29911 /// The intent of this visitor handler is to avoid looking into
29912 /// sub-types of member functions of the type we are traversing.
29913 bool
29914 visit_begin(function_decl* f)
29915 {
29916 // Do not look at sub-types of non-virtual member functions.
29917 if (is_member_function(f)
29919 return false;
29920 return true;
29921 }
29922
29923 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
29924 /// the 'has_non_canonical_type' flag. And in any case, when
29925 /// visiting a sub-type, do not visit its children nodes. So this
29926 /// function only goes to the level below the level of the top-most
29927 /// type.
29928 ///
29929 /// @return true if we are at the same level as the top-most type,
29930 /// otherwise return false.
29931 bool
29932 visit_begin(type_base* t)
29933 {
29934 if (t != type_)
29935 {
29936 if (!t->get_canonical_type())
29937 // We are looking a sub-type of 'type_' which has no
29938 // canonical type. So tada! we found one! Get out right
29939 // now with the trophy.
29940 has_non_canonical_type_ = t;
29941
29942 return false;
29943 }
29944 return true;
29945 }
29946
29947 /// When we are done visiting a sub-type, if it's been flagged as
29948 /// been non-canonicalized, then stop the traversing.
29949 ///
29950 /// Otherwise, keep going.
29951 ///
29952 /// @return false iff the sub-type that has been visited is
29953 /// non-canonicalized.
29954 bool
29955 visit_end(type_base* )
29956 {
29957 if (has_non_canonical_type_)
29958 return false;
29959 return true;
29960 }
29961}; //end class non_canonicalized_subtype_detector
29962
29963/// Test if a type has sub-types that are non-canonicalized.
29964///
29965/// @param t the type which sub-types to consider.
29966///
29967/// @return true if a type has sub-types that are non-canonicalized.
29968type_base*
29970{
29971 if (!t)
29972 return 0;
29973
29974 non_canonicalized_subtype_detector v(t.get());
29975 t->traverse(v);
29976 return v.has_non_canonical_type();
29977}
29978
29979/// Tests if the change of a given type effectively comes from just
29980/// its sub-types. That is, if the type has changed but its type name
29981/// hasn't changed, then the change of the type mostly likely is a
29982/// sub-type change.
29983///
29984/// @param t_v1 the first version of the type.
29985///
29986/// @param t_v2 the second version of the type.
29987///
29988/// @return true iff the type changed and the change is about its
29989/// sub-types.
29990bool
29991type_has_sub_type_changes(const type_base_sptr t_v1,
29992 const type_base_sptr t_v2)
29993{
29994 type_base_sptr t1 = strip_typedef(t_v1);
29995 type_base_sptr t2 = strip_typedef(t_v2);
29996
29997 string repr1 = get_pretty_representation(t1, /*internal=*/false),
29998 repr2 = get_pretty_representation(t2, /*internal=*/false);
29999 return (t1 != t2 && repr1 == repr2);
30000}
30001
30002/// Make sure that the life time of a given (smart pointer to a) type
30003/// is the same as the life time of the libabigail library.
30004///
30005/// @param t the type to consider.
30006void
30007keep_type_alive(type_base_sptr t)
30008{
30009 const environment& env = t->get_environment();
30010 lock_guard<mutex> lock(env.priv_->extra_live_types_mutex_);
30011 env.priv_->extra_live_types_.insert(t);
30012}
30013
30014/// Hash an ABI artifact that is either a type or a decl.
30015///
30016/// This function intends to provides the fastest possible hashing for
30017/// types and decls, while being completely correct.
30018///
30019/// Note that if the artifact is a type and if it has a canonical
30020/// type, the hash value is going to be the pointer value of the
30021/// canonical type. Otherwise, this function computes a hash value
30022/// for the type by recursively walking the type members. This last
30023/// code path is possibly *very* slow and should only be used when
30024/// only handful of types are going to be hashed.
30025///
30026/// If the artifact is a decl, then a combination of the hash of its
30027/// type and the hash of the other properties of the decl is computed.
30028///
30029/// @param tod the type or decl to hash.
30030///
30031/// @return the resulting hash value.
30032size_t
30034{
30035 hash_t result = 0;
30036
30037 if (tod == 0)
30038 ;
30039 else if (const type_base* t = is_type(tod))
30040 result = hash_type(t);
30041 else if (const decl_base* d = is_decl(tod))
30042 {
30043 if (const scope_decl* s = is_scope_decl(d))
30044 {
30045 if (const global_scope* g = is_global_scope(s))
30046 result = reinterpret_cast<size_t>(g);
30047 else
30048 result = reinterpret_cast<size_t>(s);
30049 }
30050 else if (var_decl* v = is_var_decl(d))
30051 {
30052 ABG_ASSERT(v->get_type());
30053 hash_t h = hash_type_or_decl(v->get_type());
30054 string repr = v->get_pretty_representation(/*internal=*/true);
30055 std::hash<string> hash_string;
30056 h = hashing::combine_hashes(h, hash_string(repr));
30057 result = h;
30058 }
30059 else if (function_decl* f = is_function_decl(d))
30060 {
30061 ABG_ASSERT(f->get_type());
30062 hash_t h = hash_type_or_decl(f->get_type());
30063 string repr = f->get_pretty_representation(/*internal=*/true);
30064 std::hash<string> hash_string;
30065 h = hashing::combine_hashes(h, hash_string(repr));
30066 result = h;
30067 }
30069 {
30070 type_base_sptr parm_type = p->get_type();
30071 ABG_ASSERT(parm_type);
30072 std::hash<bool> hash_bool;
30073 std::hash<unsigned> hash_unsigned;
30074 hash_t h = hash_type_or_decl(parm_type);
30075 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
30076 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
30077 result = h;
30078 }
30079 else if (class_decl::base_spec *bs = is_class_base_spec(d))
30080 {
30081 member_base::hash hash_member;
30082 std::hash<size_t> hash_size;
30083 std::hash<bool> hash_bool;
30084 type_base_sptr type = bs->get_base_class();
30085 hash_t h = hash_type_or_decl(type);
30086 h = hashing::combine_hashes(h, hash_member(*bs));
30087 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
30088 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
30089 result = h;
30090 }
30091 else
30092 // This is a *really* *SLOW* path. If it shows up in a
30093 // performance profile, I bet it'd be a good idea to try to
30094 // avoid it altogether.
30095 // TODO: recode this function or get rid of it altogethe.
30096 abort();
30097 }
30098 else
30099 // We should never get here.
30100 abort();
30101 return *result;
30102}
30103
30104/// Hash an ABI artifact that is a type.
30105///
30106/// This function intends to provides the fastest possible hashing for
30107/// types while being completely correct.
30108///
30109/// Note that if the type artifact has a canonical type, the hash
30110/// value is going to be the pointer value of the canonical type.
30111/// Otherwise, this function computes a hash value for the type by
30112/// recursively walking the type members. This last code path is
30113/// possibly *very* slow and should only be used when only handful of
30114/// types are going to be hashed.
30115///
30116/// @param t the type or decl to hash.
30117///
30118/// @return the resulting hash value.
30119size_t
30121{return hash_as_canonical_type_or_constant(t);}
30122
30123/// Hash an ABI artifact that is either a type of a decl.
30124///
30125/// @param tod the ABI artifact to hash.
30126///
30127/// @return the hash value of the ABI artifact.
30128size_t
30130{return hash_type_or_decl(tod.get());}
30131
30132/// Get the hash value associated to an IR node.
30133///
30134/// Unlike type_or_decl_base::hash_value(), if the IR has no
30135/// associated hash value, an empty hash value is returned.
30136///
30137/// @param artefact the IR node to consider.
30138///
30139/// @return the hash value stored on the IR node or an empty hash if
30140/// no hash value is stored in the @p artefact.
30141hash_t
30143{
30144 const type_or_decl_base* artefactp = &artefact;
30145 if (decl_base *d = is_decl(artefactp))
30146 {
30148 if (d->type_or_decl_base::priv_->get_hashing_state()
30150 return d->type_or_decl_base::priv_->hash_value_;
30151 }
30152 else if (artefact.priv_->get_hashing_state() == hashing::HASHING_FINISHED_STATE)
30153 return artefact.priv_->hash_value_;
30154
30155 return hash_t();
30156}
30157
30158/// Test if a class has at least one member function which has a
30159/// defined and exported symbol.
30160///
30161/// @param klass the class to consider.
30162///
30163/// @return true iff @p klass has at least one member function which
30164/// has a defined and exported symbol.
30165bool
30167{
30168 const type_base * type =
30169 peel_typedef_pointer_or_reference_type(&klass, /*peel_qual_type=*/true);
30170
30171 if (class_decl* klass = is_class_type(type))
30172 for (const auto& mem_fn : klass->get_member_functions())
30174 {
30175 if (mem_fn->get_symbol()
30176 && mem_fn->get_symbol()->is_public()
30177 && mem_fn->get_symbol()->is_defined())
30178 return true;
30179 }
30180
30181 return false;
30182}
30183
30184/// Test if a class has at least one member function which has a
30185/// defined and exported symbol.
30186///
30187/// @param klass the class to consider.
30188///
30189/// @return true iff @p klass has at least one member function which
30190/// has a defined and exported symbol.
30191bool
30193{
30194 if (!klass)
30195 return false;
30196
30197 return has_defined_virtual_mem_fn(*klass);
30198}
30199
30200/// Test if a class has at least one member function which has a
30201/// defined and exported symbol.
30202///
30203/// @param klass the class to consider.
30204///
30205/// @return true iff @p klass has at least one member function which
30206/// has a defined and exported symbol.
30207bool
30210
30211/// Test if a given type is allowed to be non canonicalized
30212///
30213/// This is a subroutine of hash_as_canonical_type_or_constant.
30214///
30215/// At this point in time, all types are now canonicalized. It's not
30216/// always been the case. We try to make things simpler at this
30217/// level. If at some point some types are designed to be
30218/// non-canonicalized, then this function should be made aware of
30219/// them.
30220///
30221/// @return true iff @p t is a one of the only types allowed to be
30222/// non-canonicalized in the system.
30223bool
30225{
30226 if (!t)
30227 return true;
30228
30229 return false;
30230}
30231
30232/// Test if a type is unique in the entire environment.
30233///
30234/// Examples of unique types are void, void* and variadic parameter
30235/// types.
30236///
30237/// @param t the type to test for.
30238///
30239/// @return true iff the type @p t is unique in the entire
30240/// environment.
30241bool
30242is_unique_type(const type_base_sptr& t)
30243{return is_unique_type(t.get());}
30244
30245/// Test if a type is unique in the entire environment.
30246///
30247/// Examples of unique types are void, void* and variadic parameter
30248/// types.
30249///
30250/// @param t the type to test for.
30251///
30252/// @return true iff the type @p t is unique in the entire
30253/// environment.
30254bool
30256{
30257 if (!t)
30258 return false;
30259
30260 const environment& env = t->get_environment();
30261 return (env.is_void_type(t)
30262 || env.is_void_pointer_type(t)
30263 || env.is_variadic_parameter_type(t));
30264}
30265
30266/// For a given type, return its exemplar type.
30267///
30268/// For a given type, its exemplar type is either its canonical type
30269/// or the canonical type of the definition type of a given
30270/// declaration-only type. If the neither of those two types exist,
30271/// then the exemplar type is the given type itself.
30272///
30273/// @param type the input to consider.
30274///
30275/// @return the exemplar type.
30276type_base_sptr
30277get_exemplar_type(type_base_sptr type)
30278{
30279 if (auto decl = is_decl(type))
30280 {
30281 // Make sure we get the real definition of a decl-only type.
30282 decl = look_through_decl_only(decl);
30283 type = is_type(decl);
30284 ABG_ASSERT(type);
30285 }
30286 type_base_sptr exemplar = type ? type->get_canonical_type(): nullptr;
30287 if (!exemplar)
30288 {
30289 // The type has no canonical type. Let's be sure that it's one
30290 // of those rare types that are allowed to be non canonicalized
30291 // in the system.
30292 exemplar = type;
30294 }
30295 return exemplar;
30296}
30297
30298/// For a given type, return its exemplar type.
30299///
30300/// For a given type, its exemplar type is either its canonical type
30301/// or the canonical type of the definition type of a given
30302/// declaration-only type. If the neither of those two types exist,
30303/// then the exemplar type is the given type itself.
30304///
30305/// @param type the input to consider.
30306///
30307/// @return the exemplar type.
30308type_base*
30310{
30311 if (auto decl = is_decl(type))
30312 {
30313 // Make sure we get the real definition of a decl-only type.
30314 decl = look_through_decl_only(decl);
30315 type = is_type(decl);
30316 ABG_ASSERT(type);
30317 }
30318 type_base* exemplar = type ? type->get_naked_canonical_type(): nullptr;
30319 if (!exemplar)
30320 {
30321 // The type has no canonical type. Let's be sure that it's one
30322 // of those rare types that are allowed to be non canonicalized
30323 // in the system.
30324 exemplar = const_cast<type_base*>(type);
30326 }
30327 return exemplar;
30328}
30329
30330/// Test if a given type is allowed to be non canonicalized
30331///
30332/// This is a subroutine of hash_as_canonical_type_or_constant.
30333///
30334/// For now, the only types allowed to be non canonicalized in the
30335/// system are decl-only class/union and the void type.
30336///
30337/// @return true iff @p t is a one of the only types allowed to be
30338/// non-canonicalized in the system.
30339bool
30340is_non_canonicalized_type(const type_base_sptr& t)
30341{return is_non_canonicalized_type(t.get());}
30342
30343/// Hash a type by either returning the pointer value of its canonical
30344/// type or by returning a constant if the type doesn't have a
30345/// canonical type.
30346///
30347/// This is a subroutine of hash_type.
30348///
30349/// @param t the type to consider.
30350///
30351/// @return the hash value.
30352static size_t
30353hash_as_canonical_type_or_constant(const type_base *t)
30354{
30355 type_base *canonical_type = 0;
30356
30357 if (t)
30358 canonical_type = t->get_naked_canonical_type();
30359
30360 if (!canonical_type)
30361 {
30362 // If the type doesn't have a canonical type, maybe it's because
30363 // it's a declaration-only type? If that's the case, let's try
30364 // to get the canonical type of the definition of this
30365 // declaration.
30366 decl_base *decl = is_decl(t);
30367 if (decl
30368 && decl->get_is_declaration_only()
30370 {
30371 type_base *definition =
30373 ABG_ASSERT(definition);
30374 canonical_type = definition->get_naked_canonical_type();
30375 }
30376 }
30377
30378 if (canonical_type)
30379 return reinterpret_cast<size_t>(canonical_type);
30380
30381 // If we reached this point, it means we are seeing a
30382 // non-canonicalized type. It must be a decl-only class or a void
30383 // type, otherwise it means that for some weird reason, the type
30384 // hasn't been canonicalized. It should be!
30386
30387 return 0xDEADBABE;
30388}
30389
30390/// Test if the pretty representation of a given @ref function_decl is
30391/// lexicographically less then the pretty representation of another
30392/// @ref function_decl.
30393///
30394/// @param f the first @ref function_decl to consider for comparison.
30395///
30396/// @param s the second @ref function_decl to consider for comparison.
30397///
30398/// @return true iff the pretty representation of @p f is
30399/// lexicographically less than the pretty representation of @p s.
30400bool
30402{
30405
30406 if (fr != sr)
30407 return fr < sr;
30408
30409 fr = f.get_pretty_representation(/*internal=*/true),
30410 sr = s.get_pretty_representation(/*internal=*/true);
30411
30412 if (fr != sr)
30413 return fr < sr;
30414
30415 if (f.get_symbol())
30416 fr = f.get_symbol()->get_id_string();
30417 else if (!f.get_linkage_name().empty())
30418 fr = f.get_linkage_name();
30419
30420 if (s.get_symbol())
30421 sr = s.get_symbol()->get_id_string();
30422 else if (!s.get_linkage_name().empty())
30423 sr = s.get_linkage_name();
30424
30425 return fr < sr;
30426}
30427
30428/// Test if two types have similar structures, even though they are
30429/// (or can be) different.
30430///
30431/// const and volatile qualifiers are completely ignored.
30432///
30433/// typedef are resolved to their definitions; their names are ignored.
30434///
30435/// Two indirect types (pointers or references) have similar structure
30436/// if their underlying types are of the same kind and have the same
30437/// name. In the indirect types case, the size of the underlying type
30438/// does not matter.
30439///
30440/// Two direct types (i.e, non indirect) have a similar structure if
30441/// they have the same kind, name and size. Two class types have
30442/// similar structure if they have the same name, size, and if the
30443/// types of their data members have similar types.
30444///
30445/// @param first the first type to consider.
30446///
30447/// @param second the second type to consider.
30448///
30449/// @param indirect_type whether to do an indirect comparison
30450///
30451/// @return true iff @p first and @p second have similar structures.
30452bool
30453types_have_similar_structure(const type_base_sptr& first,
30454 const type_base_sptr& second,
30455 bool indirect_type)
30456{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
30457
30458/// Test if two types have similar structures, even though they are
30459/// (or can be) different.
30460///
30461/// const and volatile qualifiers are completely ignored.
30462///
30463/// typedef are resolved to their definitions; their names are ignored.
30464///
30465/// Two indirect types (pointers, references or arrays) have similar
30466/// structure if their underlying types are of the same kind and have
30467/// the same name. In the indirect types case, the size of the
30468/// underlying type does not matter.
30469///
30470/// Two direct types (i.e, non indirect) have a similar structure if
30471/// they have the same kind, name and size. Two class types have
30472/// similar structure if they have the same name, size, and if the
30473/// types of their data members have similar types.
30474///
30475/// @param first the first type to consider.
30476///
30477/// @param second the second type to consider.
30478///
30479/// @param indirect_type if true, then consider @p first and @p
30480/// second as being underlying types of indirect types. Meaning that
30481/// their size does not matter.
30482///
30483/// @return true iff @p first and @p second have similar structures.
30484bool
30486 const type_base* second,
30487 bool indirect_type)
30488{
30489 if (!!first != !!second)
30490 return false;
30491
30492 if (!first)
30493 return false;
30494
30495 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
30496 first = peel_qualified_or_typedef_type(first);
30497 second = peel_qualified_or_typedef_type(second);
30498
30499 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
30500 // various ty2 below cannot be null.
30501 if (typeid(*first) != typeid(*second))
30502 return false;
30503
30504 // Peel off matching pointers.
30505 if (const pointer_type_def* ty1 = is_pointer_type(first))
30506 {
30507 const pointer_type_def* ty2 = is_pointer_type(second);
30508 return types_have_similar_structure(ty1->get_pointed_to_type(),
30509 ty2->get_pointed_to_type(),
30510 /*indirect_type=*/true);
30511 }
30512
30513 // Peel off matching references.
30514 if (const reference_type_def* ty1 = is_reference_type(first))
30515 {
30516 const reference_type_def* ty2 = is_reference_type(second);
30517 if (ty1->is_lvalue() != ty2->is_lvalue())
30518 return false;
30519 return types_have_similar_structure(ty1->get_pointed_to_type(),
30520 ty2->get_pointed_to_type(),
30521 /*indirect_type=*/true);
30522 }
30523
30524 // Peel off matching pointer-to-member types.
30525 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
30526 {
30527 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
30528 return (types_have_similar_structure(ty1->get_member_type(),
30529 ty2->get_member_type(),
30530 /*indirect_type=*/true)
30531 && types_have_similar_structure(ty1->get_containing_type(),
30532 ty2->get_containing_type(),
30533 /*indirect_type=*/true));
30534 }
30535
30536 if (const type_decl* ty1 = is_type_decl(first))
30537 {
30538 const type_decl* ty2 = is_type_decl(second);
30539 if (!indirect_type)
30540 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
30541 return false;
30542
30543 return ty1->get_name() == ty2->get_name();
30544 }
30545
30546 if (const enum_type_decl* ty1 = is_enum_type(first))
30547 {
30548 const enum_type_decl* ty2 = is_enum_type(second);
30549 if (!indirect_type)
30550 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
30551 return false;
30552
30553 return (get_name(ty1->get_underlying_type())
30554 == get_name(ty2->get_underlying_type()));
30555 }
30556
30557 if (const class_decl* ty1 = is_class_type(first))
30558 {
30559 const class_decl* ty2 = is_class_type(second);
30560 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
30561 && ty1->get_name() != ty2->get_name())
30562 return false;
30563
30564 if (!indirect_type)
30565 {
30566 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
30567 || (ty1->get_non_static_data_members().size()
30568 != ty2->get_non_static_data_members().size()))
30569 return false;
30570
30571 for (class_or_union::data_members::const_iterator
30572 i = ty1->get_non_static_data_members().begin(),
30573 j = ty2->get_non_static_data_members().begin();
30574 (i != ty1->get_non_static_data_members().end()
30575 && j != ty2->get_non_static_data_members().end());
30576 ++i, ++j)
30577 {
30578 var_decl_sptr dm1 = *i;
30579 var_decl_sptr dm2 = *j;
30580 if (!types_have_similar_structure(dm1->get_type().get(),
30581 dm2->get_type().get(),
30582 indirect_type))
30583 return false;
30584 }
30585 }
30586
30587 return true;
30588 }
30589
30590 if (const union_decl* ty1 = is_union_type(first))
30591 {
30592 const union_decl* ty2 = is_union_type(second);
30593 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
30594 && ty1->get_name() != ty2->get_name())
30595 return false;
30596
30597 if (!indirect_type)
30598 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
30599
30600 return true;
30601 }
30602
30603 if (const array_type_def* ty1 = is_array_type(first))
30604 {
30605 const array_type_def* ty2 = is_array_type(second);
30606 if (!indirect_type)
30607 {
30608 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
30609 || ty1->get_dimension_count() != ty2->get_dimension_count())
30610 return false;
30611
30612 // Handle int[5][2] vs int[2][5] ...
30613 //
30614 // 6.2.5/20 of
30615 // https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
30616 // says:
30617 //
30618 // "Array types are characterized by their element
30619 // type and by the number of elements in the array"
30620 //
30621 // and 6.5.2.1/3 says:
30622 //
30623 // "arrays are stored in row-major order (last subscript
30624 // varies fastest)."
30625 //
30626 // So, let's ensure that all dimensions (sub-ranges) have
30627 // the same length.
30628
30629 for (auto r1 = ty1->get_subranges().begin(),
30630 r2 = ty1->get_subranges().begin();
30631 (r1 != ty1->get_subranges().end()
30632 && r2 != ty2->get_subranges().end());
30633 ++r1, ++r2)
30634 if ((*r1)->get_length() != (*r2)->get_length())
30635 return false;
30636 }
30637
30638 // ... then compare the elements of the arrays.
30639 if (!types_have_similar_structure(ty1->get_element_type(),
30640 ty2->get_element_type(),
30641 /*indirect_type=*/true))
30642 return false;
30643
30644 return true;
30645 }
30646
30647 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
30648 {
30650 if (ty1->get_upper_bound() != ty2->get_upper_bound()
30651 || ty1->get_lower_bound() != ty2->get_lower_bound()
30652 || ty1->get_language() != ty2->get_language()
30653 || !types_have_similar_structure(ty1->get_underlying_type(),
30654 ty2->get_underlying_type(),
30655 indirect_type))
30656 return false;
30657
30658 return true;
30659 }
30660
30661 if (const function_type* ty1 = is_function_type(first))
30662 {
30663 const function_type* ty2 = is_function_type(second);
30664 if (!types_have_similar_structure(ty1->get_return_type(),
30665 ty2->get_return_type(),
30666 indirect_type))
30667 return false;
30668
30669 if (ty1->get_parameters().size() != ty2->get_parameters().size())
30670 return false;
30671
30672 for (function_type::parameters::const_iterator
30673 i = ty1->get_parameters().begin(),
30674 j = ty2->get_parameters().begin();
30675 (i != ty1->get_parameters().end()
30676 && j != ty2->get_parameters().end());
30677 ++i, ++j)
30678 if (!types_have_similar_structure((*i)->get_type(),
30679 (*j)->get_type(),
30680 indirect_type))
30681 return false;
30682
30683 return true;
30684 }
30685
30686 // All kinds of type should have been handled at this point.
30688
30689 return false;
30690}
30691
30692/// Look for a data member of a given class, struct or union type and
30693/// return it.
30694///
30695/// The data member is designated by its name.
30696///
30697/// @param type the class, struct or union type to consider.
30698///
30699/// @param dm_name the name of the data member to lookup.
30700///
30701/// @return the data member iff it was found in @type or NULL if no
30702/// data member with that name was found.
30703const var_decl*
30705 const char* dm_name)
30706
30707{
30709 if (!cou)
30710 return 0;
30711
30712 return cou->find_data_member(dm_name).get();
30713}
30714
30715/// Look for a data member of a given class, struct or union type and
30716/// return it.
30717///
30718/// The data member is designated by its name.
30719///
30720/// @param type the class, struct or union type to consider.
30721///
30722/// @param dm the data member to lookup.
30723///
30724/// @return the data member iff it was found in @type or NULL if no
30725/// data member with that name was found.
30726const var_decl_sptr
30727lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
30728{
30729 class_or_union_sptr cou = is_class_or_union_type(type);
30730 if (!cou)
30731 return var_decl_sptr();
30732
30733 return cou->find_data_member(dm);
30734}
30735
30736/// Get the function parameter designated by its index.
30737///
30738/// Note that the first function parameter has index 0.
30739///
30740/// @param fun the function to consider.
30741///
30742/// @param parm_index the index of the function parameter to get.
30743///
30744/// @return the function parameter designated by its index, of NULL if
30745/// no function parameter with that index was found.
30748 unsigned parm_index)
30749{
30751 if (!fn)
30752 return 0;
30753
30754 const function_decl::parameters &parms = fn->get_type()->get_parameters();
30755 if (parms.size() <= parm_index)
30756 return 0;
30757
30758 return parms[parm_index].get();
30759}
30760
30761/// Build the internal name of the underlying type of an enum.
30762///
30763/// @param base_name the (unqualified) name of the enum the underlying
30764/// type is destined to.
30765///
30766/// @param is_anonymous true if the underlying type of the enum is to
30767/// be anonymous.
30768string
30770 bool is_anonymous,
30771 uint64_t size)
30772{
30773 std::ostringstream o;
30774
30775 if (is_anonymous)
30776 o << "unnamed-enum";
30777 else
30778 o << "enum-" << base_name;
30779
30780 o << "-underlying-type-" << size;
30781
30782 return o.str();
30783}
30784
30785/// Find the first data member of a class or union which name matches
30786/// a regular expression.
30787///
30788/// @param t the class or union to consider.
30789///
30790/// @param r the regular expression to consider.
30791///
30792/// @return the data member matched by @p r or nil if none was found.
30795 const regex::regex_t_sptr& r)
30796{
30797 for (auto data_member : t.get_data_members())
30798 {
30799 if (regex::match(r, data_member->get_name()))
30800 return data_member;
30801 }
30802
30803 return var_decl_sptr();
30804}
30805
30806/// Find the last data member of a class or union which name matches
30807/// a regular expression.
30808///
30809/// @param t the class or union to consider.
30810///
30811/// @param r the regular expression to consider.
30812///
30813/// @return the data member matched by @p r or nil if none was found.
30816 const regex::regex_t_sptr& regex)
30817{
30818 auto d = t.get_data_members().rbegin();
30819 auto e = t.get_data_members().rend();
30820 for (; d != e; ++d)
30821 {
30822 if (regex::match(regex, (*d)->get_name()))
30823 return *d;
30824 }
30825
30826 return var_decl_sptr();
30827}
30828
30829/// Emit the pretty representation of the parameters of a function
30830/// type.
30831///
30832/// @param fn_type the function type to consider.
30833///
30834/// @param o the output stream to emit the pretty representation to.
30835///
30836/// @param qualified if true, emit fully qualified names.
30837///
30838/// @param internal if true, then the result is to be used for the
30839/// purpose of type canonicalization.
30840static void
30841stream_pretty_representation_of_fn_parms(const function_type& fn_type,
30842 ostream& o, bool qualified,
30843 bool internal)
30844{
30845 bool parms_empty = false;
30846 {
30847 lock_guard<recursive_mutex> lock(fn_type.get_mutex());
30848 parms_empty = fn_type.get_parameters().empty();
30849 }
30850
30851 o << "(";
30852 if (parms_empty)
30853 o << "void";
30854 else
30855 {
30856 type_base_sptr type;
30857 function_decl::parameters::const_iterator first_parm, end;
30858 {
30859 lock_guard<recursive_mutex> lock(fn_type.get_mutex());
30860 end = fn_type.get_parameters().end();
30861 first_parm = fn_type.get_first_non_artificial_parm();
30862 }
30864 const environment& env = fn_type.get_environment();
30865 for (auto i = first_parm; i != end; ++i)
30866 {
30867 if (i != first_parm)
30868 o << ", ";
30869 parm = *i;
30870 type = parm->get_type();
30871 // If the type is a decl-only class, union or enum that has a
30872 // definition, use the definition instead. That definition
30873 // is what is going to be serialized out in ABIXML anyway,
30874 // so use that for consistency.
30875 if (decl_base_sptr def = look_through_decl_only(is_decl(type)))
30876 type = is_type(def);
30877 if (env.is_variadic_parameter_type(type))
30878 o << "...";
30879 else
30880 o << get_type_name(type, qualified, internal);
30881 }
30882 }
30883 o << ")";
30884}
30885
30886/// When constructing the name of a pointer to function type, add the
30887/// return type to the left of the existing type identifier, and the
30888/// parameters declarator to the right.
30889///
30890/// This function considers the name of the type as an expression.
30891///
30892/// The resulting type expr is going to be made of three parts:
30893/// left_expr inner_expr right_expr.
30894///
30895/// Suppose we want to build the type expression representing:
30896///
30897/// "an array of pointer to function taking a char parameter and
30898/// returning an int".
30899///
30900/// It's going to look like:
30901///
30902/// int(*a[])(char);
30903///
30904/// Suppose the caller of this function started to emit the inner
30905/// "a[]" part of the expression already. It thus calls this
30906/// function with that input "a[]" part. We consider that "a[]" as
30907/// the "type identifier".
30908///
30909/// So the inner_expr is going to be "(*a[])".
30910///
30911/// The left_expr part is "int". The right_expr part is "(char)".
30912///
30913/// In other words, this function adds the left_expr and right_expr to
30914/// the inner_expr. left_expr and right_expr are called "outer
30915/// pointer to function type expression".
30916///
30917/// This is a sub-routine of @ref pointer_declaration_name() and @ref
30918/// array_declaration_name()
30919///
30920/// @param p the pointer to function type to consider.
30921///
30922/// @param input the type-id to use as the inner expression of the
30923/// overall pointer-to-function type expression
30924///
30925/// @param qualified if true then use qualified names in the resulting
30926/// type name.
30927///
30928/// @param internal if true then the resulting type name is going to
30929/// be used for type canonicalization purposes.
30930///
30931/// @return the name of the pointer to function type.
30932static string
30933add_outer_pointer_to_fn_type_expr(const type_base* p,
30934 const string& input,
30935 bool qualified, bool internal)
30936{
30937 if (!p)
30938 return "";
30939
30940 function_type_sptr pointed_to_fn;
30941 string star_or_ref;
30942
30943 if (const pointer_type_def* ptr = is_pointer_type(p))
30944 {
30945 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
30946 star_or_ref= "*";
30947 }
30948 else if (const reference_type_def* ref = is_reference_type(p))
30949 {
30950 star_or_ref = "&";
30951 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
30952 }
30953
30954 if (!pointed_to_fn)
30955 return "";
30956
30957 if (function_type::priv::is_pretty_printing(pointed_to_fn.get()))
30958 // We have just detected a cycle while walking the sub-tree of
30959 // this function type for the purpose of printing its
30960 // representation. We need to get out of here pronto or else
30961 // we'll be spinning endlessly.
30962 return "";
30963
30964 // Let's mark thie function type to signify that we started walking
30965 // its subtree. This is to detect potential cycles and avoid
30966 // looping endlessly.
30968
30969 std::ostringstream left, right, inner;
30970
30971 inner << "(" << star_or_ref << input << ")";
30972
30973 type_base_sptr type;
30974 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
30975 qualified, internal);
30976
30977 type_base_sptr return_type = pointed_to_fn->get_return_type();
30978 string result;
30979
30980 if (is_npaf_type(return_type)
30981 || !(is_pointer_to_function_type(return_type)
30982 || is_pointer_to_array_type(return_type)))
30983 {
30984 if (return_type)
30985 left << get_type_name(return_type, qualified, internal);
30986 result = left.str() + " " + inner.str() + right.str();
30987 }
30988 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
30989 {
30990 string inner_string = inner.str() + right.str();
30991 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
30992 qualified, internal);
30993 }
30994 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
30995 {
30996 string inner_string = inner.str() + right.str();
30997 result = add_outer_pointer_to_array_type_expr(p, inner_string,
30998 qualified, internal);
30999 }
31000 else
31002
31003 // Lets unmark this function type to signify that we are done
31004 // walking its subtree. This was to detect potential cycles and
31005 // avoid looping endlessly.
31007 return result;
31008}
31009
31010/// When constructing the name of a pointer to function type, add the
31011/// return type to the left of the existing type identifier, and the
31012/// parameters declarator to the right.
31013///
31014/// This function considers the name of the type as an expression.
31015///
31016/// The resulting type expr is going to be made of three parts:
31017/// left_expr inner_expr right_expr.
31018///
31019/// Suppose we want to build the type expression representing:
31020///
31021/// "an array of pointer to function taking a char parameter and
31022/// returning an int".
31023///
31024/// It's going to look like:
31025///
31026/// int(*a[])(char);
31027///
31028/// Suppose the caller of this function started to emit the inner
31029/// "a[]" part of the expression already. It thus calls this
31030/// function with that input "a[]" part. We consider that "a[]" as
31031/// the "type identifier".
31032///
31033/// So the inner_expr is going to be "(*a[])".
31034///
31035/// The left_expr part is "int". The right_expr part is "(char)".
31036///
31037/// In other words, this function adds the left_expr and right_expr to
31038/// the inner_expr. left_expr and right_expr are called "outer
31039/// pointer to function type expression".
31040///
31041/// This is a sub-routine of @ref pointer_declaration_name() and @ref
31042/// array_declaration_name()
31043///
31044/// @param p the pointer to function type to consider.
31045///
31046/// @param input the type-id to use as the inner expression of the
31047/// overall pointer-to-function type expression
31048///
31049/// @param qualified if true then use qualified names in the resulting
31050/// type name.
31051///
31052/// @param internal if true then the resulting type name is going to
31053/// be used for type canonicalization purposes.
31054///
31055/// @return the name of the pointer to function type.
31056static string
31057add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
31058 const string& input,
31059 bool qualified, bool internal)
31060{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
31061
31062/// When constructing the name of a pointer to array type, add the
31063/// array element type type to the left of the existing type
31064/// identifier, and the array declarator part to the right.
31065///
31066/// This function considers the name of the type as an expression.
31067///
31068/// The resulting type expr is going to be made of three parts:
31069/// left_expr inner_expr right_expr.
31070///
31071/// Suppose we want to build the type expression representing:
31072///
31073/// "a pointer to an array of int".
31074///
31075/// It's going to look like:
31076///
31077/// int(*foo)[];
31078///
31079/// Suppose the caller of this function started to emit the inner
31080/// "foo" part of the expression already. It thus calls this function
31081/// with that input "foo" part. We consider that "foo" as the "type
31082/// identifier".
31083///
31084/// So we are passed an input string that is "foo" and it's going to
31085/// be turned into the inner_expr part, which is going to be "(*foo)".
31086///
31087/// The left_expr part is "int". The right_expr part is "[]".
31088///
31089/// In other words, this function adds the left_expr and right_expr to
31090/// the inner_expr. left_expr and right_expr are called "outer
31091/// pointer to array type expression".
31092///
31093/// The model of this function was taken from the article "Reading C
31094/// type declaration", from Steve Friedl at
31095/// http://unixwiz.net/techtips/reading-cdecl.html.
31096///
31097/// This is a sub-routine of @ref pointer_declaration_name() and @ref
31098/// array_declaration_name()
31099///
31100/// @param p the pointer to array type to consider.
31101///
31102/// @param input the type-id to start from as the inner part of the
31103/// final type name.
31104///
31105/// @param qualified if true then use qualified names in the resulting
31106/// type name.
31107///
31108/// @param internal if true then the resulting type name is going to
31109/// be used for type canonicalization purposes.
31110///
31111/// @return the name of the pointer to array type.
31112static string
31113add_outer_pointer_to_array_type_expr(const type_base* p,
31114 const string& input, bool qualified,
31115 bool internal)
31116{
31117 if (!p)
31118 return "";
31119
31120 string star_or_ref;
31121 type_base_sptr pointed_to_type;
31122
31123 if (const pointer_type_def *ptr = is_pointer_type(p))
31124 {
31125 pointed_to_type = ptr->get_pointed_to_type();
31126 star_or_ref = "*";
31127 }
31128 else if (const reference_type_def *ref = is_reference_type(p))
31129 {
31130 pointed_to_type = ref->get_pointed_to_type();
31131 star_or_ref = "&";
31132 }
31133
31134 array_type_def_sptr array = is_array_type(pointed_to_type);
31135 if (!array)
31136 return "";
31137
31138 std::ostringstream left, right, inner;
31139 inner << "(" << star_or_ref << input << ")";
31140 right << array->get_subrange_representation();
31141 string result;
31142
31143 type_base_sptr array_element_type = array->get_element_type();
31144
31145 if (is_npaf_type(array_element_type)
31146 || !(is_pointer_to_function_type(array_element_type)
31147 || is_pointer_to_array_type(array_element_type)))
31148 {
31149 left << get_type_name(array_element_type, qualified, internal);
31150 result = left.str() + inner.str() + right.str();
31151 }
31152 else if (pointer_type_def_sptr p =
31153 is_pointer_to_function_type(array_element_type))
31154 {
31155 string r = inner.str() + right.str();
31156 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
31157 }
31158 else if (pointer_type_def_sptr p =
31159 is_pointer_to_array_type(array_element_type))
31160 {
31161 string inner_string = inner.str() + right.str();
31162 result = add_outer_pointer_to_array_type_expr(p, inner_string,
31163 qualified, internal);
31164 }
31165 else
31167
31168 return result;
31169}
31170
31171/// When constructing the name of a pointer to array type, add the
31172/// array element type type to the left of the existing type
31173/// identifier, and the array declarator part to the right.
31174///
31175/// This function considers the name of the type as an expression.
31176///
31177/// The resulting type expr is going to be made of three parts:
31178/// left_expr inner_expr right_expr.
31179///
31180/// Suppose we want to build the type expression representing:
31181///
31182/// "a pointer to an array of int".
31183///
31184/// It's going to look like:
31185///
31186/// int(*foo)[];
31187///
31188/// Suppose the caller of this function started to emit the inner
31189/// "foo" part of the expression already. It thus calls this function
31190/// with that input "foo" part. We consider that "foo" as the "type
31191/// identifier".
31192///
31193/// So we are passed an input string that is "foo" and it's going to
31194/// be turned into the inner_expr part, which is going to be "(*foo)".
31195///
31196/// The left_expr part is "int". The right_expr part is "[]".
31197///
31198/// In other words, this function adds the left_expr and right_expr to
31199/// the inner_expr. left_expr and right_expr are called "outer
31200/// pointer to array type expression".
31201///
31202/// The model of this function was taken from the article "Reading C
31203/// type declaration", from Steve Friedl at
31204/// http://unixwiz.net/techtips/reading-cdecl.html.
31205///
31206/// This is a sub-routine of @ref pointer_declaration_name() and @ref
31207/// array_declaration_name()
31208///
31209/// @param p the pointer to array type to consider.
31210///
31211/// @param input the type-id to start from as the inner part of the
31212/// final type name.
31213///
31214/// @param qualified if true then use qualified names in the resulting
31215/// type name.
31216///
31217/// @param internal if true then the resulting type name is going to
31218/// be used for type canonicalization purposes.
31219///
31220/// @return the name of the pointer to array type.
31221static string
31222add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
31223 const string& input, bool qualified,
31224 bool internal)
31225{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
31226 input, qualified, internal);}
31227
31228/// When constructing the name of a pointer to mebmer type, add the
31229/// return type to the left of the existing type identifier, and the
31230/// parameters declarator to the right.
31231///
31232/// This function considers the name of the type as an expression.
31233///
31234/// The resulting type expr is going to be made of three parts:
31235/// left_expr inner_expr right_expr.
31236///
31237/// Suppose we want to build the type expression representing:
31238///
31239/// "an array of pointer to member function (of a containing struct
31240/// X) taking a char parameter and returning an int".
31241///
31242/// It's going to look like:
31243///
31244/// int (X::* a[])(char);
31245///
31246/// Suppose the caller of this function started to emit the inner
31247/// "a[]" part of the expression already. It thus calls this
31248/// function with that input "a[]" part. We consider that "a[]" as
31249/// the "type identifier".
31250///
31251/// So the inner_expr is going to be "(X::* a[])".
31252///
31253/// The left_expr part is "int". The right_expr part is "(char)".
31254///
31255/// In other words, this function adds the left_expr and right_expr to
31256/// the inner_expr. left_expr and right_expr are called "outer
31257/// pointer to member type expression".
31258///
31259/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
31260///
31261/// @param p the pointer to member type to consider.
31262///
31263/// @param input the type-id to use as the inner expression of the
31264/// overall pointer-to-member type expression
31265///
31266/// @param qualified if true then use qualified names in the resulting
31267/// type name.
31268///
31269/// @param internal if true then the resulting type name is going to
31270/// be used for type canonicalization purposes.
31271///
31272/// @return the name of the pointer to member type.
31273static string
31274add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
31275 const string& input, bool qualified,
31276 bool internal)
31277{
31278 if (!p)
31279 return "";
31280
31281 std::ostringstream left, right, inner;
31282 type_base_sptr void_type = p->get_environment().get_void_type();
31283 string containing_type_name = get_type_name(p->get_containing_type(),
31284 qualified, internal);
31285 type_base_sptr mbr_type = p->get_member_type();
31286 string result;
31287 if (function_type_sptr fn_type = is_function_type(mbr_type))
31288 {
31289 inner << "(" << containing_type_name << "::*" << input << ")";
31290 stream_pretty_representation_of_fn_parms(*fn_type, right,
31291 qualified, internal);
31292 type_base_sptr return_type = fn_type->get_return_type();
31293 if (!return_type)
31294 return_type = void_type;
31295 if (is_npaf_type(return_type)
31296 || !(is_pointer_to_function_type(return_type)
31297 || is_pointer_to_array_type(return_type)
31298 || is_pointer_to_ptr_to_mbr_type(return_type)
31299 || is_ptr_to_mbr_type(return_type)))
31300 {
31301 left << get_type_name(return_type, qualified, internal) << " ";;
31302 result = left.str() + inner.str() + right.str();
31303 }
31304 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
31305 {
31306 string inner_str = inner.str() + right.str();
31307 result = pointer_declaration_name(p, inner_str, qualified, internal);
31308 }
31309 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
31310 {
31311 string inner_str = inner.str() + right.str();
31312 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
31313 qualified, internal);
31314 }
31315 else
31317 }
31318 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
31319 {
31320 inner << "(" << containing_type_name << "::*" << input << ")";
31321 stream_pretty_representation_of_fn_parms(*fn_type, right,
31322 qualified, internal);
31323 string inner_str = inner.str() + right.str();
31324 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
31325 qualified, internal);
31326 }
31327 else
31328 {
31329 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
31330 inner << containing_type_name << "::*" << input;
31331 result = left.str()+ inner.str();
31332 }
31333
31334 return result;
31335}
31336
31337/// Test if two decls have different names.
31338///
31339/// Note that this function takes into account decls whose names are
31340/// relevant from an ABI standpoint. For instance, function parameter
31341/// names are not relevant in that context.
31342///
31343/// @param d1 the first declaration to consider.
31344///
31345/// @param d2 the second declaration to consider.
31346///
31347/// @return true if d1 and d2 have different names.
31348bool
31350{
31351 string d1_name, d2_name;
31352
31353 const decl_base *d1 = dynamic_cast<const decl_base*>(a1);
31354 if (d1 == 0)
31355 return false;
31356
31357 const decl_base *d2 = dynamic_cast<const decl_base*>(a2);
31358 if (d2 == 0)
31359 return false;
31360
31362 // Name changes for fn parms are irrelevant.
31363 return false;
31364
31365 d1_name = d1->get_qualified_name();
31366 d2_name = d2->get_qualified_name();
31367
31368 return d1_name != d2_name;
31369}
31370
31371/// Test if two decls have different names.
31372///
31373/// @param d1 the first declaration to consider.
31374///
31375/// @param d2 the second declaration to consider.
31376///
31377/// @return true if d1 and d2 have different names.
31378bool
31380 const type_or_decl_base_sptr& d2)
31381{return decl_name_changed(d1.get(), d2.get());}
31382
31383/// Test if a diff node carries a change whereby two integral types
31384/// have different names in a harmless way.
31385///
31386/// Basically, if the integral type name change is accompanied by a
31387/// size change then the change is considered harmful. If there are
31388/// modifiers change, the change is considered harmful.
31389bool
31391 const type_base_sptr& s)
31392{
31393 if (is_decl(f)
31394 && is_decl(s)
31395 && ((is_integral_type(f) && is_integral_type(s))
31396 || (is_decl(f)->get_name().empty()
31397 && is_type_decl(f)
31398 && is_integral_type(s))
31399 || (is_decl(s)->get_name().empty()
31400 && is_type_decl(s)
31401 && is_integral_type(f)))
31403 && (f->get_size_in_bits() == s->get_size_in_bits())
31404 && (f->get_alignment_in_bits() == s->get_alignment_in_bits()))
31405 return true;
31406
31407 return false;
31408}
31409
31410/// Test if a diff node carries a change whereby two integral types
31411/// have different names in a harmless way.
31412///
31413/// Basically, if the integral type name change is accompanied by a
31414/// size change then the change is considered harmful. If there are
31415/// modifiers change, the change is considered harmful.
31416bool
31418 const decl_base_sptr& s)
31420
31421
31422/// When constructing the name of a pointer to mebmer type, add the
31423/// return type to the left of the existing type identifier, and the
31424/// parameters declarator to the right.
31425///
31426/// This function considers the name of the type as an expression.
31427///
31428/// The resulting type expr is going to be made of three parts:
31429/// left_expr inner_expr right_expr.
31430///
31431/// Suppose we want to build the type expression representing:
31432///
31433/// "an array of pointer to member function (of a containing struct
31434/// X) taking a char parameter and returning an int".
31435///
31436/// It's going to look like:
31437///
31438/// int (X::* a[])(char);
31439///
31440/// Suppose the caller of this function started to emit the inner
31441/// "a[]" part of the expression already. It thus calls this
31442/// function with that input "a[]" part. We consider that "a[]" as
31443/// the "type identifier".
31444///
31445/// So the inner_expr is going to be "(X::* a[])".
31446///
31447/// The left_expr part is "int". The right_expr part is "(char)".
31448///
31449/// In other words, this function adds the left_expr and right_expr to
31450/// the inner_expr. left_expr and right_expr are called "outer
31451/// pointer to member type expression".
31452///
31453/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
31454///
31455/// @param p the pointer to member type to consider.
31456///
31457/// @param input the type-id to use as the inner expression of the
31458/// overall pointer-to-member type expression
31459///
31460/// @param qualified if true then use qualified names in the resulting
31461/// type name.
31462///
31463/// @param internal if true then the resulting type name is going to
31464/// be used for type canonicalization purposes.
31465///
31466/// @return the name of the pointer to member type.
31467static string
31468add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
31469 const string& input, bool qualified,
31470 bool internal)
31471{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
31472
31473/// This adds the outer parts of a pointer to a pointer-to-member
31474/// expression.
31475///
31476/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
31477/// learn more about this function, which is similar.
31478///
31479/// This is a sub-routine of @ref pointer_declaration_name().
31480///
31481/// @param a pointer (or reference) to a pointer-to-member type.
31482///
31483/// @param input the inner type-id to add the outer parts to.
31484///
31485/// @param qualified if true then use qualified names in the resulting
31486/// type name.
31487///
31488/// @param internal if true then the resulting type name is going to
31489/// be used for type canonicalization purposes.
31490static string
31491add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
31492 const string& input, bool qualified,
31493 bool internal)
31494{
31495 if (!p)
31496 return "";
31497
31498 string star_or_ref;
31499 type_base_sptr pointed_to_type;
31500
31501 if (const pointer_type_def* ptr = is_pointer_type(p))
31502 {
31503 pointed_to_type = ptr->get_pointed_to_type();
31504 star_or_ref = "*";
31505 }
31506 else if (const reference_type_def* ref = is_reference_type(p))
31507 {
31508 pointed_to_type= ref->get_pointed_to_type();
31509 star_or_ref = "&";
31510 }
31511
31512 if (!pointed_to_type)
31513 return "";
31514
31515 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
31516 is_ptr_to_mbr_type(pointed_to_type);
31517 if (!pointed_to_ptr_to_mbr)
31518 return "";
31519
31520 std::ostringstream inner;
31521 inner << star_or_ref << input;
31522 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
31523 inner.str(),
31524 qualified, internal);
31525 return result;
31526}
31527
31528/// Emit the name of a pointer declaration.
31529///
31530/// @param the pointer to consider.
31531///
31532/// @param idname the name of the variable that has @p as a type or
31533/// the id of the type. If it's empty then the resulting name is
31534/// going to be the abstract name of the type.
31535///
31536/// @param qualified if true then the type name is going to be
31537/// fully qualified.
31538///
31539/// @param internal if true then the type name is going to be used for
31540/// type canonicalization purposes.
31541static interned_string
31542pointer_declaration_name(const type_base* ptr,
31543 const string& idname,
31544 bool qualified, bool internal)
31545{
31546 if (!ptr)
31547 return interned_string();
31548
31549 type_base_sptr pointed_to_type;
31550 string star_or_ref;
31551 if (const pointer_type_def* p = is_pointer_type(ptr))
31552 {
31553 pointed_to_type = p->get_pointed_to_type();
31554 star_or_ref = "*";
31555 }
31556 else if (const reference_type_def* p = is_reference_type(ptr))
31557 {
31558 pointed_to_type = p->get_pointed_to_type();
31559 star_or_ref = "&";
31560 }
31561
31562 if (!pointed_to_type)
31563 return interned_string();
31564
31565 string result;
31566 if (is_npaf_type(pointed_to_type)
31567 || !(is_function_type(pointed_to_type)
31568 || is_array_type(pointed_to_type)
31569 || is_ptr_to_mbr_type(pointed_to_type)))
31570 {
31571 result = get_type_name(pointed_to_type,
31572 qualified,
31573 internal)
31574 + star_or_ref;
31575
31576 if (!idname.empty())
31577 result += idname;
31578 }
31579 else
31580 {
31581 // derived type
31582 if (is_function_type(pointed_to_type))
31583 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
31584 qualified, internal);
31585 else if (is_array_type(pointed_to_type))
31586 result = add_outer_pointer_to_array_type_expr(ptr, idname,
31587 qualified, internal);
31588 else if (is_ptr_to_mbr_type(pointed_to_type))
31589 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
31590 qualified, internal);
31591 else
31593 }
31594 return ptr->get_environment().intern(result);
31595}
31596
31597
31598/// Emit the name of a pointer declaration.
31599///
31600/// @param the pointer to consider.
31601///
31602/// @param the name of the variable that has @p as a type. If it's
31603/// empty then the resulting name is going to be the abstract name of
31604/// the type.
31605///
31606/// @param qualified if true then the type name is going to be
31607/// fully qualified.
31608///
31609/// @param internal if true then the type name is going to be used for
31610/// type canonicalization purposes.
31611static interned_string
31612pointer_declaration_name(const type_base_sptr& ptr,
31613 const string& variable_name,
31614 bool qualified, bool internal)
31615{return pointer_declaration_name(ptr.get(), variable_name,
31616 qualified, internal);}
31617
31618/// Emit the name of a array declaration.
31619///
31620/// @param the array to consider.
31621///
31622/// @param the name of the variable that has @p as a type. If it's
31623/// empty then the resulting name is going to be the abstract name of
31624/// the type.
31625///
31626/// @param qualified if true then the type name is going to be
31627/// fully qualified.
31628///
31629/// @param internal if true then the type name is going to be used for
31630/// type canonicalization purposes.
31631static interned_string
31632array_declaration_name(const array_type_def* array,
31633 const string& variable_name,
31634 bool qualified, bool internal)
31635{
31636 if (!array)
31637 return interned_string();
31638
31639 type_base_sptr e_type = array->get_element_type();
31640 string e_type_repr =
31641 (e_type
31642 ? get_type_name(e_type, qualified, internal)
31643 : string("void"));
31644
31645 string result;
31646 if (is_ada_language(array->get_language()))
31647 {
31648 std::ostringstream o;
31649 if (!variable_name.empty())
31650 o << variable_name << " is ";
31651 o << "array ("
31652 << array->get_subrange_representation()
31653 << ") of " << e_type_repr;
31654 result = o.str();
31655 }
31656 else
31657 {
31658 if (is_npaf_type(e_type)
31659 || !(is_pointer_to_function_type(e_type)
31660 || is_pointer_to_array_type(e_type)
31662 || is_ptr_to_mbr_type(e_type)))
31663 {
31664 result = e_type_repr;
31665 if (!variable_name.empty())
31666 result += variable_name;
31667 result += array->get_subrange_representation();
31668 }
31669 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
31670 {
31671 string s = variable_name + array->get_subrange_representation();
31672 result = pointer_declaration_name(p, s, qualified, internal);
31673 }
31674 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
31675 {
31676 string s = variable_name + array->get_subrange_representation();
31677 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
31678 }
31679 else
31681 }
31682 return array->get_environment().intern(result);
31683}
31684
31685/// Emit the name of a array declaration.
31686///
31687/// @param the array to consider.
31688///
31689/// @param the name of the variable that has @p as a type. If it's
31690/// empty then the resulting name is going to be the abstract name of
31691/// the type.
31692///
31693/// @param qualified if true then the type name is going to be
31694/// fully qualified.
31695///
31696/// @param internal if true then the type name is going to be used for
31697/// type canonicalization purposes.
31698static interned_string
31699array_declaration_name(const array_type_def_sptr& array,
31700 const string& variable_name,
31701 bool qualified, bool internal)
31702{return array_declaration_name(array.get(), variable_name,
31703 qualified, internal);}
31704
31705/// Emit the name of a pointer-to-member declaration.
31706///
31707/// @param ptr the pointer-to-member to consider.
31708///
31709/// @param variable_name the name of the variable that has @p as a
31710/// type. If it's empty then the resulting name is going to be the
31711/// abstract name of the type.
31712///
31713/// @param qualified if true then the type name is going to be
31714/// fully qualified.
31715///
31716/// @param internal if true then the type name is going to be used for
31717/// type canonicalization purposes.
31718static interned_string
31719ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
31720 const string& variable_name,
31721 bool qualified, bool internal)
31722{
31723 if (!ptr)
31724 return interned_string();
31725
31726 string input = variable_name;
31727 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
31728 qualified, internal);
31729 return ptr->get_environment().intern(result);
31730}
31731
31732/// Emit the name of a pointer-to-member declaration.
31733///
31734/// @param ptr the pointer-to-member to consider.
31735///
31736/// @param variable_name the name of the variable that has @p as a
31737/// type. If it's empty then the resulting name is going to be the
31738/// abstract name of the type.
31739///
31740/// @param qualified if true then the type name is going to be
31741/// fully qualified.
31742///
31743/// @param internal if true then the type name is going to be used for
31744/// type canonicalization purposes.
31745static interned_string
31746ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
31747 const string& variable_name,
31748 bool qualified, bool internal)
31749{
31750 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
31751 qualified, internal);
31752}
31753
31754/// Sort types right before hashing and canonicalizing them.
31755///
31756/// @param types the vector of types to sort.
31757void
31758sort_types_for_hash_computing_and_c14n(vector<type_base_sptr>& types)
31759{
31760 sort_types_for_hash_computing_and_c14n(types.begin(), types.end());
31761}
31762
31763/// Move a member type from its current scope to the canonical type of
31764/// its current scope.
31765///
31766/// @param member_type the member_type to move.
31767void
31769{
31770 if (!member_type
31771 || !is_type(member_type)
31772 || !is_member_type(is_type(member_type)))
31773 return;
31774
31775 scope_decl_sptr scope = member_type->get_scope();
31776 if (!scope)
31777 return;
31778
31779 class_or_union_sptr cou_scope = is_class_or_union_type(scope);
31780 if (!cou_scope)
31781 return;
31782
31783 class_or_union_sptr canonical_type_of_scope =
31784 is_class_or_union_type(cou_scope->get_canonical_type());
31785 if (!canonical_type_of_scope
31786 || (canonical_type_of_scope.get() == is_class_or_union_type(scope).get()))
31787 return;
31788
31789 string name = get_type_name(is_type(member_type));
31790
31791 if (!name.empty())
31792 {
31793 bool do_move = true;
31794 if (type_base_sptr t = canonical_type_of_scope->find_member_type(name))
31795 do_move = false;
31796
31797 if (do_move)
31798 move_member_type(member_type, is_scope_decl(canonical_type_of_scope));
31799 }
31800}
31801
31802/// Bind the life time of a function type to the file time of a given
31803/// translation unit.
31804///
31805/// @param fn_type the function type bind.
31806///
31807/// @param tu the translation unit to use.
31808void
31810 translation_unit* tu)
31811{
31812 if (!tu || !fn_type)
31813 return;
31814
31815 corpus* corp = tu->get_corpus();
31816 if (corp)
31817 {
31818 lock_guard<recursive_mutex> lock(corp->priv_->get_mutex());
31819 corp->priv_->live_fn_types_.insert(fn_type);
31820 fn_type->set_corpus(corp);
31821 fn_type->set_translation_unit(tu);
31823 }
31824 else
31825 {
31826 lock_guard<mutex> lock(tu->priv_->live_fn_types_mutex_);
31827 tu->priv_->live_fn_types_.insert(fn_type);
31828 }
31829}
31830
31831/// Bind the life time of a function type to the file time of a given
31832/// translation unit.
31833///
31834/// @param fn_type the function type bind.
31835///
31836/// @param tu the translation unit to use.
31837void
31841
31842/// Hash and canonicalize a sequence of types.
31843///
31844/// Note that this function first sorts the types, then hashes them
31845/// and then canonicalizes them.
31846///
31847/// Operations must be done in that order to get predictable results.
31848///
31849///
31850/// @param types the sequence of types to to hash and canonicalize.
31851///
31852/// @param do_log if true, then this functions emits logs about its
31853/// progression.
31854///
31855/// @param show_stats if true, then this functions emits detailed
31856/// statistics about internal stuff like type canonicalization and
31857/// what not.
31858void
31859perform_type_canonicalization(vector<type_base_sptr>& types,
31860 bool do_log, bool show_stats)
31861{return hash_and_canonicalize_types(types, do_log, show_stats);}
31862
31863// <ir_node_visitor stuff>
31864
31865bool
31868
31869/// The private data structure of the ir_node_visitor type.
31870struct ir_node_visitor::priv
31871{
31872 pointer_set visited_ir_nodes;
31873 bool allow_visiting_already_visited_type_node;
31874 bool allow_visiting_member_type_nodes;
31875
31876 priv()
31877 : allow_visiting_already_visited_type_node(true),
31878 allow_visiting_member_type_nodes(true)
31879 {}
31880}; // end struct ir_node_visitory::priv
31881
31882/// Default Constructor of the ir_node_visitor type.
31884 : priv_(new priv)
31885{}
31886
31887ir_node_visitor::~ir_node_visitor() = default;
31888
31889/// Set if the walker using this visitor is allowed to re-visit a type
31890/// node that was previously visited or not.
31891///
31892/// @param f if true, then the walker using this visitor is allowed to
31893/// re-visit a type node that was previously visited.
31894void
31896{priv_->allow_visiting_already_visited_type_node = f;}
31897
31898/// Get if the walker using this visitor is allowed to re-visit a type
31899/// node that was previously visited or not.
31900///
31901/// @return true iff the walker using this visitor is allowed to
31902/// re-visit a type node that was previously visited.
31903bool
31905{return priv_->allow_visiting_already_visited_type_node;}
31906
31907/// Set if the walker using this visitor is allowed to visit member
31908/// type nodes.
31909///
31910/// @param f if true then walker using this visitor is allowed to
31911/// visit member type nodes.
31912void
31914{priv_->allow_visiting_member_type_nodes = f;}
31915
31916/// Get if the walker using this visitor is allowed to visit member
31917/// type nodes.
31918///
31919/// @return true iff the walker using this visitor is allowed to visit
31920/// member type nodes.
31921bool
31923{return priv_->allow_visiting_member_type_nodes;}
31924
31925/// Mark a given type node as having been visited.
31926///
31927/// Note that for this function to work, the type node must have been
31928/// canonicalized. Otherwise the process is aborted.
31929///
31930/// @param p the type to mark as having been visited.
31931void
31933{
31935 return;
31936
31937 if (p == 0 || type_node_has_been_visited(p))
31938 return;
31939
31940 type_base* canonical_type = p->get_naked_canonical_type();
31942 {
31943 ABG_ASSERT(!canonical_type);
31944 canonical_type = p;
31945 }
31946 ABG_ASSERT(canonical_type);
31947
31948 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
31949 priv_->visited_ir_nodes.insert(canonical_ptr_value);
31950}
31951
31952/// Un-mark all visited type nodes.
31953///
31954/// That is, no type node is going to be considered as having been
31955/// visited anymore.
31956///
31957/// In other words, after invoking this funciton,
31958/// ir_node_visitor::type_node_has_been_visited() is going to return
31959/// false on all type nodes.
31960void
31962{priv_->visited_ir_nodes.clear();}
31963
31964/// Test if a given type node has been marked as visited.
31965///
31966/// @param p the type node to consider.
31967///
31968/// @return true iff the type node @p p has been marked as visited by
31969/// the function ir_node_visitor::mark_type_node_as_visited.
31970bool
31972{
31974 return false;
31975
31976 if (p == 0)
31977 return false;
31978
31979 type_base *canonical_type = p->get_naked_canonical_type();
31981 {
31982 ABG_ASSERT(!canonical_type);
31983 canonical_type = p;
31984 }
31985 ABG_ASSERT(canonical_type);
31986
31987 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
31988 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
31989 if (it == priv_->visited_ir_nodes.end())
31990 return false;
31991
31992 return true;
31993}
31994
31995bool
31996ir_node_visitor::visit_begin(decl_base*)
31997{return true;}
31998
31999bool
32000ir_node_visitor::visit_end(decl_base*)
32001{return true;}
32002
32003bool
32004ir_node_visitor::visit_begin(type_base*)
32005{return true;}
32006
32007bool
32008ir_node_visitor::visit_end(type_base*)
32009{return true;}
32010
32011bool
32012ir_node_visitor::visit_begin(scope_decl*)
32013{return true;}
32014
32015bool
32016ir_node_visitor::visit_end(scope_decl*)
32017{return true;}
32018
32019bool
32020ir_node_visitor::visit_begin(scope_type_decl* t)
32021{return visit_begin(static_cast<type_base*>(t));}
32022
32023bool
32024ir_node_visitor::visit_end(scope_type_decl* t)
32025{return visit_end(static_cast<type_base*>(t));}
32026
32027bool
32028ir_node_visitor::visit_begin(type_decl* t)
32029{return visit_begin(static_cast<type_base*>(t));}
32030
32031bool
32032ir_node_visitor::visit_end(type_decl* t)
32033{return visit_end(static_cast<type_base*>(t));}
32034
32035bool
32036ir_node_visitor::visit_begin(namespace_decl* d)
32037{return visit_begin(static_cast<decl_base*>(d));}
32038
32039bool
32040ir_node_visitor::visit_end(namespace_decl* d)
32041{return visit_end(static_cast<decl_base*>(d));}
32042
32043bool
32044ir_node_visitor::visit_begin(qualified_type_def* t)
32045{return visit_begin(static_cast<type_base*>(t));}
32046
32047bool
32048ir_node_visitor::visit_end(qualified_type_def* t)
32049{return visit_end(static_cast<type_base*>(t));}
32050
32051bool
32052ir_node_visitor::visit_begin(pointer_type_def* t)
32053{return visit_begin(static_cast<type_base*>(t));}
32054
32055bool
32056ir_node_visitor::visit_end(pointer_type_def* t)
32057{return visit_end(static_cast<type_base*>(t));}
32058
32059bool
32060ir_node_visitor::visit_begin(reference_type_def* t)
32061{return visit_begin(static_cast<type_base*>(t));}
32062
32063bool
32064ir_node_visitor::visit_end(reference_type_def* t)
32065{return visit_end(static_cast<type_base*>(t));}
32066
32067bool
32068ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
32069{return visit_begin(static_cast<type_base*>(t));}
32070
32071bool
32072ir_node_visitor::visit_end(ptr_to_mbr_type* t)
32073{return visit_end(static_cast<type_base*>(t));}
32074
32075bool
32076ir_node_visitor::visit_begin(array_type_def* t)
32077{return visit_begin(static_cast<type_base*>(t));}
32078
32079bool
32080ir_node_visitor::visit_end(array_type_def* t)
32081{return visit_end(static_cast<type_base*>(t));}
32082
32083bool
32084ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
32085{return visit_begin(static_cast<type_base*>(t));}
32086
32087bool
32088ir_node_visitor::visit_end(array_type_def::subrange_type* t)
32089{return visit_end(static_cast<type_base*>(t));}
32090
32091bool
32092ir_node_visitor::visit_begin(enum_type_decl* t)
32093{return visit_begin(static_cast<type_base*>(t));}
32094
32095bool
32096ir_node_visitor::visit_end(enum_type_decl* t)
32097{return visit_end(static_cast<type_base*>(t));}
32098
32099bool
32100ir_node_visitor::visit_begin(typedef_decl* t)
32101{return visit_begin(static_cast<type_base*>(t));}
32102
32103bool
32104ir_node_visitor::visit_end(typedef_decl* t)
32105{return visit_end(static_cast<type_base*>(t));}
32106
32107bool
32108ir_node_visitor::visit_begin(function_type* t)
32109{return visit_begin(static_cast<type_base*>(t));}
32110
32111bool
32112ir_node_visitor::visit_end(function_type* t)
32113{return visit_end(static_cast<type_base*>(t));}
32114
32115bool
32116ir_node_visitor::visit_begin(method_type* t)
32117{return visit_begin(static_cast<type_base*>(t));}
32118
32119bool
32120ir_node_visitor::visit_end(method_type* t)
32121{return visit_end(static_cast<type_base*>(t));}
32122
32123
32124bool
32125ir_node_visitor::visit_begin(var_decl* d)
32126{return visit_begin(static_cast<decl_base*>(d));}
32127
32128bool
32129ir_node_visitor::visit_end(var_decl* d)
32130{return visit_end(static_cast<decl_base*>(d));}
32131
32132bool
32133ir_node_visitor::visit_begin(function_decl* d)
32134{return visit_begin(static_cast<decl_base*>(d));}
32135
32136bool
32137ir_node_visitor::visit_end(function_decl* d)
32138{return visit_end(static_cast<decl_base*>(d));}
32139
32140bool
32141ir_node_visitor::visit_begin(function_decl::parameter* d)
32142{return visit_begin(static_cast<decl_base*>(d));}
32143
32144bool
32145ir_node_visitor::visit_end(function_decl::parameter* d)
32146{return visit_end(static_cast<decl_base*>(d));}
32147
32148bool
32149ir_node_visitor::visit_begin(function_tdecl* d)
32150{return visit_begin(static_cast<decl_base*>(d));}
32151
32152bool
32153ir_node_visitor::visit_end(function_tdecl* d)
32154{return visit_end(static_cast<decl_base*>(d));}
32155
32156bool
32157ir_node_visitor::visit_begin(class_tdecl* d)
32158{return visit_begin(static_cast<decl_base*>(d));}
32159
32160bool
32161ir_node_visitor::visit_end(class_tdecl* d)
32162{return visit_end(static_cast<decl_base*>(d));}
32163
32164bool
32165ir_node_visitor::visit_begin(class_or_union* t)
32166{return visit_begin(static_cast<type_base*>(t));}
32167
32168bool
32169ir_node_visitor::visit_end(class_or_union* t)
32170{return visit_end(static_cast<type_base*>(t));}
32171
32172bool
32173ir_node_visitor::visit_begin(class_decl* t)
32174{return visit_begin(static_cast<type_base*>(t));}
32175
32176bool
32177ir_node_visitor::visit_end(class_decl* t)
32178{return visit_end(static_cast<type_base*>(t));}
32179
32180bool
32181ir_node_visitor::visit_begin(union_decl* t)
32182{return visit_begin(static_cast<type_base*>(t));}
32183
32184bool
32185ir_node_visitor::visit_end(union_decl* t)
32186{return visit_end(static_cast<type_base*>(t));}
32187
32188bool
32189ir_node_visitor::visit_begin(class_decl::base_spec* d)
32190{return visit_begin(static_cast<decl_base*>(d));}
32191
32192bool
32193ir_node_visitor::visit_end(class_decl::base_spec* d)
32194{return visit_end(static_cast<decl_base*>(d));}
32195
32196bool
32197ir_node_visitor::visit_begin(member_function_template* d)
32198{return visit_begin(static_cast<decl_base*>(d));}
32199
32200bool
32201ir_node_visitor::visit_end(member_function_template* d)
32202{return visit_end(static_cast<decl_base*>(d));}
32203
32204bool
32205ir_node_visitor::visit_begin(member_class_template* d)
32206{return visit_begin(static_cast<decl_base*>(d));}
32207
32208bool
32209ir_node_visitor::visit_end(member_class_template* d)
32210{return visit_end(static_cast<decl_base*>(d));}
32211
32212// </ir_node_visitor stuff>
32213
32214// <debugging facilities>
32215
32216/// Generate a different string at each invocation.
32217///
32218/// @return the resulting string.
32219static string
32220get_next_string()
32221{
32222 static __thread size_t counter;
32223 ++counter;
32224 std::ostringstream o;
32225 o << counter;
32226 return o.str();
32227}
32228
32229/// A hashing functor for a @ref function_decl
32230struct function_decl_hash
32231{
32232 size_t operator()(const function_decl* f) const
32233 {return reinterpret_cast<size_t>(f);}
32234
32235 size_t operator()(const function_decl_sptr& f) const
32236 {return operator()(f.get());}
32237};
32238
32239/// Convenience typedef for a hash map of pointer to function_decl and
32240/// string.
32241typedef unordered_map<const function_decl*, string,
32242 function_decl_hash,
32244
32245/// Return a string associated to a given function. Two functions
32246/// that compare equal would yield the same string, as far as this
32247/// routine is concerned. And two functions that are different would
32248/// yield different strings.
32249///
32250/// This is used to debug core diffing issues on functions. The
32251/// sequence of strings can be given to the 'testdiff2' program that
32252/// is in the tests/ directory of the source tree, to reproduce core
32253/// diffing issues on string and thus ease the debugging.
32254///
32255/// @param fn the function to generate a string for.
32256///
32257/// @param m the function_decl* <-> string map to be used by this
32258/// function to generate strings associated to a function.
32259///
32260/// @return the resulting string.
32261static const string&
32262fn_to_str(const function_decl* fn,
32264{
32265 fns_to_str_map_type::const_iterator i = m.find(fn);
32266 if (i != m.end())
32267 return i->second;
32268 string s = get_next_string();
32269 return m[fn]= s;
32270}
32271
32272/// Generate a sequence of string that matches a given sequence of
32273/// function. In the resulting sequence, each function is "uniquely
32274/// representated" by a string. For instance, if the same function "foo"
32275/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
32276/// we don't care about the actual string) would appear at index 1 and 3.
32277///
32278/// @param begin the beginning of the sequence of functions to consider.
32279///
32280/// @param end the end of the sequence of functions. This points to
32281/// one-passed-the-end of the actual sequence.
32282///
32283/// @param m the function_decl* <-> string map to be used by this
32284/// function to generate strings associated to a function.
32285///
32286/// @param o the output stream where to emit the generated list of
32287/// strings to.
32288static void
32289fns_to_str(vector<function_decl*>::const_iterator begin,
32290 vector<function_decl*>::const_iterator end,
32292 std::ostream& o)
32293{
32294 vector<function_decl*>::const_iterator i;
32295 for (i = begin; i != end; ++i)
32296 o << "'" << fn_to_str(*i, m) << "' ";
32297}
32298
32299/// For each sequence of functions given in argument, generate a
32300/// sequence of string that matches a given sequence of function. In
32301/// the resulting sequence, each function is "uniquely representated"
32302/// by a string. For instance, if the same function "foo" appears at
32303/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
32304/// care about the actual string) would appear at index 1 and 3.
32305///
32306/// @param a_begin the beginning of the sequence of functions to consider.
32307///
32308/// @param a_end the end of the sequence of functions. This points to
32309/// one-passed-the-end of the actual sequence.
32310///
32311/// @param b_begin the beginning of the second sequence of functions
32312/// to consider.
32313///
32314/// @param b_end the end of the second sequence of functions.
32315///
32316/// @param m the function_decl* <-> string map to be used by this
32317/// function to generate strings associated to a function.
32318///
32319/// @param o the output stream where to emit the generated list of
32320/// strings to.
32321static void
32322fns_to_str(vector<function_decl*>::const_iterator a_begin,
32323 vector<function_decl*>::const_iterator a_end,
32324 vector<function_decl*>::const_iterator b_begin,
32325 vector<function_decl*>::const_iterator b_end,
32327 std::ostream& o)
32328{
32329 fns_to_str(a_begin, a_end, m, o);
32330 o << "->|<- ";
32331 fns_to_str(b_begin, b_end, m, o);
32332 o << "\n";
32333}
32334
32335/// For each sequence of functions given in argument, generate a
32336/// sequence of string that matches a given sequence of function. In
32337/// the resulting sequence, each function is "uniquely representated"
32338/// by a string. For instance, if the same function "foo" appears at
32339/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
32340/// care about the actual string) would appear at index 1 and 3.
32341///
32342/// @param a_begin the beginning of the sequence of functions to consider.
32343///
32344/// @param a_end the end of the sequence of functions. This points to
32345/// one-passed-the-end of the actual sequence.
32346///
32347/// @param b_begin the beginning of the second sequence of functions
32348/// to consider.
32349///
32350/// @param b_end the end of the second sequence of functions.
32351///
32352/// @param o the output stream where to emit the generated list of
32353/// strings to.
32354void
32355fns_to_str(vector<function_decl*>::const_iterator a_begin,
32356 vector<function_decl*>::const_iterator a_end,
32357 vector<function_decl*>::const_iterator b_begin,
32358 vector<function_decl*>::const_iterator b_end,
32359 std::ostream& o)
32360{
32362 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
32363}
32364
32365// </debugging facilities>
32366
32367// </class template>
32368
32369}// end namespace ir
32370}//end namespace abigail
32371
32372namespace
32373{
32374
32375/// Update the qualified parent name, qualified name and scoped name
32376/// of a tree decl node.
32377///
32378/// @return true if the tree walking should continue, false otherwise.
32379///
32380/// @param d the tree node to take in account.
32381bool
32382qualified_name_setter::do_update(abigail::ir::decl_base* d)
32383{
32384 std::string parent_qualified_name;
32386 bool do_update_qualified_name = false;
32387 if (parent)
32388 {
32389 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
32390 do_update_qualified_name = true;
32391 }
32392 else
32393 d->priv_->qualified_parent_name_ = abigail::interned_string();
32394
32395 const abigail::ir::environment& env = d->get_environment();
32396
32397 if (do_update_qualified_name && !d->priv_->qualified_parent_name_.empty())
32398 {
32399 if (d->get_name().empty())
32400 d->priv_->qualified_name_ = abigail::interned_string();
32401 else
32402 {
32403 std::string n = d->priv_->qualified_parent_name_ + "::" + d->get_name();
32404 d->priv_->qualified_name_ = env.intern(n);
32405 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
32406 }
32407 }
32408 // Make sure the internal qualified name (used for type
32409 // canonicalization puroses) is always the qualified name. For
32410 // integral/real types however, only the non qualified type is used.
32411 if (!is_integral_type(d))
32412 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
32413
32414 if (do_update_qualified_name || d->priv_->scoped_name_.empty())
32415 {
32416 if (parent
32417 //&& !parent->get_is_anonymous()
32418 && !parent->get_name().empty())
32419 d->priv_->scoped_name_ =
32420 env.intern(parent->get_name() + "::" + d->get_name());
32421 else
32422 d->priv_->scoped_name_ =
32423 env.intern(d->get_name());
32424 }
32425
32426 d->priv_->cached_repr_.clear();
32427 d->priv_->internal_cached_repr_.clear();
32428
32429 if (!is_scope_decl(d))
32430 return false;
32431
32432 return true;
32433}
32434
32435/// This is called when we start visiting a decl node, during the
32436/// udpate of the qualified name of a given sub-tree.
32437///
32438/// @param d the decl node we are visiting.
32439///
32440/// @return true iff the traversal should keep going.
32441bool
32442qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
32443{return do_update(d);}
32444
32445/// This is called when we start visiting a type node, during the
32446/// udpate of the qualified name of a given sub-tree.
32447///
32448/// @param d the decl node we are visiting.
32449///
32450/// @return true iff the traversal should keep going.
32451bool
32452qualified_name_setter::visit_begin(abigail::ir::type_base* t)
32453{
32455 return do_update(d);
32456 return false;
32457}
32458
32459}// end anonymous namespace.
This header declares filters for the diff trees resulting from comparing ABI Corpora.
The private data and functions of the abigail::ir::corpus type.
reverse_wrapper< T > reverse(T &iterable)
Return the reverse_wrapper container associated with a given container.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
Definition abg-fwd.h:1790
Declaration of types pertaining to the interned string pool used throughout Libabigail,...
This contains the private implementation of the suppression engine of libabigail.
#define CACHE_COMPARISON_RESULT_AND_RETURN(value)
Cache the result of a comparison between too artifacts (l & r) and return immediately.
Definition abg-ir.cc:1571
#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r)
This macro is to be used while comparing composite types that might recursively refer to themselves....
Definition abg-ir.cc:1352
Types of the main internal representation of libabigail.
Wrappers around regex types and functions.
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
This type abstracts the configuration information of the library.
Definition abg-config.h:18
bool has_string(const char *s) const
Test if the interned string pool already contains a string with a given value.
Definition abg-ir.cc:105
const char * get_string(const char *s) const
Get a pointer to the interned string which has a given value.
Definition abg-ir.cc:118
interned_string_pool()
Default constructor.
Definition abg-ir.cc:91
~interned_string_pool()
Destructor.
Definition abg-ir.cc:155
The abstraction of an interned string.
bool operator<(const interned_string &o) const
"Less than" operator.
Definition abg-ir.cc:318
const string * raw() const
Return the underlying pointer to std::string that this interned_string wraps.
Definition abg-ir.cc:244
bool empty() const
Test if the current instance of interned_string is empty.
Definition abg-ir.cc:232
interned_string & operator=(const interned_string &o)
Assignment operator.
Definition abg-ir.cc:211
void clear()
Clear the string.
Definition abg-ir.cc:221
bool operator!=(const interned_string &o) const
Inequality operator.
Definition abg-ir.cc:273
bool operator==(const interned_string &o) const
Compare the current instance of interned_string against another instance of interned_string.
Definition abg-ir.cc:260
This class is to hold the value of the bound of a subrange. The value can be either signed or unsigne...
Definition abg-ir.h:2593
void set_signed(int64_t v)
Setter of the bound value as signed.
Definition abg-ir.cc:20010
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:19978
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:19971
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition abg-ir.cc:19985
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition abg-ir.cc:20022
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition abg-ir.cc:19993
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition abg-ir.cc:19943
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition abg-ir.cc:20000
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
Definition abg-ir.h:2578
void set_lower_bound(int64_t lb)
Setter of the lower bound.
Definition abg-ir.cc:20201
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition abg-ir.cc:20228
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition abg-ir.cc:20194
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type of the subrange, that is, the type that defines the range.
Definition abg-ir.cc:20168
string as_string() const
Return a string representation of the sub range.
Definition abg-ir.cc:20250
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:20149
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:20450
bool operator!=(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:20389
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition abg-ir.cc:20180
type_base_sptr get_underlying_type() const
Getter of the underlying type of the subrange, that is, the type that defines the range.
Definition abg-ir.cc:20160
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:20345
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition abg-ir.cc:20187
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build a pretty representation for an array_type_def::subrange_type.
Definition abg-ir.cc:20428
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition abg-ir.cc:20273
uint64_t get_length() const
Getter of the length of the subrange type.
Definition abg-ir.cc:20211
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition abg-ir.cc:20243
The abstraction of an array type.
Definition abg-ir.h:2552
virtual bool is_non_finite() const
Definition abg-ir.cc:20867
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Build and return the qualified name of the current instance of the array_type_def.
Definition abg-ir.cc:20897
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:20557
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition abg-ir.cc:20828
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition abg-ir.cc:20843
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition abg-ir.h:2570
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:20960
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition abg-ir.cc:20991
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:20806
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition abg-ir.h:2573
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of array_type_def.
Definition abg-ir.cc:20610
translation_unit::language get_language() const
Get the language of the array.
Definition abg-ir.cc:20795
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition abg-ir.cc:20853
Abstraction of a base specifier in a class declaration.
Definition abg-ir.h:4391
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition abg-ir.cc:26517
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition abg-ir.cc:26524
long get_offset_in_bits() const
Getter of the offset of the base.
Definition abg-ir.cc:26531
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:26506
virtual bool traverse(ir_node_visitor &)
Traverses an instance of class_decl::base_spec, visiting all the sub-types and decls that it might co...
Definition abg-ir.cc:26547
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition abg-ir.cc:26641
Abstracts a class declaration.
Definition abg-ir.h:4214
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition abg-ir.cc:26287
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition abg-ir.cc:27108
const virtual_mem_fn_map_type & get_virtual_mem_fns_map() const
Get the map that associates a virtual table offset to the virtual member functions with that virtual ...
Definition abg-ir.cc:26376
bool is_struct() const
Test if the class is a struct.
Definition abg-ir.cc:26296
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:27172
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition abg-ir.cc:26314
virtual ~class_decl()
Destructor of the class_decl type.
Definition abg-ir.cc:27711
virtual void on_canonical_type_set()
This method is invoked automatically right after the current instance of class_decl has been canonica...
Definition abg-ir.cc:26271
bool has_vtable() const
Test if the current instance has a vtable.
Definition abg-ir.cc:27136
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition abg-ir.cc:27150
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition abg-ir.cc:27117
base_specs get_base_specifiers_copy() const
Get a copy of the base specifiers for this class.
Definition abg-ir.cc:26321
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:27621
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition abg-ir.h:4229
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition abg-ir.cc:26303
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition abg-ir.cc:26357
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition abg-ir.cc:26381
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition abg-ir.cc:27340
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition abg-ir.cc:27469
class_decl_sptr find_base_class(const string &qualified_name) const
Find a base class of a given qualified name for the current class.
Definition abg-ir.cc:26340
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition abg-ir.cc:27099
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition abg-ir.h:4230
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Getter of the pretty representation of the current instance of class_decl.
Definition abg-ir.cc:26405
The base type of class_decl and union_decl.
Definition abg-ir.h:4005
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition abg-ir.cc:25098
const var_decl_sptr find_anonymous_data_member(const var_decl_sptr &) const
Find an anonymous data member in the class.
Definition abg-ir.cc:25281
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition abg-ir.cc:25487
data_members get_data_members_copy() const
Get a copy of the the data members of this class_or_union.
Definition abg-ir.cc:25235
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition abg-ir.cc:25599
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition abg-ir.cc:25083
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition abg-ir.cc:25116
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition abg-ir.h:4028
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition abg-ir.h:4027
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition abg-ir.cc:25228
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:24866
const method_decl * find_member_function_from_signature(const string &s) const
Find a method (member function) using its signature (pretty representation) as a key.
Definition abg-ir.cc:25573
method_decl_sptr find_member_function_sptr(const string &mangled_name)
Find a method, using its linkage name as a key.
Definition abg-ir.cc:25548
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition abg-ir.cc:25067
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:24882
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Definition abg-ir.cc:25328
const method_decl * find_member_function(const string &mangled_name) const
Find a method, using its linkage name as a key.
Definition abg-ir.cc:25521
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
Definition abg-ir.cc:25339
vector< var_decl_sptr > data_members
Convenience typedef.
Definition abg-ir.h:4026
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition abg-ir.cc:24962
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:25701
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition abg-ir.cc:25035
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition abg-ir.cc:25606
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition abg-ir.cc:25051
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition abg-ir.cc:25134
void maybe_fixup_members_of_anon_data_member(var_decl_sptr anon_dm)
Fixup the members of the type of an anonymous data member.
Definition abg-ir.cc:25008
const var_decl_sptr find_data_member(const string &) const
Find a data member of a given name in the current class_or_union.
Definition abg-ir.cc:25255
member_functions get_member_functions_copy() const
Get a copy of the member functions of this class_or_union.
Definition abg-ir.cc:25503
Abstract a class template.
Definition abg-ir.h:3825
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition abg-ir.cc:29819
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:29868
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:29823
The abstraction of the relationship between an entity and its containing scope (its context)....
Definition abg-ir.h:1283
bool operator!=(const context_rel &o) const
Inequality operator.
Definition abg-ir.cc:27801
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition abg-corpus.h:95
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
Definition abg-corpus.h:115
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
origin get_origin() const
Getter for the origin of the corpus.
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
const environment & get_environment() const
Getter of the enviroment of the corpus.
The base type of all declarations.
Definition abg-ir.h:1584
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
Definition abg-ir.cc:17103
void set_is_declaration_only(bool f)
Set a flag saying if the enum_type_decl is a declaration-only enum_type_decl.
Definition abg-ir.cc:6126
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition abg-ir.cc:6315
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition abg-ir.cc:5598
void set_is_in_public_symbol_table(bool)
Set the flag saying if this decl is from a symbol that is in a public symbols table,...
Definition abg-ir.cc:5681
friend bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
Definition abg-ir.cc:6684
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition abg-ir.cc:6059
std::list< typedef_decl_sptr > & get_naming_typedefs() const
Getter for the naming typedef of the current decl.
Definition abg-ir.cc:5827
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition abg-ir.cc:5891
const decl_base * get_naked_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Definition abg-ir.cc:6104
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition abg-ir.cc:5961
void clear_qualified_name()
Clear the qualified name of this decl.
Definition abg-ir.cc:5588
virtual void set_name(const string &n)
Setter for the name of the decl.
Definition abg-ir.cc:5760
const location & get_location() const
Get the location of a given declaration.
Definition abg-ir.cc:5704
binding
ELF binding.
Definition abg-ir.h:1632
virtual const interned_string & get_name() const
Getter for the name of the current decl.
Definition abg-ir.cc:5946
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition abg-ir.cc:5576
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition abg-ir.cc:5641
scope_decl_sptr get_scope() const
Return the type containing the current decl, if any.
Definition abg-ir.cc:5923
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition abg-ir.cc:5774
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition abg-ir.cc:6048
const decl_base_sptr get_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Definition abg-ir.cc:6085
bool has_naming_typedef(const typedef_decl_sptr)
Test if the current decl has a given naming typedef.
Definition abg-ir.cc:5867
void set_location(const location &l)
Set the location for a given declaration.
Definition abg-ir.cc:5745
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition abg-ir.cc:5787
virtual void set_scope(scope_decl_sptr)
Setter of the scope of the current decl.
Definition abg-ir.cc:6343
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition abg-ir.cc:5912
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition abg-ir.cc:5631
visibility get_visibility() const
Getter for the visibility of the decl.
Definition abg-ir.cc:5902
visibility
ELF visibility.
Definition abg-ir.h:1622
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition abg-ir.cc:6114
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:6332
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition abg-ir.cc:6070
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition abg-ir.cc:5881
void add_naming_typedef(const typedef_decl_sptr)
Set the naming typedef of the current instance of decl_base.
Definition abg-ir.cc:5848
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:6624
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:7742
virtual ~decl_base()
Destructor of the decl_base type.
Definition abg-ir.cc:6319
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:6304
const interned_string & get_qualified_parent_name() const
Return a copy of the qualified name of the parent of the current decl.
Definition abg-ir.cc:5936
bool get_is_anonymous_or_has_anonymous_parent() const
Definition abg-ir.cc:5813
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition abg-ir.cc:5802
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl_sptr scpe)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition abg-ir.cc:9616
bool get_is_in_public_symbol_table() const
Test if the decl is defined in a ELF symbol table as a public symbol.
Definition abg-ir.cc:5670
friend bool equals(const decl_base &l, const decl_base &r, change_kind *, bool qualified_name, bool linkage_name)
Compares two instances of decl_base.
Definition abg-ir.cc:6243
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition abg-ir.cc:5614
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representatin of the current declaration.
Definition abg-ir.cc:5987
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition abg-ir.h:3004
const var_decl_sptr get_anonymous_data_member() const
Return a non-nil value if this data member context relationship has an anonymous data member....
Definition abg-ir.cc:3971
void set_anonymous_data_member(var_decl_sptr)
Set the containing anonymous data member of this data member context relationship....
Definition abg-ir.cc:3984
The abstraction of the version of an ELF symbol.
Definition abg-ir.h:1230
version & operator=(const version &o)
Assign a version to the current one.
Definition abg-ir.cc:3886
bool operator==(const version &o) const
Compares the current version against another one.
Definition abg-ir.cc:3868
bool is_default() const
Getter for the 'is_default' property of the version.
Definition abg-ir.cc:3848
const string & str() const
Getter for the version name.
Definition abg-ir.cc:3834
bool operator!=(const version &o) const
Inequality operator.
Definition abg-ir.cc:3877
Abstraction of an elf symbol.
Definition abg-ir.h:959
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
Definition abg-ir.cc:2920
elf_symbol_sptr get_alias_which_equals(const elf_symbol &other) const
In the list of aliases of a given elf symbol, get the alias that equals this current symbol.
Definition abg-ir.cc:3287
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition abg-ir.cc:3177
type get_type() const
Getter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2708
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
Definition abg-ir.cc:2987
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2890
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition abg-ir.cc:3028
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
Definition abg-ir.cc:2697
bool is_suppressed() const
Getter for the 'is-suppressed' property.
Definition abg-ir.cc:2942
binding
The binding of a symbol.
Definition abg-ir.h:976
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
Definition abg-ir.cc:3035
string get_aliases_id_string(const string_elf_symbols_map_type &symtab, bool include_symbol_itself=true) const
Return a comma separated list of the id of the current symbol as well as the id string of its aliases...
Definition abg-ir.cc:3308
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2758
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
Definition abg-ir.cc:3191
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition abg-ir.cc:3053
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition abg-ir.cc:2954
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
Definition abg-ir.cc:2865
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
Definition abg-ir.cc:3102
void set_size(size_t)
Setter of the size of the symbol.
Definition abg-ir.cc:2738
const string & get_name() const
Getter for the name of the elf_symbol.
Definition abg-ir.cc:2687
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2748
static bool get_name_and_version_from_id(const string &id, string &name, string &ver)
Given the ID of a symbol, get the name and the version of said symbol.
Definition abg-ir.cc:3374
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
Definition abg-ir.cc:2856
type
The type of a symbol.
Definition abg-ir.h:963
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
Definition abg-ir.cc:2778
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
Definition abg-ir.cc:2900
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2790
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
Definition abg-ir.cc:3433
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition abg-ir.cc:3007
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition abg-ir.cc:2910
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
Definition abg-ir.cc:2585
visibility
The visibility of the symbol.
Definition abg-ir.h:985
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition abg-ir.cc:2768
bool is_common_symbol() const
Return true if the symbol is a common one.
Definition abg-ir.cc:3143
void set_index(size_t)
Setter for the index.
Definition abg-ir.cc:2677
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2801
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
Definition abg-ir.cc:3162
size_t get_index() const
Getter for the index.
Definition abg-ir.cc:2667
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition abg-ir.cc:3238
elf_symbol_sptr get_alias_from_name(const string &name) const
From the aliases of the current symbol, lookup one with a given name.
Definition abg-ir.cc:3265
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
Definition abg-ir.cc:2660
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2718
bool is_public() const
Test if the current instance of elf_symbol is public or not.
Definition abg-ir.cc:2840
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2879
size_t get_size() const
Getter of the size of the symbol.
Definition abg-ir.cc:2728
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
Definition abg-ir.cc:2812
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
Definition abg-ir.cc:2930
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition abg-ir.cc:3017
bool operator==(const elf_symbol &) const
Test if two main symbols are textually equal, or, if they have aliases that are textually equal.
Definition abg-ir.cc:3419
The abstraction of an enumerator.
Definition abg-ir.h:2882
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition abg-ir.cc:21634
bool operator!=(const enumerator &other) const
Inequality operator.
Definition abg-ir.cc:21694
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition abg-ir.cc:21736
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition abg-ir.cc:21758
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition abg-ir.cc:21703
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition abg-ir.cc:21765
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition abg-ir.cc:21751
const string & get_qualified_name(bool internal=false) const
Getter for the qualified name of the current instance of enum_type_decl::enumerator....
Definition abg-ir.cc:21720
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition abg-ir.cc:21744
bool operator==(const enumerator &other) const
Equality operator.
Definition abg-ir.cc:21681
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition abg-ir.cc:21665
Abstracts a declaration for an enum type.
Definition abg-ir.h:2796
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition abg-ir.h:2812
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:21065
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition abg-ir.cc:21234
const enumerators & get_enumerators() const
Definition abg-ir.cc:21078
bool find_enumerator_by_value(int64_t value, enum_type_decl::enumerator &result)
Find an enumerator by its value.
Definition abg-ir.cc:21125
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition abg-ir.cc:21090
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:21212
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition abg-ir.cc:21073
bool find_enumerator_by_name(const string &name, enum_type_decl::enumerator &result)
Find an enumerator by its name.
Definition abg-ir.cc:21150
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:21555
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of enum_type_decl.
Definition abg-ir.cc:21182
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition abg-ir.h:216
bool decl_only_class_equals_definition() const
Getter of the "decl-only-class-equals-definition" flag.
Definition abg-ir.cc:4455
bool is_void_pointer_type(const type_base_sptr &) const
Test if a given type is the same as the void pointer type of the environment.
Definition abg-ir.cc:4522
std::unordered_map< string, std::vector< type_base_sptr > > canonical_types_map_type
A convenience typedef for a map of canonical types. The key is the pretty representation string of a ...
Definition abg-ir.h:226
bool user_set_analyze_exported_interfaces_only() const
Getter for a property that says if the user actually did set the analyze_exported_interfaces_only() p...
Definition abg-ir.cc:4602
const vector< type_base_sptr > * get_canonical_types(const char *name) const
Get the vector of canonical types which have a given "string representation".
Definition abg-ir.cc:4775
const type_base_sptr & get_void_type() const
Get the unique type_decl that represents a "void" type for the current environment....
Definition abg-ir.cc:4375
static size_t get_number_of_threads_to_use()
Getter of the number of threads to use, as set by the user.
Definition abg-ir.cc:4650
bool is_variadic_parameter_type(const type_base *) const
Test if a type is a variadic parameter type as defined in the current environment.
Definition abg-ir.cc:4554
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition abg-ir.cc:4429
const type_base_sptr & get_void_pointer_type() const
Getter of the "pointer-to-void" IR node that is shared across the ABI corpus. This node must be the o...
Definition abg-ir.cc:4395
const config & get_config() const
Getter of the general configuration object.
Definition abg-ir.cc:4592
environment()
Default constructor of the environment type.
Definition abg-ir.cc:4252
type_base * get_canonical_type(const char *name, unsigned index)
Get a given canonical type which has a given "string representation".
Definition abg-ir.cc:4819
const type_base_sptr & get_variadic_parameter_type() const
Get a type_decl instance that represents a the type of a variadic function parameter....
Definition abg-ir.cc:4415
bool is_void_type(const type_base_sptr &) const
Test if a given type is a void type as defined in the current environment.
Definition abg-ir.cc:4491
virtual ~environment()
Destructor for the environment type.
Definition abg-ir.cc:4257
const vector< type_base_sptr > & get_sorted_canonical_types() const
Get the sorted list of canonical types.
Definition abg-ir.cc:4831
interned_string intern(const string &) const
Do intern a string.
Definition abg-ir.cc:4585
static size_t process_thread_pool_size_string(const string &)
Process a thread pool size string and convert it to a numeric value.
Definition abg-ir.cc:1448
static void set_number_of_threads_to_use(size_t)
Setter of the number of threads to use, as set by the user.
Definition abg-ir.cc:4661
bool analyze_exported_interfaces_only() const
Getter for the property that controls if we are to restrict the analysis to the types that are only r...
Definition abg-ir.cc:4628
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition abg-ir.cc:4265
Abstraction of a function parameter.
Definition abg-ir.h:3344
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition abg-ir.cc:24759
interned_string get_type_name() const
Definition abg-ir.cc:24549
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition abg-ir.cc:24587
const string get_type_pretty_representation() const
Definition abg-ir.cc:24568
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition abg-ir.cc:24735
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Compute and return a copy of the pretty representation of the current function parameter.
Definition abg-ir.cc:24779
Abstraction for a function declaration.
Definition abg-ir.h:3167
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition abg-ir.h:3190
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition abg-ir.cc:23952
string get_pretty_representation_of_declarator(bool internal=false) const
Compute and return the pretty representation for the part of the function declaration that starts at ...
Definition abg-ir.cc:23865
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition abg-ir.cc:23969
const elf_symbol_sptr get_symbol() const
Gets the the underlying ELF symbol for the current variable, that was set using function_decl::set_sy...
Definition abg-ir.cc:24013
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:24408
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition abg-ir.cc:24073
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition abg-ir.cc:24308
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition abg-ir.cc:23902
function_decl(const string &name, function_type_sptr function_type, bool declared_inline, const location &locus, const string &mangled_name, visibility vis, binding bind)
Constructor of the function_decl.
Definition abg-ir.cc:23726
const type_base_sptr get_return_type() const
Definition abg-ir.cc:24048
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition abg-ir.cc:24087
const std::vector< parameter_sptr > & get_parameters() const
Definition abg-ir.cc:24053
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition abg-ir.cc:24063
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition abg-ir.cc:23995
virtual ~function_decl()
Destructor of the function_decl type.
Definition abg-ir.cc:24426
interned_string get_id(const elf_symbol_sptr &s) const
Return an ID that tries to uniquely identify the function inside a program or a library,...
Definition abg-ir.cc:24324
parameters::const_iterator get_first_non_artificial_parm() const
Get the first parameter of the function that is not compiler-generated.
Definition abg-ir.cc:23929
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition abg-ir.cc:24294
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3193
bool is_declared_inline() const
Test if the function was declared inline.
Definition abg-ir.cc:24023
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of function_decl.
Definition abg-ir.cc:23797
interned_string get_id() const
Return an ID that tries to uniquely identify the function inside a program or a library.
Definition abg-ir.cc:24369
Abstract a function template declaration.
Definition abg-ir.h:3780
binding get_binding() const
Get the binding of the function template.
Definition abg-ir.cc:29655
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition abg-ir.cc:29648
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:29715
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition abg-ir.cc:29664
Abstraction of a function type.
Definition abg-ir.h:3429
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition abg-ir.h:3439
unsigned get_nb_parameters() const
The number of parameters of the function type in a thread-safe manner.
Definition abg-ir.cc:22829
bool has_empty_parameters() const
Test if a the function type has empty parameters in a thread-safe manner.
Definition abg-ir.cc:22815
const parameter_sptr get_parm_at(size_t) const
Get the function parameter at a given index, starting from zero.
Definition abg-ir.cc:22889
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:22783
virtual bool traverse(ir_node_visitor &)
Traverses an instance of function_type, visiting all the sub-types and decls that it might contain.
Definition abg-ir.cc:23291
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition abg-ir.cc:22945
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:23188
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:22689
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition abg-ir.cc:23250
void append_parameter(parameter_sptr parm)
Append a new parameter to the vector of parameters of the current instance of function_type.
Definition abg-ir.cc:22929
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition abg-ir.cc:22905
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition abg-ir.cc:23208
const parameter_sptr get_parm_at_index_from_first_non_implicit_parm(size_t) const
Get the Ith parameter of the vector of parameters of the current instance of function_type.
Definition abg-ir.cc:22864
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition abg-ir.cc:22794
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition abg-ir.cc:22805
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:23139
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition abg-ir.cc:22844
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3441
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Return a copy of the pretty representation of the current function_type.
Definition abg-ir.cc:23274
parameters::const_iterator get_first_non_artificial_parm() const
Get the first parameter of the function that is not compiler-generated.
Definition abg-ir.cc:23165
This abstracts the global scope of a given translation unit.
Definition abg-ir.h:1991
global_scope(translation_unit *tu)
Constructor of the global_scope type.
Definition abg-ir.cc:9698
type_base_sptr get_canonical_type_for(type_base_sptr t, homonym_type_group_sptr thiz)
Compute the canonical type for a given instance of type_base.
Definition abg-ir.cc:4055
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition abg-ir.h:4756
bool allow_visiting_already_visited_type_node() const
Get if the walker using this visitor is allowed to re-visit a type node that was previously visited o...
Definition abg-ir.cc:31904
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition abg-ir.cc:31971
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition abg-ir.cc:31961
void allow_visiting_member_type_nodes(bool)
Set if the walker using this visitor is allowed to visit member type nodes.
Definition abg-ir.cc:31913
bool allow_visiting_member_type_nodes() const
Get if the walker using this visitor is allowed to visit member type nodes.
Definition abg-ir.cc:31922
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition abg-ir.cc:31883
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition abg-ir.cc:31932
The entry point to manage locations.
Definition abg-ir.h:440
location create_new_location(const std::string &fle, size_t lne, size_t col)
Insert the triplet representing a source locus into our internal vector of location triplet....
Definition abg-ir.cc:794
void expand_location(const location &location, std::string &path, unsigned &line, unsigned &column) const
Given an instance of location type, return the triplet {path,line,column} that represents the source ...
Definition abg-ir.cc:818
The source location of a token.
Definition abg-ir.h:385
void set_artificial(size_t v)
Set the artificial-ness of the location.
Definition abg-ir.cc:667
location()
Default constructor for the location type.
Definition abg-ir.cc:692
bool get_is_artificial() const
Test if the location is artificial.
Definition abg-ir.cc:646
bool operator<(const location &other) const
"Less than" operator of the location type.
Definition abg-ir.cc:724
location & operator=(const location &l)
Assignment operator of the location.
Definition abg-ir.cc:683
bool operator==(const location &other) const
Equality operator of the location type.
Definition abg-ir.cc:714
unsigned get_value() const
Get the value of the location.
Definition abg-ir.cc:698
string expand(void) const
Expand the location into a string.
Definition abg-ir.cc:758
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the location into a tripplet path, line and column number.
Definition abg-ir.cc:738
Abstraction of a member function context relationship. This relates a member function to its parent c...
Definition abg-ir.h:4513
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition abg-ir.cc:28931
bool is_const() const
Getter for the 'is-const' property.
Definition abg-ir.cc:28978
size_t vtable_offset() const
Getter for the vtable offset property.
Definition abg-ir.cc:28905
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition abg-ir.cc:28954
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition abg-ir.h:3867
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition abg-ir.h:3887
bool get_is_static() const
Definition abg-ir.h:3899
Abstracts a member class template template.
Definition abg-ir.h:4643
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition abg-ir.cc:27968
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:28053
Abstract a member function template.
Definition abg-ir.h:4588
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:27947
Abstraction of the declaration of a method.
Definition abg-ir.h:3915
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition abg-ir.cc:7632
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition abg-ir.cc:26785
const method_type_sptr get_type() const
Definition abg-ir.cc:26817
Abstracts the type of a class member function.
Definition abg-ir.h:3527
void set_class_type(const class_or_union_sptr &t)
Sets the class type of the current instance of method_type.
Definition abg-ir.cc:23498
bool get_is_static() const
Fetter of the "is-static" property of method_type.
Definition abg-ir.cc:23563
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:23476
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition abg-ir.cc:23533
virtual bool traverse(ir_node_visitor &)
Traverses an instance of method_type, visiting all the sub-types and decls that it might contain.
Definition abg-ir.cc:23624
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition abg-ir.cc:23578
void set_is_static(bool)
Setter of the "is-static" property of method_type.
Definition abg-ir.cc:23553
virtual ~method_type()
The destructor of method_type.
Definition abg-ir.cc:23668
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Return a copy of the pretty representation of the current method_type.
Definition abg-ir.cc:23523
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition abg-ir.cc:23486
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition abg-ir.cc:23543
The abstraction of a namespace declaration.
Definition abg-ir.h:2211
bool is_empty_or_has_empty_sub_namespaces() const
Test if the current namespace_decl is empty or contains empty namespaces itself.
Definition abg-ir.cc:18200
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:18231
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition abg-ir.cc:18134
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition abg-ir.cc:18186
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build and return a copy of the pretty representation of the namespace.
Definition abg-ir.cc:18172
Abstracts non type template parameters.
Definition abg-ir.h:3690
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition abg-ir.cc:29352
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:29357
The abstraction of a pointer type.
Definition abg-ir.h:2354
void set_pointed_to_type(const type_base_sptr &)
Set the pointed-to type of the pointer.
Definition abg-ir.cc:18905
virtual void get_qualified_name(interned_string &, bool internal=false) const
Build and return the qualified name of the current instance of pointer_type_def.
Definition abg-ir.cc:19032
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18895
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:18822
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:19124
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition abg-ir.cc:18968
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition abg-ir.cc:19012
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition abg-ir.cc:19019
The abstraction of a pointer-to-member type.
Definition abg-ir.h:2489
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Get the qualified name for the current ptr_to_mbr_type.
Definition abg-ir.cc:19792
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
Definition abg-ir.cc:19702
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19715
const type_base_sptr & get_containing_type() const
Getter of the type containing the member pointed-to by the current ptr_to_mbr_type.
Definition abg-ir.cc:19735
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition abg-ir.cc:19776
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function for ptr_to_mbr_type.
Definition abg-ir.cc:19843
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition abg-ir.cc:19726
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition abg-ir.cc:19868
The abstraction of a qualified type.
Definition abg-ir.h:2240
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for qualified_type_def.
Definition abg-ir.cc:18535
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition abg-ir.cc:18668
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition abg-ir.cc:18399
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18387
string get_cv_quals_string_prefix() const
Compute and return the string prefix or suffix representing the qualifiers hold by the current instan...
Definition abg-ir.cc:18653
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition abg-ir.h:2259
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:18325
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition abg-ir.cc:18641
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:18607
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition abg-ir.cc:18633
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition abg-ir.cc:18658
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition abg-ir.cc:18479
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition abg-ir.cc:18302
The internal representation of an integral type.
Definition abg-ir-priv.h:69
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the real_type.
Definition abg-ir.cc:17577
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition abg-ir.cc:17600
base_type get_base_type() const
Getter of the base type of the real_type.
Definition abg-ir.cc:17563
bool operator==(const real_type &) const
Equality operator for the real_type.
Definition abg-ir.cc:17587
real_type()
Default constructor of the real_type.
Definition abg-ir.cc:17533
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
@ LONG_LONG_MODIFIER
The "long long" modifier.
@ LONG_MODIFIER
The "long" modifier.
@ SIGNED_MODIFIER
The "signed" modifier.
@ UNSIGNED_MODIFIER
The "unsigned" modier.
@ SHORT_MODIFIER
The "short" modifier.
base_type
The possible base types of integral types. We might have forgotten many of these, so do not hesitate ...
Definition abg-ir-priv.h:77
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
Definition abg-ir-priv.h:93
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
Definition abg-ir-priv.h:91
@ FLOAT_BASE_TYPE
The "float" base type.
Definition abg-ir-priv.h:87
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
Definition abg-ir-priv.h:83
@ CHAR_BASE_TYPE
The "char" base type.
Definition abg-ir-priv.h:81
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
Definition abg-ir-priv.h:89
@ INT_BASE_TYPE
The "int" base type.
Definition abg-ir-priv.h:79
@ ARRAY_SIZE_BASE_TYPE
The aray size type used by Clang.
Definition abg-ir-priv.h:99
@ DOUBLE_BASE_TYPE
The "double" base type.
Definition abg-ir-priv.h:85
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the real_type.
Definition abg-ir.cc:17570
Abstracts a reference type.
Definition abg-ir.h:2420
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Build and return the qualified name of the current instance of the reference_type_def.
Definition abg-ir.cc:19453
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19316
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:19218
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:19573
void set_pointed_to_type(type_base_sptr &pointed_to_type)
Setter of the pointed_to type of the current reference type.
Definition abg-ir.cc:19326
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition abg-ir.cc:19395
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of reference_type_def.
Definition abg-ir.cc:19552
A declaration that introduces a scope.
Definition abg-ir.h:1853
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl_sptr scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition abg-ir.cc:9616
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
Definition abg-ir.cc:9028
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition abg-ir.cc:9046
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition abg-ir.cc:9081
declarations get_member_decls_copy() const
Getter for a copy of the member declarations carried by the current scope_decl.
Definition abg-ir.cc:8987
std::vector< scope_decl_sptr > scopes
Convenience typedef for a vector of scope_decl_sptr.
Definition abg-ir.h:1864
bool is_empty() const
Test if the current scope is empty.
Definition abg-ir.cc:9095
type_base_sptrs_type get_sorted_member_types_copy() const
Get a copy of the sorted member types.
Definition abg-ir.cc:9325
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:9587
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition abg-ir.cc:9179
bool remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition abg-ir.cc:9258
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
Definition abg-ir.h:1860
const type_base_sptrs_type & get_sorted_canonical_types() const
Return a vector of sorted canonical types of the current scope.
Definition abg-ir.cc:8945
bool find_iterator_for_member(const decl_base *, declarations::iterator &)
Find a member of the current scope and return an iterator on it.
Definition abg-ir.cc:9538
type_base_sptr find_member_type(const string &name) const
Find a member type of a given name, inside the current scope_decl.
Definition abg-ir.cc:9190
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition abg-ir.cc:8969
const canonical_type_sptr_set_type & get_canonical_types() const
@eturn the set of canonical types of the the current scope.
Definition abg-ir.cc:8933
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition abg-ir.cc:9279
virtual bool operator==(const decl_base &) const
Return true iff both scopes have the same names and have the same member decls.
Definition abg-ir.cc:9492
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition abg-ir.cc:9005
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition abg-ir.cc:9064
A type that introduces a scope.
Definition abg-ir.h:2188
virtual bool traverse(ir_node_visitor &)
Traverses an instance of scope_type_decl, visiting all the sub-types and decls that it might contain.
Definition abg-ir.cc:18094
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition abg-ir.cc:18056
The base class of templates.
Definition abg-ir.h:3595
const std::list< template_parameter_sptr > & get_template_parameters() const
Get the list of template parameters of the current instance of template_decl.
Definition abg-ir.cc:29027
virtual ~template_decl()
Destructor.
Definition abg-ir.cc:29052
void add_template_parameter(const template_parameter_sptr p)
Add a new template parameter to the current instance of template_decl.
Definition abg-ir.cc:29019
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:29061
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition abg-ir.h:3627
virtual ~template_parameter()
Destructor.
Definition abg-ir.cc:29181
bool operator!=(const template_parameter &) const
Inequality operator.
Definition abg-ir.cc:29177
Abstracts a template template parameter.
Definition abg-ir.h:3723
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:29430
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
Definition abg-ir.h:692
const scope_decl_sptr get_global_scope() const
Getter of the the global scope of the translation unit.
Definition abg-ir.cc:1683
void set_address_size(char)
Setter of the address size in this translation unit.
Definition abg-ir.cc:1920
const type_sptr_set_type & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
Definition abg-ir.cc:1725
const std::string & get_absolute_path() const
Get the concatenation of the build directory and the relative path of the translation unit.
Definition abg-ir.cc:1820
void set_is_constructed(bool)
Setter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition abg-ir.cc:1958
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
Definition abg-ir.cc:1971
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
Definition abg-ir.cc:1872
char get_address_size() const
Getter of the address size in this translation unit.
Definition abg-ir.cc:1910
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
Definition abg-ir.cc:1795
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
Definition abg-ir.cc:1850
void set_language(language l)
Setter of the language of the source code of the translation unit.
Definition abg-ir.cc:1749
void bind_function_type_life_time(function_type_sptr) const
Ensure that the life time of a function type is bound to the life time of the current translation uni...
Definition abg-ir.cc:1997
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Definition abg-ir.cc:1896
bool is_constructed() const
Getter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition abg-ir.cc:1939
const std::string & get_path() const
Get the path of the current translation unit.
Definition abg-ir.cc:1765
void set_compilation_dir_path(const std::string &)
Set the path of the directory that was 'current' when the translation unit was compiled.
Definition abg-ir.cc:1809
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
Definition abg-ir.cc:1880
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
Definition abg-ir.cc:1779
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
Definition abg-ir.cc:2049
language
The language of the translation unit.
Definition abg-ir.h:706
bool operator!=(const translation_unit &) const
Inequality operator.
Definition abg-ir.cc:1986
const environment & get_environment() const
Getter of the environment of the current translation_unit.
Definition abg-ir.cc:1732
const type_maps & get_types() const
Getter of the types of the current translation_unit.
Definition abg-ir.cc:1709
language get_language() const
Getter of the language of the source code of the translation unit.
Definition abg-ir.cc:1739
bool visiting() const
This should returns false before and after the node has been visiting. During the visiting of the nod...
An abstraction helper for type declarations.
Definition abg-ir.h:2014
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition abg-ir.cc:17165
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition abg-ir.cc:17233
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:17132
virtual bool traverse(ir_node_visitor &)
Default implementation of traversal for types. This function does nothing. It must be implemented by ...
Definition abg-ir.cc:17268
virtual void on_canonical_type_set()
This method is invoked automatically right after the current instance of class_decl has been canonica...
Definition abg-ir.cc:16719
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition abg-ir.cc:17223
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition abg-ir.cc:17216
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition abg-ir.cc:17206
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition abg-ir.cc:17253
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition abg-ir.cc:17243
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition abg-ir.cc:17146
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition abg-ir.h:3758
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition abg-ir.cc:29536
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition abg-ir.cc:29543
A basic type declaration that introduces no scope.
Definition abg-ir.h:2122
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for type_decl.
Definition abg-ir.cc:17888
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:17728
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17967
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:17826
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:17782
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of type_decl.
Definition abg-ir.cc:17947
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
Definition abg-ir.h:593
istring_type_base_wptrs_map_type & typedef_types()
Getter for the map that associates the name of a typedef to the vector of instances of typedef_decl_s...
Definition abg-ir.cc:968
istring_type_base_wptrs_map_type & function_types()
Getter for the map that associates the name of a function type to the vector of instances of function...
Definition abg-ir.cc:1071
istring_type_base_wptrs_map_type & reference_types()
Getter for the map that associates the name of a reference type to the vector of instances of referen...
Definition abg-ir.cc:1022
const istring_type_base_wptrs_map_type & class_types() const
Getter for the map that associates the name of a class type to the vector of instances of class_decl_...
Definition abg-ir.cc:926
istring_type_base_wptrs_map_type & union_types()
Getter for the map that associates the name of a union type to the vector of instances of union_decl_...
Definition abg-ir.cc:940
istring_type_base_wptrs_map_type & array_types()
Getter for the map that associates the name of an array type to the vector of instances of array_type...
Definition abg-ir.cc:1036
istring_type_base_wptrs_map_type & enum_types()
Getter for the map that associates the name of an enum type to the vector of instances of enum_type_d...
Definition abg-ir.cc:954
bool empty() const
Test if the type_maps is empty.
Definition abg-ir.cc:894
istring_type_base_wptrs_map_type & qualified_types()
Getter for the map that associates the name of a qualified type to the vector of instances of qualifi...
Definition abg-ir.cc:981
istring_type_base_wptrs_map_type & ptr_to_mbr_types()
Getter for the map that associates the name of a pointer-to-member type to the vector of instances of...
Definition abg-ir.cc:1001
istring_type_base_wptrs_map_type & pointer_types()
Getter for the map that associates the name of a pointer type to the vector of instances of pointer_t...
Definition abg-ir.cc:994
const istring_type_base_wptrs_map_type & basic_types() const
Getter for the map that associates the name of a basic type to the vector instances of type_decl_sptr...
Definition abg-ir.cc:912
const vector< type_base_wptr > & get_types_sorted() const
Getter of all types types sorted by their pretty representation.
Definition abg-ir.cc:1583
const istring_type_base_wptrs_map_type & subrange_types() const
Getter for the map that associates the name of a subrange type to the vector of instances of array_ty...
Definition abg-ir.cc:1057
The base class of both types and declarations.
Definition abg-ir.h:1378
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:5251
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
Definition abg-ir.cc:5332
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:5033
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition abg-ir.cc:5022
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition abg-ir.cc:5184
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition abg-ir.cc:5191
std::recursive_mutex & get_mutex() const
Get the recursive mutex associated to the artifact.
Definition abg-ir.cc:5359
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition abg-ir.cc:5243
friend hash_t set_or_get_cached_hash_value(const T &type_or_decl)
Set the hash value of an IR node and return it.
offset_t get_native_offset() const
Get the native offset of a given artifact.
Definition abg-ir.cc:5205
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:5135
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition abg-ir.cc:5056
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:5045
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition abg-ir.cc:5367
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition abg-ir.cc:5076
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition abg-ir.cc:12404
void set_native_offset(const offset_t)
Set the native offset of a given artifact.
Definition abg-ir.cc:5216
void set_original_artefact(const type_or_decl_base *)
Set the original artefact that the current artefact was copied from.
Definition abg-ir.cc:5305
const type_or_decl_base * get_original_artefact() const
Get the original artefact that the current artefact was copied from.
Definition abg-ir.cc:5296
void set_corpus(corpus *) const
Set the ABI corpus associated to the current ABI artifact.
Definition abg-ir.cc:5233
const void * type_or_decl_base_pointer() const
Getter of the pointer to either the type_base sub-object of the current instance if it's a type,...
Definition abg-ir.cc:5111
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:11971
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition abg-ir.cc:5166
type_or_decl_kind
This is a bitmap type which instance is meant to contain the runtime type of a given ABI artifact....
Definition abg-ir.h:1389
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition abg-ir.cc:5148
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition abg-ir.cc:12044
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:5283
Abstracts a type template parameter.
Definition abg-ir.h:3656
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:29223
The abstraction of a typedef declaration.
Definition abg-ir.h:2936
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation of the virtual "get_qualified_name" method.
Definition abg-ir.cc:22045
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition abg-ir.cc:22030
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition abg-ir.cc:21860
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:21847
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:22077
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition abg-ir.cc:22023
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:21966
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition abg-ir.cc:21889
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build a pretty representation for a typedef_decl.
Definition abg-ir.cc:22007
Abstracts a union type declaration.
Definition abg-ir.h:4449
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:28328
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:28445
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition abg-ir.cc:28385
virtual ~union_decl()
Destructor of the union_decl type.
Definition abg-ir.cc:28519
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Getter of the pretty representation of the current instance of union_decl.
Definition abg-ir.cc:28352
Abstracts a variable declaration.
Definition abg-ir.h:3069
binding get_binding() const
Getter of the binding of the variable.
Definition abg-ir.cc:22196
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition abg-ir.cc:22178
void set_binding(binding b)
Setter of the binding of the variable.
Definition abg-ir.cc:22203
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition abg-ir.cc:7285
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition abg-ir.cc:22241
virtual const interned_string & get_qualified_name(bool internal=false) const
Get the qualified name of a given variable or data member.
Definition abg-ir.cc:22495
const elf_symbol_sptr get_symbol() const
Gets the the underlying ELF symbol for the current variable, that was set using var_decl::set_symbol(...
Definition abg-ir.cc:22234
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition abg-ir.cc:22189
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:7430
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition abg-ir.cc:22171
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:22657
string get_anon_dm_reliable_name(bool qualified=true) const
Get a name that is valid even for an anonymous data member.
Definition abg-ir.cc:22634
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition abg-ir.cc:22218
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition abg-ir.cc:22425
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build and return the pretty representation of this variable.
Definition abg-ir.cc:22525
interned_string get_id() const
Return an ID that tries to uniquely identify the variable inside a program or a library.
Definition abg-ir.cc:22444
A type used to time various part of the libabigail system.
bool stop()
Stop the timer.
bool start()
Start the timer.
This represents a queue of tasks to be performed.
tasks_type & get_completed_tasks() const
Getter of the vector of tasks that got performed.
void wait_for_workers_to_complete()
Suspends the current thread until all worker threads finish performing the tasks they are executing.
bool schedule_task(const task_sptr &)
Submit a task to the queue of tasks to be performed.
This represents a task to be performed.
Definition abg-workers.h:48
bool is_decl_only_class_with_size_change(const class_or_union &first, const class_or_union &second)
Test if two classes that are decl-only (have the decl-only flag and carry no data members) but are di...
ostream & operator<<(ostream &o, diff_category c)
Serialize an instance of diff_category to an output stream.
hash_t combine_hashes(hash_t val1, hash_t val2)
Combine two hash values to produce a third hash value.
Definition abg-hash.cc:172
@ HASHING_FINISHED_STATE
Hashing of the given IR node started, is done and a hash value has been stored onto the node....
Definition abg-hash.h:50
shared_ptr< homonym_type_group > homonym_type_group_sptr
A typedef for shared pointer of homonym_type_group_sptr.
real_type::modifiers_type operator~(real_type::modifiers_type l)
Bitwise one's complement operator for real_type::modifiers_type.
Definition abg-ir.cc:17325
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
Definition abg-fwd.h:236
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl_sptr scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition abg-ir.cc:9616
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition abg-ir.cc:30224
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition abg-ir.cc:7544
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition abg-ir.cc:8357
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
Definition abg-ir.cc:30142
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
Definition abg-ir.cc:13636
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
Definition abg-fwd.h:222
void add_member_type(scope_decl_sptr scope, type_base_sptr t)
Add a member type to a given scope.
Definition abg-ir.cc:9231
size_t hash_type(const type_base *t)
Hash an ABI artifact that is a type.
Definition abg-ir.cc:30120
const type_base_sptr lookup_type_in_scope(const string &fqn, scope_decl_sptr skope)
Lookup a type in a scope.
Definition abg-ir.cc:14149
void hash_and_canonicalize_types(SequenceType &types, bool do_log=false, bool show_stats=false)
Hash and canonicalize a sequence of types.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
Definition abg-ir.cc:13540
var_decl_sptr get_last_data_member(const class_or_union &klass)
Get the last data member of a class type.
Definition abg-ir.cc:6865
bool is_anonymous_or_typedef_named(const decl_base &d)
Test if a given decl is anonymous or has a naming typedef.
Definition abg-ir.cc:7240
scope_decl_sptr get_top_most_scope_under(decl_base_sptr decl, scope_decl_sptr scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
Definition abg-ir.cc:9816
void add_data_member(class_or_union_sptr cou, var_decl_sptr v, access_specifier access, bool is_laid_out, bool is_static, size_t offset_in_bits)
Add a data member to the current instance of class_or_union.
Definition abg-ir.cc:25165
weak_ptr< var_decl > var_decl_wptr
Convenience typedef for a weak pointer on a var_decl.
Definition abg-fwd.h:260
bool equals(const decl_base &l, const decl_base &r, change_kind *k, bool qualified_name, bool linkage_name)
Compares two instances of decl_base.
Definition abg-ir.cc:6243
bool is_template_parm_composition_type(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter composition type.
Definition abg-ir.cc:13326
bool is_function_template_pattern(decl_base_sptr decl)
Test whether a decl is the pattern of a function template.
Definition abg-ir.cc:13340
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
Definition abg-ir.cc:6684
unordered_map< uint64_t_pair_type, bool, uint64_t_pair_hash > type_comparison_result_type
A convenience typedef for a map which key is a pair of uint64_t and which value is a boolean....
pointer_type_def_sptr is_pointer_to_npaf_type(const type_base_sptr &t)
Test if we are looking at a pointer to a neither-a-pointer-to-an-array-nor-a-function type.
Definition abg-ir.cc:12784
bool debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
Test if two ABI artifacts are equal.
Definition abg-ir.cc:11373
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition abg-fwd.h:273
access_specifier
Access specifier for class members.
Definition abg-ir.h:915
size_t get_canonical_type_index(const type_base &t)
Getter of the canonical type index of a given type.
Definition abg-ir.cc:492
const type_base_wptrs_type * lookup_enum_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
Definition abg-ir.cc:15250
const global_scope_sptr get_global_scope(decl_base_sptr decl)
Return the global scope as seen by a given declaration.
Definition abg-ir.cc:9734
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition abg-ir.cc:24390
pointer_type_def_sptr is_pointer_to_array_type(const type_base_sptr &t)
Test if a type is a pointer to array type.
Definition abg-ir.cc:12766
interned_string get_function_symbol_id(const function_decl *fn)
Get the ID of the symbol of a function or the linkage name of the function if it has no symbol.
Definition abg-ir.cc:10386
bool compare_canonical_type_against_candidate(const type_base_sptr &canonical_type, const type_base_sptr &candidate_type)
Compare a canonical type against a candidate canonical type.
Definition abg-ir.cc:16551
bool type_is_suitable_for_hash_computing(const type_base &)
Test if we should attempt to compute a hash value for a given type.
Definition abg-ir.cc:16643
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
Definition abg-fwd.h:293
weak_ptr< function_type > function_type_wptr
Convenience typedef for a weak pointer on a function_type.
Definition abg-fwd.h:217
type_base_sptr lookup_class_or_typedef_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, union or typedef type which has a given qualified name.
Definition abg-ir.cc:15448
void copy_missing_member_variables(class_or_union_sptr &dest_class, const class_or_union_sptr &src_class)
Copy missing data members from a source class_decl to a destination one.
Definition abg-ir.cc:28659
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition abg-ir.cc:7675
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
void add_member_function_template(class_or_union_sptr cou, member_function_template_sptr m)
Append a member function template to the class_or_union.
Definition abg-ir.cc:25613
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
Definition abg-fwd.h:143
type_base_sptr candidate_matches_a_canonical_type_hash(const list< type_base_sptr > &cncls, type_base &type)
Test if a candidate for type canonicalization coming from ABIXML matches a canonical type by first lo...
Definition abg-ir.cc:16576
bool is_at_template_scope(decl_base_sptr decl)
Tests whether a given decl is at template scope.
Definition abg-ir.cc:11896
weak_ptr< scope_decl > scope_decl_wptr
Convenience typedef for a weak pointer on a scope_decl.
Definition abg-fwd.h:268
class_or_union_sptr is_at_class_scope(const decl_base_sptr decl)
Tests whether a given decl is at class scope.
Definition abg-ir.cc:11792
void fixup_virtual_member_function(method_decl_sptr method)
When a virtual member function has seen its virtualness set by set_member_function_is_virtual(),...
Definition abg-ir.cc:27048
bool equals_modulo_cv_qualifier(const array_type_def *l, const array_type_def *r)
Test if two array types are equals modulo CV qualifiers.
Definition abg-ir.cc:20690
const scope_decl * is_scope_decl(const decl_base *d)
Test if a declaration is a scope_decl.
Definition abg-ir.cc:6542
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition abg-ir.cc:8711
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
Definition abg-ir.cc:13017
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition abg-ir.cc:12031
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition abg-ir.cc:6957
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
Definition abg-ir.cc:2061
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
Definition abg-fwd.h:129
type_base_sptr peel_reference_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a reference_type_def node.
Definition abg-ir.cc:8266
bool remove_member_decl(scope_decl_sptr scope, decl_base_sptr member)
Remove a declaration from the current scope.
Definition abg-ir.cc:9377
class_decl::base_spec * is_class_base_spec(const type_or_decl_base *tod)
Test if an ABI artifact is a class base specifier.
Definition abg-ir.cc:27862
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition abg-ir.cc:6496
unordered_set< const class_or_union * > class_set_type
A convenience typedef for a set of pointer to class_or_union.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
Definition abg-ir.cc:13446
T * maybe_get_canonical_type(T *t)
Get the canonical type of a given type T* as a T*.
Definition abg-ir.cc:1211
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition abg-ir.h:924
type_base_sptr get_exemplar_type(type_base_sptr type)
For a given type, return its exemplar type.
Definition abg-ir.cc:30277
type_base_sptr lookup_type_from_translation_unit(const string &type_name, const string &tu_path, const corpus &corp)
Lookup a type from a given translation unit present in a give corpus.
Definition abg-ir.cc:14790
namespace_decl_sptr is_namespace(const type_or_decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition abg-ir.cc:13308
bool type_originates_from_corpus(type_base_sptr t, corpus_sptr &c)
Test if a type originates from a corpus.
Definition abg-ir.cc:525
bool parse_real_type(const string &type_name, real_type &type)
Parse a real type from a string.
Definition abg-ir.cc:17518
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition abg-ir.cc:9642
typedef_decl_sptr copy_missing_naming_typedef(decl_base_sptr type, const decl_base_sptr named_type)
Copy the naming typedef from a named type to an unnamed one.
Definition abg-ir.cc:28683
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
Definition abg-ir.cc:11392
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition abg-ir.cc:8641
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
Definition abg-ir.h:1332
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
Definition abg-ir.h:1336
@ SUBTYPE_CHANGE_KIND
This means that a given IR artifact has changes in some of its sub-types, with respect to the other a...
Definition abg-ir.h:1352
@ LOCAL_NON_TYPE_CHANGE_KIND
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
Definition abg-ir.h:1341
var_decl_sptr find_last_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &regex)
Find the last data member of a class or union which name matches a regular expression.
Definition abg-ir.cc:30815
void maybe_update_types_lookup_map(const decl_base_sptr decl)
Update the map that associates the fully qualified name of a type declaration with the type itself.
Definition abg-ir.cc:16042
const ptr_to_mbr_type * is_ptr_to_mbr_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type.
Definition abg-ir.cc:12941
const var_decl_sptr get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
Get the first non-anonymous data member of a given anonymous data member.
Definition abg-ir.cc:6800
class_decl_sptr lookup_class_type_through_scopes(const list< string > &fqn, const translation_unit &tu)
Lookup a class type from a translation unit by walking its scopes in sequence and by looking into the...
Definition abg-ir.cc:14515
unordered_set< const function_type * > fn_set_type
A convenience typedef for a set of pointer to function_type.
string get_enum_flat_representation(const enum_type_decl &enum_type, const string &indent, bool one_line, bool qualified_names)
Get the flat representation of an instance of enum_type_decl type.
Definition abg-ir.cc:10910
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition abg-ir.cc:6588
bool operator==(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep comparison operator for pointers to translation units.
Definition abg-ir.cc:2370
void move_member_type_to_canonicalized_scope(decl_base_sptr member_type)
Move a member type from its current scope to the canonical type of its current scope.
Definition abg-ir.cc:31768
decl_base_sptr lookup_var_decl_in_scope(const string &fqn, scope_decl_sptr skope)
Lookup a var_decl in a scope.
Definition abg-ir.cc:14166
shared_ptr< c14n_task > c14n_task_sptr
A convenience typedef for a shared pointer to c14n_task.
weak_ptr< class_decl > class_decl_wptr
Convenience typedef for a weak pointer on a class_decl.
Definition abg-fwd.h:203
string components_to_type_name(const list< string > &comps)
Turn a set of qualified name components (that name a type) into a qualified name string.
Definition abg-ir.cc:13566
scope_decl_sptr get_scope_of_type(type_base &type)
Getter of the scope of a type.
Definition abg-ir.cc:9759
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
Definition abg-ir.cc:1405
decl_base_sptr add_member_decl(scope_decl_sptr scope, decl_base_sptr member)
Add a member decl to this scope. Note that user code should not use this, but rather use add_decl_to_...
Definition abg-ir.cc:9147
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
Definition abg-ir.h:146
bool collect_non_anonymous_data_members(const class_or_union *cou, string_decl_base_sptr_map &dms)
Collect all the non-anonymous data members of a class or union type.
Definition abg-ir.cc:6899
shared_ptr< global_scope > global_scope_sptr
Convenience typedef for shared pointer on global_scope.
Definition abg-fwd.h:303
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition abg-ir.cc:12395
type_base_sptr synthesize_type_from_translation_unit(const type_base_sptr &type, translation_unit &tu)
In a translation unit, lookup a given type or synthesize it if it's a qualified type.
Definition abg-ir.cc:16069
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition abg-fwd.h:245
function_type_sptr lookup_or_synthesize_fn_type(const function_type_sptr &fn_t, const corpus &corpus)
Look into an ABI corpus for a function type.
Definition abg-ir.cc:14815
bool is_declaration_only_class_or_union_type(const type_base *t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Definition abg-ir.cc:12579
decl_base_sptr insert_decl_into_scope(decl_base_sptr decl, scope_decl::declarations::iterator before, scope_decl_sptr scope)
Inserts a declaration into a given scope, before a given IR child node of the scope.
Definition abg-ir.cc:9666
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
Definition abg-ir.cc:10511
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
Definition abg-ir.cc:12080
type_base_sptr lookup_class_typedef_or_enum_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, typedef or enum type which has a given qualified name.
Definition abg-ir.cc:15473
void bind_function_type_life_time(const function_type_sptr &fn_type, translation_unit_sptr tu)
Bind the life time of a function type to the file time of a given translation unit.
Definition abg-ir.cc:31838
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
Definition abg-ir.cc:8426
bool maybe_update_types_lookup_map< function_type >(const function_type_sptr type, istring_type_base_wptrs_map_type &types_map, recursive_mutex &mutex, bool)
This is the specialization for type function_type of the function template:
Definition abg-ir.cc:15986
bool has_defined_virtual_mem_fn(const class_decl &klass)
Test if a class has at least one member function which has a defined and exported symbol.
Definition abg-ir.cc:30166
const class_or_union_sptr data_member_has_anonymous_type(const var_decl &d)
Test if a data member has annonymous type or not.
Definition abg-ir.cc:7143
void maybe_adjust_canonical_type(const type_base_sptr &canonical, const type_base_sptr &type)
This is a subroutine of the canonicalize() function.
Definition abg-ir.cc:16738
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition abg-ir.cc:12197
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
Definition abg-ir.cc:7199
void add_type(type_base_sptr t, homonym_type_group_sptr group)
Add a type to a homonym type group.
Definition abg-ir.cc:4002
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
Definition abg-ir.cc:15113
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition abg-ir.cc:7574
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition abg-ir.cc:8315
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
Definition abg-ir.cc:13967
bool types_have_similar_structure(const type_base_sptr &first, const type_base_sptr &second, bool indirect_type)
Test if two types have similar structures, even though they are (or can be) different.
Definition abg-ir.cc:30453
corpus_group_sptr is_corpus_group(const corpus_sptr &corpus)
Test if a corpus is a corpus_group.
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
Definition abg-fwd.h:318
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
Definition abg-ir.cc:12626
var_decl_sptr get_data_member(class_or_union *clazz, const char *member_name)
Get a given data member, referred to by its name, of a class type.
Definition abg-ir.cc:11255
type_base * look_through_decl_only_type(type_base *t)
If a type is is decl-only, then get its definition. Otherwise, just return the initial type.
Definition abg-ir.cc:13257
const var_decl_sptr get_next_data_member(const class_or_union *klass, const var_decl_sptr &data_member)
In the context of a given class or union, this function returns the data member that is located after...
Definition abg-ir.cc:6825
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition abg-fwd.h:194
function_decl_sptr is_at_function_scope(const decl_base &decl)
Tests whether a given decl is at function scope.
Definition abg-ir.cc:11834
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def,...
Definition abg-ir.cc:8502
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
Definition abg-ir.cc:7632
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
Definition abg-ir.cc:8007
bool is_comparison_cycle_detected(T &l, T &r)
Detect if a recursive comparison cycle is detected while structurally comparing two types (a....
Definition abg-ir.cc:1310
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
Definition abg-ir.cc:3693
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
Definition abg-ir.cc:12139
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:12011
interned_string get_function_symbol_id_if_unique(const function_decl *fn)
Get the ID of the symbol of a function, or, if the ID can designate several different functions,...
Definition abg-ir.cc:10407
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
Definition abg-ir.cc:13197
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
Definition abg-ir.cc:13088
bool is_template_parameter(decl_base_sptr decl)
Tests whether a decl is a template parameter.
Definition abg-ir.cc:11905
string get_name(const type_or_decl_base *tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type or a decl.
Definition abg-ir.cc:9888
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition abg-ir.cc:6653
const class_decl * is_compatible_with_class_type(const type_base *t)
Test if a type is a class. This function looks through typedefs.
Definition abg-ir.cc:12348
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition abg-ir.cc:12241
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
Definition abg-ir.h:109
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition abg-ir.cc:7402
enum_type_decl_sptr lookup_enum_type_per_location(const interned_string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
Definition abg-ir.cc:15298
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition abg-ir.cc:11059
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition abg-fwd.h:211
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition abg-fwd.h:168
function_type_sptr synthesize_function_type_from_translation_unit(const function_type &fn_type, translation_unit &tu)
In a translation unit, lookup the sub-types that make up a given function type and if the sub-types a...
Definition abg-ir.cc:16152
std::ostream & operator<<(std::ostream &o, elf_symbol::type t)
Serialize an instance of symbol_type and stream it to a given output stream.
Definition abg-ir.cc:3565
type_base_sptr peel_pointer_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a pointer_type_def node.
Definition abg-ir.cc:8210
bool var_equals_modulo_types(const var_decl &l, const var_decl &r, change_kind *k)
Compares two instances of var_decl without taking their type into account.
Definition abg-ir.cc:22302
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
Definition abg-ir.cc:13676
type_base_sptr lookup_type_through_translation_units(const string &qn, const corpus &abi_corpus)
Lookup a type definition in all the translation units of a given ABI corpus.
Definition abg-ir.cc:14764
qualified_type_def_sptr is_array_of_qualified_element(const array_type_def_sptr &array)
Tests if the element of a given array is a qualified type.
Definition abg-ir.cc:13386
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
Definition abg-ir.cc:12844
type_base * peel_pointer_or_reference_type(const type_base *type, bool peel_qual_type)
Return the leaf underlying or pointed-to type node of a, pointer_type_def, reference_type_def or qual...
Definition abg-ir.cc:8604
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
Definition abg-ir.cc:12881
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
bool elf_symbol_is_function(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
Definition abg-ir.cc:3774
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition abg-ir.cc:2329
bool lookup_decl_only_class_types(const interned_string &qualified_name, const corpus &corp, type_base_wptrs_type &result)
Look into a given corpus to find the class type*s* that have a given qualified name and that are decl...
Definition abg-ir.cc:15037
bool member_function_has_vtable_offset(const function_decl &f)
Test if a virtual member function has a vtable offset set.
Definition abg-ir.cc:7664
void perform_type_canonicalization(vector< type_base_sptr > &types, bool do_log, bool show_stats)
Hash and canonicalize a sequence of types.
Definition abg-ir.cc:31859
void copy_missing_member_functions(class_or_union_sptr &dest_class, const class_or_union_sptr &src_class, bool copy_virtual_functions)
Copy missing member functions from a source class_decl to a destination one.
Definition abg-ir.cc:28600
unordered_map< interned_string, bool, hash_interned_string > interned_string_bool_map_type
Convenience typedef for a map of interned_string -> bool.
Definition abg-ir.cc:4248
bool compute_canonical_type_index(const list< type_base_sptr > &adjacent_canonical_types, const type_base_sptr canonical_type, int &resulting_index)
Compute the canonical type index of a recently designated canonical type.
Definition abg-ir.cc:16684
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
Definition abg-ir.cc:12330
unordered_map< interned_string, type_base_wptrs_type, hash_interned_string > istring_type_base_wptrs_map_type
A convenience typedef for a map which key is an interned_string and which value is a vector of type_b...
Definition abg-fwd.h:149
bool function_decl_is_less_than(const function_decl &f, const function_decl &s)
Test if the pretty representation of a given function_decl is lexicographically less then the pretty ...
Definition abg-ir.cc:30401
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
Definition abg-ir.cc:3489
var_decl_sptr find_data_member_from_anonymous_data_member(const var_decl_sptr &anon_dm, const string &name)
Find a data member inside an anonymous data member.
Definition abg-ir.cc:11874
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition abg-fwd.h:257
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
Definition abg-fwd.h:240
const location & get_natural_or_artificial_location(const decl_base *decl)
Get the non-artificial (natural) location of a decl.
Definition abg-ir.cc:11283
size_t hash_type_or_decl(const type_or_decl_base *tod)
Hash an ABI artifact that is either a type or a decl.
Definition abg-ir.cc:30033
method_decl_sptr copy_member_function(class_or_union_sptr t, const method_decl_sptr &method)
Copy a method of a class_or_union into a new class_or_union.
Definition abg-ir.cc:26001
bool enum_equals_modulo_name(const enum_type_decl &l, const enum_type_decl &r, change_kind *k)
Test if two enums are equal modulo their names. That is, the test compares the two enums as if they d...
Definition abg-ir.cc:21539
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
void move_member_type(decl_base_sptr member_type, scope_decl_sptr new_scope)
Move a member type of a scope_decl to another scope_decl.
Definition abg-ir.cc:26138
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
Definition abg-ir.cc:13469
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition abg-fwd.h:265
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
Definition abg-ir.cc:3726
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Definition abg-fwd.h:118
pointer_type_def_sptr lookup_pointer_type(const interned_string &type_name, const translation_unit &tu)
Lookup a pointer type from a translation unit.
Definition abg-ir.cc:13905
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition abg-fwd.h:137
bool is_data_member_of_anonymous_class_or_union(const var_decl &d)
Test if a var_decl is a data member belonging to an anonymous type.
Definition abg-ir.cc:7075
bool integral_type_has_harmless_name_change(const type_base_sptr &f, const type_base_sptr &s)
Test if a diff node carries a change whereby two integral types have different names in a harmless wa...
Definition abg-ir.cc:31390
const type_base * is_void_pointer_type_equivalent(const type_base *type)
Test if a type is equivalent to a pointer to void type.
Definition abg-ir.cc:12980
unordered_map< const function_decl *, string, function_decl_hash, function_decl::ptr_equal > fns_to_str_map_type
Convenience typedef for a hash map of pointer to function_decl and string.
Definition abg-ir.cc:32243
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition abg-ir.cc:13475
bool try_canonical_compare(const T *l, const T *r)
Compare two types by comparing their canonical types if present.
Definition abg-ir.cc:1231
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
Definition abg-ir.cc:29969
unordered_map< string, decl_base_sptr > string_decl_base_sptr_map
Convenience typedef for a map which key is a string and which value is a decl_base_sptr.
Definition abg-fwd.h:158
qualified_type_def_sptr lookup_qualified_type(const interned_string &type_name, const translation_unit &tu)
Lookup a qualified type from a translation unit.
Definition abg-ir.cc:13859
string build_qualified_name(const scope_decl_sptr scope, const string &name)
Build and return a qualified name from a name and its scope.
Definition abg-ir.cc:9934
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
Definition abg-ir.cc:2345
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:11948
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:7430
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
Definition abg-ir.cc:13713
bool string_to_elf_symbol_visibility(const string &s, elf_symbol::visibility &v)
Convert a string representing a an elf symbol visibility into an elf_symbol::visibility.
Definition abg-ir.cc:3751
bool maybe_update_types_lookup_map< class_decl >(const class_decl_sptr class_type, istring_type_base_wptrs_map_type &map, recursive_mutex &mutex, bool use_type_name_as_key)
This is the specialization for type class_decl of the function template:
Definition abg-ir.cc:15933
void add_member_function(class_or_union_sptr cou, method_decl_sptr f, access_specifier a, bool is_static, bool is_ctor, bool is_dtor, bool is_const)
Add a member function.
Definition abg-ir.cc:25436
const enum_type_decl * is_compatible_with_enum_type(const type_base *t)
Test if a type is an enum. This function looks through typedefs.
Definition abg-ir.cc:12281
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition abg-ir.h:927
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition abg-ir.cc:7602
interned_string get_name_of_reference_to_type(const type_base &pointed_to_type, bool lvalue_reference, bool qualified, bool internal)
Get the name of the reference to a given type.
Definition abg-ir.cc:10248
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition abg-fwd.h:227
type_base_sptr canonicalize(type_base_sptr type, homonym_type_group_sptr group, bool do_log=false, bool show_stats=false)
Compute the canonical type of a given type.
Definition abg-ir.cc:16924
bool is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr, const enum_type_decl &enom)
Test if a given enumerator is found present in an enum.
Definition abg-ir.cc:21248
decl_base_sptr insert_member_decl(scope_decl_sptr scope, decl_base_sptr member, scope_decl::declarations::iterator before)
Insert a member decl to a scope, right before an element pointed to by a given iterator....
Definition abg-ir.cc:9345
void sort_types_for_hash_computing_and_c14n(IteratorType begin, IteratorType end, bool do_log=false)
Sort types before hashing (and then canonicalizing) them.
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
Definition abg-ir.cc:8394
translation_unit::language string_to_translation_unit_language(const string &l)
Parse a string representing a language into a translation_unit::language enumerator into a string.
Definition abg-ir.cc:2191
type_base_sptr lookup_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a type from a corpus, by its location.
Definition abg-ir.cc:15795
bool get_next_data_member_offset(const class_or_union *klass, const var_decl_sptr &dm, uint64_t &offset)
Get the offset of the non-static data member that comes after a given one.
Definition abg-ir.cc:7315
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition abg-ir.cc:7359
shared_ptr< ir_traversable_base > ir_traversable_base_sptr
Convenience typedef for a shared pointer to ir_traversable_base.
Definition abg-fwd.h:106
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
Definition abg-ir.cc:7454
const function_decl::parameter * get_function_parameter(const decl_base *fun, unsigned parm_index)
Get the function parameter designated by its index.
Definition abg-ir.cc:30747
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition abg-ir.cc:13289
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
Definition abg-ir.cc:2313
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:11971
void keep_type_alive(type_base_sptr t)
Make sure that the life time of a given (smart pointer to a) type is the same as the life time of the...
Definition abg-ir.cc:30007
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
Definition abg-ir.cc:26879
array_type_def_sptr lookup_array_type(const interned_string &type_name, const translation_unit &tu)
Lookup an array type from a translation unit.
Definition abg-ir.cc:14011
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition abg-ir.cc:6561
string get_class_or_union_flat_representation(const class_or_union &cou, const string &indent, bool one_line, bool internal, bool qualified_names)
Get the flat representation of an instance of class_or_union type.
Definition abg-ir.cc:10733
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
Definition abg-ir.cc:30769
bool is_npaf_type(const type_base_sptr &t)
Test if a type is a neither a pointer, an array nor a function type.
Definition abg-ir.cc:12124
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:6624
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition abg-fwd.h:176
void set_data_member_offset(var_decl_sptr m, uint64_t o)
Set the offset of a data member into its containing class.
Definition abg-ir.cc:7253
type_base_sptr hash_and_canonicalize_type(type_base_sptr t)
Hash and canonicalize a type.
Definition abg-ir.cc:17022
scope_decl_sptr get_type_scope(type_base *t)
Get the scope of a given type.
Definition abg-ir.cc:10002
void set_member_function_virtuality(const function_decl_sptr &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
Definition abg-ir.cc:7820
type_base_sptr strip_typedef(const type_base_sptr type)
Recursively returns the the underlying type of a typedef. The return type should not be a typedef of ...
Definition abg-ir.cc:7851
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition abg-ir.cc:7270
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
Definition abg-ir.h:103
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:7742
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition abg-ir.cc:12709
string get_class_or_enum_flat_representation(const type_base &coe, const string &indent, bool one_line, bool internal, bool qualified_name)
Get the flat representation of an instance of enum_type_decl type.
Definition abg-ir.cc:11031
class_or_union * anonymous_data_member_to_class_or_union(const var_decl *d)
Get the class_or_union type of a given anonymous data member.
Definition abg-ir.cc:7115
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition abg-ir.cc:9968
pointer_type_def_sptr is_pointer_to_function_type(const type_base_sptr &t)
Test if a type is a pointer to function type.
Definition abg-ir.cc:12749
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition abg-ir.cc:11688
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
Definition abg-fwd.h:182
var_decl_sptr has_fake_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with one element.
Definition abg-ir.cc:12506
interned_string get_function_type_name(const function_type_sptr &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
Definition abg-ir.cc:10325
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
Definition abg-ir.cc:13148
void sort_types(IteratorType begin, IteratorType end, SortingFunctorType comp, bool do_log=false)
Sort types.
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition abg-ir.cc:12675
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition abg-ir.cc:11302
enum_type_decl_sptr lookup_enum_type(const interned_string &type_name, const translation_unit &tu)
Lookup an enum type from a translation unit.
Definition abg-ir.cc:13781
type_base_sptr peel_typedef_type(const type_base_sptr &type)
Return the leaf underlying type node of a typedef_decl node.
Definition abg-ir.cc:8155
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
Definition abg-ir.cc:15068
var_decl_sptr copy_member_variable(class_or_union_sptr t, const var_decl *variable)
Copy a data member of a class_or_union into a new class_or_union.
Definition abg-ir.cc:26074
interned_string get_name_of_qualified_type(const type_base_sptr &underlying_type, qualified_type_def::CV quals, bool qualified, bool internal)
Get the name of a qualified type, given the underlying type and its qualifiers.
Definition abg-ir.cc:10278
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
Definition abg-fwd.h:310
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
Definition abg-ir.cc:13424
function_type_sptr lookup_function_type(const interned_string &type_name, const translation_unit &tu)
Lookup a function type from a translation unit.
Definition abg-ir.cc:14031
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
Definition abg-ir.cc:11737
string get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
Get the string representation of a CV qualifier bitmap.
Definition abg-ir.cc:9858
void set_data_member_is_laid_out(var_decl_sptr m, bool l)
Set a flag saying if a data member is laid out.
Definition abg-ir.cc:7416
pointer_type_def_sptr is_pointer_to_ptr_to_mbr_type(const type_base_sptr &t)
Test if we are looking at a pointer to pointer to member type.
Definition abg-ir.cc:12801
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition abg-ir.cc:6722
var_decl_sptr find_first_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &r)
Find the first data member of a class or union which name matches a regular expression.
Definition abg-ir.cc:30794
const type_base_wptrs_type * lookup_class_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
Definition abg-ir.cc:14999
void insert_member_type(scope_decl_sptr scope, type_base_sptr t, scope_decl::declarations::iterator before)
Insert a member type to a given scope.
Definition abg-ir.cc:9207
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition abg-ir.cc:11414
var_decl_sptr has_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with non-finite data member.
Definition abg-ir.cc:12436
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition abg-ir.cc:28108
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
Definition abg-ir.cc:13353
unordered_set< type_base_sptr, shallow_type_hasher, shallow_type_eq > type_sptr_set_type
Convenience typedef for a set of type_base_sptr.
Definition abg-ir.h:194
interned_string get_method_type_name(const method_type_sptr fn_type, bool internal)
Get the name of a given method type and return a copy of it.
Definition abg-ir.cc:10433
weak_ptr< template_decl > template_decl_wptr
Convenience typedef for a weak pointer to template_decl.
Definition abg-fwd.h:313
const var_decl * lookup_data_member(const type_base *type, const char *dm_name)
Look for a data member of a given class, struct or union type and return it.
Definition abg-ir.cc:30704
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition abg-fwd.h:162
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition abg-ir.cc:8685
type_decl_sptr lookup_basic_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a type_decl type from a given corpus, by its location.
Definition abg-ir.cc:14887
bool classes_have_same_layout(const type_base_sptr &f, const type_base_sptr &s)
Test if two classes have the same layout.
Definition abg-ir.cc:11447
const type_base_sptr lookup_type_through_scopes(const type_base_sptr type, const translation_unit &tu)
Lookup a type from a translation unit by walking the scopes of the translation unit in sequence and l...
Definition abg-ir.cc:14448
type_or_decl_base * debug(const type_or_decl_base *artifact)
Emit a textual representation of an artifact to std error stream for debugging purposes.
Definition abg-ir.cc:11322
void set_pattern(function_tdecl_sptr ftdecl, function_decl_sptr p)
Set a new pattern to the function template.
Definition abg-ir.cc:29636
unordered_set< type_base_sptr, canonical_type_hash > canonical_type_sptr_set_type
Helper typedef for an unordered set of type_base_sptr which uses pointer value to tell its members ap...
Definition abg-ir.h:133
bool return_comparison_result(T &l, T &r, bool value)
Return the result of the comparison of two (sub) types.
Definition abg-ir.cc:1553
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition abg-fwd.h:288
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
Definition abg-ir.cc:2354
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
Definition abg-ir.cc:16227
void move_missing_member_types(class_or_union_sptr dest_class_or_union, class_or_union_sptr src_class_or_union)
Move member types that are present in src_class_or_union but missing from dest_class_or_union into de...
Definition abg-ir.cc:28792
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition abg-ir.cc:30242
bool types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
Test if two types are equal modulo a typedef or CV qualifiers.
Definition abg-ir.cc:11582
void mark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being compared.
Definition abg-ir.cc:1371
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
Definition abg-ir.cc:10037
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
Definition abg-ir.cc:8764
bool operator!=(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep inequality operator for pointers to translation units.
Definition abg-ir.cc:2389
interned_string get_name_of_pointer_to_type(const type_base &pointed_to_type, bool qualified, bool internal)
Get the name of the pointer to a given type.
Definition abg-ir.cc:10226
bool decl_name_changed(const type_or_decl_base *a1, const type_or_decl_base *a2)
Test if two decls have different names.
Definition abg-ir.cc:31349
typedef_decl_sptr lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
Definition abg-ir.cc:15411
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:11919
bool elf_symbol_is_variable(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
Definition abg-ir.cc:3784
bool type_has_sub_type_changes(const type_base_sptr t_v1, const type_base_sptr t_v2)
Tests if the change of a given type effectively comes from just its sub-types. That is,...
Definition abg-ir.cc:29991
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
Definition abg-ir.cc:13118
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
Definition abg-ir.cc:13068
typedef_decl_sptr lookup_typedef_type(const interned_string &type_name, const translation_unit &tu)
Lookup a typedef type from a translation unit.
Definition abg-ir.cc:13819
bool is_typedef_ptr_or_ref_to_decl_only_class_or_union_type(const type_base *t)
Test if a type is a typedef, pointer or reference to a decl-only class/union.
Definition abg-ir.cc:12821
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol.
Definition abg-ir.h:945
union_decl_sptr lookup_union_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
Definition abg-ir.cc:13746
bool class_or_union_types_of_same_kind(const class_or_union *first, const class_or_union *second)
Test if two class or union types are of the same kind.
Definition abg-ir.cc:12647
type_base_sptr maybe_move_missing_member_type(class_or_union_sptr dest_class_or_union, type_base_sptr src_member_type)
Move a member type from its current class or union scope to a destination class or union,...
Definition abg-ir.cc:28738
bool is_ptr_ref_or_qual_type(const type_base *t)
Helper to detect if a type is either a reference, a pointer, or a qualified type.
Definition abg-ir.cc:4279
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
Definition abg-ir.cc:13178
void add_canonical_type(type_base_sptr t, homonym_type_group_sptr group)
Add a canonical type to a homonym type group.
Definition abg-ir.cc:4020
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition abg-fwd.h:298
type_base * peel_qualified_or_typedef_type(const type_base *type)
Return the leaf underlying type of a qualified or typedef type.
Definition abg-ir.cc:8451
type_base_sptr type_or_void(const type_base_sptr t, const environment &env)
Return either the type given in parameter if it's non-null, or the void type.
Definition abg-ir.cc:16257
void add_member_class_template(class_or_union_sptr cou, member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition abg-ir.cc:25632
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
Definition abg-ir.cc:11765
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
Definition abg-ir.cc:12157
void canonicalize_homonym_type_groups(const vector< homonym_type_group_sptr > &groups, bool do_log, bool show_stats)
Canonicalize types coming from a vector of homonym_type_group_sptr in //.
Definition abg-ir.cc:17047
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition abg-ir.cc:6514
bool maybe_compare_as_member_decls(const decl_base &l, const decl_base &r, change_kind *k)
Compare the properties that belong to the "is-a-member-relation" of a decl.
Definition abg-ir.cc:6193
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition abg-ir.cc:7481
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
Definition abg-ir.cc:7513
bool is_declaration_only_class_type(const type_base_sptr &t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Definition abg-ir.cc:12615
bool compare_using_locations(const decl_base *f, const decl_base *s, bool &comp_result)
Compare decls using their locations.
Definition abg-ir.cc:4299
bool match(const regex_t_sptr &r, const std::string &str)
See if a string matches a regex.
Definition abg-regex.cc:127
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Definition abg-fwd.h:84
bool string_ends_with(const string &str, const string &suffix)
Test if a given string ends with a particular suffix.
const char * get_anonymous_subrange_internal_name_prefix()
Getter of the prefix for the name of anonymous range.
const char * get_anonymous_enum_internal_name_prefix()
Getter of the prefix for the name of anonymous enums.
const char * get_anonymous_struct_internal_name_prefix()
Getter of the prefix for the name of anonymous structs.
const char * get_anonymous_union_internal_name_prefix()
Getter of the prefix for the name of anonymous unions.
bool string_prefix(const string &input_string, const string &suffix, string &prefix)
Get the prefix of a string, given a suffix to consider.
size_t get_number_of_available_threads()
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
Definition abg-ir.cc:341
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
Definition abg-ir.cc:375
unordered_map< string, string * > pool_map_type
Convenience typedef for a map of string -> string*.
Definition abg-ir.cc:80
A functor to hash instances of interned_string.
A task that canonicalizes one homonym type group in its own thread.
size_t operator()(const type_base_sptr &l) const
Hash a type by returning the pointer value of its canonical type.
Definition abg-ir.cc:8879
The private data for the class_decl type.
Hasher for the class_or_union type.
Definition abg-hash.h:243
static bool is_printing_flat_representation(const class_or_union *cou)
Test if a given instance of class_or_union is being flat-representation-printed.
static void set_printing_flat_representation(const class_or_union *cou)
Mark a given instance of class_or_union as being flat-representation-printed.
static void unset_printing_flat_representation(const class_or_union *cou)
Un-mark a given instance of class_or_union as being flat-representation-printed.
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
The private data of the environment type.
static size_t compute_number_of_threads_to_use()
Compute the number of threads to use by looking at if multithreading is enabled in libabigail at all....
Definition abg-ir.cc:1456
static void clear_type_comparison_results_cache()
Clear the cache type comparison results.
Definition abg-ir.cc:1513
static size_t process_thread_pool_size_string(const string &tps)
Process a thread pool size string and convert it to a numeric value.
Definition abg-ir.cc:1481
static bool allow_type_comparison_results_caching()
Check whether if caching of the sub-types comparison results during the invocation of the equal overl...
Definition abg-ir.cc:1533
Equality functor for instances of function_decl.
Definition abg-ir.h:4713
The hashing functor for function_type.
Definition abg-hash.h:210
The type of the private data of the function_type type.
static void unset_is_pretty_printing(function_type *fn_type)
Unmark a given function pointer as being pretty-printed by add_outer_pointer_to_fn_type_expr.
static void set_is_pretty_printing(function_type *fn_type)
Mark a given function pointer as being pretty-printed by add_outer_pointer_to_fn_type_expr.
static bool is_pretty_printing(function_type *fn_type)
Getter of the 'is_pretty_printing_' boolean.
virtual bool traverse(ir_node_visitor &v)
Traverse a given IR node and its children, calling an visitor on each node.
Definition abg-ir.cc:31866
The hashing functor for member_base.
Definition abg-hash.h:236
Private type to hold private members of translation_unit.
Hash functor for instances of type_base.
Definition abg-hash.h:104
Definition of the private data of type_base.
The private data of type_or_decl_base.
A predicate for deep equality of instances of shared_ptr<type_base>
Definition abg-ir.h:2100
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.