libabigail
Loading...
Searching...
No Matches
abg-ir.cc
Go to the documentation of this file.
1// C++ -*-
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// -*- Mode: C++ -*-
4
5// Copyright (C) 2013-2026 Red Hat, Inc.
6//
7//Author: Dodji Seketeli
8
9/// @file
10///
11/// Definitions for the Internal Representation artifacts of libabigail.
12
13#include <cxxabi.h>
14#include <cstdint>
15#include <functional>
16#include <iterator>
17#include <memory>
18#include <sstream>
19#include <typeinfo>
20#include <unordered_map>
21#include <utility>
22#include <vector>
23
24#include "abg-internal.h"
25// <headers defining libabigail's API go under here>
26ABG_BEGIN_EXPORT_DECLARATIONS
27
28#include "abg-interned-str.h"
29#include "abg-ir.h"
30#include "abg-corpus.h"
31#include "abg-regex.h"
32
33ABG_END_EXPORT_DECLARATIONS
34// </headers defining libabigail's API>
35
36#include "abg-corpus-priv.h"
37#include "abg-comp-filter.h"
38#include "abg-ir-priv.h"
39
40namespace
41{
42/// This internal type is a tree walking that is used to set the
43/// qualified name of a tree of decls and types. It used by the
44/// function update_qualified_name().
45class qualified_name_setter : public abigail::ir::ir_node_visitor
46{
47
48public:
49 bool
50 do_update(abigail::ir::decl_base* d);
51
52 bool
53 visit_begin(abigail::ir::decl_base* d);
54
55 bool
56 visit_begin(abigail::ir::type_base* d);
57}; // end class qualified_name_setter
58
59}// end anon namespace
60
61namespace abigail
62{
63
64// Inject.
65using std::string;
66using std::list;
67using std::vector;
68using std::unordered_map;
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71
72/// Convenience typedef for a map of string -> string*.
73typedef unordered_map<string, string*> pool_map_type;
74
75/// The type of the private data structure of type @ref
76/// intered_string_pool.
77struct interned_string_pool::priv
78{
79 pool_map_type map;
80}; //end struc struct interned_string_pool::priv
81
82/// Default constructor.
84 : priv_(new priv)
85{
86 priv_->map[""] = 0;
87}
88
89/// Test if the interned string pool already contains a string with a
90/// given value.
91///
92/// @param s the string to test for.
93///
94/// @return true if the pool contains a string with the value @p s.
95bool
97{return priv_->map.find(s) != priv_->map.end();}
98
99/// Get a pointer to the interned string which has a given value.
100///
101/// @param s the value of the interned string to look for.
102///
103/// @return a pointer to the raw string of characters which has the
104/// value of @p s. Or null if no string with value @p s was interned.
105const char*
107{
108 unordered_map<string, string*>::const_iterator i =
109 priv_->map.find(s);
110 if (i == priv_->map.end())
111 return 0;
112 if (i->second)
113 return i->second->c_str();
114 return "";
115}
116
117/// Create an interned string with a given value.
118///
119/// @param str_value the value of the interned string to create.
120///
121/// @return the new created instance of @ref interned_string created.
123interned_string_pool::create_string(const std::string& str_value)
124{
125 string*& result = priv_->map[str_value];
126 if (!result && !str_value.empty())
127 result = new string(str_value);
128 return interned_string(result);
129}
130
131/// Destructor.
133{
134 for (pool_map_type::iterator i = priv_->map.begin();
135 i != priv_->map.end();
136 ++i)
137 if (i->second)
138 delete i->second;
139}
140
141/// Equality operator.
142///
143/// @param l the instance of std::string on the left-hand-side of the
144/// equality operator.
145///
146/// @param r the instance of @ref interned_string on the
147/// right-hand-side of the equality operator.
148///
149/// @return true iff the two string are equal.
150bool
151operator==(const std::string& l, const interned_string& r)
152{return r.operator==(l);}
153
154bool
155operator!=(const std::string& l, const interned_string& r)
156{return !(l == r);}
157
158/// Streaming operator.
159///
160/// Streams an instance of @ref interned_string to an output stream.
161///
162/// @param o the destination output stream.
163///
164/// @param s the instance of @ref interned_string to stream out.
165///
166/// @return the output stream this function just streamed to.
167std::ostream&
168operator<<(std::ostream& o, const interned_string& s)
169{
170 o << static_cast<std::string>(s);
171 return o;
172}
173
174/// Concatenation operator.
175///
176/// Concatenate two instances of @ref interned_string, builds an
177/// instance of std::string with the resulting string and return it.
178///
179/// @param s1 the first string to consider.
180///
181/// @param s2 the second string to consider.
182///
183/// @return the resuting concatenated string.
184std::string
185operator+(const interned_string& s1,const std::string& s2)
186{return static_cast<std::string>(s1) + s2;}
187
188/// Concatenation operator.
189///
190/// Concatenate two instances of @ref interned_string, builds an
191/// instance of std::string with the resulting string and return it.
192///
193/// @param s1 the first string to consider.
194///
195/// @param s2 the second string to consider.
196///
197/// @return the resuting concatenated string.
198std::string
199operator+(const std::string& s1, const interned_string& s2)
200{return s1 + static_cast<std::string>(s2);}
201
202namespace ir
203{
204
205static size_t
206hash_as_canonical_type_or_constant(const type_base *t);
207
208static bool
209has_generic_anonymous_internal_type_name(const decl_base *d);
210
211static interned_string
212get_generic_anonymous_internal_type_name(const decl_base *d);
213
214static string
215get_internal_real_type_name(const type_base*);
216
217static void
218update_qualified_name(decl_base * d);
219
220static void
221update_qualified_name(decl_base_sptr d);
222
223static interned_string
224pointer_declaration_name(const type_base* ptr,
225 const string& variable_name,
226 bool qualified, bool internal);
227
228static interned_string
229pointer_declaration_name(const type_base_sptr& ptr,
230 const string& variable_name,
231 bool qualified, bool internal);
232
233static interned_string
234ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
235 const string& variable_name,
236 bool qualified, bool internal);
237
238static interned_string
239ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
240 const string& variable_name,
241 bool qualified, bool internal);
242
243static interned_string
244array_declaration_name(const array_type_def* array,
245 const string& variable_name,
246 bool qualified, bool internal);
247
248static interned_string
249array_declaration_name(const array_type_def_sptr& array,
250 const string& variable_name,
251 bool qualified, bool internal);
252
253static void
254stream_pretty_representation_of_fn_parms(const function_type& fn_type,
255 ostream& o, bool qualified,
256 bool internal);
257static string
258add_outer_pointer_to_fn_type_expr(const type_base* pointer_to_fn,
259 const string& input, bool qualified,
260 bool internal);
261
262static string
263add_outer_pointer_to_fn_type_expr(const type_base_sptr& pointer_to_fn,
264 const string& input, bool qualified,
265 bool internal);
266
267static string
268add_outer_pointer_to_array_type_expr(const type_base* pointer_to_ar,
269 const string& input, bool qualified,
270 bool internal);
271
272static string
273add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
274 const string& input, bool qualified,
275 bool internal);
276
277static string
278add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
279 const string& input, bool qualified,
280 bool internal);
281
282static string
283add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
284 const string& input, bool qualified,
285 bool internal);
286
287static string
288add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
289 const string& input,
290 bool qualified, bool internal);
291
292void
293push_composite_type_comparison_operands(const type_base& left,
294 const type_base& right);
295
296void
297pop_composite_type_comparison_operands(const type_base& left,
298 const type_base& right);
299
300
301/// Push a pair of operands on the stack of operands of the current
302/// type comparison, during type canonicalization.
303///
304/// For more information on this, please look at the description of
305/// the environment::priv::right_type_comp_operands_ data member.
306///
307/// @param left the left-hand-side comparison operand to push.
308///
309/// @param right the right-hand-side comparison operand to push.
310void
312 const type_base& right)
313{
314 const environment& env = left.get_environment();
315 env.priv_->push_composite_type_comparison_operands(&left, &right);
316}
317
318/// Pop a pair of operands from the stack of operands to the current
319/// type comparison.
320///
321/// For more information on this, please look at the description of
322/// the environment::privright_type_comp_operands_ data member.
323///
324/// @param left the left-hand-side comparison operand we expect to
325/// pop from the top of the stack. If this doesn't match the
326/// operand found on the top of the stack, the function aborts.
327///
328/// @param right the right-hand-side comparison operand we expect to
329/// pop from the bottom of the stack. If this doesn't match the
330/// operand found on the top of the stack, the function aborts.
331void
333 const type_base& right)
334{
335 const environment& env = left.get_environment();
336 env.priv_->pop_composite_type_comparison_operands(&left, &right);
337}
338
339/// Getter of the canonical type index of a given type.
340///
341/// @param t the type to consider.
342///
343/// @return the CTI of the type.
344size_t
346{return t.priv_->canonical_type_index;}
347
348/// Getter of the canonical type index of a given type.
349///
350/// @param t the type to consider.
351///
352/// @return the CTI of the type.
353size_t
356
357/// Getter of the canonical type index of a given type.
358///
359/// @param t the type to consider.
360///
361/// @return the CTI of the type.
362size_t
363get_canonical_type_index(const type_base_sptr& t)
364{return get_canonical_type_index(t.get());}
365
366/// Test if a type originates from a corpus.
367///
368/// Note that this function supports testing if a type originates from
369/// a corpus group.
370///
371/// @param t the type to consider.
372///
373/// @param c the corpus or corpus group to consider.
374///
375/// @return true iff the type @p t originates from the corpus (or
376/// group) @p c.
377bool
378type_originates_from_corpus(type_base_sptr t, corpus_sptr& c)
379{
380 bool result = false;
381 if (c && t->get_corpus())
382 {
383 corpus_group_sptr g = is_corpus_group(c);
384 if (g)
385 {
386 if (t->get_corpus()->get_group() == g.get())
387 result = true;
388 }
389 else
390 {
391 if (t->get_corpus() == c.get())
392 result = true;
393 }
394 }
395 return result;
396}
397/// @brief the location of a token represented in its simplest form.
398/// Instances of this type are to be stored in a sorted vector, so the
399/// type must have proper relational operators.
400class expanded_location
401{
402 string path_;
403 unsigned line_;
404 unsigned column_;
405
406 expanded_location();
407
408public:
409
410 friend class location_manager;
411
412 expanded_location(const string& path, unsigned line, unsigned column)
413 : path_(path), line_(line), column_(column)
414 {}
415
416 bool
417 operator==(const expanded_location& l) const
418 {
419 return (path_ == l.path_
420 && line_ == l.line_
421 && column_ && l.column_);
422 }
423
424 bool
425 operator<(const expanded_location& l) const
426 {
427 if (path_ < l.path_)
428 return true;
429 else if (path_ > l.path_)
430 return false;
431
432 if (line_ < l.line_)
433 return true;
434 else if (line_ > l.line_)
435 return false;
436
437 return column_ < l.column_;
438 }
439};
440
441/// Expand the location into a tripplet path, line and column number.
442///
443/// @param path the output parameter where this function sets the
444/// expanded path.
445///
446/// @param line the output parameter where this function sets the
447/// expanded line.
448///
449/// @param column the ouptut parameter where this function sets the
450/// expanded column.
451void
452location::expand(std::string& path, unsigned& line, unsigned& column) const
453{
454 if (!get_location_manager())
455 {
456 // We don't have a location manager maybe because this location
457 // was just freshly instanciated. We still want to be able to
458 // expand to default values.
459 path = "";
460 line = 0;
461 column = 0;
462 return;
463 }
464 get_location_manager()->expand_location(*this, path, line, column);
465}
466
467
468/// Expand the location into a string.
469///
470/// @return the string representing the location.
471string
473{
474 string path, result;
475 unsigned line = 0, column = 0;
476 expand(path, line, column);
477
478 std::ostringstream o;
479 o << path << ":" << line << ":" << column;
480 return o.str();
481}
482
483struct location_manager::priv
484{
485 /// This sorted vector contains the expanded locations of the tokens
486 /// coming from a given ABI Corpus. The index of a given expanded
487 /// location in the table gives us an integer that is used to build
488 /// instance of location types.
489 std::vector<expanded_location> locs;
490};
491
492location_manager::location_manager()
493 : priv_(new location_manager::priv)
494{}
495
496location_manager::~location_manager() = default;
497
498/// Insert the triplet representing a source locus into our internal
499/// vector of location triplet. Return an instance of location type,
500/// built from an real type that represents the index of the
501/// source locus triplet into our source locus table.
502///
503/// @param file_path the file path of the source locus
504/// @param line the line number of the source location
505/// @param col the column number of the source location
506location
507location_manager::create_new_location(const std::string& file_path,
508 size_t line,
509 size_t col)
510{
511 expanded_location l(file_path, line, col);
512
513 // Just append the new expanded location to the end of the vector
514 // and return its index. Note that indexes start at 1.
515 priv_->locs.push_back(l);
516 return location(priv_->locs.size(), this);
517}
518
519/// Given an instance of location type, return the triplet
520/// {path,line,column} that represents the source locus. Note that
521/// the location must have been previously created from the function
522/// location_manager::create_new_location, otherwise this function yields
523/// unexpected results, including possibly a crash.
524///
525/// @param location the instance of location type to expand
526/// @param path the resulting path of the source locus
527/// @param line the resulting line of the source locus
528/// @param column the resulting colum of the source locus
529void
531 std::string& path,
532 unsigned& line,
533 unsigned& column) const
534{
535 if (location.value_ == 0)
536 return;
537 expanded_location &l = priv_->locs[location.value_ - 1];
538 path = l.path_;
539 line = l.line_;
540 column = l.column_;
541}
542
543typedef unordered_map<function_type_sptr,
544 bool,
546 type_shared_ptr_equal> fn_type_ptr_map;
547
548// <type_maps stuff>
549
550struct type_maps::priv
551{
552 mutable istring_type_base_wptrs_map_type basic_types_;
553 mutable istring_type_base_wptrs_map_type class_types_;
554 mutable istring_type_base_wptrs_map_type union_types_;
555 mutable istring_type_base_wptrs_map_type enum_types_;
556 mutable istring_type_base_wptrs_map_type typedef_types_;
557 mutable istring_type_base_wptrs_map_type qualified_types_;
558 mutable istring_type_base_wptrs_map_type pointer_types_;
559 mutable istring_type_base_wptrs_map_type ptr_to_mbr_types_;
560 mutable istring_type_base_wptrs_map_type reference_types_;
561 mutable istring_type_base_wptrs_map_type array_types_;
562 mutable istring_type_base_wptrs_map_type subrange_types_;
563 mutable istring_type_base_wptrs_map_type function_types_;
564 mutable vector<type_base_wptr> sorted_types_;
565}; // end struct type_maps::priv
566
567type_maps::type_maps()
568 : priv_(new priv)
569{}
570
571type_maps::~type_maps() = default;
572
573/// Test if the type_maps is empty.
574///
575/// @return true iff the type_maps is empty.
576bool
578{
579 return (basic_types().empty()
580 && class_types().empty()
581 && union_types().empty()
582 && enum_types().empty()
583 && typedef_types().empty()
585 && pointer_types().empty()
587 && array_types().empty()
588 && subrange_types().empty()
589 && function_types().empty());
590}
591
592/// Getter for the map that associates the name of a basic type to the
593/// vector instances of type_decl_sptr that represents that type.
596{return priv_->basic_types_;}
597
598/// Getter for the map that associates the name of a basic type to the
599/// vector of instances of @ref type_decl_sptr that represents that
600/// type.
603{return priv_->basic_types_;}
604
605/// Getter for the map that associates the name of a class type to the
606/// vector of instances of @ref class_decl_sptr that represents that
607/// type.
610{return priv_->class_types_;}
611
612/// Getter for the map that associates the name of a class type to the
613/// vector of instances of @ref class_decl_sptr that represents that
614/// type.
617{return priv_->class_types_;}
618
619/// Getter for the map that associates the name of a union type to the
620/// vector of instances of @ref union_decl_sptr that represents that
621/// type.
624{return priv_->union_types_;}
625
626/// Getter for the map that associates the name of a union type to the
627/// vector of instances of @ref union_decl_sptr that represents that
628/// type.
631{return priv_->union_types_;}
632
633/// Getter for the map that associates the name of an enum type to the
634/// vector of instances of @ref enum_type_decl_sptr that represents
635/// that type.
638{return priv_->enum_types_;}
639
640/// Getter for the map that associates the name of an enum type to the
641/// vector of instances of @ref enum_type_decl_sptr that represents
642/// that type.
645{return priv_->enum_types_;}
646
647/// Getter for the map that associates the name of a typedef to the
648/// vector of instances of @ref typedef_decl_sptr that represents tha
649/// type.
652{return priv_->typedef_types_;}
653
654/// Getter for the map that associates the name of a typedef to the
655/// vector of instances of @ref typedef_decl_sptr that represents tha
656/// type.
659{return priv_->typedef_types_;}
660
661/// Getter for the map that associates the name of a qualified type to
662/// the vector of instances of @ref qualified_type_def_sptr.
665{return priv_->qualified_types_;}
666
667/// Getter for the map that associates the name of a qualified type to
668/// the vector of instances of @ref qualified_type_def_sptr.
671{return priv_->qualified_types_;}
672
673/// Getter for the map that associates the name of a pointer type to
674/// the vector of instances of @ref pointer_type_def_sptr that
675/// represents that type.
678{return priv_->pointer_types_;}
679
680/// Getter for the map that associates the name of a pointer-to-member
681/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
682/// represents that type.
685{return priv_->ptr_to_mbr_types_;}
686
687/// Getter for the map that associates the name of a pointer-to-member
688/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
689/// represents that type.
692{return priv_->ptr_to_mbr_types_;}
693
694/// Getter for the map that associates the name of a pointer type to
695/// the vector of instances of @ref pointer_type_def_sptr that
696/// represents that type.
699{return priv_->pointer_types_;}
700
701/// Getter for the map that associates the name of a reference type to
702/// the vector of instances of @ref reference_type_def_sptr that
703/// represents that type.
706{return priv_->reference_types_;}
707
708/// Getter for the map that associates the name of a reference type to
709/// the vector of instances of @ref reference_type_def_sptr that
710/// represents that type.
713{return priv_->reference_types_;}
714
715/// Getter for the map that associates the name of an array type to
716/// the vector of instances of @ref array_type_def_sptr that
717/// represents that type.
720{return priv_->array_types_;}
721
722/// Getter for the map that associates the name of an array type to
723/// the vector of instances of @ref array_type_def_sptr that
724/// represents that type.
727{return priv_->array_types_;}
728
729/// Getter for the map that associates the name of a subrange type to
730/// the vector of instances of @ref array_type_def::subrange_sptr that
731/// represents that type.
734{return priv_->subrange_types_;}
735
736/// Getter for the map that associates the name of a subrange type to
737/// the vector of instances of @ref array_type_def::subrange_sptr that
738/// represents that type.
741{return priv_->subrange_types_;}
742
743/// Getter for the map that associates the name of a function type to
744/// the vector of instances of @ref function_type_sptr that represents
745/// that type.
748{return priv_->function_types_;}
749
750/// Getter for the map that associates the name of a function type to
751/// the vector of instances of @ref function_type_sptr that represents
752/// that type.
755{return priv_->function_types_;}
756
757/// A comparison functor to compare/sort types based on their pretty
758/// representations.
759struct type_name_comp
760{
761 /// Comparison operator for two instances of @ref type_base.
762 ///
763 /// This compares the two types by lexicographically comparing their
764 /// pretty representation.
765 ///
766 /// @param l the left-most type to compare.
767 ///
768 /// @param r the right-most type to compare.
769 ///
770 /// @return true iff @p l < @p r.
771 bool
772 operator()(type_base *l, type_base *r) const
773 {
774 if (l == 0 && r == 0)
775 return false;
776
777 string l_repr = get_pretty_representation(l);
778 string r_repr = get_pretty_representation(r);
779 return l_repr < r_repr;
780 }
781
782 /// Comparison operator for two instances of @ref type_base.
783 ///
784 /// This compares the two types by lexicographically comparing their
785 /// pretty representation.
786 ///
787 /// @param l the left-most type to compare.
788 ///
789 /// @param r the right-most type to compare.
790 ///
791 /// @return true iff @p l < @p r.
792 bool
793 operator()(const type_base_sptr &l, const type_base_sptr &r) const
794 {return operator()(l.get(), r.get());}
795
796 /// Comparison operator for two instances of @ref type_base.
797 ///
798 /// This compares the two types by lexicographically comparing their
799 /// pretty representation.
800 ///
801 /// @param l the left-most type to compare.
802 ///
803 /// @param r the right-most type to compare.
804 ///
805 /// @return true iff @p l < @p r.
806 bool
807 operator()(const type_base_wptr &l, const type_base_wptr &r) const
808 {return operator()(type_base_sptr(l), type_base_sptr(r));}
809}; // end struct type_name_comp
810
811#ifdef WITH_DEBUG_SELF_COMPARISON
812
813/// This is a function called when the ABG_RETURN* macros defined
814/// below return false.
815///
816/// The purpose of this function is to ease debugging. To know where
817/// the equality functions first compare non-equal, we can just set a
818/// breakpoint on this notify_equality_failed function and run the
819/// equality functions. Because all the equality functions use the
820/// ABG_RETURN* macros to return their values, this function is always
821/// called when any of those equality function return false.
822///
823/// @param l the first operand of the equality.
824///
825/// @param r the second operand of the equality.
826static void
827notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
828 const type_or_decl_base &r __attribute__((unused)))
829{}
830
831/// This is a function called when the ABG_RETURN* macros defined
832/// below return false.
833///
834/// The purpose of this function is to ease debugging. To know where
835/// the equality functions first compare non-equal, we can just set a
836/// breakpoint on this notify_equality_failed function and run the
837/// equality functions. Because all the equality functions use the
838/// ABG_RETURN* macros to return their values, this function is always
839/// called when any of those equality function return false.
840///
841/// @param l the first operand of the equality.
842///
843/// @param r the second operand of the equality.
844static void
845notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
846 const type_or_decl_base *r __attribute__((unused)))
847{}
848
849#define ABG_RETURN_EQUAL(l, r) \
850 do \
851 { \
852 if (l != r) \
853 notify_equality_failed(l, r); \
854 return (l == r); \
855 } \
856 while(false)
857
858
859#define ABG_RETURN_FALSE \
860 do \
861 { \
862 notify_equality_failed(l, r); \
863 return false; \
864 } while(false)
865
866#define ABG_RETURN(value) \
867 do \
868 { \
869 if (value == false) \
870 notify_equality_failed(l, r); \
871 return value; \
872 } while (false)
873
874#else // WITH_DEBUG_SELF_COMPARISON
875
876#define ABG_RETURN_FALSE return false
877#define ABG_RETURN(value) return (value)
878#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
879#endif
880
881/// Get the canonical type of a given type T* as a T*.
882///
883/// Note that normally, canonical types are returned as @ref
884/// type_base* (un-typed form, kind of). This function returns the
885/// canonical type as a T*, just like the T* it is looking at.
886///
887///
888/// @param t the type to consider.
889///
890/// @return either the canonical type of @p t or @p t itself if it
891/// doesn't have any canonical type.
892template<typename T>
893T*
895{
896 if (!t)
897 return nullptr;
898 if (type_base* type = t->get_naked_canonical_type())
899 return dynamic_cast<T*>(type);
900 return t;
901}
902
903/// Compare two types by comparing their canonical types if present.
904///
905/// If the canonical types are not present (because the types have not
906/// yet been canonicalized, for instance) then the types are compared
907/// structurally.
908///
909/// @param l the first type to take into account in the comparison.
910///
911/// @param r the second type to take into account in the comparison.
912template<typename T>
913bool
914try_canonical_compare(const T *l, const T *r)
915{
916#if WITH_DEBUG_TYPE_CANONICALIZATION
917 // We are debugging the canonicalization of a type down the stack.
918 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
919 // type being canonicalized. We are at a point where we can compare
920 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
921 // have canonical types) or structural comparison.
922 //
923 // Because we are debugging the process of type canonicalization, we
924 // want to compare 'l' and 'r' canonically *AND* structurally. Both
925 // kinds of comparison should yield the same result, otherwise type
926 // canonicalization just failed for the subtype 'r' of the type
927 // being canonicalized.
928 //
929 // In concrete terms, this function is going to be called twice with
930 // the same pair {'l', 'r'} to compare: The first time with
931 // environment::priv_->use_canonical_type_comparison_ set to true,
932 // instructing us to compare them canonically, and the second time
933 // with that boolean set to false, instructing us to compare them
934 // structurally.
935 const environment&env = l->get_environment();
936 if (env.priv_->use_canonical_type_comparison_)
937 {
938 if (const type_base *lc = l->get_naked_canonical_type())
939 if (const type_base *rc = r->get_naked_canonical_type())
940 ABG_RETURN_EQUAL(lc, rc);
941 }
942
943 // If the two types have a non-empty hash value, then consider those
944 // hash values. If the hashes are different then the two types are
945 // different. If the hashes are equal then we'll compare then
946 // structurally.
947 if (hash_t l_hash = peek_hash_value(*l))
948 if (hash_t r_hash = peek_hash_value(*r))
949 if (l_hash != r_hash)
951
952 // If a type has a canonical type, use its canonical type, always.
955
956 return equals(*l, *r, 0);
957#else
958 if (const type_base *lc = l->get_naked_canonical_type())
959 if (const type_base *rc = r->get_naked_canonical_type())
960 ABG_RETURN_EQUAL(lc, rc);
961
962 // If the two types have a non-empty hash value, then consider those
963 // hash values. If the hashes are different then the two types are
964 // different. If the hashes are equal then we'll compare then
965 // structurally.
966 if (hash_t l_hash = peek_hash_value(*l))
967 if (hash_t r_hash = peek_hash_value(*r))
968 if (l_hash != r_hash)
970
971 // If a type has a canonical type, use its canonical type, always.
974
975 return equals(*l, *r, 0);
976#endif
977}
978
979/// Detect if a recursive comparison cycle is detected while
980/// structurally comparing two types (a.k.a member-wise comparison).
981///
982/// @param l the left-hand-side operand of the current comparison.
983///
984/// @param r the right-hand-side operand of the current comparison.
985///
986/// @return true iff a comparison cycle is detected.
987template<typename T>
988bool
990{
991 bool result = l.priv_->comparison_started(l, r);
992 return result ;
993}
994
995/// Detect if a recursive comparison cycle is detected while
996/// structurally comparing two @ref class_decl types.
997///
998/// @param l the left-hand-side operand of the current comparison.
999///
1000/// @param r the right-hand-side operand of the current comparison.
1001///
1002/// @return true iff a comparison cycle is detected.
1003template<>
1004bool
1006{
1007 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
1008 static_cast<const class_or_union&>(r));
1009}
1010
1011/// This macro is to be used while comparing composite types that
1012/// might recursively refer to themselves. Comparing two such types
1013/// might get us into a cyle.
1014///
1015/// Practically, if we detect that we are already into comparing 'l'
1016/// and 'r'; then, this is a cycle.
1017//
1018/// To break the cycle, we assume the result of the comparison is true
1019/// for now. Comparing the other sub-types of l & r will tell us later
1020/// if l & r are actually different or not.
1021///
1022/// In the mean time, returning true from this macro should not be
1023/// used to propagate the canonical type of 'l' onto 'r' as we don't
1024/// know yet if l equals r. All the types that depend on l and r
1025/// can't (and that are in the comparison stack currently) can't have
1026/// their canonical type propagated either. So this macro disallows
1027/// canonical type propagation for those types that depend on a
1028/// recursively defined sub-type for now.
1029///
1030/// @param l the left-hand-side operand of the comparison.
1031#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
1032 do \
1033 { \
1034 if (is_comparison_cycle_detected(l, r)) \
1035 return true; \
1036 } \
1037 while(false)
1038
1039
1040/// Mark a pair of types as being compared.
1041///
1042/// This is helpful to later detect recursive cycles in the comparison
1043/// stack.
1044///
1045/// @param l the left-hand-side operand of the comparison.
1046///
1047/// @parm r the right-hand-side operand of the comparison.
1048template<typename T>
1049void
1051{
1052 l.priv_->mark_as_being_compared(l, r);
1054}
1055
1056/// Mark a pair of @ref class_decl types as being compared.
1057///
1058/// This is helpful to later detect recursive cycles in the comparison
1059/// stack.
1060///
1061/// @param l the left-hand-side operand of the comparison.
1062///
1063/// @parm r the right-hand-side operand of the comparison.
1064template<>
1065void
1067{
1068 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
1069 static_cast<const class_or_union&>(r));
1070}
1071
1072/// Mark a pair of types as being not compared anymore.
1073///
1074/// This is helpful to later detect recursive cycles in the comparison
1075/// stack.
1076///
1077/// Note that the types must have been passed to
1078/// mark_types_as_being_compared prior to calling this function.
1079///
1080/// @param l the left-hand-side operand of the comparison.
1081///
1082/// @parm r the right-hand-side operand of the comparison.
1083template<typename T>
1084void
1086{
1087 l.priv_->unmark_as_being_compared(l, r);
1089}
1090
1091/// Mark a pair of @ref class_decl types as being not compared
1092/// anymore.
1093///
1094/// This is helpful to later detect recursive cycles in the comparison
1095/// stack.
1096///
1097/// Note that the types must have been passed to
1098/// mark_types_as_being_compared prior to calling this function.
1099///
1100/// @param l the left-hand-side operand of the comparison.
1101///
1102/// @parm r the right-hand-side operand of the comparison.
1103template<>
1104void
1106{
1107 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
1108 static_cast<const class_or_union&>(r));
1109}
1110
1111/// Return the result of the comparison of two (sub) types.
1112///
1113/// The function does the necessary book keeping before returning the
1114/// result of the comparison of two (sub) types.
1115///
1116/// The book-keeping done is essentially about type comparison cycle detection.
1117///
1118/// @param l the left-hand-side operand of the type comparison
1119///
1120/// @param r the right-hand-side operand of the type comparison
1121///
1122/// @param value the result of the comparison of @p l and @p r.
1123///
1124/// @return the value @p value.
1125template<typename T>
1126bool
1127return_comparison_result(T& l, T& r, bool value)
1128{
1130 ABG_RETURN(value);
1131}
1132
1133#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1134 do \
1135 { \
1136 bool res = return_comparison_result(l, r, value); \
1137 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1138 return res; \
1139 } while (false)
1140
1141/// Cache the result of a comparison between too artifacts (l & r) and
1142/// return immediately.
1143///
1144/// @param value the value to cache.
1145#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1146 do \
1147 { \
1148 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1149 return value; \
1150 } while (false)
1151
1152/// Getter of all types types sorted by their pretty representation.
1153///
1154/// @return a sorted vector of all types sorted by their pretty
1155/// representation.
1156const vector<type_base_wptr>&
1158{
1159 if (priv_->sorted_types_.empty())
1160 {
1161 istring_type_base_wptrs_map_type::const_iterator i;
1163
1164 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1165 for (j = i->second.begin(); j != i->second.end(); ++j)
1166 priv_->sorted_types_.push_back(*j);
1167
1168 for (i = class_types().begin(); i != class_types().end(); ++i)
1169 for (j = i->second.begin(); j != i->second.end(); ++j)
1170 priv_->sorted_types_.push_back(*j);
1171
1172 for (i = union_types().begin(); i != union_types().end(); ++i)
1173 for (j = i->second.begin(); j != i->second.end(); ++j)
1174 priv_->sorted_types_.push_back(*j);
1175
1176 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1177 for (j = i->second.begin(); j != i->second.end(); ++j)
1178 priv_->sorted_types_.push_back(*j);
1179
1180 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1181 for (j = i->second.begin(); j != i->second.end(); ++j)
1182 priv_->sorted_types_.push_back(*j);
1183
1184 type_name_comp comp;
1185 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1186 }
1187
1188 return priv_->sorted_types_;
1189}
1190
1191// </type_maps stuff>
1192
1193// <translation_unit stuff>
1194
1195/// Constructor of translation_unit.
1196///
1197/// @param env the environment of this translation unit. Please note
1198/// that the life time of the environment must be greater than the
1199/// life time of the translation unit because the translation uses
1200/// resources that are allocated in the environment.
1201///
1202/// @param path the location of the translation unit.
1203///
1204/// @param address_size the size of addresses in the translation unit,
1205/// in bits.
1206translation_unit::translation_unit(const environment& env,
1207 const std::string& path,
1208 char address_size)
1209 : priv_(new priv(env))
1210{
1211 priv_->path_ = path;
1212 priv_->address_size_ = address_size;
1213}
1214
1215/// Getter of the the global scope of the translation unit.
1216///
1217/// @return the global scope of the current translation unit. If
1218/// there is not global scope allocated yet, this function creates one
1219/// and returns it.
1220const scope_decl_sptr&
1222{
1223 return const_cast<translation_unit*>(this)->get_global_scope();
1224}
1225
1226/// Getter of the global scope of the translation unit.
1227///
1228/// @return the global scope of the current translation unit. If
1229/// there is not allocated yet, this function creates one and returns
1230/// it.
1233{
1234 if (!priv_->global_scope_)
1235 {
1236 priv_->global_scope_.reset
1237 (new global_scope(const_cast<translation_unit*>(this)));
1238 priv_->global_scope_->set_translation_unit
1239 (const_cast<translation_unit*>(this));
1240 }
1241 return priv_->global_scope_;
1242}
1243
1244/// Getter of the types of the current @ref translation_unit.
1245///
1246/// @return the maps of the types of the translation unit.
1247const type_maps&
1249{return priv_->types_;}
1250
1251/// Getter of the types of the current @ref translation_unit.
1252///
1253/// @return the maps of the types of the translation unit.
1254type_maps&
1256{return priv_->types_;}
1257
1258/// Get the vector of function types that are used in the current
1259/// translation unit.
1260///
1261/// @return the vector of function types that are used in the current
1262/// translation unit.
1265{return priv_->live_fn_types_;}
1266
1267/// Getter of the environment of the current @ref translation_unit.
1268///
1269/// @return the translation unit of the current translation unit.
1270const environment&
1272{return priv_->env_;}
1273
1274/// Getter of the language of the source code of the translation unit.
1275///
1276/// @return the language of the source code.
1279{return priv_->language_;}
1280
1281/// Setter of the language of the source code of the translation unit.
1282///
1283/// @param l the new language.
1284void
1286{priv_->language_ = l;}
1287
1288
1289/// Get the path of the current translation unit.
1290///
1291/// This path is relative to the build directory of the translation
1292/// unit as returned by translation_unit::get_compilation_dir_path.
1293///
1294/// @return the relative path of the compilation unit associated to
1295/// the current instance of translation_unit.
1296//
1297const std::string&
1299{return priv_->path_;}
1300
1301/// Set the path associated to the current instance of
1302/// translation_unit.
1303///
1304/// This path is relative to the build directory of the translation
1305/// unit as returned by translation_unit::get_compilation_dir_path.
1306///
1307/// @param a_path the new relative path to set.
1308void
1309translation_unit::set_path(const string& a_path)
1310{priv_->path_ = a_path;}
1311
1312
1313/// Get the path of the directory that was 'current' when the
1314/// translation unit was compiled.
1315///
1316/// Note that the path returned by translation_unit::get_path is
1317/// relative to the path returned by this function.
1318///
1319/// @return the compilation directory for the current translation
1320/// unit.
1321const std::string&
1323{return priv_->comp_dir_path_;}
1324
1325/// Set the path of the directory that was 'current' when the
1326/// translation unit was compiled.
1327///
1328/// Note that the path returned by translation_unit::get_path is
1329/// relative to the path returned by this function.
1330///
1331/// @param the compilation directory for the current translation unit.
1332void
1334{priv_->comp_dir_path_ = d;}
1335
1336/// Get the concatenation of the build directory and the relative path
1337/// of the translation unit.
1338///
1339/// @return the absolute path of the translation unit.
1340const std::string&
1342{
1343 if (priv_->abs_path_.empty())
1344 {
1345 string path;
1346 if (!priv_->path_.empty())
1347 {
1348 if (!priv_->comp_dir_path_.empty())
1349 {
1350 path = priv_->comp_dir_path_;
1351 path += "/";
1352 }
1353 path += priv_->path_;
1354 }
1355 priv_->abs_path_ = path;
1356 }
1357
1358 return priv_->abs_path_;
1359}
1360
1361/// Set the corpus this translation unit is a member of.
1362///
1363/// Note that adding a translation unit to a @ref corpus automatically
1364/// triggers a call to this member function.
1365///
1366/// @param corpus the corpus.
1367void
1369{priv_->corp = c;}
1370
1371/// Get the corpus this translation unit is a member of.
1372///
1373/// @return the parent corpus, or nil if this doesn't belong to any
1374/// corpus yet.
1375corpus*
1377{return priv_->corp;}
1378
1379/// Get the corpus this translation unit is a member of.
1380///
1381/// @return the parent corpus, or nil if this doesn't belong to any
1382/// corpus yet.
1383const corpus*
1385{return const_cast<translation_unit*>(this)->get_corpus();}
1386
1387/// Getter of the location manager for the current translation unit.
1388///
1389/// @return a reference to the location manager for the current
1390/// translation unit.
1393{return priv_->loc_mgr_;}
1394
1395/// const Getter of the location manager.
1396///
1397/// @return a const reference to the location manager for the current
1398/// translation unit.
1399const location_manager&
1401{return priv_->loc_mgr_;}
1402
1403/// Tests whether if the current translation unit contains ABI
1404/// artifacts or not.
1405///
1406/// @return true iff the current translation unit is empty.
1407bool
1409{
1410 if (!priv_->global_scope_)
1411 return true;
1412 return get_global_scope()->is_empty();
1413}
1414
1415/// Getter of the address size in this translation unit.
1416///
1417/// @return the address size, in bits.
1418char
1420{return priv_->address_size_;}
1421
1422/// Setter of the address size in this translation unit.
1423///
1424/// @param a the new address size in bits.
1425void
1427{priv_->address_size_= a;}
1428
1429/// Getter of the 'is_constructed" flag. It says if the translation
1430/// unit is fully constructed or not.
1431///
1432/// This flag is important for cases when comparison might depend on
1433/// if the translation unit is fully built or not. For instance, when
1434/// reading types from DWARF, the virtual methods of a class are not
1435/// necessarily fully constructed until we have reached the end of the
1436/// translation unit. In that case, before we've reached the end of
1437/// the translation unit, we might not take virtual functions into
1438/// account when comparing classes.
1439///
1440/// @return true if the translation unit is constructed.
1441bool
1443{return priv_->is_constructed_;}
1444
1445/// Setter of the 'is_constructed" flag. It says if the translation
1446/// unit is fully constructed or not.
1447///
1448/// This flag is important for cases when comparison might depend on
1449/// if the translation unit is fully built or not. For instance, when
1450/// reading types from DWARF, the virtual methods of a class are not
1451/// necessarily fully constructed until we have reached the end of the
1452/// translation unit. In that case, before we've reached the end of
1453/// the translation unit, we might not take virtual functions into
1454/// account when comparing classes.
1455///
1456/// @param f true if the translation unit is constructed.
1457void
1459{priv_->is_constructed_ = f;}
1460
1461/// Compare the current translation unit against another one.
1462///
1463/// @param other the other tu to compare against.
1464///
1465/// @return true if the two translation units are equal, false
1466/// otherwise.
1467bool
1468translation_unit::operator==(const translation_unit& other)const
1469{
1470 if (get_address_size() != other.get_address_size())
1471 return false;
1472
1473 return *get_global_scope() == *other.get_global_scope();
1474}
1475
1476/// Inequality operator.
1477///
1478/// @param o the instance of @ref translation_unit to compare the
1479/// current instance against.
1480///
1481/// @return true iff the current instance is different from @p o.
1482bool
1483translation_unit::operator!=(const translation_unit& o) const
1484{return ! operator==(o);}
1485
1486/// Ensure that the life time of a function type is bound to the life
1487/// time of the current translation unit.
1488///
1489/// @param ftype the function time which life time to bind to the life
1490/// time of the current instance of @ref translation_unit. That is,
1491/// it's onlyh when the translation unit is destroyed that the
1492/// function type can be destroyed to.
1493void
1495{
1496 const environment& env = get_environment();
1497
1498 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1499
1500 interned_string repr = get_type_name(ftype);
1501 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1502 push_back(ftype);
1503
1504 // The function type must be out of the same environment as its
1505 // translation unit.
1506 {
1507 const environment& e = ftype->get_environment();
1508 ABG_ASSERT(&env == &e);
1509 }
1510
1511 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1512 ABG_ASSERT(existing_tu == this);
1513 else
1514 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1515
1517}
1518
1519/// This implements the ir_traversable_base::traverse virtual
1520/// function.
1521///
1522/// @param v the visitor used on the member nodes of the translation
1523/// unit during the traversal.
1524///
1525/// @return true if the entire type IR tree got traversed, false
1526/// otherwise.
1527bool
1530
1531translation_unit::~translation_unit()
1532{}
1533
1534/// Converts a translation_unit::language enumerator into a string.
1535///
1536/// @param l the language enumerator to translate.
1537///
1538/// @return the resulting string.
1539string
1541{
1542 switch (l)
1543 {
1544 case translation_unit::LANG_UNKNOWN:
1545 return "LANG_UNKNOWN";
1546 case translation_unit::LANG_Cobol74:
1547 return "LANG_Cobol74";
1548 case translation_unit::LANG_Cobol85:
1549 return "LANG_Cobol85";
1550 case translation_unit::LANG_C89:
1551 return "LANG_C89";
1552 case translation_unit::LANG_C99:
1553 return "LANG_C99";
1554 case translation_unit::LANG_C11:
1555 return "LANG_C11";
1556 case translation_unit::LANG_C17:
1557 return "LANG_C17";
1558 case translation_unit::LANG_C23:
1559 return "LANG_C23";
1560 case translation_unit::LANG_C:
1561 return "LANG_C";
1562 case translation_unit::LANG_C_plus_plus_03:
1563 return "LANG_C_plus_plus_03";
1564 case translation_unit::LANG_C_plus_plus_11:
1565 return "LANG_C_plus_plus_11";
1566 case translation_unit::LANG_C_plus_plus_14:
1567 return "LANG_C_plus_plus_14";
1568 case translation_unit::LANG_C_plus_plus_17:
1569 return "LANG_C_plus_plus_17";
1570 case translation_unit::LANG_C_plus_plus_20:
1571 return "LANG_C_plus_plus_20";
1572 case translation_unit::LANG_C_plus_plus_23:
1573 return "LANG_C_plus_plus_23";
1574 case translation_unit::LANG_C_plus_plus:
1575 return "LANG_C_plus_plus";
1576 case translation_unit::LANG_OCaml:
1577 return "LANG_OCaml";
1578 case translation_unit::LANG_Zig:
1579 return "LANG_Zig";
1580 case translation_unit::LANG_ObjC:
1581 return "LANG_ObjC";
1582 case translation_unit::LANG_ObjC_plus_plus:
1583 return "LANG_ObjC_plus_plus";
1584 case translation_unit::LANG_D:
1585 return "LANG_D";
1586 case translation_unit::LANG_Go:
1587 return "LANG_Go";
1588 case translation_unit::LANG_Rust:
1589 return "LANG_Rust";
1590 case translation_unit::LANG_Fortran77:
1591 return "LANG_Fortran77";
1592 case translation_unit::LANG_Fortran90:
1593 return "LANG_Fortran90";
1594 case translation_unit::LANG_Fortran95:
1595 return "LANG_Fortran95";
1596 case translation_unit::LANG_Fortran18:
1597 return "LANG_Fortran18";
1598 case translation_unit::LANG_Fortran23:
1599 return "LANG_Fortran23";
1600 case translation_unit::LANG_Ada83:
1601 return "LANG_Ada83";
1602 case translation_unit::LANG_Ada95:
1603 return "LANG_Ada95";
1604 case translation_unit::LANG_Ada2005:
1605 return "LANG_Ada2005";
1606 case translation_unit::LANG_Ada2012:
1607 return "LANG_Ada2012";
1608 case translation_unit::LANG_Pascal83:
1609 return "LANG_Pascal83";
1610 case translation_unit::LANG_Modula2:
1611 return "LANG_Modula2";
1612 case translation_unit::LANG_Java:
1613 return "LANG_Java";
1614 case translation_unit::LANG_Kotlin:
1615 return "LANG_Kotlin";
1616 case translation_unit::LANG_C_sharp:
1617 return "LANG_C_sharp";
1618 case translation_unit::LANG_Python:
1619 return "LANG_Python";
1620 case translation_unit::LANG_Ruby:
1621 return "LANG_Ruby";
1622 case translation_unit::LANG_PLI:
1623 return "LANG_PLI";
1624 case translation_unit::LANG_UPC:
1625 return "LANG_UPC";
1626 case translation_unit::LANG_Mips_Assembler:
1627 return "LANG_Mips_Assembler";
1628 case translation_unit::LANG_Assembly:
1629 return "LANG_Assembly";
1630 case translation_unit::LANG_Crystal:
1631 return "LANG_Crystal";
1632 case translation_unit::LANG_HIP:
1633 return "LANG_HIP";
1634 case translation_unit::LANG_Mojo:
1635 return "LANG_Mojo";
1636 case translation_unit::LANG_GLSL:
1637 return "LANG_GLSL";
1638 case translation_unit::LANG_GLSL_ES:
1639 return "LANG_GLSL_ES";
1640 case translation_unit::LANG_HLSL:
1641 return "LANG_HLSL";
1642 case translation_unit::LANG_OpenCL_CPP:
1643 return "LANG_OpenCL_CPP";
1644 case translation_unit::LANG_CPP_for_OpenCL:
1645 return "LANG_CPP_for_OpenCL";
1646 case translation_unit::LANG_SYCL:
1647 return "LANG_SYCL";
1648 case translation_unit::LANG_Odin:
1649 return "LANG_Odin";
1650 case translation_unit::LANG_P4:
1651 return "LANG_P4";
1652 case translation_unit::LANG_Metal:
1653 return "LANG_Metal";
1654 case translation_unit::LANG_Move:
1655 return "LANG_Move";
1656 case translation_unit::LANG_Hylo:
1657 return "LANG_Hylo";
1658 }
1659
1660 return "LANG_UNKNOWN";
1661}
1662
1663/// Parse a string representing a language into a
1664/// translation_unit::language enumerator into a string.
1665///
1666/// @param l the string representing the language.
1667///
1668/// @return the resulting translation_unit::language enumerator.
1671{
1672 if (l == "LANG_Cobol74")
1673 return translation_unit::LANG_Cobol74;
1674 else if (l == "LANG_Cobol85")
1675 return translation_unit::LANG_Cobol85;
1676 else if (l == "LANG_C89")
1677 return translation_unit::LANG_C89;
1678 else if (l == "LANG_C99")
1679 return translation_unit::LANG_C99;
1680 else if (l == "LANG_C11")
1681 return translation_unit::LANG_C11;
1682 else if (l == "LANG_C17")
1683 return translation_unit::LANG_C17;
1684 else if (l == "LANG_C23")
1685 return translation_unit::LANG_C23;
1686 else if (l == "LANG_C")
1687 return translation_unit::LANG_C;
1688 else if (l == "LANG_C_plus_plus_03")
1689 return translation_unit::LANG_C_plus_plus_03;
1690 else if (l == "LANG_C_plus_plus_11")
1691 return translation_unit::LANG_C_plus_plus_11;
1692 else if (l == "LANG_C_plus_plus_14")
1693 return translation_unit::LANG_C_plus_plus_14;
1694 else if (l == "LANG_C_plus_plus_17")
1695 return translation_unit::LANG_C_plus_plus_17;
1696 else if (l == "LANG_C_plus_plus_20")
1697 return translation_unit::LANG_C_plus_plus_20;
1698 else if (l == "LANG_C_plus_plus_23")
1699 return translation_unit::LANG_C_plus_plus_23;
1700 else if (l == "LANG_C_plus_plus")
1701 return translation_unit::LANG_C_plus_plus;
1702 else if (l == "LANG_OCaml")
1703 return translation_unit::LANG_OCaml;
1704 else if (l == "LANG_ObjC")
1705 return translation_unit::LANG_ObjC;
1706 else if (l == "LANG_ObjC_plus_plus")
1707 return translation_unit::LANG_ObjC_plus_plus;
1708 else if (l == "LANG_Zig")
1709 return translation_unit::LANG_Zig;
1710 else if (l == "LANG_Metal")
1711 return translation_unit::LANG_Metal;
1712 else if (l == "LANG_Fortran77")
1713 return translation_unit::LANG_Fortran77;
1714 else if (l == "LANG_Fortran90")
1715 return translation_unit::LANG_Fortran90;
1716 else if (l == "LANG_Fortran95")
1717 return translation_unit::LANG_Fortran95;
1718 else if (l == "LANG_Fortran18")
1719 return translation_unit::LANG_Fortran23;
1720 else if (l == "LANG_Ada83")
1721 return translation_unit::LANG_Ada83;
1722 else if (l == "LANG_Ada95")
1723 return translation_unit::LANG_Ada95;
1724 else if (l == "LANG_Ada2005")
1725 return translation_unit::LANG_Ada2005;
1726 else if (l == "LANG_Ada2012")
1727 return translation_unit::LANG_Ada2012;
1728 else if (l == "LANG_Pascal83")
1729 return translation_unit::LANG_Pascal83;
1730 else if (l == "LANG_Modula2")
1731 return translation_unit::LANG_Modula2;
1732 else if (l == "LANG_Java")
1733 return translation_unit::LANG_Java;
1734 else if (l == "LANG_Kotlin")
1735 return translation_unit::LANG_Kotlin;
1736 else if (l == "LANG_PLI")
1737 return translation_unit::LANG_PLI;
1738 else if (l == "LANG_UPC")
1739 return translation_unit::LANG_UPC;
1740 else if (l == "LANG_D")
1741 return translation_unit::LANG_D;
1742 else if (l == "LANG_Go")
1743 return translation_unit::LANG_Go;
1744 else if (l == "LANG_Rust")
1745 return translation_unit::LANG_Rust;
1746 else if (l == "LANG_Python")
1747 return translation_unit::LANG_Python;
1748 else if (l == "LANG_Ruby")
1749 return translation_unit::LANG_Ruby;
1750 else if (l == "LANG_Mips_Assembler")
1751 return translation_unit::LANG_Mips_Assembler;
1752 else if (l == "LANG_Assembly")
1753 return translation_unit::LANG_Assembly;
1754 else if (l == "LANG_Crystal")
1755 return translation_unit::LANG_Crystal;
1756 else if (l == "LANG_HIP")
1757 return translation_unit::LANG_HIP;
1758 else if (l == "LANG_C_sharp")
1759 return translation_unit::LANG_C_sharp;
1760 else if (l == "LANG_Mojo")
1761 return translation_unit::LANG_Mojo;
1762 else if (l == "LANG_GLSL")
1763 return translation_unit::LANG_GLSL;
1764 else if (l == "LANG_GLSL_ES")
1765 return translation_unit::LANG_GLSL_ES;
1766 else if (l == "LANG_HLSL")
1767 return translation_unit::LANG_HLSL;
1768 else if (l == "LANG_OpenCL_CPP")
1769 return translation_unit::LANG_OpenCL_CPP;
1770 else if (l == "LANG_CPP_for_OpenCL")
1771 return translation_unit::LANG_CPP_for_OpenCL;
1772 else if (l == "LANG_SYCL")
1773 return translation_unit::LANG_SYCL;
1774 else if (l == "LANG_Odin")
1775 return translation_unit::LANG_Odin;
1776 else if (l == "LANG_P4")
1777 return translation_unit::LANG_P4;
1778 else if (l == "LANG_Move")
1779 return translation_unit::LANG_Move;
1780 else if (l == "LANG_Hylo")
1781 return translation_unit::LANG_Hylo;
1782
1783 return translation_unit::LANG_UNKNOWN;
1784}
1785
1786/// Test if a language enumerator designates the C language.
1787///
1788/// @param l the language enumerator to consider.
1789///
1790/// @return true iff @p l designates the C language.
1791bool
1793{
1794 return (l == translation_unit::LANG_C89
1795 || l == translation_unit::LANG_C99
1796 || l == translation_unit::LANG_C11
1797 || l == translation_unit::LANG_C17
1798 || l == translation_unit::LANG_C23
1799 || l == translation_unit::LANG_C);
1800}
1801
1802/// Test if a language enumerator designates the C++ language.
1803///
1804/// @param l the language enumerator to consider.
1805///
1806/// @return true iff @p l designates the C++ language.
1807bool
1809{
1810 return (l == translation_unit::LANG_C_plus_plus_03
1811 || l == translation_unit::LANG_C_plus_plus_11
1812 || l == translation_unit::LANG_C_plus_plus_14
1813 || l == translation_unit::LANG_C_plus_plus_20
1814 || l == translation_unit::LANG_C_plus_plus_23
1815 || l == translation_unit::LANG_C_plus_plus);
1816}
1817
1818/// Test if a language enumerator designates the Java language.
1819///
1820/// @param l the language enumerator to consider.
1821///
1822/// @return true iff @p l designates the Java language.
1823bool
1825{return l == translation_unit::LANG_Java;}
1826
1827/// Test if a language enumerator designates the Ada language.
1828///
1829/// @param l the language enumerator to consider.
1830///
1831/// @return true iff @p l designates the Ada language.
1832bool
1834{
1835 return (l == translation_unit::LANG_Ada83
1836 || l == translation_unit::LANG_Ada95
1837 || l == translation_unit::LANG_Ada2005
1838 || l == translation_unit::LANG_Ada2012);
1839}
1840
1841/// A deep comparison operator for pointers to translation units.
1842///
1843/// @param l the first translation unit to consider for the comparison.
1844///
1845/// @param r the second translation unit to consider for the comparison.
1846///
1847/// @return true if the two translation units are equal, false otherwise.
1848bool
1850{
1851 if (l.get() == r.get())
1852 return true;
1853
1854 if (!!l != !!r)
1855 return false;
1856
1857 return *l == *r;
1858}
1859
1860/// A deep inequality operator for pointers to translation units.
1861///
1862/// @param l the first translation unit to consider for the comparison.
1863///
1864/// @param r the second translation unit to consider for the comparison.
1865///
1866/// @return true iff the two translation units are different.
1867bool
1869{return !operator==(l, r);}
1870
1871// </translation_unit stuff>
1872
1873// <elf_symbol stuff>
1874struct elf_symbol::priv
1875{
1876 const environment& env_;
1877 size_t index_;
1878 size_t size_;
1879 string name_;
1880 elf_symbol::type type_;
1881 elf_symbol::binding binding_;
1882 elf_symbol::version version_;
1883 elf_symbol::visibility visibility_;
1884 bool is_defined_;
1885 // This flag below says if the symbol is a common elf symbol. In
1886 // relocatable files, a common symbol is a symbol defined in a
1887 // section of kind SHN_COMMON.
1888 //
1889 // Note that a symbol of kind STT_COMMON is also considered a common
1890 // symbol. Here is what the gABI says about STT_COMMON and
1891 // SHN_COMMON:
1892 //
1893 // Symbols with type STT_COMMON label uninitialized common
1894 // blocks. In relocatable objects, these symbols are not
1895 // allocated and must have the special section index SHN_COMMON
1896 // (see below). In shared objects and executables these symbols
1897 // must be allocated to some section in the defining object.
1898 //
1899 // In relocatable objects, symbols with type STT_COMMON are
1900 // treated just as other symbols with index SHN_COMMON. If the
1901 // link-editor allocates space for the SHN_COMMON symbol in an
1902 // output section of the object it is producing, it must
1903 // preserve the type of the output symbol as STT_COMMON.
1904 //
1905 // When the dynamic linker encounters a reference to a symbol
1906 // that resolves to a definition of type STT_COMMON, it may (but
1907 // is not required to) change its symbol resolution rules as
1908 // follows: instead of binding the reference to the first symbol
1909 // found with the given name, the dynamic linker searches for
1910 // the first symbol with that name with type other than
1911 // STT_COMMON. If no such symbol is found, it looks for the
1912 // STT_COMMON definition of that name that has the largest size.
1913 bool is_common_;
1914 bool is_in_ksymtab_;
1917 bool is_suppressed_;
1918 elf_symbol_wptr main_symbol_;
1919 elf_symbol_wptr next_alias_;
1920 elf_symbol_wptr next_common_instance_;
1921 string id_string_;
1922
1923 priv(const environment& e)
1924 : env_(e),
1925 index_(),
1926 size_(),
1927 type_(elf_symbol::NOTYPE_TYPE),
1928 binding_(elf_symbol::GLOBAL_BINDING),
1929 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1930 is_defined_(false),
1931 is_common_(false),
1932 is_in_ksymtab_(false),
1933 crc_(),
1934 namespace_(),
1935 is_suppressed_(false)
1936 {}
1937
1938 priv(const environment& e,
1939 size_t i,
1940 size_t s,
1941 const string& n,
1944 bool d,
1945 bool c,
1946 const elf_symbol::version& ve,
1948 bool is_in_ksymtab,
1951 bool is_suppressed)
1952 : env_(e),
1953 index_(i),
1954 size_(s),
1955 name_(n),
1956 type_(t),
1957 binding_(b),
1958 version_(ve),
1959 visibility_(vi),
1960 is_defined_(d),
1961 is_common_(c),
1962 is_in_ksymtab_(is_in_ksymtab),
1963 crc_(crc),
1964 namespace_(ns),
1965 is_suppressed_(is_suppressed)
1966 {
1967 if (!is_common_)
1968 is_common_ = type_ == COMMON_TYPE;
1969 }
1970}; // end struct elf_symbol::priv
1971
1972/// Constructor of the @ref elf_symbol type.
1973///
1974/// Note that this constructor is private, so client code cannot use
1975/// it to create instances of @ref elf_symbol. Rather, client code
1976/// should use the @ref elf_symbol::create() function to create
1977/// instances of @ref elf_symbol instead.
1978///
1979/// @param e the environment we are operating from.
1980///
1981/// @param i the index of the symbol in the (ELF) symbol table.
1982///
1983/// @param s the size of the symbol.
1984///
1985/// @param n the name of the symbol.
1986///
1987/// @param t the type of the symbol.
1988///
1989/// @param b the binding of the symbol.
1990///
1991/// @param d true if the symbol is defined, false otherwise.
1992///
1993/// @param c true if the symbol is a common symbol, false otherwise.
1994///
1995/// @param ve the version of the symbol.
1996///
1997/// @param vi the visibility of the symbol.
1998///
1999/// @param crc the CRC (modversions) value of Linux Kernel symbols
2000///
2001/// @param ns the namespace of Linux Kernel symbols, if any
2002elf_symbol::elf_symbol(const environment& e,
2003 size_t i,
2004 size_t s,
2005 const string& n,
2006 type t,
2007 binding b,
2008 bool d,
2009 bool c,
2010 const version& ve,
2011 visibility vi,
2012 bool is_in_ksymtab,
2013 const abg_compat::optional<uint32_t>& crc,
2014 const abg_compat::optional<std::string>& ns,
2015 bool is_suppressed)
2016 : priv_(new priv(e,
2017 i,
2018 s,
2019 n,
2020 t,
2021 b,
2022 d,
2023 c,
2024 ve,
2025 vi,
2026 is_in_ksymtab,
2027 crc,
2028 ns,
2029 is_suppressed))
2030{}
2031
2032/// Factory of instances of @ref elf_symbol.
2033///
2034/// This is the function to use to create instances of @ref elf_symbol.
2035///
2036/// @param e the environment we are operating from.
2037///
2038/// @param i the index of the symbol in the (ELF) symbol table.
2039///
2040/// @param s the size of the symbol.
2041///
2042/// @param n the name of the symbol.
2043///
2044/// @param t the type of the symbol.
2045///
2046/// @param b the binding of the symbol.
2047///
2048/// @param d true if the symbol is defined, false otherwise.
2049///
2050/// @param c true if the symbol is a common symbol.
2051///
2052/// @param ve the version of the symbol.
2053///
2054/// @param vi the visibility of the symbol.
2055///
2056/// @param crc the CRC (modversions) value of Linux Kernel symbols
2057///
2058/// @param ns the namespace of Linux Kernel symbols, if any
2059///
2060/// @return a (smart) pointer to a newly created instance of @ref
2061/// elf_symbol.
2064 size_t i,
2065 size_t s,
2066 const string& n,
2067 type t,
2068 binding b,
2069 bool d,
2070 bool c,
2071 const version& ve,
2072 visibility vi,
2073 bool is_in_ksymtab,
2076 bool is_suppressed)
2077{
2078 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
2079 is_in_ksymtab, crc, ns, is_suppressed));
2080 sym->priv_->main_symbol_ = sym;
2081 return sym;
2082}
2083
2084/// Test textual equality between two symbols.
2085///
2086/// Textual equality means that the aliases of the compared symbols
2087/// are not taken into account. Only the name, type, and version of
2088/// the symbols are compared.
2089///
2090/// @parm l the first ELF symbol to take into consideration in the
2091/// comparison.
2092///
2093/// @param r the second ELF symbol to take into consideration in the
2094/// comparison.
2095///
2096/// @param k a pointer to a bitfield that gives information about the
2097/// kind of changes there are between @p l and @p r. This one is set
2098/// iff it's non-null and if the function returns false.
2099///
2100/// @return true iff the two symbols are textually equal.
2101static bool
2102textually_equals(const elf_symbol&l, const elf_symbol&r,
2103 change_kind* k = nullptr)
2104{
2105 bool equals = (l.get_name() == r.get_name()
2106 && l.get_type() == r.get_type()
2107 && l.is_public() == r.is_public()
2108 && l.is_defined() == r.is_defined()
2110 && l.get_version() == r.get_version()
2111 && l.get_crc() == r.get_crc()
2112 && l.get_namespace() == r.get_namespace());
2113
2114 if (!equals)
2115 if (k)
2117
2118 if (equals && l.is_variable())
2119 // These are variable symbols. Let's compare their symbol size.
2120 // The symbol size in this case is the size taken by the storage
2121 // of the variable. If that size changes, then it's an ABI
2122 // change.
2123 if (l.get_size() != r.get_size())
2124 {
2125 equals = false;
2126 if (k)
2128 }
2129
2130 return equals;
2131}
2132
2133/// Getter of the environment used by the current instance of @ref
2134/// elf_symbol.
2135///
2136/// @return the enviroment used by the current instance of @ref elf_symbol.
2137const environment&
2139{return priv_->env_;}
2140
2141/// Getter for the index
2142///
2143/// @return the index of the symbol.
2144size_t
2146{return priv_->index_;}
2147
2148/// Setter for the index.
2149///
2150/// @param s the new index.
2151void
2153{priv_->index_ = s;}
2154
2155/// Getter for the name of the @ref elf_symbol.
2156///
2157/// @return a reference to the name of the @ref symbol.
2158const string&
2160{return priv_->name_;}
2161
2162/// Setter for the name of the current intance of @ref elf_symbol.
2163///
2164/// @param n the new name.
2165void
2166elf_symbol::set_name(const string& n)
2167{
2168 priv_->name_ = n;
2169 priv_->id_string_.clear();
2170}
2171
2172/// Getter for the type of the current instance of @ref elf_symbol.
2173///
2174/// @return the type of the elf symbol.
2177{return priv_->type_;}
2178
2179/// Setter for the type of the current instance of @ref elf_symbol.
2180///
2181/// @param t the new symbol type.
2182void
2184{priv_->type_ = t;}
2185
2186/// Getter of the size of the symbol.
2187///
2188/// @return the size of the symbol, in bytes.
2189size_t
2191{return priv_->size_;}
2192
2193/// Setter of the size of the symbol.
2194///
2195/// @param size the new size of the symbol, in bytes.
2196void
2198{priv_->size_ = size;}
2199
2200/// Getter for the binding of the current instance of @ref elf_symbol.
2201///
2202/// @return the binding of the symbol.
2205{return priv_->binding_;}
2206
2207/// Setter for the binding of the current instance of @ref elf_symbol.
2208///
2209/// @param b the new binding.
2210void
2212{priv_->binding_ = b;}
2213
2214/// Getter for the version of the current instanc of @ref elf_symbol.
2215///
2216/// @return the version of the elf symbol.
2219{return priv_->version_;}
2220
2221/// Setter for the version of the current instance of @ref elf_symbol.
2222///
2223/// @param v the new version of the elf symbol.
2224void
2226{
2227 priv_->version_ = v;
2228 priv_->id_string_.clear();
2229}
2230
2231/// Setter of the visibility of the current instance of @ref
2232/// elf_symbol.
2233///
2234/// @param v the new visibility of the elf symbol.
2235void
2237{priv_->visibility_ = v;}
2238
2239/// Getter of the visibility of the current instance of @ref
2240/// elf_symbol.
2241///
2242/// @return the visibility of the elf symbol.
2245{return priv_->visibility_;}
2246
2247/// Test if the current instance of @ref elf_symbol is defined or not.
2248///
2249/// @return true if the current instance of @ref elf_symbol is
2250/// defined, false otherwise.
2251bool
2253{return priv_->is_defined_;}
2254
2255/// Sets a flag saying if the current instance of @ref elf_symbol is
2256/// defined
2257///
2258/// @param b the new value of the flag.
2259void
2261{priv_->is_defined_ = d;}
2262
2263/// Test if the current instance of @ref elf_symbol is public or not.
2264///
2265/// This tests if the symbol is defined, has default or protected
2266///visibility, and either:
2267/// - has global binding
2268/// - has weak binding
2269/// - or has a GNU_UNIQUE binding.
2270///
2271/// return true if the current instance of @ref elf_symbol is public,
2272/// false otherwise.
2273bool
2275{
2276 return (is_defined()
2277 && (get_binding() == GLOBAL_BINDING
2278 || get_binding() == WEAK_BINDING
2279 || get_binding() == GNU_UNIQUE_BINDING)
2280 && (get_visibility() == DEFAULT_VISIBILITY
2281 || get_visibility() == PROTECTED_VISIBILITY));
2282}
2283
2284/// Test if the current instance of @ref elf_symbol is a function
2285/// symbol or not.
2286///
2287/// @return true if the current instance of @ref elf_symbol is a
2288/// function symbol, false otherwise.
2289bool
2291{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2292
2293/// Test if the current instance of @ref elf_symbol is a variable
2294/// symbol or not.
2295///
2296/// @return true if the current instance of @ref elf_symbol is a
2297/// variable symbol, false otherwise.
2298bool
2300{
2301 return (get_type() == OBJECT_TYPE
2302 || get_type() == TLS_TYPE
2303 // It appears that undefined variables have NOTYPE type.
2304 || (get_type() == NOTYPE_TYPE
2305 && !is_defined()));
2306}
2307
2308/// Getter of the 'is-in-ksymtab' property.
2309///
2310/// @return true iff the current symbol is in the Linux Kernel
2311/// specific 'ksymtab' symbol table.
2312bool
2314{return priv_->is_in_ksymtab_;}
2315
2316/// Setter of the 'is-in-ksymtab' property.
2317///
2318/// @param is_in_ksymtab this is true iff the current symbol is in the
2319/// Linux Kernel specific 'ksymtab' symbol table.
2320void
2322{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2323
2324/// Getter of the 'crc' property.
2325///
2326/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2329{return priv_->crc_;}
2330
2331/// Setter of the 'crc' property.
2332///
2333/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2334void
2336{priv_->crc_ = crc;}
2337
2338/// Getter of the 'namespace' property.
2339///
2340/// @return the namespace for Linux Kernel symbols, if any
2343{return priv_->namespace_;}
2344
2345/// Setter of the 'namespace' property.
2346///
2347/// @param ns the new namespace for Linux Kernel symbols, if any
2348void
2350{priv_->namespace_ = ns;}
2351
2352/// Getter for the 'is-suppressed' property.
2353///
2354/// @return true iff the current symbol has been suppressed by a
2355/// suppression specification that was provided in the context that
2356/// led to the creation of the corpus this ELF symbol belongs to.
2357bool
2359{return priv_->is_suppressed_;}
2360
2361/// Setter for the 'is-suppressed' property.
2362///
2363/// @param true iff the current symbol has been suppressed by a
2364/// suppression specification that was provided in the context that
2365/// led to the creation of the corpus this ELF symbol belongs to.
2366void
2368{priv_->is_suppressed_ = is_suppressed;}
2369
2370/// @name Elf symbol aliases
2371///
2372/// An alias A for an elf symbol S is a symbol that is defined at the
2373/// same address as S. S is chained to A through the
2374/// elf_symbol::get_next_alias() method.
2375///
2376/// When there are several aliases to a symbol, the main symbol is the
2377/// the first symbol found in the symbol table for a given address.
2378///
2379/// The alias chain is circular. That means if S is the main symbol
2380/// and A is the alias, S is chained to A and A
2381/// is chained back to the main symbol S. The last alias in an alias
2382///chain is always chained to the main symbol.
2383///
2384/// Thus, when looping over the aliases of an elf_symbol A, detecting
2385/// an alias that is equal to the main symbol should logically be a
2386/// loop exit condition.
2387///
2388/// Accessing and adding aliases for instances of elf_symbol is done
2389/// through the member functions below.
2390
2391/// @{
2392
2393/// Get the main symbol of an alias chain.
2394///
2395///@return the main symbol.
2396const elf_symbol_sptr
2398{return priv_->main_symbol_.lock();}
2399
2400/// Get the main symbol of an alias chain.
2401///
2402///@return the main symbol.
2405{return priv_->main_symbol_.lock();}
2406
2407/// Tests whether this symbol is the main symbol.
2408///
2409/// @return true iff this symbol is the main symbol.
2410bool
2412{return get_main_symbol().get() == this;}
2413
2414/// Get the next alias of the current symbol.
2415///
2416///@return the alias, or NULL if there is no alias.
2419{return priv_->next_alias_.lock();}
2420
2421
2422/// Check if the current elf_symbol has an alias.
2423///
2424///@return true iff the current elf_symbol has an alias.
2425bool
2427{return bool(get_next_alias());}
2428
2429/// Get the number of aliases to this elf symbol
2430///
2431/// @return the number of aliases to this elf symbol.
2432int
2434{
2435 int result = 0;
2436
2438 a && a.get() != get_main_symbol().get();
2439 a = a->get_next_alias())
2440 ++result;
2441
2442 return result;
2443}
2444
2445/// Add an alias to the current elf symbol.
2446///
2447/// @param alias the new alias. Note that this elf_symbol should *NOT*
2448/// have aliases prior to the invocation of this function.
2449void
2451{
2452 if (!alias)
2453 return;
2454
2455 ABG_ASSERT(!alias->has_aliases());
2457
2458 if (has_aliases())
2459 {
2460 elf_symbol_sptr last_alias;
2462 a && !a->is_main_symbol();
2463 a = a->get_next_alias())
2464 {
2465 if (a->get_next_alias()->is_main_symbol())
2466 {
2467 ABG_ASSERT(last_alias == 0);
2468 last_alias = a;
2469 }
2470 }
2471 ABG_ASSERT(last_alias);
2472
2473 last_alias->priv_->next_alias_ = alias;
2474 }
2475 else
2476 priv_->next_alias_ = alias;
2477
2478 alias->priv_->next_alias_ = get_main_symbol();
2479 alias->priv_->main_symbol_ = get_main_symbol();
2480}
2481
2482/// Update the main symbol for a group of aliased symbols
2483///
2484/// If after the construction of the symbols (in order of discovery), the
2485/// actual main symbol can be identified (e.g. as the symbol that actually is
2486/// defined in the code), this method offers a way of updating the main symbol
2487/// through one of the aliased symbols.
2488///
2489/// For that, locate the new main symbol by name and update all references to
2490/// the main symbol among the group of aliased symbols.
2491///
2492/// @param name the name of the main symbol
2493///
2494/// @return the new main elf_symbol
2496elf_symbol::update_main_symbol(const std::string& name)
2497{
2499 if (!has_aliases() || get_name() == name)
2500 return get_main_symbol();
2501
2502 // find the new main symbol
2503 elf_symbol_sptr new_main;
2504 // we've already checked this; check the rest of the aliases
2505 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2506 a = a->get_next_alias())
2507 if (a->get_name() == name)
2508 {
2509 new_main = a;
2510 break;
2511 }
2512
2513 if (!new_main)
2514 return get_main_symbol();
2515
2516 // now update all main symbol references
2517 priv_->main_symbol_ = new_main;
2518 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2519 a = a->get_next_alias())
2520 a->priv_->main_symbol_ = new_main;
2521
2522 return new_main;
2523}
2524
2525/// Return true if the symbol is a common one.
2526///
2527/// @return true iff the symbol is common.
2528bool
2530{return priv_->is_common_;}
2531
2532/// Return true if this common common symbol has other common instances.
2533///
2534/// A common instance of a given common symbol is another common
2535/// symbol with the same name. Those exist in relocatable files. The
2536/// linker normally allocates all the instances into a common block in
2537/// the final output file.
2538///
2539/// Note that the current object must be a common symbol, otherwise,
2540/// this function aborts.
2541///
2542/// @return true iff the current common symbol has other common
2543/// instances.
2544bool
2550
2551/// Get the next common instance of the current common symbol.
2552///
2553/// A common instance of a given common symbol is another common
2554/// symbol with the same name. Those exist in relocatable files. The
2555/// linker normally allocates all the instances into a common block in
2556/// the final output file.
2557///
2558/// @return the next common instance, or nil if there is not any.
2561{return priv_->next_common_instance_.lock();}
2562
2563/// Add a common instance to the current common elf symbol.
2564///
2565/// Note that this symbol must be the main symbol. Being the main
2566/// symbol means being the first common symbol to appear in the symbol
2567/// table.
2568///
2569/// @param common the other common instance to add.
2570void
2572{
2573 if (!common)
2574 return;
2575
2576 ABG_ASSERT(!common->has_other_common_instances());
2579
2581 {
2582 elf_symbol_sptr last_common_instance;
2584 c && (c.get() != get_main_symbol().get());
2585 c = c->get_next_common_instance())
2586 {
2587 if (c->get_next_common_instance().get() == get_main_symbol().get())
2588 {
2589 ABG_ASSERT(last_common_instance == 0);
2590 last_common_instance = c;
2591 }
2592 }
2593 ABG_ASSERT(last_common_instance);
2594
2595 last_common_instance->priv_->next_common_instance_ = common;
2596 }
2597 else
2598 priv_->next_common_instance_ = common;
2599
2600 common->priv_->next_common_instance_ = get_main_symbol();
2601 common->priv_->main_symbol_ = get_main_symbol();
2602}
2603
2604/// Get a string that is representative of a given elf_symbol.
2605///
2606/// If the symbol has a version, then the ID string is the
2607/// concatenation of the name of the symbol, the '@' character, and
2608/// the version of the symbol. If the version is the default version
2609/// of the symbol then the '@' character is replaced by a "@@" string.
2610///
2611/// Otherwise, if the symbol does not have any version, this function
2612/// returns the name of the symbol.
2613///
2614/// @return a the ID string.
2615const string&
2617{
2618 if (priv_->id_string_.empty())
2619 {
2620 string s = get_name ();
2621
2622 if (!get_version().is_empty())
2623 {
2624 if (get_version().is_default())
2625 s += "@@";
2626 else
2627 s += "@";
2628 s += get_version().str();
2629 }
2630 priv_->id_string_ = s;
2631 }
2632
2633 return priv_->id_string_;
2634}
2635
2636/// From the aliases of the current symbol, lookup one with a given name.
2637///
2638/// @param name the name of symbol alias we are looking for.
2639///
2640/// @return the symbol alias that has the name @p name, or nil if none
2641/// has been found.
2643elf_symbol::get_alias_from_name(const string& name) const
2644{
2645 if (name == get_name())
2646 return elf_symbol_sptr(priv_->main_symbol_);
2647
2649 a && a.get() != get_main_symbol().get();
2650 a = a->get_next_alias())
2651 if (a->get_name() == name)
2652 return a;
2653
2654 return elf_symbol_sptr();
2655}
2656
2657/// In the list of aliases of a given elf symbol, get the alias that
2658/// equals this current symbol.
2659///
2660/// @param other the elf symbol to get the potential aliases from.
2661///
2662/// @return the alias of @p other that texually equals the current
2663/// symbol, or nil if no alias textually equals the current symbol.
2665elf_symbol::get_alias_which_equals(const elf_symbol& other) const
2666{
2667 for (elf_symbol_sptr a = other.get_next_alias();
2668 a && a.get() != a->get_main_symbol().get();
2669 a = a->get_next_alias())
2670 if (textually_equals(*this, *a))
2671 return a;
2672 return elf_symbol_sptr();
2673}
2674
2675/// Return a comma separated list of the id of the current symbol as
2676/// well as the id string of its aliases.
2677///
2678/// @param syms a map of all the symbols of the corpus the current
2679/// symbol belongs to.
2680///
2681/// @param include_symbol_itself if set to true, then the name of the
2682/// current symbol is included in the list of alias names that is emitted.
2683///
2684/// @return the string.
2685string
2687 bool include_symbol_itself) const
2688{
2689 string result;
2690
2691 if (include_symbol_itself)
2692 result = get_id_string();
2693
2695 compute_aliases_for_elf_symbol(*this, syms, aliases);
2696 if (!aliases.empty() && include_symbol_itself)
2697 result += ", ";
2698
2699 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2700 i != aliases.end();
2701 ++i)
2702 {
2703 if (i != aliases.begin())
2704 result += ", ";
2705 result += (*i)->get_id_string();
2706 }
2707 return result;
2708}
2709
2710/// Return a comma separated list of the id of the current symbol as
2711/// well as the id string of its aliases.
2712///
2713/// @param include_symbol_itself if set to true, then the name of the
2714/// current symbol is included in the list of alias names that is emitted.
2715///
2716/// @return the string.
2717string
2718elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2719{
2721 if (include_symbol_itself)
2722 aliases.push_back(get_main_symbol());
2723
2725 a && a.get() != get_main_symbol().get();
2726 a = a->get_next_alias())
2727 aliases.push_back(a);
2728
2729 string result;
2730 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2731 i != aliases.end();
2732 ++i)
2733 {
2734 if (i != aliases.begin())
2735 result += ", ";
2736 result += (*i)->get_id_string();
2737 }
2738
2739 return result;
2740}
2741
2742/// Given the ID of a symbol, get the name and the version of said
2743/// symbol.
2744///
2745/// @param id the symbol ID to consider.
2746///
2747/// @param name the symbol name extracted from the ID. This is set
2748/// only if the function returned true.
2749///
2750/// @param ver the symbol version extracted from the ID.
2751bool
2753 string& name,
2754 string& ver)
2755{
2756 name.clear(), ver.clear();
2757
2758 string::size_type i = id.find('@');
2759 if (i == string::npos)
2760 {
2761 name = id;
2762 return true;
2763 }
2764
2765 name = id.substr(0, i);
2766 ++i;
2767
2768 if (i >= id.size())
2769 return true;
2770
2771 string::size_type j = id.find('@', i);
2772 if (j == string::npos)
2773 j = i;
2774 else
2775 ++j;
2776
2777 if (j >= id.size())
2778 {
2779 ver = "";
2780 return true;
2781 }
2782
2783 ver = id.substr(j);
2784 return true;
2785}
2786
2787///@}
2788
2789/// Test if two main symbols are textually equal, or, if they have
2790/// aliases that are textually equal.
2791///
2792/// @param other the symbol to compare against.
2793///
2794/// @return true iff the current instance of elf symbol equals the @p
2795/// other.
2796bool
2797elf_symbol::operator==(const elf_symbol& other) const
2798{
2799 bool are_equal = textually_equals(*this, other);
2800 if (!are_equal)
2801 are_equal = bool(get_alias_which_equals(other));
2802 return are_equal;
2803}
2804
2805/// Test if the current symbol aliases another one.
2806///
2807/// @param o the other symbol to test against.
2808///
2809/// @return true iff the current symbol aliases @p o.
2810bool
2811elf_symbol::does_alias(const elf_symbol& o) const
2812{
2813 if (*this == o)
2814 return true;
2815
2816 if (get_main_symbol() == o.get_main_symbol())
2817 return true;
2818
2820 a && !a->is_main_symbol();
2821 a = a->get_next_alias())
2822 {
2823 if (o == *a)
2824 return true;
2825 }
2826 return false;
2827}
2828
2829/// Equality operator for smart pointers to elf_symbol.
2830///
2831/// @param lhs the first elf symbol to consider.
2832///
2833/// @param rhs the second elf symbol to consider.
2834///
2835/// @return true iff @p lhs equals @p rhs.
2836bool
2838{
2839 if (!!lhs != !!rhs)
2840 return false;
2841
2842 if (!lhs)
2843 return true;
2844
2845 return *lhs == *rhs;
2846}
2847
2848/// Inequality operator for smart pointers to elf_symbol.
2849///
2850/// @param lhs the first elf symbol to consider.
2851///
2852/// @param rhs the second elf symbol to consider.
2853///
2854/// @return true iff @p lhs is different from @p rhs.
2855bool
2857{return !operator==(lhs, rhs);}
2858
2859/// Test if two symbols alias.
2860///
2861/// @param s1 the first symbol to consider.
2862///
2863/// @param s2 the second symbol to consider.
2864///
2865/// @return true if @p s1 aliases @p s2.
2866bool
2868{return s1.does_alias(s2) || s2.does_alias(s1);}
2869
2870void
2871compute_aliases_for_elf_symbol(const elf_symbol& sym,
2872 const string_elf_symbols_map_type& symtab,
2873 vector<elf_symbol_sptr>& aliases)
2874{
2875
2876 if (elf_symbol_sptr a = sym.get_next_alias())
2877 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2878 aliases.push_back(a);
2879 else
2880 {
2881 // No pre-linked alias chain (e.g. symbols loaded from abixml).
2882 // Look up by name in the symtab (O(1) hash lookup) instead of
2883 // scanning the entire table (which was O(N) per call).
2884 string_elf_symbols_map_type::const_iterator i =
2885 symtab.find(sym.get_name());
2886 if (i == symtab.end())
2887 return;
2888
2889 for (elf_symbols::const_iterator j = i->second.begin();
2890 j != i->second.end();
2891 ++j)
2892 {
2893 if (**j == sym)
2894 for (elf_symbol_sptr s = (*j)->get_next_alias();
2895 s && !s->is_main_symbol();
2896 s = s->get_next_alias())
2897 aliases.push_back(s);
2898 else
2899 for (elf_symbol_sptr s = (*j)->get_next_alias();
2900 s && !s->is_main_symbol();
2901 s = s->get_next_alias())
2902 if (*s == sym)
2903 aliases.push_back(*j);
2904 }
2905 }
2906}
2907
2908/// Test if two symbols alias.
2909///
2910/// @param s1 the first symbol to consider.
2911///
2912/// @param s2 the second symbol to consider.
2913///
2914/// @return true if @p s1 aliases @p s2.
2915bool
2917{
2918 if (!!s1 != !!s2)
2919 return false;
2920 if (s1 == s2)
2921 return true;
2922 return elf_symbols_alias(*s1, *s2);
2923}
2924
2925/// Test if two symbols alias.
2926///
2927/// @param s1 the first symbol to consider.
2928///
2929/// @param s2 the second symbol to consider.
2930///
2931/// @return true if @p s1 aliases @p s2.
2932bool
2934{return elf_symbols_alias(s1.get(), s2.get());}
2935
2936/// Serialize an instance of @ref symbol_type and stream it to a given
2937/// output stream.
2938///
2939/// @param o the output stream to serialize the symbole type to.
2940///
2941/// @param t the symbol type to serialize.
2942std::ostream&
2943operator<<(std::ostream& o, elf_symbol::type t)
2944{
2945 string repr;
2946
2947 switch (t)
2948 {
2949 case elf_symbol::NOTYPE_TYPE:
2950 repr = "unspecified symbol type";
2951 break;
2952 case elf_symbol::OBJECT_TYPE:
2953 repr = "variable symbol type";
2954 break;
2955 case elf_symbol::FUNC_TYPE:
2956 repr = "function symbol type";
2957 break;
2958 case elf_symbol::SECTION_TYPE:
2959 repr = "section symbol type";
2960 break;
2961 case elf_symbol::FILE_TYPE:
2962 repr = "file symbol type";
2963 break;
2964 case elf_symbol::COMMON_TYPE:
2965 repr = "common data object symbol type";
2966 break;
2967 case elf_symbol::TLS_TYPE:
2968 repr = "thread local data object symbol type";
2969 break;
2970 case elf_symbol::GNU_IFUNC_TYPE:
2971 repr = "indirect function symbol type";
2972 break;
2973 default:
2974 {
2975 std::ostringstream s;
2976 s << "unknown symbol type (" << (char)t << ')';
2977 repr = s.str();
2978 }
2979 break;
2980 }
2981
2982 o << repr;
2983 return o;
2984}
2985
2986/// Serialize an instance of @ref symbol_binding and stream it to a
2987/// given output stream.
2988///
2989/// @param o the output stream to serialize the symbole type to.
2990///
2991/// @param b the symbol binding to serialize.
2992std::ostream&
2993operator<<(std::ostream& o, elf_symbol::binding b)
2994{
2995 string repr;
2996
2997 switch (b)
2998 {
2999 case elf_symbol::LOCAL_BINDING:
3000 repr = "local binding";
3001 break;
3002 case elf_symbol::GLOBAL_BINDING:
3003 repr = "global binding";
3004 break;
3005 case elf_symbol::WEAK_BINDING:
3006 repr = "weak binding";
3007 break;
3008 case elf_symbol::GNU_UNIQUE_BINDING:
3009 repr = "GNU unique binding";
3010 break;
3011 default:
3012 {
3013 std::ostringstream s;
3014 s << "unknown binding (" << (unsigned char) b << ")";
3015 repr = s.str();
3016 }
3017 break;
3018 }
3019
3020 o << repr;
3021 return o;
3022}
3023
3024/// Serialize an instance of @ref elf_symbol::visibility and stream it
3025/// to a given output stream.
3026///
3027/// @param o the output stream to serialize the symbole type to.
3028///
3029/// @param v the symbol visibility to serialize.
3030std::ostream&
3031operator<<(std::ostream& o, elf_symbol::visibility v)
3032{
3033 string repr;
3034
3035 switch (v)
3036 {
3037 case elf_symbol::DEFAULT_VISIBILITY:
3038 repr = "default visibility";
3039 break;
3040 case elf_symbol::PROTECTED_VISIBILITY:
3041 repr = "protected visibility";
3042 break;
3043 case elf_symbol::HIDDEN_VISIBILITY:
3044 repr = "hidden visibility";
3045 break;
3046 case elf_symbol::INTERNAL_VISIBILITY:
3047 repr = "internal visibility";
3048 break;
3049 default:
3050 {
3051 std::ostringstream s;
3052 s << "unknown visibility (" << (unsigned char) v << ")";
3053 repr = s.str();
3054 }
3055 break;
3056 }
3057
3058 o << repr;
3059 return o;
3060}
3061
3062/// Convert a string representing a symbol type into an
3063/// elf_symbol::type.
3064///
3065///@param s the string to convert.
3066///
3067///@param t the resulting elf_symbol::type.
3068///
3069/// @return true iff the conversion completed successfully.
3070bool
3072{
3073 if (s == "no-type")
3074 t = elf_symbol::NOTYPE_TYPE;
3075 else if (s == "object-type")
3076 t = elf_symbol::OBJECT_TYPE;
3077 else if (s == "func-type")
3078 t = elf_symbol::FUNC_TYPE;
3079 else if (s == "section-type")
3080 t = elf_symbol::SECTION_TYPE;
3081 else if (s == "file-type")
3082 t = elf_symbol::FILE_TYPE;
3083 else if (s == "common-type")
3084 t = elf_symbol::COMMON_TYPE;
3085 else if (s == "tls-type")
3086 t = elf_symbol::TLS_TYPE;
3087 else if (s == "gnu-ifunc-type")
3088 t = elf_symbol::GNU_IFUNC_TYPE;
3089 else
3090 return false;
3091
3092 return true;
3093}
3094
3095/// Convert a string representing a an elf symbol binding into an
3096/// elf_symbol::binding.
3097///
3098/// @param s the string to convert.
3099///
3100/// @param b the resulting elf_symbol::binding.
3101///
3102/// @return true iff the conversion completed successfully.
3103bool
3105{
3106 if (s == "local-binding")
3107 b = elf_symbol::LOCAL_BINDING;
3108 else if (s == "global-binding")
3109 b = elf_symbol::GLOBAL_BINDING;
3110 else if (s == "weak-binding")
3111 b = elf_symbol::WEAK_BINDING;
3112 else if (s == "gnu-unique-binding")
3113 b = elf_symbol::GNU_UNIQUE_BINDING;
3114 else
3115 return false;
3116
3117 return true;
3118}
3119
3120/// Convert a string representing a an elf symbol visibility into an
3121/// elf_symbol::visibility.
3122///
3123/// @param s the string to convert.
3124///
3125/// @param b the resulting elf_symbol::visibility.
3126///
3127/// @return true iff the conversion completed successfully.
3128bool
3130{
3131 if (s == "default-visibility")
3132 v = elf_symbol::DEFAULT_VISIBILITY;
3133 else if (s == "protected-visibility")
3134 v = elf_symbol::PROTECTED_VISIBILITY;
3135 else if (s == "hidden-visibility")
3136 v = elf_symbol::HIDDEN_VISIBILITY;
3137 else if (s == "internal-visibility")
3138 v = elf_symbol::INTERNAL_VISIBILITY;
3139 else
3140 return false;
3141
3142 return true;
3143}
3144
3145/// Test if the type of an ELF symbol denotes a function symbol.
3146///
3147/// @param t the type of the ELF symbol.
3148///
3149/// @return true iff elf symbol type @p t denotes a function symbol
3150/// type.
3151bool
3153{return t == elf_symbol::FUNC_TYPE;}
3154
3155/// Test if the type of an ELF symbol denotes a function symbol.
3156///
3157/// @param t the type of the ELF symbol.
3158///
3159/// @return true iff elf symbol type @p t denotes a function symbol
3160/// type.
3161bool
3163{return t == elf_symbol::OBJECT_TYPE;}
3164
3165// <elf_symbol::version stuff>
3166
3167struct elf_symbol::version::priv
3168{
3169 string version_;
3170 bool is_default_;
3171
3172 priv()
3173 : is_default_(false)
3174 {}
3175
3176 priv(const string& v,
3177 bool d)
3178 : version_(v),
3179 is_default_(d)
3180 {}
3181}; // end struct elf_symbol::version::priv
3182
3183elf_symbol::version::version()
3184 : priv_(new priv)
3185{}
3186
3187/// @param v the name of the version.
3188///
3189/// @param is_default true if this is a default version.
3190elf_symbol::version::version(const string& v,
3191 bool is_default)
3192 : priv_(new priv(v, is_default))
3193{}
3194
3195elf_symbol::version::version(const elf_symbol::version& v)
3196 : priv_(new priv(v.str(), v.is_default()))
3197{
3198}
3199
3200elf_symbol::version::~version() = default;
3201
3202/// Cast the version_type into a string that is its name.
3203///
3204/// @return the name of the version.
3205elf_symbol::version::operator const string&() const
3206{return priv_->version_;}
3207
3208/// Getter for the version name.
3209///
3210/// @return the version name.
3211const string&
3213{return priv_->version_;}
3214
3215/// Setter for the version name.
3216///
3217/// @param s the version name.
3218void
3220{priv_->version_ = s;}
3221
3222/// Getter for the 'is_default' property of the version.
3223///
3224/// @return true iff this is a default version.
3225bool
3227{return priv_->is_default_;}
3228
3229/// Setter for the 'is_default' property of the version.
3230///
3231/// @param f true if this is the default version.
3232void
3234{priv_->is_default_ = f;}
3235
3236bool
3237elf_symbol::version::is_empty() const
3238{return str().empty();}
3239
3240/// Compares the current version against another one.
3241///
3242/// @param o the other version to compare the current one to.
3243///
3244/// @return true iff the current version equals @p o.
3245bool
3247{return str() == o.str();}
3248
3249/// Inequality operator.
3250///
3251/// @param o the version to compare against the current one.
3252///
3253/// @return true iff both versions are different.
3254bool
3255elf_symbol::version::operator!=(const version& o) const
3256{return !operator==(o);}
3257
3258/// Assign a version to the current one.
3259///
3260/// @param o the other version to assign to this one.
3261///
3262/// @return a reference to the assigned version.
3265{
3266 str(o.str());
3268 return *this;
3269}
3270
3271// </elf_symbol::version stuff>
3272
3273// </elf_symbol stuff>
3274
3275// <class dm_context_rel stuff>
3276struct dm_context_rel::priv
3277{
3278 bool is_laid_out_;
3279 size_t offset_in_bits_;
3280 var_decl* anonymous_data_member_;
3281
3282 priv(bool is_static = false)
3283 : is_laid_out_(!is_static),
3284 offset_in_bits_(0),
3285 anonymous_data_member_()
3286 {}
3287
3288 priv(bool is_laid_out, size_t offset_in_bits)
3289 : is_laid_out_(is_laid_out),
3290 offset_in_bits_(offset_in_bits),
3291 anonymous_data_member_()
3292 {}
3293}; //end struct dm_context_rel::priv
3294
3295dm_context_rel::dm_context_rel()
3296 : context_rel(),
3297 priv_(new priv)
3298{}
3299
3300dm_context_rel::dm_context_rel(scope_decl* s,
3301 bool is_laid_out,
3302 size_t offset_in_bits,
3304 bool is_static)
3305 : context_rel(s, a, is_static),
3306 priv_(new priv(is_laid_out, offset_in_bits))
3307{}
3308
3309dm_context_rel::dm_context_rel(scope_decl* s)
3310 : context_rel(s),
3311 priv_(new priv())
3312{}
3313
3314bool
3315dm_context_rel::get_is_laid_out() const
3316{return priv_->is_laid_out_;}
3317
3318void
3319dm_context_rel::set_is_laid_out(bool f)
3320{priv_->is_laid_out_ = f;}
3321
3322size_t
3323dm_context_rel::get_offset_in_bits() const
3324{return priv_->offset_in_bits_;}
3325
3326void
3327dm_context_rel::set_offset_in_bits(size_t o)
3328{priv_->offset_in_bits_ = o;}
3329
3330bool
3331dm_context_rel::operator==(const dm_context_rel& o) const
3332{
3333 if (!context_rel::operator==(o))
3334 return false;
3335
3336 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3337 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3338}
3339
3340bool
3341dm_context_rel::operator!=(const dm_context_rel& o) const
3342{return !operator==(o);}
3343
3344/// Return a non-nil value if this data member context relationship
3345/// has an anonymous data member. That means, if the data member this
3346/// relation belongs to is part of an anonymous data member.
3347///
3348/// @return the containing anonymous data member of this data member
3349/// relationship. Nil if there is none.
3350const var_decl*
3352{return priv_->anonymous_data_member_;}
3353
3354/// Set the containing anonymous data member of this data member
3355/// context relationship. That means that the data member this
3356/// relation belongs to is part of an anonymous data member.
3357///
3358/// @param anon_dm the containing anonymous data member of this data
3359/// member relationship. Nil if there is none.
3360void
3362{priv_->anonymous_data_member_ = anon_dm;}
3363
3364dm_context_rel::~dm_context_rel()
3365{}
3366// </class dm_context_rel stuff>
3367
3368// <environment stuff>
3369
3370/// Convenience typedef for a map of interned_string -> bool.
3371typedef unordered_map<interned_string,
3373
3374
3375/// Default constructor of the @ref environment type.
3377 :priv_(new priv)
3378{}
3379
3380/// Destructor for the @ref environment type.
3383
3384/// Getter the map of canonical types.
3385///
3386/// @return the map of canonical types. The key of the map is the
3387/// hash of the canonical type and its value if the canonical type.
3390{return priv_->canonical_types_;}
3391
3392/// Getter the map of canonical types.
3393///
3394/// @return the map of canonical types. The key of the map is the
3395/// hash of the canonical type and its value if the canonical type.
3399
3400/// Helper to detect if a type is either a reference, a pointer, or a
3401/// qualified type.
3402bool
3404{
3405 if (is_pointer_type(t)
3406 || is_reference_type(t)
3407 || is_qualified_type(t))
3408 return true;
3409 return false;
3410}
3411
3412/// Compare decls using their locations.
3413///
3414/// @param f the first decl to compare.
3415///
3416/// @param s the second decl to compare.
3417///
3418/// @return true if @p f compares less than @p s.
3419bool
3421 const decl_base *s)
3422{
3423 // If a decl has artificial location, then use that one over the
3424 // natural one.
3427
3428 ABG_ASSERT(fl.get_value() && sl.get_value());
3429 if (fl.get_is_artificial() == sl.get_is_artificial())
3430 {
3431 // The locations of the two artfifacts have the same
3432 // artificial-ness so they can be compared.
3433 string p1, p2;
3434 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3435 fl.expand(p1, l1, c1);
3436 sl.expand(p2, l2, c2);
3437 if (p1 != p2)
3438 return p1 < p2;
3439 if (l1 != l2)
3440 return l1 < l2;
3441 if (c1 != c2)
3442 return c1 < c2;
3443 }
3444
3445 return (get_pretty_representation(f, /*internal=*/false)
3446 < get_pretty_representation(s, /*internal=*/false));
3447}
3448
3449/// Sort types in a hopefully stable manner.
3450///
3451/// @param types a set of types with canonical types to sort.
3452///
3453/// @param result the resulting sorted vector.
3454void
3456 vector<type_base_sptr>& result)
3457{
3458 for (auto t: types)
3459 result.push_back(t);
3460
3461 type_topo_comp comp;
3462 std::stable_sort(result.begin(), result.end(), comp);
3463}
3464
3465/// Get the unique @ref type_decl that represents a "void" type for
3466/// the current environment. This node must be the only one
3467/// representing a void type in the system.
3468///
3469/// Note that upon first use of this IR node (by the relevant
3470/// front-end, for instance) it must be added to a scope using e.g,
3471/// the @ref add_decl_to_scope() function.
3472///
3473/// @return the @ref type_decl that represents a "void" type.
3474const type_base_sptr&
3476{
3477 if (!priv_->void_type_)
3478 priv_->void_type_.reset(new type_decl(*this,
3479 intern("void"),
3480 0, 0, location()));
3481 return priv_->void_type_;
3482}
3483
3484/// Getter of the "pointer-to-void" IR node that is shared across the
3485/// ABI corpus. This node must be the only one representing a void
3486/// pointer type in the system.
3487///
3488/// Note that upon first use of this IR node (by the relevant
3489/// front-end, for instance) it must be added to a scope using e.g,
3490/// the @ref add_decl_to_scope() function.
3491///
3492/// @return the "pointer-to-void" IR node.
3493const type_base_sptr&
3495{
3496 if (!priv_->void_pointer_type_)
3497 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3498 0, 0, location()));
3499 return priv_->void_pointer_type_;
3500}
3501
3502/// Get a @ref type_decl instance that represents a the type of a
3503/// variadic function parameter. This node must be the only one
3504/// representing a variadic parameter type in the system.
3505///
3506/// Note that upon first use of this IR node (by the relevant
3507/// front-end, for instance) it must be added to a scope using e.g,
3508/// the @ref add_decl_to_scope() function.
3509///
3510/// @return the Get a @ref type_decl instance that represents a the
3511/// type of a variadic function parameter.
3512const type_base_sptr&
3514{
3515 if (!priv_->variadic_marker_type_)
3516 priv_->variadic_marker_type_.
3518 0, 0, location()));
3519 return priv_->variadic_marker_type_;
3520}
3521
3522/// Getter of the name of the variadic parameter type.
3523///
3524/// @return the name of the variadic parameter type.
3525string&
3527{
3528 static string variadic_parameter_type_name = "variadic parameter type";
3529 return variadic_parameter_type_name;
3530}
3531
3532/// Test if the canonicalization of types created out of the current
3533/// environment is done.
3534///
3535/// @return true iff the canonicalization of types created out of the current
3536/// environment is done.
3537bool
3539{return priv_->canonicalization_is_done_;}
3540
3541/// Set a flag saying if the canonicalization of types created out of
3542/// the current environment is done or not.
3543///
3544/// Note that this function must only be called by internal code of
3545/// the library that creates ABI artifacts (e.g, read an abi corpus
3546/// from elf or from our own xml format and creates representations of
3547/// types out of it) and thus needs to canonicalize types to speed-up
3548/// further type comparison.
3549///
3550/// @param f the new value of the flag.
3551void
3553{
3554 priv_->canonicalization_is_done_ = f;
3555 if (priv_->canonicalization_is_done_)
3557}
3558
3559/// Getter of a flag saying if the canonicalization process has
3560/// started or not.
3561///
3562/// @return the flag saying if the canonicalization process has
3563/// started or not.
3564bool
3566{return priv_->canonicalization_started_;}
3567
3568/// Setter of a flag saying if the canonicalization process has
3569/// started or not.
3570///
3571/// @param f the new value of the flag saying if the canonicalization
3572/// process has started or not.
3573void
3575{priv_->canonicalization_started_ = f;}
3576
3577/// Getter of the "decl-only-class-equals-definition" flag.
3578///
3579/// Usually, a declaration-only class named 'struct foo' compares
3580/// equal to any class definition named "struct foo'. This is at
3581/// least true for C++.
3582///
3583/// In C, though, because there can be multiple definitions of 'struct
3584/// foo' in the binary, a declaration-only "struct foo" might be
3585/// considered to *NOT* resolve to any of the struct foo defined. In
3586/// that case, the declaration-only "struct foo" is considered
3587/// different from the definitions.
3588///
3589/// This flag controls the behaviour of the comparison of an
3590/// unresolved decl-only class against a definition of the same name.
3591///
3592/// If set to false, the the declaration equals the definition. If
3593/// set to false, then the decalration is considered different from
3594/// the declaration.
3595///
3596/// @return the value of the "decl-only-class-equals-definition" flag.
3597bool
3599{return priv_->decl_only_class_equals_definition_;}
3600
3601/// Setter of the "decl-only-class-equals-definition" flag.
3602///
3603/// Usually, a declaration-only class named 'struct foo' compares
3604/// equal to any class definition named "struct foo'. This is at
3605/// least true for C++.
3606///
3607/// In C, though, because there can be multiple definitions of 'struct
3608/// foo' in the binary, a declaration-only "struct foo" might be
3609/// considered to *NOT* resolve to any of the struct foo defined. In
3610/// that case, the declaration-only "struct foo" is considered
3611/// different from the definitions.
3612///
3613/// This flag controls the behaviour of the comparison of an
3614/// unresolved decl-only class against a definition of the same name.
3615///
3616/// If set to false, the the declaration equals the definition. If
3617/// set to false, then the decalration is considered different from
3618/// the declaration.
3619///
3620/// @param the new value of the "decl-only-class-equals-definition"
3621/// flag.
3622void
3624{priv_->decl_only_class_equals_definition_ = f;}
3625
3626/// Test if a given type is a void type as defined in the current
3627/// environment.
3628///
3629/// @param t the type to consider.
3630///
3631/// @return true iff @p t is a void type as defined in the current
3632/// environment.
3633bool
3634environment::is_void_type(const type_base_sptr& t) const
3635{
3636 if (!t)
3637 return false;
3638 return is_void_type(t.get());
3639}
3640
3641/// Test if a given type is a void type as defined in the current
3642/// environment.
3643///
3644/// @param t the type to consider.
3645///
3646/// @return true iff @p t is a void type as defined in the current
3647/// environment.
3648bool
3650{
3651 if (!t)
3652 return false;
3653 return (t == get_void_type().get()
3654 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3655}
3656
3657/// Test if a given type is the same as the void pointer type of the
3658/// environment.
3659///
3660/// @param t the IR type to test.
3661///
3662/// @return true iff @p t is the void pointer returned by
3663/// environment::get_void_pointer_type().
3664bool
3665environment::is_void_pointer_type(const type_base_sptr& t) const
3666{
3667 if (!t)
3668 return false;
3669
3670 return t.get() == get_void_pointer_type().get();
3671}
3672
3673/// Test if a given type is the same as the void pointer type of the
3674/// environment.
3675///
3676/// @param t the IR type to test.
3677///
3678/// @return true iff @p t is the void pointer returned by
3679/// environment::get_void_pointer_type().
3680bool
3682{
3683 if (!t)
3684 return false;
3685
3686 return t == get_void_pointer_type().get();
3687}
3688
3689/// Test if a type is a variadic parameter type as defined in the
3690/// current environment.
3691///
3692/// @param t the type to consider.
3693///
3694/// @return true iff @p t is a variadic parameter type as defined in
3695/// the current environment.
3696bool
3698{
3699 if (!t)
3700 return false;
3701 return t == get_variadic_parameter_type().get();
3702}
3703
3704/// Test if a type is a variadic parameter type as defined in the
3705/// current environment.
3706///
3707/// @param t the type to consider.
3708///
3709/// @return true iff @p t is a variadic parameter type as defined in
3710/// the current environment.
3711bool
3712environment::is_variadic_parameter_type(const type_base_sptr& t) const
3713{return is_variadic_parameter_type(t.get());}
3714
3715/// Do intern a string.
3716///
3717/// If a value of this string already exists in the interned string
3718/// pool of the current environment, then this function returns a new
3719/// interned_string pointing to that already existing string.
3720/// Otherwise, a new string is created, stored in the interned string
3721/// pool and a new interned_string instance is created to point to
3722/// that new intrerned string, and it's return.
3723///
3724/// @param s the value of the string to intern.
3725///
3726/// @return the interned string.
3728environment::intern(const string& s) const
3729{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3730
3731/// Getter of the general configuration object.
3732///
3733/// @return the configuration object.
3734const config&
3736{return priv_->config_;}
3737
3738/// Getter for a property that says if the user actually did set the
3739/// analyze_exported_interfaces_only() property. If not, it means
3740/// the default behaviour prevails.
3741///
3742/// @return tru iff the user did set the
3743/// analyze_exported_interfaces_only() property.
3744bool
3746{return priv_->analyze_exported_interfaces_only_.has_value();}
3747
3748/// Setter for the property that controls if we are to restrict the
3749/// analysis to the types that are only reachable from the exported
3750/// interfaces only, or if the set of types should be more broad than
3751/// that. Typically, we'd restrict the analysis to types reachable
3752/// from exported interfaces only (stricto sensu, that would really be
3753/// only the types that are part of the ABI of well designed
3754/// libraries) for performance reasons.
3755///
3756/// @param f the value of the flag.
3757void
3759{priv_->analyze_exported_interfaces_only_ = f;}
3760
3761/// Getter for the property that controls if we are to restrict the
3762/// analysis to the types that are only reachable from the exported
3763/// interfaces only, or if the set of types should be more broad than
3764/// that. Typically, we'd restrict the analysis to types reachable
3765/// from exported interfaces only (stricto sensu, that would really be
3766/// only the types that are part of the ABI of well designed
3767/// libraries) for performance reasons.
3768///
3769/// @param f the value of the flag.
3770bool
3772{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3773
3774#ifdef WITH_DEBUG_SELF_COMPARISON
3775/// Setter of the corpus of the input corpus of the self comparison
3776/// that takes place when doing "abidw --debug-abidiff <binary>".
3777///
3778/// The first invocation of this function sets the first corpus of the
3779/// self comparison. The second invocation of this very same function
3780/// sets the second corpus of the self comparison. That second corpus
3781/// is supposed to come from the abixml serialization of the first
3782/// corpus.
3783///
3784/// @param c the corpus of the input binary or the corpus of the
3785/// abixml serialization of the initial binary input.
3786void
3787environment::set_self_comparison_debug_input(const corpus_sptr& c)
3788{
3789 self_comparison_debug_is_on(true);
3790 if (priv_->first_self_comparison_corpus_.expired())
3791 priv_->first_self_comparison_corpus_ = c;
3792 else if (priv_->second_self_comparison_corpus_.expired()
3793 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3794 priv_->second_self_comparison_corpus_ = c;
3795}
3796
3797/// Getter for the corpora of the input binary and the intermediate
3798/// abixml of the self comparison that takes place when doing
3799/// 'abidw --debug-abidiff <binary>'.
3800///
3801/// @param first_corpus output parameter that is set to the corpus of
3802/// the input corpus.
3803///
3804/// @param second_corpus output parameter that is set to the corpus of
3805/// the second corpus.
3806void
3807environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3808 corpus_sptr& second_corpus)
3809{
3810 first_corpus = priv_->first_self_comparison_corpus_.lock();
3811 second_corpus = priv_->second_self_comparison_corpus_.lock();
3812}
3813
3814/// Turn on/off the self comparison debug mode.
3815///
3816/// @param f true iff the self comparison debug mode is turned on.
3817void
3818environment::self_comparison_debug_is_on(bool f)
3819{priv_->self_comparison_debug_on_ = f;}
3820
3821/// Test if we are in the process of the 'self-comparison
3822/// debugging' as triggered by 'abidw --debug-abidiff' command.
3823///
3824/// @return true if self comparison debug is on.
3825bool
3826environment::self_comparison_debug_is_on() const
3827{return priv_->self_comparison_debug_on_;}
3828#endif
3829
3830#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3831/// Set the "type canonicalization debugging" mode, triggered by using
3832/// the command: "abidw --debug-tc".
3833///
3834/// @param flag if true then the type canonicalization debugging mode
3835/// is enabled.
3836void
3837environment::debug_type_canonicalization_is_on(bool flag)
3838{priv_->debug_type_canonicalization_ = flag;}
3839
3840/// Getter of the "type canonicalization debugging" mode, triggered by
3841/// using the command: "abidw --debug-tc".
3842///
3843/// @return true iff the type canonicalization debugging mode is
3844/// enabled.
3845bool
3846environment::debug_type_canonicalization_is_on() const
3847{return priv_->debug_type_canonicalization_;}
3848
3849/// Setter of the "DIE canonicalization debugging" mode, triggered by
3850/// using the command: "abidw --debug-dc".
3851///
3852/// @param flag true iff the DIE canonicalization debugging mode is
3853/// enabled.
3854void
3855environment::debug_die_canonicalization_is_on(bool flag)
3856{priv_->debug_die_canonicalization_ = flag;}
3857
3858/// Getter of the "DIE canonicalization debugging" mode, triggered by
3859/// using the command: "abidw --debug-dc".
3860///
3861/// @return true iff the DIE canonicalization debugging mode is
3862/// enabled.
3863bool
3864environment::debug_die_canonicalization_is_on() const
3865{return priv_->debug_die_canonicalization_;}
3866#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3867
3868/// Get the vector of canonical types which have a given "string
3869/// representation".
3870///
3871/// @param 'name', the textual representation of the type as returned
3872/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3873/// /*qualified=*/true)
3874///
3875/// This is useful to for debugging purposes as it's handy to use from
3876/// inside a debugger like GDB.
3877///
3878/// @return a pointer to the vector of canonical types having the
3879/// representation @p name, or nullptr if no type with that
3880/// representation exists.
3883{
3884 auto ti = get_canonical_types_map().find(name);
3885 if (ti == get_canonical_types_map().end())
3886 return nullptr;
3887 return &ti->second;
3888}
3889
3890/// Get a given canonical type which has a given "string
3891/// representation".
3892///
3893/// @param 'name', the textual representation of the type as returned
3894/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3895/// /*qualified=*/true).
3896///
3897/// @param index, the index of the type in the vector of types that
3898/// all have the same textual representation @p 'name'. That vector
3899/// is returned by the function environment::get_canonical_types().
3900///
3901/// @return the canonical type which has the representation @p name,
3902/// and which is at index @p index in the vector of canonical types
3903/// having that same textual representation.
3904type_base*
3905environment::get_canonical_type(const char* name, unsigned index)
3906{
3907 const vector<type_base_sptr> *types = get_canonical_types(name);
3908 if (!types ||index >= types->size())
3909 return nullptr;
3910 return (*types)[index].get();
3911}
3912
3913#ifdef WITH_DEBUG_SELF_COMPARISON
3914/// Get the set of abixml type-id and the pointer value of the
3915/// (canonical) type it's associated to.
3916///
3917/// This is useful for debugging purposes, especially in the context
3918/// of the use of the command:
3919/// 'abidw --debug-abidiff <binary>'.
3920///
3921/// @return the set of abixml type-id and the pointer value of the
3922/// (canonical) type it's associated to.
3923const unordered_map<string, uintptr_t>&
3924environment::get_type_id_canonical_type_map() const
3925{return priv_->get_type_id_canonical_type_map();}
3926
3927/// Get the set of abixml type-id and the pointer value of the
3928/// (canonical) type it's associated to.
3929///
3930/// This is useful for debugging purposes, especially in the context
3931/// of the use of the command:
3932/// 'abidw --debug-abidiff <binary>'.
3933///
3934/// @return the set of abixml type-id and the pointer value of the
3935/// (canonical) type it's associated to.
3936unordered_map<string, uintptr_t>&
3937environment::get_type_id_canonical_type_map()
3938{return priv_->get_type_id_canonical_type_map();}
3939
3940/// Getter of the map that associates the values of type pointers to
3941/// their type-id strings.
3942///
3943/// Note that this map is populated at abixml reading time, (by
3944/// build_type()) when a given XML element representing a type is
3945/// read into a corresponding abigail::ir::type_base.
3946///
3947/// This is used only for the purpose of debugging the
3948/// self-comparison process. That is, when invoking "abidw
3949/// --debug-abidiff".
3950///
3951/// @return the map that associates the values of type pointers to
3952/// their type-id strings.
3953const unordered_map<uintptr_t, string>&
3954environment::get_pointer_type_id_map() const
3955{return priv_->get_pointer_type_id_map();}
3956
3957/// Getter of the map that associates the values of type pointers to
3958/// their type-id strings.
3959///
3960/// Note that this map is populated at abixml reading time, (by
3961/// build_type()) when a given XML element representing a type is
3962/// read into a corresponding abigail::ir::type_base.
3963///
3964/// This is used only for the purpose of debugging the
3965/// self-comparison process. That is, when invoking "abidw
3966/// --debug-abidiff".
3967///
3968/// @return the map that associates the values of type pointers to
3969/// their type-id strings.
3970unordered_map<uintptr_t, string>&
3971environment::get_pointer_type_id_map()
3972{return priv_->get_pointer_type_id_map();}
3973
3974/// Getter of the type-id that corresponds to the value of a pointer
3975/// to abigail::ir::type_base that was created from the abixml reader.
3976///
3977/// That value is retrieved from the map returned from
3978/// environment::get_pointer_type_id_map().
3979///
3980/// That map is populated at abixml reading time, (by build_type())
3981/// when a given XML element representing a type is read into a
3982/// corresponding abigail::ir::type_base.
3983///
3984/// This is used only for the purpose of debugging the
3985/// self-comparison process. That is, when invoking "abidw
3986/// --debug-abidiff".
3987///
3988/// @return the type-id strings that corresponds
3989string
3990environment::get_type_id_from_pointer(uintptr_t ptr) const
3991{return priv_->get_type_id_from_pointer(ptr);}
3992
3993/// Getter of the type-id that corresponds to the value of an
3994/// abigail::ir::type_base that was created from the abixml reader.
3995///
3996/// That value is retrieved from the map returned from
3997/// environment::get_pointer_type_id_map().
3998///
3999/// That map is populated at abixml reading time, (by build_type())
4000/// when a given XML element representing a type is read into a
4001/// corresponding abigail::ir::type_base.
4002///
4003/// This is used only for the purpose of debugging the
4004/// self-comparison process. That is, when invoking "abidw
4005/// --debug-abidiff".
4006///
4007/// @return the type-id strings that corresponds
4008string
4009environment::get_type_id_from_type(const type_base *t) const
4010{return priv_->get_type_id_from_type(t);}
4011
4012/// Getter of the canonical type of the artifact designated by a
4013/// type-id.
4014///
4015/// That type-id was generated by the abixml writer at the emitting
4016/// time of the abixml file. The corresponding canonical type was
4017/// stored in the map returned by
4018/// environment::get_type_id_canonical_type_map().
4019///
4020/// This is useful for debugging purposes, especially in the context
4021/// of the use of the command:
4022/// 'abidw --debug-abidiff <binary>'.
4023///
4024/// @return the set of abixml type-id and the pointer value of the
4025/// (canonical) type it's associated to.
4026uintptr_t
4027environment::get_canonical_type_from_type_id(const char* type_id) const
4028{return priv_->get_canonical_type_from_type_id(type_id);}
4029#endif
4030
4031// </environment stuff>
4032
4033// <type_or_decl_base stuff>
4034
4035/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4036/// bitmap type.
4040{
4041 return static_cast<type_or_decl_base::type_or_decl_kind>
4042 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4043}
4044
4045/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4046/// bitmap type.
4050{
4051 l = l | r;
4052 return l;
4053}
4054
4055/// bitwise "AND" operator for the
4056/// type_or_decl_base::type_or_decl_kind bitmap type.
4060{
4061 return static_cast<type_or_decl_base::type_or_decl_kind>
4062 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4063}
4064
4065/// bitwise "A&=" operator for the
4066/// type_or_decl_base::type_or_decl_kind bitmap type.
4070{
4071 l = l & r;
4072 return l;
4073}
4074
4075/// Constructor of @ref type_or_decl_base.
4076///
4077/// @param the environment the current ABI artifact is constructed
4078/// from.
4079///
4080/// @param k the runtime identifier bitmap of the type being built.
4081type_or_decl_base::type_or_decl_base(const environment& e,
4082 enum type_or_decl_kind k)
4083 :priv_(new priv(e, k))
4084{}
4085
4086/// The destructor of the @ref type_or_decl_base type.
4089
4090/// Getter of the flag that says if the artefact is artificial.
4091///
4092/// Being artificial means it was not explicitely mentionned in the
4093/// source code, but was rather artificially created by the compiler
4094/// or libabigail.
4095///
4096/// @return true iff the declaration is artificial.
4097bool
4099{return priv_->is_artificial_;}
4100
4101/// Setter of the flag that says if the artefact is artificial.
4102///
4103/// Being artificial means the artefact was not explicitely
4104/// mentionned in the source code, but was rather artificially created
4105/// by the compiler or by libabigail.
4106///
4107/// @param f the new value of the flag that says if the artefact is
4108/// artificial.
4109void
4111{priv_->is_artificial_ = f;}
4112
4113/// Getter for the "kind" property of @ref type_or_decl_base type.
4114///
4115/// This property holds the identifier bitmap of the runtime type of
4116/// an ABI artifact.
4117///
4118/// @return the runtime type identifier bitmap of the current ABI
4119/// artifact.
4122{return priv_->kind();}
4123
4124/// Setter for the "kind" property of @ref type_or_decl_base type.
4125///
4126/// This property holds the identifier bitmap of the runtime type of
4127/// an ABI artifact.
4128///
4129/// @param the runtime type identifier bitmap of the current ABI
4130/// artifact.
4131void
4133{priv_->kind(k);}
4134
4135/// Getter of the pointer to the runtime type sub-object of the
4136/// current instance.
4137///
4138/// @return the pointer to the runtime type sub-object of the current
4139/// instance.
4140const void*
4142{return priv_->rtti_;}
4143
4144/// Getter of the pointer to the runtime type sub-object of the
4145/// current instance.
4146///
4147/// @return the pointer to the runtime type sub-object of the current
4148/// instance.
4149void*
4151{return priv_->rtti_;}
4152
4153/// Setter of the pointer to the runtime type sub-object of the
4154/// current instance.
4155///
4156/// @param i the new pointer to the runtime type sub-object of the
4157/// current instance.
4158void
4160{
4161 priv_->rtti_ = i;
4162 if (type_base* t = dynamic_cast<type_base*>(this))
4163 priv_->type_or_decl_ptr_ = t;
4164 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4165 priv_->type_or_decl_ptr_ = d;
4166}
4167
4168/// Getter of the pointer to either the type_base sub-object of the
4169/// current instance if it's a type, or to the decl_base sub-object of
4170/// the current instance if it's a decl.
4171///
4172/// @return the pointer to either the type_base sub-object of the
4173/// current instance if it's a type, or to the decl_base sub-object of
4174/// the current instance if it's a decl.
4175const void*
4177{return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4178
4179/// Getter of the pointer to either the type_base sub-object of the
4180/// current instance if it's a type, or to the decl_base sub-object of
4181/// the current instance if it's a decl.
4182///
4183/// @return the pointer to either the type_base sub-object of the
4184/// current instance if it's a type, or to the decl_base sub-object of
4185/// the current instance if it's a decl.
4186void*
4188{return priv_->type_or_decl_ptr_;}
4189
4190/// Return the hash value of the current IR node.
4191///
4192/// Note that upon the first invocation, this member functions
4193/// computes the hash value and returns it. Subsequent invocations
4194/// just return the hash value that was previously calculated.
4195///
4196/// @return the hash value of the current IR node.
4197hash_t
4199{return priv_->hash_value_;}
4200
4201void
4202type_or_decl_base::set_hash_value(hash_t h) const
4203{priv_->set_hash_value(h);}
4204
4205/// Getter of the environment of the current ABI artifact.
4206///
4207/// @return the environment of the artifact.
4208const environment&
4210{return priv_->env_;}
4211
4212/// Setter of the artificial location of the artificat.
4213///
4214/// The artificial location is a location that was artificially
4215/// generated by libabigail, not generated by the original emitter of
4216/// the ABI meta-data. For instance, when reading an XML element from
4217/// an abixml file, the artificial location is the source location of
4218/// the XML element within the file, not the value of the
4219/// 'location'property that might be carried by the element.
4220///
4221/// Artificial locations might be useful to ensure that abixml emitted
4222/// by the abixml writer are sorted the same way as the input abixml
4223/// read by the reader.
4224///
4225/// @param l the new artificial location.
4226void
4228{priv_->artificial_location_ = l;}
4229
4230/// Getter of the artificial location of the artifact.
4231///
4232/// The artificial location is a location that was artificially
4233/// generated by libabigail, not generated by the original emitter of
4234/// the ABI meta-data. For instance, when reading an XML element from
4235/// an abixml file, the artificial location is the source location of
4236/// the XML element within the file, not the value of the
4237/// 'location'property that might be carried by the element.
4238///
4239/// Artificial locations might be useful to ensure that the abixml
4240/// emitted by the abixml writer is sorted the same way as the input
4241/// abixml read by the reader.
4242///
4243/// @return the new artificial location.
4244location&
4246{return priv_->artificial_location_;}
4247
4248/// Test if the current ABI artifact carries an artificial location.
4249///
4250/// @return true iff the current ABI artifact carries an artificial location.
4251bool
4253{
4254 return (priv_->artificial_location_
4255 && priv_->artificial_location_.get_is_artificial());
4256}
4257
4258/// Get the @ref corpus this ABI artifact belongs to.
4259///
4260/// @return the corpus this ABI artifact belongs to, or nil if it
4261/// belongs to none for now.
4262corpus*
4264{
4266 if (!tu)
4267 return 0;
4268 return tu->get_corpus();
4269}
4270
4271
4272/// Get the @ref corpus this ABI artifact belongs to.
4273///
4274/// @return the corpus this ABI artifact belongs to, or nil if it
4275/// belongs to none for now.
4276const corpus*
4278{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4279
4280/// Set the @ref translation_unit this ABI artifact belongs to.
4281///
4282/// Note that adding an ABI artifact to a containining on should
4283/// invoke this member function.
4284void
4286{priv_->translation_unit_ = tu;}
4287
4288
4289/// Get the @ref translation_unit this ABI artifact belongs to.
4290///
4291/// @return the translation unit this ABI artifact belongs to, or nil
4292/// if belongs to none for now.
4295{return priv_->translation_unit_;}
4296
4297/// Get the @ref translation_unit this ABI artifact belongs to.
4298///
4299/// @return the translation unit this ABI artifact belongs to, or nil
4300/// if belongs to none for now.
4301const translation_unit*
4303{return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4304
4305/// Traverse the the ABI artifact.
4306///
4307/// @param v the visitor used to traverse the sub-tree nodes of the
4308/// artifact.
4309bool
4312
4313/// Non-member equality operator for the @type_or_decl_base type.
4314///
4315/// @param lr the left-hand operand of the equality.
4316///
4317/// @param rr the right-hand operatnr of the equality.
4318///
4319/// @return true iff @p lr equals @p rr.
4320bool
4322{
4323 const type_or_decl_base* l = &lr;
4324 const type_or_decl_base* r = &rr;
4325
4326 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4327 *dr = dynamic_cast<const decl_base*>(r);
4328
4329 if (!!dl != !!dr)
4330 return false;
4331
4332 if (dl && dr)
4333 return *dl == *dr;
4334
4335 const type_base* tl = dynamic_cast<const type_base*>(l),
4336 *tr = dynamic_cast<const type_base*>(r);
4337
4338 if (!!tl != !!tr)
4339 return false;
4340
4341 if (tl && tr)
4342 return *tl == *tr;
4343
4344 return false;
4345}
4346
4347/// Non-member equality operator for the @type_or_decl_base type.
4348///
4349/// @param l the left-hand operand of the equality.
4350///
4351/// @param r the right-hand operatnr of the equality.
4352///
4353/// @return true iff @p l equals @p r.
4354bool
4356{
4357 if (!! l != !!r)
4358 return false;
4359
4360 if (!l)
4361 return true;
4362
4363 return *r == *l;
4364}
4365
4366/// Non-member inequality operator for the @type_or_decl_base type.
4367///
4368/// @param l the left-hand operand of the equality.
4369///
4370/// @param r the right-hand operator of the equality.
4371///
4372/// @return true iff @p l is different from @p r.
4373bool
4376
4377// </type_or_decl_base stuff>
4378
4379// <Decl definition>
4380
4381struct decl_base::priv
4382{
4383 bool in_pub_sym_tab_;
4384 bool is_anonymous_;
4385 location location_;
4386 context_rel *context_;
4387 interned_string name_;
4388 interned_string qualified_parent_name_;
4389 // This temporary qualified name is the cache used for the qualified
4390 // name before the type associated to this decl (if applicable) is
4391 // canonicalized. Once the type is canonicalized, the cached use is
4392 // the data member qualified_parent_name_ above.
4393 interned_string temporary_qualified_name_;
4394 // This is the fully qualified name of the decl. It contains the
4395 // name of the decl and the qualified name of its scope. So if in
4396 // the parent scopes of the decl, there is one anonymous struct,
4397 // somewhere in the name, there is going to by an
4398 // __anonymous_struct__ string, even if the anonymous struct is not
4399 // the direct containing scope of this decl.
4400 interned_string qualified_name_;
4401 interned_string temporary_internal_qualified_name_;
4402 interned_string internal_qualified_name_;
4403 interned_string internal_cached_repr_;
4404 interned_string cached_repr_;
4405 // Unline qualified_name_, scoped_name_ contains the name of the
4406 // decl and the name of its scope; not the qualified name of the
4407 // scope.
4408 interned_string scoped_name_;
4409 interned_string linkage_name_;
4410 visibility visibility_;
4411 decl_base_sptr declaration_;
4412 decl_base_wptr definition_of_declaration_;
4413 decl_base* naked_definition_of_declaration_;
4414 bool is_declaration_only_;
4415 typedef_decl_sptr naming_typedef_;
4416
4417 priv()
4418 : in_pub_sym_tab_(false),
4419 is_anonymous_(true),
4420 context_(),
4421 visibility_(VISIBILITY_DEFAULT),
4422 naked_definition_of_declaration_(),
4423 is_declaration_only_(false)
4424 {}
4425
4426 priv(interned_string name, interned_string linkage_name, visibility vis)
4427 : in_pub_sym_tab_(false),
4428 context_(),
4429 name_(name),
4430 qualified_name_(name),
4431 linkage_name_(linkage_name),
4432 visibility_(vis),
4433 naked_definition_of_declaration_(),
4434 is_declaration_only_(false)
4435 {
4436 is_anonymous_ = name_.empty();
4437 }
4438
4439 ~priv()
4440 {
4441 delete context_;
4442 }
4443};// end struct decl_base::priv
4444
4445/// Constructor for the @ref decl_base type.
4446///
4447/// @param e the environment the current @ref decl_base is being
4448/// created in.
4449///
4450/// @param name the name of the declaration.
4451///
4452/// @param locus the location where to find the declaration in the
4453/// source code.
4454///
4455/// @param linkage_name the linkage name of the declaration.
4456///
4457/// @param vis the visibility of the declaration.
4458decl_base::decl_base(const environment& e,
4459 const string& name,
4460 const location& locus,
4461 const string& linkage_name,
4462 visibility vis)
4463 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4464 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4465{
4466 set_location(locus);
4467}
4468
4469/// Constructor.
4470///
4471/// @param e the environment this instance of @ref decl_base is
4472/// created in.
4473///
4474/// @param name the name of the declaration being constructed.
4475///
4476/// @param locus the source location of the declaration being constructed.
4477///
4478/// @param linkage_name the linkage name of the declaration being
4479/// constructed.
4480///
4481/// @param vis the visibility of the declaration being constructed.
4482decl_base::decl_base(const environment& e,
4483 const interned_string& name,
4484 const location& locus,
4485 const interned_string& linkage_name,
4486 visibility vis)
4487 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4488 priv_(new priv(name, linkage_name, vis))
4489{
4490 set_location(locus);
4491}
4492
4493/// Constructor for the @ref decl_base type.
4494///
4495///@param environment the environment this instance of @ref decl_base
4496/// is being constructed in.
4497///
4498/// @param l the location where to find the declaration in the source
4499/// code.
4500decl_base::decl_base(const environment& e, const location& l)
4501 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4502 priv_(new priv())
4503{
4504 set_location(l);
4505}
4506
4507/// Getter for the qualified name.
4508///
4509/// Unlike decl_base::get_qualified_name() this doesn't try to update
4510/// the qualified name.
4511///
4512/// @return the qualified name.
4513const interned_string&
4515{return priv_->qualified_name_;}
4516
4517/// Clear the qualified name of this decl.
4518///
4519/// This is useful to ensure that the cache for the qualified name of
4520/// the decl is refreshed right after type canonicalization, for
4521/// instance.
4522void
4524{priv_->qualified_name_.clear();}
4525
4526/// Setter for the qualified name.
4527///
4528/// @param n the new qualified name.
4529void
4531{priv_->qualified_name_ = n;}
4532
4533/// Getter of the temporary qualified name of the current declaration.
4534///
4535/// This temporary qualified name is used as a qualified name cache by
4536/// the type for which this is the declaration (when applicable)
4537/// before the type is canonicalized. Once the type is canonicalized,
4538/// it's the result of decl_base::peek_qualified_name() that becomes
4539/// the qualified name cached.
4540///
4541/// @return the temporary qualified name.
4542const interned_string&
4544{return priv_->temporary_qualified_name_;}
4545
4546/// Setter for the temporary qualified name of the current
4547/// declaration.
4548///
4549///@param n the new temporary qualified name.
4550///
4551/// This temporary qualified name is used as a qualified name cache by
4552/// the type for which this is the declaration (when applicable)
4553/// before the type is canonicalized. Once the type is canonicalized,
4554/// it's the result of decl_base::peek_qualified_name() that becomes
4555/// the qualified name cached.
4556void
4558{priv_->temporary_qualified_name_ = n;}
4559
4560///Getter for the context relationship.
4561///
4562///@return the context relationship for the current decl_base.
4563const context_rel*
4565{return priv_->context_;}
4566
4567///Getter for the context relationship.
4568///
4569///@return the context relationship for the current decl_base.
4572{return priv_->context_;}
4573
4574void
4575decl_base::set_context_rel(context_rel *c)
4576{priv_->context_ = c;}
4577
4578/// Test if the decl is defined in a ELF symbol table as a public
4579/// symbol.
4580///
4581/// @return true iff the decl is defined in a ELF symbol table as a
4582/// public symbol.
4583bool
4585{return priv_->in_pub_sym_tab_;}
4586
4587/// Set the flag saying if this decl is from a symbol that is in
4588/// a public symbols table, defined as public (global or weak).
4589///
4590/// @param f the new flag value.
4591void
4593{priv_->in_pub_sym_tab_ = f;}
4594
4595/// Get the location of a given declaration.
4596///
4597/// The location is an abstraction for the tripplet {file path,
4598/// line, column} that defines where the declaration appeared in the
4599/// source code.
4600///
4601/// To get the value of the tripplet {file path, line, column} from
4602/// the @ref location, you need to use the
4603/// location_manager::expand_location() method.
4604///
4605/// The instance of @ref location_manager that you want is
4606/// accessible from the instance of @ref translation_unit that the
4607/// current instance of @ref decl_base belongs to, via a call to
4608/// translation_unit::get_loc_mgr().
4609///
4610/// @return the location of the current instance of @ref decl_base.
4611const location&
4613{return priv_->location_;}
4614
4615/// Set the location for a given declaration.
4616///
4617/// The location is an abstraction for the tripplet {file path,
4618/// line, column} that defines where the declaration appeared in the
4619/// source code.
4620///
4621/// To create a location from a tripplet {file path, line, column},
4622/// you need to use the method @ref
4623/// location_manager::create_new_location().
4624///
4625/// Note that there can be two kinds of location. An artificial
4626/// location and a non-artificial one. The non-artificial location is
4627/// the one emitted by the original emitter of the ABI artifact, for
4628/// instance, if the ABI artifact comes from debug info, then the
4629/// source location that is present in the debug info represent a
4630/// non-artificial location. When looking at an abixml file on the
4631/// other hand, the value of the 'location' attribute of an XML
4632/// element describing an artifact is the non-artificial location.
4633/// The artificial location is the location (line number from the
4634/// beginning of the file) of the XML element within the abixml file.
4635///
4636/// So, if the location that is being set is artificial, note that the
4637/// type_or_decl_base::has_artificial_location() method of this decl will
4638/// subsequently return true and that artificial location will have to
4639/// be retrieved using type_or_decl_base::get_artificial_location().
4640/// If the location is non-artificial however,
4641/// type_or_decl_base::has_artificial_location() will subsequently
4642/// return false and the non-artificial location will have to be
4643/// retrieved using decl_base::get_location().
4644///
4645/// The instance of @ref location_manager that you want is
4646/// accessible from the instance of @ref translation_unit that the
4647/// current instance of @ref decl_base belongs to, via a call to
4648/// translation_unit::get_loc_mgr().
4649void
4651{
4652 if (l.get_is_artificial())
4654 else
4655 priv_->location_ = l;
4656}
4657
4658/// Setter for the name of the decl.
4659///
4660/// @param n the new name to set.
4661void
4662decl_base::set_name(const string& n)
4663{
4664 priv_->name_ = get_environment().intern(n);
4665 priv_->is_anonymous_ = n.empty();
4666}
4667
4668/// Test if the current declaration is anonymous.
4669///
4670/// Being anonymous means that the declaration was created without a
4671/// name. This can usually happen for enum or struct types.
4672///
4673/// @return true iff the type is anonymous.
4674bool
4676{return priv_->is_anonymous_;}
4677
4678/// Set the "is_anonymous" flag of the current declaration.
4679///
4680/// Being anonymous means that the declaration was created without a
4681/// name. This can usually happen for enum or struct types.
4682///
4683/// @param f the new value of the flag.
4684void
4686{priv_->is_anonymous_ = f;}
4687
4688
4689/// Get the "has_anonymous_parent" flag of the current declaration.
4690///
4691/// Having an anoymous parent means having a anonymous parent scope
4692/// (containing type or namespace) which is either direct or indirect.
4693///
4694/// @return true iff the current decl has a direct or indirect scope
4695/// which is anonymous.
4696bool
4698{
4699 scope_decl *scope = get_scope();
4700 if (!scope)
4701 return false;
4702 return scope->get_is_anonymous();
4703}
4704
4705/// @return the logical "OR" of decl_base::get_is_anonymous() and
4706/// decl_base::get_has_anonymous_parent().
4707bool
4710
4711/// Getter for the naming typedef of the current decl.
4712///
4713/// Consider the C idiom:
4714///
4715/// typedef struct {int member;} foo_type;
4716///
4717/// In that idiom, foo_type is the naming typedef of the anonymous
4718/// struct that is declared.
4719///
4720/// @return the naming typedef, if any. Otherwise, returns nil.
4723{return priv_->naming_typedef_;}
4724
4725/// Set the naming typedef of the current instance of @ref decl_base.
4726///
4727/// Consider the C idiom:
4728///
4729/// typedef struct {int member;} foo_type;
4730///
4731/// In that idiom, foo_type is the naming typedef of the anonymous
4732/// struct that is declared.
4733///
4734/// After completion of this function, the decl will not be considered
4735/// anonymous anymore. It's name is going to be the name of the
4736/// naming typedef.
4737///
4738/// @param typedef_type the new naming typedef.
4739void
4741{
4742 // A naming typedef is usually for an anonymous type.
4744 // Whe the typedef-named decl is saved into abixml, it's
4745 // not anonymous anymore. Its name is the typedef name.
4746 // So when we read it back, we must still be able to
4747 // apply the naming typedef to the decl.
4748 || t->get_name() == get_name());
4749 // Only non canonicalized types can be edited this way.
4750 ABG_ASSERT(is_type(this)
4751 && is_type(this)->get_naked_canonical_type() == nullptr);
4752
4753 priv_->naming_typedef_ = t;
4754 set_name(t->get_name());
4755 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4756 set_qualified_name(get_environment().intern(qualified_name));
4757 set_is_anonymous(false);
4758 // Now that the qualified type of the decl has changed, let's update
4759 // the qualified names of the member types of this decls.
4760 update_qualified_name(this);
4761}
4762
4763/// Getter for the mangled name.
4764///
4765/// @return the new mangled name.
4766const interned_string&
4768{return priv_->linkage_name_;}
4769
4770/// Setter for the linkage name.
4771///
4772/// @param m the new linkage name.
4773void
4775{
4776 const environment& env = get_environment();
4777 priv_->linkage_name_ = env.intern(m);
4778}
4779
4780/// Getter for the visibility of the decl.
4781///
4782/// @return the new visibility.
4785{return priv_->visibility_;}
4786
4787/// Setter for the visibility of the decl.
4788///
4789/// @param v the new visibility.
4790void
4792{priv_->visibility_ = v;}
4793
4794/// Return the type containing the current decl, if any.
4795///
4796/// @return the type that contains the current decl, or NULL if there
4797/// is none.
4800{
4801 if (priv_->context_)
4802 return priv_->context_->get_scope();
4803 return 0;
4804}
4805
4806/// Return a copy of the qualified name of the parent of the current
4807/// decl.
4808///
4809/// @return the newly-built qualified name of the of the current decl.
4810const interned_string&
4812{return priv_->qualified_parent_name_;}
4813
4814/// Getter for the name of the current decl.
4815///
4816/// @return the name of the current decl.
4817const interned_string&
4819{return priv_->name_;}
4820
4821/// Compute the qualified name of the decl.
4822///
4823/// @param qn the resulting qualified name.
4824///
4825/// @param internal set to true if the call is intended for an
4826/// internal use (for technical use inside the library itself), false
4827/// otherwise. If you don't know what this is for, then set it to
4828/// false.
4829void
4831{qn = get_qualified_name(internal);}
4832
4833/// Get the pretty representatin of the current declaration.
4834///
4835///
4836/// @param internal set to true if the call is intended to get a
4837/// representation of the decl (or type) for the purpose of canonical
4838/// type comparison. This is mainly used in the function
4839/// type_base::get_canonical_type_for().
4840///
4841/// In other words if the argument for this parameter is true then the
4842/// call is meant for internal use (for technical use inside the
4843/// library itself), false otherwise. If you don't know what this is
4844/// for, then set it to false.
4845///
4846/// @param qualified_name if true, names emitted in the pretty
4847/// representation are fully qualified.
4848///
4849/// @return the default pretty representation for a decl. This is
4850/// basically the fully qualified name of the decl optionally prefixed
4851/// with a meaningful string to add context for the user.
4852string
4854 bool qualified_name) const
4855{
4856 if (internal
4857 && get_is_anonymous()
4858 && has_generic_anonymous_internal_type_name(this))
4859 {
4860 // We are looking at an anonymous enum, union or class and we
4861 // want an *internal* pretty representation for it. All
4862 // anonymous types of this kind in the same namespace must have
4863 // the same internal representation for type canonicalization to
4864 // work properly.
4865 //
4866 // OK, in practise, we are certainly looking at an enum because
4867 // classes and unions should have their own overloaded virtual
4868 // member function for this.
4869 string name = get_generic_anonymous_internal_type_name(this);
4870 if (qualified_name && !get_qualified_parent_name().empty())
4871 name = get_qualified_parent_name() + "::" + name;
4872 return name;
4873 }
4874
4875 if (qualified_name)
4876 return get_qualified_name(internal);
4877 return get_name();
4878}
4879
4880/// Get the pretty representation of the current decl.
4881///
4882/// The pretty representation is retrieved from a cache. If the cache
4883/// is empty, this function computes the pretty representation, put it
4884/// in the cache and returns it.
4885///
4886/// Please note that if this function is called too early in the life
4887/// cycle of the decl (before it is fully constructed), then the
4888/// pretty representation that is cached is going to represent a
4889/// non-complete (and thus wrong) representation of the decl. Thus
4890/// this function must be called only once the decl is fully
4891/// constructed.
4892///
4893/// @param internal if true, then the pretty representation is to be
4894/// used for purpuses that are internal to the libabigail library
4895/// itself. If you don't know what this means, then you probably
4896/// should set this parameter to "false".
4897///
4898/// @return a reference to a cached @ref interned_string holding the
4899/// pretty representation of the current decl.
4900const interned_string&
4902{
4903 if (internal)
4904 {
4905 if (priv_->internal_cached_repr_.empty())
4906 {
4907 string r = ir::get_pretty_representation(this, internal);
4908 priv_->internal_cached_repr_ = get_environment().intern(r);
4909 }
4910 return priv_->internal_cached_repr_;
4911 }
4912
4913 if (priv_->cached_repr_.empty())
4914 {
4915 string r = ir::get_pretty_representation(this, internal);
4916 priv_->cached_repr_ = get_environment().intern(r);
4917 }
4918
4919 return priv_->cached_repr_;
4920}
4921
4922/// Return the qualified name of the decl.
4923///
4924/// This is the fully qualified name of the decl. It's made of the
4925/// concatenation of the name of the decl with the qualified name of
4926/// its scope.
4927///
4928/// Note that the value returned by this function is computed by @ref
4929/// update_qualified_name when the decl is added to its scope.
4930///
4931/// @param internal set to true if the call is intended for an
4932/// internal use (for technical use inside the library itself), false
4933/// otherwise. If you don't know what this is for, then set it to
4934/// false.
4935///
4936/// @return the resulting qualified name.
4937const interned_string&
4938decl_base::get_qualified_name(bool /*internal*/) const
4939{return priv_->qualified_name_;}
4940
4941/// Return the scoped name of the decl.
4942///
4943/// This is made of the concatenation of the name of the decl with the
4944/// name of its scope. It doesn't contain the qualified name of its
4945/// scope, unlike what is returned by decl_base::get_qualified_name.
4946///
4947/// Note that the value returned by this function is computed by @ref
4948/// update_qualified_name when the decl is added to its scope.
4949///
4950/// @return the scoped name of the decl.
4951const interned_string&
4953{return priv_->scoped_name_;}
4954
4955/// If this @ref decl_base is a definition, get its earlier
4956/// declaration.
4957///
4958/// @return the earlier declaration of the class, if any.
4959const decl_base_sptr
4961{return priv_->declaration_;}
4962
4963/// set the earlier declaration of this @ref decl_base definition.
4964///
4965/// @param d the earlier declaration to set. Note that it's set only
4966/// if it's a pure declaration.
4967void
4969{
4970 if (d && d->get_is_declaration_only())
4971 priv_->declaration_ = d;
4972}
4973
4974
4975/// If this @ref decl_base is declaration-only, get its definition, if
4976/// any.
4977///
4978/// @return the definition of this decl-only @ref decl_base.
4979const decl_base_sptr
4981{return priv_->definition_of_declaration_.lock();}
4982
4983/// If this @ref decl_base is declaration-only, get its definition,
4984/// if any.
4985///
4986/// Note that this function doesn't return a smart pointer, but rather
4987/// the underlying pointer managed by the smart pointer. So it's as
4988/// fast as possible. This getter is to be used in code paths that
4989/// are proven to be performance hot spots; especially, when comparing
4990/// sensitive types like enums, classes or unions. Those are compared
4991/// extremely frequently and thus, their access to the definition of
4992/// declaration must be fast.
4993///
4994/// @return the definition of the declaration.
4995const decl_base*
4997{return priv_->naked_definition_of_declaration_;}
4998
4999/// Test if a @ref decl_base is a declaration-only decl.
5000///
5001/// @return true iff the current @ref decl_base is declaration-only.
5002bool
5004{return priv_->is_declaration_only_;}
5005
5006/// Set a flag saying if the @ref enum_type_decl is a declaration-only
5007/// @ref enum_type_decl.
5008///
5009/// @param f true if the @ref enum_type_decl is a declaration-only
5010/// @ref enum_type_decl.
5011void
5013{
5014 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5015
5016 priv_->is_declaration_only_ = f;
5017
5018 if (update_types_lookup_map)
5019 if (scope_decl* s = get_scope())
5020 {
5021 scope_decl::declarations::iterator i;
5022 if (s->find_iterator_for_member(this, i))
5024 else
5026 }
5027}
5028
5031{
5032 return static_cast<change_kind>(static_cast<unsigned>(l)
5033 | static_cast<unsigned>(r));
5034}
5035
5038{
5039 return static_cast<change_kind>(static_cast<unsigned>(l)
5040 & static_cast<unsigned>(r));
5041}
5042
5043change_kind&
5044operator|=(change_kind& l, change_kind r)
5045{
5046 l = l | r;
5047 return l;
5048}
5049
5052{
5053 l = l & r;
5054 return l;
5055}
5056
5057/// Compare the properties that belong to the "is-a-member-relation"
5058/// of a decl.
5059///
5060/// For instance, access specifiers are part of the
5061/// "is-a-member-relation" of a decl.
5062///
5063/// This comparison however doesn't take decl names into account. So
5064/// typedefs for instance are decls that we want to compare with this
5065/// function.
5066///
5067/// This function is a sub-routine of the more general 'equals'
5068/// overload for instances of decl_base.
5069///
5070/// @param l the left-hand side operand of the comparison.
5071///
5072/// @param r the right-hand side operand of the comparison.
5073///
5074/// @return true iff @p l compare equals, as a member decl, to @p r.
5075bool
5077 const decl_base& r,
5078 change_kind* k)
5079{
5080 bool result = true;
5081 if (is_member_decl(l) && is_member_decl(r))
5082 {
5083 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5084 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5085
5086 access_specifier la = no_access, ra = no_access;
5087 bool member_types_or_functions =
5088 ((is_type(l) && is_type(r))
5089 || (is_function_decl(l) && is_function_decl(r)));
5090
5091 if (member_types_or_functions)
5092 {
5093 // Access specifiers on member types in DWARF is not
5094 // reliable; in the same DSO, the same struct can be either
5095 // a class or a struct, and the access specifiers of its
5096 // member types are not necessarily given, so they
5097 // effectively can be considered differently, again, in the
5098 // same DSO. So, here, let's avoid considering those!
5099 // during comparison.
5100 la = r1->get_access_specifier();
5101 ra = r2->get_access_specifier();
5102 r1->set_access_specifier(no_access);
5103 r2->set_access_specifier(no_access);
5104 }
5105
5106 bool rels_are_different = *r1 != *r2;
5107
5108 if (member_types_or_functions)
5109 {
5110 // restore the access specifiers.
5111 r1->set_access_specifier(la);
5112 r2->set_access_specifier(ra);
5113 }
5114
5115 if (rels_are_different)
5116 {
5117 result = false;
5118 if (k)
5120 }
5121 }
5122 ABG_RETURN(result);
5123}
5124
5125/// Compares two instances of @ref decl_base.
5126///
5127/// If the two intances are different, set a bitfield to give some
5128/// insight about the kind of differences there are.
5129///
5130/// @param l the first artifact of the comparison.
5131///
5132/// @param r the second artifact of the comparison.
5133///
5134/// @param k a pointer to a bitfield that gives information about the
5135/// kind of changes there are between @p l and @p r. This one is set
5136/// iff it's non-null and if the function returns false.
5137///
5138/// Please note that setting k to a non-null value does have a
5139/// negative performance impact because even if @p l and @p r are not
5140/// equal, the function keeps up the comparison in order to determine
5141/// the different kinds of ways in which they are different.
5142///
5143/// @return true if @p l equals @p r, false otherwise.
5144bool
5145equals(const decl_base& l, const decl_base& r, change_kind* k)
5146{
5147 bool result = true;
5148 const interned_string &l_linkage_name = l.get_linkage_name();
5149 const interned_string &r_linkage_name = r.get_linkage_name();
5150 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5151 {
5152 if (l_linkage_name != r_linkage_name)
5153 {
5154 // Linkage names are different. That usually means the two
5155 // decls are different, unless we are looking at two
5156 // function declarations which have two different symbols
5157 // that are aliases of each other.
5158 const function_decl *f1 = is_function_decl(&l),
5159 *f2 = is_function_decl(&r);
5160 if (f1 && f2 && function_decls_alias(*f1, *f2))
5161 ;// The two functions are aliases, so they are not
5162 // different.
5163 else
5164 {
5165 result = false;
5166 if (k)
5168 else
5170 }
5171 }
5172 }
5173
5174 if (r.get_is_anonymous() && l.get_is_anonymous())
5175 // We are looking at too anonymous types (or two members of
5176 // anonymous types) with one not yet been added to the IR. That
5177 // means we want to compare just the object part of the
5178 // anonymous type and not their qualified names. This is used
5179 // when looking up an anonymous type inside a class type.
5180 ABG_RETURN(result);
5181
5182 // This is the name of the decls that we want to compare.
5183 interned_string ln = l.get_name(), rn = r.get_name();
5184
5185 /// If both of the current decls have an anonymous scope then let's
5186 /// compare their name component by component by properly handling
5187 /// anonymous scopes. That's the slow path.
5188 ///
5189 /// Otherwise, let's just compare their name, the obvious way.
5190 /// That's the fast path because in that case the names are
5191 /// interned_string and comparing them is much faster.
5192 bool decls_are_same = (ln == rn);
5193
5194 if (!decls_are_same)
5195 {
5196 result = false;
5197 if (k)
5199 else
5201 }
5202
5203 result &= maybe_compare_as_member_decls(l, r, k);
5204
5205 ABG_RETURN(result);
5206}
5207
5208/// Return true iff the two decls have the same name.
5209///
5210/// This function doesn't test if the scopes of the the two decls are
5211/// equal.
5212///
5213/// Note that this virtual function is to be implemented by classes
5214/// that extend the \p decl_base class.
5215bool
5216decl_base::operator==(const decl_base& other) const
5217{return equals(*this, other, 0);}
5218
5219/// Inequality operator.
5220///
5221/// @param other to other instance of @ref decl_base to compare the
5222/// current instance to.
5223///
5224/// @return true iff the current instance of @ref decl_base is
5225/// different from @p other.
5226bool
5227decl_base::operator!=(const decl_base& other) const
5228{return !operator==(other);}
5229
5230/// Destructor of the @ref decl_base type.
5232{delete priv_;}
5233
5234/// This implements the ir_traversable_base::traverse pure virtual
5235/// function.
5236///
5237/// @param v the visitor used on the member nodes of the translation
5238/// unit during the traversal.
5239///
5240/// @return true if the entire IR node tree got traversed, false
5241/// otherwise.
5242bool
5244{
5245 // Do nothing in the base class.
5246 return true;
5247}
5248
5249/// Setter of the scope of the current decl.
5250///
5251/// Note that the decl won't hold a reference on the scope. It's
5252/// rather the scope that holds a reference on its members.
5253void
5254decl_base::set_scope(scope_decl* scope)
5255{
5256 if (!priv_->context_)
5257 priv_->context_ = new context_rel(scope);
5258 else
5259 priv_->context_->set_scope(scope);
5260}
5261
5262// </decl_base definition>
5263
5264/// Streaming operator for the decl_base::visibility.
5265///
5266/// @param o the output stream to serialize the visibility to.
5267///
5268/// @param v the visibility to serialize.
5269///
5270/// @return the output stream.
5271std::ostream&
5272operator<<(std::ostream& o, decl_base::visibility v)
5273{
5274 string r;
5275 switch (v)
5276 {
5277 case decl_base::VISIBILITY_NONE:
5278 r = "none";
5279 break;
5280 case decl_base::VISIBILITY_DEFAULT:
5281 r = "default";
5282 break;
5283 case decl_base::VISIBILITY_PROTECTED:
5284 r = "protected";
5285 break;
5286 case decl_base::VISIBILITY_HIDDEN:
5287 r = "hidden";
5288 break;
5289 case decl_base::VISIBILITY_INTERNAL:
5290 r = "internal";
5291 break;
5292 }
5293 return o;
5294}
5295
5296/// Streaming operator for decl_base::binding.
5297///
5298/// @param o the output stream to serialize the visibility to.
5299///
5300/// @param b the binding to serialize.
5301///
5302/// @return the output stream.
5303std::ostream&
5304operator<<(std::ostream& o, decl_base::binding b)
5305{
5306 string r;
5307 switch (b)
5308 {
5309 case decl_base::BINDING_NONE:
5310 r = "none";
5311 break;
5312 case decl_base::BINDING_LOCAL:
5313 r = "local";
5314 break;
5315 case decl_base::BINDING_GLOBAL:
5316 r = "global";
5317 break;
5318 case decl_base::BINDING_WEAK:
5319 r = "weak";
5320 break;
5321 }
5322 o << r;
5323 return o;
5324}
5325
5326/// Turn equality of shared_ptr of decl_base into a deep equality;
5327/// that is, make it compare the pointed to objects, not just the
5328/// pointers.
5329///
5330/// @param l the shared_ptr of decl_base on left-hand-side of the
5331/// equality.
5332///
5333/// @param r the shared_ptr of decl_base on right-hand-side of the
5334/// equality.
5335///
5336/// @return true if the decl_base pointed to by the shared_ptrs are
5337/// equal, false otherwise.
5338bool
5339operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5340{
5341 if (l.get() == r.get())
5342 return true;
5343 if (!!l != !!r)
5344 return false;
5345
5346 return *l == *r;
5347}
5348
5349/// Inequality operator of shared_ptr of @ref decl_base.
5350///
5351/// This is a deep equality operator, that is, it compares the
5352/// pointed-to objects, rather than just the pointers.
5353///
5354/// @param l the left-hand-side operand.
5355///
5356/// @param r the right-hand-side operand.
5357///
5358/// @return true iff @p l is different from @p r.
5359bool
5360operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5361{return !operator==(l, r);}
5362
5363/// Turn equality of shared_ptr of type_base into a deep equality;
5364/// that is, make it compare the pointed to objects too.
5365///
5366/// @param l the shared_ptr of type_base on left-hand-side of the
5367/// equality.
5368///
5369/// @param r the shared_ptr of type_base on right-hand-side of the
5370/// equality.
5371///
5372/// @return true if the type_base pointed to by the shared_ptrs are
5373/// equal, false otherwise.
5374bool
5375operator==(const type_base_sptr& l, const type_base_sptr& r)
5376{
5377 if (l.get() == r.get())
5378 return true;
5379 if (!!l != !!r)
5380 return false;
5381
5382 return *l == *r;
5383}
5384
5385/// Turn inequality of shared_ptr of type_base into a deep equality;
5386/// that is, make it compare the pointed to objects..
5387///
5388/// @param l the shared_ptr of type_base on left-hand-side of the
5389/// equality.
5390///
5391/// @param r the shared_ptr of type_base on right-hand-side of the
5392/// equality.
5393///
5394/// @return true iff the type_base pointed to by the shared_ptrs are
5395/// different.
5396bool
5397operator!=(const type_base_sptr& l, const type_base_sptr& r)
5398{return !operator==(l, r);}
5399
5400/// Tests if a declaration has got a scope.
5401///
5402/// @param d the declaration to consider.
5403///
5404/// @return true if the declaration has got a scope, false otherwise.
5405bool
5407{return (d.get_scope());}
5408
5409/// Tests if a declaration has got a scope.
5410///
5411/// @param d the declaration to consider.
5412///
5413/// @return true if the declaration has got a scope, false otherwise.
5414bool
5415has_scope(const decl_base_sptr d)
5416{return has_scope(*d.get());}
5417
5418/// Tests if a declaration is a class member.
5419///
5420/// @param d the declaration to consider.
5421///
5422/// @return true if @p d is a class member, false otherwise.
5423bool
5424is_member_decl(const decl_base_sptr d)
5425{return is_at_class_scope(d) || is_method_decl(d);}
5426
5427/// Tests if a declaration is a class member.
5428///
5429/// @param d the declaration to consider.
5430///
5431/// @return true if @p d is a class member, false otherwise.
5432bool
5435
5436/// Tests if a declaration is a class member.
5437///
5438/// @param d the declaration to consider.
5439///
5440/// @return true if @p d is a class member, false otherwise.
5441bool
5444
5445/// Test if a declaration is a @ref scope_decl.
5446///
5447/// @param d the declaration to take in account.
5448///
5449/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5450/// if d is a @ref scope_decl.
5451const scope_decl*
5453{return dynamic_cast<const scope_decl*>(d);}
5454
5455/// Test if a declaration is a @ref scope_decl.
5456///
5457/// @param d the declaration to take in account.
5458///
5459/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5460/// if d is a @ref scope_decl.
5462is_scope_decl(const decl_base_sptr& d)
5463{return dynamic_pointer_cast<scope_decl>(d);}
5464
5465/// Tests if a type is a class member.
5466///
5467/// @param t the type to consider.
5468///
5469/// @return true if @p t is a class member type, false otherwise.
5470bool
5471is_member_type(const type_base_sptr& t)
5472{
5473 decl_base_sptr d = get_type_declaration(t);
5474 return is_member_decl(d);
5475}
5476
5477/// Test if a type is user-defined.
5478///
5479/// A type is considered user-defined if it's a
5480/// struct/class/union/enum that is *NOT* artificial.
5481///
5482/// @param t the type to consider.
5483///
5484/// @return true iff the type @p t is user-defined.
5485bool
5487{
5488 if (t == 0)
5489 return false;
5490
5492 decl_base *d = is_decl(t);
5493
5495 && d && !d->get_is_artificial())
5496 return true;
5497
5498 return false;
5499}
5500
5501/// Test if a type is user-defined.
5502///
5503/// A type is considered user-defined if it's a
5504/// struct/class/union/enum.
5505///
5506///
5507/// @param t the type to consider.
5508///
5509/// @return true iff the type @p t is user-defined.
5510bool
5511is_user_defined_type(const type_base_sptr& t)
5512{return is_user_defined_type(t.get());}
5513
5514/// Gets the access specifier for a class member.
5515///
5516/// @param d the declaration of the class member to consider. Note
5517/// that this must be a class member otherwise the function aborts the
5518/// current process.
5519///
5520/// @return the access specifier for the class member @p d.
5523{
5525
5526 const context_rel* c = d.get_context_rel();
5527 ABG_ASSERT(c);
5528
5529 return c->get_access_specifier();
5530}
5531
5532/// Gets the access specifier for a class member.
5533///
5534/// @param d the declaration of the class member to consider. Note
5535/// that this must be a class member otherwise the function aborts the
5536/// current process.
5537///
5538/// @return the access specifier for the class member @p d.
5540get_member_access_specifier(const decl_base_sptr& d)
5541{return get_member_access_specifier(*d);}
5542
5543/// Sets the access specifier for a class member.
5544///
5545/// @param d the class member to set the access specifier for. Note
5546/// that this must be a class member otherwise the function aborts the
5547/// current process.
5548///
5549/// @param a the new access specifier to set the class member to.
5550void
5553{
5555
5557 ABG_ASSERT(c);
5558
5559 c->set_access_specifier(a);
5560}
5561
5562/// Sets the access specifier for a class member.
5563///
5564/// @param d the class member to set the access specifier for. Note
5565/// that this must be a class member otherwise the function aborts the
5566/// current process.
5567///
5568/// @param a the new access specifier to set the class member to.
5569void
5570set_member_access_specifier(const decl_base_sptr& d,
5573
5574/// Gets a flag saying if a class member is static or not.
5575///
5576/// @param d the declaration for the class member to consider. Note
5577/// that this must be a class member otherwise the function aborts the
5578/// current process.
5579///
5580/// @return true if the class member @p d is static, false otherwise.
5581bool
5582get_member_is_static(const decl_base&d)
5583{
5585
5586 const context_rel* c = d.get_context_rel();
5587 ABG_ASSERT(c);
5588
5589 return c->get_is_static();
5590}
5591
5592/// Gets a flag saying if a class member is static or not.
5593///
5594/// @param d the declaration for the class member to consider. Note
5595/// that this must be a class member otherwise the function aborts the
5596/// current process.
5597///
5598/// @return true if the class member @p d is static, false otherwise.
5599bool
5602
5603/// Gets a flag saying if a class member is static or not.
5604///
5605/// @param d the declaration for the class member to consider. Note
5606/// that this must be a class member otherwise the function aborts the
5607/// current process.
5608///
5609/// @return true if the class member @p d is static, false otherwise.
5610bool
5611get_member_is_static(const decl_base_sptr& d)
5612{return get_member_is_static(*d);}
5613
5614/// Test if a var_decl is a data member.
5615///
5616/// @param v the var_decl to consider.
5617///
5618/// @return true if @p v is data member, false otherwise.
5619bool
5621{return is_at_class_scope(v);}
5622
5623/// Test if a var_decl is a data member.
5624///
5625/// @param v the var_decl to consider.
5626///
5627/// @return true if @p v is data member, false otherwise.
5628bool
5630{return is_data_member(*v);}
5631
5632/// Test if a var_decl is a data member.
5633///
5634/// @param v the var_decl to consider.
5635///
5636/// @return true if @p v is data member, false otherwise.
5637bool
5640
5641/// Test if a decl is a data member.
5642///
5643/// @param d the decl to consider.
5644///
5645/// @return a pointer to the data member iff @p d is a data member, or
5646/// a null pointer.
5648is_data_member(const decl_base_sptr& d)
5649{
5650 if (var_decl_sptr v = is_var_decl(d))
5651 {
5652 if (is_data_member(v))
5653 return v;
5654 }
5655 return var_decl_sptr();
5656}
5657
5658/// Test if a decl is a data member.
5659///
5660/// @param d the decl to consider.
5661///
5662/// @return a pointer to the data member iff @p d is a data member, or
5663/// a null pointer.
5666{
5667 if (var_decl_sptr v = is_var_decl(d))
5668 {
5669 if (is_data_member(v))
5670 return v;
5671 }
5672 return var_decl_sptr();
5673}
5674
5675/// Test if a decl is a data member.
5676///
5677/// @param d the decl to consider.
5678///
5679/// @return a pointer to the data member iff @p d is a data member, or
5680/// a null pointer.
5681var_decl*
5683{
5684 if (var_decl *v = is_var_decl(d))
5685 if (is_data_member(v))
5686 return v;
5687 return 0;
5688}
5689
5690/// Test if a decl is a data member.
5691///
5692/// @param d the decl to consider.
5693///
5694/// @return a pointer to the data member iff @p d is a data member, or
5695/// a null pointer.
5696var_decl*
5698{
5699 if (var_decl *v = is_var_decl(d))
5700 if (is_data_member(v))
5701 return v;
5702 return 0;
5703}
5704
5705/// Get the first non-anonymous data member of a given anonymous data
5706/// member.
5707///
5708/// E.g:
5709///
5710/// struct S
5711/// {
5712/// union // <-- for this anonymous data member, the function
5713/// // returns a.
5714/// {
5715/// int a;
5716/// charb;
5717/// };
5718/// };
5719///
5720/// @return anon_dm the anonymous data member to consider.
5721///
5722/// @return the first non-anonymous data member of @p anon_dm. If no
5723/// data member was found then this function returns @p anon_dm.
5724const var_decl_sptr
5726{
5727 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5728 return anon_dm;
5729
5730 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5731 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5732
5733 if (is_anonymous_data_member(first))
5735
5736 return first;
5737}
5738
5739/// In the context of a given class or union, this function returns
5740/// the data member that is located after a given data member.
5741///
5742/// @param klass the class or union to consider.
5743///
5744/// @param the data member to consider.
5745///
5746/// @return the data member that is located right after @p
5747/// data_member.
5748const var_decl_sptr
5750 const var_decl_sptr &data_member)
5751{
5752 if (!klass ||!data_member)
5753 return var_decl_sptr();
5754
5755 for (class_or_union::data_members::const_iterator it =
5756 klass->get_non_static_data_members().begin();
5757 it != klass->get_non_static_data_members().end();
5758 ++it)
5759 if (**it == *data_member)
5760 {
5761 ++it;
5762 if (it != klass->get_non_static_data_members().end())
5764 break;
5765 }
5766
5767 return var_decl_sptr();
5768}
5769
5770/// In the context of a given class or union, this function returns
5771/// the data member that is located after a given data member.
5772///
5773/// @param klass the class or union to consider.
5774///
5775/// @param the data member to consider.
5776///
5777/// @return the data member that is located right after @p
5778/// data_member.
5779const var_decl_sptr
5780get_next_data_member(const class_or_union_sptr& klass,
5781 const var_decl_sptr &data_member)
5782{return get_next_data_member(klass.get(), data_member);}
5783
5784/// Get the last data member of a class type.
5785///
5786/// @param klass the class type to consider.
5789{return klass.get_non_static_data_members().back();}
5790
5791/// Get the last data member of a class type.
5792///
5793/// @param klass the class type to consider.
5797
5798/// Get the last data member of a class type.
5799///
5800/// @param klass the class type to consider.
5802get_last_data_member(const class_or_union_sptr &klass)
5803{return get_last_data_member(klass.get());}
5804
5805/// Collect all the non-anonymous data members of a class or union type.
5806///
5807/// If the class contains any anonymous data member, this function
5808/// looks through it to collect the non-anonymous data members that it
5809/// contains. The function also looks through the base classes of the
5810/// current type.
5811///
5812/// @param cou the class or union type to consider.
5813///
5814/// @param dms output parameter. This is populated by the function
5815/// with a map containing the non-anonymous data members that were
5816/// collected. The key of the map is the name of the data member.
5817/// This is set iff the function returns true.
5818///
5819/// @return true iff at least one non-anonymous data member was
5820/// collected.
5821bool
5824{
5825 if (!cou)
5826 return false;
5827
5828 bool result = false;
5829 class_decl* klass = is_class_type(cou);
5830 if (klass)
5831 // First look into base classes for data members.
5833 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
5834
5835 // Then look into our data members
5836 for (var_decl_sptr member : cou->get_non_static_data_members())
5837 {
5838 if (is_anonymous_data_member(member))
5839 {
5840 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
5841 ABG_ASSERT(cl);
5842 result |= collect_non_anonymous_data_members(cl.get(), dms);
5843 }
5844 else
5845 {
5846 dms[member->get_name()] = member;
5847 result = true;
5848 }
5849 }
5850 return result;
5851}
5852
5853/// Collect all the non-anonymous data members of a class or union type.
5854///
5855/// If the class contains any anonymous data member, this function
5856/// looks through it to collect the non-anonymous data members that it
5857/// contains. The function also also looks through the base classes
5858/// of the current type.
5859///
5860/// @param cou the class or union type to consider.
5861///
5862/// @param dms output parameter. This is populated by the function
5863/// with a map containing the non-anonymous data members that were
5864/// collected. The key of the map is the name of the data member.
5865/// This is set iff the function returns true.
5866///
5867/// @return true iff at least one non-anonymous data member was
5868/// collected.
5869bool
5871{return collect_non_anonymous_data_members(cou.get(), dms);}
5872
5873/// Test if a decl is an anonymous data member.
5874///
5875/// @param d the decl to consider.
5876///
5877/// @return true iff @p d is an anonymous data member.
5878bool
5881
5882/// Test if a decl is an anonymous data member.
5883///
5884/// @param d the decl to consider.
5885///
5886/// @return the var_decl representing the data member iff @p d is an
5887/// anonymous data member.
5888const var_decl*
5890{
5891 if (const var_decl* v = is_data_member(d))
5892 {
5894 return v;
5895 }
5896 return 0;
5897}
5898
5899/// Test if a decl is an anonymous data member.
5900///
5901/// @param d the decl to consider.
5902///
5903/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5904/// it's an anonymous data member. Otherwise returns a nil pointer.
5905const var_decl*
5907{
5908 if (const var_decl* v = is_data_member(d))
5909 {
5911 return v;
5912 }
5913 return 0;
5914}
5915
5916/// Test if a decl is an anonymous data member.
5917///
5918/// @param d the decl to consider.
5919///
5920/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5921/// it's an anonymous data member. Otherwise returns a nil pointer.
5924{
5925 if (var_decl_sptr v = is_data_member(d))
5926 {
5928 return v;
5929 }
5930 return var_decl_sptr();
5931}
5932
5933/// Test if a decl is an anonymous data member.
5934///
5935/// @param d the decl to consider.
5936///
5937/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5938/// it's an anonymous data member. Otherwise returns a nil pointer.
5940is_anonymous_data_member(const decl_base_sptr& d)
5941{
5942 if (var_decl_sptr v = is_data_member(d))
5943 return is_anonymous_data_member(v);
5944 return var_decl_sptr();
5945}
5946
5947/// Test if a @ref var_decl is an anonymous data member.
5948///
5949/// @param d the @ref var_decl to consider.
5950///
5951/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5952/// it's an anonymous data member. Otherwise returns a nil pointer.
5955{
5956 if (is_anonymous_data_member(d.get()))
5957 return d;
5958 return var_decl_sptr();
5959}
5960
5961/// Test if a @ref var_decl is an anonymous data member.
5962///
5963/// @param d the @ref var_decl to consider.
5964///
5965/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5966/// it's an anonymous data member. Otherwise returns a nil pointer.
5967const var_decl*
5969{
5970 if (d && is_anonymous_data_member(*d))
5971 return d;
5972 return 0;
5973}
5974
5975/// Test if a @ref var_decl is an anonymous data member.
5976///
5977/// @param d the @ref var_decl to consider.
5978///
5979/// @return true iff @p d is an anonymous data member.
5980bool
5982{
5983 return (is_data_member(d)
5984 && d.get_is_anonymous()
5985 && d.get_name().empty()
5987}
5988
5989/// Test if a @ref var_decl is a data member belonging to an anonymous
5990/// type.
5991///
5992/// @param d the @ref var_decl to consider.
5993///
5994/// @return true iff @p d is a data member belonging to an anonymous
5995/// type.
5996bool
5998{
5999 if (is_data_member(d))
6000 {
6001 scope_decl* scope = d.get_scope();
6002 if (scope && scope->get_is_anonymous())
6003 return true;
6004 }
6005 return false;
6006}
6007
6008/// Test if a @ref var_decl is a data member belonging to an anonymous
6009/// type.
6010///
6011/// @param d the @ref var_decl to consider.
6012///
6013/// @return true iff @p d is a data member belonging to an anonymous
6014/// type.
6015bool
6018
6019/// Test if a @ref var_decl is a data member belonging to an anonymous
6020/// type.
6021///
6022/// @param d the @ref var_decl to consider.
6023///
6024/// @return true iff @p d is a data member belonging to an anonymous
6025/// type.
6026bool
6029
6030/// Get the @ref class_or_union type of a given anonymous data member.
6031///
6032/// @param d the anonymous data member to consider.
6033///
6034/// @return the @ref class_or_union type of the anonymous data member
6035/// @p d.
6038{
6039 if ((d = is_anonymous_data_member(d)))
6040 return is_class_or_union_type(d->get_type().get());
6041 return 0;
6042}
6043
6044/// Get the @ref class_or_union type of a given anonymous data member.
6045///
6046/// @param d the anonymous data member to consider.
6047///
6048/// @return the @ref class_or_union type of the anonymous data member
6049/// @p d.
6050class_or_union_sptr
6052{
6054 return is_class_or_union_type(d.get_type());
6055 return class_or_union_sptr();
6056}
6057
6058/// Test if a data member has annonymous type or not.
6059///
6060/// @param d the data member to consider.
6061///
6062/// @return the anonymous class or union type iff @p turns out to have
6063/// an anonymous type. Otherwise, returns nil.
6064const class_or_union_sptr
6066{
6067 if (is_data_member(d))
6068 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6069 if (cou->get_is_anonymous())
6070 return cou;
6071
6072 return class_or_union_sptr();
6073}
6074
6075/// Test if a data member has annonymous type or not.
6076///
6077/// @param d the data member to consider.
6078///
6079/// @return the anonymous class or union type iff @p turns out to have
6080/// an anonymous type. Otherwise, returns nil.
6081const class_or_union_sptr
6083{
6084 if (d)
6086 return class_or_union_sptr();
6087}
6088
6089/// Test if a data member has annonymous type or not.
6090///
6091/// @param d the data member to consider.
6092///
6093/// @return the anonymous class or union type iff @p turns out to have
6094/// an anonymous type. Otherwise, returns nil.
6095const class_or_union_sptr
6098
6099/// Get the @ref class_or_union type of a given anonymous data member.
6100///
6101/// @param d the anonymous data member to consider.
6102///
6103/// @return the @ref class_or_union type of the anonymous data member
6104/// @p d.
6105class_or_union_sptr
6107{
6109 return is_class_or_union_type(v->get_type());
6110 return class_or_union_sptr();
6111}
6112
6113/// Test if a given anonymous data member exists in a class or union.
6114///
6115/// @param anon_dm the anonymous data member to consider.
6116///
6117/// @param clazz the class to consider.
6118///
6119/// @return true iff @p anon_dm exists in the @clazz.
6120bool
6122 const class_or_union& clazz)
6123{
6124 if (!anon_dm.get_is_anonymous()
6125 || !is_class_or_union_type(anon_dm.get_type()))
6126 return false;
6127
6128 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6129 ABG_ASSERT(cl);
6130
6131 // Look for the presence of each data member of anon_dm in clazz.
6132 //
6133 // If one data member of anon_dm is not present in clazz, then the
6134 // data member anon_dm is considered to not exist in clazz.
6135 for (auto anon_dm_m : cl->get_non_static_data_members())
6136 {
6137 // If the data member anon_dm_m is not an anonymous data member,
6138 // it's easy to look for it.
6139 if (!is_anonymous_data_member(anon_dm_m))
6140 {
6141 if (!clazz.find_data_member(anon_dm_m->get_name()))
6142 return false;
6143 }
6144 // If anon_dm_m is itself an anonymous data member then recurse
6145 else
6146 {
6147 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6148 return false;
6149 }
6150 }
6151
6152 return true;
6153}
6154
6155/// Test if a given decl is anonymous or has a naming typedef.
6156///
6157/// @param d the decl to consider.
6158///
6159/// @return true iff @p d is anonymous or has a naming typedef.
6160bool
6162{
6163 if (d.get_is_anonymous() || d.get_naming_typedef())
6164 return true;
6165 return false;
6166}
6167
6168/// Set the offset of a data member into its containing class.
6169///
6170/// @param m the data member to consider.
6171///
6172/// @param o the offset, in bits.
6173void
6175{
6177
6178 dm_context_rel* ctxt_rel =
6179 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6180 ABG_ASSERT(ctxt_rel);
6181
6182 ctxt_rel->set_offset_in_bits(o);
6183}
6184
6185/// Get the offset of a data member.
6186///
6187/// @param m the data member to consider.
6188///
6189/// @return the offset (in bits) of @p m in its containing class.
6190uint64_t
6191get_data_member_offset(const var_decl& m)
6192{
6194 const dm_context_rel* ctxt_rel =
6195 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6196 ABG_ASSERT(ctxt_rel);
6197 return ctxt_rel->get_offset_in_bits();
6198}
6199
6200/// Get the offset of a data member.
6201///
6202/// @param m the data member to consider.
6203///
6204/// @return the offset (in bits) of @p m in its containing class.
6205uint64_t
6208
6209/// Get the offset of a data member.
6210///
6211/// @param m the data member to consider.
6212///
6213/// @return the offset (in bits) of @p m in its containing class.
6214uint64_t
6215get_data_member_offset(const decl_base_sptr d)
6216{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6217
6218/// Get the offset of the non-static data member that comes after a
6219/// given one.
6220///
6221/// If there is no data member after after the one given to this
6222/// function (maybe because the given one is the last data member of
6223/// the class type) then the function return false.
6224///
6225/// @param klass the class to consider.
6226///
6227/// @param dm the data member before the one we want to retrieve.
6228///
6229/// @param offset out parameter. This parameter is set by the
6230/// function to the offset of the data member that comes right after
6231/// the data member @p dm, iff the function returns true.
6232///
6233/// @return true iff the data member coming right after @p dm was
6234/// found.
6235bool
6237 const var_decl_sptr& dm,
6238 uint64_t& offset)
6239{
6240 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6241 if (!next_dm)
6242 return false;
6243 offset = get_data_member_offset(next_dm);
6244 return true;
6245}
6246
6247/// Get the offset of the non-static data member that comes after a
6248/// given one.
6249///
6250/// If there is no data member after after the one given to this
6251/// function (maybe because the given one is the last data member of
6252/// the class type) then the function return false.
6253///
6254/// @param klass the class to consider.
6255///
6256/// @param dm the data member before the one we want to retrieve.
6257///
6258/// @param offset out parameter. This parameter is set by the
6259/// function to the offset of the data member that comes right after
6260/// the data member @p dm, iff the function returns true.
6261///
6262/// @return true iff the data member coming right after @p dm was
6263/// found.
6264bool
6265get_next_data_member_offset(const class_or_union_sptr& klass,
6266 const var_decl_sptr& dm,
6267 uint64_t& offset)
6268{return get_next_data_member_offset(klass.get(), dm, offset);}
6269
6270/// Get the absolute offset of a data member.
6271///
6272/// If the data member is part of an anonymous data member then this
6273/// returns the absolute offset -- relative to the beginning of the
6274/// containing class of the anonymous data member.
6275///
6276/// @param m the data member to consider.
6277///
6278/// @return the aboslute offset of the data member @p m.
6279uint64_t
6281{
6283 const dm_context_rel* ctxt_rel =
6284 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6285 ABG_ASSERT(ctxt_rel);
6286
6287 const var_decl *containing_anonymous_data_member =
6288 ctxt_rel->get_anonymous_data_member();
6289
6290 uint64_t containing_anonymous_data_member_offset = 0;
6291 if (containing_anonymous_data_member)
6292 containing_anonymous_data_member_offset =
6293 get_absolute_data_member_offset(*containing_anonymous_data_member);
6294
6295 return (ctxt_rel->get_offset_in_bits()
6296 +
6297 containing_anonymous_data_member_offset);
6298}
6299
6300/// Get the absolute offset of a data member.
6301///
6302/// If the data member is part of an anonymous data member then this
6303/// returns the absolute offset -- relative to the beginning of the
6304/// containing class of the anonymous data member.
6305///
6306/// @param m the data member to consider.
6307///
6308/// @return the aboslute offset of the data member @p m.
6309uint64_t
6311{
6312 if (!m)
6313 return 0;
6315}
6316
6317/// Get the size of a given variable.
6318///
6319/// @param v the variable to consider.
6320///
6321/// @return the size of variable @p v.
6322uint64_t
6324{
6325 type_base_sptr t = v->get_type();
6326 ABG_ASSERT(t);
6327
6328 return t->get_size_in_bits();
6329}
6330
6331/// Set a flag saying if a data member is laid out.
6332///
6333/// @param m the data member to consider.
6334///
6335/// @param l true if @p m is to be considered as laid out.
6336void
6338{
6340 dm_context_rel* ctxt_rel =
6341 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6342 ctxt_rel->set_is_laid_out(l);
6343}
6344
6345/// Test whether a data member is laid out.
6346///
6347/// @param m the data member to consider.
6348///
6349/// @return true if @p m is laid out, false otherwise.
6350bool
6352{
6354 const dm_context_rel* ctxt_rel =
6355 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6356
6357 return ctxt_rel->get_is_laid_out();
6358}
6359
6360/// Test whether a data member is laid out.
6361///
6362/// @param m the data member to consider.
6363///
6364/// @return true if @p m is laid out, false otherwise.
6365bool
6368
6369/// Test whether a function_decl is a member function.
6370///
6371/// @param f the function_decl to test.
6372///
6373/// @return true if @p f is a member function, false otherwise.
6374bool
6377
6378/// Test whether a function_decl is a member function.
6379///
6380/// @param f the function_decl to test.
6381///
6382/// @return true if @p f is a member function, false otherwise.
6383bool
6386
6387/// Test whether a function_decl is a member function.
6388///
6389/// @param f the function_decl to test.
6390///
6391/// @return true if @p f is a member function, false otherwise.
6392bool
6395
6396/// Test whether a member function is a constructor.
6397///
6398/// @param f the member function to test.
6399///
6400/// @return true if @p f is a constructor, false otherwise.
6401bool
6403{
6405
6406 const method_decl* m = is_method_decl(&f);
6407 ABG_ASSERT(m);
6408
6409 const mem_fn_context_rel* ctxt =
6410 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6411
6412 return ctxt->is_constructor();
6413}
6414
6415/// Test whether a member function is a constructor.
6416///
6417/// @param f the member function to test.
6418///
6419/// @return true if @p f is a constructor, false otherwise.
6420bool
6423
6424
6425/// Setter for the is_ctor property of the member function.
6426///
6427/// @param f the member function to set.
6428///
6429/// @param f the new boolean value of the is_ctor property. Is true
6430/// if @p f is a constructor, false otherwise.
6431void
6433{
6435
6436 method_decl* m = is_method_decl(&f);
6437 ABG_ASSERT(m);
6438
6439 mem_fn_context_rel* ctxt =
6440 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6441
6442 ctxt->is_constructor(c);
6443}
6444
6445/// Setter for the is_ctor property of the member function.
6446///
6447/// @param f the member function to set.
6448///
6449/// @param f the new boolean value of the is_ctor property. Is true
6450/// if @p f is a constructor, false otherwise.
6451void
6454
6455/// Test whether a member function is a destructor.
6456///
6457/// @param f the function to test.
6458///
6459/// @return true if @p f is a destructor, false otherwise.
6460bool
6462{
6464
6465 const method_decl* m = is_method_decl(&f);
6466 ABG_ASSERT(m);
6467
6468 const mem_fn_context_rel* ctxt =
6469 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6470
6471 return ctxt->is_destructor();
6472}
6473
6474/// Test whether a member function is a destructor.
6475///
6476/// @param f the function to test.
6477///
6478/// @return true if @p f is a destructor, false otherwise.
6479bool
6482
6483/// Set the destructor-ness property of a member function.
6484///
6485/// @param f the function to set.
6486///
6487/// @param d true if @p f is a destructor, false otherwise.
6488void
6490{
6492
6493 method_decl* m = is_method_decl(&f);
6494 ABG_ASSERT(m);
6495
6496 mem_fn_context_rel* ctxt =
6497 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6498
6499 ctxt->is_destructor(d);
6500}
6501
6502/// Set the destructor-ness property of a member function.
6503///
6504/// @param f the function to set.
6505///
6506/// @param d true if @p f is a destructor, false otherwise.
6507void
6510
6511/// Test whether a member function is const.
6512///
6513/// @param f the function to test.
6514///
6515/// @return true if @p f is const, false otherwise.
6516bool
6518{
6520
6521 const method_decl* m = is_method_decl(&f);
6522 ABG_ASSERT(m);
6523
6524 const mem_fn_context_rel* ctxt =
6525 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6526
6527 return ctxt->is_const();
6528}
6529
6530/// Test whether a member function is const.
6531///
6532/// @param f the function to test.
6533///
6534/// @return true if @p f is const, false otherwise.
6535bool
6538
6539/// set the const-ness property of a member function.
6540///
6541/// @param f the function to set.
6542///
6543/// @param is_const the new value of the const-ness property of @p f
6544void
6546{
6548
6549 method_decl* m = is_method_decl(&f);
6550 ABG_ASSERT(m);
6551
6552 mem_fn_context_rel* ctxt =
6553 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6554
6555 ctxt->is_const(is_const);
6556}
6557
6558/// set the const-ness property of a member function.
6559///
6560/// @param f the function to set.
6561///
6562/// @param is_const the new value of the const-ness property of @p f
6563void
6566
6567/// Test if a virtual member function has a vtable offset set.
6568///
6569/// @param f the virtual member function to consider.
6570///
6571/// @return true iff the virtual member function has its vtable offset
6572/// set, i.e, if the vtable offset of @p is different from -1.
6573bool
6576
6577/// Get the vtable offset of a member function.
6578///
6579/// @param f the member function to consider.
6580///
6581/// @return the vtable offset of @p f. Note that a vtable offset of
6582/// value -1 means that the member function does *NOT* yet have a
6583/// vtable offset associated to it.
6584ssize_t
6586{
6588
6589 const method_decl* m =
6590 dynamic_cast<const method_decl*>(&f);
6591 ABG_ASSERT(m);
6592
6593 const mem_fn_context_rel* ctxt =
6594 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6595
6596 return ctxt->vtable_offset();
6597}
6598
6599/// Get the vtable offset of a member function.
6600///
6601/// @param f the member function to consider.
6602///
6603/// @return the vtable offset of @p f. Note that a vtable offset of
6604/// value -1 means that the member function does *NOT* yet have a
6605/// vtable offset associated to it.
6606ssize_t
6609
6610/// Set the vtable offset of a member function.
6611///
6612/// @param f the member function to consider.
6613///
6614/// @param s the new vtable offset. Please note that a vtable offset
6615/// of value -1 means that the virtual member function does not (yet)
6616/// have any vtable offset associated to it.
6617static void
6618set_member_function_vtable_offset(function_decl& f, ssize_t s)
6619{
6621
6622 method_decl* m = is_method_decl(&f);
6623 ABG_ASSERT(m);
6624
6625 mem_fn_context_rel* ctxt =
6626 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6627
6628 ctxt->vtable_offset(s);
6629}
6630
6631/// Get the vtable offset of a member function.
6632///
6633/// @param f the member function to consider.
6634///
6635/// @param s the new vtable offset. Please note that a vtable offset
6636/// of value -1 means that the virtual member function does not (yet)
6637/// have any vtable offset associated to it.
6638static void
6639set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6640{return set_member_function_vtable_offset(*f, s);}
6641
6642/// Test if a given member function is virtual.
6643///
6644/// @param mem_fn the member function to consider.
6645///
6646/// @return true iff a @p mem_fn is virtual.
6647bool
6649{
6651
6652 const method_decl* m =
6653 dynamic_cast<const method_decl*>(&f);
6654 ABG_ASSERT(m);
6655
6656 const mem_fn_context_rel* ctxt =
6657 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6658
6659 return ctxt->is_virtual();
6660}
6661
6662/// Test if a given member function is virtual.
6663///
6664/// @param mem_fn the member function to consider.
6665///
6666/// @return true iff a @p mem_fn is virtual.
6667bool
6669{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6670
6671/// Test if a given member function is virtual.
6672///
6673/// @param mem_fn the member function to consider.
6674///
6675/// @return true iff a @p mem_fn is virtual.
6676bool
6678{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6679
6680/// Set the virtual-ness of a member function.
6681///
6682/// @param f the member function to consider.
6683///
6684/// @param is_virtual set to true if the function is virtual.
6685static void
6686set_member_function_is_virtual(function_decl& f, bool is_virtual)
6687{
6689
6690 method_decl* m = is_method_decl(&f);
6691 ABG_ASSERT(m);
6692
6693 mem_fn_context_rel* ctxt =
6694 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6695
6696 ctxt->is_virtual(is_virtual);
6697}
6698
6699/// Set the virtual-ness of a member function.
6700///
6701/// @param f the member function to consider.
6702///
6703/// @param is_virtual set to true if the function is virtual.
6704static void
6705set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6706{
6707 if (fn)
6708 {
6709 set_member_function_is_virtual(*fn, is_virtual);
6711 }
6712}
6713
6714/// Set the virtual-ness of a member fcuntion
6715///
6716/// @param fn the member function to consider.
6717///
6718/// @param is_virtual whether the function is virtual.
6719///
6720/// @param voffset the virtual offset of the virtual function.
6721void
6723 bool is_virtual,
6724 ssize_t voffset)
6725{
6726 // Setting the offset must come first because the second function
6727 // does assume the voffset is set, in case of virtuality
6728 set_member_function_vtable_offset(fn, voffset);
6729 set_member_function_is_virtual(fn, is_virtual);
6730}
6731
6732/// Set the virtual-ness of a member fcuntion
6733///
6734/// @param fn the member function to consider.
6735///
6736/// @param is_virtual whether the function is virtual.
6737///
6738/// @param voffset the virtual offset of the virtual function.
6739void
6741 bool is_virtual,
6742 ssize_t voffset)
6743{
6744 if (fn)
6745 set_member_function_virtuality(*fn, is_virtual, voffset);
6746}
6747
6748/// Set the virtual-ness of a member fcuntion
6749///
6750/// @param fn the member function to consider.
6751///
6752/// @param is_virtual whether the function is virtual.
6753///
6754/// @param voffset the virtual offset of the virtual function.
6755void
6757 bool is_virtual,
6758 ssize_t voffset)
6759{
6760 set_member_function_vtable_offset(fn, voffset);
6761 set_member_function_is_virtual(fn, is_virtual);
6762}
6763
6764/// Recursively returns the the underlying type of a typedef. The
6765/// return type should not be a typedef of anything anymore.
6766///
6767///
6768/// Also recursively strip typedefs from the sub-types of the type
6769/// given in arguments.
6770///
6771/// Note that this function builds types in which typedefs are
6772/// stripped off. Usually, types are held by their scope, so their
6773/// life time is bound to the life time of their scope. But as this
6774/// function cannot really insert the built type into it's scope, it
6775/// must ensure that the newly built type stays live long enough.
6776///
6777/// So, if the newly built type has a canonical type, this function
6778/// returns the canonical type. Otherwise, this function ensure that
6779/// the newly built type has a life time that is the same as the life
6780/// time of the entire libabigail library.
6781///
6782/// @param type the type to strip the typedefs from.
6783///
6784/// @return the resulting type stripped from its typedefs, or just
6785/// return @p type if it has no typedef in any of its sub-types.
6786type_base_sptr
6787strip_typedef(const type_base_sptr type)
6788{
6789 if (!type)
6790 return type;
6791
6792 // If type is a class type then do not try to strip typedefs from it.
6793 // And if it has no canonical type (which can mean that it's a
6794 // declaration-only class), then, make sure its live for ever and
6795 // return it.
6796 if (class_decl_sptr cl = is_class_type(type))
6797 {
6798 if (!cl->get_canonical_type())
6799 keep_type_alive(type);
6800 return type;
6801 }
6802
6803 const environment& env = type->get_environment();
6804 type_base_sptr t = type;
6805
6806 if (const typedef_decl_sptr ty = is_typedef(t))
6807 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6808 else if (const reference_type_def_sptr ty = is_reference_type(t))
6809 {
6810 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6811 env));
6812 ABG_ASSERT(p);
6813 t.reset(new reference_type_def(p,
6814 ty->is_lvalue(),
6815 ty->get_size_in_bits(),
6816 ty->get_alignment_in_bits(),
6817 ty->get_location()));
6818 }
6819 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6820 {
6821 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6822 env));
6823 ABG_ASSERT(p);
6824 t.reset(new pointer_type_def(p,
6825 ty->get_size_in_bits(),
6826 ty->get_alignment_in_bits(),
6827 ty->get_location()));
6828 }
6829 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6830 {
6831 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6832 env));
6833 ABG_ASSERT(p);
6834 t.reset(new qualified_type_def(p,
6835 ty->get_cv_quals(),
6836 ty->get_location()));
6837 }
6838 else if (const array_type_def_sptr ty = is_array_type(t))
6839 {
6840 type_base_sptr p = strip_typedef(ty->get_element_type());
6841 ABG_ASSERT(p);
6842 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6843 }
6844 else if (const method_type_sptr ty = is_method_type(t))
6845 {
6847 for (function_decl::parameters::const_iterator i =
6848 ty->get_parameters().begin();
6849 i != ty->get_parameters().end();
6850 ++i)
6851 {
6853 type_base_sptr typ = strip_typedef(p->get_type());
6854 ABG_ASSERT(typ);
6856 (new function_decl::parameter(typ,
6857 p->get_index(),
6858 p->get_name(),
6859 p->get_location(),
6860 p->get_variadic_marker(),
6861 p->get_is_artificial()));
6862 parm.push_back(stripped);
6863 }
6864 type_base_sptr p = strip_typedef(ty->get_return_type());
6865 ABG_ASSERT(!!p == !!ty->get_return_type());
6866 t.reset(new method_type(p, ty->get_class_type(),
6867 parm, ty->get_is_const(),
6868 ty->get_size_in_bits(),
6869 ty->get_alignment_in_bits()));
6870 }
6871 else if (const function_type_sptr ty = is_function_type(t))
6872 {
6874 for (function_decl::parameters::const_iterator i =
6875 ty->get_parameters().begin();
6876 i != ty->get_parameters().end();
6877 ++i)
6878 {
6880 type_base_sptr typ = strip_typedef(p->get_type());
6881 ABG_ASSERT(typ);
6883 (new function_decl::parameter(typ,
6884 p->get_index(),
6885 p->get_name(),
6886 p->get_location(),
6887 p->get_variadic_marker(),
6888 p->get_is_artificial()));
6889 parm.push_back(stripped);
6890 }
6891 type_base_sptr p = strip_typedef(ty->get_return_type());
6892 ABG_ASSERT(!!p == !!ty->get_return_type());
6893 t.reset(new function_type(p, parm,
6894 ty->get_size_in_bits(),
6895 ty->get_alignment_in_bits()));
6896 }
6897
6898 if (!t->get_translation_unit())
6899 t->set_translation_unit(type->get_translation_unit());
6900
6901 if (!(type->get_canonical_type() && canonicalize(t)))
6902 keep_type_alive(t);
6903
6904 return t->get_canonical_type() ? t->get_canonical_type() : t;
6905}
6906
6907/// Strip qualification from a qualified type, when it makes sense.
6908///
6909/// DWARF constructs "const reference". This is redundant because a
6910/// reference is always const. It also constructs the useless "const
6911/// void" type. The issue is these redundant types then leak into the
6912/// IR and make for bad diagnostics.
6913///
6914/// This function thus strips the const qualifier from the type in
6915/// that case. It might contain code to strip other cases like this
6916/// in the future.
6917///
6918/// @param t the type to strip const qualification from.
6919///
6920/// @return the stripped type or just return @p t.
6921decl_base_sptr
6922strip_useless_const_qualification(const qualified_type_def_sptr t)
6923{
6924 if (!t)
6925 return t;
6926
6927 decl_base_sptr result = t;
6928 type_base_sptr u = t->get_underlying_type();
6929 const environment& env = t->get_environment();
6930
6931 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6932 && (is_reference_type(u)))
6933 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6934 && env.is_void_type(u))
6935 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6936 // Let's strip the const qualifier because a reference is always
6937 // 'const' and a const void doesn't make sense. They will just
6938 // lead to spurious changes later down the pipeline, that we'll
6939 // have to deal with by doing painful and error-prone editing of
6940 // the diff IR. Dropping that useless and inconsistent artefact
6941 // right here seems to be a good way to go.
6942 result = is_decl(u);
6943
6944 return result;
6945}
6946
6947/// Merge redundant qualifiers from a tree of qualified types.
6948///
6949/// Suppose a tree of qualified types leads to:
6950///
6951/// const virtual const restrict const int;
6952///
6953/// Suppose the IR tree of qualified types ressembles (with C meaning
6954/// const, V meaning virtual and R meaning restrict):
6955///
6956/// [C|V]-->[C|R] -->[C] --> [int].
6957///
6958/// This function walks the IR and remove the redundant CV qualifiers
6959/// so the IR becomes:
6960///
6961/// [C|V] --> [R] --> [] -->[int].
6962///
6963/// Note that the empty qualified type (noted []) represents a
6964/// qualified type with no qualifier. It's rare, but it can exist.
6965/// I've put it here just for the sake of example.
6966///
6967/// The resulting IR thus represents the (merged) type:
6968///
6969/// const virtual restrict int.
6970///
6971/// This function is a sub-routine of the overload @ref
6972/// strip_useless_const_qualification which doesn't return any value.
6973///
6974/// @param t the qualified type to consider.
6975///
6976/// @param redundant_quals the (redundant) qualifiers to be removed
6977/// from the qualifiers of the underlying types of @p t.
6978///
6979/// @return the underlying type of @p t which might have had its
6980/// redundant qualifiers removed.
6981static qualified_type_def_sptr
6982strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6983 qualified_type_def::CV redundant_quals)
6984{
6985 if (!t)
6986 return t;
6987
6988 // We must NOT edit canonicalized types.
6989 ABG_ASSERT(!t->get_canonical_type());
6990
6991 qualified_type_def_sptr underlying_qualified_type =
6992 is_qualified_type(t->get_underlying_type());
6993
6994 // Let's build 'currated qualifiers' that are the qualifiers of the
6995 // current type from which redundant qualifiers are removed.
6996 qualified_type_def::CV currated_quals = t->get_cv_quals();
6997
6998 // Remove the redundant qualifiers from these currated qualifiers
6999 currated_quals &= ~redundant_quals;
7000 t->set_cv_quals(currated_quals);
7001
7002 // The redundant qualifiers, moving forward, is now the union of the
7003 // previous set of redundant qualifiers and the currated qualifiers.
7004 redundant_quals |= currated_quals;
7005
7006 qualified_type_def_sptr result = t;
7007 if (underlying_qualified_type)
7008 // Now remove the redundant qualifiers from the qualified types
7009 // potentially carried by the underlying type.
7010 result =
7011 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
7012 redundant_quals);
7013
7014 return result;
7015}
7016
7017/// Merge redundant qualifiers from a tree of qualified types.
7018///
7019/// Suppose a tree of qualified types leads to:
7020///
7021/// const virtual const restrict const int;
7022///
7023/// Suppose the IR tree of qualified types ressembles (with C meaning
7024/// const, V meaning virtual and R meaning restrict):
7025///
7026/// [C|V]-->[C|R] -->[C] --> [int].
7027///
7028/// This function walks the IR and remove the redundant CV qualifiers
7029/// so the IR becomes:
7030///
7031/// [C|V] --> [R] --> [] -->[int].
7032///
7033/// Note that the empty qualified type (noted []) represents a
7034/// qualified type with no qualifier. It's rare, but it can exist.
7035/// I've put it here just for the sake of example.
7036///
7037/// The resulting IR thus represents the (merged) type:
7038///
7039/// const virtual restrict int.
7040///
7041/// @param t the qualified type to consider. The IR below the
7042/// argument to this parameter will be edited to remove redundant
7043/// qualifiers where applicable.
7044void
7045strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
7046{
7047 if (!t)
7048 return;
7049
7050 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
7051 strip_redundant_quals_from_underyling_types(t, redundant_quals);
7052}
7053
7054/// Return the leaf underlying type node of a @ref typedef_decl node.
7055///
7056/// If the underlying type of a @ref typedef_decl node is itself a
7057/// @ref typedef_decl node, then recursively look at the underlying
7058/// type nodes to get the first one that is not a a @ref typedef_decl
7059/// node. This is what a leaf underlying type node means.
7060///
7061/// Otherwise, if the underlying type node of @ref typedef_decl is
7062/// *NOT* a @ref typedef_decl node, then just return the underlying
7063/// type node.
7064///
7065/// And if the type node considered is not a @ref typedef_decl node,
7066/// then just return it.
7067///
7068/// @return the leaf underlying type node of a @p type.
7069type_base_sptr
7070peel_typedef_type(const type_base_sptr& type)
7071{
7072 typedef_decl_sptr t = is_typedef(type);
7073 if (!t)
7074 return type;
7075
7076 if (is_typedef(t->get_underlying_type()))
7077 return peel_typedef_type(t->get_underlying_type());
7078 return t->get_underlying_type();
7079}
7080
7081/// Return the leaf underlying type node of a @ref typedef_decl node.
7082///
7083/// If the underlying type of a @ref typedef_decl node is itself a
7084/// @ref typedef_decl node, then recursively look at the underlying
7085/// type nodes to get the first one that is not a a @ref typedef_decl
7086/// node. This is what a leaf underlying type node means.
7087///
7088/// Otherwise, if the underlying type node of @ref typedef_decl is
7089/// *NOT* a @ref typedef_decl node, then just return the underlying
7090/// type node.
7091///
7092/// And if the type node considered is not a @ref typedef_decl node,
7093/// then just return it.
7094///
7095/// @return the leaf underlying type node of a @p type.
7096const type_base*
7098{
7099 const typedef_decl* t = is_typedef(type);
7100 if (!t)
7101 return type;
7102
7103 return peel_typedef_type(t->get_underlying_type()).get();
7104}
7105
7106/// Return the leaf pointed-to type node of a @ref pointer_type_def
7107/// node.
7108///
7109/// If the pointed-to type of a @ref pointer_type_def node is itself a
7110/// @ref pointer_type_def node, then recursively look at the
7111/// pointed-to type nodes to get the first one that is not a a @ref
7112/// pointer_type_def node. This is what a leaf pointed-to type node
7113/// means.
7114///
7115/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7116/// *NOT* a @ref pointer_type_def node, then just return the
7117/// pointed-to type node.
7118///
7119/// And if the type node considered is not a @ref pointer_type_def
7120/// node, then just return it.
7121///
7122/// @return the leaf pointed-to type node of a @p type.
7123type_base_sptr
7124peel_pointer_type(const type_base_sptr& type)
7125{
7127 if (!t)
7128 return type;
7129
7130 if (is_pointer_type(t->get_pointed_to_type()))
7131 return peel_pointer_type(t->get_pointed_to_type());
7132 return t->get_pointed_to_type();
7133}
7134
7135/// Return the leaf pointed-to type node of a @ref pointer_type_def
7136/// node.
7137///
7138/// If the pointed-to type of a @ref pointer_type_def node is itself a
7139/// @ref pointer_type_def node, then recursively look at the
7140/// pointed-to type nodes to get the first one that is not a a @ref
7141/// pointer_type_def node. This is what a leaf pointed-to type node
7142/// means.
7143///
7144/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7145/// *NOT* a @ref pointer_type_def node, then just return the
7146/// pointed-to type node.
7147///
7148/// And if the type node considered is not a @ref pointer_type_def
7149/// node, then just return it.
7150///
7151/// @return the leaf pointed-to type node of a @p type.
7152const type_base*
7154{
7155 const pointer_type_def* t = is_pointer_type(type);
7156 if (!t)
7157 return type;
7158
7159 return peel_pointer_type(t->get_pointed_to_type()).get();
7160}
7161
7162/// Return the leaf pointed-to type node of a @ref reference_type_def
7163/// node.
7164///
7165/// If the pointed-to type of a @ref reference_type_def node is itself
7166/// a @ref reference_type_def node, then recursively look at the
7167/// pointed-to type nodes to get the first one that is not a a @ref
7168/// reference_type_def node. This is what a leaf pointed-to type node
7169/// means.
7170///
7171/// Otherwise, if the pointed-to type node of @ref reference_type_def
7172/// is *NOT* a @ref reference_type_def node, then just return the
7173/// pointed-to type node.
7174///
7175/// And if the type node considered is not a @ref reference_type_def
7176/// node, then just return it.
7177///
7178/// @return the leaf pointed-to type node of a @p type.
7179type_base_sptr
7180peel_reference_type(const type_base_sptr& type)
7181{
7183 if (!t)
7184 return type;
7185
7186 if (is_reference_type(t->get_pointed_to_type()))
7187 return peel_reference_type(t->get_pointed_to_type());
7188 return t->get_pointed_to_type();
7189}
7190
7191/// Return the leaf pointed-to type node of a @ref reference_type_def
7192/// node.
7193///
7194/// If the pointed-to type of a @ref reference_type_def node is itself
7195/// a @ref reference_type_def node, then recursively look at the
7196/// pointed-to type nodes to get the first one that is not a a @ref
7197/// reference_type_def node. This is what a leaf pointed-to type node
7198/// means.
7199///
7200/// Otherwise, if the pointed-to type node of @ref reference_type_def
7201/// is *NOT* a @ref reference_type_def node, then just return the
7202/// pointed-to type node.
7203///
7204/// And if the type node considered is not a @ref reference_type_def
7205/// node, then just return it.
7206///
7207/// @return the leaf pointed-to type node of a @p type.
7208const type_base*
7210{
7211 const reference_type_def* t = is_reference_type(type);
7212 if (!t)
7213 return type;
7214
7215 return peel_reference_type(t->get_pointed_to_type()).get();
7216}
7217
7218/// Return the leaf element type of an array.
7219///
7220/// If the element type is itself an array, then recursively return
7221/// the element type of that array itself.
7222///
7223/// @param type the array type to consider. If this is not an array
7224/// type, this type is returned by the function.
7225///
7226/// @return the leaf element type of the array @p type, or, if it's
7227/// not an array type, then just return @p.
7228const type_base_sptr
7229peel_array_type(const type_base_sptr& type)
7230{
7231 const array_type_def_sptr t = is_array_type(type);
7232 if (!t)
7233 return type;
7234
7235 return peel_array_type(t->get_element_type());
7236}
7237
7238/// Return the leaf element type of an array.
7239///
7240/// If the element type is itself an array, then recursively return
7241/// the element type of that array itself.
7242///
7243/// @param type the array type to consider. If this is not an array
7244/// type, this type is returned by the function.
7245///
7246/// @return the leaf element type of the array @p type, or, if it's
7247/// not an array type, then just return @p.
7248const type_base*
7250{
7251 const array_type_def* t = is_array_type(type);
7252 if (!t)
7253 return type;
7254
7255 return peel_array_type(t->get_element_type()).get();
7256}
7257
7258/// Return the leaf underlying type of a qualified type.
7259///
7260/// If the underlying type is itself a qualified type, then
7261/// recursively return the first underlying type of that qualified
7262/// type to return the first underlying type that is not a qualified type.
7263///
7264/// If the underlying type is NOT a qualified type, then just return
7265/// that underlying type.
7266///
7267/// @param type the qualified type to consider.
7268///
7269/// @return the leaf underlying type.
7270const type_base*
7272{
7273 const qualified_type_def* t = is_qualified_type(type);
7274 if (!t)
7275 return type;
7276
7277 return peel_qualified_type(t->get_underlying_type().get());
7278}
7279
7280/// Return the leaf underlying type of a qualified type.
7281///
7282/// If the underlying type is itself a qualified type, then
7283/// recursively return the first underlying type of that qualified
7284/// type to return the first underlying type that is not a qualified type.
7285///
7286/// If the underlying type is NOT a qualified type, then just return
7287/// that underlying type.
7288///
7289/// @param type the qualified type to consider.
7290///
7291/// @return the leaf underlying type.
7292const type_base_sptr
7293peel_qualified_type(const type_base_sptr& type)
7294{
7295 const qualified_type_def_sptr t = is_qualified_type(type);
7296 if (!t)
7297 return type;
7298
7299 return peel_qualified_type(t->get_underlying_type());
7300}
7301
7302/// Test if a given qualified type is const.
7303///
7304/// @pram t the qualified type to consider.
7305///
7306/// @return true iff @p t is a const qualified type.
7307bool
7308is_const_qualified_type(const qualified_type_def_sptr& t)
7309{
7310 if (!t)
7311 return false;
7312
7313 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
7314 return true;
7315
7316 return false;
7317}
7318
7319/// Test if a given type is const-qualified.
7320///
7321/// @pram t the type to consider.
7322///
7323/// @return true iff @p t is a const qualified type.
7324bool
7325is_const_qualified_type(const type_base_sptr& t)
7326{
7327 qualified_type_def_sptr q = is_qualified_type(t);
7328 if (!q)
7329 return false;
7330 return is_const_qualified_type(q);
7331}
7332
7333/// If a qualified type is const, then return its underlying type.
7334///
7335/// @param q the qualified type to consider.
7336///
7337/// @return the underlying type of @p q if it's a const-qualified
7338/// type, otherwise, return @p q itself.
7339type_base_sptr
7340peel_const_qualified_type(const qualified_type_def_sptr& q)
7341{
7342 if (!q)
7343 return q;
7344
7346 return q->get_underlying_type();
7347
7348 return q;
7349}
7350
7351/// Return the leaf underlying type of a qualified or typedef type.
7352///
7353/// If the underlying type is itself a qualified or typedef type, then
7354/// recursively return the first underlying type of that qualified or
7355/// typedef type to return the first underlying type that is not a
7356/// qualified or typedef type.
7357///
7358/// If the underlying type is NOT a qualified nor a typedef type, then
7359/// just return that underlying type.
7360///
7361/// @param type the qualified or typedef type to consider.
7362///
7363/// @return the leaf underlying type.
7364type_base*
7366{
7367 while (is_typedef(type) || is_qualified_type(type))
7368 {
7369 if (const typedef_decl* t = is_typedef(type))
7370 type = peel_typedef_type(t);
7371
7372 if (const qualified_type_def* t = is_qualified_type(type))
7373 type = peel_qualified_type(t);
7374 }
7375
7376 return const_cast<type_base*>(type);
7377}
7378
7379/// Return the leaf underlying type of a qualified or typedef type.
7380///
7381/// If the underlying type is itself a qualified or typedef type, then
7382/// recursively return the first underlying type of that qualified or
7383/// typedef type to return the first underlying type that is not a
7384/// qualified or typedef type.
7385///
7386/// If the underlying type is NOT a qualified nor a typedef type, then
7387/// just return that underlying type.
7388///
7389/// @param type the qualified or typedef type to consider.
7390///
7391/// @return the leaf underlying type.
7392type_base_sptr
7393peel_qualified_or_typedef_type(const type_base_sptr &t)
7394{
7395 type_base_sptr type = t;
7396 while (is_typedef(type) || is_qualified_type(type))
7397 {
7398 if (typedef_decl_sptr t = is_typedef(type))
7399 type = peel_typedef_type(t);
7400
7401 if (qualified_type_def_sptr t = is_qualified_type(type))
7402 type = peel_qualified_type(t);
7403 }
7404
7405 return type;
7406}
7407
7408/// Return the leaf underlying or pointed-to type node of a @ref
7409/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7410/// or @ref array_type_def node.
7411///
7412/// @param type the type to peel.
7413///
7414/// @return the leaf underlying or pointed-to type node of @p type.
7415type_base_sptr
7417{
7418 type_base_sptr typ = type;
7419 while (is_typedef(typ)
7420 || is_pointer_type(typ)
7421 || is_reference_type(typ)
7422 || is_array_type(typ))
7423 {
7424 if (typedef_decl_sptr t = is_typedef(typ))
7425 typ = peel_typedef_type(t);
7426
7428 typ = peel_pointer_type(t);
7429
7431 typ = peel_reference_type(t);
7432
7433 if (const array_type_def_sptr t = is_array_type(typ))
7434 typ = peel_array_type(t);
7435 }
7436
7437 return typ;
7438}
7439
7440/// Return the leaf underlying or pointed-to type node of a @ref
7441/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7442/// node.
7443///
7444/// @param type the type to peel.
7445///
7446/// @return the leaf underlying or pointed-to type node of @p type.
7447type_base*
7449{
7450 while (is_typedef(type)
7451 || is_pointer_type(type)
7452 || is_reference_type(type)
7453 || is_array_type(type))
7454 {
7455 if (const typedef_decl* t = is_typedef(type))
7456 type = peel_typedef_type(t);
7457
7458 if (const pointer_type_def* t = is_pointer_type(type))
7459 type = peel_pointer_type(t);
7460
7461 if (const reference_type_def* t = is_reference_type(type))
7462 type = peel_reference_type(t);
7463
7464 if (const array_type_def* t = is_array_type(type))
7465 type = peel_array_type(t);
7466 }
7467
7468 return const_cast<type_base*>(type);
7469}
7470
7471/// Return the leaf underlying or pointed-to type node of a @ref
7472/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7473/// node.
7474///
7475/// @param type the type to peel.
7476///
7477/// @return the leaf underlying or pointed-to type node of @p type.
7478type_base*
7480 bool peel_qual_type)
7481{
7482 while (is_typedef(type)
7483 || is_pointer_type(type)
7484 || is_reference_type(type)
7485 || is_array_type(type)
7486 || (peel_qual_type && is_qualified_type(type)))
7487 {
7488 if (const typedef_decl* t = is_typedef(type))
7489 type = peel_typedef_type(t);
7490
7491 if (const pointer_type_def* t = is_pointer_type(type))
7492 type = peel_pointer_type(t);
7493
7494 if (const reference_type_def* t = is_reference_type(type))
7495 type = peel_reference_type(t);
7496
7497 if (const array_type_def* t = is_array_type(type))
7498 type = peel_array_type(t);
7499
7500 if (peel_qual_type)
7501 if (const qualified_type_def* t = is_qualified_type(type))
7502 type = peel_qualified_type(t);
7503 }
7504
7505 return const_cast<type_base*>(type);
7506}
7507
7508/// Return the leaf underlying or pointed-to type node of a, @ref
7509/// pointer_type_def, @ref reference_type_def or @ref
7510/// qualified_type_def type node.
7511///
7512/// @param type the type to peel.
7513///
7514/// @param peel_qualified_type if true, also peel qualified types.
7515///
7516/// @return the leaf underlying or pointed-to type node of @p type.
7517type_base*
7519 bool peel_qual_type)
7520{
7521 while (is_pointer_type(type)
7522 || is_reference_type(type)
7523 || is_array_type(type)
7524 || (peel_qual_type && is_qualified_type(type)))
7525 {
7526 if (const pointer_type_def* t = is_pointer_type(type))
7527 type = peel_pointer_type(t);
7528
7529 if (const reference_type_def* t = is_reference_type(type))
7530 type = peel_reference_type(t);
7531
7532 if (const array_type_def* t = is_array_type(type))
7533 type = peel_array_type(t);
7534
7535 if (peel_qual_type)
7536 if (const qualified_type_def* t = is_qualified_type(type))
7537 type = peel_qualified_type(t);
7538 }
7539
7540 return const_cast<type_base*>(type);
7541}
7542
7543/// Clone an array type.
7544///
7545/// Note that the element type of the new array is shared witht the
7546/// old one.
7547///
7548/// @param array the array type to clone.
7549///
7550/// @return a newly built array type. Note that it needs to be added
7551/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7552/// bound to the one of that scope. Otherwise, its lifetime is bound
7553/// to the lifetime of its containing shared pointer.
7556{
7558
7560 array->get_subranges().begin();
7561 i != array->get_subranges().end();
7562 ++i)
7563 {
7565 (new array_type_def::subrange_type(array->get_environment(),
7566 (*i)->get_name(),
7567 (*i)->get_lower_bound(),
7568 (*i)->get_upper_bound(),
7569 (*i)->get_underlying_type(),
7570 (*i)->get_location(),
7571 (*i)->get_language()));
7572 subrange->is_non_finite((*i)->is_non_finite());
7573 if (scope_decl *scope = (*i)->get_scope())
7574 add_decl_to_scope(subrange, scope);
7575 subranges.push_back(subrange);
7576 }
7577
7578 array_type_def_sptr result
7579 (new array_type_def(array->get_element_type(),
7580 subranges, array->get_location()));
7581
7582 return result;
7583}
7584
7585/// Clone a typedef type.
7586///
7587/// Note that the underlying type of the newly constructed typedef is
7588/// shared with the old one.
7589///
7590/// @param t the typedef to clone.
7591///
7592/// @return the newly constructed typedef. Note that it needs to be
7593/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7594/// to be bound to the one of that scope. Otherwise, its lifetime is
7595/// bound to the lifetime of its containing shared pointer.
7598{
7599 if (!t)
7600 return t;
7601
7602 typedef_decl_sptr result
7603 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7604 t->get_location(), t->get_linkage_name(),
7605 t->get_visibility()));
7606 return result;
7607}
7608
7609/// Clone a qualifiend type.
7610///
7611/// Note that underlying type of the newly constructed qualified type
7612/// is shared with the old one.
7613///
7614/// @param t the qualified type to clone.
7615///
7616/// @return the newly constructed qualified type. Note that it needs
7617/// to be added to a scope (e.g, using add_decl_to_scope) for its
7618/// lifetime to be bound to the one of that scope. Otherwise, its
7619/// lifetime is bound to the lifetime of its containing shared
7620/// pointer.
7621qualified_type_def_sptr
7622clone_qualified_type(const qualified_type_def_sptr& t)
7623{
7624 if (!t)
7625 return t;
7626
7627 qualified_type_def_sptr result
7628 (new qualified_type_def(t->get_underlying_type(),
7629 t->get_cv_quals(), t->get_location()));
7630
7631 return result;
7632}
7633
7634/// Clone a typedef, an array or a qualified tree.
7635///
7636/// @param type the typedef, array or qualified tree to clone. any
7637/// order.
7638///
7639/// @return the cloned type, or NULL if @type was neither a typedef,
7640/// array nor a qualified type.
7641static type_base_sptr
7642clone_typedef_array_qualified_type(type_base_sptr type)
7643{
7644 if (!type)
7645 return type;
7646
7647 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7648 type_base_sptr result;
7649
7650 if (typedef_decl_sptr t = is_typedef(type))
7651 result = clone_typedef(is_typedef(t));
7652 else if (qualified_type_def_sptr t = is_qualified_type(type))
7653 result = clone_qualified_type(t);
7654 else if (array_type_def_sptr t = is_array_type(type))
7655 result = clone_array(t);
7656 else
7657 return type_base_sptr();
7658
7659 if (scope)
7660 add_decl_to_scope(is_decl(result), scope);
7661
7662 return result;
7663}
7664
7665/// Clone a type tree made of an array or a typedef of array.
7666///
7667/// Note that this can be a tree which root node is a typedef an which
7668/// sub-tree can be any arbitrary combination of typedef, qualified
7669/// type and arrays.
7670///
7671/// @param t the array or typedef of qualified array to consider.
7672///
7673/// @return a clone of @p t.
7674type_base_sptr
7675clone_array_tree(const type_base_sptr t)
7676{
7678
7679 scope_decl* scope = is_decl(t)->get_scope();
7680 type_base_sptr result = clone_typedef_array_qualified_type(t);
7681 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7682
7683 type_base_sptr subtree;
7684 if (typedef_decl_sptr type = is_typedef(result))
7685 {
7686 type_base_sptr s =
7687 clone_typedef_array_qualified_type(type->get_underlying_type());
7688 if (s)
7689 {
7690 subtree = s;
7691 type->set_underlying_type(subtree);
7692 }
7693 }
7694 else if (array_type_def_sptr type = is_array_type(result))
7695 {
7696 type_base_sptr s =
7697 clone_typedef_array_qualified_type(type->get_element_type());
7698 if (s)
7699 {
7700 subtree = s;
7701 type->set_element_type(subtree);
7702 }
7703 }
7704 add_decl_to_scope(is_decl(subtree), scope);
7705
7706 for (;;)
7707 {
7708 if (typedef_decl_sptr t = is_typedef(subtree))
7709 {
7710 type_base_sptr s =
7711 clone_typedef_array_qualified_type(t->get_underlying_type());
7712 if (s)
7713 {
7714 scope_decl* scope =
7715 is_decl(t->get_underlying_type())->get_scope();
7716 ABG_ASSERT(scope);
7717 add_decl_to_scope(is_decl(s), scope);
7718 t->set_underlying_type (s);
7719 subtree = s;
7720 }
7721 else
7722 break;
7723 }
7724 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7725 {
7726 type_base_sptr s =
7727 clone_typedef_array_qualified_type(t->get_underlying_type());
7728 if (s)
7729 {
7730 scope_decl* scope =
7731 is_decl(t->get_underlying_type())->get_scope();
7732 ABG_ASSERT(scope);
7733 add_decl_to_scope(is_decl(s), scope);
7734 t->set_underlying_type(s);
7735 subtree = s;
7736 }
7737 else
7738 break;
7739 }
7740 else if (array_type_def_sptr t = is_array_type(subtree))
7741 {
7742 type_base_sptr e = t->get_element_type();
7743 if (is_typedef(e) || is_qualified_type(e))
7744 {
7745 type_base_sptr s =
7746 clone_typedef_array_qualified_type(e);
7747 if (s)
7748 {
7749 scope_decl* scope = is_decl(e)->get_scope();
7750 ABG_ASSERT(scope);
7751 add_decl_to_scope(is_decl(s), scope);
7752 t->set_element_type(s);
7753 }
7754 else
7755 break;
7756 }
7757 break;
7758 }
7759 else
7760 break;
7761 }
7762 return result;
7763}
7764
7765/// Update the qualified name of a given sub-tree.
7766///
7767/// @param d the sub-tree for which to update the qualified name.
7768static void
7769update_qualified_name(decl_base * d)
7770{
7771 ::qualified_name_setter setter;
7772 d->traverse(setter);
7773}
7774
7775/// Update the qualified name of a given sub-tree.
7776///
7777/// @param d the sub-tree for which to update the qualified name.
7778static void
7779update_qualified_name(decl_base_sptr d)
7780{return update_qualified_name(d.get());}
7781
7782// <scope_decl stuff>
7783
7784/// Hash a type by returning the pointer value of its canonical type.
7785///
7786/// @param l the type to hash.
7787///
7788/// @return the the pointer value of the canonical type of @p l.
7789size_t
7790canonical_type_hash::operator()(const type_base_sptr& l) const
7791{return operator()(l.get());}
7792
7793/// Hash a (canonical) type by returning its pointer value
7794///
7795/// @param l the canonical type to hash.
7796///
7797/// @return the pointer value of the canonical type of @p l.
7798size_t
7800{return reinterpret_cast<size_t>(l);}
7801
7802struct scope_decl::priv
7803{
7804 declarations members_;
7805 declarations sorted_members_;
7806 type_base_sptrs_type member_types_;
7807 type_base_sptrs_type sorted_member_types_;
7808 scopes member_scopes_;
7809 canonical_type_sptr_set_type canonical_types_;
7810 type_base_sptrs_type sorted_canonical_types_;
7811 bool clear_sorted_member_types_cache_ = false;
7812}; // end struct scope_decl::priv
7813
7814/// Constructor of the @ref scope_decl type.
7815///
7816/// @param the environment to use for the new instance.
7817///
7818/// @param the name of the scope decl.
7819///
7820/// @param locus the source location where the scope_decl is defined.
7821///
7822/// @param vis the visibility of the declaration.
7823scope_decl::scope_decl(const environment& env,
7824 const string& name,
7825 const location& locus,
7826 visibility vis)
7827 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7828 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7829 priv_(new priv)
7830{}
7831
7832/// Constructor of the @ref scope_decl type.
7833///
7834/// @param the environment to use for the new instance.
7835///
7836/// @param l the source location where the scope_decl is defined.
7837///
7838/// @param vis the visibility of the declaration.
7839scope_decl::scope_decl(const environment& env, location& l)
7840 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7841 decl_base(env, "", l),
7842 priv_(new priv)
7843{}
7844
7845/// @eturn the set of canonical types of the the current scope.
7848{return priv_->canonical_types_;}
7849
7850/// @eturn the set of canonical types of the the current scope.
7853{return const_cast<scope_decl*>(this)->get_canonical_types();}
7854
7855/// Return a vector of sorted canonical types of the current scope.
7856///
7857/// The types are sorted "almost topologically". That means, they are
7858/// sorted using the lexicographic order of the string representing
7859/// the location their definition point. If a type doesn't have a
7860/// location, then its pretty representation is used.
7861///
7862/// @return a vector of sorted canonical types of the current scope.
7865{
7866 if (priv_->sorted_canonical_types_.empty())
7867 {
7868 for (canonical_type_sptr_set_type::const_iterator e =
7869 get_canonical_types().begin();
7870 e != get_canonical_types().end();
7871 ++e)
7872 priv_->sorted_canonical_types_.push_back(*e);
7873
7874 type_topo_comp comp;
7875 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7876 priv_->sorted_canonical_types_.end(),
7877 comp);
7878 }
7879 return priv_->sorted_canonical_types_;
7880}
7881
7882/// Getter for the member declarations carried by the current @ref
7883/// scope_decl.
7884///
7885/// @return the member declarations carried by the current @ref
7886/// scope_decl.
7889{return priv_->members_;}
7890
7891/// Getter for the member declarations carried by the current @ref
7892/// scope_decl.
7893///
7894/// @return the member declarations carried by the current @ref
7895/// scope_decl.
7898{return priv_->members_;}
7899
7900/// Getter for the sorted member declarations carried by the current
7901/// @ref scope_decl.
7902///
7903/// @return the sorted member declarations carried by the current @ref
7904/// scope_decl. The declarations are sorted topologically.
7907{
7908 decl_topo_comp comp;
7909 if (priv_->sorted_members_.empty())
7910 {
7911 for (declarations::const_iterator i = get_member_decls().begin();
7912 i != get_member_decls().end();
7913 ++i)
7914 priv_->sorted_members_.push_back(*i);
7915
7916 std::stable_sort(priv_->sorted_members_.begin(),
7917 priv_->sorted_members_.end(),
7918 comp);
7919 }
7920 return priv_->sorted_members_;
7921}
7922
7923/// Getter for the number of anonymous classes contained in this
7924/// scope.
7925///
7926/// @return the number of anonymous classes contained in this scope.
7927size_t
7929{
7930 int result = 0;
7931 for (declarations::const_iterator it = get_member_decls().begin();
7932 it != get_member_decls().end();
7933 ++it)
7934 if (class_decl_sptr t = is_class_type(*it))
7935 if (t->get_is_anonymous())
7936 ++result;
7937
7938 return result;
7939}
7940
7941/// Getter for the number of anonymous unions contained in this
7942/// scope.
7943///
7944/// @return the number of anonymous unions contained in this scope.
7945size_t
7947{
7948 int result = 0;
7949 for (declarations::const_iterator it = get_member_decls().begin();
7950 it != get_member_decls().end();
7951 ++it)
7952 if (union_decl_sptr t = is_union_type(*it))
7953 if (t->get_is_anonymous())
7954 ++result;
7955
7956 return result;
7957}
7958
7959/// Getter for the number of anonymous enums contained in this
7960/// scope.
7961///
7962/// @return the number of anonymous enums contained in this scope.
7963size_t
7965{
7966 int result = 0;
7967 for (declarations::const_iterator it = get_member_decls().begin();
7968 it != get_member_decls().end();
7969 ++it)
7970 if (enum_type_decl_sptr t = is_enum_type(*it))
7971 if (t->get_is_anonymous())
7972 ++result;
7973
7974 return result;
7975}
7976
7977/// Getter for the scopes carried by the current scope.
7978///
7979/// @return the scopes carried by the current scope.
7982{return priv_->member_scopes_;}
7983
7984/// Getter for the scopes carried by the current scope.
7985///
7986/// @return the scopes carried by the current scope.
7987const scope_decl::scopes&
7989{return priv_->member_scopes_;}
7990
7991/// Test if the current scope is empty.
7992///
7993/// @return true iff the current scope is empty.
7994bool
7996{
7997 return (get_member_decls().empty()
7998 && get_canonical_types().empty());
7999}
8000
8001/// Set the translation unit of a decl
8002///
8003/// It also perform some IR integrity checks.
8004///
8005/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
8006///
8007/// @param decl the decl to set the translation unit for.
8008///
8009/// @param tu the translation unit to set.
8010static void
8011maybe_set_translation_unit(const decl_base_sptr& decl,
8012 translation_unit* tu)
8013{
8014 ABG_ASSERT(tu);
8015
8016 if (translation_unit* existing_tu = decl->get_translation_unit())
8017 // The decl already belongs to a translation unit.
8018 // Either:
8019 //
8020 // 1/ it's a unique type, in which case we should not add it to
8021 // any translation unique since unique types are "logically"
8022 // supposed to belong to no translation unit in particular, as
8023 // they are unique.
8024 //
8025 // 2/ or the decl was already added to this translation unit.
8026 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
8027 else
8028 decl->set_translation_unit(tu);
8029}
8030
8031/// Add a member decl to this scope. Note that user code should not
8032/// use this, but rather use add_decl_to_scope.
8033///
8034/// Note that this function updates the qualified name of the member
8035/// decl that is added. It also sets the scope of the member. Thus,
8036/// it ABG_ASSERTs that member should not have its scope set, prior to
8037/// calling this function.
8038///
8039/// @param member the new member decl to add to this scope.
8040decl_base_sptr
8041scope_decl::add_member_decl(const decl_base_sptr& member)
8042{
8043 ABG_ASSERT(!has_scope(member));
8044
8045 member->set_scope(this);
8046 priv_->members_.push_back(member);
8047 if (is_type(member))
8048 {
8049 priv_->member_types_.push_back(is_type(member));
8050 priv_->clear_sorted_member_types_cache_ = true;
8051 }
8052
8053 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8054 priv_->member_scopes_.push_back(m);
8055
8056 update_qualified_name(member);
8057
8059 maybe_set_translation_unit(member, tu);
8060
8062
8063 return member;
8064}
8065
8066/// Get the member types of this @ref scope_decl.
8067///
8068/// @return a vector of the member types of this ref class_or_union.
8071{return priv_->member_types_;}
8072
8073/// Find a member type of a given name, inside the current @ref
8074/// scope_decl.
8075///
8076/// @param name the name of the member type to look for.
8077///
8078/// @return a pointer to the @ref type_base that represents the member
8079/// type of name @p name, for the current scope.
8080type_base_sptr
8081scope_decl::find_member_type(const string& name) const
8082{
8083 for (auto t : get_member_types())
8084 if (get_type_name(t, /*qualified*/false) == name)
8085 return t;
8086 return type_base_sptr();
8087}
8088
8089/// Insert a member type.
8090///
8091/// @param t the type to insert in the @ref scope_decl type.
8092///
8093/// @param an iterator right before which @p t has to be inserted.
8094void
8096 declarations::iterator before)
8097{
8098 decl_base_sptr d = get_type_declaration(t);
8099 ABG_ASSERT(d);
8100 ABG_ASSERT(!has_scope(d));
8101
8102 priv_->member_types_.push_back(t);
8103 priv_->clear_sorted_member_types_cache_= true;
8104 insert_member_decl(d, before);
8105}
8106
8107/// Add a member type to the current instance of class_or_union.
8108///
8109/// @param t the member type to add. It must not have been added to a
8110/// scope, otherwise this will violate an ABG_ASSERTion.
8111void
8114
8115/// Add a member type to the current instance of class_or_union.
8116///
8117/// @param t the type to be added as a member type to the current
8118/// instance of class_or_union. An instance of class_or_union::member_type
8119/// will be created out of @p t and and added to the the class.
8120///
8121/// @param a the access specifier for the member type to be created.
8122type_base_sptr
8124{
8125 decl_base_sptr d = get_type_declaration(t);
8126 ABG_ASSERT(d);
8128 add_member_type(t);
8130 return t;
8131}
8132
8133/// Remove a member type from the current @ref class_or_union scope.
8134///
8135/// @param t the type to remove.
8136void
8138{
8139 for (auto i = priv_->member_types_.begin();
8140 i != priv_->member_types_.end();
8141 ++i)
8142 {
8143 if (*((*i)) == *t)
8144 {
8145 priv_->member_types_.erase(i);
8146 return;
8147 }
8148 }
8149}
8150
8151/// Get the sorted member types of this @ref scope_decl
8152///
8153/// @return a vector of the sorted member types of this ref
8154/// class_or_union.
8157{
8158 if (priv_->clear_sorted_member_types_cache_)
8159 {
8160 priv_->sorted_member_types_.clear();
8161 priv_->clear_sorted_member_types_cache_ = false;
8162 }
8163
8164 if (priv_->sorted_member_types_.empty())
8165 {
8166 unordered_set<type_base_sptr> canonical_pointer_types;
8167 for (auto t : get_member_types())
8168 {
8170 priv_->sorted_member_types_.push_back(t);
8171 else if (auto c = t->get_canonical_type())
8172 canonical_pointer_types.insert(c);
8173 else
8174 canonical_pointer_types.insert(t);
8175 }
8176
8177 for (auto t : canonical_pointer_types)
8178 priv_->sorted_member_types_.push_back(t);
8179
8180 type_topo_comp comp;
8181 std::stable_sort(priv_->sorted_member_types_.begin(),
8182 priv_->sorted_member_types_.end(),
8183 comp);
8184 }
8185
8186 const ir::environment& env = get_environment();
8188 priv_->clear_sorted_member_types_cache_ = true;
8189
8190 return priv_->sorted_member_types_;
8191}
8192
8193/// Insert a member decl to this scope, right before an element
8194/// pointed to by a given iterator. Note that user code should not
8195/// use this, but rather use insert_decl_into_scope.
8196///
8197/// Note that this function updates the qualified name of the inserted
8198/// member.
8199///
8200/// @param member the new member decl to add to this scope.
8201///
8202/// @param before an interator pointing to the element before which
8203/// the new member should be inserted.
8204decl_base_sptr
8206 declarations::iterator before)
8207{
8208 ABG_ASSERT(!member->get_scope());
8209
8210 member->set_scope(this);
8211 priv_->members_.insert(before, member);
8212
8213 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8214 priv_-> member_scopes_.push_back(m);
8215
8216 update_qualified_name(member);
8217
8219 maybe_set_translation_unit(member, tu);
8220
8222
8223 return member;
8224}
8225
8226/// Remove a declaration from the current scope.
8227///
8228/// @param member the declaration to remove from the scope.
8229void
8231{
8232 for (declarations::iterator i = priv_->members_.begin();
8233 i != priv_->members_.end();
8234 ++i)
8235 {
8236 if (**i == *member)
8237 {
8238 priv_->members_.erase(i);
8239 // Do not access i after this point as it's invalided by the
8240 // erase call.
8241 break;
8242 }
8243 }
8244
8245 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8246 if (scope)
8247 {
8248 for (scopes::iterator i = priv_->member_scopes_.begin();
8249 i != priv_->member_scopes_.end();
8250 ++i)
8251 {
8252 if (**i == *member)
8253 {
8254 priv_->member_scopes_.erase(i);
8255 break;
8256 }
8257 }
8258 }
8259
8260 member->set_scope(nullptr);
8261 member->set_translation_unit(nullptr);
8262}
8263
8264/// Compares two instances of @ref scope_decl.
8265///
8266/// If the two intances are different, set a bitfield to give some
8267/// insight about the kind of differences there are.
8268///
8269/// @param l the first artifact of the comparison.
8270///
8271/// @param r the second artifact of the comparison.
8272///
8273/// @param k a pointer to a bitfield that gives information about the
8274/// kind of changes there are between @p l and @p r. This one is set
8275/// iff @p k is non-null and the function returns false.
8276///
8277/// Please note that setting k to a non-null value does have a
8278/// negative performance impact because even if @p l and @p r are not
8279/// equal, the function keeps up the comparison in order to determine
8280/// the different kinds of ways in which they are different.
8281///
8282/// @return true if @p l equals @p r, false otherwise.
8283bool
8285{
8286 bool result = true;
8287
8288 if (!l.decl_base::operator==(r))
8289 {
8290 result = false;
8291 if (k)
8293 else
8295 }
8296
8297 scope_decl::declarations::const_iterator i, j;
8298 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8299 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8300 ++i, ++j)
8301 {
8302 if (**i != **j)
8303 {
8304 result = false;
8305 if (k)
8306 {
8307 *k |= SUBTYPE_CHANGE_KIND;
8308 break;
8309 }
8310 else
8312 }
8313 }
8314
8315 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8316 {
8317 result = false;
8318 if (k)
8320 else
8322 }
8323
8324 ABG_RETURN(result);
8325}
8326
8327/// Return true iff both scopes have the same names and have the same
8328/// member decls.
8329///
8330/// This function doesn't check for equality of the scopes of its
8331/// arguments.
8332bool
8333scope_decl::operator==(const decl_base& o) const
8334{
8335 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8336 if (!other)
8337 return false;
8338
8339 return equals(*this, *other, 0);
8340}
8341
8342/// Equality operator for @ref scope_decl_sptr.
8343///
8344/// @param l the left hand side operand of the equality operator.
8345///
8346/// @pram r the right hand side operand of the equalify operator.
8347///
8348/// @return true iff @p l equals @p r.
8349bool
8351{
8352 if (!!l != !!r)
8353 return false;
8354 if (l.get() == r.get())
8355 return true;
8356 return *l == *r;
8357}
8358
8359/// Inequality operator for @ref scope_decl_sptr.
8360///
8361/// @param l the left hand side operand of the equality operator.
8362///
8363/// @pram r the right hand side operand of the equalify operator.
8364///
8365/// @return true iff @p l equals @p r.
8366bool
8368{return !operator==(l, r);}
8369
8370/// Find a member of the current scope and return an iterator on it.
8371///
8372/// @param decl the scope member to find.
8373///
8374/// @param i the iterator to set to the member @p decl. This is set
8375/// iff the function returns true.
8376///
8377/// @return true if the member decl was found, false otherwise.
8378bool
8380 declarations::iterator& i)
8381{
8382 if (!decl)
8383 return false;
8384
8385 if (get_member_decls().empty())
8386 {
8387 i = get_member_decls().end();
8388 return false;
8389 }
8390
8391 for (declarations::iterator it = get_member_decls().begin();
8392 it != get_member_decls().end();
8393 ++it)
8394 {
8395 if ((*it).get() == decl)
8396 {
8397 i = it;
8398 return true;
8399 }
8400 }
8401
8402 return false;
8403}
8404
8405/// Find a member of the current scope and return an iterator on it.
8406///
8407/// @param decl the scope member to find.
8408///
8409/// @param i the iterator to set to the member @p decl. This is set
8410/// iff the function returns true.
8411///
8412/// @return true if the member decl was found, false otherwise.
8413bool
8415 declarations::iterator& i)
8416{return find_iterator_for_member(decl.get(), i);}
8417
8418/// This implements the ir_traversable_base::traverse pure virtual
8419/// function.
8420///
8421/// @param v the visitor used on the current instance of scope_decl
8422/// and on its member nodes.
8423///
8424/// @return true if the traversal of the tree should continue, false
8425/// otherwise.
8426bool
8428{
8429 if (visiting())
8430 return true;
8431
8432 if (v.visit_begin(this))
8433 {
8434 visiting(true);
8435 for (scope_decl::declarations::const_iterator i =
8436 get_member_decls().begin();
8437 i != get_member_decls ().end();
8438 ++i)
8439 if (!(*i)->traverse(v))
8440 break;
8441 visiting(false);
8442 }
8443 return v.visit_end(this);
8444}
8445
8446scope_decl::~scope_decl()
8447{}
8448
8449/// Appends a declaration to a given scope, if the declaration
8450/// doesn't already belong to one and if the declaration is not for a
8451/// type that is supposed to be unique.
8452///
8453/// @param decl the declaration to add to the scope
8454///
8455/// @param scope the scope to append the declaration to
8456decl_base_sptr
8457add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8458{
8459 if (!scope)
8460 return decl;
8461
8462 if (scope && decl && !decl->get_scope())
8463 decl = scope->add_member_decl(decl);
8464
8465 return decl;
8466}
8467
8468/// Appends a declaration to a given scope, if the declaration doesn't
8469/// already belong to a scope.
8470///
8471/// @param decl the declaration to add append to the scope
8472///
8473/// @param scope the scope to append the decl to
8474decl_base_sptr
8475add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8476{return add_decl_to_scope(decl, scope.get());}
8477
8478/// Remove a given decl from its scope
8479///
8480/// @param decl the decl to remove from its scope.
8481void
8482remove_decl_from_scope(decl_base_sptr decl)
8483{
8484 if (!decl)
8485 return;
8486
8487 scope_decl* scope = decl->get_scope();
8488 scope->remove_member_decl(decl);
8489}
8490
8491/// Inserts a declaration into a given scope, before a given IR child
8492/// node of the scope.
8493///
8494/// @param decl the declaration to insert into the scope.
8495///
8496/// @param before an iterator pointing to the child IR node before
8497/// which to insert the declaration.
8498///
8499/// @param scope the scope into which to insert the declaration.
8500decl_base_sptr
8501insert_decl_into_scope(decl_base_sptr decl,
8502 scope_decl::declarations::iterator before,
8503 scope_decl* scope)
8504{
8505 if (scope && decl && !decl->get_scope())
8506 {
8507 decl_base_sptr d = scope->insert_member_decl(decl, before);
8508 decl = d;
8509 }
8510 return decl;
8511}
8512
8513/// Inserts a declaration into a given scope, before a given IR child
8514/// node of the scope.
8515///
8516/// @param decl the declaration to insert into the scope.
8517///
8518/// @param before an iterator pointing to the child IR node before
8519/// which to insert the declaration.
8520///
8521/// @param scope the scope into which to insert the declaration.
8522decl_base_sptr
8523insert_decl_into_scope(decl_base_sptr decl,
8524 scope_decl::declarations::iterator before,
8525 scope_decl_sptr scope)
8526{return insert_decl_into_scope(decl, before, scope.get());}
8527
8528/// Constructor of the @ref global_scope type.
8529///
8530/// @param tu the translation unit the scope belongs to.
8531global_scope::global_scope(translation_unit *tu)
8532 : type_or_decl_base(tu->get_environment(),
8533 GLOBAL_SCOPE_DECL
8534 | ABSTRACT_DECL_BASE
8535 | ABSTRACT_SCOPE_DECL),
8536 decl_base(tu->get_environment(), "", location()),
8537 scope_decl(tu->get_environment(), "", location()),
8538 translation_unit_(tu)
8539{
8540 runtime_type_instance(this);
8541}
8542
8543/// return the global scope as seen by a given declaration.
8544///
8545/// @param decl the declaration to consider.
8546///
8547/// @return the global scope of the decl, or a null pointer if the
8548/// decl is not yet added to a translation_unit.
8549const global_scope*
8551{
8552 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8553 return s;
8554
8555 scope_decl* scope = decl.get_scope();
8556 while (scope && !dynamic_cast<global_scope*>(scope))
8557 scope = scope->get_scope();
8558
8559 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8560}
8561
8562/// return the global scope as seen by a given declaration.
8563///
8564/// @param decl the declaration to consider.
8565///
8566/// @return the global scope of the decl, or a null pointer if the
8567/// decl is not yet added to a translation_unit.
8568const global_scope*
8570{return get_global_scope(*decl);}
8571
8572/// Return the global scope as seen by a given declaration.
8573///
8574/// @param decl the declaration to consider.
8575///
8576/// @return the global scope of the decl, or a null pointer if the
8577/// decl is not yet added to a translation_unit.
8578const global_scope*
8579get_global_scope(const shared_ptr<decl_base> decl)
8580{return get_global_scope(decl.get());}
8581
8582/// Return the a scope S containing a given declaration and that is
8583/// right under a given scope P.
8584///
8585/// Note that @p scope must come before @p decl in topological
8586/// order.
8587///
8588/// @param decl the decl for which to find a scope.
8589///
8590/// @param scope the scope under which the resulting scope must be.
8591///
8592/// @return the resulting scope.
8593const scope_decl*
8595 const scope_decl* scope)
8596{
8597 if (!decl)
8598 return 0;
8599
8600 if (scope == 0)
8601 return get_global_scope(decl);
8602
8603 // Handle the case where decl is a scope itself.
8604 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8605 if (!s)
8606 s = decl->get_scope();
8607
8608 if (is_global_scope(s))
8609 return scope;
8610
8611 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8612 // same. The caller needs to be prepared to deal with this case.
8613 if (s == scope)
8614 return s;
8615
8616 while (s && !is_global_scope(s) && s->get_scope() != scope)
8617 s = s->get_scope();
8618
8619 if (!s || is_global_scope(s))
8620 // SCOPE must come before decl in topological order, but I don't
8621 // know how to ensure that ...
8622 return scope;
8623 ABG_ASSERT(s);
8624
8625 return s;
8626}
8627
8628/// Return the a scope S containing a given declaration and that is
8629/// right under a given scope P.
8630///
8631/// @param decl the decl for which to find a scope.
8632///
8633/// @param scope the scope under which the resulting scope must be.
8634///
8635/// @return the resulting scope.
8636const scope_decl*
8637get_top_most_scope_under(const decl_base_sptr decl,
8638 const scope_decl* scope)
8639{return get_top_most_scope_under(decl.get(), scope);}
8640
8641/// Return the a scope S containing a given declaration and that is
8642/// right under a given scope P.
8643///
8644/// @param decl the decl for which to find a scope.
8645///
8646/// @param scope the scope under which the resulting scope must be.
8647///
8648/// @return the resulting scope.
8649const scope_decl*
8650get_top_most_scope_under(const decl_base_sptr decl,
8651 const scope_decl_sptr scope)
8652{return get_top_most_scope_under(decl, scope.get());}
8653
8654// </scope_decl stuff>
8655
8656
8657/// Get the string representation of a CV qualifier bitmap.
8658///
8659/// @param cv_quals the bitmap of CV qualifiers to consider.
8660///
8661/// @return the string representation.
8662string
8664{
8665 string repr;
8666 if (cv_quals & qualified_type_def::CV_RESTRICT)
8667 repr = "restrict";
8668 if (cv_quals & qualified_type_def::CV_CONST)
8669 {
8670 if (!repr.empty())
8671 repr += ' ';
8672 repr += "const";
8673 }
8674 if (cv_quals & qualified_type_def::CV_VOLATILE)
8675 {
8676 if (!repr.empty())
8677 repr += ' ';
8678 repr += "volatile";
8679 }
8680 return repr;
8681}
8682
8683/// Build and return a copy of the name of an ABI artifact that is
8684/// either a type or a decl.
8685///
8686/// @param tod the ABI artifact to get the name for.
8687///
8688/// @param qualified if yes, return the qualified name of @p tod;
8689/// otherwise, return the non-qualified name;
8690///
8691/// @return the name of @p tod.
8692string
8693get_name(const type_or_decl_base *tod, bool qualified)
8694{
8695 string result;
8696
8697 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8698
8699 if (type_base* t = dynamic_cast<type_base*>(a))
8700 result = get_type_name(t, qualified);
8701 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8702 {
8703 if (qualified)
8704 result = d->get_qualified_name();
8705 else
8706 result = d->get_name();
8707 }
8708 else
8709 // We should never reach this point.
8710 abort();
8711
8712 return result;
8713}
8714
8715/// Build and return a copy of the name of an ABI artifact that is
8716/// either a type of a decl.
8717///
8718/// @param tod the ABI artifact to get the name for.
8719///
8720/// @param qualified if yes, return the qualified name of @p tod;
8721/// otherwise, return the non-qualified name;
8722///
8723/// @return the name of @p tod.
8724string
8725get_name(const type_or_decl_base_sptr& tod, bool qualified)
8726{return get_name(tod.get(), qualified);}
8727
8728/// Build and return a qualified name from a name and its scope.
8729///
8730/// The name is supposed to be for an entity that is part of the
8731/// scope.
8732///
8733/// @param the scope to consider.
8734///
8735/// @param name of the name to consider.
8736///
8737/// @return a copy of the string that represents the qualified name.
8738string
8739build_qualified_name(const scope_decl* scope, const string& name)
8740{
8741 if (name.empty())
8742 return "";
8743
8744 string qualified_name;
8745 if (scope)
8746 qualified_name = scope->get_qualified_name();
8747
8748 if (qualified_name.empty())
8749 qualified_name = name;
8750 else
8751 qualified_name = qualified_name + "::" + name;
8752
8753 return qualified_name;
8754}
8755
8756/// Build and return the qualified name of a type in its scope.
8757///
8758/// @param scope the scope of the type to consider.
8759///
8760/// @param type the type to consider.
8761string
8762build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8763{return build_qualified_name(scope, get_name((type)));}
8764
8765// </scope_decl stuff>
8766
8767/// Get the location of the declaration of a given type.
8768///
8769/// @param type the type to consider.
8770///
8771/// @return the location of the declaration of type @p type.
8773get_location(const type_base_sptr& type)
8774{
8775 if (decl_base_sptr decl = get_type_declaration(type))
8776 return get_location(decl);
8777 return location();
8778}
8779
8780/// Get the location of a given declaration.
8781///
8782/// @param decl the declaration to consider.
8783///
8784/// @return the location of the declaration @p decl.
8786get_location(const decl_base_sptr& decl)
8787{
8788 location loc = decl->get_location();
8789 if (!loc)
8790 {
8791 if (class_or_union_sptr c = is_class_or_union_type(decl))
8792 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8793 {
8794 c = is_class_or_union_type(c->get_definition_of_declaration());
8795 loc = c->get_location();
8796 }
8797 }
8798 return loc;
8799}
8800
8801/// Get the scope of a given type.
8802///
8803/// @param t the type to consider.
8804///
8805/// @return the scope of type @p t or 0 if the type has no scope yet.
8808{
8809 if (!t)
8810 return 0;
8811
8813 if (d)
8814 return d->get_scope();
8815 return 0;
8816}
8817
8818/// Get the scope of a given type.
8819///
8820/// @param t the type to consider.
8821///
8822/// @return the scope of type @p t or 0 if the type has no scope yet.
8824get_type_scope(const type_base_sptr& t)
8825{return get_type_scope(t.get());}
8826
8827/// Get the name of a given type and return a copy of it.
8828///
8829/// @param t the type to consider.
8830///
8831/// @param qualified if true then return the qualified name of the
8832/// type.
8833///
8834/// @param internal set to true if the call is intended for an
8835/// internal use (for technical use inside the library itself), false
8836/// otherwise. If you don't know what this is for, then set it to
8837/// false.
8838///
8839/// @return a copy of the type name if the type has a name, or the
8840/// empty string if it does not.
8842get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8843{return get_type_name(t.get(), qualified, internal);}
8844
8845/// Return true iff a decl is for a type type that has a generic
8846/// anonymous internal type name.
8847///
8848/// @param d the decl to considier.
8849///
8850/// @return true iff @p d is for a type type that has a generic
8851/// anonymous internal type name.
8852static bool
8853has_generic_anonymous_internal_type_name(const decl_base *d)
8854{
8855 return (is_class_or_union_type(d)
8856 || is_enum_type(d)
8857 || is_subrange_type(d));
8858}
8859
8860/// Return the generic internal name of an anonymous type.
8861///
8862/// For internal purposes, we want to define a generic name for all
8863/// anonymous types of a certain kind. For instance, all anonymous
8864/// structs will be have a generic name of "__anonymous_struct__", all
8865/// anonymous unions will have a generic name of
8866/// "__anonymous_union__", etc.
8867///
8868/// That generic name can be used as a hash to put all anonymous types
8869/// of a certain kind in the same hash table bucket, for instance.
8870static interned_string
8871get_generic_anonymous_internal_type_name(const decl_base *d)
8872{
8873 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8874
8875 const environment&env = d->get_environment();
8876
8877 interned_string result;
8878 if (is_class_type(d))
8879 result =
8881 else if (is_union_type(d))
8882 result =
8884 else if (is_enum_type(d))
8885 result =
8887 else if (is_subrange_type(d))
8888 result =
8890 else
8892
8893 return result;
8894}
8895
8896/// Get the internal name for a given real type.
8897///
8898/// All real types that have the modifiers 'short, long or long
8899/// long' have the same internal name. This is so that they can all
8900/// have the same canonical type if they are of the same size.
8901/// Otherwise, 'long int' and 'long long int' would have different
8902/// canonical types even though they are equivalent from an ABI point
8903/// of view.
8904///
8905/// @param t the real type to consider
8906///
8907/// @return the internal name for @p t if it's an integral type, or
8908/// the empty string if @p t is not a real type.
8909static string
8910get_internal_real_type_name(const type_base* t)
8911{
8912 string name;
8913 type_decl *type = is_real_type(t);
8914
8915 if (!type)
8916 return name;
8917
8918 real_type int_type;
8919 if (parse_real_type(type->get_name(), int_type))
8920 name = int_type.to_string(/*internal=*/true);
8921
8922 return name;
8923}
8924
8925/// Get the name of a given type and return a copy of it.
8926///
8927/// @param t the type to consider.
8928///
8929/// @param qualified if true then return the qualified name of the
8930/// type.
8931///
8932/// @param internal set to true if the call is intended for an
8933/// internal use (for technical use inside the library itself), false
8934/// otherwise. If you don't know what this is for, then set it to
8935/// false.
8936///
8937/// @return a copy of the type name if the type has a name, or the
8938/// empty string if it does not.
8940get_type_name(const type_base* t, bool qualified, bool internal)
8941{
8942 interned_string empty_string;
8943
8944 if (!t)
8945 return empty_string;
8946
8947 const decl_base* d = dynamic_cast<const decl_base*>(t);
8948 if (!d)
8949 {
8950 const function_type* fn_type = is_function_type(t);
8951 if (!fn_type)
8952 return empty_string;
8953 return fn_type->get_cached_name(internal);
8954 }
8955
8956 const environment&env = d->get_environment();
8957
8958 // All anonymous types of a given kind get to have the same internal
8959 // name for internal purpose. This to allow them to be compared
8960 // among themselves during type canonicalization.
8961 if (internal)
8962 {
8963 if (d->get_is_anonymous() && !is_type_decl(t))
8964 {
8965 // Note that anonymous type_decl that are used for
8966 // enumerators are not handled here because they don't have
8967 // generic internal type names.
8968 string r;
8969 r += get_generic_anonymous_internal_type_name(d);
8970 return t->get_environment().intern(r);
8971 }
8972
8973 if (is_typedef(t))
8974 return d->get_name();
8975
8976 if (qualified)
8977 return d->get_qualified_name(internal);
8978
8979 return env.intern(get_internal_real_type_name(t));
8980 }
8981
8982 if (d->get_is_anonymous())
8983 {
8985 return env.intern
8987 /*one_line=*/true,
8988 internal, qualified));
8989 }
8990
8991 if (qualified)
8992 return d->get_qualified_name(internal);
8993 return d->get_name();
8994}
8995
8996/// Get the name of a given type and return a copy of it.
8997///
8998/// @param t the type to consider.
8999///
9000/// @param qualified if true then return the qualified name of the
9001/// type.
9002///
9003/// @param internal set to true if the call is intended for an
9004/// internal use (for technical use inside the library itself), false
9005/// otherwise. If you don't know what this is for, then set it to
9006/// false.
9007///
9008/// @return a copy of the type name if the type has a name, or the
9009/// empty string if it does not.
9011get_type_name(const type_base& t, bool qualified, bool internal)
9012{return get_type_name(&t, qualified, internal);}
9013
9014/// Get the name of the pointer to a given type.
9015///
9016/// @param pointed_to_type the pointed-to-type to consider.
9017///
9018/// @param qualified this is true if the resulting name should be of a
9019/// pointer to a *fully-qualified* pointed-to-type.
9020///
9021/// @param internal true if the name is for libabigail-internal
9022/// purposes.
9023///
9024/// @return the name (string representation) of the pointer.
9027 bool qualified, bool internal)
9028{
9029 const environment& env = pointed_to_type.get_environment();
9030 string tn = get_type_name(pointed_to_type, qualified, internal);
9031 tn = tn + "*";
9032
9033 return env.intern(tn);
9034}
9035
9036/// Get the name of the reference to a given type.
9037///
9038/// @param pointed_to_type the pointed-to-type to consider.
9039///
9040/// @param qualified this is true if the resulting name should be of a
9041/// reference to a *fully-qualified* pointed-to-type.
9042///
9043/// @param internal true if the name is for libabigail-internal
9044/// purposes.
9045///
9046/// @return the name (string representation) of the reference.
9049 bool lvalue_reference,
9050 bool qualified, bool internal)
9051{
9052 const environment& env = pointed_to_type.get_environment();
9053
9054 string name = get_type_name(pointed_to_type, qualified, internal);
9055 if (lvalue_reference)
9056 name = name + "&";
9057 else
9058 name = name + "&&";
9059
9060 return env.intern(name);
9061}
9062
9063/// Get the name of a qualified type, given the underlying type and
9064/// its qualifiers.
9065///
9066/// @param underlying_type the underlying type to consider.
9067///
9068/// @param quals the CV qualifiers of the name.
9069///
9070/// @param qualified true if we should consider the fully qualified
9071/// name of @p underlying_type.
9072///
9073/// @param internal true if the result is to be used for
9074/// libabigail-internal purposes.
9075///
9076/// @return the name (string representation) of the qualified type.
9078get_name_of_qualified_type(const type_base_sptr& underlying_type,
9080 bool qualified, bool internal)
9081{
9082 const environment& env = underlying_type->get_environment();
9083
9084 string quals_repr = get_string_representation_of_cv_quals(quals);
9085 string name = get_type_name(underlying_type, qualified, internal);
9086
9087 if (quals_repr.empty() && internal)
9088 // We are asked to return the internal name, that might be used
9089 // for type canonicalization. For that canonicalization, we need
9090 // to make a difference between a no-op qualified type which
9091 // underlying type is foo (the qualified type is named "none
9092 // foo"), and the name of foo, which is just "foo".
9093 //
9094 // Please remember that this has to be kept in sync with what is
9095 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
9096 // change this code here, please change that code there too.
9097 quals_repr = "";
9098
9099 if (!quals_repr.empty())
9100 {
9101 if (is_pointer_type(peel_qualified_type(underlying_type))
9102 || is_reference_type(peel_qualified_type(underlying_type)))
9103 {
9104 name += " ";
9105 name += quals_repr;
9106 }
9107 else
9108 name = quals_repr + " " + name;
9109 }
9110
9111 return env.intern(name);
9112}
9113
9114/// Get the name of a given function type and return a copy of it.
9115///
9116/// @param fn_type the function type to consider.
9117///
9118/// @param internal set to true if the call is intended for an
9119/// internal use (for technical use inside the library itself), false
9120/// otherwise. If you don't know what this is for, then set it to
9121/// false.
9122///
9123/// @return a copy of the function type name
9126 bool internal)
9127{return get_function_type_name(fn_type.get(), internal);}
9128
9129/// Get the name of a given function type and return a copy of it.
9130///
9131/// @param fn_type the function type to consider.
9132///
9133/// @param internal set to true if the call is intended for an
9134/// internal use (for technical use inside the library itself), false
9135/// otherwise. If you don't know what this is for, then set it to
9136/// false.
9137///
9138/// @return a copy of the function type name
9141 bool internal)
9142{
9143 ABG_ASSERT(fn_type);
9144
9145 if (const method_type* method = is_method_type(fn_type))
9146 return get_method_type_name(method, internal);
9147
9148 return get_function_type_name(*fn_type, internal);
9149}
9150
9151/// Get the name of a given function type and return a copy of it.
9152///
9153/// @param fn_type the function type to consider.
9154///
9155/// @param internal set to true if the call is intended for an
9156/// internal use (for technical use inside the library itself), false
9157/// otherwise. If you don't know what this is for, then set it to
9158/// false.
9159///
9160/// @return a copy of the function type name
9163 bool internal)
9164{
9165 std::ostringstream o;
9166 // When the function name is used for internal purposes (e.g, for
9167 // canonicalization), we want its representation to stay the same,
9168 // regardless of typedefs. So let's strip typedefs from the return
9169 // type.
9170 type_base_sptr return_type = fn_type.get_return_type();
9171 const environment& env = fn_type.get_environment();
9172
9173 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
9174 stream_pretty_representation_of_fn_parms(fn_type, o,
9175 /*qualified=*/true,
9176 internal);
9177 return env.intern(o.str());
9178}
9179
9180/// Get the ID of a function, or, if the ID can designate several
9181/// different functions, get its pretty representation.
9182///
9183/// @param fn the function to consider
9184///
9185/// @return the function ID of pretty representation of @p fn.
9188{
9189 ABG_ASSERT(fn);
9190
9191 interned_string result = fn->get_environment().intern(fn->get_id());
9192
9193 if (const corpus *c = fn->get_corpus())
9194 {
9196 c->get_exported_decls_builder();
9197 if (b->fn_id_maps_to_several_fns(fn))
9198 result = fn->get_environment().intern(fn->get_pretty_representation());
9199 }
9200
9201 return result;
9202}
9203
9204/// Get the name of a given method type and return a copy of it.
9205///
9206/// @param fn_type the function type to consider.
9207///
9208/// @param internal set to true if the call is intended for an
9209/// internal use (for technical use inside the library itself), false
9210/// otherwise. If you don't know what this is for, then set it to
9211/// false.
9212///
9213/// @return a copy of the function type name
9216 bool internal)
9217{return get_method_type_name(fn_type.get(), internal);}
9218
9219/// Get the name of a given method type and return a copy of it.
9220///
9221/// @param fn_type the function type to consider.
9222///
9223/// @param internal set to true if the call is intended for an
9224/// internal use (for technical use inside the library itself), false
9225/// otherwise. If you don't know what this is for, then set it to
9226/// false.
9227///
9228/// @return a copy of the function type name
9231 bool internal)
9232{
9233 if (fn_type)
9234 return get_method_type_name(*fn_type, internal);
9235
9236 return interned_string();
9237}
9238
9239/// Get the name of a given method type and return a copy of it.
9240///
9241/// @param fn_type the function type to consider.
9242///
9243/// @param internal set to true if the call is intended for an
9244/// internal use (for technical use inside the library itself), false
9245/// otherwise. If you don't know what this is for, then set it to
9246/// false.
9247///
9248/// @return a copy of the function type name
9250get_method_type_name(const method_type& fn_type,
9251 bool internal)
9252{
9253 std::ostringstream o;
9254 // When the function name is used for internal purposes (e.g, for
9255 // canonicalization), we want its representation to stay the same,
9256 // regardless of typedefs. So let's strip typedefs from the return
9257 // type.
9258 type_base_sptr return_type = fn_type.get_return_type();
9259
9260 const environment& env = fn_type.get_environment();
9261
9262 if (return_type)
9263 o << get_type_name(return_type, /*qualified=*/true, internal);
9264 else
9265 // There are still some abixml files out there in which "void"
9266 // can be expressed as an empty type.
9267 o << "void";
9268
9269 class_or_union_sptr class_type = fn_type.get_class_type();
9270 ABG_ASSERT(class_type);
9271
9272 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9273 stream_pretty_representation_of_fn_parms(fn_type, o,
9274 /*qualified=*/true,
9275 internal);
9276
9277 return env.intern(o.str());
9278}
9279
9280/// Build and return a copy of the pretty representation of an ABI
9281/// artifact that could be either a type of a decl.
9282///
9283/// param tod the ABI artifact to consider.
9284///
9285/// @param internal set to true if the call is intended for an
9286/// internal use (for technical use inside the library itself), false
9287/// otherwise. If you don't know what this is for, then set it to
9288/// false.
9289///
9290/// @return a copy of the pretty representation of an ABI artifact
9291/// that could be either a type of a decl.
9292string
9294{
9295 string result;
9296
9297 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9298 result = get_pretty_representation(t, internal);
9299 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9300 result = get_pretty_representation(d, internal);
9301 else
9302 // We should never reach this point
9303 abort();
9304
9305 return result;
9306}
9307
9308/// Build and return a copy of the pretty representation of an ABI
9309/// artifact that could be either a type of a decl.
9310///
9311/// param tod the ABI artifact to consider.
9312///
9313/// @param internal set to true if the call is intended for an
9314/// internal use (for technical use inside the library itself), false
9315/// otherwise. If you don't know what this is for, then set it to
9316/// false.
9317///
9318/// @return a copy of the pretty representation of an ABI artifact
9319/// that could be either a type of a decl.
9320string
9322{return get_pretty_representation(tod.get(), internal);}
9323
9324/// Get a copy of the pretty representation of a decl.
9325///
9326/// @param d the decl to consider.
9327///
9328/// @param internal set to true if the call is intended for an
9329/// internal use (for technical use inside the library itself), false
9330/// otherwise. If you don't know what this is for, then set it to
9331/// false.
9332///
9333/// @return the pretty representation of the decl.
9334string
9335get_pretty_representation(const decl_base* d, bool internal)
9336{
9337 if (!d)
9338 return "";
9339 return d->get_pretty_representation(internal);
9340}
9341
9342/// Get a copy of the pretty representation of a type.
9343///
9344/// @param d the type to consider.
9345///
9346/// @param internal set to true if the call is intended for an
9347/// internal use (for technical use inside the library itself), false
9348/// otherwise. If you don't know what this is for, then set it to
9349/// false.
9350///
9351/// @return the pretty representation of the type.
9352string
9353get_pretty_representation(const type_base* t, bool internal)
9354{
9355 if (!t)
9356 return "void";
9357 if (const function_type* fn_type = is_function_type(t))
9358 return get_pretty_representation(fn_type, internal);
9359
9360 const decl_base* d = get_type_declaration(t);
9361 ABG_ASSERT(d);
9362 return get_pretty_representation(d, internal);
9363}
9364
9365/// Get a copy of the pretty representation of a decl.
9366///
9367/// @param d the decl to consider.
9368///
9369/// @param internal set to true if the call is intended for an
9370/// internal use (for technical use inside the library itself), false
9371/// otherwise. If you don't know what this is for, then set it to
9372/// false.
9373///
9374/// @return the pretty representation of the decl.
9375string
9376get_pretty_representation(const decl_base_sptr& d, bool internal)
9377{return get_pretty_representation(d.get(), internal);}
9378
9379/// Get a copy of the pretty representation of a type.
9380///
9381/// @param d the type to consider.
9382///
9383/// @param internal set to true if the call is intended for an
9384/// internal use (for technical use inside the library itself), false
9385/// otherwise. If you don't know what this is for, then set it to
9386/// false.
9387///
9388/// @return the pretty representation of the type.
9389string
9390get_pretty_representation(const type_base_sptr& t, bool internal)
9391{return get_pretty_representation(t.get(), internal);}
9392
9393/// Get the pretty representation of a function type.
9394///
9395/// @param fn_type the function type to consider.
9396///
9397/// @param internal set to true if the call is intended for an
9398/// internal use (for technical use inside the library itself), false
9399/// otherwise. If you don't know what this is for, then set it to
9400/// false.
9401///
9402/// @return the string represenation of the function type.
9403string
9405 bool internal)
9406{return get_pretty_representation(fn_type.get(), internal);}
9407
9408/// Get the pretty representation of a function type.
9409///
9410/// @param fn_type the function type to consider.
9411///
9412/// @param internal set to true if the call is intended for an
9413/// internal use (for technical use inside the library itself), false
9414/// otherwise. If you don't know what this is for, then set it to
9415/// false.
9416///
9417/// @return the string represenation of the function type.
9418string
9419get_pretty_representation(const function_type* fn_type, bool internal)
9420{
9421 if (!fn_type)
9422 return "void";
9423
9424 if (const method_type* method = is_method_type(fn_type))
9425 return get_pretty_representation(method, internal);
9426
9427 return get_pretty_representation(*fn_type, internal);
9428}
9429
9430/// Get the pretty representation of a function type.
9431///
9432/// @param fn_type the function type to consider.
9433///
9434/// @param internal set to true if the call is intended for an
9435/// internal use (for technical use inside the library itself), false
9436/// otherwise. If you don't know what this is for, then set it to
9437/// false.
9438///
9439/// @return the string represenation of the function type.
9440string
9441get_pretty_representation(const function_type& fn_type, bool internal)
9442{
9443 std::ostringstream o;
9444 o << "function type " << get_function_type_name(fn_type, internal);
9445 return o.str();
9446}
9447
9448/// Get the pretty representation of a method type.
9449///
9450/// @param method the method type to consider.
9451///
9452/// @param internal set to true if the call is intended for an
9453/// internal use (for technical use inside the library itself), false
9454/// otherwise. If you don't know what this is for, then set it to
9455/// false.
9456///
9457/// @return the string represenation of the method type.
9458string
9459get_pretty_representation(const method_type& method, bool internal)
9460{
9461 std::ostringstream o;
9462 o << "method type " << get_method_type_name(method, internal);
9463 return o.str();
9464}
9465
9466/// Get the pretty representation of a method type.
9467///
9468/// @param method the method type to consider.
9469///
9470/// @param internal set to true if the call is intended for an
9471/// internal use (for technical use inside the library itself), false
9472/// otherwise. If you don't know what this is for, then set it to
9473/// false.
9474///
9475/// @return the string represenation of the method type.
9476string
9477get_pretty_representation(const method_type* method, bool internal)
9478{
9479 if (!method)
9480 return "void";
9481 return get_pretty_representation(*method, internal);
9482}
9483
9484/// Get the pretty representation of a method type.
9485///
9486/// @param method the method type to consider.
9487///
9488/// @param internal set to true if the call is intended for an
9489/// internal use (for technical use inside the library itself), false
9490/// otherwise. If you don't know what this is for, then set it to
9491/// false.
9492///
9493/// @return the string represenation of the method type.
9494string
9496{return get_pretty_representation(method.get(), internal);}
9497
9498/// Get the flat representation of an instance of @ref class_or_union
9499/// type.
9500///
9501/// The flat representation of a given @ref class_or_union type is the
9502/// actual definition of the type, for instance:
9503///
9504/// struct foo {int a; char b;}
9505///
9506///@param cou the instance of @ref class_or_union to consider.
9507///
9508///@param indent the identation spaces to use in the representation.
9509///
9510///@param one_line if true, then the flat representation stands on one
9511///line. Otherwise, it stands on multiple lines.
9512///
9513///@return the resulting flat representation.
9514string
9516 const string& indent,
9517 bool one_line,
9518 bool internal,
9519 bool qualified_names)
9520{
9521 string repr;
9522 string local_indent = " ";
9523
9524 if (class_decl* clazz = is_class_type(&cou))
9525 {
9526 repr = indent;
9527 if (!internal && clazz->is_struct())
9528 repr += "struct";
9529 else
9530 repr += "class";
9531 }
9532 else if (is_union_type(cou))
9533 repr = indent + "union";
9534 else
9535 return "";
9536
9537 repr += " ";
9538
9539 string name = cou.get_qualified_name();
9540
9541 if (!cou.get_is_anonymous())
9542 repr += name;
9543
9544 if (cou.priv_->is_printing_flat_representation())
9545 {
9546 // We have just detected a cycle while walking the sub-tree
9547 // of this class or union type for the purpose of printing
9548 // its flat representation. We need to get out of here
9549 // pronto or else we'll be spinning endlessly.
9550 repr += "{}";
9551 return repr;
9552 }
9553
9554 // Let's mark this class or union type to signify that we started
9555 // walking its sub-tree. This is to detect potential cycles and
9556 // avoid looping endlessly.
9558
9559 repr += "{";
9560
9561 if (!one_line)
9562 repr += "\n";
9563
9564 string real_indent;
9566 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9567 dm != dmems.end();
9568 ++dm)
9569 {
9570 if (dm != dmems.begin())
9571 {
9572 if (one_line)
9573 real_indent = " ";
9574 else
9575 real_indent = "\n" + indent + local_indent;
9576 }
9577
9579 repr +=
9582 real_indent, one_line, internal, qualified_names);
9583 else
9584 {
9585 if (one_line)
9586 {
9587 if (dm != dmems.begin())
9588 repr += real_indent;
9589 repr += (*dm)->get_pretty_representation(internal,
9590 qualified_names);
9591 }
9592 else
9593 repr +=
9594 real_indent+ (*dm)->get_pretty_representation(internal,
9595 qualified_names);
9596 }
9597 repr += ";";
9598 }
9599
9600 if (one_line)
9601 repr += "}";
9602 else
9603 repr += indent + "}";
9604
9605 // Let's unmark this class or union type to signify that we are done
9606 // walking its sub-tree. This was to detect potential cycles and
9607 // avoid looping endlessly.
9609
9610 return repr;
9611}
9612
9613/// Get the flat representation of an instance of @ref class_or_union
9614/// type.
9615///
9616/// The flat representation of a given @ref class_or_union type is the
9617/// actual definition of the type, for instance:
9618///
9619/// struct foo {int a; char b;}
9620///
9621///@param cou the instance of @ref class_or_union to consider.
9622///
9623///@param indent the identation spaces to use in the representation.
9624///
9625///@param one_line if true, then the flat representation stands on one
9626///line. Otherwise, it stands on multiple lines.
9627///
9628///@return the resulting flat representation.
9629string
9631 const string& indent,
9632 bool one_line,
9633 bool internal,
9634 bool qualified_names)
9635{
9636 if (cou)
9637 return get_class_or_union_flat_representation(*cou, indent, one_line,
9638 internal, qualified_names);
9639 return "";
9640}
9641
9642/// Get the flat representation of an instance of @ref class_or_union
9643/// type.
9644///
9645/// The flat representation of a given @ref class_or_union type is the
9646/// actual definition of the type, for instance:
9647///
9648/// struct foo {int a; char b;}
9649///
9650///@param cou the instance of @ref class_or_union to consider.
9651///
9652///@param indent the identation spaces to use in the representation.
9653///
9654///@param one_line if true, then the flat representation stands on one
9655///line. Otherwise, it stands on multiple lines.
9656///
9657///@return the resulting flat representation.
9658string
9659get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9660 const string& indent,
9661 bool one_line,
9662 bool internal,
9663 bool qualified_names)
9665 indent,
9666 one_line,
9667 internal,
9668 qualified_names);}
9669
9670/// Get the flat representation of an instance of @ref enum_type_decl
9671/// type.
9672///
9673/// The flat representation of a given @ref enum_type_decl type is the
9674/// actual definition of the type, for instance:
9675///
9676/// enum {E_0 =0, E_1 = 1}
9677///
9678///@param enum_type the enum type to consider.
9679///
9680///@param indent the identation spaces to use in the representation.
9681///
9682///@param one_line if true, then the flat representation stands on one
9683///line. Otherwise, it stands on multiple lines.
9684///
9685///@param qualified_names use qualified names when applicable.
9686///Typically, if this is true, the name of the enum is going to be
9687///qualified.
9688///
9689///@return the resulting flat representation.
9690string
9692 const string& indent, bool one_line,
9693 bool qualified_names)
9694{
9695 string repr;
9696 std::ostringstream o;
9697 string local_indent = " ";
9698
9699 repr = indent + "enum ";
9700
9701 if (!enum_type.get_is_anonymous())
9702 o << (qualified_names
9703 ? enum_type.get_qualified_name()
9704 : enum_type.get_name()) + " ";
9705
9706 o << "{";
9707
9708 if (!one_line)
9709 o << "\n";
9710
9711 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9712 {
9713 if (!one_line)
9714 o << "\n" + indent;
9715
9716 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9717 }
9718
9719 if (!one_line)
9720 o << "\n" + indent << "}";
9721 else
9722 o << "}";
9723
9724 repr =o.str();
9725
9726 return repr;
9727}
9728
9729/// Get the flat representation of an instance of @ref enum_type_decl
9730/// type.
9731///
9732/// The flat representation of a given @ref enum_type_decl type is the
9733/// actual definition of the type, for instance:
9734///
9735/// enum {E_0 =0, E_1 = 1}
9736///
9737///@param enum_type the enum type to consider.
9738///
9739///@param indent the identation spaces to use in the representation.
9740///
9741///@param one_line if true, then the flat representation stands on one
9742///line. Otherwise, it stands on multiple lines.
9743///
9744///@param qualified_names use qualified names when applicable.
9745///Typically, if this is true, the name of the enum is going to be
9746///qualified.
9747///
9748///@return the resulting flat representation.
9749string
9751 const string& indent, bool one_line,
9752 bool qualified_names)
9753{
9754 if (!enum_type)
9755 return "";
9756
9757 return get_enum_flat_representation(*enum_type, indent,
9758 one_line, qualified_names);
9759}
9760
9761/// Get the flat representation of an instance of @ref enum_type_decl
9762/// type.
9763///
9764/// The flat representation of a given @ref enum_type_decl type is the
9765/// actual definition of the type, for instance:
9766///
9767/// enum {E_0 =0, E_1 = 1}
9768///
9769///@param enum_type the enum type to consider.
9770///
9771///@param indent the identation spaces to use in the representation.
9772///
9773///@param one_line if true, then the flat representation stands on one
9774///line. Otherwise, it stands on multiple lines.
9775///
9776///@param qualified_names use qualified names when applicable.
9777///Typically, if this is true, the name of the enum is going to be
9778///qualified.
9779///
9780///@return the resulting flat representation.
9781string
9783 const string& indent, bool one_line,
9784 bool qualified_names)
9785{
9786 return get_enum_flat_representation(enum_type.get(),
9787 indent, one_line,
9788 qualified_names);
9789}
9790
9791/// Get the flat representation of an instance of @ref enum_type_decl
9792/// type.
9793///
9794/// The flat representation of a given @ref enum_type_decl type is the
9795/// actual definition of the type, for instance:
9796///
9797/// enum {E_0 =0, E_1 = 1}
9798///
9799///@param enum_type the enum type to consider.
9800///
9801///@param indent the identation spaces to use in the representation.
9802///
9803///@param one_line if true, then the flat representation stands on one
9804///line. Otherwise, it stands on multiple lines.
9805///
9806///@param qualified_names use qualified names when applicable.
9807///Typically, if this is true, the name of the enum is going to be
9808///qualified.
9809///
9810///@return the resulting flat representation.
9811string
9813 const string& indent,
9814 bool one_line,
9815 bool internal,
9816 bool qualified_name)
9817
9818{
9819 string repr;
9820 if (const class_or_union* cou = is_class_or_union_type(&coe))
9821 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9822 internal, qualified_name);
9823 else if (const enum_type_decl* enom = is_enum_type(&coe))
9824 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9825
9826 return repr;
9827}
9828
9829/// Get the textual representation of a type for debugging purposes.
9830///
9831/// If the type is a class/union, this shows the data members, virtual
9832/// member functions, size, pointer value of its canonical type, etc.
9833/// Otherwise, this just shows the name of the artifact as returned by
9834/// type_or_decl_base:get_pretty_representation().
9835///
9836/// @param artifact the artifact to show a debugging representation of.
9837///
9838/// @return a debugging string representation of @p artifact.
9839string
9841{
9842 string nil_str;
9843 if (!artifact)
9844 return nil_str;
9845
9846 class_or_union * c = is_class_or_union_type(artifact);
9847 if (c)
9848 {
9849 class_decl *clazz = is_class_type(c);
9850 string name = c->get_qualified_name();
9851 std::ostringstream o;
9852 if (clazz)
9853 {
9854 if (clazz->is_struct())
9855 o << "struct ";
9856 else
9857 o << "class ";
9858 }
9859 else if (is_union_type(c))
9860 o << "union ";
9861 o << name;
9862
9863 if (clazz)
9864 {
9865 if (!clazz->get_base_specifiers().empty())
9866 o << " :" << std::endl;
9867 for (auto &b : clazz->get_base_specifiers())
9868 {
9869 o << " ";
9870 if (b->get_is_virtual())
9871 o << "virtual ";
9872 o << b->get_base_class()->get_qualified_name()
9873 << " // hash: ";
9874 hash_t h = peek_hash_value(*b->get_base_class());
9875 if (h)
9876 o << std::hex << *h << std::dec;
9877 else
9878 o << "none";
9879 o << std::endl;
9880 }
9881 }
9882 o << std::endl
9883 << "{"
9884 << " // size in bits: " << c->get_size_in_bits() << "\n"
9885 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9886 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9887 << " // translation unit: "
9888 << (c->get_translation_unit()
9890 : nil_str)
9891 << std::endl
9892 << " // @: " << std::hex << is_type(c)
9893 << ", @canonical: " << c->get_canonical_type().get() << std::dec << "\n"
9894 << " // hash: " ;
9895
9896 hash_t h = peek_hash_value(*c);
9897 if (h)
9898 o << std::hex << *h << std::dec;
9899 else
9900 o << "none";
9901 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*c);
9902 o << "\n\n";
9903
9904
9905 for (auto member_type : c->get_sorted_member_types())
9906 {
9907 o << " "
9908 << member_type->get_pretty_representation(/*internal=*/false,
9909 /*qualified=*/false)
9910 << ";";
9911 if (member_type->get_canonical_type())
9912 {
9913 o << " // uses canonical type: '@"
9914 << std::hex << member_type->get_canonical_type().get() << "'";
9915 o << " / h:";
9916 hash_t h = peek_hash_value(*member_type);
9917 o << std::hex << *h << std::dec;
9918 if (get_canonical_type_index(*member_type))
9919 o << "#" << get_canonical_type_index(*member_type);
9920 }
9921 o << "\n";
9922 }
9923
9924 if (!c->get_sorted_member_types().empty())
9925 o << std::endl;
9926
9927 for (auto m : c->get_data_members())
9928 {
9929 type_base_sptr t = m->get_type();
9931
9932 o << " "
9933 << m->get_pretty_representation(/*internal=*/false,
9934 /*qualified=*/false)
9935 << ";";
9936
9937 if (t && t->get_canonical_type())
9938 o << " // uses canonical type '@"
9939 << std::hex << t->get_canonical_type().get() << "'";
9940
9941 o << "/ h:";
9942 hash_t h = peek_hash_value(*m->get_type());
9943 if (h)
9944 o << std::hex << *h << std::dec;
9945 else
9946 o << "none";
9947 o << std::endl;
9948 }
9949
9950 if (!c->get_data_members().empty())
9951 o << std::endl;
9952
9953 if (clazz && clazz->has_vtable())
9954 {
9955 o << " // virtual member functions\n\n";
9956 for (auto f : clazz->get_virtual_mem_fns())
9957 {
9958 o << " " << f->get_pretty_representation(/*internal=*/false,
9959 /*qualified=*/false)
9960 << " // voffset: " << get_member_function_vtable_offset(f)
9961 << ", h: ";
9962 hash_t h = peek_hash_value(*f->get_type());
9963 if (h)
9964 o << std::hex << *h << std::dec;
9965 else
9966 o << "none";
9967 o << ";" << std::endl;
9968 }
9969 }
9970
9971 o << "};" << std::endl;
9972
9973 return o.str();
9974 }
9975 else if (const enum_type_decl* e = is_enum_type(artifact))
9976 {
9977 string name = e->get_qualified_name();
9978 std::ostringstream o;
9979 o << "enum " << name
9980 << " : "
9981 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9982 true)
9983 << "\n"
9984 << "{\n"
9985 << " // size in bits: " << e->get_size_in_bits() << "\n"
9986 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9987 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9988 << " // translation unit: "
9989 << e->get_translation_unit()->get_absolute_path() << "\n"
9990 << " // @: " << std::hex << is_type(e)
9991 << ", @canonical: " << e->get_canonical_type().get() << std::dec << "\n"
9992 << " // hash: ";
9993
9994 hash_t h = peek_hash_value(*e);
9995 if (h)
9996 o << std::hex << *h << std::dec;
9997 else
9998 o << "none";
9999 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*e);
10000 o << "\n\n";
10001
10002 for (const auto &enom : e->get_enumerators())
10003 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
10004
10005 o << "};\n";
10006
10007 return o.str();
10008 }
10009 else if (type_base *t = is_type(artifact))
10010 {
10011 std::ostringstream o;
10012 o << t->get_pretty_representation(/*internal=*/true,
10013 /*qualified=*/true)
10014 << " // cti: " << get_canonical_type_index(*t)
10015 << "\n";
10016 return o.str();
10017 }
10018
10019 return artifact->get_pretty_representation(/*internal=*/true,
10020 /*qualified=*/true);
10021}
10022
10023/// Get a given data member, referred to by its name, of a class type.
10024///
10025/// @param clazz the class to consider.
10026///
10027/// @param member_name name of the data member to get.
10028///
10029/// @return the resulting data member or nullptr if none was found.
10031get_data_member(class_or_union *clazz, const char* member_name)
10032{
10033 if (!clazz)
10034 return var_decl_sptr();
10035 return clazz->find_data_member(member_name);
10036}
10037
10038/// Get a given data member, referred to by its name, of a class type.
10039///
10040/// @param clazz the class to consider.
10041///
10042/// @param member_name name of the data member to get.
10043///
10044/// @return the resulting data member or nullptr if none was found.
10046get_data_member(type_base *clazz, const char* member_name)
10047{return get_data_member(is_class_or_union_type(clazz), member_name);}
10048
10049/// Get the non-artificial (natural) location of a decl.
10050///
10051/// If the decl doesn't have a natural location then return its
10052/// artificial one.
10053///
10054/// @param decl the decl to consider.
10055///
10056/// @return the natural location @p decl if it has one; otherwise,
10057/// return its artificial one.
10058const location&
10060{
10061 ABG_ASSERT(decl);
10062
10063 if (decl->get_location())
10064 return decl->get_location();
10065 return decl->get_artificial_location();
10066}
10067
10068/// Get the artificial location of a decl.
10069///
10070/// If the decl doesn't have an artificial location then return its
10071/// natural one.
10072///
10073/// @param decl the decl to consider.
10074///
10075/// @return the artificial location @p decl if it has one; otherwise,
10076/// return its natural one.
10077const location&
10079{
10080 ABG_ASSERT(decl);
10081
10082 if (decl->has_artificial_location())
10083 return decl->get_artificial_location();
10084 return decl->get_location();
10085}
10086
10087/// Emit a textual representation of an artifact to std error stream
10088/// for debugging purposes.
10089///
10090/// This is useful to invoke from within a command line debugger like
10091/// GDB to help make sense of a given ABI artifact.
10092///
10093/// @param artifact the ABI artifact to emit the debugging
10094/// representation for.
10095///
10096/// @return the artifact @p artifact.
10098debug(const type_or_decl_base* artifact)
10099{
10100 std::cerr << get_debug_representation(artifact) << std::endl;
10101 return const_cast<type_or_decl_base*>(artifact);
10102}
10103
10104/// Emit a textual representation of an artifact to std error stream
10105/// for debugging purposes.
10106///
10107/// This is useful to invoke from within a command line debugger like
10108/// GDB to help make sense of a given ABI artifact.
10109///
10110/// @param artifact the ABI artifact to emit the debugging
10111/// representation for.
10112///
10113/// @return the artifact @p artifact.
10114type_base*
10115debug(const type_base* artifact)
10116{
10117 debug(static_cast<const type_or_decl_base*>(artifact));
10118 return const_cast<type_base*>(artifact);
10119}
10120
10121/// Emit a textual representation of an artifact to std error stream
10122/// for debugging purposes.
10123///
10124/// This is useful to invoke from within a command line debugger like
10125/// GDB to help make sense of a given ABI artifact.
10126///
10127/// @param artifact the ABI artifact to emit the debugging
10128/// representation for.
10129///
10130/// @return the artifact @p artifact.
10131decl_base*
10132debug(const decl_base* artifact)
10133{
10134 debug(static_cast<const type_or_decl_base*>(artifact));
10135 return const_cast<decl_base*>(artifact);
10136}
10137
10138/// Test if two ABI artifacts are equal.
10139///
10140/// This can be useful when used from the command line of a debugger
10141/// like GDB.
10142///
10143/// @param l the first ABI artifact to consider in the comparison.
10144///
10145/// @param r the second ABI artifact to consider in the comparison.
10146///
10147/// @return true iff @p l equals @p r.
10148bool
10150{
10151 if (!!l != !!r)
10152 return false;
10153 if (!l && !r)
10154 return true;
10155
10156 return (*l == *r);
10157}
10158
10159/// Emit a trace of a comparison operand stack.
10160///
10161/// @param vect the operand stack to emit the trace for.
10162///
10163/// @param o the output stream to emit the trace to.
10164static void
10165debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10166{
10167 for (auto t : vect)
10168 {
10169 o << "|" << t->get_pretty_representation()
10170 << "@" << std::hex << t << std::dec;
10171 }
10172 if (!vect.empty())
10173 o << "|";
10174}
10175
10176/// Construct a trace of the two comparison operand stacks.
10177///
10178/// @param the environment in which the comparison operand stacks are.
10179///
10180/// @return a string representing the trace.
10181static string
10182print_comp_stack(const environment& env)
10183{
10184 std::ostringstream o;
10185 o << "left-operands: ";
10186 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10187 o << "\n" << "right-operands: ";
10188 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10189 o << "\n";
10190 return o.str();
10191}
10192
10193/// Emit a trace of the two comparison operands stack on the standard
10194/// error stream.
10195///
10196/// @param env the environment the comparison operands stack belong
10197/// to.
10198void
10200{
10201 std::cerr << print_comp_stack(env);
10202 std::cerr << std::endl;
10203}
10204
10205/// By looking at the language of the TU a given ABI artifact belongs
10206/// to, test if the ONE Definition Rule should apply.
10207///
10208/// To date, it applies to c++, java and ada.
10209///
10210/// @param artifact the ABI artifact to consider.
10211///
10212/// @return true iff the One Definition Rule should apply.
10213bool
10215{
10216 if (!artifact.get_translation_unit())
10217 return false;
10218
10220 artifact.get_translation_unit()->get_language();
10221
10223 || is_java_language(l)
10224 || is_ada_language(l))
10225 return true;
10226
10227 return false;
10228}
10229
10230/// Get the declaration for a given type.
10231///
10232/// @param t the type to consider.
10233///
10234/// @return the declaration for the type to return.
10235const decl_base*
10237{return dynamic_cast<const decl_base*>(t);}
10238
10239/// Get the declaration for a given type.
10240///
10241/// @param t the type to consider.
10242///
10243/// @return the declaration for the type to return.
10244decl_base*
10246{return dynamic_cast<decl_base*>(t);}
10247
10248/// Get the declaration for a given type.
10249///
10250/// @param t the type to consider.
10251///
10252/// @return the declaration for the type to return.
10253decl_base_sptr
10254get_type_declaration(const type_base_sptr t)
10255{return dynamic_pointer_cast<decl_base>(t);}
10256
10257/// Test if two classes have the same layout.
10258///
10259/// Test if all the types and offsets of the members are equal,
10260/// regardless of their access modifiers.
10261///
10262/// @param f the first class to take into account.
10263///
10264/// @param s the second class to take into account.
10265///
10266/// @return true iff @p s and @p f are class types with the same
10267/// layout.
10268bool
10269classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
10270{
10271#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10272#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10273#endif
10274
10275#ifdef ENSURE_NO_ENDLESS_LOOP
10276#undef ENSURE_NO_ENDLESS_LOOP
10277#endif
10278
10279#define RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(VALUE) \
10280 do \
10281 { \
10282 auto t1 = is_class_or_union_type(f); \
10283 auto t2 = is_class_or_union_type(s); \
10284 t1->priv_->comparing_class_layouts_.erase(t2.get()); \
10285 t2->priv_->comparing_class_layouts_.erase(t1.get()); \
10286 return VALUE; \
10287 } while (false)
10288
10289#define ENSURE_NO_ENDLESS_LOOP \
10290 do \
10291 { \
10292 auto t1 = is_class_or_union_type(f); \
10293 auto t2 = is_class_or_union_type(s); \
10294 const auto& END = t1->priv_->comparing_class_layouts_.end(); \
10295 if (t1->priv_->comparing_class_layouts_.find(t2.get()) != END \
10296 || t2->priv_->comparing_class_layouts_.find(t1.get()) != END) \
10297 return true; \
10298 t1->priv_->comparing_class_layouts_.insert(t2.get()); \
10299 t2->priv_->comparing_class_layouts_.insert(t1.get()); \
10300 } while (false)
10301
10304
10305 if (!fc
10306 || !sc
10307 || (fc->get_qualified_name() != sc->get_qualified_name())
10308 || (fc->get_size_in_bits() != sc->get_size_in_bits())
10309 || (fc->get_data_members().size() != sc->get_data_members().size()))
10310 return false;
10311
10312 if (*fc == *sc)
10313 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
10314
10315 // Compare the types and offsets of data members one by one.
10316 for (auto f_decl_it = fc->get_data_members().begin(),
10317 s_decl_it = sc->get_data_members().begin();
10318 (f_decl_it != fc->get_data_members().end()
10319 && s_decl_it != sc->get_data_members().end());
10320 ++f_decl_it, ++s_decl_it)
10321 {
10322 var_decl_sptr dm1 = *f_decl_it, dm2 = *s_decl_it;
10323 type_base_sptr dm1_type = dm1->get_type(), dm2_type = dm2->get_type();
10324
10325 if (*dm1_type != *dm2_type
10327 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10328 }
10329
10330 // Compare the layout of base types
10331 for (auto f_bs_it = fc->get_base_specifiers().begin(),
10332 s_bs_it = sc->get_base_specifiers().end();
10333 (f_bs_it != fc->get_base_specifiers().end()
10334 && s_bs_it != sc->get_base_specifiers().end());
10335 ++f_bs_it, ++s_bs_it)
10336 {
10337 class_decl::base_spec_sptr f_bs = *f_bs_it, s_bs = *s_bs_it;
10338 if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
10339 || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
10340 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10341
10342 class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
10343 if (!classes_have_same_layout(fb, sb))
10344 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10345 }
10346
10347 if (fc->has_vtable() != sc->has_vtable())
10348 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10349
10350 // Compare virtual function types
10351 ENSURE_NO_ENDLESS_LOOP;
10352 if (fc->has_vtable())
10353 {
10354 if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
10355 // Some virtual member function got removed. Bad.
10356 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10357
10358 for (auto it1 = fc->get_virtual_mem_fns().begin(),
10359 it2 = sc->get_virtual_mem_fns().begin();
10360 (it1 != fc->get_virtual_mem_fns().end()
10361 && it2 != sc->get_virtual_mem_fns().end());
10362 ++it1, ++it2)
10363 {
10364 method_decl_sptr method1 = *it1;
10365 method_decl_sptr method2 = *it2;
10366
10369 || !types_are_compatible(method1->get_type(),
10370 method2->get_type()))
10371 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10372 }
10373 }
10374
10375 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
10376
10377#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10378#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10379#endif
10380
10381#ifdef ENSURE_NO_ENDLESS_LOOP
10382#undef ENSURE_NO_ENDLESS_LOOP
10383#endif
10384}
10385
10386/// Test if two types are equal modulo a typedef or CV qualifiers.
10387///
10388/// Type A and B are compatible if
10389///
10390/// - A and B are equal
10391/// - or A and B are integral types with harmless name change
10392/// - or if one type is a typedef of the other one.
10393/// - or if one type is the CV qualified version of the other
10394/// - or if A and B are classes with the same layout.
10395/// - or if A and B are pointers, references or arrays of
10396/// compatible types
10397///
10398/// @param type1 the first type to consider.
10399///
10400/// @param type2 the second type to consider.
10401///
10402/// @return true iff @p type1 and @p type2 are compatible.
10403bool
10404types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
10405{
10406 if (!type1 || !type2)
10407 return false;
10408
10409 if (type1 == type2 || *type1 == *type2)
10410 return true;
10411
10412 type_base_sptr t1 = peel_qualified_or_typedef_type(type1);
10413 type_base_sptr t2 = peel_qualified_or_typedef_type(type2);
10414
10415 if (t1 && t2 && *t1 == *t2)
10416 return true;
10417
10419 return true;
10420
10421 if (is_pointer_type(t1) && is_pointer_type(t2))
10422 {
10425 return types_are_compatible(t1, t2);
10426 }
10427
10428 if (is_reference_type(t1) && is_reference_type(t2))
10429 {
10430 t1 = is_reference_type(t1)->get_pointed_to_type();
10431 t2 = is_reference_type(t2)->get_pointed_to_type();
10432 return types_are_compatible(t1, t2);
10433 }
10434
10435 if (is_array_type(t1) && is_array_type(t2))
10436 {
10439 type_base_sptr e1 = a1->get_element_type();
10440 type_base_sptr e2 = a2->get_element_type();
10443
10444 if ((a1->get_size_in_bits() != a2->get_size_in_bits())
10445 || (a1->get_dimension_count() != a2->get_dimension_count())
10446 || !types_are_compatible(e1, e2))
10447 return false;
10448
10449 return true;
10450 }
10451
10452 if (function_type_sptr fn_type1 = is_function_type(t1))
10453 if (function_type_sptr fn_type2 = is_function_type(t2))
10454 {
10455 // Compare return types
10456 if (!types_are_compatible(fn_type1->get_return_type(),
10457 fn_type2->get_return_type()))
10458 return false;
10459
10460 // Compare parameter types, omitting the implicit parameter to
10461 // avoid infinite recursion when we are being called from
10462 // classes_have_same_layout on classes with virtual member
10463 // functions.
10464 if (fn_type1->get_parameters().size()
10465 != fn_type2->get_parameters().size())
10466 return false;
10467
10468 for (auto p1 = fn_type1->get_first_non_implicit_parm(),
10469 p2 = fn_type2->get_first_non_implicit_parm();
10470 (p1 != fn_type1->get_parameters().end()
10471 && p2 != fn_type2->get_parameters().end());
10472 ++p1, ++p2)
10473 if (!types_are_compatible((*p1)->get_type(),
10474 (*p2)->get_type()))
10475 return false;
10476
10477 return true;
10478 }
10479
10480 if (classes_have_same_layout(t1, t2))
10481 return true;
10482
10483 return false;
10484}
10485
10486/// Test if two types are equal modulo a typedef.
10487///
10488/// Type A and B are compatible if
10489///
10490/// - A and B are equal
10491/// - or if one type is a typedef of the other one.
10492///
10493/// @param type1 the declaration of the first type to consider.
10494///
10495/// @param type2 the declaration of the second type to consider.
10496///
10497/// @return true iff @p type1 and @p type2 are compatible.
10498bool
10499types_are_compatible(const decl_base_sptr d1,
10500 const decl_base_sptr d2)
10501{return types_are_compatible(is_type(d1), is_type(d2));}
10502
10503/// Return the translation unit a declaration belongs to.
10504///
10505/// @param decl the declaration to consider.
10506///
10507/// @return the resulting translation unit, or null if the decl is not
10508/// yet added to a translation unit.
10511{
10512 translation_unit* result =
10513 const_cast<translation_unit*>(t.get_translation_unit());
10514
10515 if (result)
10516 return result;
10517
10518 if (decl_base* decl = is_decl(&t))
10519 {
10520 scope_decl* scope = decl->get_scope();
10521 while (scope)
10522 {
10523 result = scope->get_translation_unit();
10524 if (result)
10525 break;
10526 scope = scope->get_scope();
10527 }
10528 }
10529
10530 return result;
10531}
10532
10533/// Return the translation unit a declaration belongs to.
10534///
10535/// @param decl the declaration to consider.
10536///
10537/// @return the resulting translation unit, or null if the decl is not
10538/// yet added to a translation unit.
10541{return decl ? get_translation_unit(*decl) : nullptr;}
10542
10543/// Return the translation unit a declaration belongs to.
10544///
10545/// @param decl the declaration to consider.
10546///
10547/// @return the resulting translation unit, or null if the decl is not
10548/// yet added to a translation unit.
10552
10553/// Tests whether if a given scope is the global scope.
10554///
10555/// @param scope the scope to consider.
10556///
10557/// @return true iff the current scope is the global one.
10558bool
10560{return !!dynamic_cast<const global_scope*>(&scope);}
10561
10562/// Tests whether if a given scope is the global scope.
10563///
10564/// @param scope the scope to consider.
10565///
10566/// @return the @ref global_scope* representing the scope @p scope or
10567/// 0 if @p scope is not a global scope.
10568const global_scope*
10570{return dynamic_cast<const global_scope*>(scope);}
10571
10572/// Tests whether if a given scope is the global scope.
10573///
10574/// @param scope the scope to consider.
10575///
10576/// @return true iff the current scope is the global one.
10577bool
10578is_global_scope(const shared_ptr<scope_decl>scope)
10579{return is_global_scope(scope.get());}
10580
10581/// Tests whether a given declaration is at global scope.
10582///
10583/// @param decl the decl to consider.
10584///
10585/// @return true iff decl is at global scope.
10586bool
10588{return (is_global_scope(decl.get_scope()));}
10589
10590/// Tests whether a given declaration is at global scope.
10591///
10592/// @param decl the decl to consider.
10593///
10594/// @return true iff decl is at global scope.
10595bool
10596is_at_global_scope(const decl_base_sptr decl)
10597{return (decl && is_global_scope(decl->get_scope()));}
10598
10599/// Tests whether a given declaration is at global scope.
10600///
10601/// @param decl the decl to consider.
10602///
10603/// @return true iff decl is at global scope.
10604bool
10606{return decl && is_at_global_scope(*decl);}
10607
10608/// Tests whether a given decl is at class scope.
10609///
10610/// @param decl the decl to consider.
10611///
10612/// @return true iff decl is at class scope.
10614is_at_class_scope(const decl_base_sptr decl)
10615{return is_at_class_scope(decl.get());}
10616
10617/// Tests whether a given decl is at class scope.
10618///
10619/// @param decl the decl to consider.
10620///
10621/// @return true iff decl is at class scope.
10624{
10625 if (!decl)
10626 return nullptr;
10627
10628 return is_at_class_scope(*decl);
10629}
10630
10631/// Tests whether a given decl is at class scope.
10632///
10633/// @param decl the decl to consider.
10634///
10635/// @return true iff decl is at class scope.
10638{
10639 scope_decl* scope = decl.get_scope();
10640 if (!scope)
10641 return nullptr;
10642
10643 if (class_or_union* cl = is_class_type(scope))
10644 return cl;
10645 if (class_or_union* cl = is_union_type(scope))
10646 return cl;
10647 return 0;
10648}
10649
10650/// Find a data member inside an anonymous data member.
10651///
10652/// An anonymous data member has a type which is a class or union.
10653/// This function looks for a data member inside the type of that
10654/// anonymous data member.
10655///
10656/// @param anon_dm the anonymous data member to consider.
10657///
10658/// @param name the name of the data member to look for.
10661 const string& name)
10662{
10663 const class_or_union* containing_class_or_union =
10665
10666 if (!containing_class_or_union)
10667 return var_decl_sptr();
10668
10669 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10670 return result;
10671}
10672
10673/// Tests whether a given decl is at template scope.
10674///
10675/// Note that only template parameters , types that are compositions,
10676/// and template patterns (function or class) can be at template scope.
10677///
10678/// @param decl the decl to consider.
10679///
10680/// @return true iff the decl is at template scope.
10681bool
10682is_at_template_scope(const shared_ptr<decl_base> decl)
10683{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10684
10685/// Tests whether a decl is a template parameter.
10686///
10687/// @param decl the decl to consider.
10688///
10689/// @return true iff decl is a template parameter.
10690bool
10691is_template_parameter(const shared_ptr<decl_base> decl)
10692{
10693 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10694 || dynamic_pointer_cast<non_type_tparameter>(decl)
10695 || dynamic_pointer_cast<template_tparameter>(decl)));
10696}
10697
10698/// Test whether a declaration is a @ref function_decl.
10699///
10700/// @param d the declaration to test for.
10701///
10702/// @return a shared pointer to @ref function_decl if @p d is a @ref
10703/// function_decl. Otherwise, a nil shared pointer.
10706{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10707
10708/// Test whether a declaration is a @ref function_decl.
10709///
10710/// @param d the declaration to test for.
10711///
10712/// @return true if @p d is a function_decl.
10713bool
10716
10717/// Test whether a declaration is a @ref function_decl.
10718///
10719/// @param d the declaration to test for.
10720///
10721/// @return a shared pointer to @ref function_decl if @p d is a @ref
10722/// function_decl. Otherwise, a nil shared pointer.
10725{return dynamic_pointer_cast<function_decl>(d);}
10726
10727/// Test whether a declaration is a @ref function_decl.
10728///
10729/// @param d the declaration to test for.
10730///
10731/// @return a pointer to @ref function_decl if @p d is a @ref
10732/// function_decl. Otherwise, a nil shared pointer.
10735{
10736 return dynamic_cast<function_decl::parameter*>
10737 (const_cast<type_or_decl_base*>(tod));
10738}
10739
10740/// Test whether an ABI artifact is a @ref function_decl.
10741///
10742/// @param tod the declaration to test for.
10743///
10744/// @return a pointer to @ref function_decl if @p d is a @ref
10745/// function_decl. Otherwise, a nil shared pointer.
10748{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10749
10750/// Test if an ABI artifact is a declaration.
10751///
10752/// @param d the artifact to consider.
10753///
10754/// @param return the declaration sub-object of @p d if it's a
10755/// declaration, or NULL if it is not.
10756decl_base*
10757is_decl(const type_or_decl_base* d)
10758{
10759 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10760 {
10761 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10762 // The artifact is a decl-only (like a function or a
10763 // variable). That is, it's not a type that also has a
10764 // declaration. In this case, we are in the fast path and we
10765 // have a pointer to the decl sub-object handy. Just return
10766 // it ...
10767 return reinterpret_cast<decl_base*>
10768 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10769
10770 // ... Otherwise, we are in the slow path, which is that the
10771 // artifact is a type which has a declaration. In that case,
10772 // let's use the slow dynamic_cast because we don't have the
10773 // pointer to the decl sub-object handily present.
10774 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10775 }
10776 return 0;
10777}
10778
10779/// Test if an ABI artifact is a declaration.
10780///
10781/// @param d the artifact to consider.
10782///
10783/// @param return the declaration sub-object of @p d if it's a
10784/// declaration, or NULL if it is not.
10785decl_base_sptr
10787{return dynamic_pointer_cast<decl_base>(d);}
10788
10789/// Test if an ABI artifact is a declaration.
10790///
10791/// This is done using a slow path that uses dynamic_cast.
10792///
10793/// @param d the artifact to consider.
10794///
10795/// @param return the declaration sub-object of @p d if it's a
10796decl_base*
10798{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10799
10800/// Test if an ABI artifact is a declaration.
10801///
10802/// This is done using a slow path that uses dynamic_cast.
10803///
10804/// @param d the artifact to consider.
10805///
10806/// @param return the declaration sub-object of @p d if it's a
10807decl_base_sptr
10809{return dynamic_pointer_cast<decl_base>(t);}
10810
10811/// Test whether a declaration is a type.
10812///
10813/// @param d the IR artefact to test for.
10814///
10815/// @return true if the artifact is a type, false otherwise.
10816bool
10818{
10819 if (dynamic_cast<const type_base*>(&tod))
10820 return true;
10821 return false;
10822}
10823
10824/// Test whether a declaration is a type.
10825///
10826/// @param d the IR artefact to test for.
10827///
10828/// @return true if the artifact is a type, false otherwise.
10829type_base*
10830is_type(const type_or_decl_base* t)
10831{
10832 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10833 return reinterpret_cast<type_base*>
10834 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10835
10836 return 0;
10837}
10838
10839/// Test whether a declaration is a type.
10840///
10841/// @param d the IR artefact to test for.
10842///
10843/// @return true if the artifact is a type, false otherwise.
10844type_base_sptr
10846{return dynamic_pointer_cast<type_base>(tod);}
10847
10848/// Test whether a declaration is a type.
10849///
10850/// @param d the declaration to test for.
10851///
10852/// @return true if the declaration is a type, false otherwise.
10853
10854/// Test if a given type is anonymous.
10855///
10856/// Note that this function considers that an anonymous class that is
10857/// named by a typedef is not anonymous anymore. This is the C idiom:
10858///
10859/// typedef struct {int member;} s_type;
10860///
10861/// The typedef s_type becomes the name of the originally anonymous
10862/// struct.
10863///
10864/// @param t the type to consider.
10865///
10866/// @return true iff @p t is anonymous.
10867bool
10869{
10870 const decl_base* d = get_type_declaration(t);
10871 if (d)
10872 if (d->get_is_anonymous())
10873 {
10875 {
10876 // An anonymous class that is named by a typedef is not
10877 // considered anonymous anymore.
10878 if (!cou->get_naming_typedef())
10879 return true;
10880 }
10881 else
10882 return true;
10883 }
10884 return false;
10885}
10886
10887/// Test if a given type is anonymous.
10888///
10889/// @param t the type to consider.
10890///
10891/// @return true iff @p t is anonymous.
10892bool
10893is_anonymous_type(const type_base_sptr& t)
10894{return is_anonymous_type(t.get());}
10895
10896/// Test if a type is a neither a pointer, an array nor a function
10897/// type.
10898///
10899/// @param t the type to consider.
10900///
10901/// @return true if the @p t is NOT a pointer, an array nor a
10902/// function.
10903bool
10904is_npaf_type(const type_base_sptr& t)
10905{
10906 if (!(is_pointer_type(t)
10907 || is_array_type(t)
10908 || is_function_type(t)
10909 || is_ptr_to_mbr_type(t)))
10910 return true;
10911 return false;
10912}
10913
10914/// Test whether a type is a type_decl (a builtin type).
10915///
10916/// @return the type_decl* for @t if it's type_decl, otherwise, return
10917/// nil.
10918const type_decl*
10920{return dynamic_cast<const type_decl*>(t);}
10921
10922/// Test whether a type is a type_decl (a builtin type).
10923///
10924/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10925/// return nil.
10928{return dynamic_pointer_cast<type_decl>(t);}
10929
10930/// Test if a type is a real type.
10931///
10932/// @param t the type to test.
10933///
10934/// @return the real type @p t can be converted to, or nil if @p
10935/// is not a real type.
10936type_decl*
10938{
10939 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10940 if (!type)
10941 return nullptr;
10942
10943 real_type int_type;
10944 if (!parse_real_type(type->get_name(), int_type))
10945 return nullptr;
10946
10947 return type;
10948}
10949
10950/// Test if a type is a real type.
10951///
10952/// @param t the type to test.
10953///
10954/// @return the real type @p t can be converted to, or nil if @p is
10955/// not a real type.
10958{
10959 const type_decl_sptr type = is_type_decl(t);
10960 if (!type)
10961 return type_decl_sptr();
10962
10963 real_type int_type;
10964 if (!parse_real_type(type->get_name(), int_type))
10965 return type_decl_sptr();
10966
10967 return type;
10968}
10969
10970/// Test if a type is an integral type.
10971///
10972/// @param t the type to test.
10973///
10974/// @return the integral type @p t can be converted to, or nil if @p
10975/// is not an integral type.
10976type_decl*
10978{
10979 type_decl* type = is_real_type(t);
10980 if (!type)
10981 return nullptr;
10982
10983 real_type rt;
10984 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10987 return nullptr;
10988
10989 return type;
10990}
10991
10992/// Test if a type is an integral type.
10993///
10994/// @param t the type to test.
10995///
10996/// @return the integral type @p t can be converted to, or nil if @p
10997/// is not an integral type.
11000{
11001 type_decl_sptr type = is_real_type(t);
11002 if (!type)
11003 return type;
11004
11005 real_type rt;
11006 ABG_ASSERT(parse_real_type(type->get_name(), rt));
11009 return type_decl_sptr();
11010
11011 return type;
11012}
11013
11014/// Test whether a type is a typedef.
11015///
11016/// @param t the type to test for.
11017///
11018/// @return the typedef declaration of the @p t, or NULL if it's not a
11019/// typedef.
11022{return dynamic_pointer_cast<typedef_decl>(t);}
11023
11024/// Test whether a type is a typedef.
11025///
11026/// @param t the declaration of the type to test for.
11027///
11028/// @return the typedef declaration of the @p t, or NULL if it's not a
11029/// typedef.
11030const typedef_decl*
11032{return dynamic_cast<const typedef_decl*>(t);}
11033
11034/// Test whether a type is a typedef.
11035///
11036/// @param t the declaration of the type to test for.
11037///
11038/// @return the typedef declaration of the @p t, or NULL if it's not a
11039/// typedef.
11042{return dynamic_cast<typedef_decl*>(t);}
11043
11044/// Test whether a type is a typedef.
11045///
11046/// @param t the declaration of the type to test for.
11047///
11048/// @return the typedef declaration of the @p t, or NULL if it's not a
11049/// typedef.
11050const typedef_decl*
11052{return dynamic_cast<const typedef_decl*>(t);}
11053
11054/// Test if a type is an enum. This function looks through typedefs.
11055///
11056/// @parm t the type to consider.
11057///
11058/// @return the enum_decl if @p t is an @ref enum_decl or null
11059/// otherwise.
11060const enum_type_decl*
11062{
11063 if (!t)
11064 return nullptr;
11065
11066 type_base* ty = const_cast<type_base*>(peel_typedef_type(t));
11067 return is_enum_type(ty);
11068}
11069
11070/// Test if a type is an enum. This function looks through typedefs.
11071///
11072/// @parm t the type to consider.
11073///
11074/// @return the enum_decl if @p t is an @ref enum_decl or null
11075/// otherwise.
11077is_compatible_with_enum_type(const type_base_sptr& t)
11078{
11079 if (!t)
11080 return enum_type_decl_sptr();
11081
11082 // Normally we should strip typedefs entirely, but this is
11083 // potentially costly, especially on binaries with huge changesets
11084 // like the Linux Kernel. So we just get the leaf types for now.
11085 //
11086 // Maybe there should be an option by which users accepts to pay the
11087 // CPU usage toll in exchange for finer filtering?
11088
11089 // type_base_sptr ty = strip_typedef(t);
11090 type_base_sptr ty = peel_typedef_type(t);;
11091 return is_enum_type(ty);
11092}
11093
11094/// Test if a type is an enum. This function looks through typedefs.
11095///
11096/// @parm t the type to consider.
11097///
11098/// @return the enum_decl if @p t is an @ref enum_decl or null
11099/// otherwise.
11101is_compatible_with_enum_type(const decl_base_sptr& t)
11103
11104/// Test if a decl is an enum_type_decl
11105///
11106/// @param d the decl to test for.
11107///
11108/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
11109const enum_type_decl*
11111{return dynamic_cast<const enum_type_decl*>(d);}
11112
11113/// Test if a decl is an enum_type_decl
11114///
11115/// @param d the decl to test for.
11116///
11117/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
11120{return dynamic_pointer_cast<enum_type_decl>(d);}
11121
11122/// Test if a type is a class. This function looks through typedefs.
11123///
11124/// @parm t the type to consider.
11125///
11126/// @return the class_decl if @p t is a class_decl or null otherwise.
11127const class_decl*
11129{
11130 if(!t)
11131 return nullptr;
11132
11133 const type_base* ty = peel_typedef_type(t);
11134 return is_class_type(ty);
11135}
11136
11137/// Test if a type is a class. This function looks through typedefs.
11138///
11139/// @parm t the type to consider.
11140///
11141/// @return the class_decl if @p t is a class_decl or null otherwise.
11143is_compatible_with_class_type(const type_base_sptr& t)
11144{
11145 if (!t)
11146 return class_decl_sptr();
11147
11148 // Normally we should strip typedefs entirely, but this is
11149 // potentially costly, especially on binaries with huge changesets
11150 // like the Linux Kernel. So we just get the leaf types for now.
11151 //
11152 // Maybe there should be an option by which users accepts to pay the
11153 // CPU usage toll in exchange for finer filtering?
11154
11155 // type_base_sptr ty = strip_typedef(t);
11156 type_base_sptr ty = peel_typedef_type(t);
11157 return is_class_type(ty);
11158}
11159
11160/// Test if a type is a class. This function looks through typedefs.
11161///
11162/// @parm t the type to consider.
11163///
11164/// @return the class_decl if @p t is a class_decl or null otherwise.
11166is_compatible_with_class_type(const decl_base_sptr& t)
11168
11169/// Test whether a type is a class.
11170///
11171/// @parm t the type to consider.
11172///
11173/// @return true iff @p t is a class_decl.
11174bool
11176{return is_class_type(&t);}
11177
11178/// Test whether a type is a class.
11179///
11180/// @parm t the type to consider.
11181///
11182/// @return the class_decl if @p t is a class_decl or null otherwise.
11184is_class_type(const type_or_decl_base* t)
11185{
11186 if (!t)
11187 return 0;
11188
11189 if (t->kind() & type_or_decl_base::CLASS_TYPE)
11190 return reinterpret_cast<class_decl*>
11191 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
11192
11193 return 0;
11194}
11195
11196/// Test whether a type is a class.
11197///
11198/// @parm t the type to consider.
11199///
11200/// @return the class_decl if @p t is a class_decl or null otherwise.
11203{return dynamic_pointer_cast<class_decl>(d);}
11204
11205/// Test if the last data member of a class is an array with
11206/// non-finite data member.
11207///
11208/// The flexible data member idiom is a well known C idiom:
11209/// https://en.wikipedia.org/wiki/Flexible_array_member.
11210///
11211/// @param klass the class to consider.
11212///
11213/// @return the data member which type is a flexible array, if any, or
11214/// nil.
11217{
11218 var_decl_sptr nil;
11220 if (dms.empty())
11221 return nil;
11222
11223 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11224 {// The type of the last data member is an array.
11225 if (array->is_non_finite())
11226 // The array has a non-finite size. We are thus looking at a
11227 // flexible array data member. Let's return it.
11228 return dms.back();
11229 }
11230
11231 return nil;
11232}
11233
11234/// Test if the last data member of a class is an array with
11235/// non-finite data member.
11236///
11237/// The flexible data member idiom is a well known C idiom:
11238/// https://en.wikipedia.org/wiki/Flexible_array_member.
11239///
11240/// @param klass the class to consider.
11241///
11242/// @return the data member which type is a flexible array, if any, or
11243/// nil.
11246{
11247 if (!klass)
11248 return var_decl_sptr();
11249
11250 return has_flexible_array_data_member(*klass);
11251}
11252
11253/// Test if the last data member of a class is an array with
11254/// non-finite data member.
11255///
11256/// The flexible data member idiom is a well known C idiom:
11257/// https://en.wikipedia.org/wiki/Flexible_array_member.
11258///
11259/// @param klass the class to consider.
11260///
11261/// @return the data member which type is a flexible array, if any, or
11262/// nil.
11266
11267/// Test if the last data member of a class is an array with
11268/// one element.
11269///
11270/// An array with one element is a way to mimic the flexible data
11271/// member idiom that was later standardized in C99.
11272///
11273/// To learn more about the flexible data member idiom, please
11274/// consider reading :
11275/// https://en.wikipedia.org/wiki/Flexible_array_member.
11276///
11277/// The various ways of representing that idiom pre-standardization
11278/// are presented in this article:
11279/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11280///
11281/// @param klass the class to consider.
11282///
11283/// @return the data member which type is a fake flexible array, if
11284/// any, or nil.
11287{
11288 var_decl_sptr nil;
11290 if (dms.empty())
11291 return nil;
11292
11293 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11294 {// The type of the last data member is an array.
11295 if (array->get_subranges().size() == 1
11296 && array->get_subranges()[0]->get_length() == 1)
11297 // The array has a size of one. We are thus looking at a
11298 // "fake" flexible array data member. Let's return it.
11299 return dms.back();
11300 }
11301
11302 return nil;
11303}
11304
11305/// Test if the last data member of a class is an array with
11306/// one element.
11307///
11308/// An array with one element is a way to mimic the flexible data
11309/// member idiom that was later standardized in C99.
11310///
11311/// To learn more about the flexible data member idiom, please
11312/// consider reading :
11313/// https://en.wikipedia.org/wiki/Flexible_array_member.
11314///
11315/// The various ways of representing that idiom pre-standardization
11316/// are presented in this article:
11317/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11318///
11319/// @param klass the class to consider.
11320///
11321/// @return the data member which type is a fake flexible array, if
11322/// any, or nil.
11326
11327/// Test if the last data member of a class is an array with
11328/// one element.
11329///
11330/// An array with one element is a way to mimic the flexible data
11331/// member idiom that was later standardized in C99.
11332///
11333/// To learn more about the flexible data member idiom, please
11334/// consider reading :
11335/// https://en.wikipedia.org/wiki/Flexible_array_member.
11336///
11337/// The various ways of representing that idiom pre-standardization
11338/// are presented in this article:
11339/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11340///
11341/// @param klass the class to consider.
11342///
11343/// @return the data member which type is a fake flexible array, if
11344/// any, or nil.
11348
11349/// Test wheter a type is a declaration-only class.
11350///
11351/// @param t the type to considier.
11352///
11353/// @param look_through_decl_only if true, then look through the
11354/// decl-only class to see if it actually has a class definition in
11355/// the same ABI corpus.
11356///
11357/// @return true iff @p t is a declaration-only class.
11358bool
11361{
11362 if (class_or_union *klass = is_class_or_union_type(t))
11363 {
11365 klass = look_through_decl_only_class(klass);
11366 return klass->get_is_declaration_only();
11367 }
11368 return false;
11369}
11370
11371/// Test wheter a type is a declaration-only class.
11372///
11373/// @param t the type to considier.
11374///
11375/// @param look_through_decl_only if true, then look through the
11376/// decl-only class to see if it actually has a class definition in
11377/// the same ABI corpus.
11378///
11379/// @return true iff @p t is a declaration-only class.
11380bool
11384
11385/// Test wheter a type is a declaration-only class.
11386///
11387/// @param t the type to considier.
11388///
11389/// @param look_through_decl_only if true, then look through the
11390/// decl-only class to see if it actually has a class definition in
11391/// the same ABI corpus.
11392///
11393/// @return true iff @p t is a declaration-only class.
11394bool
11398
11399/// Test if a type is a @ref class_or_union.
11400///
11401/// @param t the type to consider.
11402///
11403/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11404/// nil otherwise.
11407{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
11408
11409/// Test if a type is a @ref class_or_union.
11410///
11411/// @param t the type to consider.
11412///
11413/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11414/// nil otherwise.
11415shared_ptr<class_or_union>
11416is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
11417{return dynamic_pointer_cast<class_or_union>(t);}
11418
11419/// Test if two class or union types are of the same kind.
11420///
11421/// @param first the first type to consider.
11422///
11423/// @param second the second type to consider.
11424///
11425/// @return true iff @p first is of the same kind as @p second.
11426bool
11428 const class_or_union* second)
11429{
11430 if ((is_class_type(first) && is_class_type(second))
11431 || (is_union_type(first) && is_union_type(second)))
11432 return true;
11433
11434 return false;
11435}
11436
11437/// Test if two class or union types are of the same kind.
11438///
11439/// @param first the first type to consider.
11440///
11441/// @param second the second type to consider.
11442///
11443/// @return true iff @p first is of the same kind as @p second.
11444bool
11445class_or_union_types_of_same_kind(const class_or_union_sptr& first,
11446 const class_or_union_sptr& second)
11447{return class_or_union_types_of_same_kind(first.get(), second.get());}
11448
11449/// Test if a type is a @ref union_decl.
11450///
11451/// @param t the type to consider.
11452///
11453/// @return true iff @p t is a union_decl.
11454bool
11456{return is_union_type(&t);}
11457
11458/// Test if a type is a @ref union_decl.
11459///
11460/// @param t the type to consider.
11461///
11462/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11463/// otherwise.
11466{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
11467
11468/// Test if a type is a @ref union_decl.
11469///
11470/// @param t the type to consider.
11471///
11472/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11473/// otherwise.
11474union_decl_sptr
11475is_union_type(const shared_ptr<type_or_decl_base>& t)
11476{return dynamic_pointer_cast<union_decl>(t);}
11477
11478/// Test whether a type is a pointer_type_def.
11479///
11480/// @param t the type to test.
11481///
11482/// @param look_through_decl_only if this is true, then look through
11483/// qualified types to see if the underlying type is a
11484/// pointer_type_def.
11485///
11486/// @return the @ref pointer_type_def_sptr if @p t is a
11487/// pointer_type_def, null otherwise.
11488const pointer_type_def*
11490 bool look_through_qualifiers)
11491{
11492 if (!t)
11493 return 0;
11494
11495 const type_base* type = is_type(t);
11496 if (look_through_qualifiers)
11497 type = peel_qualified_type(is_type(t));
11498
11499 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11500}
11501
11502/// Test whether a type is a pointer_type_def.
11503///
11504/// @param t the type to test.
11505///
11506/// @param look_through_decl_only if this is true, then look through
11507/// qualified types to see if the underlying type is a
11508/// pointer_type_def.
11509///
11510/// @return the @ref pointer_type_def_sptr if @p t is a
11511/// pointer_type_def, null otherwise.
11514 bool look_through_qualifiers)
11515{
11516 type_base_sptr type = is_type(t);
11517 if (look_through_qualifiers)
11518 type = peel_qualified_type(type);
11519 return dynamic_pointer_cast<pointer_type_def>(type);
11520}
11521
11522/// Test if a type is a pointer to function type.
11523///
11524/// @param t the type to consider.
11525///
11526/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11527/// function type.
11529is_pointer_to_function_type(const type_base_sptr& t)
11530{
11532 {
11533 if (is_function_type(p->get_pointed_to_type()))
11534 return p;
11535 }
11536 return pointer_type_def_sptr();
11537}
11538
11539/// Test if a type is a pointer to array type.
11540///
11541/// @param t the type to consider.
11542///
11543/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11544/// type.
11546is_pointer_to_array_type(const type_base_sptr& t)
11547{
11549 {
11550 if (is_array_type(p->get_pointed_to_type()))
11551 return p;
11552 }
11553 return pointer_type_def_sptr();
11554}
11555
11556/// Test if we are looking at a pointer to a
11557/// neither-a-pointer-to-an-array-nor-a-function type.
11558///
11559/// @param t the type to consider.
11560///
11561/// @return the @ref pointer_type_def_sptr type iff @p t is a
11562/// neither-a-pointer-an-array-nor-a-function type.
11564is_pointer_to_npaf_type(const type_base_sptr& t)
11565{
11567 {
11568 if (is_npaf_type(p->get_pointed_to_type()))
11569 return p;
11570 }
11571 return pointer_type_def_sptr();
11572}
11573
11574/// Test if we are looking at a pointer to pointer to member type.
11575///
11576/// @param t the type to consider.
11577///
11578/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11579/// to pointer to member type.
11581is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11582{
11584 {
11585 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11586 return p;
11587 }
11588 return pointer_type_def_sptr();
11589}
11590
11591/// Test if a type is a typedef, pointer or reference to a decl-only
11592/// class/union.
11593///
11594/// This looks into qualified types too.
11595///
11596/// @param t the type to consider.
11597///
11598/// @return true iff @p t is a type is a typedef, pointer or reference
11599/// to a decl-only class/union.
11600bool
11602{
11603 const type_base * type =
11604 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11605
11607 /*look_through_decl_only=*/true))
11608 return true;
11609
11610 return false;
11611}
11612
11613/// Test if a type is a typedef of a class or union type, or a typedef
11614/// of a qualified class or union type.
11615///
11616/// Note that if the type is directly a class or union type, the
11617/// function returns true as well.
11618///
11619/// @param t the type to consider.
11620///
11621/// @return true iff @p t is a typedef of a class or union type, or a
11622/// typedef of a qualified class or union type.
11623bool
11625{
11626 if (!t)
11627 return false;
11628
11631 return true;
11632
11633return false;
11634}
11635
11636/// Test if a type is a typedef of a class or union type, or a typedef
11637/// of a qualified class or union type.
11638///
11639/// Note that if the type is directly a class or union type, the
11640/// function returns true as well.
11641///
11642/// @param t the type to consider.
11643///
11644/// @return true iff @p t is a typedef of a class or union type, or a
11645/// typedef of a qualified class or union type.
11646bool
11649
11650/// Test whether a type is a reference_type_def.
11651///
11652/// @param t the type to test.
11653///
11654/// @param look_through_decl_only if this is true, then look through
11655/// qualified types to see if the underlying type is a
11656/// reference_type_def.
11657///
11658/// @return the @ref reference_type_def_sptr if @p t is a
11659/// reference_type_def, null otherwise.
11662 bool look_through_qualifiers)
11663{
11664 const type_base* type = is_type(t);
11665 if (!type)
11666 return nullptr;
11667
11668 if (look_through_qualifiers)
11669 type = peel_qualified_type(type);
11670 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11671}
11672
11673/// Test whether a type is a reference_type_def.
11674///
11675/// @param t the type to test.
11676///
11677/// @param look_through_decl_only if this is true, then look through
11678/// qualified types to see if the underlying type is a
11679/// reference_type_def.
11680///
11681/// @return the @ref reference_type_def_sptr if @p t is a
11682/// reference_type_def, null otherwise.
11683const reference_type_def*
11685 bool look_through_qualifiers)
11686{
11687 const type_base* type = is_type(t);
11688
11689 if (look_through_qualifiers)
11690 type = peel_qualified_type(type);
11691 return dynamic_cast<const reference_type_def*>(type);
11692}
11693
11694/// Test whether a type is a reference_type_def.
11695///
11696/// @param t the type to test.
11697///
11698/// @param look_through_decl_only if this is true, then look through
11699/// qualified types to see if the underlying type is a
11700/// reference_type_def.
11701///
11702/// @return the @ref reference_type_def_sptr if @p t is a
11703/// reference_type_def, null otherwise.
11706 bool look_through_qualifiers)
11707{
11708 type_base_sptr type = is_type(t);
11709 if (look_through_qualifiers)
11710 type = peel_qualified_type(type);
11711 return dynamic_pointer_cast<reference_type_def>(type);
11712}
11713
11714/// Test whether a type is a @ref ptr_to_mbr_type.
11715///
11716/// @param t the type to test.
11717///
11718/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11719/// ptr_to_mbr_type type, null otherwise.
11720const ptr_to_mbr_type*
11722 bool look_through_qualifiers)
11723{
11724 const type_base* type = is_type(t);
11725 if (look_through_qualifiers)
11726 type = peel_qualified_type(type);
11727 return dynamic_cast<const ptr_to_mbr_type*>(type);
11728}
11729
11730/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11731///
11732/// @param t the type to test.
11733///
11734/// @param look_through_decl_only if this is true, then look through
11735/// qualified types to see if the underlying type is a
11736/// ptr_to_mbr_type..
11737///
11738/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11739/// ptr_to_mbr_type type, null otherwise.
11742 bool look_through_qualifiers)
11743{
11744 type_base_sptr type = is_type(t);
11745 if (look_through_qualifiers)
11746 type = peel_qualified_type(type);
11747 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11748}
11749
11750/// Test if a type is equivalent to a pointer to void type.
11751///
11752/// Note that this looks trough typedefs or CV qualifiers to look for
11753/// the void pointer.
11754///
11755/// @param type the type to consider.
11756///
11757/// @return the actual void pointer if @p is eqivalent to a void
11758/// pointer or NULL if it's not.
11759const type_base*
11761{
11762 type = peel_qualified_or_typedef_type(type);
11763
11764 const pointer_type_def * t = is_pointer_type(type);
11765 if (!t)
11766 return 0;
11767
11768 // Look through typedefs in the pointed-to type as well.
11769 type_base * ty = t->get_pointed_to_type().get();
11771 if (ty && ty->get_environment().is_void_type(ty))
11772 return ty;
11773
11774 return 0;
11775}
11776
11777/// Test if a type is equivalent to a pointer to void type.
11778///
11779/// Note that this looks trough typedefs or CV qualifiers to look for
11780/// the void pointer.
11781///
11782/// @param type the type to consider.
11783///
11784/// @return the actual void pointer if @p is eqivalent to a void
11785/// pointer or NULL if it's not.
11786const type_base*
11789
11790/// Test if a type is a pointer to void type.
11791///
11792/// @param type the type to consider.
11793///
11794/// @return the actual void pointer if @p is a void pointer or NULL if
11795/// it's not.
11796const type_base*
11798{
11799 if (!t)
11800 return nullptr;
11801
11802 if (t->get_environment().get_void_pointer_type().get() == t)
11803 return t;
11804
11805 const pointer_type_def* ptr = is_pointer_type(t);
11806 if (!ptr)
11807 return nullptr;
11808
11810 return t;
11811
11812 return nullptr;
11813}
11814
11815/// Test if a type is a pointer to void type.
11816///
11817/// @param type the type to consider.
11818///
11819/// @return the actual void pointer if @p is a void pointer or NULL if
11820/// it's not.
11821const type_base_sptr
11822is_void_pointer_type(const type_base_sptr& t)
11823{
11824 type_base_sptr nil;
11825 if (!t)
11826 return nil;
11827
11828 if (t->get_environment().get_void_pointer_type().get() == t.get())
11829 return t;
11830
11831 const pointer_type_def* ptr = is_pointer_type(t.get());
11832 if (!ptr)
11833 return nil;
11834
11835 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11836 return t;
11837
11838 return nil;
11839}
11840
11841/// Test whether a type is a reference_type_def.
11842///
11843/// @param t the type to test.
11844///
11845/// @return the @ref reference_type_def_sptr if @p t is a
11846/// reference_type_def, null otherwise.
11849{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11850
11851/// Test whether a type is a qualified_type_def.
11852///
11853/// @param t the type to test.
11854///
11855/// @return the @ref qualified_type_def_sptr if @p t is a
11856/// qualified_type_def, null otherwise.
11857qualified_type_def_sptr
11859{return dynamic_pointer_cast<qualified_type_def>(t);}
11860
11861/// Test whether a type is a function_type.
11862///
11863/// @param t the type to test.
11864///
11865/// @return the @ref function_type_sptr if @p t is a
11866/// function_type, null otherwise.
11869{return dynamic_pointer_cast<function_type>(t);}
11870
11871/// Test whether a type is a function_type.
11872///
11873/// @param t the type to test.
11874///
11875/// @return the @ref function_type_sptr if @p t is a
11876/// function_type, null otherwise.
11879{return dynamic_cast<function_type*>(t);}
11880
11881/// Test whether a type is a function_type.
11882///
11883/// @param t the type to test.
11884///
11885/// @return the @ref function_type_sptr if @p t is a
11886/// function_type, null otherwise.
11887const function_type*
11889{return dynamic_cast<const function_type*>(t);}
11890
11891/// Test whether a type is a method_type.
11892///
11893/// @param t the type to test.
11894///
11895/// @return the @ref method_type_sptr if @p t is a
11896/// method_type, null otherwise.
11899{return dynamic_pointer_cast<method_type>(t);}
11900
11901/// Test whether a type is a method_type.
11902///
11903/// @param t the type to test.
11904///
11905/// @return the @ref method_type_sptr if @p t is a
11906/// method_type, null otherwise.
11907const method_type*
11909{return dynamic_cast<const method_type*>(t);}
11910
11911/// Test whether a type is a method_type.
11912///
11913/// @param t the type to test.
11914///
11915/// @return the @ref method_type_sptr if @p t is a
11916/// method_type, null otherwise.
11919{return dynamic_cast<method_type*>(t);}
11920
11921/// If a class (or union) is a decl-only class, get its definition.
11922/// Otherwise, just return the initial class.
11923///
11924/// @param the_class the class (or union) to consider.
11925///
11926/// @return either the definition of the class, or the class itself.
11930
11931/// If a class (or union) is a decl-only class, get its definition.
11932/// Otherwise, just return the initial class.
11933///
11934/// @param the_class the class (or union) to consider.
11935///
11936/// @return either the definition of the class, or the class itself.
11937class_or_union_sptr
11940
11941/// If a class (or union) is a decl-only class, get its definition.
11942/// Otherwise, just return the initial class.
11943///
11944/// @param klass the class (or union) to consider.
11945///
11946/// @return either the definition of the class, or the class itself.
11947class_or_union_sptr
11948look_through_decl_only_class(class_or_union_sptr klass)
11950
11951/// If an enum is a decl-only enum, get its definition.
11952/// Otherwise, just return the initial enum.
11953///
11954/// @param the_enum the enum to consider.
11955///
11956/// @return either the definition of the enum, or the enum itself.
11960
11961/// If an enum is a decl-only enum, get its definition.
11962/// Otherwise, just return the initial enum.
11963///
11964/// @param enom the enum to consider.
11965///
11966/// @return either the definition of the enum, or the enum itself.
11970
11971/// If a decl is decl-only get its definition. Otherwise, just return nil.
11972///
11973/// @param d the decl to consider.
11974///
11975/// @return either the definition of the decl, or nil.
11976decl_base_sptr
11978{
11979 decl_base_sptr decl;
11982
11983 if (!decl)
11984 return decl;
11985
11986 while (decl->get_is_declaration_only()
11987 && decl->get_definition_of_declaration())
11988 decl = decl->get_definition_of_declaration();
11989
11990 return decl;
11991}
11992
11993/// If a decl is decl-only enum, get its definition. Otherwise, just
11994/// return the initial decl.
11995///
11996/// @param d the decl to consider.
11997///
11998/// @return either the definition of the enum, or the decl itself.
11999decl_base*
12001{
12002 if (!d)
12003 return d;
12004
12005 decl_base* result = look_through_decl_only(*d).get();
12006 if (!result)
12007 result = d;
12008
12009 return result;
12010}
12011
12012/// If a decl is decl-only get its definition. Otherwise, just return nil.
12013///
12014/// @param d the decl to consider.
12015///
12016/// @return either the definition of the decl, or nil.
12017decl_base_sptr
12018look_through_decl_only(const decl_base_sptr& d)
12019{
12020 if (!d)
12021 return d;
12022
12023 decl_base_sptr result = look_through_decl_only(*d);
12024 if (!result)
12025 result = d;
12026
12027 return result;
12028}
12029
12030/// If a type is is decl-only, then get its definition. Otherwise,
12031/// just return the initial type.
12032///
12033/// @param d the decl to consider.
12034///
12035/// @return either the definition of the decl, or the initial type.
12036type_base*
12038{
12039 decl_base* d = is_decl(t);
12040 if (!d)
12041 return t;
12043 return is_type(d);
12044}
12045
12046/// If a type is is decl-only, then get its definition. Otherwise,
12047/// just return the initial type.
12048///
12049/// @param d the decl to consider.
12050///
12051/// @return either the definition of the decl, or the initial type.
12052type_base_sptr
12053look_through_decl_only_type(const type_base_sptr& t)
12054{
12055 decl_base_sptr d = is_decl(t);
12056 if (!d)
12057 return t;
12059 return is_type(d);
12060}
12061
12062/// Tests if a declaration is a variable declaration.
12063///
12064/// @param decl the decl to test.
12065///
12066/// @return the var_decl_sptr iff decl is a variable declaration; nil
12067/// otherwise.
12068var_decl*
12070{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
12071
12072/// Tests if a declaration is a variable declaration.
12073///
12074/// @param decl the decl to test.
12075///
12076/// @return the var_decl_sptr iff decl is a variable declaration; nil
12077/// otherwise.
12080{return dynamic_pointer_cast<var_decl>(decl);}
12081
12082/// Tests if a declaration is a namespace declaration.
12083///
12084/// @param d the decalration to consider.
12085///
12086/// @return the namespace declaration if @p d is a namespace.
12088is_namespace(const decl_base_sptr& d)
12089{return dynamic_pointer_cast<namespace_decl>(d);}
12090
12091/// Tests if a declaration is a namespace declaration.
12092///
12093/// @param d the decalration to consider.
12094///
12095/// @return the namespace declaration if @p d is a namespace.
12098{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
12099
12100/// Tests whether a decl is a template parameter composition type.
12101///
12102/// @param decl the declaration to consider.
12103///
12104/// @return true iff decl is a template parameter composition type.
12105bool
12106is_template_parm_composition_type(const shared_ptr<decl_base> decl)
12107{
12108 return (decl
12109 && is_at_template_scope(decl)
12110 && is_type(decl)
12111 && !is_template_parameter(decl));
12112}
12113
12114/// Test whether a decl is the pattern of a function template.
12115///
12116/// @param decl the decl to consider.
12117///
12118/// @return true iff decl is the pattern of a function template.
12119bool
12120is_function_template_pattern(const shared_ptr<decl_base> decl)
12121{
12122 return (decl
12123 && dynamic_pointer_cast<function_decl>(decl)
12124 && dynamic_cast<template_decl*>(decl->get_scope()));
12125}
12126
12127/// Test if a type is an array_type_def.
12128///
12129/// @param type the type to consider.
12130///
12131/// @return true iff @p type is an array_type_def.
12134 bool look_through_qualifiers)
12135{
12136 const type_base* t = is_type(type);
12137
12138 if (look_through_qualifiers)
12139 t = peel_qualified_type(t);
12140 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
12141}
12142
12143/// Test if a type is an array_type_def.
12144///
12145/// @param type the type to consider.
12146///
12147/// @return true iff @p type is an array_type_def.
12150 bool look_through_qualifiers)
12151{
12152 type_base_sptr t = is_type(type);
12153
12154 if (look_through_qualifiers)
12155 t = peel_qualified_type(t);
12156 return dynamic_pointer_cast<array_type_def>(t);
12157}
12158
12159/// Tests if the element of a given array is a qualified type.
12160///
12161/// @param array the array type to consider.
12162///
12163/// @return the qualified element of the array iff it's a qualified
12164/// type. Otherwise, return a nil object.
12165qualified_type_def_sptr
12167{
12168 if (!array)
12169 return qualified_type_def_sptr();
12170
12171 return is_qualified_type(array->get_element_type());
12172}
12173
12174/// Test if an array type is an array to a qualified element type.
12175///
12176/// @param type the array type to consider.
12177///
12178/// @return true the array @p type iff it's an array to a qualified
12179/// element type.
12181is_array_of_qualified_element(const type_base_sptr& type)
12182{
12183 if (array_type_def_sptr array = is_array_type(type))
12185 return array;
12186
12187 return array_type_def_sptr();
12188}
12189
12190/// Test if a type is a typedef of an array.
12191///
12192/// Note that the function looks through qualified and typedefs types
12193/// of the underlying type of the current typedef. In other words, if
12194/// we are looking at a typedef of a CV-qualified array, or at a
12195/// typedef of a CV-qualified typedef of an array, this function will
12196/// still return TRUE.
12197///
12198/// @param t the type to consider.
12199///
12200/// @return true if t is a typedef which underlying type is an array.
12201/// That array might be either cv-qualified array or a typedef'ed
12202/// array, or a combination of both.
12204is_typedef_of_array(const type_base_sptr& t)
12205{
12206 array_type_def_sptr result;
12207
12208 if (typedef_decl_sptr typdef = is_typedef(t))
12209 {
12210 type_base_sptr u =
12211 peel_qualified_or_typedef_type(typdef->get_underlying_type());
12212 result = is_array_type(u);
12213 }
12214
12215 return result;
12216}
12217
12218/// Test if a type is an array_type_def::subrange_type.
12219///
12220/// @param type the type to consider.
12221///
12222/// @return the array_type_def::subrange_type which @p type is a type
12223/// of, or nil if it's not of that type.
12226{
12227 return dynamic_cast<array_type_def::subrange_type*>
12228 (const_cast<type_or_decl_base*>(type));
12229}
12230
12231/// Test if a type is an array_type_def::subrange_type.
12232///
12233/// @param type the type to consider.
12234///
12235/// @return the array_type_def::subrange_type which @p type is a type
12236/// of, or nil if it's not of that type.
12239{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
12240
12241/// Tests whether a decl is a template.
12242///
12243/// @param decl the decl to consider.
12244///
12245/// @return true iff decl is a function template, class template, or
12246/// template template parameter.
12247bool
12248is_template_decl(const decl_base_sptr& decl)
12249{return decl && dynamic_pointer_cast<template_decl>(decl);}
12250
12251/// This enum describe the kind of entity to lookup, while using the
12252/// lookup API.
12254{
12255 LOOKUP_ENTITY_TYPE,
12256 LOOKUP_ENTITY_VAR,
12257};
12258
12259/// Find the first relevant delimiter (the "::" string) in a fully
12260/// qualified C++ type name, starting from a given position. The
12261/// delimiter returned separates a type name from the name of its
12262/// context.
12263///
12264/// This is supposed to work correctly on names in cases like this:
12265///
12266/// foo<ns1::name1, ns2::name2>
12267///
12268/// In that case when called with with parameter @p begin set to 0, no
12269/// delimiter is returned, because the type name in this case is:
12270/// 'foo<ns1::name1, ns2::name2>'.
12271///
12272/// But in this case:
12273///
12274/// foo<p1, bar::name>::some_type
12275///
12276/// The "::" returned is the one right before 'some_type'.
12277///
12278/// @param fqn the fully qualified name of the type to consider.
12279///
12280/// @param begin the position from which to look for the delimiter.
12281///
12282/// @param delim_pos out parameter. Is set to the position of the
12283/// delimiter iff the function returned true.
12284///
12285/// @return true iff the function found and returned the delimiter.
12286static bool
12287find_next_delim_in_cplus_type(const string& fqn,
12288 size_t begin,
12289 size_t& delim_pos)
12290{
12291 int angle_count = 0;
12292 bool found = false;
12293 size_t i = begin;
12294 for (; i < fqn.size(); ++i)
12295 {
12296 if (fqn[i] == '<')
12297 ++angle_count;
12298 else if (fqn[i] == '>')
12299 --angle_count;
12300 else if (i + 1 < fqn.size()
12301 && !angle_count
12302 && fqn[i] == ':'
12303 && fqn[i+1] == ':')
12304 {
12305 delim_pos = i;
12306 found = true;
12307 break;
12308 }
12309 }
12310 return found;
12311}
12312
12313/// Decompose a fully qualified name into the list of its components.
12314///
12315/// @param fqn the fully qualified name to decompose.
12316///
12317/// @param comps the resulting list of component to fill.
12318void
12319fqn_to_components(const string& fqn,
12320 list<string>& comps)
12321{
12322 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
12323 do
12324 {
12325 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
12326 comp_end = fqn_size;
12327
12328 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
12329 comps.push_back(comp);
12330
12331 comp_begin = comp_end + 2;
12332 if (comp_begin >= fqn_size)
12333 break;
12334 } while (true);
12335}
12336
12337/// Turn a set of qualified name components (that name a type) into a
12338/// qualified name string.
12339///
12340/// @param comps the name components
12341///
12342/// @return the resulting string, which would be the qualified name of
12343/// a type.
12344string
12345components_to_type_name(const list<string>& comps)
12346{
12347 string result;
12348 for (list<string>::const_iterator c = comps.begin();
12349 c != comps.end();
12350 ++c)
12351 if (c == comps.begin())
12352 result = *c;
12353 else
12354 result += "::" + *c;
12355 return result;
12356}
12357
12358/// This predicate returns true if a given container iterator points
12359/// to the last element of the container, false otherwise.
12360///
12361/// @tparam T the type of the container of the iterator.
12362///
12363/// @param container the container the iterator points into.
12364///
12365/// @param i the iterator to consider.
12366///
12367/// @return true iff the iterator points to the last element of @p
12368/// container.
12369template<typename T>
12370static bool
12371iterator_is_last(T& container,
12372 typename T::const_iterator i)
12373{
12374 typename T::const_iterator next = i;
12375 ++next;
12376 return (next == container.end());
12377}
12378
12379//--------------------------------
12380// <type and decls lookup stuff>
12381// ------------------------------
12382
12383/// Lookup all the type*s* that have a given fully qualified name.
12384///
12385/// @param type_name the fully qualified name of the type to
12386/// lookup.
12387///
12388/// @param type_map the map to look into.
12389///
12390/// @return the vector containing the types named @p type_name. If
12391/// the lookup didn't yield any type, then this function returns nil.
12392static const type_base_wptrs_type*
12393lookup_types_in_map(const interned_string& type_name,
12394 const istring_type_base_wptrs_map_type& type_map)
12395{
12396 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12397 if (i != type_map.end())
12398 return &i->second;
12399 return 0;
12400}
12401
12402/// Lookup a type (with a given name) in a map that associates a type
12403/// name to a type. If there are several types with a given name,
12404/// then try to return the first one that is not decl-only.
12405/// Otherwise, return the last of such types, that is, the last one
12406/// that got registered.
12407///
12408/// @tparam TypeKind the type of the type this function is supposed to
12409/// return.
12410///
12411/// @param type_name the name of the type to lookup.
12412///
12413/// @param type_map the map in which to look.
12414///
12415/// @return a shared_ptr to the type found. If no type was found or
12416/// if the type found was not of type @p TypeKind then the function
12417/// returns nil.
12418template <class TypeKind>
12419static shared_ptr<TypeKind>
12420lookup_type_in_map(const interned_string& type_name,
12421 const istring_type_base_wptrs_map_type& type_map)
12422{
12423 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12424 if (i != type_map.end())
12425 {
12426 // Walk the types that have the name "type_name" and return the
12427 // first one that is not declaration-only ...
12428 for (auto j : i->second)
12429 {
12430 type_base_sptr t(j);
12431 decl_base_sptr d = is_decl(t);
12432 if (d && !d->get_is_declaration_only())
12433 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12434 }
12435 // ... or return the last type with the name "type_name" that
12436 // was recorded. It's likely to be declaration-only if we
12437 // reached this point.
12438 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12439 }
12440 return shared_ptr<TypeKind>();
12441}
12442
12443/// Lookup a basic type from a translation unit.
12444///
12445/// This is done by looking the type up in the type map that is
12446/// maintained in the translation unit. So this is as fast as
12447/// possible.
12448///
12449/// @param type_name the name of the basic type to look for.
12450///
12451/// @param tu the translation unit to look into.
12452///
12453/// @return the basic type found or nil if no basic type was found.
12456{
12457 return lookup_type_in_map<type_decl>(type_name,
12458 tu.get_types().basic_types());
12459}
12460
12461/// Lookup a basic type from a translation unit.
12462///
12463/// This is done by looking the type up in the type map that is
12464/// maintained in the translation unit. So this is as fast as
12465/// possible.
12466///
12467/// @param type_name the name of the basic type to look for.
12468///
12469/// @param tu the translation unit to look into.
12470///
12471/// @return the basic type found or nil if no basic type was found.
12473lookup_basic_type(const string& type_name, const translation_unit& tu)
12474{
12475 const environment& env = tu.get_environment();
12476
12477 interned_string s = env.intern(type_name);
12478 return lookup_basic_type(s, tu);
12479}
12480
12481/// Lookup a class type from a translation unit.
12482///
12483/// This is done by looking the type up in the type map that is
12484/// maintained in the translation unit. So this is as fast as
12485/// possible.
12486///
12487/// @param fqn the fully qualified name of the class type node to look
12488/// up.
12489///
12490/// @param tu the translation unit to perform lookup from.
12491///
12492/// @return the declaration of the class type IR node found, NULL
12493/// otherwise.
12495lookup_class_type(const string& fqn, const translation_unit& tu)
12496{
12497 const environment& env = tu.get_environment();
12498 interned_string s = env.intern(fqn);
12499 return lookup_class_type(s, tu);
12500}
12501
12502/// Lookup a class type from a translation unit.
12503///
12504/// This is done by looking the type up in the type map that is
12505/// maintained in the translation unit. So this is as fast as
12506/// possible.
12507///
12508/// @param type_name the name of the class type to look for.
12509///
12510/// @param tu the translation unit to look into.
12511///
12512/// @return the class type found or nil if no class type was found.
12515{
12516 return lookup_type_in_map<class_decl>(type_name,
12517 tu.get_types().class_types());
12518}
12519
12520/// Lookup a union type from a translation unit.
12521///
12522/// This is done by looking the type up in the type map that is
12523/// maintained in the translation unit. So this is as fast as
12524/// possible.
12525///
12526/// @param type_name the name of the union type to look for.
12527///
12528/// @param tu the translation unit to look into.
12529///
12530/// @return the union type found or nil if no union type was found.
12531union_decl_sptr
12533{
12534 return lookup_type_in_map<union_decl>(type_name,
12535 tu.get_types().union_types());
12536}
12537
12538/// Lookup a union type from a translation unit.
12539///
12540/// This is done by looking the type up in the type map that is
12541/// maintained in the translation unit. So this is as fast as
12542/// possible.
12543///
12544/// @param fqn the fully qualified name of the type to lookup.
12545///
12546/// @param tu the translation unit to look into.
12547///
12548/// @return the union type found or nil if no union type was found.
12549union_decl_sptr
12550lookup_union_type(const string& fqn, const translation_unit& tu)
12551{
12552 const environment& env = tu.get_environment();
12553 interned_string s = env.intern(fqn);
12554 return lookup_union_type(s, tu);
12555}
12556
12557/// Lookup a union type in a given corpus, from its location.
12558///
12559/// @param loc the location of the union type to look for.
12560///
12561/// @param corp the corpus to look it from.
12562///
12563/// @return the resulting union_decl.
12564union_decl_sptr
12566{
12569 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12570
12571 return result;
12572}
12573
12574/// Lookup a union type in a given corpus, from its location.
12575///
12576/// @param loc the location of the union type to look for.
12577///
12578/// @param corp the corpus to look it from.
12579///
12580/// @return the resulting union_decl.
12581union_decl_sptr
12582lookup_union_type_per_location(const string& loc, const corpus& corp)
12583{
12584 const environment& env = corp.get_environment();
12585 return lookup_union_type_per_location(env.intern(loc), corp);
12586}
12587
12588/// Lookup an enum type from a translation unit.
12589///
12590/// This is done by looking the type up in the type map that is
12591/// maintained in the translation unit. So this is as fast as
12592/// possible.
12593///
12594/// @param type_name the name of the enum type to look for.
12595///
12596/// @param tu the translation unit to look into.
12597///
12598/// @return the enum type found or nil if no enum type was found.
12601{
12602 return lookup_type_in_map<enum_type_decl>(type_name,
12603 tu.get_types().enum_types());
12604}
12605
12606/// Lookup an enum type from a translation unit.
12607///
12608/// This is done by looking the type up in the type map that is
12609/// maintained in the translation unit. So this is as fast as
12610/// possible.
12611///
12612/// @param type_name the name of the enum type to look for.
12613///
12614/// @param tu the translation unit to look into.
12615///
12616/// @return the enum type found or nil if no enum type was found.
12618lookup_enum_type(const string& type_name, const translation_unit& tu)
12619{
12620 const environment& env = tu.get_environment();
12621 interned_string s = env.intern(type_name);
12622 return lookup_enum_type(s, tu);
12623}
12624
12625/// Lookup a typedef type from a translation unit.
12626///
12627/// This is done by looking the type up in the type map that is
12628/// maintained in the translation unit. So this is as fast as
12629/// possible.
12630///
12631/// @param type_name the name of the typedef type to look for.
12632///
12633/// @param tu the translation unit to look into.
12634///
12635/// @return the typedef type found or nil if no typedef type was
12636/// found.
12639 const translation_unit& tu)
12640{
12641 return lookup_type_in_map<typedef_decl>(type_name,
12642 tu.get_types().typedef_types());
12643}
12644
12645/// Lookup a typedef type from a translation unit.
12646///
12647/// This is done by looking the type up in the type map that is
12648/// maintained in the translation unit. So this is as fast as
12649/// possible.
12650///
12651/// @param type_name the name of the typedef type to look for.
12652///
12653/// @param tu the translation unit to look into.
12654///
12655/// @return the typedef type found or nil if no typedef type was
12656/// found.
12658lookup_typedef_type(const string& type_name, const translation_unit& tu)
12659{
12660 const environment& env = tu.get_environment();
12661 interned_string s = env.intern(type_name);
12662 return lookup_typedef_type(s, tu);
12663}
12664
12665/// Lookup a qualified type from a translation unit.
12666///
12667/// This is done by looking the type up in the type map that is
12668/// maintained in the translation unit. So this is as fast as
12669/// possible.
12670///
12671/// @param type_name the name of the qualified type to look for.
12672///
12673/// @param tu the translation unit to look into.
12674///
12675/// @return the qualified type found or nil if no qualified type was
12676/// found.
12677qualified_type_def_sptr
12679 const translation_unit& tu)
12680{
12681 const type_maps& m = tu.get_types();
12682 return lookup_type_in_map<qualified_type_def>(type_name,
12683 m.qualified_types());
12684}
12685
12686/// Lookup a qualified type from a translation unit.
12687///
12688/// This is done by looking the type up in the type map that is
12689/// maintained in the translation unit. So this is as fast as
12690/// possible.
12691///
12692/// @param underlying_type the underying type of the qualified type to
12693/// look up.
12694///
12695/// @param quals the CV-qualifiers of the qualified type to look for.
12696///
12697/// @param tu the translation unit to look into.
12698///
12699/// @return the qualified type found or nil if no qualified type was
12700/// found.
12701qualified_type_def_sptr
12702lookup_qualified_type(const type_base_sptr& underlying_type,
12704 const translation_unit& tu)
12705{
12706 interned_string type_name = get_name_of_qualified_type(underlying_type,
12707 quals);
12708 return lookup_qualified_type(type_name, tu);
12709}
12710
12711/// Lookup a pointer type from a translation unit.
12712///
12713/// This is done by looking the type up in the type map that is
12714/// maintained in the translation unit. So this is as fast as
12715/// possible.
12716///
12717/// @param type_name the name of the pointer type to look for.
12718///
12719/// @param tu the translation unit to look into.
12720///
12721/// @return the pointer type found or nil if no pointer type was
12722/// found.
12725 const translation_unit& tu)
12726{
12727 const type_maps& m = tu.get_types();
12728 return lookup_type_in_map<pointer_type_def>(type_name,
12729 m.pointer_types());
12730}
12731
12732/// Lookup a pointer type from a translation unit.
12733///
12734/// This is done by looking the type up in the type map that is
12735/// maintained in the translation unit. So this is as fast as
12736/// possible.
12737///
12738/// @param type_name the name of the pointer type to look for.
12739///
12740/// @param tu the translation unit to look into.
12741///
12742/// @return the pointer type found or nil if no pointer type was
12743/// found.
12745lookup_pointer_type(const string& type_name, const translation_unit& tu)
12746{
12747 const environment& env = tu.get_environment();
12748 interned_string s = env.intern(type_name);
12749 return lookup_pointer_type(s, tu);
12750}
12751
12752/// Lookup a pointer type from a translation unit.
12753///
12754/// This is done by looking the type up in the type map that is
12755/// maintained in the translation unit. So this is as fast as
12756/// possible.
12757///
12758/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12759///
12760/// @param tu the translation unit to look into.
12761///
12762/// @return the pointer type found or nil if no pointer type was
12763/// found.
12765lookup_pointer_type(const type_base_sptr& pointed_to_type,
12766 const translation_unit& tu)
12767{
12768 type_base_sptr t = look_through_decl_only_type(pointed_to_type);
12770 return lookup_pointer_type(type_name, tu);
12771}
12772
12773/// Lookup a reference type from a translation unit.
12774///
12775/// This is done by looking the type up in the type map that is
12776/// maintained in the translation unit. So this is as fast as
12777/// possible.
12778///
12779/// @param type_name the name of the reference type to look for.
12780///
12781/// @param tu the translation unit to look into.
12782///
12783/// @return the reference type found or nil if no reference type was
12784/// found.
12787 const translation_unit& tu)
12788{
12789 const type_maps& m = tu.get_types();
12790 return lookup_type_in_map<reference_type_def>(type_name,
12791 m.reference_types());
12792}
12793
12794/// Lookup a reference type from a translation unit.
12795///
12796/// This is done by looking the type up in the type map that is
12797/// maintained in the translation unit. So this is as fast as
12798/// possible.
12799///
12800/// @param pointed_to_type the pointed-to-type of the reference to
12801/// look up.
12802///
12803/// @param tu the translation unit to look into.
12804///
12805/// @return the reference type found or nil if no reference type was
12806/// found.
12808lookup_reference_type(const type_base_sptr& pointed_to_type,
12809 bool lvalue_reference,
12810 const translation_unit& tu)
12811{
12812 interned_string type_name =
12814 lvalue_reference);
12815 return lookup_reference_type(type_name, tu);
12816}
12817
12818/// Lookup an array type from a translation unit.
12819///
12820/// This is done by looking the type up in the type map that is
12821/// maintained in the translation unit. So this is as fast as
12822/// possible.
12823///
12824/// @param type_name the name of the array type to look for.
12825///
12826/// @param tu the translation unit to look into.
12827///
12828/// @return the array type found or nil if no array type was found.
12831 const translation_unit& tu)
12832{
12833 const type_maps& m = tu.get_types();
12834 return lookup_type_in_map<array_type_def>(type_name,
12835 m.array_types());
12836}
12837
12838/// Lookup a function type from a translation unit.
12839///
12840/// This is done by looking the type up in the type map that is
12841/// maintained in the translation unit. So this is as fast as
12842/// possible.
12843///
12844/// @param type_name the name of the type to lookup.
12845///
12846/// @param tu the translation unit to look into.
12847///
12848/// @return the function type found, or NULL of none was found.
12851 const translation_unit& tu)
12852{
12853 const type_maps& m = tu.get_types();
12854 return lookup_type_in_map<function_type>(type_name,
12855 m.function_types());
12856}
12857
12858/// Lookup a function type from a translation unit.
12859///
12860/// This walks all the function types held by the translation unit and
12861/// compare their sub-type *names*. If the names match then return
12862/// the function type found in the translation unit.
12863///
12864/// @param t the function type to look for.
12865///
12866/// @param tu the translation unit to look into.
12867///
12868/// @return the function type found, or NULL of none was found.
12871 const translation_unit& tu)
12872{
12873 interned_string type_name = get_type_name(t);
12874 return lookup_function_type(type_name, tu);
12875}
12876
12877/// Lookup a function type from a translation unit.
12878///
12879/// This is done by looking the type up in the type map that is
12880/// maintained in the translation unit. So this is as fast as
12881/// possible.
12882///
12883/// @param t the function type to look for.
12884///
12885/// @param tu the translation unit to look into.
12886///
12887/// @return the function type found, or NULL of none was found.
12890 const translation_unit& tu)
12891{return lookup_function_type(*t, tu);}
12892
12893/// Lookup a type in a translation unit.
12894///
12895/// @param fqn the fully qualified name of the type to lookup.
12896///
12897/// @param tu the translation unit to consider.
12898///
12899/// @return the declaration of the type if found, NULL otherwise.
12900const type_base_sptr
12902 const translation_unit& tu)
12903{
12904 type_base_sptr result;
12905 ((result = lookup_typedef_type(fqn, tu))
12906 || (result = lookup_class_type(fqn, tu))
12907 || (result = lookup_union_type(fqn, tu))
12908 || (result = lookup_enum_type(fqn, tu))
12909 || (result = lookup_qualified_type(fqn, tu))
12910 || (result = lookup_pointer_type(fqn, tu))
12911 || (result = lookup_reference_type(fqn, tu))
12912 || (result = lookup_array_type(fqn, tu))
12913 || (result = lookup_function_type(fqn, tu))
12914 || (result = lookup_basic_type(fqn, tu)));
12915
12916 return result;
12917}
12918
12919/// Lookup a type in a translation unit, starting from the global
12920/// namespace.
12921///
12922/// @param fqn the fully qualified name of the type to lookup.
12923///
12924/// @param tu the translation unit to consider.
12925///
12926/// @return the declaration of the type if found, NULL otherwise.
12927type_base_sptr
12928lookup_type(const string& fqn, const translation_unit& tu)
12929{
12930 const environment&env = tu.get_environment();
12931 interned_string ifqn = env.intern(fqn);
12932 return lookup_type(ifqn, tu);
12933}
12934
12935/// Lookup a type from a translation unit.
12936///
12937/// @param fqn the components of the fully qualified name of the node
12938/// to look up.
12939///
12940/// @param tu the translation unit to perform lookup from.
12941///
12942/// @return the declaration of the IR node found, NULL otherwise.
12943const type_base_sptr
12944lookup_type(const type_base_sptr type,
12945 const translation_unit& tu)
12946{
12947 interned_string type_name = get_type_name(type);
12948 return lookup_type(type_name, tu);
12949}
12950
12951/// Lookup a type in a scope.
12952///
12953/// This is really slow as it walks the member types of the scope in
12954/// sequence to find the type with a given name.
12955///
12956/// If possible, users should prefer looking up types from the
12957/// enclosing translation unit or even ABI corpus because both the
12958/// translation unit and the corpus have a map of type, indexed by
12959/// their name. Looking up a type from those maps is thus much
12960/// faster.
12961///
12962/// @param fqn the fully qualified name of the type to lookup.
12963///
12964/// @param skope the scope to look into.
12965///
12966/// @return the declaration of the type if found, NULL otherwise.
12967const type_base_sptr
12968lookup_type_in_scope(const string& fqn,
12969 const scope_decl_sptr& skope)
12970{
12971 list<string> comps;
12972 fqn_to_components(fqn, comps);
12973 return lookup_type_in_scope(comps, skope);
12974}
12975
12976/// Lookup a @ref var_decl in a scope.
12977///
12978/// @param fqn the fuly qualified name of the @var_decl to lookup.
12979///
12980/// @param skope the scope to look into.
12981///
12982/// @return the declaration of the @ref var_decl if found, NULL
12983/// otherwise.
12984const decl_base_sptr
12986 const scope_decl_sptr& skope)
12987{
12988 list<string> comps;
12989 fqn_to_components(fqn, comps);
12990 return lookup_var_decl_in_scope(comps, skope);
12991}
12992
12993/// A generic function (template) to get the name of a node, whatever
12994/// node it is. This has to be specialized for the kind of node we
12995/// want.
12996///
12997/// Note that a node is a member of a scope.
12998///
12999/// @tparam NodeKind the kind of node to consider.
13000///
13001/// @param node the node to get the name from.
13002///
13003/// @return the name of the node.
13004template<typename NodeKind>
13005static const interned_string&
13006get_node_name(shared_ptr<NodeKind> node);
13007
13008/// Gets the name of a class_decl node.
13009///
13010/// @param node the decl_base node to get the name from.
13011///
13012/// @return the name of the node.
13013template<>
13014const interned_string&
13015get_node_name(class_decl_sptr node)
13016{return node->get_name();}
13017
13018/// Gets the name of a type_base node.
13019///
13020/// @param node the type_base node to get the name from.
13021///
13022/// @return the name of the node.
13023template<>
13024const interned_string&
13025get_node_name(type_base_sptr node)
13026{return get_type_declaration(node)->get_name();}
13027
13028/// Gets the name of a var_decl node.
13029///
13030/// @param node the var_decl node to get the name from.
13031///
13032/// @return the name of the node.
13033template<>
13034const interned_string&
13035get_node_name(var_decl_sptr node)
13036{return node->get_name();}
13037
13038/// Generic function to get the declaration of a given node, whatever
13039/// it is. There has to be specializations for the kind of the nodes
13040/// we want to support.
13041///
13042/// @tparam NodeKind the type of the node we are looking at.
13043///
13044/// @return the declaration.
13045template<typename NodeKind>
13046static decl_base_sptr
13047convert_node_to_decl(shared_ptr<NodeKind> node);
13048
13049/// Lookup a node in a given scope.
13050///
13051/// @tparam the type of the node to lookup.
13052///
13053/// @param fqn the components of the fully qualified name of the node
13054/// to lookup.
13055///
13056/// @param skope the scope to look into.
13057///
13058/// @return the declaration of the looked up node, or NULL if it
13059/// wasn't found.
13060template<typename NodeKind>
13061static const type_or_decl_base_sptr
13062lookup_node_in_scope(const list<string>& fqn,
13063 const scope_decl_sptr& skope)
13064{
13065 type_or_decl_base_sptr resulting_decl;
13066 shared_ptr<NodeKind> node;
13067 bool it_is_last = false;
13068 scope_decl_sptr cur_scope = skope, new_scope, scope;
13069
13070 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
13071 {
13072 new_scope.reset();
13073 it_is_last = iterator_is_last(fqn, c);
13074 for (scope_decl::declarations::const_iterator m =
13075 cur_scope->get_member_decls().begin();
13076 m != cur_scope->get_member_decls().end();
13077 ++m)
13078 {
13079 if (!it_is_last)
13080 {
13081 // looking for a scope
13082 scope = dynamic_pointer_cast<scope_decl>(*m);
13083 if (scope && scope->get_name() == *c)
13084 {
13085 new_scope = scope;
13086 break;
13087 }
13088 }
13089 else
13090 {
13091 //looking for a final type.
13092 node = dynamic_pointer_cast<NodeKind>(*m);
13093 if (node && get_node_name(node) == *c)
13094 {
13095 if (class_decl_sptr cl =
13096 dynamic_pointer_cast<class_decl>(node))
13097 if (cl->get_is_declaration_only()
13098 && !cl->get_definition_of_declaration())
13099 continue;
13100 resulting_decl = node;
13101 break;
13102 }
13103 }
13104 }
13105 if (!new_scope && !resulting_decl)
13106 return decl_base_sptr();
13107 cur_scope = new_scope;
13108 }
13109 ABG_ASSERT(resulting_decl);
13110 return resulting_decl;
13111}
13112
13113/// lookup a type in a scope.
13114///
13115///
13116/// This is really slow as it walks the member types of the scope in
13117/// sequence to find the type with a given name.
13118///
13119/// If possible, users should prefer looking up types from the
13120/// enclosing translation unit or even ABI corpus because both the
13121/// translation unit and the corpus have a map of type, indexed by
13122/// their name. Looking up a type from those maps is thus much
13123/// faster.
13124///
13125/// @param comps the components of the fully qualified name of the
13126/// type to lookup.
13127///
13128/// @param skope the scope to look into.
13129///
13130/// @return the declaration of the type found.
13131const type_base_sptr
13132lookup_type_in_scope(const list<string>& comps,
13133 const scope_decl_sptr& scope)
13134{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
13135
13136/// lookup a type in a scope.
13137///
13138/// This is really slow as it walks the member types of the scope in
13139/// sequence to find the type with a given name.
13140///
13141/// If possible, users should prefer looking up types from the
13142/// enclosing translation unit or even ABI corpus because both the
13143/// translation unit and the corpus have a map of type, indexed by
13144/// their name. Looking up a type from those maps is thus much
13145/// faster.
13146///
13147/// @param type the type to look for.
13148///
13149/// @param access_path a vector of scopes the path of scopes to follow
13150/// before reaching the scope into which to look for @p type. Note
13151/// that the deepest scope (the one immediately containing @p type) is
13152/// at index 0 of this vector, and the top-most scope is the last
13153/// element of the vector.
13154///
13155/// @param scope the top-most scope into which to look for @p type.
13156///
13157/// @return the scope found in @p scope, or NULL if it wasn't found.
13158static const type_base_sptr
13160 const vector<scope_decl*>& access_path,
13161 const scope_decl* scope)
13162{
13163 vector<scope_decl*> a = access_path;
13164 type_base_sptr result;
13165
13166 scope_decl* first_scope = 0;
13167 if (!a.empty())
13168 {
13169 first_scope = a.back();
13170 ABG_ASSERT(first_scope->get_name() == scope->get_name());
13171 a.pop_back();
13172 }
13173
13174 if (a.empty())
13175 {
13176 interned_string n = get_type_name(type, false);
13177 for (scope_decl::declarations::const_iterator i =
13178 scope->get_member_decls().begin();
13179 i != scope->get_member_decls().end();
13180 ++i)
13181 if (is_type(*i) && (*i)->get_name() == n)
13182 {
13183 result = is_type(*i);
13184 break;
13185 }
13186 }
13187 else
13188 {
13189 first_scope = a.back();
13190 interned_string scope_name, cur_scope_name = first_scope->get_name();
13191 for (scope_decl::scopes::const_iterator i =
13192 scope->get_member_scopes().begin();
13193 i != scope->get_member_scopes().end();
13194 ++i)
13195 {
13196 scope_name = (*i)->get_name();
13197 if (scope_name == cur_scope_name)
13198 {
13199 result = lookup_type_in_scope(type, a, (*i).get());
13200 break;
13201 }
13202 }
13203 }
13204 return result;
13205}
13206
13207/// lookup a type in a scope.
13208///
13209/// This is really slow as it walks the member types of the scope in
13210/// sequence to find the type with a given name.
13211///
13212/// If possible, users should prefer looking up types from the
13213/// enclosing translation unit or even ABI corpus because both the
13214/// translation unit and the corpus have a map of type, indexed by
13215/// their name. Looking up a type from those maps is thus much
13216/// faster.
13217///
13218/// @param type the type to look for.
13219///
13220/// @param scope the top-most scope into which to look for @p type.
13221///
13222/// @return the scope found in @p scope, or NULL if it wasn't found.
13223static const type_base_sptr
13224lookup_type_in_scope(const type_base_sptr type,
13225 const scope_decl* scope)
13226{
13227 if (!type || is_function_type(type))
13228 return type_base_sptr();
13229
13230 decl_base_sptr type_decl = get_type_declaration(type);
13232 vector<scope_decl*> access_path;
13233 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
13234 {
13235 access_path.push_back(s);
13236 if (is_global_scope(s))
13237 break;
13238 }
13239 return lookup_type_in_scope(*type, access_path, scope);
13240}
13241
13242/// Lookup a type from a translation unit by walking the scopes of the
13243/// translation unit in sequence and looking into them.
13244///
13245/// This is really slow as it walks the member types of the scopes in
13246/// sequence to find the type with a given name.
13247///
13248/// If possible, users should prefer looking up types from the
13249/// translation unit or even ABI corpus in a more direct way, by using
13250/// the lookup_type() functins.
13251///
13252///
13253/// This is because both the translation unit and the corpus have a
13254/// map of types, indexed by their name. Looking up a type from those
13255/// maps is thus much faster. @param fqn the components of the fully
13256/// qualified name of the node to look up.
13257///
13258/// @param tu the translation unit to perform lookup from.
13259///
13260/// @return the declaration of the IR node found, NULL otherwise.
13261const type_base_sptr
13262lookup_type_through_scopes(const type_base_sptr type,
13263 const translation_unit& tu)
13264{
13265 if (function_type_sptr fn_type = is_function_type(type))
13266 return lookup_function_type(fn_type, tu);
13267 return lookup_type_in_scope(type, tu.get_global_scope().get());
13268}
13269
13270/// lookup a var_decl in a scope.
13271///
13272/// @param comps the components of the fully qualified name of the
13273/// var_decl to lookup.
13274///
13275/// @param skope the scope to look into.
13276const decl_base_sptr
13277lookup_var_decl_in_scope(const std::list<string>& comps,
13278 const scope_decl_sptr& skope)
13279{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
13280
13281/// Lookup an IR node from a translation unit.
13282///
13283/// @tparam NodeKind the type of the IR node to lookup from the
13284/// translation unit.
13285///
13286/// @param fqn the components of the fully qualified name of the node
13287/// to look up.
13288///
13289/// @param tu the translation unit to perform lookup from.
13290///
13291/// @return the declaration of the IR node found, NULL otherwise.
13292template<typename NodeKind>
13293static const type_or_decl_base_sptr
13294lookup_node_in_translation_unit(const list<string>& fqn,
13295 const translation_unit& tu)
13296{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
13297
13298/// Lookup a type from a translation unit by walking its scopes in
13299/// sequence and by looking into them.
13300///
13301/// This is much slower than using the lookup_type() function.
13302///
13303/// @param fqn the components of the fully qualified name of the node
13304/// to look up.
13305///
13306/// @param tu the translation unit to perform lookup from.
13307///
13308/// @return the declaration of the IR node found, NULL otherwise.
13309type_base_sptr
13310lookup_type_through_scopes(const list<string>& fqn,
13311 const translation_unit& tu)
13312{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
13313
13314
13315/// Lookup a class type from a translation unit by walking its scopes
13316/// in sequence and by looking into them.
13317///
13318/// This is much slower than using the lookup_class_type() function
13319/// because it walks all the scopes of the translation unit in
13320/// sequence and lookup the types to find one that has a given name.
13321///
13322/// @param fqn the components of the fully qualified name of the class
13323/// type node to look up.
13324///
13325/// @param tu the translation unit to perform lookup from.
13326///
13327/// @return the declaration of the class type IR node found, NULL
13328/// otherwise.
13330lookup_class_type_through_scopes(const list<string>& fqn,
13331 const translation_unit& tu)
13332{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
13333
13334/// Lookup a basic type from all the translation units of a given
13335/// corpus.
13336///
13337/// @param fqn the components of the fully qualified name of the basic
13338/// type node to look up.
13339///
13340/// @param tu the translation unit to perform lookup from.
13341///
13342/// @return the declaration of the basic type IR node found, NULL
13343/// otherwise.
13344static type_decl_sptr
13345lookup_basic_type_through_translation_units(const interned_string& type_name,
13346 const corpus& abi_corpus)
13347{
13348 type_decl_sptr result;
13349
13350 for (translation_units::const_iterator tu =
13351 abi_corpus.get_translation_units().begin();
13352 tu != abi_corpus.get_translation_units().end();
13353 ++tu)
13354 if ((result = lookup_basic_type(type_name, **tu)))
13355 break;
13356
13357 return result;
13358}
13359
13360/// Lookup a union type from all the translation units of a given
13361/// corpus.
13362///
13363/// @param fqn the components of the fully qualified name of the union
13364/// type node to look up.
13365///
13366/// @param tu the translation unit to perform lookup from.
13367///
13368/// @return the declaration of the union type IR node found, NULL
13369/// otherwise.
13370static union_decl_sptr
13371lookup_union_type_through_translation_units(const interned_string& type_name,
13372 const corpus & abi_corpus)
13373{
13374 union_decl_sptr result;
13375
13376 for (translation_units::const_iterator tu =
13377 abi_corpus.get_translation_units().begin();
13378 tu != abi_corpus.get_translation_units().end();
13379 ++tu)
13380 if ((result = lookup_union_type(type_name, **tu)))
13381 break;
13382
13383 return result;
13384}
13385
13386/// Lookup an enum type from all the translation units of a given
13387/// corpus.
13388///
13389/// @param fqn the components of the fully qualified name of the enum
13390/// type node to look up.
13391///
13392/// @param tu the translation unit to perform lookup from.
13393///
13394/// @return the declaration of the enum type IR node found, NULL
13395/// otherwise.
13397lookup_enum_type_through_translation_units(const interned_string& type_name,
13398 const corpus & abi_corpus)
13399{
13400 enum_type_decl_sptr result;
13401
13402 for (translation_units::const_iterator tu =
13403 abi_corpus.get_translation_units().begin();
13404 tu != abi_corpus.get_translation_units().end();
13405 ++tu)
13406 if ((result = lookup_enum_type(type_name, **tu)))
13407 break;
13408
13409 return result;
13410}
13411
13412/// Lookup a typedef type definition in all the translation units of a
13413/// given ABI corpus.
13414///
13415/// @param @param qn the fully qualified name of the typedef type to lookup.
13416///
13417/// @param abi_corpus the ABI corpus which to look the type up in.
13418///
13419/// @return the type definition if any was found, or a NULL pointer.
13420static typedef_decl_sptr
13421lookup_typedef_type_through_translation_units(const interned_string& type_name,
13422 const corpus & abi_corpus)
13423{
13424 typedef_decl_sptr result;
13425
13426 for (translation_units::const_iterator tu =
13427 abi_corpus.get_translation_units().begin();
13428 tu != abi_corpus.get_translation_units().end();
13429 ++tu)
13430 if ((result = lookup_typedef_type(type_name, **tu)))
13431 break;
13432
13433 return result;
13434}
13435
13436/// Lookup a qualified type definition in all the translation units of a
13437/// given ABI corpus.
13438///
13439/// @param @param qn the fully qualified name of the qualified type to
13440/// lookup.
13441///
13442/// @param abi_corpus the ABI corpus which to look the type up in.
13443///
13444/// @return the type definition if any was found, or a NULL pointer.
13445static qualified_type_def_sptr
13446lookup_qualified_type_through_translation_units(const interned_string& t_name,
13447 const corpus & abi_corpus)
13448{
13449 qualified_type_def_sptr result;
13450
13451 for (translation_units::const_iterator tu =
13452 abi_corpus.get_translation_units().begin();
13453 tu != abi_corpus.get_translation_units().end();
13454 ++tu)
13455 if ((result = lookup_qualified_type(t_name, **tu)))
13456 break;
13457
13458 return result;
13459}
13460
13461/// Lookup a pointer type definition in all the translation units of a
13462/// given ABI corpus.
13463///
13464/// @param @param qn the fully qualified name of the pointer type to
13465/// lookup.
13466///
13467/// @param abi_corpus the ABI corpus which to look the type up in.
13468///
13469/// @return the type definition if any was found, or a NULL pointer.
13471lookup_pointer_type_through_translation_units(const interned_string& type_name,
13472 const corpus & abi_corpus)
13473{
13474 pointer_type_def_sptr result;
13475
13476 for (translation_units::const_iterator tu =
13477 abi_corpus.get_translation_units().begin();
13478 tu != abi_corpus.get_translation_units().end();
13479 ++tu)
13480 if ((result = lookup_pointer_type(type_name, **tu)))
13481 break;
13482
13483 return result;
13484}
13485
13486/// Lookup a reference type definition in all the translation units of a
13487/// given ABI corpus.
13488///
13489/// @param @param qn the fully qualified name of the reference type to
13490/// lookup.
13491///
13492/// @param abi_corpus the ABI corpus which to look the type up in.
13493///
13494/// @return the type definition if any was found, or a NULL pointer.
13496lookup_reference_type_through_translation_units(const interned_string& t_name,
13497 const corpus & abi_corpus)
13498{
13500
13501 for (translation_units::const_iterator tu =
13502 abi_corpus.get_translation_units().begin();
13503 tu != abi_corpus.get_translation_units().end();
13504 ++tu)
13505 if ((result = lookup_reference_type(t_name, **tu)))
13506 break;
13507
13508 return result;
13509}
13510
13511/// Lookup a array type definition in all the translation units of a
13512/// given ABI corpus.
13513///
13514/// @param @param qn the fully qualified name of the array type to
13515/// lookup.
13516///
13517/// @param abi_corpus the ABI corpus which to look the type up in.
13518///
13519/// @return the type definition if any was found, or a NULL pointer.
13521lookup_array_type_through_translation_units(const interned_string& type_name,
13522 const corpus & abi_corpus)
13523{
13524 array_type_def_sptr result;
13525
13526 for (translation_units::const_iterator tu =
13527 abi_corpus.get_translation_units().begin();
13528 tu != abi_corpus.get_translation_units().end();
13529 ++tu)
13530 if ((result = lookup_array_type(type_name, **tu)))
13531 break;
13532
13533 return result;
13534}
13535
13536/// Lookup a function type definition in all the translation units of
13537/// a given ABI corpus.
13538///
13539/// @param @param qn the fully qualified name of the function type to
13540/// lookup.
13541///
13542/// @param abi_corpus the ABI corpus which to look the type up in.
13543///
13544/// @return the type definition if any was found, or a NULL pointer.
13545static function_type_sptr
13546lookup_function_type_through_translation_units(const interned_string& type_name,
13547 const corpus & abi_corpus)
13548{
13549 function_type_sptr result;
13550
13551 for (translation_units::const_iterator tu =
13552 abi_corpus.get_translation_units().begin();
13553 tu != abi_corpus.get_translation_units().end();
13554 ++tu)
13555 if ((result = lookup_function_type(type_name, **tu)))
13556 break;
13557
13558 return result;
13559}
13560
13561/// Lookup a type definition in all the translation units of a given
13562/// ABI corpus.
13563///
13564/// @param @param qn the fully qualified name of the type to lookup.
13565///
13566/// @param abi_corpus the ABI corpus which to look the type up in.
13567///
13568/// @return the type definition if any was found, or a NULL pointer.
13569type_base_sptr
13571 const corpus& abi_corpus)
13572{
13573 type_base_sptr result;
13574
13575 for (translation_units::const_iterator tu =
13576 abi_corpus.get_translation_units().begin();
13577 tu != abi_corpus.get_translation_units().end();
13578 ++tu)
13579 if ((result = lookup_type(qn, **tu)))
13580 break;
13581
13582 return result;
13583}
13584
13585/// Lookup a type from a given translation unit present in a give corpus.
13586///
13587/// @param type_name the name of the type to look for.
13588///
13589/// @parm tu_path the path of the translation unit to consider.
13590///
13591/// @param corp the corpus to consider.
13592///
13593/// @return the resulting type, if any.
13594type_base_sptr
13596 const string& tu_path,
13597 const corpus& corp)
13598{
13599 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13600 if (i == corp.priv_->path_tu_map.end())
13601 return type_base_sptr();
13602
13603 translation_unit_sptr tu = i->second;
13604 ABG_ASSERT(tu);
13605
13606 type_base_sptr t = lookup_type(type_name, *tu);
13607 return t;
13608}
13609
13610/// Look into an ABI corpus for a function type.
13611///
13612/// @param fn_type the function type to be looked for in the ABI
13613/// corpus.
13614///
13615/// @param corpus the ABI corpus into which to look for the function
13616/// type.
13617///
13618/// @return the function type found in the corpus.
13621 const corpus& corpus)
13622{
13623 ABG_ASSERT(fn_t);
13624
13625 function_type_sptr result;
13626
13627 if ((result = lookup_function_type(fn_t, corpus)))
13628 return result;
13629
13630 for (translation_units::const_iterator i =
13631 corpus.get_translation_units().begin();
13632 i != corpus.get_translation_units().end();
13633 ++i)
13635 **i)))
13636 return result;
13637
13638 return result;
13639}
13640
13641/// Look into a given corpus to find a type which has the same
13642/// qualified name as a giventype.
13643///
13644/// If the per-corpus type map is non-empty (because the corpus allows
13645/// the One Definition Rule) then the type islooked up in that
13646/// per-corpus type map. Otherwise, the type is looked-up in each
13647/// translation unit.
13648///
13649/// @param t the type which has the same qualified name as the type we
13650/// are looking for.
13651///
13652/// @param corp the ABI corpus to look into for the type.
13654lookup_basic_type(const type_decl& t, const corpus& corp)
13655{return lookup_basic_type(t.get_name(), corp);}
13656
13657/// Look into a given corpus to find a basic type which has a given
13658/// qualified name.
13659///
13660/// If the per-corpus type map is non-empty (because the corpus allows
13661/// the One Definition Rule) then the type islooked up in that
13662/// per-corpus type map. Otherwise, the type is looked-up in each
13663/// translation unit.
13664///
13665/// @param qualified_name the qualified name of the basic type to look
13666/// for.
13667///
13668/// @param corp the corpus to look into.
13670lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13671{
13673 type_decl_sptr result;
13674
13675 if (!m.empty())
13676 result = lookup_type_in_map<type_decl>(qualified_name, m);
13677 else
13678 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13679
13680 return result;
13681}
13682
13683/// Lookup a @ref type_decl type from a given corpus, by its location.
13684///
13685/// @param loc the location to consider.
13686///
13687/// @param corp the corpus to consider.
13688///
13689/// @return the resulting basic type, if any.
13692 const corpus &corp)
13693{
13696 type_decl_sptr result;
13697
13698 result = lookup_type_in_map<type_decl>(loc, m);
13699
13700 return result;
13701}
13702
13703/// Lookup a @ref type_decl type from a given corpus, by its location.
13704///
13705/// @param loc the location to consider.
13706///
13707/// @param corp the corpus to consider.
13708///
13709/// @return the resulting basic type, if any.
13711lookup_basic_type_per_location(const string &loc, const corpus &corp)
13712{
13713 const environment& env = corp.get_environment();
13714 return lookup_basic_type_per_location(env.intern(loc), corp);
13715}
13716
13717/// Look into a given corpus to find a basic type which has a given
13718/// qualified name.
13719///
13720/// If the per-corpus type map is non-empty (because the corpus allows
13721/// the One Definition Rule) then the type islooked up in that
13722/// per-corpus type map. Otherwise, the type is looked-up in each
13723/// translation unit.
13724///
13725/// @param qualified_name the qualified name of the basic type to look
13726/// for.
13727///
13728/// @param corp the corpus to look into.
13730lookup_basic_type(const string& qualified_name, const corpus& corp)
13731{
13732 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13733 corp);
13734}
13735
13736/// Look into a given corpus to find a class type which has the same
13737/// qualified name as a given type.
13738///
13739/// If the per-corpus type map is non-empty (because the corpus allows
13740/// the One Definition Rule) then the type islooked up in that
13741/// per-corpus type map. Otherwise, the type is looked-up in each
13742/// translation unit.
13743///
13744/// @param t the class decl type which has the same qualified name as
13745/// the type we are looking for.
13746///
13747/// @param corp the corpus to look into.
13750{
13752 return lookup_class_type(s, corp);
13753}
13754
13755/// Look into a given corpus to find a class type which has a given
13756/// qualified name.
13757///
13758/// If the per-corpus type map is non-empty (because the corpus allows
13759/// the One Definition Rule) then the type islooked up in that
13760/// per-corpus type map. Otherwise, the type is looked-up in each
13761/// translation unit.
13762///
13763/// @param qualified_name the qualified name of the type to look for.
13764///
13765/// @param corp the corpus to look into.
13767lookup_class_type(const string& qualified_name, const corpus& corp)
13768{
13769 interned_string s = corp.get_environment().intern(qualified_name);
13770 return lookup_class_type(s, corp);
13771}
13772
13773/// Look into a given corpus to find a class type which has a given
13774/// qualified name.
13775///
13776/// If the per-corpus type map is non-empty (because the corpus allows
13777/// the One Definition Rule) then the type islooked up in that
13778/// per-corpus type map. Otherwise, the type is looked-up in each
13779/// translation unit.
13780///
13781/// @param qualified_name the qualified name of the type to look for.
13782///
13783/// @param corp the corpus to look into.
13785lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13786{
13788
13789 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13790
13791 return result;
13792}
13793
13794/// Look into a given corpus to find the class type*s* that have a
13795/// given qualified name.
13796///
13797/// @param qualified_name the qualified name of the type to look for.
13798///
13799/// @param corp the corpus to look into.
13800///
13801/// @return the vector of class types named @p qualified_name.
13803lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13804{
13806
13807 return lookup_types_in_map(qualified_name, m);
13808}
13809
13810/// Look into a given corpus to find the class type*s* that have a
13811/// given qualified name and that are declaration-only.
13812///
13813/// @param qualified_name the qualified name of the type to look for.
13814///
13815/// @param corp the corpus to look into.
13816///
13817/// @param result the vector of decl-only class types named @p
13818/// qualified_name. This is populated iff the function returns true.
13819///
13820/// @return true iff @p result was populated with the decl-only
13821/// classes named @p qualified_name.
13822bool
13824 const corpus& corp,
13825 type_base_wptrs_type& result)
13826{
13828
13829 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13830 if (!v)
13831 return false;
13832
13833 for (auto type : *v)
13834 {
13835 type_base_sptr t(type);
13837 if (c->get_is_declaration_only()
13838 && !c->get_definition_of_declaration())
13839 result.push_back(type);
13840 }
13841
13842 return !result.empty();
13843}
13844
13845/// Look into a given corpus to find the union type*s* that have a
13846/// given qualified name.
13847///
13848/// @param qualified_name the qualified name of the type to look for.
13849///
13850/// @param corp the corpus to look into.
13851///
13852/// @return the vector of union types named @p qualified_name.
13854lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13855{
13857
13858 return lookup_types_in_map(qualified_name, m);
13859}
13860
13861/// Look into a given corpus to find the class type*s* that have a
13862/// given qualified name.
13863///
13864/// @param qualified_name the qualified name of the type to look for.
13865///
13866/// @param corp the corpus to look into.
13867///
13868/// @return the vector of class types which name is @p qualified_name.
13870lookup_class_types(const string& qualified_name, const corpus& corp)
13871{
13872 interned_string s = corp.get_environment().intern(qualified_name);
13873 return lookup_class_types(s, corp);
13874}
13875
13876/// Look into a given corpus to find the union types that have a given
13877/// qualified name.
13878///
13879/// @param qualified_name the qualified name of the type to look for.
13880///
13881/// @param corp the corpus to look into.
13882///
13883/// @return the vector of union types which name is @p qualified_name.
13885lookup_union_types(const string& qualified_name, const corpus& corp)
13886{
13887 interned_string s = corp.get_environment().intern(qualified_name);
13888 return lookup_union_types(s, corp);
13889}
13890
13891/// Look up a @ref class_decl from a given corpus by its location.
13892///
13893/// @param loc the location to consider.
13894///
13895/// @param corp the corpus to consider.
13896///
13897/// @return the resulting class decl, if any.
13900 const corpus& corp)
13901{
13904 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13905
13906 return result;
13907}
13908
13909/// Look up a @ref class_decl from a given corpus by its location.
13910///
13911/// @param loc the location to consider.
13912///
13913/// @param corp the corpus to consider.
13914///
13915/// @return the resulting class decl, if any.
13917lookup_class_type_per_location(const string &loc, const corpus &corp)
13918{
13919 const environment& env = corp.get_environment();
13920 return lookup_class_type_per_location(env.intern(loc), corp);
13921}
13922
13923/// Look into a given corpus to find a union type which has a given
13924/// qualified name.
13925///
13926/// If the per-corpus type map is non-empty (because the corpus allows
13927/// the One Definition Rule) then the type islooked up in that
13928/// per-corpus type map. Otherwise, the type is looked-up in each
13929/// translation unit.
13930///
13931/// @param qualified_name the qualified name of the type to look for.
13932///
13933/// @param corp the corpus to look into.
13934union_decl_sptr
13935lookup_union_type(const interned_string& type_name, const corpus& corp)
13936{
13938
13939 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13940 if (!result)
13941 result = lookup_union_type_through_translation_units(type_name, corp);
13942
13943 return result;
13944}
13945
13946/// Look into a given corpus to find a union type which has a given
13947/// qualified name.
13948///
13949/// If the per-corpus type map is non-empty (because the corpus allows
13950/// the One Definition Rule) then the type islooked up in that
13951/// per-corpus type map. Otherwise, the type is looked-up in each
13952/// translation unit.
13953///
13954/// @param qualified_name the qualified name of the type to look for.
13955///
13956/// @param corp the corpus to look into.
13957union_decl_sptr
13958lookup_union_type(const string& type_name, const corpus& corp)
13959{
13960 interned_string s = corp.get_environment().intern(type_name);
13961 return lookup_union_type(s, corp);
13962}
13963
13964/// Look into a given corpus to find an enum type which has the same
13965/// qualified name as a given enum type.
13966///
13967/// If the per-corpus type map is non-empty (because the corpus allows
13968/// the One Definition Rule) then the type islooked up in that
13969/// per-corpus type map. Otherwise, the type is looked-up in each
13970/// translation unit.
13971///
13972/// @param t the enum type which has the same qualified name as the
13973/// type we are looking for.
13974///
13975/// @param corp the corpus to look into.
13978{
13980 return lookup_enum_type(s, corp);
13981}
13982
13983/// Look into a given corpus to find an enum type which has a given
13984/// qualified name.
13985///
13986/// If the per-corpus type map is non-empty (because the corpus allows
13987/// the One Definition Rule) then the type islooked up in that
13988/// per-corpus type map. Otherwise, the type is looked-up in each
13989/// translation unit.
13990///
13991/// @param qualified_name the qualified name of the enum type to look
13992/// for.
13993///
13994/// @param corp the corpus to look into.
13996lookup_enum_type(const string& qualified_name, const corpus& corp)
13997{
13998 interned_string s = corp.get_environment().intern(qualified_name);
13999 return lookup_enum_type(s, corp);
14000}
14001
14002/// Look into a given corpus to find an enum type which has a given
14003/// qualified name.
14004///
14005/// If the per-corpus type map is non-empty (because the corpus allows
14006/// the One Definition Rule) then the type islooked up in that
14007/// per-corpus type map. Otherwise, the type is looked-up in each
14008/// translation unit.
14009///
14010/// @param qualified_name the qualified name of the enum type to look
14011/// for.
14012///
14013/// @param corp the corpus to look into.
14015lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
14016{
14018
14019 enum_type_decl_sptr result =
14020 lookup_type_in_map<enum_type_decl>(qualified_name, m);
14021 if (!result)
14022 result = lookup_enum_type_through_translation_units(qualified_name, corp);
14023
14024 return result;
14025}
14026
14027/// Look into a given corpus to find the enum type*s* that have a
14028/// given qualified name.
14029///
14030/// @param qualified_name the qualified name of the type to look for.
14031///
14032/// @param corp the corpus to look into.
14033///
14034/// @return the vector of enum types that which name is @p qualified_name.
14036lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
14037{
14039
14040 return lookup_types_in_map(qualified_name, m);
14041}
14042
14043/// Look into a given corpus to find the enum type*s* that have a
14044/// given qualified name.
14045///
14046/// @param qualified_name the qualified name of the type to look for.
14047///
14048/// @param corp the corpus to look into.
14049///
14050/// @return the vector of enum types that which name is @p qualified_name.
14052lookup_enum_types(const string& qualified_name, const corpus& corp)
14053{
14054 interned_string s = corp.get_environment().intern(qualified_name);
14055 return lookup_enum_types(s, corp);
14056}
14057
14058/// Look up an @ref enum_type_decl from a given corpus, by its location.
14059///
14060/// @param loc the location to consider.
14061///
14062/// @param corp the corpus to look the type from.
14063///
14064/// @return the resulting enum type, if any.
14067{
14070 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
14071
14072 return result;
14073}
14074
14075/// Look up an @ref enum_type_decl from a given corpus, by its location.
14076///
14077/// @param loc the location to consider.
14078///
14079/// @param corp the corpus to look the type from.
14080///
14081/// @return the resulting enum type, if any.
14083lookup_enum_type_per_location(const string &loc, const corpus &corp)
14084{
14085 const environment& env = corp.get_environment();
14086 return lookup_enum_type_per_location(env.intern(loc), corp);
14087}
14088
14089/// Look into a given corpus to find a typedef type which has the
14090/// same qualified name as a given typedef type.
14091///
14092/// If the per-corpus type map is non-empty (because the corpus allows
14093/// the One Definition Rule) then the type islooked up in that
14094/// per-corpus type map. Otherwise, the type is looked-up in each
14095/// translation unit.
14096///
14097/// @param t the typedef type which has the same qualified name as the
14098/// typedef type we are looking for.
14099///
14100/// @param corp the corpus to look into.
14103{
14105 return lookup_typedef_type(s, corp);
14106}
14107
14108/// Look into a given corpus to find a typedef type which has the
14109/// same qualified name as a given typedef type.
14110///
14111/// If the per-corpus type map is non-empty (because the corpus allows
14112/// the One Definition Rule) then the type islooked up in that
14113/// per-corpus type map. Otherwise, the type is looked-up in each
14114/// translation unit.
14115///
14116/// @param t the typedef type which has the same qualified name as the
14117/// typedef type we are looking for.
14118///
14119/// @param corp the corpus to look into.
14121lookup_typedef_type(const string& qualified_name, const corpus& corp)
14122{
14123 interned_string s = corp.get_environment().intern(qualified_name);
14124 return lookup_typedef_type(s, corp);
14125}
14126
14127/// Look into a given corpus to find a typedef type which has a
14128/// given qualified name.
14129///
14130/// If the per-corpus type map is non-empty (because the corpus allows
14131/// the One Definition Rule) then the type islooked up in that
14132/// per-corpus type map. Otherwise, the type is looked-up in each
14133/// translation unit.
14134///
14135/// @param qualified_name the qualified name of the typedef type to
14136/// look for.
14137///
14138/// @param corp the corpus to look into.
14140lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
14141{
14143
14144 typedef_decl_sptr result =
14145 lookup_type_in_map<typedef_decl>(qualified_name, m);
14146 if (!result)
14147 result = lookup_typedef_type_through_translation_units(qualified_name,
14148 corp);
14149
14150 return result;
14151}
14152
14153/// Lookup a @ref typedef_decl from a corpus, by its location.
14154///
14155/// @param loc the location to consider.
14156///
14157/// @param corp the corpus to consider.
14158///
14159/// @return the typedef_decl found, if any.
14162{
14165 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
14166
14167 return result;
14168}
14169
14170/// Lookup a @ref typedef_decl from a corpus, by its location.
14171///
14172/// @param loc the location to consider.
14173///
14174/// @param corp the corpus to consider.
14175///
14176/// @return the typedef_decl found, if any.
14178lookup_typedef_type_per_location(const string &loc, const corpus &corp)
14179{
14180 const environment& env = corp.get_environment();
14181 return lookup_typedef_type_per_location(env.intern(loc), corp);
14182}
14183
14184/// Look into a corpus to find a class, union or typedef type which
14185/// has a given qualified name.
14186///
14187/// If the per-corpus type map is non-empty (because the corpus allows
14188/// the One Definition Rule) then the type islooked up in that
14189/// per-corpus type map. Otherwise, the type is looked-up in each
14190/// translation unit.
14191///
14192/// @param qualified_name the name of the type to find.
14193///
14194/// @param corp the corpus to look into.
14195///
14196/// @return the typedef or class type found.
14197type_base_sptr
14198lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
14199{
14200 type_base_sptr result = lookup_class_type(qualified_name, corp);
14201 if (!result)
14202 result = lookup_union_type(qualified_name, corp);
14203
14204 if (!result)
14205 result = lookup_typedef_type(qualified_name, corp);
14206 return result;
14207}
14208
14209/// Look into a corpus to find a class, typedef or enum type which has
14210/// a given qualified name.
14211///
14212/// If the per-corpus type map is non-empty (because the corpus allows
14213/// the One Definition Rule) then the type islooked up in that
14214/// per-corpus type map. Otherwise, the type is looked-up in each
14215/// translation unit.
14216///
14217/// @param qualified_name the qualified name of the type to look for.
14218///
14219/// @param corp the corpus to look into.
14220///
14221/// @return the typedef, class or enum type found.
14222type_base_sptr
14223lookup_class_typedef_or_enum_type(const string& qualified_name,
14224 const corpus& corp)
14225{
14226 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
14227 if (!result)
14228 result = lookup_enum_type(qualified_name, corp);
14229
14230 return result;
14231}
14232
14233/// Look into a given corpus to find a qualified type which has the
14234/// same qualified name as a given type.
14235///
14236/// @param t the type which has the same qualified name as the
14237/// qualified type we are looking for.
14238///
14239/// @param corp the corpus to look into.
14240///
14241/// @return the qualified type found.
14242qualified_type_def_sptr
14244{
14246 return lookup_qualified_type(s, corp);
14247}
14248
14249/// Look into a given corpus to find a qualified type which has a
14250/// given qualified name.
14251///
14252/// @param qualified_name the qualified name of the type to look for.
14253///
14254/// @param corp the corpus to look into.
14255///
14256/// @return the type found.
14257qualified_type_def_sptr
14258lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
14259{
14261 corp.get_types().qualified_types();
14262
14263 qualified_type_def_sptr result =
14264 lookup_type_in_map<qualified_type_def>(qualified_name, m);
14265
14266 if (!result)
14267 result = lookup_qualified_type_through_translation_units(qualified_name,
14268 corp);
14269
14270 return result;
14271}
14272
14273/// Look into a given corpus to find a pointer type which has the same
14274/// qualified name as a given pointer type.
14275///
14276/// @param t the pointer type which has the same qualified name as the
14277/// type we are looking for.
14278///
14279/// @param corp the corpus to look into.
14280///
14281/// @return the pointer type found.
14284{
14286 return lookup_pointer_type(s, corp);
14287}
14288
14289/// Look into a given corpus to find a pointer type which has a given
14290/// qualified name.
14291///
14292/// If the per-corpus type map is non-empty (because the corpus allows
14293/// the One Definition Rule) then the type islooked up in that
14294/// per-corpus type map. Otherwise, the type is looked-up in each
14295/// translation unit.
14296///
14297/// @param qualified_name the qualified name of the pointer type to
14298/// look for.
14299///
14300/// @param corp the corpus to look into.
14301///
14302/// @return the pointer type found.
14304lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
14305{
14307
14308 pointer_type_def_sptr result =
14309 lookup_type_in_map<pointer_type_def>(qualified_name, m);
14310 if (!result)
14311 result = lookup_pointer_type_through_translation_units(qualified_name,
14312 corp);
14313
14314 return result;
14315}
14316
14317/// Look into a given corpus to find a reference type which has the
14318/// same qualified name as a given reference type.
14319///
14320/// If the per-corpus type map is non-empty (because the corpus allows
14321/// the One Definition Rule) then the type islooked up in that
14322/// per-corpus type map. Otherwise, the type is looked-up in each
14323/// translation unit.
14324///
14325/// @param t the reference type which has the same qualified name as
14326/// the reference type we are looking for.
14327///
14328/// @param corp the corpus to look into.
14329///
14330/// @return the reference type found.
14333{
14335 return lookup_reference_type(s, corp);
14336}
14337
14338/// Look into a given corpus to find a reference type which has a
14339/// given qualified name.
14340///
14341/// If the per-corpus type map is non-empty (because the corpus allows
14342/// the One Definition Rule) then the type islooked up in that
14343/// per-corpus type map. Otherwise, the type is looked-up in each
14344/// translation unit.
14345///
14346/// @param qualified_name the qualified name of the reference type to
14347/// look for.
14348///
14349/// @param corp the corpus to look into.
14350///
14351/// @return the reference type found.
14353lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
14354{
14356 corp.get_types().reference_types();
14357
14359 lookup_type_in_map<reference_type_def>(qualified_name, m);
14360 if (!result)
14361 result = lookup_reference_type_through_translation_units(qualified_name,
14362 corp);
14363
14364 return result;
14365}
14366
14367/// Look into a given corpus to find an array type which has a given
14368/// qualified name.
14369///
14370/// If the per-corpus type map is non-empty (because the corpus allows
14371/// the One Definition Rule) then the type islooked up in that
14372/// per-corpus type map. Otherwise, the type is looked-up in each
14373/// translation unit.
14374///
14375/// @param qualified_name the qualified name of the array type to look
14376/// for.
14377///
14378/// @param corp the corpus to look into.
14379///
14380/// @return the array type found.
14383{
14385 return lookup_array_type(s, corp);
14386}
14387
14388/// Look into a given corpus to find an array type which has the same
14389/// qualified name as a given array type.
14390///
14391/// If the per-corpus type map is non-empty (because the corpus allows
14392/// the One Definition Rule) then the type islooked up in that
14393/// per-corpus type map. Otherwise, the type is looked-up in each
14394/// translation unit.
14395///
14396/// @param t the type which has the same qualified name as the type we
14397/// are looking for.
14398///
14399/// @param corp the corpus to look into.
14400///
14401/// @return the type found.
14403lookup_array_type(const interned_string& qualified_name, const corpus& corp)
14404{
14406
14407 array_type_def_sptr result =
14408 lookup_type_in_map<array_type_def>(qualified_name, m);
14409 if (!result)
14410 result = lookup_array_type_through_translation_units(qualified_name, corp);
14411
14412 return result;
14413}
14414
14415/// Look into a given corpus to find a function type which has the same
14416/// qualified name as a given function type.
14417///
14418/// If the per-corpus type map is non-empty (because the corpus allows
14419/// the One Definition Rule) then the type islooked up in that
14420/// per-corpus type map. Otherwise, the type is looked-up in each
14421/// translation unit.
14422///
14423/// @param t the function type which has the same qualified name as
14424/// the function type we are looking for.
14425///
14426/// @param corp the corpus to look into.
14427///
14428/// @return the function type found.
14431{
14432 interned_string type_name = get_type_name(t);
14433 return lookup_function_type(type_name, corp);
14434}
14435
14436/// Look into a given corpus to find a function type which has the same
14437/// qualified name as a given function type.
14438///
14439/// If the per-corpus type map is non-empty (because the corpus allows
14440/// the One Definition Rule) then the type islooked up in that
14441/// per-corpus type map. Otherwise, the type is looked-up in each
14442/// translation unit.
14443///
14444/// @param t the function type which has the same qualified name as
14445/// the function type we are looking for.
14446///
14447/// @param corp the corpus to look into.
14448///
14449/// @return the function type found.
14452 const corpus& corpus)
14453{
14454 if (fn_t)
14455 return lookup_function_type(*fn_t, corpus);
14456 return function_type_sptr();
14457}
14458
14459/// Look into a given corpus to find a function type which has a given
14460/// qualified name.
14461///
14462/// If the per-corpus type map is non-empty (because the corpus allows
14463/// the One Definition Rule) then the type islooked up in that
14464/// per-corpus type map. Otherwise, the type is looked-up in each
14465/// translation unit.
14466///
14467/// @param qualified_name the qualified name of the function type to
14468/// look for.
14469///
14470/// @param corp the corpus to look into.
14471///
14472/// @return the function type found.
14474lookup_function_type(const interned_string& qualified_name, const corpus& corp)
14475{
14477
14478 function_type_sptr result =
14479 lookup_type_in_map<function_type>(qualified_name, m);
14480 if (!result)
14481 result = lookup_function_type_through_translation_units(qualified_name,
14482 corp);
14483
14484 return result;
14485}
14486
14487/// Look into a given corpus to find a type which has a given
14488/// qualified name.
14489///
14490/// If the per-corpus type map is non-empty (because the corpus allows
14491/// the One Definition Rule) then the type islooked up in that
14492/// per-corpus type map. Otherwise, the type is looked-up in each
14493/// translation unit.
14494///
14495/// @param qualified_name the qualified name of the function type to
14496/// look for.
14497///
14498/// @param corp the corpus to look into.
14499///
14500/// @return the function type found.
14501type_base_sptr
14502lookup_type(const interned_string& n, const corpus& corp)
14503{
14504 type_base_sptr result;
14505
14506 ((result = lookup_basic_type(n, corp))
14507 || (result = lookup_class_type(n, corp))
14508 || (result = lookup_union_type(n, corp))
14509 || (result = lookup_enum_type(n, corp))
14510 || (result = lookup_typedef_type(n, corp))
14511 || (result = lookup_qualified_type(n, corp))
14512 || (result = lookup_pointer_type(n, corp))
14513 || (result = lookup_reference_type(n, corp))
14514 || (result = lookup_array_type(n, corp))
14515 || (result= lookup_function_type(n, corp)));
14516
14517 return result;
14518}
14519
14520/// Lookup a type from a corpus, by its location.
14521///
14522/// @param loc the location to consider.
14523///
14524/// @param corp the corpus to look the type from.
14525///
14526/// @return the resulting type, if any found.
14527type_base_sptr
14529{
14530 // TODO: finish this.
14531
14532 //TODO: when we fully support types indexed by their location, this
14533 //function should return a vector of types because at each location,
14534 //there can be several types that are defined (yay, C and C++,
14535 //*sigh*).
14536
14537 type_base_sptr result;
14538 ((result = lookup_basic_type_per_location(loc, corp))
14539 || (result = lookup_class_type_per_location(loc, corp))
14540 || (result = lookup_union_type_per_location(loc, corp))
14541 || (result = lookup_enum_type_per_location(loc, corp))
14542 || (result = lookup_typedef_type_per_location(loc, corp)));
14543
14544 return result;
14545}
14546
14547/// Look into a given corpus to find a type
14548///
14549/// If the per-corpus type map is non-empty (because the corpus allows
14550/// the One Definition Rule) then the type islooked up in that
14551/// per-corpus type map. Otherwise, the type is looked-up in each
14552/// translation unit.
14553///
14554/// @param qualified_name the qualified name of the function type to
14555/// look for.
14556///
14557/// @param corp the corpus to look into.
14558///
14559/// @return the function type found.
14560type_base_sptr
14561lookup_type(const type_base&t, const corpus& corp)
14562{
14564 return lookup_type(n, corp);
14565}
14566
14567/// Look into a given corpus to find a type
14568///
14569/// If the per-corpus type map is non-empty (because the corpus allows
14570/// the One Definition Rule) then the type islooked up in that
14571/// per-corpus type map. Otherwise, the type is looked-up in each
14572/// translation unit.
14573///
14574/// @param qualified_name the qualified name of the function type to
14575/// look for.
14576///
14577/// @param corp the corpus to look into.
14578///
14579/// @return the function type found.
14580type_base_sptr
14581lookup_type(const type_base_sptr&t, const corpus& corp)
14582{
14583 if (t)
14584 return lookup_type(*t, corp);
14585 return type_base_sptr();
14586}
14587
14588/// Update the map that associates a fully qualified name of a given
14589/// type to that type.
14590///
14591///
14592/// @param type the type we are considering.
14593///
14594/// @param types_map the map to update. It's a map that assciates a
14595/// fully qualified name of a type to the type itself.
14596///
14597/// @param use_type_name_as_key if true, use the name of the type as
14598/// the key to look it up later. If false, then use the location of
14599/// the type as a key to look it up later.
14600///
14601/// @return true iff the type was added to the map.
14602template<typename TypeKind>
14603bool
14604maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14606 bool use_type_name_as_key = true)
14607{
14609
14610 if (use_type_name_as_key)
14611 s = get_type_name(type);
14612 else if (location l = type->get_location())
14613 {
14614 string str = l.expand();
14615 s = type->get_environment().intern(str);
14616 }
14617
14618 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14619 bool result = false;
14620
14621 if (i == types_map.end())
14622 {
14623 types_map[s].push_back(type);
14624 result = true;
14625 }
14626 else
14627 i->second.push_back(type);
14628
14629 return result;
14630}
14631
14632/// This is the specialization for type @ref class_decl of the
14633/// function template:
14634///
14635/// maybe_update_types_lookup_map<T>(scope_decl*,
14636/// const shared_ptr<T>&,
14637/// istring_type_base_wptrs_map_type&)
14638///
14639/// @param class_type the type to consider.
14640///
14641/// @param types_map the type map to update.
14642///
14643/// @return true iff the type was added to the map.
14644template<>
14645bool
14648 bool use_type_name_as_key)
14649{
14650 class_decl_sptr type = class_type;
14651
14652 bool update_qname_map = true;
14653 if (type->get_is_declaration_only())
14654 {
14655 // Let's try to look through decl-only classes to get their
14656 // definition. But if the class doesn't have a definition then
14657 // we'll keep it.
14658 if (class_decl_sptr def =
14659 is_class_type(class_type->get_definition_of_declaration()))
14660 type = def;
14661 }
14662
14663 if (!update_qname_map)
14664 return false;
14665
14667 if (use_type_name_as_key)
14668 {
14669 string qname = type->get_qualified_name();
14670 s = type->get_environment().intern(qname);
14671 }
14672 else if (location l = type->get_location())
14673 {
14674 string str = l.expand();
14675 s = type->get_environment().intern(str);
14676 }
14677
14678 bool result = false;
14679 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14680 if (i == map.end())
14681 {
14682 map[s].push_back(type);
14683 result = true;
14684 }
14685 else
14686 i->second.push_back(type);
14687
14688 return result;
14689}
14690
14691/// This is the specialization for type @ref function_type of the
14692/// function template:
14693///
14694/// maybe_update_types_lookup_map<T>(scope_decl*,
14695/// const shared_ptr<T>&,
14696/// istring_type_base_wptrs_map_type&)
14697///
14698/// @param scope the scope of the type to consider.
14699///
14700/// @param class_type the type to consider.
14701///
14702/// @param types_map the type map to update.
14703///
14704/// @return true iff the type was added to the map.
14705template<>
14706bool
14708(const function_type_sptr& type,
14710 bool /*use_type_name_as_key*/)
14711{
14712 bool result = false;
14714 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14715 if (i == types_map.end())
14716 {
14717 types_map[s].push_back(type);
14718 result = true;
14719 }
14720 else
14721 i->second.push_back(type);
14722
14723 return result;
14724}
14725
14726/// Update the map that associates the fully qualified name of a basic
14727/// type with the type itself.
14728///
14729/// The per-translation unit type map is updated if no type with this
14730/// name was already existing in that map.
14731///
14732/// If no type with this name did already exist in the per-corpus type
14733/// map, then that per-corpus type map is updated. Otherwise, that
14734/// type is erased from that per-corpus map.
14735///
14736/// @param basic_type the basic type to consider.
14737void
14739{
14740 if (translation_unit *tu = basic_type->get_translation_unit())
14742 (basic_type, tu->get_types().basic_types());
14743
14744 if (corpus *type_corpus = basic_type->get_corpus())
14745 {
14747 (basic_type,
14748 type_corpus->priv_->get_types().basic_types());
14749
14751 (basic_type,
14752 type_corpus->get_type_per_loc_map().basic_types(),
14753 /*use_type_name_as_key*/false);
14754
14755 if (corpus *group = type_corpus->get_group())
14756 {
14758 (basic_type,
14759 group->priv_->get_types().basic_types());
14760
14762 (basic_type,
14763 group->get_type_per_loc_map().basic_types(),
14764 /*use_type_name_as_key*/false);
14765 }
14766 }
14767
14768}
14769
14770/// Update the map that associates the fully qualified name of a class
14771/// type with the type itself.
14772///
14773/// The per-translation unit type map is updated if no type with this
14774/// name was already existing in that map.
14775///
14776/// If no type with this name did already exist in the per-corpus type
14777/// map, then that per-corpus type map is updated. Otherwise, that
14778/// type is erased from that per-corpus map.
14779///
14780/// @param class_type the class type to consider.
14781void
14783{
14784 if (translation_unit *tu = class_type->get_translation_unit())
14786 (class_type, tu->get_types().class_types());
14787
14788 if (corpus *type_corpus = class_type->get_corpus())
14789 {
14791 (class_type,
14792 type_corpus->priv_->get_types().class_types());
14793
14795 (class_type,
14796 type_corpus->get_type_per_loc_map().class_types(),
14797 /*use_type_name_as_key*/false);
14798
14799 if (corpus *group = type_corpus->get_group())
14800 {
14802 (class_type,
14803 group->priv_->get_types().class_types());
14804
14806 (class_type,
14807 group->get_type_per_loc_map().class_types(),
14808 /*use_type_name_as_key*/false);
14809 }
14810 }
14811}
14812
14813/// Update the map that associates the fully qualified name of a union
14814/// type with the type itself.
14815///
14816/// The per-translation unit type map is updated if no type with this
14817/// name was already existing in that map.
14818///
14819/// If no type with this name did already exist in the per-corpus type
14820/// map, then that per-corpus type map is updated. Otherwise, that
14821/// type is erased from that per-corpus map.
14822///
14823/// @param union_type the union type to consider.
14824void
14825maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14826{
14827 if (translation_unit *tu = union_type->get_translation_unit())
14829 (union_type, tu->get_types().union_types());
14830
14831 if (corpus *type_corpus = union_type->get_corpus())
14832 {
14834 (union_type,
14835 type_corpus->priv_->get_types().union_types());
14836
14838 (union_type,
14839 type_corpus->get_type_per_loc_map().union_types(),
14840 /*use_type_name_as_key*/false);
14841
14842 if (corpus *group = type_corpus->get_group())
14843 {
14845 (union_type,
14846 group->priv_->get_types().union_types());
14847
14849 (union_type,
14850 group->get_type_per_loc_map().union_types(),
14851 /*use_type_name_as_key*/false);
14852 }
14853 }
14854}
14855
14856/// Update the map that associates the fully qualified name of an enum
14857/// type with the type itself.
14858///
14859/// The per-translation unit type map is updated if no type with this
14860/// name was already existing in that map.
14861///
14862/// If no type with this name did already exist in the per-corpus type
14863/// map, then that per-corpus type map is updated. Otherwise, that
14864/// type is erased from that per-corpus map.
14865///
14866/// @param enum_type the type to consider.
14867void
14869{
14870 if (translation_unit *tu = enum_type->get_translation_unit())
14872 (enum_type, tu->get_types().enum_types());
14873
14874 if (corpus *type_corpus = enum_type->get_corpus())
14875 {
14877 (enum_type,
14878 type_corpus->priv_->get_types().enum_types());
14879
14881 (enum_type,
14882 type_corpus->get_type_per_loc_map().enum_types(),
14883 /*use_type_name_as_key*/false);
14884
14885 if (corpus *group = type_corpus->get_group())
14886 {
14888 (enum_type,
14889 group->priv_->get_types().enum_types());
14890
14892 (enum_type,
14893 group->get_type_per_loc_map().enum_types(),
14894 /*use_type_name_as_key*/false);
14895 }
14896 }
14897
14898}
14899
14900/// Update the map that associates the fully qualified name of a
14901/// typedef type with the type itself.
14902///
14903/// The per-translation unit type map is updated if no type with this
14904/// name was already existing in that map.
14905///
14906/// If no type with this name did already exist in the per-corpus type
14907/// map, then that per-corpus type map is updated. Otherwise, that
14908/// type is erased from that per-corpus map.
14909///
14910/// @param typedef_type the type to consider.
14911void
14913{
14914 if (translation_unit *tu = typedef_type->get_translation_unit())
14916 (typedef_type, tu->get_types().typedef_types());
14917
14918 if (corpus *type_corpus = typedef_type->get_corpus())
14919 {
14921 (typedef_type,
14922 type_corpus->priv_->get_types().typedef_types());
14923
14925 (typedef_type,
14926 type_corpus->get_type_per_loc_map().typedef_types(),
14927 /*use_type_name_as_key*/false);
14928
14929 if (corpus *group = type_corpus->get_group())
14930 {
14932 (typedef_type,
14933 group->priv_->get_types().typedef_types());
14934
14936 (typedef_type,
14937 group->get_type_per_loc_map().typedef_types(),
14938 /*use_type_name_as_key*/false);
14939 }
14940 }
14941}
14942
14943/// Update the map that associates the fully qualified name of a
14944/// qualified type with the type itself.
14945///
14946/// The per-translation unit type map is updated if no type with this
14947/// name was already existing in that map.
14948///
14949/// If no type with this name did already exist in the per-corpus type
14950/// map, then that per-corpus type map is updated. Otherwise, that
14951/// type is erased from that per-corpus map.
14952///
14953/// @param qualified_type the type to consider.
14954void
14955maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14956{
14957 if (translation_unit *tu = qualified_type->get_translation_unit())
14959 (qualified_type, tu->get_types().qualified_types());
14960
14961 if (corpus *type_corpus = qualified_type->get_corpus())
14962 {
14964 (qualified_type,
14965 type_corpus->priv_->get_types().qualified_types());
14966
14967 if (corpus *group = type_corpus->get_group())
14968 {
14970 (qualified_type,
14971 group->priv_->get_types().qualified_types());
14972 }
14973 }
14974}
14975
14976/// Update the map that associates the fully qualified name of a
14977/// pointer type with the type itself.
14978///
14979/// The per-translation unit type map is updated if no type with this
14980/// name was already existing in that map.
14981///
14982/// If no type with this name did already exist in the per-corpus type
14983/// map, then that per-corpus type map is updated. Otherwise, that
14984/// type is erased from that per-corpus map.
14985///
14986/// @param pointer_type the type to consider.
14987void
14989{
14990 if (translation_unit *tu = pointer_type->get_translation_unit())
14992 (pointer_type, tu->get_types().pointer_types());
14993
14994 if (corpus *type_corpus = pointer_type->get_corpus())
14995 {
14997 (pointer_type,
14998 type_corpus->priv_->get_types().pointer_types());
14999
15000 if (corpus *group = type_corpus->get_group())
15001 {
15003 (pointer_type,
15004 group->priv_->get_types().pointer_types());
15005 }
15006 }
15007}
15008
15009/// Update the map that associates the fully qualified name of a
15010/// pointer-to-member type with the type itself.
15011///
15012/// The per-translation unit type map is updated if no type with this
15013/// name was already existing in that map.
15014///
15015/// If no type with this name did already exist in the per-corpus type
15016/// map, then that per-corpus type map is updated. Otherwise, that
15017/// type is erased from that per-corpus map.
15018///
15019/// @param ptr_to_mbr_type the type to consider.
15020void
15022{
15023 if (translation_unit *tu = ptr_to_member->get_translation_unit())
15025 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
15026
15027 if (corpus *type_corpus = ptr_to_member->get_corpus())
15028 {
15030 (ptr_to_member,
15031 type_corpus->priv_->get_types().ptr_to_mbr_types());
15032
15033 if (corpus *group = type_corpus->get_group())
15034 {
15036 (ptr_to_member,
15037 group->priv_->get_types().ptr_to_mbr_types());
15038 }
15039 }
15040}
15041
15042/// Update the map that associates the fully qualified name of a
15043/// reference type with the type itself.
15044///
15045/// The per-translation unit type map is updated if no type with this
15046/// name was already existing in that map.
15047///
15048/// If no type with this name did already exist in the per-corpus type
15049/// map, then that per-corpus type map is updated. Otherwise, that
15050/// type is erased from that per-corpus map.
15051///
15052/// @param reference_type the type to consider.
15053void
15055{
15056 if (translation_unit *tu = reference_type->get_translation_unit())
15058 (reference_type, tu->get_types().reference_types());
15059
15060 if (corpus *type_corpus = reference_type->get_corpus())
15061 {
15063 (reference_type,
15064 type_corpus->priv_->get_types().reference_types());
15065
15066 if (corpus *group = type_corpus->get_group())
15067 {
15069 (reference_type,
15070 group->priv_->get_types().reference_types());
15071 }
15072 }
15073}
15074
15075/// Update the map that associates the fully qualified name of a type
15076/// with the type itself.
15077///
15078/// The per-translation unit type map is updated if no type with this
15079/// name was already existing in that map.
15080///
15081/// If no type with this name did already exist in the per-corpus type
15082/// map, then that per-corpus type map is updated. Otherwise, that
15083/// type is erased from that per-corpus map.
15084///
15085/// @param array_type the type to consider.
15086void
15088{
15089 if (translation_unit *tu = array_type->get_translation_unit())
15091 (array_type, tu->get_types().array_types());
15092
15093 if (corpus *type_corpus = array_type->get_corpus())
15094 {
15096 (array_type,
15097 type_corpus->priv_->get_types().array_types());
15098
15100 (array_type,
15101 type_corpus->get_type_per_loc_map().array_types(),
15102 /*use_type_name_as_key*/false);
15103
15104 if (corpus *group = type_corpus->get_group())
15105 {
15107 (array_type,
15108 group->priv_->get_types().array_types());
15109
15111 (array_type,
15112 group->get_type_per_loc_map().array_types(),
15113 /*use_type_name_as_key*/false);
15114 }
15115 }
15116}
15117
15118/// Update the map that associates the fully qualified name of a type
15119/// with the type itself.
15120///
15121/// The per-translation unit type map is updated if no type with this
15122/// name was already existing in that map.
15123///
15124/// If no type with this name did already exist in the per-corpus type
15125/// map, then that per-corpus type map is updated. Otherwise, that
15126/// type is erased from that per-corpus map.
15127///
15128/// @param subrange_type the type to consider.
15129void
15131(const array_type_def::subrange_sptr& subrange_type)
15132{
15133 if (translation_unit *tu = subrange_type->get_translation_unit())
15135 (subrange_type, tu->get_types().subrange_types());
15136
15137 if (corpus *type_corpus = subrange_type->get_corpus())
15138 {
15140 (subrange_type,
15141 type_corpus->priv_->get_types().subrange_types());
15142
15144 (subrange_type,
15145 type_corpus->get_type_per_loc_map().subrange_types(),
15146 /*use_type_name_as_key*/false);
15147
15148 if (corpus *group = subrange_type->get_corpus())
15149 {
15151 (subrange_type,
15152 group->priv_->get_types().subrange_types());
15153
15155 (subrange_type,
15156 group->get_type_per_loc_map().subrange_types(),
15157 /*use_type_name_as_key*/false);
15158 }
15159 }
15160}
15161
15162/// Update the map that associates the fully qualified name of a
15163/// function type with the type itself.
15164///
15165/// The per-translation unit type map is updated if no type with this
15166/// name was already existing in that map.
15167///
15168/// If no type with this name did already exist in the per-corpus type
15169/// map, then that per-corpus type map is updated. Otherwise, that
15170/// type is erased from that per-corpus map.
15171///
15172/// @param scope the scope of the function type.
15173/// @param fn_type the type to consider.
15174void
15176{
15177 if (translation_unit *tu = fn_type->get_translation_unit())
15179 (fn_type, tu->get_types().function_types());
15180
15181 if (corpus *type_corpus = fn_type->get_corpus())
15182 {
15184 (fn_type,
15185 type_corpus->priv_->get_types().function_types());
15186
15187 if (corpus *group = fn_type->get_corpus())
15188 {
15190 (fn_type,
15191 group->priv_->get_types().function_types());
15192 }
15193 }
15194}
15195
15196/// Update the map that associates the fully qualified name of a type
15197/// declaration with the type itself.
15198///
15199/// The per-translation unit type map is updated if no type with this
15200/// name was already existing in that map.
15201///
15202/// If no type with this name did already exist in the per-corpus type
15203/// map, then that per-corpus type map is updated. Otherwise, that
15204/// type is erased from that per-corpus map.
15205///
15206/// @param decl the declaration of the type to consider.
15207void
15208maybe_update_types_lookup_map(const decl_base_sptr& decl)
15209{
15210 if (!is_type(decl))
15211 return;
15212
15213 if (type_decl_sptr basic_type = is_type_decl(decl))
15215 else if (class_decl_sptr class_type = is_class_type(decl))
15217 else if (union_decl_sptr union_type = is_union_type(decl))
15219 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
15221 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
15222 maybe_update_types_lookup_map(typedef_type);
15223 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
15224 maybe_update_types_lookup_map(qualified_type);
15225 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
15226 maybe_update_types_lookup_map(pointer_type);
15227 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
15228 maybe_update_types_lookup_map(ptr_to_member);
15229 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
15230 maybe_update_types_lookup_map(reference_type);
15231 else if (array_type_def_sptr array_type = is_array_type(decl))
15233 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
15234 maybe_update_types_lookup_map(subrange_type);
15235 else if (function_type_sptr fn_type = is_function_type(decl))
15237 else
15239}
15240
15241/// Update the map that associates the fully qualified name of a type
15242/// with the type itself.
15243///
15244/// The per-translation unit type map is updated if no type with this
15245/// name was already existing in that map.
15246///
15247/// If no type with this name did already exist in the per-corpus type
15248/// map, then that per-corpus type map is updated. Otherwise, that
15249/// type is erased from that per-corpus map.
15250///
15251/// @param type the type to consider.
15252void
15253maybe_update_types_lookup_map(const type_base_sptr& type)
15254{
15255 if (decl_base_sptr decl = get_type_declaration(type))
15257 else if (function_type_sptr fn_type = is_function_type(type))
15259 else
15261}
15262
15263//--------------------------------
15264// </type and decls lookup stuff>
15265// ------------------------------
15266
15267/// In a translation unit, lookup a given type or synthesize it if
15268/// it's a qualified type.
15269///
15270/// So this function first looks the type up in the translation unit.
15271/// If it's found, then OK, it's returned. Otherwise, if it's a
15272/// qualified, reference or pointer or function type (a composite
15273/// type), lookup the underlying type, synthesize the type we want
15274/// from it and return it.
15275///
15276/// If the underlying types is not not found, then give up and return
15277/// nil.
15278///
15279/// @return the type that was found or the synthesized type.
15280type_base_sptr
15281synthesize_type_from_translation_unit(const type_base_sptr& type,
15282 translation_unit& tu)
15283{
15284 type_base_sptr result;
15285
15286 result = lookup_type(type, tu);
15287
15288 if (!result)
15289 {
15290 if (qualified_type_def_sptr qual = is_qualified_type(type))
15291 {
15292 type_base_sptr underlying_type =
15293 synthesize_type_from_translation_unit(qual->get_underlying_type(),
15294 tu);
15295 if (underlying_type)
15296 {
15297 result.reset(new qualified_type_def(underlying_type,
15298 qual->get_cv_quals(),
15299 qual->get_location()));
15300 }
15301 }
15302 else if (pointer_type_def_sptr p = is_pointer_type(type))
15303 {
15304 type_base_sptr pointed_to_type =
15305 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
15306 tu);
15307 if (pointed_to_type)
15308 {
15309 result.reset(new pointer_type_def(pointed_to_type,
15310 p->get_size_in_bits(),
15311 p->get_alignment_in_bits(),
15312 p->get_location()));
15313 }
15314 }
15315 else if (reference_type_def_sptr r = is_reference_type(type))
15316 {
15317 type_base_sptr pointed_to_type =
15318 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
15319 if (pointed_to_type)
15320 {
15321 result.reset(new reference_type_def(pointed_to_type,
15322 r->is_lvalue(),
15323 r->get_size_in_bits(),
15324 r->get_alignment_in_bits(),
15325 r->get_location()));
15326 }
15327 }
15328 else if (function_type_sptr f = is_function_type(type))
15330
15331 if (result)
15332 {
15334 canonicalize(result);
15335 }
15336 }
15337
15338 if (result)
15339 tu.priv_->synthesized_types_.push_back(result);
15340
15341 return result;
15342}
15343
15344/// In a translation unit, lookup the sub-types that make up a given
15345/// function type and if the sub-types are all found, synthesize and
15346/// return a function_type with them.
15347///
15348/// This function is like lookup_function_type_in_translation_unit()
15349/// execept that it constructs the function type from the sub-types
15350/// found in the translation, rather than just looking for the
15351/// function types held by the translation unit. This can be useful
15352/// if the translation unit doesnt hold the function type we are
15353/// looking for (i.e, lookup_function_type_in_translation_unit()
15354/// returned NULL) but we still want to see if the sub-types of the
15355/// function types are present in the translation unit.
15356///
15357/// @param fn_type the function type to consider.
15358///
15359/// @param tu the translation unit to look into.
15360///
15361/// @return the resulting synthesized function type if all its
15362/// sub-types have been found, NULL otherwise.
15365 translation_unit& tu)
15366{
15368
15369 const environment& env = tu.get_environment();
15370
15371 type_base_sptr return_type = fn_type.get_return_type();
15372 type_base_sptr result_return_type;
15373 if (!return_type || env.is_void_type(return_type))
15374 result_return_type = env.get_void_type();
15375 else
15376 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
15377 if (!result_return_type)
15378 return nil;
15379
15381 type_base_sptr parm_type;
15383 for (function_type::parameters::const_iterator i =
15384 fn_type.get_parameters().begin();
15385 i != fn_type.get_parameters().end();
15386 ++i)
15387 {
15388 type_base_sptr t = (*i)->get_type();
15389 parm_type = synthesize_type_from_translation_unit(t, tu);
15390 if (!parm_type)
15391 return nil;
15392 parm.reset(new function_decl::parameter(parm_type,
15393 (*i)->get_index(),
15394 (*i)->get_name(),
15395 (*i)->get_location(),
15396 (*i)->get_variadic_marker(),
15397 (*i)->get_is_artificial()));
15398 parms.push_back(parm);
15399 }
15400
15401 class_or_union_sptr class_type;
15402 const method_type* method = is_method_type(&fn_type);
15403 if (method)
15404 {
15405 class_type = is_class_or_union_type
15407 ABG_ASSERT(class_type);
15408 }
15409
15410 function_type_sptr result_fn_type;
15411
15412 if (class_type)
15413 result_fn_type.reset(new method_type(result_return_type,
15414 class_type,
15415 parms,
15416 method->get_is_const(),
15417 fn_type.get_size_in_bits(),
15418 fn_type.get_alignment_in_bits()));
15419 else
15420 result_fn_type.reset(new function_type(result_return_type,
15421 parms,
15422 fn_type.get_size_in_bits(),
15423 fn_type.get_alignment_in_bits()));
15424
15425 tu.priv_->synthesized_types_.push_back(result_fn_type);
15426 tu.bind_function_type_life_time(result_fn_type);
15427
15428 canonicalize(result_fn_type);
15429 return result_fn_type;
15430}
15431
15432/// Demangle a C++ mangled name and return the resulting string
15433///
15434/// @param mangled_name the C++ mangled name to demangle.
15435///
15436/// @return the resulting mangled name.
15437string
15438demangle_cplus_mangled_name(const string& mangled_name)
15439{
15440 if (mangled_name.empty())
15441 return "";
15442
15443 size_t l = 0;
15444 int status = 0;
15445 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15446 NULL, &l, &status);
15447 string demangled_name = mangled_name;
15448 if (str)
15449 {
15450 ABG_ASSERT(status == 0);
15451 demangled_name = str;
15452 free(str);
15453 str = 0;
15454 }
15455 return demangled_name;
15456}
15457
15458/// Return either the type given in parameter if it's non-null, or the
15459/// void type.
15460///
15461/// @param t the type to consider.
15462///
15463/// @param env the environment to use. If NULL, just abort the
15464/// process.
15465///
15466/// @return either @p t if it is non-null, or the void type.
15467type_base_sptr
15468type_or_void(const type_base_sptr t, const environment& env)
15469{
15470 type_base_sptr r;
15471
15472 if (t)
15473 r = t;
15474 else
15475 r = type_base_sptr(env.get_void_type());
15476
15477 return r;
15478}
15479
15480global_scope::~global_scope()
15481{
15482}
15483
15484/// Test if two types are eligible to the "Linux Kernel Fast Type
15485/// Comparison Optimization", a.k.a LKFTCO.
15486///
15487/// Two types T1 and T2 (who are presumably of the same name and kind)
15488/// are eligible to the LKFTCO if they fulfill the following criteria/
15489///
15490/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15491/// either class, union or enums.
15492///
15493/// 2/ They are defined in the same translation unit.
15494///
15495/// @param t1 the first type to consider.
15496///
15497/// @param t2 the second type to consider.
15498///
15499/// @return true iff t1 and t2 are eligible to the LKFTCO.
15500static bool
15501types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15502 const type_base& t2)
15503{
15504 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15505 string t1_file_path, t2_file_path;
15506
15507 /// If the t1 (and t2) are classes/unions/enums from the same linux
15508 /// kernel corpus, let's move on. Otherwise bail out.
15509 if (!(t1_corpus && t2_corpus
15510 && t1_corpus == t2_corpus
15511 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15512 && (is_class_or_union_type(&t1)
15513 || is_enum_type(&t1))))
15514 return false;
15515
15516 class_or_union *c1 = 0, *c2 = 0;
15517 c1 = is_class_or_union_type(&t1);
15518 c2 = is_class_or_union_type(&t2);
15519
15520 // Two anonymous class types with no naming typedefs cannot be
15521 // eligible to this optimization.
15522 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15523 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15524 return false;
15525
15526 // Two anonymous classes with naming typedefs should have the same
15527 // typedef name.
15528 if (c1
15529 && c2
15530 && c1->get_is_anonymous() && c1->get_naming_typedef()
15531 && c2->get_is_anonymous() && c2->get_naming_typedef())
15532 if (c1->get_naming_typedef()->get_name()
15533 != c2->get_naming_typedef()->get_name())
15534 return false;
15535
15536 // Two anonymous enum types cannot be eligible to this optimization.
15537 if (const enum_type_decl *e1 = is_enum_type(&t1))
15538 if (const enum_type_decl *e2 = is_enum_type(&t2))
15539 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15540 return false;
15541
15542 // Look through declaration-only types. That is, get the associated
15543 // definition type.
15546
15547 if (c1 && c2)
15548 {
15549 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15550 {
15551 if (c1->get_environment().decl_only_class_equals_definition())
15552 // At least one of classes/union is declaration-only.
15553 // Because we are in a context in which a declaration-only
15554 // class/union is equal to all definitions of that
15555 // class/union, we can assume that the two types are
15556 // equal.
15557 return true;
15558 }
15559 }
15560
15561 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15562 return false;
15563
15564 // Look at the file names of the locations of t1 and t2. If they
15565 // are equal, then t1 and t2 are defined in the same file.
15566 {
15567 location l;
15568
15569 if (c1)
15570 l = c1->get_location();
15571 else
15572 l = dynamic_cast<const decl_base&>(t1).get_location();
15573
15574 unsigned line = 0, col = 0;
15575 if (l)
15576 l.expand(t1_file_path, line, col);
15577 if (c2)
15578 l = c2->get_location();
15579 else
15580 l = dynamic_cast<const decl_base&>(t2).get_location();
15581 if (l)
15582 l.expand(t2_file_path, line, col);
15583 }
15584
15585 if (t1_file_path.empty() || t2_file_path.empty())
15586 return false;
15587
15588 if (t1_file_path == t2_file_path)
15589 return true;
15590
15591 return false;
15592}
15593
15594
15595/// Compare a type T against a canonical type.
15596///
15597/// This function is called during the canonicalization process of the
15598/// type T. T is called the "candidate type" because it's in the
15599/// process of being canonicalized. Meaning, it's going to be
15600/// compared to a canonical type C. If T equals C, then the canonical
15601/// type of T is C.
15602///
15603/// The purpose of this function is to allow the debugging of the
15604/// canonicalization of T, if that debugging is activated by
15605/// configuring the libabigail package with
15606/// --enable-debug-type-canonicalization and by running "abidw
15607/// --debug-tc". In that case, T is going to be compared to C twice:
15608/// once with canonical equality and once with structural equality.
15609/// The two comparisons must be equal. Otherwise, the
15610/// canonicalization process is said to be faulty and this function
15611/// aborts.
15612///
15613/// This is a sub-routine of type_base::get_canonical_type_for.
15614///
15615/// @param canonical_type the canonical type to compare the candidate
15616/// type against.
15617///
15618/// @param candidate_type the candidate type to compare against the
15619/// canonical type.
15620///
15621/// @return true iff @p canonical_type equals @p candidate_type.
15622///
15623static bool
15624compare_types_during_canonicalization(const type_base& canonical_type,
15625 const type_base& candidate_type)
15626{
15627#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15628 const environment& env = canonical_type.get_environment();
15629 if (env.debug_type_canonicalization_is_on())
15630 {
15631 bool canonical_equality = false, structural_equality = false;
15632 env.priv_->allow_type_comparison_results_caching(false);
15633 env.priv_->use_canonical_type_comparison_ = false;
15634 structural_equality = canonical_type == candidate_type;
15635 env.priv_->use_canonical_type_comparison_ = true;
15636 canonical_equality = canonical_type == candidate_type;
15637 env.priv_->allow_type_comparison_results_caching(true);
15638 if (canonical_equality != structural_equality)
15639 {
15640 std::cerr << "structural & canonical equality different for type: "
15641 << canonical_type.get_pretty_representation(true, true)
15642 << std::endl;
15644 }
15645 return structural_equality;
15646 }
15647#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15648 return canonical_type == candidate_type;
15649}
15650
15651/// Compare a canonical type against a candidate canonical type.
15652///
15653/// This is ultimately a sub-routine of the
15654/// type_base::get_canonical_type_for().
15655///
15656/// The goal of this function is to ease debugging because it can be
15657/// called from within type_base::get_canonical_type_for() from the
15658/// prompt of the debugger (with some breakpoint appropriately set) to
15659/// debug the comparison that happens during type canonicalization,
15660/// between a candidate type being canonicalized, and an existing
15661/// canonical type that is registered in the system, in as returned by
15662/// environment::get_canonical_types()
15663///
15664/// @param canonical_type the canonical type to consider.
15665///
15666/// @param candidate_type the candidate type that is being
15667/// canonicalized, and thus compared to @p canonical_type.
15668///
15669/// @return true iff @p canonical_type compares equal to @p
15670/// candidate_type.
15671static bool
15672compare_canonical_type_against_candidate(const type_base& canonical_type,
15673 const type_base& candidate_type)
15674{
15675 environment& env = const_cast<environment&>(canonical_type.get_environment());
15676
15677 // Before the "*it == it" comparison below is done, let's
15678 // perform on-the-fly-canonicalization. For C types, let's
15679 // consider that an unresolved struct declaration 'struct S'
15680 // is different from a definition 'struct S'. This is
15681 // because normally, at this point all the declarations of
15682 // struct S that are compatible with the definition of
15683 // struct S have already been resolved to that definition,
15684 // during the DWARF parsing. The remaining unresolved
15685 // declaration are thus considered different. With this
15686 // setup we can properly handle cases of two *different*
15687 // struct S being defined in the same binary (in different
15688 // translation units), and a third struct S being only
15689 // declared as an opaque type in a third translation unit of
15690 // its own, with no definition in there. In that case, the
15691 // declaration-only struct S should be left alone and not
15692 // resolved to any of the two definitions of struct S.
15693 bool saved_decl_only_class_equals_definition =
15695
15696 // Compare types by considering that decl-only classes don't
15697 // equal their definition.
15698 env.decl_only_class_equals_definition(false);
15699 env.priv_->allow_type_comparison_results_caching(true);
15700 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15701 candidate_type)
15702 || compare_types_during_canonicalization(canonical_type,
15703 candidate_type));
15704 // Restore the state of the on-the-fly-canonicalization and
15705 // the decl-only-class-being-equal-to-a-matching-definition
15706 // flags.
15707 env.priv_->clear_type_comparison_results_cache();
15708 env.priv_->allow_type_comparison_results_caching(false);
15709 env.decl_only_class_equals_definition
15710 (saved_decl_only_class_equals_definition);
15711 return equal;
15712}
15713
15714/// Compare a canonical type against a candidate canonical type.
15715///
15716/// This is ultimately a sub-routine of the
15717/// type_base::get_canonical_type_for().
15718///
15719/// The goal of this function is to ease debugging because it can be
15720/// called from within type_base::get_canonical_type_for() from the
15721/// prompt of the debugger (with some breakpoint appropriately set) to
15722/// debug the comparison that happens during type canonicalization,
15723/// between a candidate type being canonicalized, and an existing
15724/// canonical type that is registered in the system, in as returned by
15725/// environment::get_canonical_types()
15726///
15727/// @param canonical_type the canonical type to consider.
15728///
15729/// @param candidate_type the candidate type that is being
15730/// canonicalized, and thus compared to @p canonical_type.
15731///
15732/// @return true iff @p canonical_type compares equal to @p
15733/// candidate_type.
15734static bool
15735compare_canonical_type_against_candidate(const type_base* canonical_type,
15736 const type_base* candidate_type)
15737{
15738 return compare_canonical_type_against_candidate(*canonical_type,
15739 *candidate_type);
15740}
15741
15742/// Compare a canonical type against a candidate canonical type.
15743///
15744/// This is ultimately a sub-routine of the
15745/// type_base::get_canonical_type_for().
15746///
15747/// The goal of this function is to ease debugging because it can be
15748/// called from within type_base::get_canonical_type_for() from the
15749/// prompt of the debugger (with some breakpoint appropriately set) to
15750/// debug the comparison that happens during type canonicalization,
15751/// between a candidate type being canonicalized, and an existing
15752/// canonical type that is registered in the system, in as returned by
15753/// environment::get_canonical_types()
15754///
15755/// @param canonical_type the canonical type to consider.
15756///
15757/// @param candidate_type the candidate type that is being
15758/// canonicalized, and thus compared to @p canonical_type.
15759///
15760/// @return true iff @p canonical_type compares equal to @p
15761/// candidate_type.
15762static bool
15763compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15764 const type_base_sptr& candidate_type)
15765{
15766 return compare_canonical_type_against_candidate(canonical_type.get(),
15767 candidate_type.get());
15768}
15769
15770/// Test if a candidate for type canonicalization coming from ABIXML
15771/// matches a canonical type by first looking at their hash values.
15772///
15773/// If the two hash values are equal then the candidate is
15774/// structurally compared to the canonical type. If the two hashes
15775/// are different then the two types are considered different and the
15776/// function returns nullptr.
15777///
15778/// If the candidate doesn't come from ABIXML then the function
15779/// returns nullptr.
15780///
15781/// @param cncls the vector of canonical types to consider.
15782///
15783/// @param type the candidate to consider for canonicalization.
15784///
15785/// @return the canonical type from @p cncls that matches the
15786/// candidate @p type.
15787static type_base_sptr
15788candidate_matches_a_canonical_type_hash(const vector<type_base_sptr>& cncls,
15789 type_base& type)
15790{
15791 if (type.get_corpus()
15792 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
15793 && peek_hash_value(type))
15794 {
15795 // The candidate type comes from ABIXML and does have a stashed
15796 // hash value coming from the ABIXML.
15797
15798 // Let's see if we find a potential canonical type whose hash
15799 // matches the stashed hash and whose canonical type index
15800 // matches it too.
15801 for (const auto& c : cncls)
15802 if (peek_hash_value(type) == peek_hash_value(*c))
15804 // We found a potential canonical type which hash matches the
15805 // stashed hash of the candidate type. Let's compare them to
15806 // see if they match.
15807 if (compare_canonical_type_against_candidate(*c, type))
15808 return c;
15809
15810 // Let's do the same things, but just consideing hash values.
15811 for (const auto& c : cncls)
15812 if (peek_hash_value(type) == peek_hash_value(*c))
15813 // We found a potential canonical type which hash matches the
15814 // stashed hash of the candidate type. Let's compare them to
15815 // see if they match.
15816 if (compare_canonical_type_against_candidate(*c, type))
15817 return c;
15818 }
15819
15820 return nullptr;
15821}
15822
15823/// Test if we should attempt to compute a hash value for a given
15824/// type.
15825///
15826/// For now this function returns true only for types originating from
15827/// ELF. For types originating from ABIXML, for instance, the
15828/// function return false, meaning that types originating from ABIXML
15829/// should NOT be hashed.
15830///
15831/// @param t the type to consider.
15832///
15833/// @return true iff @p type should be considered for hashing.
15834bool
15836{
15837 if (t.get_corpus()
15838 && (t.get_corpus()->get_origin() & corpus::ELF_ORIGIN))
15839 return true;
15840 return false;
15841}
15842
15843/// Compute the canonical type for a given instance of @ref type_base.
15844///
15845/// Consider two types T and T'. The canonical type of T, denoted
15846/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15847/// otherwise, to compare two types, one just needs to compare their
15848/// canonical types using pointer equality. That makes type
15849/// comparison faster than the structural comparison performed by the
15850/// abigail::ir::equals() overloads.
15851///
15852/// If there is not yet any canonical type for @p t, then @p t is its
15853/// own canonical type. Otherwise, this function returns the
15854/// canonical type of @p t which is the canonical type that has the
15855/// same hash value as @p t and that structurally equals @p t. Note
15856/// that after invoking this function, the life time of the returned
15857/// canonical time is then equals to the life time of the current
15858/// process.
15859///
15860/// @param t a smart pointer to instance of @ref type_base we want to
15861/// compute a canonical type for.
15862///
15863/// @return the canonical type for the current instance of @ref
15864/// type_base.
15865type_base_sptr
15866type_base::get_canonical_type_for(type_base_sptr t)
15867{
15868 if (!t)
15869 return t;
15870
15871 environment& env = const_cast<environment&>(t->get_environment());
15872
15874 // This type should not be canonicalized!
15875 return type_base_sptr();
15876
15877 if (is_decl(t))
15879
15880 // Look through decl-only types (classes, unions and enums)
15881 bool decl_only_class_equals_definition =
15883
15884 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15885
15886 // In the context of types from C++ or languages where we assume the
15887 // "One Definition Rule", we assume that a declaration-only
15888 // non-anonymous class equals all fully defined classes of the same
15889 // name.
15890 //
15891 // Otherwise, all classes, including declaration-only classes are
15892 // canonicalized and only canonical comparison is going to be used
15893 // in the system.
15894 if (decl_only_class_equals_definition)
15895 if (class_or_union)
15897 return type_base_sptr();
15898
15899 class_decl_sptr is_class = is_class_type(t);
15900 if (t->get_canonical_type())
15901 return t->get_canonical_type();
15902
15903 // For classes and union, ensure that an anonymous class doesn't
15904 // have a linkage name. If it does in the future, then me must be
15905 // mindful that the linkage name respects the type identity
15906 // constraints which states that "if two linkage names are different
15907 // then the two types are different".
15911
15912 // We want the pretty representation of the type, but for an
15913 // internal use, not for a user-facing purpose.
15914 //
15915 // If two classe types Foo are declared, one as a class and the
15916 // other as a struct, but are otherwise equivalent, we want their
15917 // pretty representation to be the same. Hence the 'internal'
15918 // argument of ir::get_pretty_representation() is set to true here.
15919 // So in this case, the pretty representation of Foo is going to be
15920 // "class Foo", regardless of its struct-ness. This also applies to
15921 // composite types which would have "class Foo" as a sub-type.
15922 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15923
15924 // If 't' already has a canonical type 'inside' its corpus
15925 // (t_corpus), then this variable is going to contain that canonical
15926 // type.
15927 type_base_sptr canonical_type_present_in_corpus;
15930
15931 type_base_sptr result;
15932 environment::canonical_types_map_type::iterator i = types.find(repr);
15933
15934 if (i == types.end())
15935 {
15937 v.push_back(t);
15938 types[repr] = v;
15939 result = t;
15940 }
15941 else
15942 {
15943 vector<type_base_sptr> &v = i->second;
15944 // Look at the canonical types and if the current candidate type
15945 // coming from abixml has the same hash as one of the canonical
15946 // types, then compare the current candidate with the one with a
15947 // matching hash.
15948 result = candidate_matches_a_canonical_type_hash(v, *t);
15949
15950 // Let's compare 't' structurally (i.e, compare its sub-types
15951 // recursively) against the canonical types of the system. If it
15952 // equals a given canonical type C, then it means C is the
15953 // canonical type of 't'. Otherwise, if 't' is different from
15954 // all the canonical types of the system, then it means 't' is a
15955 // canonical type itself.
15956 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15957 !result && it != v.rend();
15958 ++it)
15959 {
15960 bool equal = compare_canonical_type_against_candidate(*it, t);
15961 if (equal)
15962 {
15963 result = *it;
15964 break;
15965 }
15966 }
15967#ifdef WITH_DEBUG_SELF_COMPARISON
15968 if (env.self_comparison_debug_is_on())
15969 {
15970 // So we are debugging the canonicalization process,
15971 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15972 corpus_sptr corp1, corp2;
15973 env.get_self_comparison_debug_inputs(corp1, corp2);
15974 if (corp1 && corp2 && type_originates_from_corpus(t, corp2)
15975 && corp1->get_origin() != corp2->get_origin()
15976 && corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
15977 {
15978 // If 't' comes from the second corpus, then it *must*
15979 // be equal to its matching canonical type coming from
15980 // the first corpus because the second corpus is the
15981 // abixml representation of the first corpus. In other
15982 // words, all types coming from the second corpus must
15983 // have canonical types coming from the first corpus.
15984 if (result)
15985 {
15986 if (!env.priv_->
15987 check_canonical_type_from_abixml_during_self_comp(t,
15988 result))
15989 {
15990 // The canonical type of the type re-read from abixml
15991 // type doesn't match the canonical type that was
15992 // initially serialized down.
15993 uintptr_t should_have_canonical_type = 0;
15994 string type_id = env.get_type_id_from_type(t.get());
15995 if (type_id.empty())
15996 type_id = "type-id-<not-found>";
15997 else
15998 should_have_canonical_type =
15999 env.get_canonical_type_from_type_id(type_id.c_str());
16000 std::cerr << "error: wrong canonical type for '"
16001 << repr
16002 << "' / type: @"
16003 << std::hex
16004 << t.get()
16005 << "/ canon: @"
16006 << result.get()
16007 << ", type-id: '"
16008 << type_id
16009 << "'. Should have had canonical type: "
16010 << std::hex
16011 << should_have_canonical_type
16012 << std::dec
16013 << std::endl;
16014 }
16015 }
16016 else //!result
16017 {
16018 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
16019 string type_id = env.get_type_id_from_pointer(ptr_val);
16020 if (type_id.empty())
16021 type_id = "type-id-<not-found>";
16022 // We are in the case where 't' is different from all
16023 // the canonical types of the same name that come from
16024 // the first corpus.
16025 //
16026 // If 't' indeed comes from the second corpus then this
16027 // clearly is a canonicalization failure.
16028 //
16029 // There was a problem either during the serialization
16030 // of 't' into abixml, or during the de-serialization
16031 // from abixml into abigail::ir. Further debugging is
16032 // needed to determine what that root cause problem is.
16033 //
16034 // Note that the first canonicalization problem of this
16035 // kind must be fixed before looking at the subsequent
16036 // ones, because the later might well just be
16037 // consequences of the former.
16038 std::cerr << "error: wrong induced canonical type for '"
16039 << repr
16040 << "' from second corpus"
16041 << ", ptr: " << std::hex << t.get()
16042 << " type-id: " << type_id
16043 << " /hash="
16044 << *t->hash_value()
16045 << std::dec
16046 << std::endl;
16047 }
16048 }
16049 if (result)
16050 {
16051 if (!is_type_decl(t))
16052 if (hash_t t_hash = peek_hash_value(*t))
16053 if (hash_t result_hash = peek_hash_value(*result))
16054 if (t_hash != result_hash)
16055 {
16056 std::cerr << "error: type hash mismatch"
16057 << " between type: '"
16058 << repr
16059 << "' @ "
16060 << std::hex
16061 << t.get()
16062 << "/hash="
16063 << *t->hash_value()
16064 << " and its computed canonical type @"
16065 << std::hex
16066 << result.get()
16067 << "/hash="
16068 << std::hex
16069 << *result->hash_value()
16070 << std::dec
16071 << std::endl;
16072 }
16073 }
16074 }
16075#endif //WITH_DEBUG_SELF_COMPARISON
16076
16077 if (!result)
16078 {
16079 v.push_back(t);
16080 result = t;
16081 // we need to generate a canonical type index to sort these
16082 // types that have the same representation and potentially
16083 // same hash value but are canonically different.
16084 t->priv_->canonical_type_index = v.size();
16085 }
16086 }
16087
16088 return result;
16089}
16090
16091/// This method is invoked automatically right after the current
16092/// instance of @ref class_decl has been canonicalized.
16093void
16096
16097/// This is a subroutine of the canonicalize() function.
16098///
16099/// When the canonical type C of type T has just been computed, there
16100/// can be cases where T has member functions that C doesn't have.
16101///
16102/// This is possible because non virtual member functions are not
16103/// taken in account when comparing two types.
16104///
16105/// In that case, this function updates C so that it contains the
16106/// member functions.
16107///
16108/// There can also be cases where C has a method M which is not linked
16109/// to any underlying symbol, whereas in T, M is to link to an
16110/// underlying symbol. In that case, this function updates M in C so
16111/// that it's linked to the same underlying symbol as for M in T.
16112static void
16113maybe_adjust_canonical_type(const type_base_sptr& canonical,
16114 const type_base_sptr& type)
16115{
16116 if (type->get_naked_canonical_type())
16117 return;
16118
16119 class_decl_sptr canonical_class = is_class_type(canonical);
16120
16121 if (class_decl_sptr cl = is_class_type(type))
16122 {
16124 if (canonical_class
16125 && canonical_class.get() != cl.get())
16126 {
16127 // Set symbols of member functions that might be missing
16128 // theirs.
16129 for (class_decl::member_functions::const_iterator i =
16130 cl->get_member_functions().begin();
16131 i != cl->get_member_functions().end();
16132 ++i)
16133 if ((*i)->get_symbol())
16134 {
16135 if (method_decl *m = canonical_class->
16136 find_member_function((*i)->get_linkage_name()))
16137 {
16138 elf_symbol_sptr s1 = (*i)->get_symbol();
16139 if (s1 && !m->get_symbol())
16140 // Method 'm' in the canonical type is not
16141 // linked to the underlying symbol of '*i'.
16142 // Let's link it now. have th
16143 m->set_symbol(s1);
16144 }
16145 else
16146 if (!is_anonymous_type(cl)
16147 && canonical_class->get_corpus()
16148 && cl->get_corpus()
16149 && (cl->get_corpus() == canonical_class->get_corpus()))
16150 // There is a member function defined and publicly
16151 // exported in the other class and the canonical
16152 // class doesn't have that member function. This
16153 // should not have happened! For instance, the
16154 // DWARF reader does merge the member functions of
16155 // classes having the same name so that all of them
16156 // end-up having the same member functions. What's
16157 // going on here?
16159 }
16160
16161 // Set symbols of static data members that might be missing
16162 // theirs.
16163 for (const auto& data_member : cl->get_data_members())
16164 {
16165 if (!get_member_is_static(data_member))
16166 continue;
16167 elf_symbol_sptr sym = data_member->get_symbol();
16168 if (!sym)
16169 continue;
16170 const auto& canonical_data_member =
16171 canonical_class->find_data_member(data_member->get_name());
16172 if (!canonical_data_member)
16173 {
16174 // Two classes my be equivalent (same name, non-static
16175 // sub-objects) and yet not have the same number of
16176 // static data members, if they are coming from
16177 // different corpora. If they are in the same corpus,
16178 // however then that means there is a problem!
16179 if (!is_anonymous_type(cl)
16180 && canonical_class->get_corpus()
16181 && cl->get_corpus()
16182 && canonical_class->get_corpus() == cl->get_corpus())
16184
16185 continue;
16186 }
16187
16188 if (!canonical_data_member->get_symbol())
16189 canonical_data_member->set_symbol(sym);
16190 }
16191 }
16192 }
16193
16194 // Make sure the virtual member functions with exported symbols are
16195 // all added to the set of exported functions of the corpus.
16196
16197 // If we are looking at a non-canonicalized class (for instance, a
16198 // decl-only class that has virtual member functions), let's pretend
16199 // it does have a canonical class so that we can perform the
16200 // necessary virtual member function adjustments
16201 if (class_decl_sptr cl = is_class_type(type))
16203 {
16204 ABG_ASSERT(!canonical_class);
16205 canonical_class = cl;
16206 }
16207
16208 if (canonical_class)
16209 {
16210 if (auto abi_corpus = canonical_class->get_corpus())
16211 {
16212 for (auto& fn : canonical_class->get_member_functions())
16213 {
16214 if (elf_symbol_sptr sym = fn->get_symbol())
16215 {
16216 if (sym->is_defined() && sym->is_public())
16217 {
16218 fn->set_is_in_public_symbol_table(true);
16219 auto b = abi_corpus->get_exported_decls_builder();
16220 b->maybe_add_fn_to_exported_fns(fn.get());
16221 }
16222 else if (!sym->is_defined())
16223 abi_corpus->get_undefined_functions().insert(fn.get());
16224 }
16225 }
16226 }
16227 }
16228
16229 // If an artificial function type equals a non-artfificial one in
16230 // the system, then the canonical type of both should be deemed
16231 // non-artificial. This is important because only non-artificial
16232 // canonical function types are emitted out into abixml, so if don't
16233 // do this we risk missing to emit some function types.
16234 if (is_function_type(type))
16235 if (type->get_is_artificial() != canonical->get_is_artificial())
16236 canonical->set_is_artificial(false);
16237}
16238
16239/// Compute the canonical type of a given type.
16240///
16241/// It means that after invoking this function, comparing the intance
16242/// instance @ref type_base and another one (on which
16243/// type_base::enable_canonical_equality() would have been invoked as
16244/// well) is performed by just comparing the pointer values of the
16245/// canonical types of both types. That equality comparison is
16246/// supposedly faster than structural comparison of the types.
16247///
16248/// @param t a smart pointer to the instance of @ref type_base for
16249/// which to compute the canonical type. After this call,
16250/// t->get_canonical_type() will return the newly computed canonical
16251/// type.
16252///
16253/// @param do_log if true then logs are emitted about canonicalization
16254/// progress.
16255///
16256/// @param show_stats if true and if @p do_log is true as well, then
16257/// more detailed logs are emitted about canonicalization.
16258///
16259/// @return the canonical type computed for @p t.
16260type_base_sptr
16261canonicalize(type_base_sptr t, bool do_log, bool show_stats)
16262{
16263 if (!t)
16264 return t;
16265
16266 if (t->get_canonical_type())
16267 return t->get_canonical_type();
16268
16269 if (do_log && show_stats)
16270 std::cerr << "Canonicalization of type '"
16271 << t->get_pretty_representation(true, true)
16272 << "/@#" << std::hex << t.get() << ": ";
16273
16275
16276 if (do_log && show_stats)
16277 tmr.start();
16278 type_base_sptr canonical = type_base::get_canonical_type_for(t);
16279
16280 if (do_log && show_stats)
16281 tmr.stop();
16282
16283 if (do_log && show_stats)
16284 std::cerr << tmr << "\n";
16285
16286 maybe_adjust_canonical_type(canonical, t);
16287
16288 t->priv_->canonical_type = canonical;
16289 t->priv_->naked_canonical_type = canonical.get();
16290
16291 if (canonical)
16292 if (!t->priv_->canonical_type_index)
16293 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
16294
16295 if (class_decl_sptr cl = is_class_type(t))
16296 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
16297 if ((canonical = d->get_canonical_type()))
16298 {
16299 d->priv_->canonical_type = canonical;
16300 d->priv_->naked_canonical_type = canonical.get();
16301 }
16302
16303 if (canonical)
16304 {
16305 if (decl_base_sptr d = is_decl_slow(canonical))
16306 {
16307 scope_decl *scope = d->get_scope();
16308 // Add the canonical type to the set of canonical types
16309 // belonging to its scope.
16310 if (scope)
16311 {
16312 if (is_type(scope))
16313 // The scope in question is itself a type (e.g, a class
16314 // or union). Let's call that type ST. We want to add
16315 // 'canonical' to the set of canonical types belonging
16316 // to ST.
16317 if (type_base_sptr c = is_type(scope)->get_canonical_type())
16318 // We want to add 'canonical' to the set of
16319 // canonical types belonging to the canonical type
16320 // of ST. That way, just looking at the canonical
16321 // type of ST is enough to get the types that belong
16322 // to the scope of the class of equivalence of ST.
16323 scope = is_scope_decl(is_decl(c)).get();
16324 scope->get_canonical_types().insert(canonical);
16325 }
16326 // else, if the type doesn't have a scope, it's not meant to be
16327 // emitted. This can be the case for the result of the
16328 // function strip_typedef, for instance.
16329 }
16330 }
16331
16332 t->on_canonical_type_set();
16333 return canonical;
16334}
16335
16336/// Set the definition of this declaration-only @ref decl_base.
16337///
16338/// @param d the new definition to set.
16339void
16341{
16343 priv_->definition_of_declaration_ = d;
16344 if (type_base *t = is_type(this))
16345 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
16346 t->priv_->canonical_type = canonical_type;
16347
16348 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
16349}
16350
16351/// The constructor of @ref type_base.
16352///
16353/// @param s the size of the type, in bits.
16354///
16355/// @param a the alignment of the type, in bits.
16356type_base::type_base(const environment& e, size_t s, size_t a)
16357 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
16358 priv_(new priv(s, a))
16359{}
16360
16361/// Return the hash value of the current IR node.
16362///
16363/// Note that upon the first invocation, this member functions
16364/// computes the hash value and returns it. Subsequent invocations
16365/// just return the hash value that was previously calculated.
16366///
16367/// @return the hash value of the current IR node.
16368hash_t
16370{
16371 type_base::hash do_hash;
16372 return do_hash(this);
16373}
16374
16375/// Getter of the canonical type of the current instance of @ref
16376/// type_base.
16377///
16378/// @return a smart pointer to the canonical type of the current
16379/// intance of @ref type_base, or an empty smart pointer if the
16380/// current instance of @ref type_base doesn't have any canonical
16381/// type.
16382type_base_sptr
16384{return priv_->canonical_type.lock();}
16385
16386/// Getter of the canonical type pointer.
16387///
16388/// Note that this function doesn't return a smart pointer, but rather
16389/// the underlying pointer managed by the smart pointer. So it's as
16390/// fast as possible. This getter is to be used in code paths that
16391/// are proven to be performance hot spots; especially, when comparing
16392/// sensitive types like class, function, pointers and reference
16393/// types. Those are compared extremely frequently and thus, their
16394/// accessing the canonical type must be fast.
16395///
16396/// @return the canonical type pointer, not managed by a smart
16397/// pointer.
16398type_base*
16400{return priv_->naked_canonical_type;}
16401
16402/// Get the pretty representation of the current type.
16403///
16404/// The pretty representation is retrieved from a cache. If the cache
16405/// is empty, this function computes the pretty representation, put it
16406/// in the cache and returns it.
16407///
16408/// Please note that if this function is called too early in the life
16409/// cycle of the type (before the type is fully constructed), then the
16410/// pretty representation that is cached is going to represent a
16411/// non-complete (and thus wrong) representation of the type. Thus
16412/// this function must be called only once the type is fully
16413/// constructed.
16414///
16415/// @param internal if true, then the pretty representation is to be
16416/// used for purpuses that are internal to the libabigail library
16417/// itself. If you don't know what this means, then you probably
16418/// should set this parameter to "false".
16419///
16420/// @return a reference to a cached @ref interned_string holding the
16421/// pretty representation of the current type.
16422const interned_string&
16424{
16425 if (internal)
16426 {
16427 if (priv_->internal_cached_repr_.empty())
16428 {
16429 string r = ir::get_pretty_representation(this, internal);
16430 priv_->internal_cached_repr_ = get_environment().intern(r);
16431 }
16432 return priv_->internal_cached_repr_;
16433 }
16434
16435 if (priv_->cached_repr_.empty())
16436 {
16437 string r = ir::get_pretty_representation(this, internal);
16438 priv_->cached_repr_ = get_environment().intern(r);
16439 }
16440
16441 return priv_->cached_repr_;
16442}
16443
16444/// Compares two instances of @ref type_base.
16445///
16446/// If the two intances are different, set a bitfield to give some
16447/// insight about the kind of differences there are.
16448///
16449/// @param l the first artifact of the comparison.
16450///
16451/// @param r the second artifact of the comparison.
16452///
16453/// @param k a pointer to a bitfield that gives information about the
16454/// kind of changes there are between @p l and @p r. This one is set
16455/// iff @p is non-null and if the function returns false.
16456///
16457/// Please note that setting k to a non-null value does have a
16458/// negative performance impact because even if @p l and @p r are not
16459/// equal, the function keeps up the comparison in order to determine
16460/// the different kinds of ways in which they are different.
16461///
16462/// @return true if @p l equals @p r, false otherwise.
16463bool
16464equals(const type_base& l, const type_base& r, change_kind* k)
16465{
16466 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
16468 if (!result)
16469 if (k)
16471 ABG_RETURN(result);
16472}
16473
16474/// Return true iff both type declarations are equal.
16475///
16476/// Note that this doesn't test if the scopes of both types are equal.
16477bool
16478type_base::operator==(const type_base& other) const
16479{return equals(*this, other, 0);}
16480
16481/// Inequality operator.
16482///
16483///@param other the instance of @ref type_base to compare the current
16484/// instance against.
16485///
16486/// @return true iff the current instance is different from @p other.
16487bool
16488type_base::operator!=(const type_base& other) const
16489{return !operator==(other);}
16490
16491/// Setter for the size of the type.
16492///
16493/// @param s the new size -- in bits.
16494void
16496{priv_->size_in_bits = s;}
16497
16498/// Getter for the size of the type.
16499///
16500/// @return the size in bits of the type.
16501size_t
16503{return priv_->size_in_bits;}
16504
16505/// Setter for the alignment of the type.
16506///
16507/// @param a the new alignment -- in bits.
16508void
16510{priv_->alignment_in_bits = a;}
16511
16512/// Getter for the alignment of the type.
16513///
16514/// @return the alignment of the type in bits.
16515size_t
16517{return priv_->alignment_in_bits;}
16518
16519/// Default implementation of traversal for types. This function does
16520/// nothing. It must be implemented by every single new type that is
16521/// written.
16522///
16523/// Please look at e.g, class_decl::traverse() for an example of how
16524/// to implement this.
16525///
16526/// @param v the visitor used to visit the type.
16527bool
16529{
16530 if (v.type_node_has_been_visited(this))
16531 return true;
16532
16533 v.visit_begin(this);
16534 bool result = v.visit_end(this);
16536
16537 return result;
16538}
16539
16540type_base::~type_base()
16541{delete priv_;}
16542
16543// </type_base definitions>
16544
16545// <real_type definitions>
16546
16547/// Bitwise OR operator for real_type::modifiers_type.
16548///
16549/// @param l the left-hand side operand.
16550///
16551/// @param r the right-hand side operand.
16552///
16553/// @return the result of the bitwise OR.
16556{
16557 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16558 |
16559 static_cast<unsigned>(r));
16560}
16561
16562/// Bitwise AND operator for real_type::modifiers_type.
16563///
16564/// @param l the left-hand side operand.
16565///
16566/// @param r the right-hand side operand.
16567///
16568/// @return the result of the bitwise AND.
16571{
16572 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16573 &
16574 static_cast<unsigned>(r));
16575}
16576
16577/// Bitwise one's complement operator for real_type::modifiers_type.
16578///
16579/// @param l the left-hand side operand.
16580///
16581/// @param r the right-hand side operand.
16582///
16583/// @return the result of the bitwise one's complement operator.
16586{
16587 return static_cast<real_type::modifiers_type>(~static_cast<unsigned>(l));
16588}
16589
16590/// Bitwise |= operator for real_type::modifiers_type.
16591///
16592/// @param l the left-hand side operand.
16593///
16594/// @param r the right-hand side operand.
16595///
16596/// @return the result of the bitwise |=.
16599{
16600 l = l | r;
16601 return l;
16602}
16603
16604/// Bitwise &= operator for real_type::modifiers_type.
16605///
16606/// @param l the left-hand side operand.
16607///
16608/// @param r the right-hand side operand.
16609///
16610/// @return the result of the bitwise &=.
16613{
16614 l = l & r;
16615 return l;
16616}
16617
16618/// Parse a word containing one real type modifier.
16619///
16620/// A word is considered to be a string of characters that doesn't
16621/// contain any white space.
16622///
16623/// @param word the word to parse. It is considered to be a string of
16624/// characters that doesn't contain any white space.
16625///
16626/// @param modifiers out parameter. It's set by this function to the
16627/// parsed modifier iff the function returned true.
16628///
16629/// @return true iff @word was successfully parsed.
16630static bool
16631parse_real_type_modifier(const string& word,
16632 real_type::modifiers_type &modifiers)
16633{
16634 if (word == "signed")
16635 modifiers |= real_type::SIGNED_MODIFIER;
16636 else if (word == "unsigned")
16637 modifiers |= real_type::UNSIGNED_MODIFIER;
16638 else if (word == "short")
16639 modifiers |= real_type::SHORT_MODIFIER;
16640 else if (word == "long")
16641 modifiers |= real_type::LONG_MODIFIER;
16642 else if (word == "long long")
16643 modifiers |= real_type::LONG_LONG_MODIFIER;
16644 else
16645 return false;
16646
16647 return true;
16648}
16649
16650/// Parse a base type of a real type from a string.
16651///
16652/// @param type_name the type name to parse.
16653///
16654/// @param base out parameter. This is set to the resulting base type
16655/// parsed, iff the function returned true.
16656///
16657/// @return true iff the function could successfully parse the base
16658/// type.
16659static bool
16660parse_base_real_type(const string& type_name,
16662{
16663 if (type_name == "int")
16665 else if (type_name == "char")
16667 else if (type_name == "bool" || type_name == "_Bool")
16669 else if (type_name == "double")
16671 else if (type_name =="float")
16673 else if (type_name == "char16_t")
16675 else if (type_name == "char32_t")
16677 else if (type_name == "wchar_t")
16679 else if (type_name == "__ARRAY_SIZE_TYPE__")
16681 else if (type_name == "sizetype")
16682 base = real_type::SIZE_BASE_TYPE;
16683 else if (type_name == "ssizetype")
16684 base = real_type::SSIZE_BASE_TYPE;
16685 else if (type_name == "bitsizetype")
16686 base = real_type::BIT_SIZE_BASE_TYPE;
16687 else if (type_name == "sbitsizetype")
16688 base = real_type::SBIT_SIZE_BASE_TYPE;
16689 else
16690 return false;
16691
16692 return true;
16693}
16694
16695/// Parse a real type from a string.
16696///
16697/// @param type_name the string containing the real type to parse.
16698///
16699/// @param base out parameter. Is set by this function to the base
16700/// type of the real type, iff the function returned true.
16701///
16702/// @param modifiers out parameter If set by this function to the
16703/// modifier of the real type, iff the function returned true.
16704///
16705/// @return true iff the function could parse a real type from @p
16706/// type_name.
16707static bool
16708parse_real_type(const string& type_name,
16710 real_type::modifiers_type& modifiers)
16711{
16712 string input = type_name;
16713 string::size_type len = input.length();
16714 string::size_type cur_pos = 0, prev_pos = 0;
16715 string cur_word, prev_word;
16716 bool ok = false;
16717
16718 while (cur_pos < len)
16719 {
16720 if (cur_pos < len && isspace(input[cur_pos]))
16721 do
16722 ++cur_pos;
16723 while (cur_pos < len && isspace(input[cur_pos]));
16724
16725 prev_pos = cur_pos;
16726 cur_pos = input.find(' ', prev_pos);
16727 prev_word = cur_word;
16728 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16729
16730 if (cur_pos < len
16731 && cur_word == "long"
16732 && prev_word != "long")
16733 {
16734 if (cur_pos < len && isspace(input[cur_pos]))
16735 do
16736 ++cur_pos;
16737 while (cur_pos < len && isspace(input[cur_pos]));
16738 prev_pos = cur_pos;
16739
16740 cur_pos = input.find(' ', prev_pos);
16741 string saved_prev_word = prev_word;
16742 prev_word = cur_word;
16743 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16744 if (cur_word == "long")
16745 cur_word = "long long";
16746 else
16747 {
16748 cur_pos = prev_pos;
16749 cur_word = prev_word;
16750 prev_word = saved_prev_word;
16751 }
16752 }
16753
16754 if (!parse_real_type_modifier(cur_word, modifiers))
16755 {
16756 if (!parse_base_real_type(cur_word, base))
16757 return false;
16758 else
16759 ok = true;
16760 }
16761 else
16762 ok = true;
16763 }
16764
16765 return ok;
16766}
16767
16768/// Parse a real type from a string.
16769///
16770/// @param str the string containing the real type to parse.
16771///
16772///@param type the resulting @ref real_type. Is set to the result
16773///of the parse, iff the function returns true.
16774///
16775/// @return true iff the function could parse a real type from @p
16776/// str.
16777bool
16778parse_real_type(const string& str, real_type& type)
16779{
16781 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16782
16783 if (!parse_real_type(str, base_type, modifiers))
16784 return false;
16785
16786 // So this is a real type.
16787 real_type int_type(base_type, modifiers);
16788 type = int_type;
16789 return true;
16790}
16791
16792/// Default constructor of the @ref real_type.
16794 : base_(INT_BASE_TYPE),
16795 modifiers_(NO_MODIFIER)
16796{}
16797
16798/// Constructor of the @ref real_type.
16799///
16800/// @param b the base type of the real type.
16801///
16802/// @param m the modifiers of the real type.
16804 : base_(b), modifiers_(m)
16805{}
16806
16807/// Constructor of the @ref real_type.
16808///
16809/// @param the name of the real type to parse to initialize the
16810/// current instance of @ref real_type.
16811real_type::real_type(const string& type_name)
16812 : base_(INT_BASE_TYPE),
16813 modifiers_(NO_MODIFIER)
16814{
16815 bool could_parse = parse_real_type(type_name, base_, modifiers_);
16816 ABG_ASSERT(could_parse);
16817}
16818
16819/// Getter of the base type of the @ref real_type.
16820///
16821/// @return the base type of the @ref real_type.
16824{return base_;}
16825
16826/// Getter of the modifiers bitmap of the @ref real_type.
16827///
16828/// @return the modifiers bitmap of the @ref real_type.
16831{return modifiers_;}
16832
16833/// Setter of the modifiers bitmap of the @ref real_type.
16834///
16835/// @param m the new modifiers.
16836void
16838{modifiers_ = m;}
16839
16840/// Equality operator for the @ref real_type.
16841///
16842/// @param other the other real type to compare against.
16843///
16844/// @return true iff @p other equals the current instance of @ref
16845/// real_type.
16846bool
16848{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16849
16850/// Return the string representation of the current instance of @ref
16851/// real_type.
16852///
16853/// @param internal if true the string representation is to be used
16854/// for internal purposes. In general, it means it's for type
16855/// canonicalization purposes.
16856///
16857/// @return the string representation of the current instance of @ref
16858/// real_type.
16859string
16860real_type::to_string(bool internal) const
16861{
16862 string result;
16863
16864 // Look at modifiers ...
16865 if (modifiers_ & SIGNED_MODIFIER)
16866 result += "signed ";
16867 if (modifiers_ & UNSIGNED_MODIFIER)
16868 result += "unsigned ";
16869 if (!internal)
16870 {
16871 // For canonicalization purposes, we won't emit the "short, long, or
16872 // long long" modifiers. This is because on some platforms, "long
16873 // int" and "long long int" might have the same size. In those
16874 // cases, we want the two types to be equivalent if they have the
16875 // same size. If they don't have the same internal string
16876 // representation, they'd automatically have different canonical
16877 // types and thus be canonically different.
16878 if (modifiers_ & SHORT_MODIFIER)
16879 result += "short ";
16880 if (modifiers_ & LONG_MODIFIER)
16881 result += "long ";
16882 if (modifiers_ & LONG_LONG_MODIFIER)
16883 result += "long long ";
16884 }
16885
16886 // ... and look at base types.
16887 if (base_ == INT_BASE_TYPE)
16888 result += "int";
16889 else if (base_ == CHAR_BASE_TYPE)
16890 result += "char";
16891 else if (base_ == BOOL_BASE_TYPE)
16892 result += "bool";
16893 else if (base_ == DOUBLE_BASE_TYPE)
16894 result += "double";
16895 else if (base_ == FLOAT_BASE_TYPE)
16896 result += "float";
16897 else if (base_ == CHAR16_T_BASE_TYPE)
16898 result += "char16_t";
16899 else if (base_ == CHAR32_T_BASE_TYPE)
16900 result += "char32_t";
16901 else if (base_ == WCHAR_T_BASE_TYPE)
16902 result += "wchar_t";
16903 else if (base_ == ARRAY_SIZE_BASE_TYPE)
16904 result += "__ARRAY_SIZE_TYPE__";
16905 else if (base_ == SIZE_BASE_TYPE)
16906 result += "sizetype";
16907 else if (base_ == SSIZE_BASE_TYPE)
16908 result += "ssizetype";
16909 else if (base_ == BIT_SIZE_BASE_TYPE)
16910 result += "bitsizetype";
16911 else if (base_ == SBIT_SIZE_BASE_TYPE)
16912 result += "sbitsizetype";
16913 return result;
16914}
16915
16916/// Convert the current instance of @ref real_type into its string
16917/// representation.
16918///
16919/// @return the string representation of the current instance of @ref
16920/// real_type.
16921real_type::operator string() const
16922{return to_string();}
16923
16924// </real_type definitions>
16925
16926//<type_decl definitions>
16927
16928/// Constructor.
16929///
16930/// @param env the environment we are operating from.
16931///
16932/// @param name the name of the type declaration.
16933///
16934/// @param size_in_bits the size of the current type_decl, in bits.
16935///
16936/// @param alignment_in_bits the alignment of the current typ, in
16937/// bits.
16938///
16939/// @param locus the source location of the current type declaration.
16940///
16941/// @param linkage_name the linkage_name of the current type declaration.
16942///
16943/// @param vis the visibility of the type declaration.
16944type_decl::type_decl(const environment& env,
16945 const string& name,
16946 size_t size_in_bits,
16947 size_t alignment_in_bits,
16948 const location& locus,
16949 const string& linkage_name,
16950 visibility vis)
16951
16952 : type_or_decl_base(env,
16953 BASIC_TYPE
16954 | ABSTRACT_TYPE_BASE
16955 | ABSTRACT_DECL_BASE),
16956 decl_base(env, name, locus, linkage_name, vis),
16957 type_base(env, size_in_bits, alignment_in_bits)
16958{
16960
16962 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16963 real_type int_type(base_type, modifiers);
16964 if (parse_real_type(name, int_type))
16965 {
16966 // Convert the real_type into its canonical string
16967 // representation.
16968 string real_type_name = int_type;
16969
16970 // Set the name of this type_decl to the canonical string
16971 // representation above
16972 set_name(real_type_name);
16974
16975 if (!get_linkage_name().empty())
16976 set_linkage_name(real_type_name);
16977 }
16978}
16979
16980/// Return the hash value of the current IR node.
16981///
16982/// Note that upon the first invocation, this member functions
16983/// computes the hash value and returns it. Subsequent invocations
16984/// just return the hash value that was previously calculated.
16985///
16986/// @return the hash value of the current IR node.
16987hash_t
16989{
16991 return h;
16992}
16993
16994/// Compares two instances of @ref type_decl.
16995///
16996/// If the two intances are different, set a bitfield to give some
16997/// insight about the kind of differences there are.
16998///
16999/// @param l the first artifact of the comparison.
17000///
17001/// @param r the second artifact of the comparison.
17002///
17003/// @param k a pointer to a bitfield that gives information about the
17004/// kind of changes there are between @p l and @p r. This one is set
17005/// iff @p k is non-null and the function returns false.
17006///
17007/// Please note that setting k to a non-null value does have a
17008/// negative performance impact because even if @p l and @p r are not
17009/// equal, the function keeps up the comparison in order to determine
17010/// the different kinds of ways in which they are different.
17011///
17012/// @return true if @p l equals @p r, false otherwise.
17013bool
17014equals(const type_decl& l, const type_decl& r, change_kind* k)
17015{
17016 bool result = false;
17017
17018 // Consider the types as decls to compare their decls-related
17019 // properties.
17020 result = equals(static_cast<const decl_base&>(l),
17021 static_cast<const decl_base&>(r),
17022 k);
17023 if (!k && !result)
17025
17026 // Now consider the types a "types' to compare their size-related
17027 // properties.
17028 result &= equals(static_cast<const type_base&>(l),
17029 static_cast<const type_base&>(r),
17030 k);
17031 ABG_RETURN(result);
17032}
17033
17034/// Return true if both types equals.
17035///
17036/// This operator re-uses the overload that takes a decl_base.
17037///
17038/// Note that this does not check the scopes of any of the types.
17039///
17040/// @param o the other type_decl to check agains.
17041bool
17042type_decl::operator==(const type_base& o) const
17043{
17044 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17045 if (!other)
17046 return false;
17047 return *this == *other;
17048}
17049
17050/// Return true if both types equals.
17051///
17052/// Note that this does not check the scopes of any of the types.
17053///
17054/// @param o the other type_decl to check against.
17055bool
17056type_decl::operator==(const decl_base& o) const
17057{
17058 const type_decl* other = dynamic_cast<const type_decl*>(&o);
17059 if (!other)
17060 return false;
17061 return try_canonical_compare(this, other);
17062}
17063
17064/// Return true if both types equals.
17065///
17066/// Note that this does not check the scopes of any of the types.
17067///
17068/// @param o the other type_decl to check against.
17069///
17070/// @return true iff the current isntance equals @p o
17071bool
17072type_decl::operator==(const type_decl& o) const
17073{
17074 const decl_base& other = o;
17075 return *this == other;
17076}
17077
17078/// Return true if both types equals.
17079///
17080/// Note that this does not check the scopes of any of the types.
17081///
17082/// @param o the other type_decl to check against.
17083///
17084/// @return true iff the current isntance equals @p o
17085bool
17086type_decl::operator!=(const type_base&o)const
17087{return !operator==(o);}
17088
17089/// Return true if both types equals.
17090///
17091/// Note that this does not check the scopes of any of the types.
17092///
17093/// @param o the other type_decl to check against.
17094///
17095/// @return true iff the current isntance equals @p o
17096bool
17097type_decl::operator!=(const decl_base&o)const
17098{return !operator==(o);}
17099
17100/// Inequality operator.
17101///
17102/// @param o the other type to compare against.
17103///
17104/// @return true iff the current instance is different from @p o.
17105bool
17106type_decl::operator!=(const type_decl& o) const
17107{return !operator==(o);}
17108
17109/// Equality operator for @ref type_decl_sptr.
17110///
17111/// @param l the first operand to compare.
17112///
17113/// @param r the second operand to compare.
17114///
17115/// @return true iff @p l equals @p r.
17116bool
17118{
17119 if (!!l != !!r)
17120 return false;
17121 if (l.get() == r.get())
17122 return true;
17123 return *l == *r;
17124}
17125
17126/// Inequality operator for @ref type_decl_sptr.
17127///
17128/// @param l the first operand to compare.
17129///
17130/// @param r the second operand to compare.
17131///
17132/// @return true iff @p l is different from @p r.
17133bool
17135{return !operator==(l, r);}
17136
17137/// Implementation for the virtual qualified name builder for @ref
17138/// type_decl.
17139///
17140/// @param qualified_name the output parameter to hold the resulting
17141/// qualified name.
17142///
17143/// @param internal set to true if the call is intended for an
17144/// internal use (for technical use inside the library itself), false
17145/// otherwise. If you don't know what this is for, then set it to
17146/// false.
17147void
17149 bool internal) const
17150{qualified_name = get_qualified_name(internal);}
17151
17152/// Implementation for the virtual qualified name builder for @ref
17153/// type_decl.
17154///
17155/// @param qualified_name the output parameter to hold the resulting
17156/// qualified name.
17157///
17158/// @param internal set to true if the call is intended for an
17159/// internal use (for technical use inside the library itself), false
17160/// otherwise. If you don't know what this is for, then set it to
17161/// false.
17162const interned_string&
17164{
17165 const environment& env = get_environment();
17166
17167
17168 if (internal)
17169 if (is_real_type(this))
17170 {
17172 {
17173 if (decl_base::priv_->internal_qualified_name_.empty())
17174 decl_base::priv_->internal_qualified_name_ =
17175 env.intern(get_internal_real_type_name(this));
17176 return decl_base::priv_->internal_qualified_name_;
17177 }
17178 else
17179 {
17180 decl_base::priv_->temporary_internal_qualified_name_ =
17181 env.intern(get_internal_real_type_name(this));
17182 return decl_base::priv_->temporary_internal_qualified_name_;
17183 }
17184 }
17185
17186 return decl_base::get_qualified_name(/*internal=*/false);
17187}
17188
17189/// Get the pretty representation of the current instance of @ref
17190/// type_decl.
17191///
17192/// @param internal set to true if the call is intended to get a
17193/// representation of the decl (or type) for the purpose of canonical
17194/// type comparison. This is mainly used in the function
17195/// type_base::get_canonical_type_for().
17196///
17197/// In other words if the argument for this parameter is true then the
17198/// call is meant for internal use (for technical use inside the
17199/// library itself), false otherwise. If you don't know what this is
17200/// for, then set it to false.
17201///
17202/// @param qualified_name if true, names emitted in the pretty
17203/// representation are fully qualified.
17204///
17205/// @return the pretty representatin of the @ref type_decl.
17206string
17208 bool qualified_name) const
17209{
17210 if (internal)
17211 if (is_real_type(this))
17212 return get_internal_real_type_name(this);
17213
17214 if (qualified_name)
17215 return get_qualified_name(internal);
17216 return get_name();
17217}
17218
17219/// This implements the ir_traversable_base::traverse pure virtual
17220/// function.
17221///
17222/// @param v the visitor used on the current instance.
17223///
17224/// @return true if the entire IR node tree got traversed, false
17225/// otherwise.
17226bool
17228{
17229 if (v.type_node_has_been_visited(this))
17230 return true;
17231
17232 v.visit_begin(this);
17233 bool result = v.visit_end(this);
17235
17236 return result;
17237}
17238
17239type_decl::~type_decl()
17240{}
17241//</type_decl definitions>
17242
17243// <scope_type_decl definitions>
17244
17245/// Constructor.
17246///
17247/// @param env the environment we are operating from.
17248///
17249/// @param name the name of the type.
17250///
17251/// @param size_in_bits the size of the type, in bits.
17252///
17253/// @param alignment_in_bits the alignment of the type, in bits.
17254///
17255/// @param locus the source location where the type is defined.
17256///
17257/// @param vis the visibility of the type.
17258scope_type_decl::scope_type_decl(const environment& env,
17259 const string& name,
17260 size_t size_in_bits,
17261 size_t alignment_in_bits,
17262 const location& locus,
17263 visibility vis)
17264 : type_or_decl_base(env,
17265 ABSTRACT_SCOPE_TYPE_DECL
17266 | ABSTRACT_TYPE_BASE
17267 | ABSTRACT_DECL_BASE),
17268 decl_base(env, name, locus, "", vis),
17269 type_base(env, size_in_bits, alignment_in_bits),
17270 scope_decl(env, name, locus)
17271{}
17272
17273/// Compares two instances of @ref scope_type_decl.
17274///
17275/// If the two intances are different, set a bitfield to give some
17276/// insight about the kind of differences there are.
17277///
17278/// @param l the first artifact of the comparison.
17279///
17280/// @param r the second artifact of the comparison.
17281///
17282/// @param k a pointer to a bitfield that gives information about the
17283/// kind of changes there are between @p l and @p r. This one is set
17284/// iff @p k is non-null and the function returns false.
17285///
17286/// Please note that setting k to a non-null value does have a
17287/// negative performance impact because even if @p l and @p r are not
17288/// equal, the function keeps up the comparison in order to determine
17289/// the different kinds of ways in which they are different.
17290///
17291/// @return true if @p l equals @p r, false otherwise.
17292bool
17294{
17295 bool result = equals(static_cast<const scope_decl&>(l),
17296 static_cast<const scope_decl&>(r),
17297 k);
17298
17299 if (!k && !result)
17301
17302 result &= equals(static_cast<const type_base&>(l),
17303 static_cast<const type_base&>(r),
17304 k);
17305
17306 ABG_RETURN(result);
17307}
17308
17309/// Equality operator between two scope_type_decl.
17310///
17311/// Note that this function does not consider the scope of the scope
17312/// types themselves.
17313///
17314/// @return true iff both scope types are equal.
17315bool
17317{
17318 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
17319 if (!other)
17320 return false;
17321 return try_canonical_compare(this, other);
17322}
17323
17324/// Equality operator between two scope_type_decl.
17325///
17326/// This re-uses the equality operator that takes a decl_base.
17327///
17328/// @param o the other scope_type_decl to compare against.
17329///
17330/// @return true iff both scope types are equal.
17331bool
17332scope_type_decl::operator==(const type_base& o) const
17333{
17334 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17335 if (!other)
17336 return false;
17337
17338 return *this == *other;
17339}
17340
17341/// Traverses an instance of @ref scope_type_decl, visiting all the
17342/// sub-types and decls that it might contain.
17343///
17344/// @param v the visitor that is used to visit every IR sub-node of
17345/// the current node.
17346///
17347/// @return true if either
17348/// - all the children nodes of the current IR node were traversed
17349/// and the calling code should keep going with the traversing.
17350/// - or the current IR node is already being traversed.
17351/// Otherwise, returning false means that the calling code should not
17352/// keep traversing the tree.
17353bool
17355{
17356 if (visiting())
17357 return true;
17358
17359 if (v.type_node_has_been_visited(this))
17360 return true;
17361
17362 if (v.visit_begin(this))
17363 {
17364 visiting(true);
17365 for (scope_decl::declarations::const_iterator i =
17366 get_member_decls().begin();
17367 i != get_member_decls ().end();
17368 ++i)
17369 if (!(*i)->traverse(v))
17370 break;
17371 visiting(false);
17372 }
17373
17374 bool result = v.visit_end(this);
17376
17377 return result;
17378}
17379
17380scope_type_decl::~scope_type_decl()
17381{}
17382// </scope_type_decl definitions>
17383
17384// <namespace_decl>
17385
17386/// Constructor.
17387///
17388/// @param the environment we are operatin from.
17389///
17390/// @param name the name of the namespace.
17391///
17392/// @param locus the source location where the namespace is defined.
17393///
17394/// @param vis the visibility of the namespace.
17396 const string& name,
17397 const location& locus,
17398 visibility vis)
17399 // We need to call the constructor of decl_base directly here
17400 // because it is virtually inherited by scope_decl. Note that we
17401 // just implicitely call the default constructor for scope_decl
17402 // here, as what we really want is to initialize the decl_base
17403 // subobject. Wow, virtual inheritance is useful, but setting it
17404 // up is ugly.
17405 : type_or_decl_base(env,
17406 NAMESPACE_DECL
17407 | ABSTRACT_DECL_BASE
17408 | ABSTRACT_SCOPE_DECL),
17409 decl_base(env, name, locus, "", vis),
17410 scope_decl(env, name, locus)
17411{
17413}
17414
17415/// Build and return a copy of the pretty representation of the
17416/// namespace.
17417///
17418/// @param internal set to true if the call is intended to get a
17419/// representation of the decl (or type) for the purpose of canonical
17420/// type comparison. This is mainly used in the function
17421/// type_base::get_canonical_type_for().
17422///
17423/// In other words if the argument for this parameter is true then the
17424/// call is meant for internal use (for technical use inside the
17425/// library itself), false otherwise. If you don't know what this is
17426/// for, then set it to false.
17427///
17428/// @param qualified_name if true, names emitted in the pretty
17429/// representation are fully qualified.
17430///
17431/// @return a copy of the pretty representation of the namespace.
17432string
17434 bool qualified_name) const
17435{
17436 string r =
17437 "namespace " + scope_decl::get_pretty_representation(internal,
17438 qualified_name);
17439 return r;
17440}
17441
17442/// Return true iff both namespaces and their members are equal.
17443///
17444/// Note that this function does not check if the scope of these
17445/// namespaces are equal.
17446bool
17448{
17449 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
17450 if (!other)
17451 return false;
17452 return scope_decl::operator==(*other);
17453}
17454
17455/// Test if the current namespace_decl is empty or contains empty
17456/// namespaces itself.
17457///
17458/// @return true iff the current namespace_decl is empty or contains
17459/// empty itself.
17460bool
17462{
17463 if (is_empty())
17464 return true;
17465
17466 for (declarations::const_iterator i = get_member_decls().begin();
17467 i != get_member_decls().end();
17468 ++i)
17469 {
17470 if (!is_namespace(*i))
17471 return false;
17472
17474 ABG_ASSERT(ns);
17475
17476 if (!ns->is_empty_or_has_empty_sub_namespaces())
17477 return false;
17478 }
17479
17480 return true;
17481}
17482
17483/// This implements the ir_traversable_base::traverse pure virtual
17484/// function.
17485///
17486/// @param v the visitor used on the current instance and on its
17487/// member nodes.
17488///
17489/// @return true if the entire IR node tree got traversed, false
17490/// otherwise.
17491bool
17493{
17494 if (visiting())
17495 return true;
17496
17497 if (v.visit_begin(this))
17498 {
17499 visiting(true);
17500 scope_decl::declarations::const_iterator i;
17501 for (i = get_member_decls().begin();
17502 i != get_member_decls ().end();
17503 ++i)
17504 {
17506 dynamic_pointer_cast<ir_traversable_base>(*i);
17507 if (t)
17508 if (!t->traverse (v))
17509 break;
17510 }
17511 visiting(false);
17512 }
17513 return v.visit_end(this);
17514}
17515
17516namespace_decl::~namespace_decl()
17517{
17518}
17519
17520// </namespace_decl>
17521
17522// <qualified_type_def>
17523
17524/// Type of the private data of qualified_type_def.
17525class qualified_type_def::priv
17526{
17527 friend class qualified_type_def;
17528
17529 qualified_type_def::CV cv_quals_;
17530 // Before the type is canonicalized, this is used as a temporary
17531 // internal name.
17532 interned_string temporary_internal_name_;
17533 // Once the type is canonicalized, this is used as the internal
17534 // name.
17535 interned_string internal_name_;
17536 weak_ptr<type_base> underlying_type_;
17537
17538 priv()
17539 : cv_quals_(CV_NONE)
17540 {}
17541
17542 priv(qualified_type_def::CV quals,
17543 type_base_sptr t)
17544 : cv_quals_(quals),
17545 underlying_type_(t)
17546 {}
17547
17548 priv(qualified_type_def::CV quals)
17549 : cv_quals_(quals)
17550 {}
17551};// end class qualified_type_def::priv
17552
17553/// Build the name of the current instance of qualified type.
17554///
17555/// @param fully_qualified if true, build a fully qualified name.
17556///
17557/// @param internal set to true if the call is intended for an
17558/// internal use (for technical use inside the library itself), false
17559/// otherwise. If you don't know what this is for, then set it to
17560/// false.
17561///
17562/// @return a copy of the newly-built name.
17563string
17564qualified_type_def::build_name(bool fully_qualified, bool internal) const
17565{
17566 type_base_sptr t = get_underlying_type();
17567 if (!t)
17568 // The qualified type might temporarily have no underlying type,
17569 // especially during the construction of the type, while the
17570 // underlying type is not yet constructed. In that case, let's do
17571 // like if the underlying type is the 'void' type.
17573
17575 fully_qualified,
17576 internal);
17577}
17578
17579/// This function is automatically invoked whenever an instance of
17580/// this type is canonicalized.
17581///
17582/// It's an overload of the virtual type_base::on_canonical_type_set.
17583///
17584/// We put here what is thus meant to be executed only at the point of
17585/// type canonicalization.
17586void
17589
17590/// Constructor of the qualified_type_def
17591///
17592/// @param type the underlying type
17593///
17594/// @param quals a bitfield representing the const/volatile qualifiers
17595///
17596/// @param locus the location of the qualified type definition
17597qualified_type_def::qualified_type_def(type_base_sptr type,
17598 CV quals,
17599 const location& locus)
17601 QUALIFIED_TYPE
17602 | ABSTRACT_TYPE_BASE
17603 | ABSTRACT_DECL_BASE),
17604 type_base(type->get_environment(), type->get_size_in_bits(),
17605 type->get_alignment_in_bits()),
17606 decl_base(type->get_environment(), "", locus, "",
17607 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
17608 priv_(new priv(quals, type))
17609{
17611 interned_string name = type->get_environment().intern(build_name(false));
17612 set_name(name);
17613}
17614
17615/// Constructor of the qualified_type_def
17616///
17617/// @param env the environment of the type.
17618///
17619/// @param quals a bitfield representing the const/volatile qualifiers
17620///
17621/// @param locus the location of the qualified type definition
17622qualified_type_def::qualified_type_def(const environment& env,
17623 CV quals,
17624 const location& locus)
17625 : type_or_decl_base(env,
17626 QUALIFIED_TYPE
17627 | ABSTRACT_TYPE_BASE
17628 | ABSTRACT_DECL_BASE),
17629 type_base(env, /*size_in_bits=*/0,
17630 /*alignment_in_bits=*/0),
17631 decl_base(env, "", locus, ""),
17632 priv_(new priv(quals))
17633{
17635 // We don't yet have an underlying type. So for naming purpose,
17636 // let's temporarily pretend the underlying type is 'void'.
17637 interned_string name = env.intern("void");
17638 set_name(name);
17639}
17640
17641/// Return the hash value of the current IR node.
17642///
17643/// Note that upon the first invocation, this member functions
17644/// computes the hash value and returns it. Subsequent invocations
17645/// just return the hash value that was previously calculated.
17646///
17647/// @return the hash value of the current IR node.
17648hash_t
17650{
17652 return h;
17653}
17654
17655/// Get the size of the qualified type def.
17656///
17657/// This is an overload for type_base::get_size_in_bits().
17658///
17659/// @return the size of the qualified type.
17660size_t
17662{
17663 size_t s = 0;
17664 if (type_base_sptr ut = get_underlying_type())
17665 {
17666 // We do have the underlying type properly set, so let's make
17667 // the size of the qualified type match the size of its
17668 // underlying type.
17669 s = ut->get_size_in_bits();
17670 if (s != type_base::get_size_in_bits())
17671 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
17672 }
17674}
17675
17676/// Compares two instances of @ref qualified_type_def.
17677///
17678/// If the two intances are different, set a bitfield to give some
17679/// insight about the kind of differences there are.
17680///
17681/// @param l the first artifact of the comparison.
17682///
17683/// @param r the second artifact of the comparison.
17684///
17685/// @param k a pointer to a bitfield that gives information about the
17686/// kind of changes there are between @p l and @p r. This one is set
17687/// iff @p k is non-null and the function returns false.
17688///
17689/// Please note that setting k to a non-null value does have a
17690/// negative performance impact because even if @p l and @p r are not
17691/// equal, the function keeps up the comparison in order to determine
17692/// the different kinds of ways in which they are different.
17693///
17694/// @return true if @p l equals @p r, false otherwise.
17695bool
17697{
17698 bool result = true;
17699 if (l.get_cv_quals() != r.get_cv_quals())
17700 {
17701 result = false;
17702 if (k)
17704 else
17706 }
17707
17709 {
17710 result = false;
17711 if (k)
17712 {
17714 r.get_underlying_type().get()))
17715 // Underlying type changes in which the structure of the
17716 // type changed are considered local changes to the
17717 // qualified type.
17719 else
17720 *k |= SUBTYPE_CHANGE_KIND;
17721 }
17722 else
17723 // okay strictly speaking this is not necessary, but I am
17724 // putting it here to maintenance; that is, so that adding
17725 // subsequent clauses needed to compare two qualified types
17726 // later still works.
17728 }
17729
17730 ABG_RETURN(result);
17731}
17732
17733/// Equality operator for qualified types.
17734///
17735/// Note that this function does not check for equality of the scopes.
17736///
17737///@param o the other qualified type to compare against.
17738///
17739/// @return true iff both qualified types are equal.
17740bool
17741qualified_type_def::operator==(const decl_base& o) const
17742{
17743 const qualified_type_def* other =
17744 dynamic_cast<const qualified_type_def*>(&o);
17745 if (!other)
17746 return false;
17747 return try_canonical_compare(this, other);
17748}
17749
17750/// Equality operator for qualified types.
17751///
17752/// Note that this function does not check for equality of the scopes.
17753/// Also, this re-uses the equality operator above that takes a
17754/// decl_base.
17755///
17756///@param o the other qualified type to compare against.
17757///
17758/// @return true iff both qualified types are equal.
17759bool
17760qualified_type_def::operator==(const type_base& o) const
17761{
17762 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17763 if (!other)
17764 return false;
17765 return *this == *other;
17766}
17767
17768/// Equality operator for qualified types.
17769///
17770/// Note that this function does not check for equality of the scopes.
17771/// Also, this re-uses the equality operator above that takes a
17772/// decl_base.
17773///
17774///@param o the other qualified type to compare against.
17775///
17776/// @return true iff both qualified types are equal.
17777bool
17778qualified_type_def::operator==(const qualified_type_def& o) const
17779{
17780 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17781 if (!other)
17782 return false;
17783 return *this == *other;
17784}
17785
17786/// Implementation for the virtual qualified name builder for @ref
17787/// qualified_type_def.
17788///
17789/// @param qualified_name the output parameter to hold the resulting
17790/// qualified name.
17791///
17792/// @param internal set to true if the call is intended for an
17793/// internal use (for technical use inside the library itself), false
17794/// otherwise. If you don't know what this is for, then set it to
17795/// false.
17796void
17798 bool internal) const
17799{qualified_name = get_qualified_name(internal);}
17800
17801/// Implementation of the virtual qualified name builder/getter.
17802///
17803/// @param internal set to true if the call is intended for an
17804/// internal use (for technical use inside the library itself), false
17805/// otherwise. If you don't know what this is for, then set it to
17806/// false.
17807///
17808/// @return the resulting qualified name.
17809const interned_string&
17811{
17812 const environment& env = get_environment();
17813
17814
17815 if (!get_canonical_type())
17816 {
17817 // The type hasn't been canonicalized yet. We want to return a
17818 // temporary name that is not cached because the structure of
17819 // this type (and so its name) can change until its
17820 // canonicalized.
17821 if (internal)
17822 {
17823 // We are asked to return a temporary *internal* name.
17824 // Lets compute it and return a reference to where it's
17825 // stored.
17826 if (priv_->temporary_internal_name_.empty())
17827 priv_->temporary_internal_name_ =
17828 env.intern(build_name(true, /*internal=*/true));
17829 return priv_->temporary_internal_name_;
17830 }
17831 else
17832 {
17833 // We are asked to return a temporary non-internal name.
17835 (env.intern(build_name(true, /*internal=*/false)));
17837 }
17838 }
17839 else
17840 {
17841 // The type has already been canonicalized. We want to return
17842 // the definitive name and cache it.
17843 if (internal)
17844 {
17845 if (priv_->internal_name_.empty())
17846 priv_->internal_name_ =
17847 env.intern(build_name(/*qualified=*/true,
17848 /*internal=*/true));
17849 return priv_->internal_name_;
17850 }
17851 else
17852 {
17853 if (peek_qualified_name().empty())
17855 (env.intern(build_name(/*qualified=*/true,
17856 /*internal=*/false)));
17857 return peek_qualified_name();
17858 }
17859 }
17860}
17861
17862/// This implements the ir_traversable_base::traverse pure virtual
17863/// function.
17864///
17865/// @param v the visitor used on the current instance.
17866///
17867/// @return true if the entire IR node tree got traversed, false
17868/// otherwise.
17869bool
17871{
17872 if (v.type_node_has_been_visited(this))
17873 return true;
17874
17875 if (visiting())
17876 return true;
17877
17878 if (v.visit_begin(this))
17879 {
17880 visiting(true);
17881 if (type_base_sptr t = get_underlying_type())
17882 t->traverse(v);
17883 visiting(false);
17884 }
17885 bool result = v.visit_end(this);
17887 return result;
17888}
17889
17890qualified_type_def::~qualified_type_def()
17891{
17892}
17893
17894/// Getter of the const/volatile qualifier bit field
17897{return priv_->cv_quals_;}
17898
17899/// Setter of the const/value qualifiers bit field
17900void
17902{priv_->cv_quals_ = cv_quals;}
17903
17904/// Compute and return the string prefix or suffix representing the
17905/// qualifiers hold by the current instance of @ref
17906/// qualified_type_def.
17907///
17908/// @return the newly-built cv string.
17909string
17912
17913/// Getter of the underlying type
17914type_base_sptr
17916{return priv_->underlying_type_.lock();}
17917
17918/// Setter of the underlying type.
17919///
17920/// @param t the new underlying type.
17921void
17923{
17924 ABG_ASSERT(t);
17925 priv_->underlying_type_ = t;
17926 // Now we need to update other properties that depend on the new underlying type.
17927 set_size_in_bits(t->get_size_in_bits());
17928 set_alignment_in_bits(t->get_alignment_in_bits());
17930 set_name(name);
17931 if (scope_decl* s = get_scope())
17932 {
17933 // Now that the name has been updated, we need to update the
17934 // lookup maps accordingly.
17935 scope_decl::declarations::iterator i;
17936 if (s->find_iterator_for_member(this, i))
17938 else
17940 }
17941}
17942
17943/// Non-member equality operator for @ref qualified_type_def
17944///
17945/// @param l the left-hand side of the equality operator
17946///
17947/// @param r the right-hand side of the equality operator
17948///
17949/// @return true iff @p l and @p r equals.
17950bool
17951operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17952{
17953 if (l.get() == r.get())
17954 return true;
17955 if (!!l != !!r)
17956 return false;
17957
17958 return *l == *r;
17959}
17960
17961/// Non-member inequality operator for @ref qualified_type_def
17962///
17963/// @param l the left-hand side of the equality operator
17964///
17965/// @param r the right-hand side of the equality operator
17966///
17967/// @return true iff @p l and @p r equals.
17968bool
17969operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17970{return ! operator==(l, r);}
17971
17972/// Overloaded bitwise OR operator for cv qualifiers.
17975{
17976 return static_cast<qualified_type_def::CV>
17977 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17978}
17979
17980/// Overloaded bitwise |= operator for cv qualifiers.
17983{
17984 l = l | r;
17985 return l;
17986}
17987
17988/// Overloaded bitwise &= operator for cv qualifiers.
17991{
17992 l = l & r;
17993 return l;
17994}
17995
17996/// Overloaded bitwise AND operator for CV qualifiers.
17999{
18000 return static_cast<qualified_type_def::CV>
18001 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
18002}
18003
18004/// Overloaded bitwise inverting operator for CV qualifiers.
18007{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
18008
18009/// Streaming operator for qualified_type_decl::CV
18010///
18011/// @param o the output stream to serialize the cv qualifier to.
18012///
18013/// @param cv the cv qualifier to serialize.
18014///
18015/// @return the output stream used.
18016std::ostream&
18017operator<<(std::ostream& o, qualified_type_def::CV cv)
18018{
18019 string str;
18020
18021 switch (cv)
18022 {
18023 case qualified_type_def::CV_NONE:
18024 str = "none";
18025 break;
18026 case qualified_type_def::CV_CONST:
18027 str = "const";
18028 break;
18029 case qualified_type_def::CV_VOLATILE:
18030 str = "volatile";
18031 break;
18032 case qualified_type_def::CV_RESTRICT:
18033 str = "restrict";
18034 break;
18035 }
18036
18037 o << str;
18038 return o;
18039}
18040
18041// </qualified_type_def>
18042
18043//<pointer_type_def definitions>
18044
18045/// Private data structure of the @ref pointer_type_def.
18046struct pointer_type_def::priv
18047{
18048 type_base_wptr pointed_to_type_;
18049 type_base* naked_pointed_to_type_;
18050 interned_string internal_qualified_name_;
18051 interned_string temp_internal_qualified_name_;
18052
18053 priv(const type_base_sptr& t)
18054 : pointed_to_type_(type_or_void(t, t->get_environment())),
18055 naked_pointed_to_type_(t.get())
18056 {}
18057
18058 priv()
18059 : naked_pointed_to_type_()
18060 {}
18061}; //end struct pointer_type_def
18062
18063/// This function is automatically invoked whenever an instance of
18064/// this type is canonicalized.
18065///
18066/// It's an overload of the virtual type_base::on_canonical_type_set.
18067///
18068/// We put here what is thus meant to be executed only at the point of
18069/// type canonicalization.
18070void
18073
18074
18075///Constructor of @ref pointer_type_def.
18076///
18077/// @param pointed_to the pointed-to type.
18078///
18079/// @param size_in_bits the size of the type, in bits.
18080///
18081/// @param align_in_bits the alignment of the type, in bits.
18082///
18083/// @param locus the source location where the type was defined.
18084pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
18085 size_t size_in_bits,
18086 size_t align_in_bits,
18087 const location& locus)
18088 : type_or_decl_base(pointed_to->get_environment(),
18089 POINTER_TYPE
18090 | ABSTRACT_TYPE_BASE
18091 | ABSTRACT_DECL_BASE),
18092 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18093 decl_base(pointed_to->get_environment(), "", locus, ""),
18094 priv_(new priv(pointed_to))
18095{
18097 try
18098 {
18099 ABG_ASSERT(pointed_to);
18100 const environment& env = pointed_to->get_environment();
18101 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18102 string name = (pto ? pto->get_name() : string("void")) + "*";
18103 set_name(env.intern(name));
18104 if (pto)
18105 set_visibility(pto->get_visibility());
18106 }
18107 catch (...)
18108 {}
18109}
18110
18111///Constructor of @ref pointer_type_def.
18112///
18113/// @param env the environment of the type.
18114///
18115/// @param size_in_bits the size of the type, in bits.
18116///
18117/// @param align_in_bits the alignment of the type, in bits.
18118///
18119/// @param locus the source location where the type was defined.
18120pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
18121 size_t alignment_in_bits,
18122 const location& locus)
18123 : type_or_decl_base(env,
18124 POINTER_TYPE
18125 | ABSTRACT_TYPE_BASE
18126 | ABSTRACT_DECL_BASE),
18127 type_base(env, size_in_bits, alignment_in_bits),
18128 decl_base(env, "", locus, ""),
18129 priv_(new priv())
18130{
18132 string name = string("void") + "*";
18133 set_name(env.intern(name));
18134}
18135
18136/// Return the hash value of the current IR node.
18137///
18138/// Note that upon the first invocation, this member functions
18139/// computes the hash value and returns it. Subsequent invocations
18140/// just return the hash value that was previously calculated.
18141///
18142/// @return the hash value of the current IR node.
18143hash_t
18145{
18147 return h;
18148}
18149
18150/// Set the pointed-to type of the pointer.
18151///
18152/// @param t the new pointed-to type.
18153void
18155{
18156 ABG_ASSERT(t);
18157 priv_->pointed_to_type_ = t;
18158 priv_->naked_pointed_to_type_ = t.get();
18159
18160 try
18161 {
18162 const environment& env = t->get_environment();
18163 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
18164 string name = (pto ? pto->get_name() : string("void")) + "*";
18165 set_name(env.intern(name));
18166 if (pto)
18167 set_visibility(pto->get_visibility());
18168 }
18169 catch (...)
18170 {}
18171}
18172
18173/// Compares two instances of @ref pointer_type_def.
18174///
18175/// If the two intances are different, set a bitfield to give some
18176/// insight about the kind of differences there are.
18177///
18178/// @param l the first artifact of the comparison.
18179///
18180/// @param r the second artifact of the comparison.
18181///
18182/// @param k a pointer to a bitfield that gives information about the
18183/// kind of changes there are between @p l and @p r. This one is set
18184/// iff @p k is non-null and the function returns false.
18185///
18186/// Please note that setting k to a non-null value does have a
18187/// negative performance impact because even if @p l and @p r are not
18188/// equal, the function keeps up the comparison in order to determine
18189/// the different kinds of ways in which they are different.
18190///
18191/// @return true if @p l equals @p r, false otherwise.
18192bool
18194{
18195 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18196 bool result = p1 == p2;
18197 if (!result)
18198 if (k)
18199 {
18200 if (!types_have_similar_structure(&l, &r))
18201 // pointed-to type changes in which the structure of the
18202 // type changed are considered local changes to the pointer
18203 // type.
18205 *k |= SUBTYPE_CHANGE_KIND;
18206 }
18207
18208 ABG_RETURN(result);
18209}
18210
18211/// Return true iff both instances of pointer_type_def are equal.
18212///
18213/// Note that this function does not check for the scopes of the this
18214/// types.
18215bool
18216pointer_type_def::operator==(const decl_base& o) const
18217{
18218 const pointer_type_def* other = is_pointer_type(&o);
18219 if (!other)
18220 return false;
18221 return try_canonical_compare(this, other);
18222}
18223
18224/// Return true iff both instances of pointer_type_def are equal.
18225///
18226/// Note that this function does not check for the scopes of the
18227/// types.
18228///
18229/// @param other the other type to compare against.
18230///
18231/// @return true iff @p other equals the current instance.
18232bool
18233pointer_type_def::operator==(const type_base& other) const
18234{
18235 const decl_base* o = is_decl(&other);
18236 if (!o)
18237 return false;
18238 return *this == *o;
18239}
18240
18241/// Return true iff both instances of pointer_type_def are equal.
18242///
18243/// Note that this function does not check for the scopes of the
18244/// types.
18245///
18246/// @param other the other type to compare against.
18247///
18248/// @return true iff @p other equals the current instance.
18249bool
18250pointer_type_def::operator==(const pointer_type_def& other) const
18251{
18252 const decl_base& o = other;
18253 return *this == o;
18254}
18255
18256/// Getter of the pointed-to type.
18257///
18258/// @return the pointed-to type.
18259const type_base_sptr
18261{return priv_->pointed_to_type_.lock();}
18262
18263/// Getter of a naked pointer to the pointed-to type.
18264///
18265/// @return a naked pointed to the pointed-to type.
18266type_base*
18268{return priv_->naked_pointed_to_type_;}
18269
18270/// Build and return the qualified name of the current instance of
18271/// @ref pointer_type_def.
18272///
18273/// @param qn output parameter. The resulting qualified name.
18274///
18275/// @param internal set to true if the call is intended for an
18276/// internal use (for technical use inside the library itself), false
18277/// otherwise. If you don't know what this is for, then set it to
18278/// false.
18279void
18281{qn = get_qualified_name(internal);}
18282
18283/// Build, cache and return the qualified name of the current instance
18284/// of @ref pointer_type_def. Subsequent invocations of this function
18285/// return the cached value.
18286///
18287/// Note that this function should work even if the underlying type is
18288/// momentarily empty.
18289///
18290/// @param internal set to true if the call is intended for an
18291/// internal use (for technical use inside the library itself), false
18292/// otherwise. If you don't know what this is for, then set it to
18293/// false.
18294///
18295/// @return the resulting qualified name.
18296const interned_string&
18298{
18299 type_base* pointed_to_type = get_naked_pointed_to_type();
18300 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18301
18302 if (internal)
18303 {
18304 if (get_canonical_type())
18305 {
18306 if (priv_->internal_qualified_name_.empty())
18307 if (pointed_to_type)
18308 priv_->internal_qualified_name_ =
18309 pointer_declaration_name(this,
18310 /*variable_name=*/"",
18311 /*qualified_name=*/
18312 is_typedef(pointed_to_type)
18313 ? false
18314 : true,
18315 /*internal=*/true);
18316 return priv_->internal_qualified_name_;
18317 }
18318 else
18319 {
18320 // As the type hasn't yet been canonicalized, its structure
18321 // (and so its name) can change. So let's invalidate the
18322 // cache where we store its name at each invocation of this
18323 // function.
18324 if (pointed_to_type)
18325 if (priv_->temp_internal_qualified_name_.empty())
18326 priv_->temp_internal_qualified_name_ =
18327 pointer_declaration_name(this,
18328 /*variable_name=*/"",
18329 /*qualified_name=*/
18330 is_typedef(pointed_to_type)
18331 ? false
18332 : true,
18333 /*internal=*/true);
18334 return priv_->temp_internal_qualified_name_;
18335 }
18336 }
18337 else
18338 {
18340 {
18341 if (decl_base::peek_qualified_name().empty())
18343 (pointer_declaration_name(this,
18344 /*variable_name=*/"",
18345 /*qualified_name=*/true,
18346 /*internal=*/false));
18348 }
18349 else
18350 {
18351 // As the type hasn't yet been canonicalized, its structure
18352 // (and so its name) can change. So let's invalidate the
18353 // cache where we store its name at each invocation of this
18354 // function.
18355 if (pointed_to_type)
18357 (pointer_declaration_name(this,
18358 /*variable_name=*/"",
18359 /*qualified_name=*/true,
18360 /*internal=*/false));
18362 }
18363 }
18364}
18365
18366/// This implements the ir_traversable_base::traverse pure virtual
18367/// function.
18368///
18369/// @param v the visitor used on the current instance.
18370///
18371/// @return true if the entire IR node tree got traversed, false
18372/// otherwise.
18373bool
18375{
18376 if (v.type_node_has_been_visited(this))
18377 return true;
18378
18379 if (visiting())
18380 return true;
18381
18382 if (v.visit_begin(this))
18383 {
18384 visiting(true);
18385 if (type_base_sptr t = get_pointed_to_type())
18386 t->traverse(v);
18387 visiting(false);
18388 }
18389
18390 bool result = v.visit_end(this);
18392 return result;
18393}
18394
18395pointer_type_def::~pointer_type_def()
18396{}
18397
18398/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
18399/// equality; that is, make it compare the pointed to objects too.
18400///
18401/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18402/// of the equality.
18403///
18404/// @param r the shared_ptr of @ref pointer_type_def on
18405/// right-hand-side of the equality.
18406///
18407/// @return true if the @ref pointer_type_def pointed to by the
18408/// shared_ptrs are equal, false otherwise.
18409bool
18411{
18412 if (l.get() == r.get())
18413 return true;
18414 if (!!l != !!r)
18415 return false;
18416
18417 return *l == *r;
18418}
18419
18420/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
18421/// equality; that is, make it compare the pointed to objects too.
18422///
18423/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18424/// of the equality.
18425///
18426/// @param r the shared_ptr of @ref pointer_type_def on
18427/// right-hand-side of the equality.
18428///
18429/// @return true iff the @ref pointer_type_def pointed to by the
18430/// shared_ptrs are different.
18431bool
18433{return !operator==(l, r);}
18434
18435// </pointer_type_def definitions>
18436
18437// <reference_type_def definitions>
18438
18439/// Private data structure of the @ref reference_type_def type.
18440struct reference_type_def::priv
18441{
18442
18443 type_base_wptr pointed_to_type_;
18444 bool is_lvalue_;
18445 interned_string internal_qualified_name_;
18446 interned_string temp_internal_qualified_name_;
18447
18448 priv(const type_base_sptr& t, bool is_lvalue)
18449 : pointed_to_type_(type_or_void(t, t->get_environment())),
18450 is_lvalue_(is_lvalue)
18451 {}
18452
18453 priv(bool is_lvalue)
18454 : is_lvalue_(is_lvalue)
18455 {}
18456
18457 priv() = delete;
18458};
18459
18460/// This function is automatically invoked whenever an instance of
18461/// this type is canonicalized.
18462///
18463/// It's an overload of the virtual type_base::on_canonical_type_set.
18464///
18465/// We put here what is thus meant to be executed only at the point of
18466/// type canonicalization.
18467void
18470
18471/// Constructor of the reference_type_def type.
18472///
18473/// @param pointed_to the pointed to type.
18474///
18475/// @param lvalue wether the reference is an lvalue reference. If
18476/// false, the reference is an rvalue one.
18477///
18478/// @param size_in_bits the size of the type, in bits.
18479///
18480/// @param align_in_bits the alignment of the type, in bits.
18481///
18482/// @param locus the source location of the type.
18483reference_type_def::reference_type_def(const type_base_sptr pointed_to,
18484 bool lvalue,
18485 size_t size_in_bits,
18486 size_t align_in_bits,
18487 const location& locus)
18488 : type_or_decl_base(pointed_to->get_environment(),
18489 REFERENCE_TYPE
18490 | ABSTRACT_TYPE_BASE
18491 | ABSTRACT_DECL_BASE),
18492 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18493 decl_base(pointed_to->get_environment(), "", locus, ""),
18494 priv_(new priv(pointed_to, lvalue))
18495{
18497
18498 try
18499 {
18500 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18501 string name;
18502 if (pto)
18503 {
18504 set_visibility(pto->get_visibility());
18505 name = string(pto->get_name()) + "&";
18506 }
18507 else
18508 name = string(get_type_name(is_function_type(pointed_to),
18509 /*qualified_name=*/true)) + "&";
18510
18511 if (!is_lvalue())
18512 name += "&";
18513 const environment& env = pointed_to->get_environment();
18514 set_name(env.intern(name));
18515 }
18516 catch (...)
18517 {}
18518}
18519
18520/// Constructor of the reference_type_def type.
18521///
18522/// This one creates a type that has no pointed-to type, temporarily.
18523/// This is useful for cases where the underlying type is not yet
18524/// available. It can be set later using
18525/// reference_type_def::set_pointed_to_type().
18526///
18527/// @param env the environment of the type.
18528///
18529/// @param lvalue wether the reference is an lvalue reference. If
18530/// false, the reference is an rvalue one.
18531///
18532/// @param size_in_bits the size of the type, in bits.
18533///
18534/// @param align_in_bits the alignment of the type, in bits.
18535///
18536/// @param locus the source location of the type.
18537reference_type_def::reference_type_def(const environment& env, bool lvalue,
18538 size_t size_in_bits,
18539 size_t alignment_in_bits,
18540 const location& locus)
18541 : type_or_decl_base(env,
18542 REFERENCE_TYPE
18543 | ABSTRACT_TYPE_BASE
18544 | ABSTRACT_DECL_BASE),
18545 type_base(env, size_in_bits, alignment_in_bits),
18546 decl_base(env, "", locus, ""),
18547 priv_(new priv(lvalue))
18548{
18550 string name = "void&";
18551 if (!is_lvalue())
18552 name += "&";
18553
18554 set_name(env.intern(name));
18555 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
18556}
18557
18558/// Return the hash value of the current IR node.
18559///
18560/// Note that upon the first invocation, this member functions
18561/// computes the hash value and returns it. Subsequent invocations
18562/// just return the hash value that was previously calculated.
18563///
18564/// @return the hash value of the current IR node.
18565hash_t
18567{
18569 return h;
18570}
18571
18572/// Setter of the pointed_to type of the current reference type.
18573///
18574/// @param pointed_to the new pointed to type.
18575void
18576reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
18577{
18578 ABG_ASSERT(pointed_to_type);
18579 priv_->pointed_to_type_ = pointed_to_type;
18580
18581 decl_base_sptr pto;
18582 try
18583 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18584 catch (...)
18585 {}
18586
18587 if (pto)
18588 {
18589 set_visibility(pto->get_visibility());
18590 string name = string(pto->get_name()) + "&";
18591 if (!is_lvalue())
18592 name += "&";
18593 const environment& env = pto->get_environment();
18594 set_name(env.intern(name));
18595 }
18596}
18597
18598/// Compares two instances of @ref reference_type_def.
18599///
18600/// If the two intances are different, set a bitfield to give some
18601/// insight about the kind of differences there are.
18602///
18603/// @param l the first artifact of the comparison.
18604///
18605/// @param r the second artifact of the comparison.
18606///
18607/// @param k a pointer to a bitfield that gives information about the
18608/// kind of changes there are between @p l and @p r. This one is set
18609/// iff @p k is non-null and the function returns false.
18610///
18611/// Please note that setting k to a non-null value does have a
18612/// negative performance impact because even if @p l and @p r are not
18613/// equal, the function keeps up the comparison in order to determine
18614/// the different kinds of ways in which they are different.
18615///
18616/// @return true if @p l equals @p r, false otherwise.
18617bool
18619{
18620 if (l.is_lvalue() != r.is_lvalue())
18621 {
18622 if (k)
18625 }
18626 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18627 bool result = p1 == p2;
18628 if (!result)
18629 if (k)
18630 {
18631 if (!types_have_similar_structure(&l, &r))
18633 *k |= SUBTYPE_CHANGE_KIND;
18634 }
18635 ABG_RETURN(result);
18636}
18637
18638/// Equality operator of the @ref reference_type_def type.
18639///
18640/// @param o the other instance of @ref reference_type_def to compare
18641/// against.
18642///
18643/// @return true iff the two instances are equal.
18644bool
18645reference_type_def::operator==(const decl_base& o) const
18646{
18647 const reference_type_def* other =
18648 dynamic_cast<const reference_type_def*>(&o);
18649 if (!other)
18650 return false;
18651 return try_canonical_compare(this, other);
18652}
18653
18654/// Equality operator of the @ref reference_type_def type.
18655///
18656/// @param o the other instance of @ref reference_type_def to compare
18657/// against.
18658///
18659/// @return true iff the two instances are equal.
18660bool
18661reference_type_def::operator==(const type_base& o) const
18662{
18663 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18664 if (!other)
18665 return false;
18666 return *this == *other;
18667}
18668
18669/// Equality operator of the @ref reference_type_def type.
18670///
18671/// @param o the other instance of @ref reference_type_def to compare
18672/// against.
18673///
18674/// @return true iff the two instances are equal.
18675bool
18676reference_type_def::operator==(const reference_type_def& o) const
18677{
18678 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18679 if (!other)
18680 return false;
18681 return *this == *other;
18682}
18683
18684type_base_sptr
18685reference_type_def::get_pointed_to_type() const
18686{return priv_->pointed_to_type_.lock();}
18687
18688bool
18689reference_type_def::is_lvalue() const
18690{return priv_->is_lvalue_;}
18691
18692/// Build and return the qualified name of the current instance of the
18693/// @ref reference_type_def.
18694///
18695/// @param qn output parameter. Is set to the newly-built qualified
18696/// name of the current instance of @ref reference_type_def.
18697///
18698/// @param internal set to true if the call is intended for an
18699/// internal use (for technical use inside the library itself), false
18700/// otherwise. If you don't know what this is for, then set it to
18701/// false.
18702void
18704{qn = get_qualified_name(internal);}
18705
18706/// Build, cache and return the qualified name of the current instance
18707/// of the @ref reference_type_def. Subsequent invocations of this
18708/// function return the cached value.
18709///
18710/// @param internal set to true if the call is intended for an
18711/// internal use (for technical use inside the library itself), false
18712/// otherwise. If you don't know what this is for, then set it to
18713/// false.
18714///
18715/// @return the newly-built qualified name of the current instance of
18716/// @ref reference_type_def.
18717const interned_string&
18719{
18720 type_base_sptr pointed_to_type = get_pointed_to_type();
18721 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18722
18723 if (internal)
18724 {
18725 if (get_canonical_type())
18726 {
18727 if (priv_->internal_qualified_name_.empty())
18728 if (pointed_to_type)
18729 priv_->internal_qualified_name_ =
18730 get_name_of_reference_to_type(*pointed_to_type,
18731 is_lvalue(),
18732 /*qualified_name=*/
18733 is_typedef(pointed_to_type)
18734 ? false
18735 : true,
18736 /*internal=*/true);
18737 return priv_->internal_qualified_name_;
18738 }
18739 else
18740 {
18741 // As the type hasn't yet been canonicalized, its structure
18742 // (and so its name) can change. So let's invalidate the
18743 // cache where we store its name at each invocation of this
18744 // function.
18745 if (pointed_to_type)
18746 if (priv_->temp_internal_qualified_name_.empty())
18747 priv_->temp_internal_qualified_name_ =
18748 get_name_of_reference_to_type(*pointed_to_type,
18749 is_lvalue(),
18750 /*qualified_name=*/
18751 is_typedef(pointed_to_type)
18752 ? false
18753 : true,
18754 /*internal=*/true);
18755 return priv_->temp_internal_qualified_name_;
18756 }
18757 }
18758 else
18759 {
18761 {
18763 (get_name_of_reference_to_type(*pointed_to_type,
18764 is_lvalue(),
18765 /*qualified_name=*/true,
18766 /*internal=*/false));
18768 }
18769 else
18770 {
18771 // As the type hasn't yet been canonicalized, its structure
18772 // (and so its name) can change. So let's invalidate the
18773 // cache where we store its name at each invocation of this
18774 // function.
18775 if (pointed_to_type)
18777 (get_name_of_reference_to_type(*pointed_to_type,
18778 is_lvalue(),
18779 /*qualified_name=*/true,
18780 /*internal=*/false));
18782 }
18783 }
18784}
18785
18786/// Get the pretty representation of the current instance of @ref
18787/// reference_type_def.
18788///
18789/// @param internal set to true if the call is intended to get a
18790/// representation of the decl (or type) for the purpose of canonical
18791/// type comparison. This is mainly used in the function
18792/// type_base::get_canonical_type_for().
18793///
18794/// In other words if the argument for this parameter is true then the
18795/// call is meant for internal use (for technical use inside the
18796/// library itself), false otherwise. If you don't know what this is
18797/// for, then set it to false.
18798///
18799/// @param qualified_name if true, names emitted in the pretty
18800/// representation are fully qualified.
18801///
18802/// @return the pretty representatin of the @ref reference_type_def.
18803string
18805 bool qualified_name) const
18806{
18807 string result =
18809 (get_pointed_to_type()),
18810 is_lvalue(),
18811 qualified_name,
18812 internal);
18813
18814 return result;
18815}
18816
18817/// This implements the ir_traversable_base::traverse pure virtual
18818/// function.
18819///
18820/// @param v the visitor used on the current instance.
18821///
18822/// @return true if the entire IR node tree got traversed, false
18823/// otherwise.
18824bool
18826{
18827 if (v.type_node_has_been_visited(this))
18828 return true;
18829
18830 if (visiting())
18831 return true;
18832
18833 if (v.visit_begin(this))
18834 {
18835 visiting(true);
18836 if (type_base_sptr t = get_pointed_to_type())
18837 t->traverse(v);
18838 visiting(false);
18839 }
18840
18841 bool result = v.visit_end(this);
18843 return result;
18844}
18845
18846reference_type_def::~reference_type_def()
18847{}
18848
18849/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18850/// equality; that is, make it compare the pointed to objects too.
18851///
18852/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18853/// of the equality.
18854///
18855/// @param r the shared_ptr of @ref reference_type_def on
18856/// right-hand-side of the equality.
18857///
18858/// @return true if the @ref reference_type_def pointed to by the
18859/// shared_ptrs are equal, false otherwise.
18860bool
18862{
18863 if (l.get() == r.get())
18864 return true;
18865 if (!!l != !!r)
18866 return false;
18867
18868 return *l == *r;
18869}
18870
18871/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18872/// equality; that is, make it compare the pointed to objects too.
18873///
18874/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18875/// of the equality.
18876///
18877/// @param r the shared_ptr of @ref reference_type_def on
18878/// right-hand-side of the equality.
18879///
18880/// @return true iff the @ref reference_type_def pointed to by the
18881/// shared_ptrs are different.
18882bool
18885
18886// </reference_type_def definitions>
18887
18888// <ptr_to_mbr_type definitions>
18889
18890/// The private data type of @ref ptr_to_mbr_type.
18891struct ptr_to_mbr_type::priv
18892{
18893 // The type of the data member this pointer-to-member-type
18894 // designates.
18895 type_base_sptr dm_type_;
18896 // The class (or typedef to potentially qualified class) containing
18897 // the data member this pointer-to-member-type designates.
18898 type_base_sptr containing_type_;
18899 interned_string internal_qualified_name_;
18900 interned_string temp_internal_qualified_name_;
18901
18902 priv()
18903 {}
18904
18905 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18906 : dm_type_(dm_type),
18907 containing_type_(containing_type)
18908 {}
18909};// end struct ptr_to_mbr_type::priv
18910
18911/// A constructor for a @ref ptr_to_mbr_type type.
18912///
18913/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18914///
18915/// @param member_type the member type of the of the @ref
18916/// ptr_to_mbr_type to construct.
18917///
18918/// @param containing_type the containing type of the @ref
18919/// ptr_to_mbr_type to construct.
18920///
18921/// @param size_in_bits the size (in bits) of the resulting type.
18922///
18923/// @param alignment_in_bits the alignment (in bits) of the resulting
18924/// type.
18925///
18926/// @param locus the source location of the definition of the
18927/// resulting type.
18928ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18929 const type_base_sptr& member_type,
18930 const type_base_sptr& containing_type,
18931 size_t size_in_bits,
18932 size_t alignment_in_bits,
18933 const location& locus)
18934 : type_or_decl_base(env,
18935 POINTER_TO_MEMBER_TYPE
18936 | ABSTRACT_TYPE_BASE
18937 | ABSTRACT_DECL_BASE),
18938 type_base(env, size_in_bits, alignment_in_bits),
18939 decl_base(env, "", locus, ""),
18940 priv_(new priv(member_type, containing_type))
18941{
18943 ABG_ASSERT(member_type);
18944 ABG_ASSERT(containing_type);
18945 set_is_anonymous(false);
18946}
18947
18948/// Getter of the name of the current ptr-to-mbr-type.
18949///
18950/// This just returns the qualified name.
18951///
18952/// @return the (qualified) name of the the type.
18953const interned_string&
18955{
18956 return get_qualified_name(/*internal=*/false);
18957}
18958
18959/// Return the hash value of the current IR node.
18960///
18961/// Note that upon the first invocation, this member functions
18962/// computes the hash value and returns it. Subsequent invocations
18963/// just return the hash value that was previously calculated.
18964///
18965/// @return the hash value of the current IR node.
18966hash_t
18968{
18970 return h;
18971}
18972
18973/// Getter of the member type of the current @ref ptr_to_mbr_type.
18974///
18975/// @return the type of the member referred to by the current
18976/// @ptr_to_mbr_type.
18977const type_base_sptr&
18979{return priv_->dm_type_;}
18980
18981/// Getter of the type containing the member pointed-to by the current
18982/// @ref ptr_to_mbr_type.
18983///
18984/// @return the type containing the member pointed-to by the current
18985/// @ref ptr_to_mbr_type.
18986const type_base_sptr&
18988{return priv_->containing_type_;}
18989
18990/// Equality operator for the current @ref ptr_to_mbr_type.
18991///
18992///@param o the other instance of @ref ptr_to_mbr_type to compare the
18993///current instance to.
18994///
18995/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18996bool
18997ptr_to_mbr_type::operator==(const decl_base& o) const
18998{
18999 const ptr_to_mbr_type* other =
19000 dynamic_cast<const ptr_to_mbr_type*>(&o);
19001 if (!other)
19002 return false;
19003 return try_canonical_compare(this, other);
19004}
19005
19006/// Equality operator for the current @ref ptr_to_mbr_type.
19007///
19008///@param o the other instance of @ref ptr_to_mbr_type to compare the
19009///current instance to.
19010///
19011/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
19012bool
19013ptr_to_mbr_type::operator==(const type_base& o) const
19014{
19015 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19016 if (!other)
19017 return false;
19018 return *this == *other;
19019}
19020
19021/// Equality operator for the current @ref ptr_to_mbr_type.
19022///
19023///@param o the other instance of @ref ptr_to_mbr_type to compare the
19024///current instance to.
19025///
19026/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
19027bool
19028ptr_to_mbr_type::operator==(const ptr_to_mbr_type& o) const
19029{
19030 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19031 if (!other)
19032 return false;
19033 return *this == *other;
19034}
19035
19036/// Get the qualified name for the current @ref ptr_to_mbr_type.
19037///
19038/// @param qualified_name out parameter. This is set to the name of
19039/// the current @ref ptr_to_mbr_type.
19040///
19041/// @param internal if this is true, then the qualified name is for
19042/// the purpose of type canoicalization.
19043void
19045 bool internal) const
19046{qualified_name = get_qualified_name(internal);}
19047
19048/// Get the qualified name for the current @ref ptr_to_mbr_type.
19049///
19050/// @param internal if this is true, then the qualified name is for
19051/// the purpose of type canoicalization.
19052///
19053/// @return the qualified name for the current @ref ptr_to_mbr_type.
19054const interned_string&
19056{
19057 type_base_sptr member_type = get_member_type();
19058 type_base_sptr containing_type = get_containing_type();
19059
19060 if (internal)
19061 {
19062 if (get_canonical_type())
19063 {
19064 if (priv_->internal_qualified_name_.empty())
19065 priv_->internal_qualified_name_ =
19066 ptr_to_mbr_declaration_name(this, "",
19067 /*qualified=*/true,
19068 internal);
19069 return priv_->internal_qualified_name_;
19070 }
19071 else
19072 {
19073 priv_->temp_internal_qualified_name_ =
19074 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
19075 return priv_->temp_internal_qualified_name_;
19076 }
19077 }
19078 else
19079 {
19081 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
19082 /*internal=*/false));
19084 }
19085}
19086
19087/// This implements the ir_traversable_base::traverse pure virtual
19088/// function for @ref ptr_to_mbr_type.
19089///
19090/// @param v the visitor used on the current instance.
19091///
19092/// @return true if the entire IR node tree got traversed, false
19093/// otherwise.
19094bool
19096{
19097 if (v.type_node_has_been_visited(this))
19098 return true;
19099
19100 if (visiting())
19101 return true;
19102
19103 if (v.visit_begin(this))
19104 {
19105 visiting(true);
19106 if (type_base_sptr t = get_member_type())
19107 t->traverse(v);
19108
19109 if (type_base_sptr t = get_containing_type())
19110 t->traverse(v);
19111 visiting(false);
19112 }
19113
19114 bool result = v.visit_end(this);
19116 return result;
19117}
19118
19119/// Desctructor for @ref ptr_to_mbr_type.
19122
19123
19124/// Compares two instances of @ref ptr_to_mbr_type.
19125///
19126/// If the two intances are different, set a bitfield to give some
19127/// insight about the kind of differences there are.
19128///
19129/// @param l the first artifact of the comparison.
19130///
19131/// @param r the second artifact of the comparison.
19132///
19133/// @param k a pointer to a bitfield that gives information about the
19134/// kind of changes there are between @p l and @p r. This one is set
19135/// iff @p k is non-null and the function returns false.
19136///
19137/// Please note that setting k to a non-null value does have a
19138/// negative performance impact because even if @p l and @p r are not
19139/// equal, the function keeps up the comparison in order to determine
19140/// the different kinds of ways in which they are different.
19141///
19142/// @return true if @p l equals @p r, false otherwise.
19143bool
19145{
19146 bool result = true;
19147
19148 if (!(l.decl_base::operator==(r)))
19149 {
19150 result = false;
19151 if (k)
19153 else
19154 result = false;
19155 }
19156
19157 if (l.get_member_type() != r.get_member_type())
19158 {
19159 if (k)
19160 {
19161 if (!types_have_similar_structure(&l, &r))
19163 *k |= SUBTYPE_CHANGE_KIND;
19164 }
19165 result = false;
19166 }
19167
19169 {
19170 if (k)
19171 {
19172 if (!types_have_similar_structure(&l, &r))
19174 *k |= SUBTYPE_CHANGE_KIND;
19175 }
19176 result = false;
19177 }
19178
19179 ABG_RETURN(result);
19180}
19181
19182// </ptr_to_mbr_type definitions>
19183
19184// <array_type_def definitions>
19185
19186// <array_type_def::subrange_type>
19187array_type_def::subrange_type::~subrange_type() = default;
19188
19189// <array_type_def::subrante_type::bound_value>
19190
19191/// Default constructor of the @ref
19192/// array_type_def::subrange_type::bound_value class.
19193///
19194/// Constructs an unsigned bound_value of value zero.
19196 : s_(UNSIGNED_SIGNEDNESS)
19197{
19198 v_.unsigned_ = 0;
19199}
19200
19201/// Initialize an unsigned bound_value with a given value.
19202///
19203/// @param v the initial bound value.
19205 : s_(UNSIGNED_SIGNEDNESS)
19206{
19207 v_.unsigned_ = v;
19208}
19209
19210/// Initialize a signed bound_value with a given value.
19211///
19212/// @param v the initial bound value.
19214 : s_(SIGNED_SIGNEDNESS)
19215{
19216 v_.signed_ = v;
19217}
19218
19219/// Getter of the signedness (unsigned VS signed) of the bound value.
19220///
19221/// @return the signedness of the bound value.
19222enum array_type_def::subrange_type::bound_value::signedness
19225
19226/// Setter of the signedness (unsigned VS signed) of the bound value.
19227///
19228/// @param s the new signedness of the bound value.
19229void
19232
19233/// Getter of the bound value as a signed value.
19234///
19235/// @return the bound value as signed.
19236int64_t
19240
19241/// Getter of the bound value as an unsigned value.
19242///
19243/// @return the bound value as unsigned.
19244uint64_t
19247
19248/// Setter of the bound value as unsigned.
19249///
19250/// @param v the new unsigned value.
19251void
19253{
19254 s_ = UNSIGNED_SIGNEDNESS;
19255 v_.unsigned_ = v;
19256}
19257
19258/// Setter of the bound value as signed.
19259///
19260/// @param v the new signed value.
19261void
19263{
19264 s_ = SIGNED_SIGNEDNESS;
19265 v_.signed_ = v;
19266}
19267
19268/// Equality operator of the bound value.
19269///
19270/// @param v the other bound value to compare with.
19271///
19272/// @return true iff the current bound value equals @p v.
19273bool
19275{
19276 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
19277}
19278
19279// </array_type_def::subrante_type::bound_value>
19280
19281struct array_type_def::subrange_type::priv
19282{
19283 bound_value lower_bound_;
19284 bound_value upper_bound_;
19285 type_base_wptr underlying_type_;
19287 bool infinite_;
19288
19289 priv(bound_value ub,
19290 translation_unit::language l = translation_unit::LANG_C11)
19291 : upper_bound_(ub), language_(l), infinite_(false)
19292 {}
19293
19294 priv(bound_value lb, bound_value ub,
19295 translation_unit::language l = translation_unit::LANG_C11)
19296 : lower_bound_(lb), upper_bound_(ub),
19297 language_(l), infinite_(false)
19298 {}
19299
19300 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
19301 translation_unit::language l = translation_unit::LANG_C11)
19302 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
19303 language_(l), infinite_(false)
19304 {}
19305};
19306
19307/// Constructor of an array_type_def::subrange_type type.
19308///
19309/// @param env the environment this type was created from.
19310///
19311/// @param name the name of the subrange type.
19312///
19313/// @param lower_bound the lower bound of the array. This is
19314/// generally zero (at least for C and C++).
19315///
19316/// @param upper_bound the upper bound of the array.
19317///
19318/// @param underlying_type the underlying type of the subrange type.
19319///
19320/// @param loc the source location where the type is defined.
19321array_type_def::subrange_type::subrange_type(const environment& env,
19322 const string& name,
19323 bound_value lower_bound,
19324 bound_value upper_bound,
19325 const type_base_sptr& utype,
19326 const location& loc,
19328 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19329 type_base(env,
19330 utype
19331 ? utype->get_size_in_bits()
19332 : 0,
19333 0),
19334 decl_base(env, name, loc, ""),
19335 priv_(new priv(lower_bound, upper_bound, utype, l))
19336{
19338}
19339
19340/// Constructor of the array_type_def::subrange_type type.
19341///
19342/// @param env the environment this type is being created in.
19343///
19344/// @param name the name of the subrange type.
19345///
19346/// @param lower_bound the lower bound of the array. This is
19347/// generally zero (at least for C and C++).
19348///
19349/// @param upper_bound the upper bound of the array.
19350///
19351/// @param loc the source location where the type is defined.
19352///
19353/// @param l the language that generated this subrange.
19354array_type_def::subrange_type::subrange_type(const environment& env,
19355 const string& name,
19356 bound_value lower_bound,
19357 bound_value upper_bound,
19358 const location& loc,
19360 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19361 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
19362 decl_base(env, name, loc, ""),
19363 priv_(new priv(lower_bound, upper_bound, l))
19364{
19366}
19367
19368/// Constructor of the array_type_def::subrange_type type.
19369///
19370/// @param env the environment this type is being created from.
19371///
19372/// @param name of the name of type.
19373///
19374/// @param upper_bound the upper bound of the array. The lower bound
19375/// is considered to be zero.
19376///
19377/// @param loc the source location of the type.
19378///
19379/// @param the language that generated this type.
19380array_type_def::subrange_type::subrange_type(const environment& env,
19381 const string& name,
19382 bound_value upper_bound,
19383 const location& loc,
19385 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19386 type_base(env, upper_bound.get_unsigned_value(), 0),
19387 decl_base(env, name, loc, ""),
19388 priv_(new priv(upper_bound, l))
19389{
19391}
19392
19393/// Return the hash value of the current IR node.
19394///
19395/// Note that upon the first invocation, this member functions
19396/// computes the hash value and returns it. Subsequent invocations
19397/// just return the hash value that was previously calculated.
19398///
19399/// @return the hash value of the current IR node.
19400hash_t
19402{
19404 return h;
19405}
19406
19407/// Getter of the underlying type of the subrange, that is, the type
19408/// that defines the range.
19409///
19410/// @return the underlying type.
19411type_base_sptr
19413{return priv_->underlying_type_.lock();}
19414
19415/// Setter of the underlying type of the subrange, that is, the type
19416/// that defines the range.
19417///
19418/// @param u the new underlying type.
19419void
19421{
19422 ABG_ASSERT(priv_->underlying_type_.expired());
19423 priv_->underlying_type_ = u;
19424 if (u)
19425 set_size_in_bits(u->get_size_in_bits());
19426}
19427
19428/// Getter of the upper bound of the subrange type.
19429///
19430/// @return the upper bound of the subrange type.
19431int64_t
19433{return priv_->upper_bound_.get_signed_value();}
19434
19435/// Getter of the lower bound of the subrange type.
19436///
19437/// @return the lower bound of the subrange type.
19438int64_t
19440{return priv_->lower_bound_.get_signed_value();}
19441
19442/// Setter of the upper bound of the subrange type.
19443///
19444/// @param ub the new value of the upper bound.
19445void
19447{priv_->upper_bound_ = ub;}
19448
19449/// Setter of the lower bound.
19450///
19451/// @param lb the new value of the lower bound.
19452void
19454{priv_->lower_bound_ = lb;}
19455
19456/// Getter of the length of the subrange type.
19457///
19458/// Note that a length of zero means the array has an infinite (or
19459/// rather a non-known) size.
19460///
19461/// @return the length of the subrange type.
19462uint64_t
19464{
19465 if (is_non_finite())
19466 return 0;
19467
19468 // A subrange can have an upper bound that is lower than its lower
19469 // bound. This is possible in Ada for instance. In that case, the
19470 // length of the subrange is considered to be zero.
19472 return get_upper_bound() - get_lower_bound() + 1;
19473 return 0;
19474}
19475
19476/// Test if the length of the subrange type is infinite.
19477///
19478/// @return true iff the length of the subrange type is infinite.
19479bool
19481{return priv_->infinite_;}
19482
19483/// Set the infinite-ness status of the subrange type.
19484///
19485/// @param f true iff the length of the subrange type should be set to
19486/// being infinite.
19487void
19489{priv_->infinite_ = f;}
19490
19491/// Getter of the language that generated this type.
19492///
19493/// @return the language of this type.
19496{return priv_->language_;}
19497
19498/// Return a string representation of the sub range.
19499///
19500/// @return the string representation of the sub range.
19501string
19503{
19504 std::ostringstream o;
19505
19507 {
19508 type_base_sptr underlying_type = get_underlying_type();
19509 if (underlying_type)
19510 o << ir::get_pretty_representation(underlying_type, false) << " ";
19511 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
19512 }
19513 else if (is_non_finite())
19514 o << "[]";
19515 else
19516 o << "[" << get_length() << "]";
19517
19518 return o.str();
19519}
19520
19521/// Return a string representation of a vector of subranges
19522///
19523/// @return the string representation of a vector of sub ranges.
19524string
19526{
19527 if (v.empty())
19528 return "[]";
19529
19530 string r;
19531 for (vector<subrange_sptr>::const_iterator i = v.begin();
19532 i != v.end();
19533 ++i)
19534 r += (*i)->as_string();
19535
19536 return r;
19537}
19538
19539/// Compares two isntances of @ref array_type_def::subrange_type.
19540///
19541/// If the two intances are different, set a bitfield to give some
19542/// insight about the kind of differences there are.
19543///
19544/// @param l the first artifact of the comparison.
19545///
19546/// @param r the second artifact of the comparison.
19547///
19548/// @param k a pointer to a bitfield that gives information about the
19549/// kind of changes there are between @p l and @p r. This one is set
19550/// iff @p k is non-null and the function returns false.
19551///
19552/// Please note that setting k to a non-null value does have a
19553/// negative performance impact because even if @p l and @p r are not
19554/// equal, the function keeps up the comparison in order to determine
19555/// the different kinds of ways in which they are different.
19556///
19557/// @return true if @p l equals @p r, false otherwise.
19558bool
19561 change_kind* k)
19562{
19563 bool result = true;
19564
19565 if (l.get_lower_bound() != r.get_lower_bound()
19566 || l.get_upper_bound() != r.get_upper_bound()
19567 || l.get_name() != r.get_name())
19568 {
19569 result = false;
19570 if (k)
19572 else
19573 ABG_RETURN(result);
19574 }
19575
19576 if (l.get_underlying_type()
19577 && r.get_underlying_type()
19578 && (*l.get_underlying_type() != *r.get_underlying_type()))
19579 {
19580 result = false;
19581 if (k)
19582 *k |= SUBTYPE_CHANGE_KIND;
19583 else
19584 ABG_RETURN(result);
19585 }
19586
19587 ABG_RETURN(result);
19588}
19589
19590/// Equality operator.
19591///
19592/// @param o the other subrange to test against.
19593///
19594/// @return true iff @p o equals the current instance of
19595/// array_type_def::subrange_type.
19596bool
19598{
19599 const subrange_type* other =
19600 dynamic_cast<const subrange_type*>(&o);
19601 if (!other)
19602 return false;
19603 return try_canonical_compare(this, other);
19604}
19605
19606/// Equality operator.
19607///
19608/// @param o the other subrange to test against.
19609///
19610/// @return true iff @p o equals the current instance of
19611/// array_type_def::subrange_type.
19612bool
19614{
19615 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19616 if (!other)
19617 return false;
19618 return *this == *other;
19619}
19620
19621/// Equality operator.
19622///
19623/// @param o the other subrange to test against.
19624///
19625/// @return true iff @p o equals the current instance of
19626/// array_type_def::subrange_type.
19627bool
19629{
19630 const type_base &t = o;
19631 return operator==(t);
19632}
19633
19634/// Equality operator.
19635///
19636/// @param o the other subrange to test against.
19637///
19638/// @return true iff @p o equals the current instance of
19639/// array_type_def::subrange_type.
19640bool
19642{return !operator==(o);}
19643
19644/// Equality operator.
19645///
19646/// @param o the other subrange to test against.
19647///
19648/// @return true iff @p o equals the current instance of
19649/// array_type_def::subrange_type.
19650bool
19652{return !operator==(o);}
19653
19654/// Inequality operator.
19655///
19656/// @param o the other subrange to test against.
19657///
19658/// @return true iff @p o is different from the current instance of
19659/// array_type_def::subrange_type.
19660bool
19662{return !operator==(o);}
19663
19664/// Build a pretty representation for an
19665/// array_type_def::subrange_type.
19666///
19667/// @param internal set to true if the call is intended to get a
19668/// representation of the decl (or type) for the purpose of canonical
19669/// type comparison. This is mainly used in the function
19670/// type_base::get_canonical_type_for().
19671///
19672/// In other words if the argument for this parameter is true then the
19673/// call is meant for internal use (for technical use inside the
19674/// library itself), false otherwise. If you don't know what this is
19675/// for, then set it to false.
19676///
19677/// @return a copy of the pretty representation of the current
19678/// instance of typedef_decl.
19679string
19681{
19682 string name = get_name();
19683 string repr;
19684
19685 if (name.empty())
19686 repr += "<anonymous range>";
19687 else
19688 repr += "<range " + get_name() + ">";
19689 repr += as_string();
19690
19691 return repr;
19692}
19693
19694/// This implements the ir_traversable_base::traverse pure virtual
19695/// function.
19696///
19697/// @param v the visitor used on the current instance.
19698///
19699/// @return true if the entire IR node tree got traversed, false
19700/// otherwise.
19701bool
19703{
19704 if (v.type_node_has_been_visited(this))
19705 return true;
19706
19707 if (v.visit_begin(this))
19708 {
19709 visiting(true);
19710 if (type_base_sptr u = get_underlying_type())
19711 u->traverse(v);
19712 visiting(false);
19713 }
19714
19715 bool result = v.visit_end(this);
19717 return result;
19718}
19719
19720// </array_type_def::subrange_type>
19721
19722struct array_type_def::priv
19723{
19724 type_base_wptr element_type_;
19725 subranges_type subranges_;
19726 interned_string temp_internal_qualified_name_;
19727 interned_string internal_qualified_name_;
19728
19729 priv(type_base_sptr t)
19730 : element_type_(t)
19731 {}
19732
19733 priv(type_base_sptr t, subranges_type subs)
19734 : element_type_(t), subranges_(subs)
19735 {}
19736
19737 priv()
19738 {}
19739};
19740
19741/// Constructor for the type array_type_def
19742///
19743/// Note how the constructor expects a vector of subrange
19744/// objects. Parsing of the array information always entails
19745/// parsing the subrange info as well, thus the class subrange_type
19746/// is defined inside class array_type_def and also parsed
19747/// simultaneously.
19748///
19749/// @param e_type the type of the elements contained in the array
19750///
19751/// @param subs a vector of the array's subranges(dimensions)
19752///
19753/// @param locus the source location of the array type definition.
19754array_type_def::array_type_def(const type_base_sptr e_type,
19755 const std::vector<subrange_sptr>& subs,
19756 const location& locus)
19758 ARRAY_TYPE
19759 | ABSTRACT_TYPE_BASE
19760 | ABSTRACT_DECL_BASE),
19761 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19762 decl_base(e_type->get_environment(), locus),
19763 priv_(new priv(e_type))
19764{
19766 append_subranges(subs);
19767}
19768
19769/// Constructor for the type array_type_def
19770///
19771/// This constructor builds a temporary array that has no element type
19772/// associated. Later when the element type is available, it be set
19773/// with the array_type_def::set_element_type() member function.
19774///
19775/// Note how the constructor expects a vector of subrange
19776/// objects. Parsing of the array information always entails
19777/// parsing the subrange info as well, thus the class subrange_type
19778/// is defined inside class array_type_def and also parsed
19779/// simultaneously.
19780///
19781/// @param env the environment of the array type.
19782///
19783/// @param subs a vector of the array's subranges(dimensions)
19784///
19785/// @param locus the source location of the array type definition.
19786array_type_def::array_type_def(const environment& env,
19787 const std::vector<subrange_sptr>& subs,
19788 const location& locus)
19789 : type_or_decl_base(env,
19790 ARRAY_TYPE
19791 | ABSTRACT_TYPE_BASE
19792 | ABSTRACT_DECL_BASE),
19793 type_base(env, 0, 0),
19794 decl_base(env, locus),
19795 priv_(new priv)
19796{
19798 append_subranges(subs);
19799}
19800
19801/// Return the hash value of the current IR node.
19802///
19803/// Note that upon the first invocation, this member functions
19804/// computes the hash value and returns it. Subsequent invocations
19805/// just return the hash value that was previously calculated.
19806///
19807/// @return the hash value of the current IR node.
19808hash_t
19810{
19812 return h;
19813}
19814
19815/// Update the size of the array.
19816///
19817/// This function computes the size of the array and sets it using
19818/// type_base::set_size_in_bits().
19819void
19820array_type_def::update_size()
19821{
19822 type_base_sptr e = priv_->element_type_.lock();
19823 if (e)
19824 {
19825 size_t s = e->get_size_in_bits();
19826 if (s)
19827 {
19828 for (const auto &sub : get_subranges())
19829 s *= sub->get_length();
19831 }
19832 set_alignment_in_bits(e->get_alignment_in_bits());
19833 }
19834}
19835
19836string
19837array_type_def::get_subrange_representation() const
19838{
19840 return r;
19841}
19842
19843/// Get the pretty representation of the current instance of @ref
19844/// array_type_def.
19845///
19846/// @param internal set to true if the call is intended to get a
19847/// representation of the decl (or type) for the purpose of canonical
19848/// type comparison. This is mainly used in the function
19849/// type_base::get_canonical_type_for().
19850///
19851/// In other words if the argument for this parameter is true then the
19852/// call is meant for internal use (for technical use inside the
19853/// library itself), false otherwise. If you don't know what this is
19854/// for, then set it to false.
19855/// @param internal set to true if the call is intended for an
19856/// internal use (for technical use inside the library itself), false
19857/// otherwise. If you don't know what this is for, then set it to
19858/// false.
19859///
19860/// @return the pretty representation of the ABI artifact.
19861string
19863 bool qualified_name) const
19864{
19865 return array_declaration_name(this, /*variable_name=*/"",
19866 qualified_name, internal);
19867}
19868
19869/// Compares two instances of @ref array_type_def.
19870///
19871/// If the two intances are different, set a bitfield to give some
19872/// insight about the kind of differences there are.
19873///
19874/// @param l the first artifact of the comparison.
19875///
19876/// @param r the second artifact of the comparison.
19877///
19878/// @param k a pointer to a bitfield that gives information about the
19879/// kind of changes there are between @p l and @p r. This one is set
19880/// iff @p k is non-null and the function returns false.
19881///
19882/// Please note that setting k to a non-null value does have a
19883/// negative performance impact because even if @p l and @p r are not
19884/// equal, the function keeps up the comparison in order to determine
19885/// the different kinds of ways in which they are different.
19886///
19887/// @return true if @p l equals @p r, false otherwise.
19888bool
19890{
19891 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19892 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19893
19894 bool result = true;
19895 if (this_subs.size() != other_subs.size())
19896 {
19897 result = false;
19898 if (k)
19900 else
19902 }
19903
19904 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19905 for (i = this_subs.begin(), j = other_subs.begin();
19906 i != this_subs.end() && j != other_subs.end();
19907 ++i, ++j)
19908 if (**i != **j)
19909 {
19910 result = false;
19911 if (k)
19912 {
19914 break;
19915 }
19916 else
19918 }
19919
19920 // Compare the element types modulo the typedefs they might have
19921 if (l.get_element_type() != r.get_element_type())
19922 {
19923 result = false;
19924 if (k)
19925 *k |= SUBTYPE_CHANGE_KIND;
19926 else
19928 }
19929
19930 ABG_RETURN(result);
19931}
19932
19933/// Test if two array types are equals modulo CV qualifiers.
19934///
19935/// @param l the first array of the comparison.
19936///
19937/// @param r the second array of the comparison.
19938///
19939/// @return true iff @p l equals @p r or, if they are different, the
19940/// difference between the too is just a matter of CV qualifiers.
19941bool
19943{
19944 if (l == r)
19945 return true;
19946
19947 if (!l || !r)
19949
19952
19953 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19954 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19955
19956 if (this_subs.size() != other_subs.size())
19958
19959 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19960 for (i = this_subs.begin(), j = other_subs.begin();
19961 i != this_subs.end() && j != other_subs.end();
19962 ++i, ++j)
19963 if (**i != **j)
19965
19966 type_base *first_element_type =
19968 type_base *second_element_type =
19970
19971 if (*first_element_type != *second_element_type)
19973
19974 return true;
19975}
19976
19977/// Test if two array types are equals modulo CV qualifiers.
19978///
19979/// @param l the first array of the comparison.
19980///
19981/// @param r the second array of the comparison.
19982///
19983/// @return true iff @p l equals @p r or, if they are different, the
19984/// difference between the too is just a matter of CV qualifiers.
19985bool
19987 const array_type_def_sptr& r)
19988{return equals_modulo_cv_qualifier(l.get(), r.get());}
19989
19990/// Test if two pointer types are equals modulo CV qualifiers.
19991///
19992/// @param l the first pointer of the comparison.
19993///
19994/// @param r the second pointer of the comparison.
19995///
19996/// @return true iff @p l equals @p r or, if they are different, the
19997/// difference between the too is just a matter of CV qualifiers.
19998bool
20000{
20001 if (l == r)
20002 return true;
20003
20004 if (!l || !r)
20006
20007 type_base_sptr l_ptt = l->get_pointed_to_type(),
20008 r_ptt = r->get_pointed_to_type();
20009
20010 do
20011 {
20012 l_ptt = peel_qualified_or_typedef_type(l_ptt);
20013 r_ptt = peel_qualified_or_typedef_type(r_ptt);
20014
20015 l_ptt = is_pointer_type(l_ptt)
20017 : l_ptt;
20018
20019 r_ptt = is_pointer_type(r_ptt)
20021 : r_ptt;
20022 } while (is_pointer_type(l_ptt) && is_pointer_type(r_ptt));
20023
20024 l_ptt = peel_qualified_or_typedef_type(l_ptt);
20025 r_ptt = peel_qualified_or_typedef_type(r_ptt);
20026
20027 return *l_ptt == *r_ptt;
20028}
20029
20030/// Test if two pointer types are equals modulo CV qualifiers.
20031///
20032/// @param l the first pointer of the comparison.
20033///
20034/// @param r the second pointer of the comparison.
20035///
20036/// @return true iff @p l equals @p r or, if they are different, the
20037/// difference between the too is just a matter of CV qualifiers.
20038bool
20042
20043/// Get the language of the array.
20044///
20045/// @return the language of the array.
20048{
20049 const std::vector<subrange_sptr>& subranges =
20050 get_subranges();
20051
20052 if (subranges.empty())
20053 return translation_unit::LANG_C11;
20054 return subranges.front()->get_language();
20055}
20056
20057bool
20058array_type_def::operator==(const decl_base& o) const
20059{
20060 const array_type_def* other =
20061 dynamic_cast<const array_type_def*>(&o);
20062 if (!other)
20063 return false;
20064 return try_canonical_compare(this, other);
20065}
20066
20067bool
20068array_type_def::operator==(const type_base& o) const
20069{
20070 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20071 if (!other)
20072 return false;
20073 return *this == *other;
20074}
20075
20076/// Getter of the type of an array element.
20077///
20078/// @return the type of an array element.
20079const type_base_sptr
20081{return priv_->element_type_.lock();}
20082
20083/// Setter of the type of array element.
20084///
20085/// Beware that after using this function, one might want to
20086/// re-compute the canonical type of the array, if one has already
20087/// been computed.
20088///
20089/// The intended use of this method is to permit in-place adjustment
20090/// of the element type's qualifiers. In particular, the size of the
20091/// element type should not be changed.
20092///
20093/// @param element_type the new element type to set.
20094void
20095array_type_def::set_element_type(const type_base_sptr& element_type)
20096{
20097 priv_->element_type_ = element_type;
20098 update_size();
20100}
20101
20102/// Append subranges from the vector @param subs to the current
20103/// vector of subranges.
20104void
20105array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
20106{
20107
20108 for (const auto &sub : subs)
20109 priv_->subranges_.push_back(sub);
20110
20111 update_size();
20113}
20114
20115/// @return true if one of the sub-ranges of the array is infinite, or
20116/// if the array has no sub-range at all, also meaning that the size
20117/// of the array is infinite.
20118bool
20120{
20121 if (priv_->subranges_.empty())
20122 return true;
20123
20124 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
20125 priv_->subranges_.begin();
20126 i != priv_->subranges_.end();
20127 ++i)
20128 if ((*i)->is_non_finite())
20129 return true;
20130
20131 return false;
20132}
20133
20134int
20135array_type_def::get_dimension_count() const
20136{return priv_->subranges_.size();}
20137
20138/// Build and return the qualified name of the current instance of the
20139/// @ref array_type_def.
20140///
20141/// @param qn output parameter. Is set to the newly-built qualified
20142/// name of the current instance of @ref array_type_def.
20143///
20144/// @param internal set to true if the call is intended for an
20145/// internal use (for technical use inside the library itself), false
20146/// otherwise. If you don't know what this is for, then set it to
20147/// false.
20148void
20150{qn = get_qualified_name(internal);}
20151
20152/// Compute the qualified name of the array.
20153///
20154/// @param internal set to true if the call is intended for an
20155/// internal use (for technical use inside the library itself), false
20156/// otherwise. If you don't know what this is for, then set it to
20157/// false.
20158///
20159/// @return the resulting qualified name.
20160const interned_string&
20162{
20163 if (internal)
20164 {
20165 if (get_canonical_type())
20166 {
20167 if (priv_->internal_qualified_name_.empty())
20168 priv_->internal_qualified_name_ =
20169 array_declaration_name(this, /*variable_name=*/"",
20170 /*qualified=*/false,
20171 /*internal=*/true);
20172 return priv_->internal_qualified_name_;
20173 }
20174 else
20175 {
20176 priv_->temp_internal_qualified_name_ =
20177 array_declaration_name(this, /*variable_name=*/"",
20178 /*qualified*/false, /*internal*/true);
20179 return priv_->temp_internal_qualified_name_;
20180 }
20181 }
20182 else
20183 {
20184 if (get_canonical_type())
20185 {
20186 if (decl_base::peek_qualified_name().empty())
20187 set_qualified_name(array_declaration_name(this,
20188 /*variable_name=*/"",
20189 /*qualified=*/false,
20190 /*internal=*/false));
20192 }
20193 else
20194 {
20196 (array_declaration_name(this, /*variable_name=*/"",
20197 /*qualified=*/false,
20198 /*internal=*/false));
20200 }
20201 }
20202}
20203
20204/// This implements the ir_traversable_base::traverse pure virtual
20205/// function.
20206///
20207/// @param v the visitor used on the current instance.
20208///
20209/// @return true if the entire IR node tree got traversed, false
20210/// otherwise.
20211bool
20213{
20214 if (v.type_node_has_been_visited(this))
20215 return true;
20216
20217 if (visiting())
20218 return true;
20219
20220 if (v.visit_begin(this))
20221 {
20222 visiting(true);
20223 if (type_base_sptr t = get_element_type())
20224 t->traverse(v);
20225 visiting(false);
20226 }
20227
20228 bool result = v.visit_end(this);
20230 return result;
20231}
20232
20233const location&
20235{return decl_base::get_location();}
20236
20237/// Get the array's subranges
20238const std::vector<array_type_def::subrange_sptr>&
20240{return priv_->subranges_;}
20241
20242array_type_def::~array_type_def()
20243{}
20244
20245// </array_type_def definitions>
20246
20247// <enum_type_decl definitions>
20248
20249class enum_type_decl::priv
20250{
20251 type_base_sptr underlying_type_;
20252 enumerators enumerators_;
20253 mutable enumerators sorted_enumerators_;
20254
20255 friend class enum_type_decl;
20256
20257 priv();
20258
20259public:
20260 priv(type_base_sptr underlying_type,
20262 : underlying_type_(underlying_type),
20263 enumerators_(enumerators)
20264 {}
20265}; // end class enum_type_decl::priv
20266
20267/// Constructor.
20268///
20269/// @param name the name of the type declaration.
20270///
20271/// @param locus the source location where the type was defined.
20272///
20273/// @param underlying_type the underlying type of the enum.
20274///
20275/// @param enums the enumerators of this enum type.
20276///
20277/// @param linkage_name the linkage name of the enum.
20278///
20279/// @param vis the visibility of the enum type.
20280enum_type_decl::enum_type_decl(const string& name,
20281 const location& locus,
20282 type_base_sptr underlying_type,
20283 enumerators& enums,
20284 const string& linkage_name,
20285 visibility vis)
20286 : type_or_decl_base(underlying_type->get_environment(),
20287 ENUM_TYPE
20288 | ABSTRACT_TYPE_BASE
20289 | ABSTRACT_DECL_BASE),
20290 type_base(underlying_type->get_environment(),
20291 underlying_type->get_size_in_bits(),
20292 underlying_type->get_alignment_in_bits()),
20293 decl_base(underlying_type->get_environment(),
20294 name, locus, linkage_name, vis),
20295 priv_(new priv(underlying_type, enums))
20296{
20298 for (enumerators::iterator e = get_enumerators().begin();
20299 e != get_enumerators().end();
20300 ++e)
20301 e->set_enum_type(this);
20302}
20303
20304/// Return the hash value of the current IR node.
20305///
20306/// Note that upon the first invocation, this member functions
20307/// computes the hash value and returns it. Subsequent invocations
20308/// just return the hash value that was previously calculated.
20309///
20310/// @return the hash value of the current IR node.
20311hash_t
20313{
20315 return h;
20316}
20317
20318/// Return the underlying type of the enum.
20319type_base_sptr
20321{return priv_->underlying_type_;}
20322
20323/// @return the list of enumerators of the enum.
20326{return priv_->enumerators_;}
20327
20328/// @return the list of enumerators of the enum.
20331{return priv_->enumerators_;}
20332
20333/// Get the lexicographically sorted vector of enumerators.
20334///
20335/// @return the lexicographically sorted vector of enumerators.
20338{
20339 if (priv_->sorted_enumerators_.empty())
20340 {
20341 for (auto e = get_enumerators().rbegin();
20342 e != get_enumerators().rend();
20343 ++e)
20344 priv_->sorted_enumerators_.push_back(*e);
20345
20346 std::sort(priv_->sorted_enumerators_.begin(),
20347 priv_->sorted_enumerators_.end(),
20348 [](const enum_type_decl::enumerator& l,
20350 {
20351 if (l.get_name() == r.get_name())
20352 return l.get_value() < r.get_value();
20353 return (l.get_name() < r.get_name());
20354 });
20355 }
20356
20357 return priv_->sorted_enumerators_;
20358}
20359
20360/// Find an enumerator by its value.
20361///
20362/// @param value the enumerator value to look for.
20363///
20364/// @param result output parameter. This is set to the enumerator
20365/// which value is @p value, if found. This is set iff the function
20366/// returns true.
20367///
20368/// @return true iff an enumerator with value @p value was found and
20369/// returned by argument via @p result.
20370bool
20372 enum_type_decl:: enumerator& result)
20373{
20374 for (auto& e : get_enumerators())
20375 if (e.get_value() == value)
20376 {
20377 result = e;
20378 return true;
20379 }
20380
20381 return false;
20382}
20383
20384/// Find an enumerator by its name
20385///
20386/// @param name the enumerator name to look for.
20387///
20388/// @param result output parameter. This is set to the enumerator
20389/// which name is @p name, if found. This is set iff the function
20390/// returns true.
20391///
20392/// @return true iff an enumerator with name @p name was found and
20393/// returned by argument via @p result.
20394bool
20397{
20398 for (auto& e : get_enumerators())
20399 if (e.get_name() == name)
20400 {
20401 result = e;
20402 return true;
20403 }
20404
20405 return false;
20406}
20407
20408/// Get the pretty representation of the current instance of @ref
20409/// enum_type_decl.
20410///
20411/// @param internal set to true if the call is intended to get a
20412/// representation of the decl (or type) for the purpose of canonical
20413/// type comparison. This is mainly used in the function
20414/// type_base::get_canonical_type_for().
20415///
20416/// In other words if the argument for this parameter is true then the
20417/// call is meant for internal use (for technical use inside the
20418/// library itself), false otherwise. If you don't know what this is
20419/// for, then set it to false.
20420///
20421/// @param qualified_name if true, names emitted in the pretty
20422/// representation are fully qualified.
20423///
20424/// @return the pretty representation of the enum type.
20425string
20427 bool qualified_name) const
20428{
20429 string r = "enum ";
20430
20431 if (internal && get_is_anonymous())
20432 r += get_type_name(this, qualified_name, /*internal=*/true);
20433 else if (get_is_anonymous())
20434 r += get_enum_flat_representation(*this, "",
20435 /*one_line=*/true,
20436 qualified_name);
20437 else
20439 qualified_name);
20440 return r;
20441}
20442
20443/// This implements the ir_traversable_base::traverse pure virtual
20444/// function.
20445///
20446/// @param v the visitor used on the current instance.
20447///
20448/// @return true if the entire IR node tree got traversed, false
20449/// otherwise.
20450bool
20452{
20453 if (v.type_node_has_been_visited(this))
20454 return true;
20455
20456 if (visiting())
20457 return true;
20458
20459 if (v.visit_begin(this))
20460 {
20461 visiting(true);
20462 if (type_base_sptr t = get_underlying_type())
20463 t->traverse(v);
20464 visiting(false);
20465 }
20466
20467 bool result = v.visit_end(this);
20469 return result;
20470}
20471
20472/// Destructor for the enum type declaration.
20475
20476/// Test if a given enumerator is found present in an enum.
20477///
20478/// This is a subroutine of the equals function for enums.
20479///
20480/// @param enr the enumerator to consider.
20481///
20482/// @param enom the enum to consider.
20483///
20484/// @return true iff the enumerator @p enr is present in the enum @p
20485/// enom.
20486bool
20488 const enum_type_decl &enom)
20489{
20490 for (const auto &e : enom.get_enumerators())
20491 if (e == enr)
20492 return true;
20493 return false;
20494}
20495
20496/// Check if two enumerators values are equal.
20497///
20498/// This function doesn't check if the names of the enumerators are
20499/// equal or not.
20500///
20501/// @param enr the first enumerator to consider.
20502///
20503/// @param enl the second enumerator to consider.
20504///
20505/// @return true iff @p enr has the same value as @p enl.
20506static bool
20507enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
20508 const enum_type_decl::enumerator &enl)
20509{return enr.get_value() == enl.get_value();}
20510
20511/// Detect if a given enumerator value is present in an enum.
20512///
20513/// This function looks inside the enumerators of a given enum and
20514/// detect if the enum contains at least one enumerator or a given
20515/// value. The function also detects if the enumerator value we are
20516/// looking at is present in the enum with a different name. An
20517/// enumerator with the same value but with a different name is named
20518/// a "redundant enumerator". The function returns the set of
20519/// enumerators that are redundant with the value we are looking at.
20520///
20521/// @param enr the enumerator to consider.
20522///
20523/// @param enom the enum to consider.
20524///
20525/// @param redundant_enrs if the function returns true, then this
20526/// vector is filled with enumerators that are redundant with the
20527/// value of @p enr.
20528///
20529/// @return true iff the function detects that @p enom contains
20530/// enumerators with the same value as @p enr.
20531static bool
20532is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
20533 const enum_type_decl &enom,
20534 vector<enum_type_decl::enumerator>& redundant_enrs)
20535{
20536 bool found = false;
20537 for (const auto &e : enom.get_enumerators())
20538 if (enumerators_values_are_equal(e, enr))
20539 {
20540 found = true;
20541 if (e != enr)
20542 redundant_enrs.push_back(e);
20543 }
20544
20545 return found;
20546}
20547
20548/// Check if an enumerator value is redundant in a given enum.
20549///
20550/// Given an enumerator value, this function detects if an enum
20551/// contains at least one enumerator with the the same value but with
20552/// a different name.
20553///
20554/// @param enr the enumerator to consider.
20555///
20556/// @param enom the enum to consider.
20557///
20558/// @return true iff @p enr is a redundant enumerator in enom.
20559static bool
20560is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
20561 const enum_type_decl &enom)
20562{
20564 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
20565 {
20566 if (!redundant_enrs.empty())
20567 return true;
20568 }
20569 return false;
20570}
20571
20572/// Compares two instances of @ref enum_type_decl.
20573///
20574/// If the two intances are different, set a bitfield to give some
20575/// insight about the kind of differences there are.
20576///
20577/// @param l the first artifact of the comparison.
20578///
20579/// @param r the second artifact of the comparison.
20580///
20581/// @param k a pointer to a bitfield that gives information about the
20582/// kind of changes there are between @p l and @p r. This one is set
20583/// iff @p k is non-null and the function returns false.
20584///
20585/// Please note that setting k to a non-null value does have a
20586/// negative performance impact because even if @p l and @p r are not
20587/// equal, the function keeps up the comparison in order to determine
20588/// the different kinds of ways in which they are different.
20589///
20590/// @return true if @p l equals @p r, false otherwise.
20591bool
20593{
20594 bool result = true;
20595
20596 //
20597 // Look through decl-only-enum.
20598 //
20599
20600 const enum_type_decl *def1 =
20603 : &l;
20604
20605 const enum_type_decl *def2 =
20608 : &r;
20609
20610 if (!!def1 != !!def2)
20611 {
20612 // One enum is decl-only while the other is not.
20613 // So the two enums are different.
20614 result = false;
20615 if (k)
20616 *k |= SUBTYPE_CHANGE_KIND;
20617 else
20619 }
20620
20621 //
20622 // At this point, both enums have the same state of decl-only-ness.
20623 // So we can compare oranges to oranges.
20624 //
20625
20626 if (!def1)
20627 def1 = &l;
20628 if (!def2)
20629 def2 = &r;
20630
20631 if (def1->get_underlying_type() != def2->get_underlying_type())
20632 {
20633 result = false;
20634 if (k)
20635 *k |= SUBTYPE_CHANGE_KIND;
20636 else
20638 }
20639
20640 if (!(def1->decl_base::operator==(*def2)
20641 && def1->type_base::operator==(*def2)))
20642 {
20643 result = false;
20644 if (k)
20645 {
20646 if (!def1->decl_base::operator==(*def2))
20648 if (!def1->type_base::operator==(*def2))
20650 }
20651 else
20653 }
20654
20655 // Now compare the enumerators.
20656
20657 // First in a naive (but potentially fast) way in case both enums
20658 // are equal in a naive manner.
20659
20660 if (def1->get_enumerators().size() == def2->get_enumerators().size())
20661 {
20662 bool equals = true;
20663 for (auto e1 = def1->get_enumerators().begin(),
20664 e2 = def2->get_enumerators().begin();
20665 (e1 != def1->get_enumerators().end()
20666 && e2 != def2->get_enumerators().end());
20667 ++e1, ++e2)
20668 {
20669 if (*e1 != *e2)
20670 {
20671 equals = false;
20672 break;
20673 }
20674 }
20675 if (equals)
20676 ABG_RETURN(result);
20677 }
20678
20679 // If the two enums where not naively equals, let's try a more
20680 // clever (and slow) way.
20681
20682 // Note that the order of declaration
20683 // of enumerators should not matter in the comparison.
20684 //
20685 // Also if an enumerator value is redundant, that shouldn't impact
20686 // the comparison.
20687 //
20688 // In that case, note that the two enums below are considered equal:
20689 //
20690 // enum foo
20691 // {
20692 // e0 = 0;
20693 // e1 = 1;
20694 // e2 = 2;
20695 // };
20696 //
20697 // enum foo
20698 // {
20699 // e0 = 0;
20700 // e1 = 1;
20701 // e2 = 2;
20702 // e_added = 1; // <-- this value is redundant with the value
20703 // // of the enumerator e1.
20704 // };
20705 //
20706 // Note however that in the case below, the enums are different.
20707 //
20708 // enum foo
20709 // {
20710 // e0 = 0;
20711 // e1 = 1;
20712 // };
20713 //
20714 // enum foo
20715 // {
20716 // e0 = 0;
20717 // e2 = 1; // <-- this enum value is present in the first version
20718 // // of foo, but is not redundant with any enumerator
20719 // // in the second version of of enum foo.
20720 // };
20721 //
20722 // These two enums are considered equal.
20723
20724 for(const auto &e : def1->get_enumerators())
20725 if (!is_enumerator_present_in_enum(e, *def2)
20726 && (!is_enumerator_value_redundant(e, *def2)
20727 || !is_enumerator_value_redundant(e, *def1)))
20728 {
20729 result = false;
20730 if (k)
20731 {
20733 break;
20734 }
20735 else
20737 }
20738
20739 for(const auto &e : def2->get_enumerators())
20740 if (!is_enumerator_present_in_enum(e, *def1)
20741 && (!is_enumerator_value_redundant(e, *def1)
20742 || !is_enumerator_value_redundant(e, *def2)))
20743 {
20744 result = false;
20745 if (k)
20746 {
20748 break;
20749 }
20750 else
20752 }
20753
20754 ABG_RETURN(result);
20755}
20756
20757/// Equality operator.
20758///
20759/// @param o the other enum to test against.
20760///
20761/// @return true iff @p o equals the current instance of enum type
20762/// decl.
20763bool
20764enum_type_decl::operator==(const decl_base& o) const
20765{
20766 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
20767 if (!op)
20768 return false;
20769 return try_canonical_compare(this, op);
20770}
20771
20772/// Equality operator.
20773///
20774/// @param o the other enum to test against.
20775///
20776/// @return true iff @p o is equals the current instance of enum type
20777/// decl.
20778bool
20779enum_type_decl::operator==(const type_base& o) const
20780{
20781 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20782 if (!other)
20783 return false;
20784 return *this == *other;
20785}
20786
20787/// Equality operator for @ref enum_type_decl_sptr.
20788///
20789/// @param l the first operand to compare.
20790///
20791/// @param r the second operand to compare.
20792///
20793/// @return true iff @p l equals @p r.
20794bool
20796{
20797 if (!!l != !!r)
20798 return false;
20799 if (l.get() == r.get())
20800 return true;
20801 decl_base_sptr o = r;
20802 return *l == *o;
20803}
20804
20805/// Inequality operator for @ref enum_type_decl_sptr.
20806///
20807/// @param l the first operand to compare.
20808///
20809/// @param r the second operand to compare.
20810///
20811/// @return true iff @p l equals @p r.
20812bool
20814{return !operator==(l, r);}
20815
20816/// The type of the private data of an @ref
20817/// enum_type_decl::enumerator.
20818class enum_type_decl::enumerator::priv
20819{
20820 string name_;
20821 int64_t value_;
20822 string qualified_name_;
20823 enum_type_decl* enum_type_;
20824
20825 friend class enum_type_decl::enumerator;
20826
20827public:
20828
20829 priv()
20830 : enum_type_()
20831 {}
20832
20833 priv(const string& name,
20834 int64_t value,
20835 enum_type_decl* e = 0)
20836 : name_(name),
20837 value_(value),
20838 enum_type_(e)
20839 {}
20840}; // end class enum_type_def::enumerator::priv
20841
20842/// Default constructor of the @ref enum_type_decl::enumerator type.
20844 : priv_(new priv)
20845{}
20846
20847enum_type_decl::enumerator::~enumerator() = default;
20848
20849/// Constructor of the @ref enum_type_decl::enumerator type.
20850///
20851/// @param env the environment we are operating from.
20852///
20853/// @param name the name of the enumerator.
20854///
20855/// @param value the value of the enumerator.
20857 int64_t value)
20858 : priv_(new priv(name, value))
20859{}
20860
20861/// Copy constructor of the @ref enum_type_decl::enumerator type.
20862///
20863/// @param other enumerator to copy.
20865 : priv_(new priv(other.get_name(),
20866 other.get_value(),
20867 other.get_enum_type()))
20868{}
20869
20870/// Assignment operator of the @ref enum_type_decl::enumerator type.
20871///
20872/// @param o
20875{
20876 priv_->name_ = o.get_name();
20877 priv_->value_ = o.get_value();
20878 priv_->enum_type_ = o.get_enum_type();
20879 return *this;
20880}
20881
20882/// Equality operator
20883///
20884/// @param other the enumerator to compare to the current
20885/// instance of enum_type_decl::enumerator.
20886///
20887/// @return true if @p other equals the current instance of
20888/// enum_type_decl::enumerator.
20889bool
20891{
20892 bool names_equal = true;
20893 names_equal = (get_name() == other.get_name());
20894 return names_equal && (get_value() == other.get_value());
20895}
20896
20897/// Inequality operator.
20898///
20899/// @param other the other instance to compare against.
20900///
20901/// @return true iff @p other is different from the current instance.
20902bool
20904{return !operator==(other);}
20905
20906/// Getter for the name of the current instance of
20907/// enum_type_decl::enumerator.
20908///
20909/// @return a reference to the name of the current instance of
20910/// enum_type_decl::enumerator.
20911const string&
20913{return priv_->name_;}
20914
20915/// Getter for the qualified name of the current instance of
20916/// enum_type_decl::enumerator. The first invocation of the method
20917/// builds the qualified name, caches it and return a reference to the
20918/// cached qualified name. Subsequent invocations just return the
20919/// cached value.
20920///
20921/// @param internal set to true if the call is intended for an
20922/// internal use (for technical use inside the library itself), false
20923/// otherwise. If you don't know what this is for, then set it to
20924/// false.
20925///
20926/// @return the qualified name of the current instance of
20927/// enum_type_decl::enumerator.
20928const string&
20930{
20931 if (priv_->qualified_name_.empty())
20932 {
20933 priv_->qualified_name_ =
20934 get_enum_type()->get_qualified_name(internal)
20935 + "::"
20936 + get_name();
20937 }
20938 return priv_->qualified_name_;
20939}
20940
20941/// Setter for the name of @ref enum_type_decl::enumerator.
20942///
20943/// @param n the new name.
20944void
20946{priv_->name_ = n;}
20947
20948/// Getter for the value of @ref enum_type_decl::enumerator.
20949///
20950/// @return the value of the current instance of
20951/// enum_type_decl::enumerator.
20952int64_t
20954{return priv_->value_;}
20955
20956/// Setter for the value of @ref enum_type_decl::enumerator.
20957///
20958/// @param v the new value of the enum_type_decl::enumerator.
20959void
20961{priv_->value_= v;}
20962
20963/// Getter for the enum type that this enumerator is for.
20964///
20965/// @return the enum type that this enumerator is for.
20966enum_type_decl*
20968{return priv_->enum_type_;}
20969
20970/// Setter for the enum type that this enumerator is for.
20971///
20972/// @param e the new enum type.
20973void
20975{priv_->enum_type_ = e;}
20976// </enum_type_decl definitions>
20977
20978// <typedef_decl definitions>
20979
20980/// Private data structure of the @ref typedef_decl.
20981struct typedef_decl::priv
20982{
20983 type_base_wptr underlying_type_;
20984
20985 priv(const type_base_sptr& t)
20986 : underlying_type_(t)
20987 {}
20988}; // end struct typedef_decl::priv
20989
20990/// Constructor of the typedef_decl type.
20991///
20992/// @param name the name of the typedef.
20993///
20994/// @param underlying_type the underlying type of the typedef.
20995///
20996/// @param locus the source location of the typedef declaration.
20997///
20998/// @param linkage_name the mangled name of the typedef.
20999///
21000/// @param vis the visibility of the typedef type.
21001typedef_decl::typedef_decl(const string& name,
21002 const type_base_sptr underlying_type,
21003 const location& locus,
21004 const string& linkage_name,
21005 visibility vis)
21006 : type_or_decl_base(underlying_type->get_environment(),
21007 TYPEDEF_TYPE
21008 | ABSTRACT_TYPE_BASE
21009 | ABSTRACT_DECL_BASE),
21010 type_base(underlying_type->get_environment(),
21011 underlying_type->get_size_in_bits(),
21012 underlying_type->get_alignment_in_bits()),
21013 decl_base(underlying_type->get_environment(),
21014 name, locus, linkage_name, vis),
21015 priv_(new priv(underlying_type))
21016{
21018}
21019
21020/// Constructor of the typedef_decl type.
21021///
21022/// @param name the name of the typedef.
21023///
21024/// @param env the environment of the current typedef.
21025///
21026/// @param locus the source location of the typedef declaration.
21027///
21028/// @param mangled_name the mangled name of the typedef.
21029///
21030/// @param vis the visibility of the typedef type.
21031typedef_decl::typedef_decl(const string& name,
21032 const environment& env,
21033 const location& locus,
21034 const string& mangled_name,
21035 visibility vis)
21036 : type_or_decl_base(env,
21037 TYPEDEF_TYPE
21038 | ABSTRACT_TYPE_BASE
21039 | ABSTRACT_DECL_BASE),
21040 type_base(env, /*size_in_bits=*/0,
21041 /*alignment_in_bits=*/0),
21042 decl_base(env, name, locus, mangled_name, vis),
21043 priv_(new priv(nullptr))
21044{
21046}
21047
21048/// Return the hash value of the current IR node.
21049///
21050/// Note that upon the first invocation, this member functions
21051/// computes the hash value and returns it. Subsequent invocations
21052/// just return the hash value that was previously calculated.
21053///
21054/// @return the hash value of the current IR node.
21055hash_t
21057{
21059 return h;
21060}
21061
21062/// Return the size of the typedef.
21063///
21064/// This function looks at the size of the underlying type and ensures
21065/// that it's the same as the size of the typedef.
21066///
21067/// @return the size of the typedef.
21068size_t
21070{
21071 if (!get_underlying_type())
21072 return 0;
21073 size_t s = get_underlying_type()->get_size_in_bits();
21074 if (s != type_base::get_size_in_bits())
21075 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
21077}
21078
21079/// Return the alignment of the typedef.
21080///
21081/// This function looks at the alignment of the underlying type and
21082/// ensures that it's the same as the alignment of the typedef.
21083///
21084/// @return the size of the typedef.
21085size_t
21087{
21088 if (!get_underlying_type())
21089 return 0;
21090 size_t s = get_underlying_type()->get_alignment_in_bits();
21092 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
21094}
21095
21096/// Compares two instances of @ref typedef_decl.
21097///
21098/// If the two intances are different, set a bitfield to give some
21099/// insight about the kind of differences there are.
21100///
21101/// @param l the first artifact of the comparison.
21102///
21103/// @param r the second artifact of the comparison.
21104///
21105/// @param k a pointer to a bitfield that gives information about the
21106/// kind of changes there are between @p l and @p r. This one is set
21107/// iff @p k is non-null and the function returns false.
21108///
21109/// Please note that setting k to a non-null value does have a
21110/// negative performance impact because even if @p l and @p r are not
21111/// equal, the function keeps up the comparison in order to determine
21112/// the different kinds of ways in which they are different.
21113///
21114/// @return true if @p l equals @p r, false otherwise.
21115bool
21117{
21118 bool result = true;
21119
21120 // No need to go further if the types have different names or
21121 // different size / alignment.
21122 if (!(l.decl_base::operator==(r)))
21123 {
21124 result = false;
21125 if (k)
21127 else
21129 }
21130
21132 {
21133 // Changes to the underlying type of a typedef are considered
21134 // local, a bit like for pointers.
21135 result = false;
21136 if (k)
21138 else
21140 }
21141
21142 ABG_RETURN(result);
21143}
21144
21145/// Equality operator
21146///
21147/// @param o the other typedef_decl to test against.
21148bool
21149typedef_decl::operator==(const decl_base& o) const
21150{
21151 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
21152 if (!other)
21153 return false;
21154 return try_canonical_compare(this, other);
21155}
21156
21157/// Equality operator
21158///
21159/// @param o the other typedef_decl to test against.
21160///
21161/// @return true if the current instance of @ref typedef_decl equals
21162/// @p o.
21163bool
21164typedef_decl::operator==(const type_base& o) const
21165{
21166 const decl_base* other = dynamic_cast<const decl_base*>(&o);
21167 if (!other)
21168 return false;
21169 return *this == *other;
21170}
21171
21172/// Build a pretty representation for a typedef_decl.
21173///
21174/// @param internal set to true if the call is intended to get a
21175/// representation of the decl (or type) for the purpose of canonical
21176/// type comparison. This is mainly used in the function
21177/// type_base::get_canonical_type_for().
21178///
21179/// In other words if the argument for this parameter is true then the
21180/// call is meant for internal use (for technical use inside the
21181/// library itself), false otherwise. If you don't know what this is
21182/// for, then set it to false.
21183
21184/// @param qualified_name if true, names emitted in the pretty
21185/// representation are fully qualified.
21186///
21187/// @return a copy of the pretty representation of the current
21188/// instance of typedef_decl.
21189string
21191 bool qualified_name) const
21192{
21193
21194 string result = "typedef ";
21195 if (qualified_name)
21196 result += get_qualified_name(internal);
21197 else
21198 result += get_name();
21199
21200 return result;
21201}
21202
21203/// Getter of the underlying type of the typedef.
21204///
21205/// @return the underlying_type.
21206type_base_sptr
21208{return priv_->underlying_type_.lock();}
21209
21210/// Setter ofthe underlying type of the typedef.
21211///
21212/// @param t the new underlying type of the typedef.
21213void
21215{
21216 priv_->underlying_type_ = t;
21217 set_size_in_bits(t->get_size_in_bits());
21218 set_alignment_in_bits(t->get_alignment_in_bits());
21219}
21220
21221/// Implementation of the virtual "get_qualified_name" method.
21222///
21223/// @param qualified_name the resuling qualified name of the typedef type.
21224///
21225/// @param internal if true, then it means the qualified name is for
21226/// "internal" purposes, meaning mainly for type canonicalization
21227/// purposes.
21228void
21230 bool internal) const
21231{qualified_name = get_qualified_name(internal);}
21232
21233/// Implementation of the virtual "get_qualified_name" method.
21234///
21235/// @param internal if true, then it means the qualified name is for
21236/// "internal" purposes, meaning mainly for type canonicalization
21237/// purposes.
21238///
21239/// @return the qualified name.
21240const interned_string&
21242{
21243 // Note that the qualified name has been already set by
21244 // qualified_name_setter::do_update, which is invoked by
21245 // update_qualified_name. The latter is itself invoked whenever the
21246 // typedef is added to its scope, in scope_decl::add_member_decl.
21247 if (internal)
21248 return decl_base::priv_->internal_qualified_name_;
21249 else
21250 return decl_base::priv_->qualified_name_;
21251}
21252
21253/// This implements the ir_traversable_base::traverse pure virtual
21254/// function.
21255///
21256/// @param v the visitor used on the current instance.
21257///
21258/// @return true if the entire IR node tree got traversed, false
21259/// otherwise.
21260bool
21262{
21263 if (v.type_node_has_been_visited(this))
21264 return true;
21265
21266 if (visiting())
21267 return true;
21268
21269 if (v.visit_begin(this))
21270 {
21271 visiting(true);
21272 if (type_base_sptr t = get_underlying_type())
21273 t->traverse(v);
21274 visiting(false);
21275 }
21276
21277 bool result = v.visit_end(this);
21279 return result;
21280}
21281
21282typedef_decl::~typedef_decl()
21283{}
21284// </typedef_decl definitions>
21285
21286// <var_decl definitions>
21287
21288struct var_decl::priv
21289{
21290 type_base_wptr type_;
21291 type_base* naked_type_;
21292 decl_base::binding binding_;
21293 elf_symbol_sptr symbol_;
21294 interned_string id_;
21295
21296 priv()
21297 : naked_type_(),
21298 binding_(decl_base::BINDING_GLOBAL)
21299 {}
21300
21301 priv(type_base_sptr t,
21303 : type_(t),
21304 naked_type_(t.get()),
21305 binding_(b)
21306 {}
21307
21308 /// Setter of the type of the variable.
21309 ///
21310 /// @param t the new variable type.
21311 void
21312 set_type(type_base_sptr t)
21313 {
21314 type_ = t;
21315 naked_type_ = t.get();
21316 }
21317}; // end struct var_decl::priv
21318
21319/// Constructor of the @ref var_decl type.
21320///
21321/// @param name the name of the variable declaration
21322///
21323/// @param type the type of the variable declaration
21324///
21325/// @param locus the source location where the variable was defined.
21326///
21327/// @param linkage_name the linkage name of the variable.
21328///
21329/// @param vis the visibility of of the variable.
21330///
21331/// @param bind the binding kind of the variable.
21332var_decl::var_decl(const string& name,
21333 type_base_sptr type,
21334 const location& locus,
21335 const string& linkage_name,
21336 visibility vis,
21337 binding bind)
21339 VAR_DECL | ABSTRACT_DECL_BASE),
21340 decl_base(type->get_environment(), name, locus, linkage_name, vis),
21341 priv_(new priv(type, bind))
21342{
21344}
21345
21346/// Getter of the type of the variable.
21347///
21348/// @return the type of the variable.
21349const type_base_sptr
21351{return priv_->type_.lock();}
21352
21353/// Setter of the type of the variable.
21354///
21355/// @param the new type of the variable.
21356void
21357var_decl::set_type(type_base_sptr& t)
21358{priv_->set_type(t);}
21359
21360/// Getter of the type of the variable.
21361///
21362/// This getter returns a bare pointer, as opposed to a smart pointer.
21363/// It's to be used on performance sensitive code paths identified by
21364/// careful profiling.
21365///
21366/// @return the type of the variable, as a bare pointer.
21367const type_base*
21369{return priv_->naked_type_;}
21370
21371/// Getter of the binding of the variable.
21372///
21373/// @return the biding of the variable.
21376{return priv_->binding_;}
21377
21378/// Setter of the binding of the variable.
21379///
21380/// @param b the new binding value.
21381void
21383{priv_->binding_ = b;}
21384
21385/// Sets the underlying ELF symbol for the current variable.
21386///
21387/// And underlyin$g ELF symbol for the current variable might exist
21388/// only if the corpus that this variable originates from was
21389/// constructed from an ELF binary file.
21390///
21391/// Note that comparing two variables that have underlying ELF symbols
21392/// involves comparing their underlying elf symbols. The decl name
21393/// for the variable thus becomes irrelevant in the comparison.
21394///
21395/// @param sym the new ELF symbol for this variable decl.
21396void
21398{
21399 priv_->symbol_ = sym;
21400 // The variable id cache that depends on the symbol must be
21401 // invalidated because the symbol changed.
21402 priv_->id_ = get_environment().intern("");
21403}
21404
21405/// Gets the the underlying ELF symbol for the current variable,
21406/// that was set using var_decl::set_symbol(). Please read the
21407/// documentation for that member function for more information about
21408/// "underlying ELF symbols".
21409///
21410/// @return sym the underlying ELF symbol for this variable decl, if
21411/// one exists.
21412const elf_symbol_sptr&
21414{return priv_->symbol_;}
21415
21416/// Create a new var_decl that is a clone of the current one.
21417///
21418/// @return the cloned var_decl.
21421{
21422 var_decl_sptr v(new var_decl(get_name(),
21423 get_type(),
21424 get_location(),
21427 get_binding()));
21428
21429 v->set_symbol(get_symbol());
21430
21431 if (is_member_decl(*this))
21432 {
21433 class_or_union* scope = is_class_or_union_type(get_scope());
21436 get_member_is_static(*this),
21437 get_data_member_offset(*this));
21438 }
21439 else
21441
21442 return v;
21443}
21444/// Setter of the scope of the current var_decl.
21445///
21446/// Note that the decl won't hold a reference on the scope. It's
21447/// rather the scope that holds a reference on its members.
21448///
21449/// @param scope the new scope.
21450void
21451var_decl::set_scope(scope_decl* scope)
21452{
21453 if (!get_context_rel())
21454 set_context_rel(new dm_context_rel(scope));
21455 else
21456 get_context_rel()->set_scope(scope);
21457}
21458
21459/// Compares two instances of @ref var_decl without taking their type
21460/// into account.
21461///
21462/// If the two intances are different modulo their type, set a
21463/// bitfield to give some insight about the kind of differences there
21464/// are.
21465///
21466/// @param l the first artifact of the comparison.
21467///
21468/// @param r the second artifact of the comparison.
21469///
21470/// @param k a pointer to a bitfield that gives information about the
21471/// kind of changes there are between @p l and @p r. This one is set
21472/// iff @p k is non-null and the function returns false.
21473///
21474/// Please note that setting k to a non-null value does have a
21475/// negative performance impact because even if @p l and @p r are not
21476/// equal, the function keeps up the comparison in order to determine
21477/// the different kinds of ways in which they are different.
21478///
21479/// @return true if @p l equals @p r, false otherwise.
21480bool
21482{
21483 bool result = true;
21484
21485 // If there are underlying elf symbols for these variables,
21486 // compare them. And then compare the other parts.
21487 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21488 if (!!s0 != !!s1)
21489 {
21490 result = false;
21491 if (k)
21493 else
21495 }
21496 else if (s0 && !textually_equals(*s0, *s1, k))
21497 {
21498 result = false;
21499 if (!k)
21501 }
21502 bool symbols_are_equal = (s0 && s1 && result);
21503
21504 if (symbols_are_equal)
21505 {
21506 // The variables have underlying elf symbols that are equal, so
21507 // now, let's compare the decl_base part of the variables w/o
21508 // considering their decl names.
21509 const environment& env = l.get_environment();
21510 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
21511 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
21512 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
21513 bool decl_bases_different = !l.decl_base::operator==(r);
21514 const_cast<var_decl&>(l).set_qualified_name(n1);
21515 const_cast<var_decl&>(r).set_qualified_name(n2);
21516
21517 if (decl_bases_different)
21518 {
21519 result = false;
21520 if (k)
21522 else
21524 }
21525 }
21526 else
21527 if (!l.decl_base::operator==(r))
21528 {
21529 result = false;
21530 if (k)
21532 else
21534 }
21535
21536 const dm_context_rel* c0 =
21537 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
21538 const dm_context_rel* c1 =
21539 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
21540 ABG_ASSERT(c0 && c1);
21541
21542 if (*c0 != *c1)
21543 {
21544 result = false;
21545 if (k)
21547 else
21549 }
21550
21551 ABG_RETURN(result);
21552}
21553
21554/// Compares two instances of @ref var_decl.
21555///
21556/// If the two intances are different, set a bitfield to give some
21557/// insight about the kind of differences there are.
21558///
21559/// @param l the first artifact of the comparison.
21560///
21561/// @param r the second artifact of the comparison.
21562///
21563/// @param k a pointer to a bitfield that gives information about the
21564/// kind of changes there are between @p l and @p r. This one is set
21565/// iff @p k is non-null and the function returns false.
21566///
21567/// Please note that setting k to a non-null value does have a
21568/// negative performance impact because even if @p l and @p r are not
21569/// equal, the function keeps up the comparison in order to determine
21570/// the different kinds of ways in which they are different.
21571///
21572/// @return true if @p l equals @p r, false otherwise.
21573bool
21574equals(const var_decl& l, const var_decl& r, change_kind* k)
21575{
21576 bool result = true;
21577
21578 // First test types of variables. This should be fast because in
21579 // the general case, most types should be canonicalized.
21580 if (*l.get_naked_type() != *r.get_naked_type())
21581 {
21582 result = false;
21583 if (k)
21584 {
21586 r.get_naked_type()))
21587 *k |= (LOCAL_TYPE_CHANGE_KIND);
21588 else
21589 *k |= SUBTYPE_CHANGE_KIND;
21590 }
21591 else
21593 }
21594
21595 result &= var_equals_modulo_types(l, r, k);
21596
21597 ABG_RETURN(result);
21598}
21599
21600/// Comparison operator of @ref var_decl.
21601///
21602/// @param o the instance of @ref var_decl to compare against.
21603///
21604/// @return true iff the current instance of @ref var_decl equals @p o.
21605bool
21606var_decl::operator==(const decl_base& o) const
21607{
21608 const var_decl* other = dynamic_cast<const var_decl*>(&o);
21609 if (!other)
21610 return false;
21611
21612 return equals(*this, *other, 0);
21613}
21614
21615/// Return an ID that tries to uniquely identify the variable inside a
21616/// program or a library.
21617///
21618/// So if the variable has an underlying elf symbol, the ID is the
21619/// concatenation of the symbol name and its version. Otherwise, the
21620/// ID is the linkage name if its non-null. Otherwise, it's the
21621/// pretty representation of the variable.
21622///
21623/// @return the ID.
21626{
21627 if (priv_->id_.empty())
21628 {
21629 string repr = get_name();
21630 string sym_str;
21631 if (elf_symbol_sptr s = get_symbol())
21632 sym_str = s->get_id_string();
21633 else if (!get_linkage_name().empty())
21634 sym_str = get_linkage_name();
21635
21636 const environment& env = get_type()->get_environment();
21637 priv_->id_ = env.intern(repr);
21638 if (!sym_str.empty())
21639 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
21640 }
21641 return priv_->id_;
21642}
21643
21644/// Get the qualified name of a given variable or data member.
21645///
21646///
21647/// Note that if the current instance of @ref var_decl is an anonymous
21648/// data member, then the qualified name is actually the flat
21649/// representation (the definition) of the type of the anonymous data
21650/// member. We chose the flat representation because otherwise, the
21651/// name of an *anonymous* data member is empty, by construction, e.g:
21652///
21653/// struct foo {
21654/// int a;
21655/// union {
21656/// char b;
21657/// char c;
21658/// }; // <---- this data member is anonymous.
21659/// int d;
21660/// }
21661///
21662/// The string returned for the anonymous member here is going to be:
21663///
21664/// "union {char b; char c}"
21665///
21666/// @param internal if true then this is for a purpose to the library,
21667/// otherwise, it's for being displayed to users.
21668///
21669/// @return the resulting qualified name.
21670const interned_string&
21672{
21673 if (is_anonymous_data_member(this)
21674 && decl_base::get_qualified_name().empty())
21675 {
21676 // Display the anonymous data member in a way that makes sense.
21677 string r = get_pretty_representation(internal);
21679 }
21680
21681 return decl_base::get_qualified_name(internal);
21682}
21683
21684/// Build and return the pretty representation of this variable.
21685///
21686/// @param internal set to true if the call is intended to get a
21687/// representation of the decl (or type) for the purpose of canonical
21688/// type comparison. This is mainly used in the function
21689/// type_base::get_canonical_type_for().
21690///
21691/// In other words if the argument for this parameter is true then the
21692/// call is meant for internal use (for technical use inside the
21693/// library itself), false otherwise. If you don't know what this is
21694/// for, then set it to false.
21695///
21696/// @param qualified_name if true, names emitted in the pretty
21697/// representation are fully qualified.
21698///
21699/// @return a copy of the pretty representation of this variable.
21700string
21701var_decl::get_pretty_representation(bool internal, bool qualified_name) const
21702{
21703 string result;
21704
21705 if (is_member_decl(this) && get_member_is_static(this))
21706 result = "static ";
21707
21708 // Detect if the current instance of var_decl is a member of
21709 // an anonymous class or union.
21710 bool member_of_anonymous_class = false;
21711 if (class_or_union* scope = is_at_class_scope(this))
21712 if (scope->get_is_anonymous())
21713 member_of_anonymous_class = true;
21714
21715 type_base_sptr type = get_type();
21716 if (is_array_type(type, /*look_through_qualifiers=*/true)
21717 || is_pointer_type(type, /*look_through_qualifiers=*/true)
21718 || is_reference_type(type, /*look_through_qualifiers=*/true)
21719 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
21720 {
21721 string name;
21722 if (member_of_anonymous_class || !qualified_name)
21723 name = get_name();
21724 else
21725 name = get_qualified_name(internal);
21726
21727 if (qualified_type_def_sptr q = is_qualified_type(type))
21728 {
21729 string quals_repr =
21730 get_string_representation_of_cv_quals(q->get_cv_quals());
21731 if (!quals_repr.empty())
21732 name = quals_repr + " " + name;
21733 type = peel_qualified_type(type);
21734 }
21735
21736 name = string(" ") + name;
21737 if (array_type_def_sptr t = is_array_type(type))
21738 result += array_declaration_name(t, name, qualified_name, internal);
21739 else if (pointer_type_def_sptr t = is_pointer_type(type))
21740 result += pointer_declaration_name(t, name, qualified_name, internal);
21741 else if (reference_type_def_sptr t = is_reference_type(type))
21742 result += pointer_declaration_name(t, name, qualified_name, internal);
21743 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
21744 result += ptr_to_mbr_declaration_name(t, name,
21745 qualified_name,
21746 internal);
21747 }
21748 else
21749 {
21750 if (/*The current var_decl is to be used as an anonymous data
21751 member. */
21752 get_name().empty())
21753 {
21754 // Display the anonymous data member in a way that
21755 // makes sense.
21756 result +=
21759 "", /*one_line=*/true, internal);
21760 }
21761 else if (data_member_has_anonymous_type(this))
21762 {
21765 "", /*one_line=*/true, internal);
21766 result += " ";
21767 if (!internal
21768 && (member_of_anonymous_class || !qualified_name))
21769 // It doesn't make sense to name the member of an
21770 // anonymous class or union like:
21771 // "__anonymous__::data_member_name". So let's just use
21772 // its non-qualified name.
21773 result += get_name();
21774 else
21775 result += get_qualified_name(internal);
21776 }
21777 else
21778 {
21779 result +=
21781 + " ";
21782
21783 if (!internal
21784 && (member_of_anonymous_class || !qualified_name))
21785 // It doesn't make sense to name the member of an
21786 // anonymous class or union like:
21787 // "__anonymous__::data_member_name". So let's just use
21788 // its non-qualified name.
21789 result += get_name();
21790 else
21791 result += get_qualified_name(internal);
21792 }
21793 }
21794 return result;
21795}
21796
21797/// Get a name that is valid even for an anonymous data member.
21798///
21799/// If the current @ref var_decl is an anonymous data member, then
21800/// return its pretty representation. As of now, that pretty
21801/// representation is actually its flat representation as returned by
21802/// get_class_or_union_flat_representation().
21803///
21804/// Otherwise, just return the name of the current @ref var_decl.
21805///
21806/// @param qualified if true, return the qualified name. This doesn't
21807/// have an effet if the current @ref var_decl represents an anonymous
21808/// data member.
21809string
21811{
21812 string name;
21813 if (is_anonymous_data_member(this))
21814 // This function is used in the comparison engine to determine
21815 // which anonymous data member was deleted. So it's not involved
21816 // in type comparison or canonicalization. We don't want to use
21817 // the 'internal' version of the pretty presentation.
21818 name = get_pretty_representation(/*internal=*/false, qualified);
21819 else
21820 name = get_name();
21821
21822 return name;
21823}
21824
21825/// This implements the ir_traversable_base::traverse pure virtual
21826/// function.
21827///
21828/// @param v the visitor used on the current instance.
21829///
21830/// @return true if the entire IR node tree got traversed, false
21831/// otherwise.
21832bool
21834{
21835 if (visiting())
21836 return true;
21837
21838 if (v.visit_begin(this))
21839 {
21840 visiting(true);
21841 if (type_base_sptr t = get_type())
21842 t->traverse(v);
21843 visiting(false);
21844 }
21845 return v.visit_end(this);
21846}
21847
21848var_decl::~var_decl()
21849{}
21850
21851// </var_decl definitions>
21852
21853/// This function is automatically invoked whenever an instance of
21854/// this type is canonicalized.
21855///
21856/// It's an overload of the virtual type_base::on_canonical_type_set.
21857///
21858/// We put here what is thus meant to be executed only at the point of
21859/// type canonicalization.
21860void
21862{
21863 priv_->cached_name_.clear();
21864 priv_->internal_cached_name_.clear();
21865}
21866
21867/// The most straightforward constructor for the function_type class.
21868///
21869/// @param return_type the return type of the function type.
21870///
21871/// @param parms the list of parameters of the function type.
21872/// Stricto sensu, we just need a list of types; we are using a list
21873/// of parameters (where each parameter also carries the name of the
21874/// parameter and its source location) to try and provide better
21875/// diagnostics whenever it makes sense. If it appears that this
21876/// wasts too many resources, we can fall back to taking just a
21877/// vector of types here.
21878///
21879/// @param size_in_bits the size of this type, in bits.
21880///
21881/// @param alignment_in_bits the alignment of this type, in bits.
21882///
21883/// @param size_in_bits the size of this type.
21884function_type::function_type(type_base_sptr return_type,
21885 const parameters& parms,
21886 size_t size_in_bits,
21887 size_t alignment_in_bits)
21888 : type_or_decl_base(return_type->get_environment(),
21889 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21890 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21891 priv_(new priv(parms, return_type))
21892{
21894
21895 for (parameters::size_type i = 0, j = 1;
21896 i < priv_->parms_.size();
21897 ++i, ++j)
21898 {
21899 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21900 // If the first parameter is artificial, then it certainly
21901 // means that this is a member function, and the first
21902 // parameter is the implicit this pointer. In that case, set
21903 // the index of that implicit parameter to zero. Otherwise,
21904 // the index of the first parameter starts at one.
21905 j = 0;
21906 priv_->parms_[i]->set_index(j);
21907 }
21908}
21909
21910/// A constructor for a function_type that takes no parameters.
21911///
21912/// @param return_type the return type of this function_type.
21913///
21914/// @param size_in_bits the size of this type, in bits.
21915///
21916/// @param alignment_in_bits the alignment of this type, in bits.
21917function_type::function_type(type_base_sptr return_type,
21918 size_t size_in_bits, size_t alignment_in_bits)
21919 : type_or_decl_base(return_type->get_environment(),
21920 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21921 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21922 priv_(new priv(return_type))
21923{
21925}
21926
21927/// A constructor for a function_type that takes no parameter and
21928/// that has no return_type yet. These missing parts can (and must)
21929/// be added later.
21930///
21931/// @param env the environment we are operating from.
21932///
21933/// @param size_in_bits the size of this type, in bits.
21934///
21935/// @param alignment_in_bits the alignment of this type, in bits.
21936function_type::function_type(const environment& env,
21937 size_t size_in_bits,
21938 size_t alignment_in_bits)
21939 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21940 type_base(env, size_in_bits, alignment_in_bits),
21941 priv_(new priv)
21942{
21944}
21945
21946/// Return the hash value of the current IR node.
21947///
21948/// Note that upon the first invocation, this member functions
21949/// computes the hash value and returns it. Subsequent invocations
21950/// just return the hash value that was previously calculated.
21951///
21952/// @return the hash value of the current IR node.
21953hash_t
21955{
21957 return h;
21958}
21959
21960/// Getter for the return type of the current instance of @ref
21961/// function_type.
21962///
21963/// @return the return type.
21964type_base_sptr
21966{return priv_->return_type_.lock();}
21967
21968/// Setter of the return type of the current instance of @ref
21969/// function_type.
21970///
21971/// @param t the new return type to set.
21972void
21974{priv_->return_type_ = t;}
21975
21976/// Getter for the set of parameters of the current intance of @ref
21977/// function_type.
21978///
21979/// @return the parameters of the current instance of @ref
21980/// function_type.
21983{return priv_->parms_;}
21984
21985/// Get the Ith parameter of the vector of parameters of the current
21986/// instance of @ref function_type.
21987///
21988/// Note that the first parameter is at index 0. That parameter is
21989/// the first parameter that comes after the possible implicit "this"
21990/// parameter, when the current instance @ref function_type is for a
21991/// member function. Otherwise, if the current instance of @ref
21992/// function_type is for a non-member function, the parameter at index
21993/// 0 is the first parameter of the function.
21994///
21995///
21996/// @param i the index of the parameter to return. If i is greater
21997/// than the index of the last parameter, then this function returns
21998/// an empty parameter (smart) pointer.
21999///
22000/// @return the @p i th parameter that is not implicit.
22003{
22004 parameter_sptr result;
22005 if (dynamic_cast<const method_type*>(this))
22006 {
22007 if (i + 1 < get_parameters().size())
22008 result = get_parameters()[i + 1];
22009 }
22010 else
22011 {
22012 if (i < get_parameters().size())
22013 result = get_parameters()[i];
22014 }
22015 return result;
22016}
22017
22018/// Setter for the parameters of the current instance of @ref
22019/// function_type.
22020///
22021/// @param p the new vector of parameters to set.
22022void
22024{
22025 priv_->parms_ = p;
22026 for (parameters::size_type i = 0, j = 1;
22027 i < priv_->parms_.size();
22028 ++i, ++j)
22029 {
22030 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22031 // If the first parameter is artificial, then it certainly
22032 // means that this is a member function, and the first
22033 // parameter is the implicit this pointer. In that case, set
22034 // the index of that implicit parameter to zero. Otherwise,
22035 // the index of the first parameter starts at one.
22036 j = 0;
22037 priv_->parms_[i]->set_index(j);
22038 }
22039}
22040
22041/// Append a new parameter to the vector of parameters of the current
22042/// instance of @ref function_type.
22043///
22044/// @param parm the parameter to append.
22045void
22047{
22048 parm->set_index(priv_->parms_.size());
22049 priv_->parms_.push_back(parm);
22050}
22051
22052/// Test if the current instance of @ref function_type is for a
22053/// variadic function.
22054///
22055/// A variadic function is a function that takes a variable number of
22056/// arguments.
22057///
22058/// @return true iff the current instance of @ref function_type is for
22059/// a variadic function.
22060bool
22062{
22063 return (!priv_->parms_.empty()
22064 && priv_->parms_.back()->get_variadic_marker());
22065}
22066
22067/// Compare two function types.
22068///
22069/// In case these function types are actually method types, this
22070/// function avoids comparing two parameters (of the function types)
22071/// if the types of the parameters are actually the types of the
22072/// classes of the method types. This prevents infinite recursion
22073/// during the comparison of two classes that are structurally
22074/// identical.
22075///
22076/// This is a subroutine of the equality operator of function_type.
22077///
22078/// @param lhs the first function type to consider
22079///
22080/// @param rhs the second function type to consider
22081///
22082/// @param k a pointer to a bitfield set by the function to give
22083/// information about the kind of changes carried by @p lhs and @p
22084/// rhs. It is set iff @p k is non-null and the function returns
22085/// false.
22086///
22087/// Please note that setting k to a non-null value does have a
22088/// negative performance impact because even if @p l and @p r are not
22089/// equal, the function keeps up the comparison in order to determine
22090/// the different kinds of ways in which they are different.
22091///
22092///@return true if lhs == rhs, false otherwise.
22093bool
22094equals(const function_type& l, const function_type& r, change_kind* k)
22095{
22096#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
22097
22099
22100 {
22101 // First of all, let's see if these two function types haven't
22102 // already been compared. If so, and if the result of the
22103 // comparison has been cached, let's just re-use it, rather than
22104 // comparing them all over again.
22105 bool cached_result = false;
22106 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
22107 cached_result))
22108 ABG_RETURN(cached_result);
22109 }
22110
22112
22113 bool result = true;
22114
22115 if (!l.type_base::operator==(r))
22116 {
22117 result = false;
22118 if (k)
22120 else
22121 RETURN(result);
22122 }
22123
22124 class_or_union* l_class = 0, *r_class = 0;
22125 if (const method_type* m = dynamic_cast<const method_type*>(&l))
22126 l_class = m->get_class_type().get();
22127
22128 if (const method_type* m = dynamic_cast<const method_type*>(&r))
22129 r_class = m->get_class_type().get();
22130
22131 // Compare the names of the class of the method
22132
22133 if (!!l_class != !!r_class)
22134 {
22135 result = false;
22136 if (k)
22138 else
22139 RETURN(result);
22140 }
22141 else if (l_class
22142 && (l_class->get_qualified_name()
22143 != r_class->get_qualified_name()))
22144 {
22145 result = false;
22146 if (k)
22148 else
22149 RETURN(result);
22150 }
22151
22152 // Then compare the return type; Beware if it's t's a class type
22153 // that is the same as the method class name; we can recurse for
22154 // ever in that case.
22155
22156 decl_base* l_return_type_decl =
22158 decl_base* r_return_type_decl =
22160 bool compare_result_types = true;
22161 string l_rt_name = l_return_type_decl
22162 ? l_return_type_decl->get_qualified_name()
22163 : string();
22164 string r_rt_name = r_return_type_decl
22165 ? r_return_type_decl->get_qualified_name()
22166 : string();
22167
22168 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
22169 ||
22170 (r_class && (r_class->get_qualified_name() == r_rt_name)))
22171 compare_result_types = false;
22172
22173 if (compare_result_types)
22174 {
22175 // Let's not consider typedefs when comparing return types to
22176 // avoid spurious changes.
22177 //
22178 // TODO: We should also do this for parameter types, or rather,
22179 // we should teach the equality operators in the IR, at some
22180 // point, to peel typedefs off.
22181 if (l.get_return_type() != r.get_return_type())
22182 {
22183 result = false;
22184 if (k)
22185 {
22187 r.get_return_type()))
22189 else
22190 *k |= SUBTYPE_CHANGE_KIND;
22191 }
22192 else
22193 RETURN(result);
22194 }
22195 }
22196 else
22197 if (l_rt_name != r_rt_name)
22198 {
22199 result = false;
22200 if (k)
22201 *k |= SUBTYPE_CHANGE_KIND;
22202 else
22203 RETURN(result);
22204 }
22205
22206 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
22207 for (i = l.get_first_parm(), j = r.get_first_parm();
22208 i != l.get_parameters().end() && j != r.get_parameters().end();
22209 ++i, ++j)
22210 {
22211 if (**i != **j)
22212 {
22213 result = false;
22214 if (k)
22215 {
22216 if (!types_have_similar_structure((*i)->get_type(),
22217 (*j)->get_type()))
22219 else
22220 *k |= SUBTYPE_CHANGE_KIND;
22221 }
22222 else
22223 RETURN(result);
22224 }
22225 }
22226
22227 if ((i != l.get_parameters().end()
22228 || j != r.get_parameters().end()))
22229 {
22230 result = false;
22231 if (k)
22233 else
22234 RETURN(result);
22235 }
22236
22237 RETURN(result);
22238#undef RETURN
22239}
22240
22241/// Get the first parameter of the function.
22242///
22243/// If the function is a non-static member function, the parameter
22244/// returned is the first one following the implicit 'this' parameter.
22245///
22246/// @return the first non implicit parameter of the function.
22247function_type::parameters::const_iterator
22249{
22250 if (get_parameters().empty())
22251 return get_parameters().end();
22252
22253 bool is_method = dynamic_cast<const method_type*>(this);
22254
22255 parameters::const_iterator i = get_parameters().begin();
22256
22257 if (is_method && (*i)->get_is_artificial())
22258 ++i;
22259
22260 return i;
22261}
22262
22263/// Get the first parameter of the function.
22264///
22265/// Note that if the function is a non-static member function, the
22266/// parameter returned is the implicit 'this' parameter.
22267///
22268/// @return the first parameter of the function.
22269function_type::parameters::const_iterator
22271{return get_parameters().begin();}
22272
22273/// Get the name of the current @ref function_type.
22274///
22275/// The name is retrieved from a cache. If the cache is empty, this
22276/// function computes the name of the type, stores it in the cache and
22277/// returns it. Subsequent invocation of the function are going to
22278/// just hit the cache.
22279///
22280/// Note that if the type is *NOT* canonicalized then function type
22281/// name is never cached.
22282///
22283/// @param internal if true then it means the function type name is
22284/// going to be used for purposes that are internal to libabigail
22285/// itself. If you don't know what this is then you probably should
22286/// set this parameter to 'false'.
22287///
22288/// @return the name of the function type.
22289const interned_string&
22291{
22292 if (internal)
22293 {
22295 {
22296 if (priv_->internal_cached_name_.empty())
22297 priv_->internal_cached_name_ =
22298 get_function_type_name(this, /*internal=*/true);
22299 return priv_->internal_cached_name_;
22300 }
22301 else
22302 {
22303 priv_->temp_internal_cached_name_ =
22304 get_function_type_name(this, /*internal=*/true);
22305 return priv_->temp_internal_cached_name_;
22306 }
22307 }
22308 else
22309 {
22311 {
22312 if (priv_->cached_name_.empty())
22313 priv_->cached_name_ =
22314 get_function_type_name(this, /*internal=*/false);
22315 return priv_->cached_name_;
22316 }
22317 else
22318 {
22319 priv_->cached_name_ =
22320 get_function_type_name(this, /*internal=*/false);
22321 return priv_->cached_name_;
22322 }
22323 }
22324}
22325
22326/// Equality operator for function_type.
22327///
22328/// @param o the other function_type to compare against.
22329///
22330/// @return true iff the two function_type are equal.
22331bool
22332function_type::operator==(const type_base& other) const
22333{
22334 const function_type* o = dynamic_cast<const function_type*>(&other);
22335 if (!o)
22336 return false;
22337 return try_canonical_compare(this, o);
22338}
22339
22340/// Return a copy of the pretty representation of the current @ref
22341/// function_type.
22342///
22343/// @param internal set to true if the call is intended to get a
22344/// representation of the decl (or type) for the purpose of canonical
22345/// type comparison. This is mainly used in the function
22346/// type_base::get_canonical_type_for().
22347///
22348/// In other words if the argument for this parameter is true then the
22349/// call is meant for internal use (for technical use inside the
22350/// library itself), false otherwise. If you don't know what this is
22351/// for, then set it to false.
22352///
22353/// @return a copy of the pretty representation of the current @ref
22354/// function_type.
22355string
22357 bool /*qualified_name*/) const
22358{return ir::get_pretty_representation(this, internal);}
22359
22360/// Traverses an instance of @ref function_type, visiting all the
22361/// sub-types and decls that it might contain.
22362///
22363/// @param v the visitor that is used to visit every IR sub-node of
22364/// the current node.
22365///
22366/// @return true if either
22367/// - all the children nodes of the current IR node were traversed
22368/// and the calling code should keep going with the traversing.
22369/// - or the current IR node is already being traversed.
22370/// Otherwise, returning false means that the calling code should not
22371/// keep traversing the tree.
22372bool
22374{
22375 // TODO: should we allow the walker to avoid visiting function type
22376 // twice? I think that if we do, then ir_node_visitor needs an
22377 // option to specifically disallow this feature for function types.
22378
22379 if (visiting())
22380 return true;
22381
22382 if (v.visit_begin(this))
22383 {
22384 visiting(true);
22385 bool keep_going = true;
22386
22387 if (type_base_sptr t = get_return_type())
22388 {
22389 if (!t->traverse(v))
22390 keep_going = false;
22391 }
22392
22393 if (keep_going)
22394 for (parameters::const_iterator i = get_parameters().begin();
22395 i != get_parameters().end();
22396 ++i)
22397 if (type_base_sptr parm_type = (*i)->get_type())
22398 if (!parm_type->traverse(v))
22399 break;
22400
22401 visiting(false);
22402 }
22403 return v.visit_end(this);
22404}
22405
22406function_type::~function_type()
22407{}
22408// </function_type>
22409
22410// <method_type>
22411
22412struct method_type::priv
22413{
22414 class_or_union_wptr class_type_;
22415 bool is_const;
22416
22417 priv()
22418 : is_const()
22419 {}
22420}; // end struct method_type::priv
22421
22422/// Constructor for instances of method_type.
22423///
22424/// Instances of method_decl must be of type method_type.
22425///
22426/// @param return_type the type of the return value of the method.
22427///
22428/// @param class_type the base type of the method type. That is, the
22429/// type of the class the method belongs to.
22430///
22431/// @param p the vector of the parameters of the method.
22432///
22433/// @param is_const whether this method type is for a const method.
22434/// Note that const-ness is a property of the method *type* and of the
22435/// relationship between a method *declaration* and its scope.
22436///
22437/// @param size_in_bits the size of an instance of method_type,
22438/// expressed in bits.
22439///
22440/// @param alignment_in_bits the alignment of an instance of
22441/// method_type, expressed in bits.
22442method_type::method_type (type_base_sptr return_type,
22443 class_or_union_sptr class_type,
22444 const std::vector<function_decl::parameter_sptr>& p,
22445 bool is_const,
22446 size_t size_in_bits,
22447 size_t alignment_in_bits)
22448 : type_or_decl_base(class_type->get_environment(),
22449 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22450 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22451 function_type(return_type, p, size_in_bits, alignment_in_bits),
22452 priv_(new priv)
22453{
22455 set_class_type(class_type);
22456 set_is_const(is_const);
22457}
22458
22459/// Constructor of instances of method_type.
22460///
22461///Instances of method_decl must be of type method_type.
22462///
22463/// @param return_type the type of the return value of the method.
22464///
22465/// @param class_type the type of the class the method belongs to.
22466/// The actual (dynamic) type of class_type must be a pointer
22467/// class_type. We are setting it to pointer to type_base here to
22468/// help client code that is compiled without rtti and thus cannot
22469/// perform dynamic casts.
22470///
22471/// @param p the vector of the parameters of the method type.
22472///
22473/// @param is_const whether this method type is for a const method.
22474/// Note that const-ness is a property of the method *type* and of the
22475/// relationship between a method *declaration* and its scope.
22476///
22477/// @param size_in_bits the size of an instance of method_type,
22478/// expressed in bits.
22479///
22480/// @param alignment_in_bits the alignment of an instance of
22481/// method_type, expressed in bits.
22482method_type::method_type(type_base_sptr return_type,
22483 type_base_sptr class_type,
22484 const std::vector<function_decl::parameter_sptr>& p,
22485 bool is_const,
22486 size_t size_in_bits,
22487 size_t alignment_in_bits)
22488 : type_or_decl_base(class_type->get_environment(),
22489 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22490 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22491 function_type(return_type, p, size_in_bits, alignment_in_bits),
22492 priv_(new priv)
22493{
22495 set_class_type(is_class_type(class_type));
22496 set_is_const(is_const);
22497}
22498
22499/// Constructor of the qualified_type_def
22500///
22501/// @param env the environment we are operating from.
22502///
22503/// @param size_in_bits the size of the type, expressed in bits.
22504///
22505/// @param alignment_in_bits the alignment of the type, expressed in bits
22506method_type::method_type(const environment& env,
22507 size_t size_in_bits,
22508 size_t alignment_in_bits)
22509 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22510 type_base(env, size_in_bits, alignment_in_bits),
22511 function_type(env, size_in_bits, alignment_in_bits),
22512 priv_(new priv)
22513{
22515}
22516
22517/// Constructor of instances of method_type.
22518///
22519/// When constructed with this constructor, and instane of method_type
22520/// must set a return type using method_type::set_return_type
22521///
22522/// @param class_typ the base type of the method type. That is, the
22523/// type of the class (or union) the method belongs to.
22524///
22525/// @param size_in_bits the size of an instance of method_type,
22526/// expressed in bits.
22527///
22528/// @param alignment_in_bits the alignment of an instance of
22529/// method_type, expressed in bits.
22530method_type::method_type(class_or_union_sptr class_type,
22531 bool is_const,
22532 size_t size_in_bits,
22533 size_t alignment_in_bits)
22534 : type_or_decl_base(class_type->get_environment(),
22535 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22536 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22537 function_type(class_type->get_environment(),
22538 size_in_bits,
22539 alignment_in_bits),
22540 priv_(new priv)
22541{
22543 set_class_type(class_type);
22544 set_is_const(is_const);
22545}
22546
22547/// Return the hash value of the current IR node.
22548///
22549/// Note that upon the first invocation, this member functions
22550/// computes the hash value and returns it. Subsequent invocations
22551/// just return the hash value that was previously calculated.
22552///
22553/// @return the hash value of the current IR node.
22554hash_t
22556{
22558 return h;
22559}
22560
22561/// Get the class type this method belongs to.
22562///
22563/// @return the class type.
22564class_or_union_sptr
22566{return class_or_union_sptr(priv_->class_type_);}
22567
22568/// Sets the class type of the current instance of method_type.
22569///
22570/// The class type is the type of the class the method belongs to.
22571///
22572/// @param t the new class type to set.
22573void
22574method_type::set_class_type(const class_or_union_sptr& t)
22575{
22576 if (!t)
22577 return;
22578
22579 priv_->class_type_ = t;
22580}
22581
22582/// Return a copy of the pretty representation of the current @ref
22583/// method_type.
22584///
22585/// @param internal set to true if the call is intended to get a
22586/// representation of the decl (or type) for the purpose of canonical
22587/// type comparison. This is mainly used in the function
22588/// type_base::get_canonical_type_for().
22589///
22590/// In other words if the argument for this parameter is true then the
22591/// call is meant for internal use (for technical use inside the
22592/// library itself), false otherwise. If you don't know what this is
22593/// for, then set it to false.
22594///
22595/// @return a copy of the pretty representation of the current @ref
22596/// method_type.
22597string
22599 bool /*qualified_name*/) const
22600{return ir::get_pretty_representation(*this, internal);}
22601
22602/// Setter of the "is-const" property of @ref method_type.
22603///
22604/// @param the new value of the "is-const" property.
22605void
22607{priv_->is_const = f;}
22608
22609/// Getter of the "is-const" property of @ref method_type.
22610///
22611/// @return true iff the "is-const" property was set.
22612bool
22614{return priv_->is_const;}
22615
22616/// Test if the current method type is for a static method or not.
22617///
22618/// @return true iff the current method_type denotes a the type of a
22619/// static method.
22620bool
22622{
22623 // Let's see if the first parameter is artificial and is a pointer
22624 // to an instance of the same class type as the current class.
22626 if (!get_parameters().empty())
22627 first_parm = get_parameters()[0];
22628 if (!first_parm)
22629 return true;
22630 if (!first_parm->get_is_artificial())
22631 return true;
22632
22633 type_base_sptr this_ptr_type = first_parm->get_type();
22634 // Sometimes, the type of the "this" pointer is "const class_type*
22635 // const". Meaning that the "this pointer" itself is const
22636 // qualified. So let's get the underlying non-qualified pointer.
22637 this_ptr_type = peel_qualified_type(this_ptr_type);
22638 if (!is_pointer_type(this_ptr_type))
22639 return true;
22640
22641 type_base_sptr candidate_class_type =
22642 is_pointer_type(this_ptr_type)->get_pointed_to_type();
22643 candidate_class_type = peel_qualified_type(candidate_class_type);
22644 if (is_class_type(candidate_class_type)
22645 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
22646 // At this point, we are sure we are looking at a *non-static*
22647 // method.
22648 return false;
22649
22650 return true;
22651}
22652
22653/// The destructor of method_type
22656
22657// </method_type>
22658
22659// <function_decl definitions>
22660
22661struct function_decl::priv
22662{
22663 bool declared_inline_;
22664 decl_base::binding binding_;
22665 function_type_wptr type_;
22666 function_type* naked_type_;
22667 elf_symbol_sptr symbol_;
22668 interned_string id_;
22669
22670 priv()
22671 : declared_inline_(false),
22672 binding_(decl_base::BINDING_GLOBAL),
22673 naked_type_()
22674 {}
22675
22676 priv(function_type_sptr t,
22677 bool declared_inline,
22678 decl_base::binding binding)
22679 : declared_inline_(declared_inline),
22680 binding_(binding),
22681 type_(t),
22682 naked_type_(t.get())
22683 {}
22684
22685 priv(function_type_sptr t,
22686 bool declared_inline,
22687 decl_base::binding binding,
22689 : declared_inline_(declared_inline),
22690 binding_(binding),
22691 type_(t),
22692 naked_type_(t.get()),
22693 symbol_(s)
22694 {}
22695}; // end sruct function_decl::priv
22696
22697/// Constructor of the @ref function_decl.
22698///
22699/// @param name the name of the function.
22700///
22701/// @param function_type the type of the function.
22702///
22703/// @param declared_inline wether the function is declared inline.
22704///
22705/// @param locus the source location of the function.
22706///
22707/// @param mangled_name the linkage name of the function.
22708///
22709/// @param vis the visibility of the function.
22710///
22711/// @param bind the binding of the function.
22714 bool declared_inline,
22715 const location& locus,
22716 const string& mangled_name,
22717 visibility vis,
22718 binding bind)
22720 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22721 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
22722 priv_(new priv(function_type, declared_inline, bind))
22723{
22725}
22726
22727/// Constructor of the function_decl type.
22728///
22729/// This flavour of constructor is for when the pointer to the
22730/// instance of function_type that the client code has is presented as
22731/// a pointer to type_base. In that case, this constructor saves the
22732/// client code from doing a dynamic_cast to get the function_type
22733/// pointer.
22734///
22735/// @param name the name of the function declaration.
22736///
22737/// @param fn_type the type of the function declaration. The dynamic
22738/// type of this parameter should be 'pointer to function_type'
22739///
22740/// @param declared_inline whether this function was declared inline
22741///
22742/// @param locus the source location of the function declaration.
22743///
22744/// @param linkage_name the mangled name of the function declaration.
22745///
22746/// @param vis the visibility of the function declaration.
22747///
22748/// @param bind the kind of the binding of the function
22749/// declaration.
22751 type_base_sptr fn_type,
22752 bool declared_inline,
22753 const location& locus,
22754 const string& linkage_name,
22755 visibility vis,
22756 binding bind)
22758 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22759 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
22760 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
22761 declared_inline,
22762 bind))
22763{
22765}
22766
22767/// Get the pretty representation of the current instance of @ref function_decl.
22768///
22769/// @param internal set to true if the call is intended to get a
22770/// representation of the decl (or type) for the purpose of canonical
22771/// type comparison. This is mainly used in the function
22772/// type_base::get_canonical_type_for().
22773///
22774/// In other words if the argument for this parameter is true then the
22775/// call is meant for internal use (for technical use inside the
22776/// library itself), false otherwise. If you don't know what this is
22777/// for, then set it to false.
22778///
22779/// @return the pretty representation for a function.
22780string
22782 bool qualified_name) const
22783{
22784 const method_decl* mem_fn =
22785 dynamic_cast<const method_decl*>(this);
22786
22787 string fn_prefix = mem_fn ? "method ": "function ";
22788 string result;
22789
22790 if (mem_fn
22791 && is_member_function(mem_fn)
22793 fn_prefix += "virtual ";
22794
22795 decl_base_sptr return_type;
22796 if ((mem_fn
22797 && is_member_function(mem_fn)
22798 && (get_member_function_is_dtor(*mem_fn)
22799 || get_member_function_is_ctor(*mem_fn))))
22800 /*cdtors do not have return types. */;
22801 else
22802 return_type = mem_fn
22803 ? get_type_declaration(mem_fn->get_type()->get_return_type())
22805
22806 result = get_pretty_representation_of_declarator(internal);
22807 if (return_type)
22808 {
22809 if (is_npaf_type(is_type(return_type))
22810 || !(is_pointer_to_function_type(is_type(return_type))
22811 || is_pointer_to_array_type(is_type(return_type))))
22812 result = get_type_name(is_type(return_type).get(), qualified_name,
22813 internal) + " " + result;
22814 else if (pointer_type_def_sptr p =
22816 result = add_outer_pointer_to_fn_type_expr(p, result,
22817 /*qualified=*/true,
22818 internal);
22819 else if(pointer_type_def_sptr p =
22820 is_pointer_to_array_type(is_type(return_type)))
22821 result = add_outer_pointer_to_array_type_expr(p, result,
22822 qualified_name,
22823 internal);
22824 else
22826 }
22827
22828 return fn_prefix + result;
22829}
22830
22831/// Compute and return the pretty representation for the part of the
22832/// function declaration that starts at the declarator. That is, the
22833/// return type and the other specifiers of the beginning of the
22834/// function's declaration ar omitted.
22835///
22836/// @param internal set to true if the call is intended to get a
22837/// representation of the decl (or type) for the purpose of canonical
22838/// type comparison. This is mainly used in the function
22839/// type_base::get_canonical_type_for().
22840///
22841/// In other words if the argument for this parameter is true then the
22842/// call is meant for internal use (for technical use inside the
22843/// library itself), false otherwise. If you don't know what this is
22844/// for, then set it to false.
22845///
22846/// @return the pretty representation for the part of the function
22847/// declaration that starts at the declarator.
22848string
22850{
22851 const method_decl* mem_fn =
22852 dynamic_cast<const method_decl*>(this);
22853
22854 string result;
22855
22856 if (mem_fn)
22857 {
22858 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22859 + "::" + mem_fn->get_name();
22860 }
22861 else
22862 result += get_qualified_name();
22863
22864 std::ostringstream fn_parms;
22865 stream_pretty_representation_of_fn_parms(*get_type(),
22866 fn_parms,
22867 /*qualified=*/true,
22868 internal);
22869 result += fn_parms.str();
22870
22871 if (mem_fn
22872 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22873 || is_method_type(mem_fn->get_type())->get_is_const()))
22874 result += " const";
22875
22876 return result;
22877}
22878
22879/// Getter for the first non-implicit parameter of a function decl.
22880///
22881/// If the function is a non-static member function, the parameter
22882/// returned is the first one following the implicit 'this' parameter.
22883///
22884/// @return the first non implicit parm.
22885function_decl::parameters::const_iterator
22887{
22888 if (get_parameters().empty())
22889 return get_parameters().end();
22890
22891 bool is_method = dynamic_cast<const method_decl*>(this);
22892
22893 parameters::const_iterator i = get_parameters().begin();
22894 if (is_method)
22895 ++i;
22896
22897 return i;
22898}
22899
22900/// Return the type of the current instance of @ref function_decl.
22901///
22902/// It's either a function_type or method_type.
22903/// @return the type of the current instance of @ref function_decl.
22904const shared_ptr<function_type>
22906{return priv_->type_.lock();}
22907
22908/// Fast getter of the type of the current instance of @ref function_decl.
22909///
22910/// Note that this function returns the underlying pointer managed by
22911/// the smart pointer returned by function_decl::get_type(). It's
22912/// faster than function_decl::get_type(). This getter is to be used
22913/// in code paths that are proven to be performance hot spots;
22914/// especially (for instance) when comparing function types. Those
22915/// are compared extremely frequently when libabigail is used to
22916/// handle huge binaries with a lot of functions.
22917///
22918/// @return the type of the current instance of @ref function_decl.
22919const function_type*
22921{return priv_->naked_type_;}
22922
22923void
22924function_decl::set_type(const function_type_sptr& fn_type)
22925{
22926 priv_->type_ = fn_type;
22927 priv_->naked_type_ = fn_type.get();
22928}
22929
22930/// This sets the underlying ELF symbol for the current function decl.
22931///
22932/// And underlyin$g ELF symbol for the current function decl might
22933/// exist only if the corpus that this function decl originates from
22934/// was constructed from an ELF binary file.
22935///
22936/// Note that comparing two function decls that have underlying ELF
22937/// symbols involves comparing their underlying elf symbols. The decl
22938/// name for the function thus becomes irrelevant in the comparison.
22939///
22940/// @param sym the new ELF symbol for this function decl.
22941void
22943{
22944 priv_->symbol_ = sym;
22945 // The function id cache that depends on the symbol must be
22946 // invalidated because the symbol changed.
22947 priv_->id_ = get_environment().intern("");
22948}
22949
22950/// Gets the the underlying ELF symbol for the current variable,
22951/// that was set using function_decl::set_symbol(). Please read the
22952/// documentation for that member function for more information about
22953/// "underlying ELF symbols".
22954///
22955/// @return sym the underlying ELF symbol for this function decl, if
22956/// one exists.
22957const elf_symbol_sptr&
22959{return priv_->symbol_;}
22960
22961/// Test if the function was declared inline.
22962///
22963/// @return true iff the function was declared inline.
22964bool
22966{return priv_->declared_inline_;}
22967
22968/// Set the property of the function being declared inline.
22969///
22970/// @param value true iff the function was declared inline.
22971void
22973{priv_->declared_inline_ = value;}
22974
22976function_decl::get_binding() const
22977{return priv_->binding_;}
22978
22979/// @return the return type of the current instance of function_decl.
22980const shared_ptr<type_base>
22982{return get_type()->get_return_type();}
22983
22984/// @return the parameters of the function.
22985const std::vector<shared_ptr<function_decl::parameter> >&
22987{return get_type()->get_parameters();}
22988
22989/// Append a parameter to the type of this function.
22990///
22991/// @param parm the parameter to append.
22992void
22993function_decl::append_parameter(shared_ptr<parameter> parm)
22994{get_type()->append_parameter(parm);}
22995
22996/// Append a vector of parameters to the type of this function.
22997///
22998/// @param parms the vector of parameters to append.
22999void
23000function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
23001{
23002 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
23003 i != parms.end();
23004 ++i)
23005 get_type()->append_parameter(*i);
23006}
23007
23008/// Create a new instance of function_decl that is a clone of the
23009/// current one.
23010///
23011/// @return the new clone.
23014{
23016 if (is_member_function(*this))
23017 {
23018 method_decl_sptr
23019 m(new method_decl(get_name(),
23020 get_type(),
23022 get_location(),
23025 get_binding()));
23026 class_or_union* scope = is_class_or_union_type(get_scope());
23027 ABG_ASSERT(scope);
23031 get_member_is_static(*this),
23035 f = m;
23036 }
23037 else
23038 {
23039 f.reset(new function_decl(get_name(),
23040 get_type(),
23042 get_location(),
23045 get_binding()));
23047 }
23048 f->set_symbol(get_symbol());
23049
23050 return f;
23051}
23052
23053/// Compares two instances of @ref function_decl.
23054///
23055/// If the two intances are different, set a bitfield to give some
23056/// insight about the kind of differences there are.
23057///
23058/// @param l the first artifact of the comparison.
23059///
23060/// @param r the second artifact of the comparison.
23061///
23062/// @param k a pointer to a bitfield that gives information about the
23063/// kind of changes there are between @p l and @p r. This one is set
23064/// iff @p k is non-null and the function returns false.
23065///
23066/// Please note that setting k to a non-null value does have a
23067/// negative performance impact because even if @p l and @p r are not
23068/// equal, the function keeps up the comparison in order to determine
23069/// the different kinds of ways in which they are different.
23070///
23071/// @return true if @p l equals @p r, false otherwise.
23072bool
23074{
23075 bool result = true;
23076
23077 // Compare function types
23078 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
23079 if (t0 == t1 || *t0 == *t1)
23080 ; // the types are equal, let's move on to compare the other
23081 // properties of the functions.
23082 else
23083 {
23084 result = false;
23085 if (k)
23086 {
23087 if (!types_have_similar_structure(t0, t1))
23089 else
23090 *k |= SUBTYPE_CHANGE_KIND;
23091 }
23092 else
23094 }
23095
23096 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
23097 if (!!s0 != !!s1)
23098 {
23099 result = false;
23100 if (k)
23102 else
23104 }
23105 else if (s0 && s0 != s1)
23106 {
23107 if (!elf_symbols_alias(s0, s1))
23108 {
23109 result = false;
23110 if (k)
23112 else
23114 }
23115 }
23116 bool symbols_are_equal = (s0 && s1 && result);
23117
23118 if (symbols_are_equal)
23119 {
23120 // The functions have underlying elf symbols that are equal,
23121 // so now, let's compare the decl_base part of the functions
23122 // w/o considering their decl names.
23123 interned_string n1 = l.get_name(), n2 = r.get_name();
23125 const_cast<function_decl&>(l).set_name("");
23126 const_cast<function_decl&>(l).set_linkage_name("");
23127 const_cast<function_decl&>(r).set_name("");
23128 const_cast<function_decl&>(r).set_linkage_name("");
23129
23130 bool decl_bases_different = !l.decl_base::operator==(r);
23131
23132 const_cast<function_decl&>(l).set_name(n1);
23133 const_cast<function_decl&>(l).set_linkage_name(ln1);
23134 const_cast<function_decl&>(r).set_name(n2);
23135 const_cast<function_decl&>(r).set_linkage_name(ln2);
23136
23137 if (decl_bases_different)
23138 {
23139 result = false;
23140 if (k)
23142 else
23144 }
23145 }
23146 else
23147 if (!l.decl_base::operator==(r))
23148 {
23149 result = false;
23150 if (k)
23152 else
23154 }
23155
23156 // Compare the remaining properties. Note that we don't take into
23157 // account the fact that the function was declared inline or not as
23158 // that doesn't have any impact on the final ABI.
23159 if (l.get_binding() != r.get_binding())
23160 {
23161 result = false;
23162 if (k)
23164 else
23166 }
23167
23169 {
23170 result = false;
23171 if (k)
23173 else
23175 }
23176
23178 {
23191 {
23192 result = false;
23193 if (k)
23195 else
23197 }
23198 }
23199
23200 ABG_RETURN(result);
23201}
23202
23203/// Comparison operator for @ref function_decl.
23204///
23205/// @param other the other instance of @ref function_decl to compare
23206/// against.
23207///
23208/// @return true iff the current instance of @ref function_decl equals
23209/// @p other.
23210bool
23211function_decl::operator==(const decl_base& other) const
23212{
23213 const function_decl* o = dynamic_cast<const function_decl*>(&other);
23214 if (!o)
23215 return false;
23216 return equals(*this, *o, 0);
23217}
23218
23219/// Return true iff the function takes a variable number of
23220/// parameters.
23221///
23222/// @return true if the function taks a variable number
23223/// of parameters.
23224bool
23226{
23227 return (!get_parameters().empty()
23228 && get_parameters().back()->get_variadic_marker());
23229}
23230
23231/// Return an ID that tries to uniquely identify the function inside a
23232/// program or a library.
23233///
23234/// So if the function has an underlying elf symbol, the ID is the
23235/// concatenation of the symbol name and its version. Otherwise, the
23236/// ID is the linkage name if its non-null. Otherwise, it's the
23237/// pretty representation of the function.
23238///
23239/// @return the ID.
23242{
23243 if (priv_->id_.empty())
23244 {
23245 const environment& env = get_type()->get_environment();
23246 if (elf_symbol_sptr s = get_symbol())
23247 {
23248 string virtual_member_suffix;
23249 if (is_member_function(this))
23250 {
23251 method_decl* m = is_method_decl(this);
23252 ABG_ASSERT(m);
23254 {
23256 (m->get_type()->get_class_type(),
23257 /*look_through_decl_only=*/true))
23258 virtual_member_suffix += "/o";
23259 }
23260 }
23261 if (s->has_aliases())
23262 // The symbol has several aliases, so let's use a scheme
23263 // that allows all aliased functions to have different
23264 // IDs.
23265 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
23266 else
23267 // Let's use the full symbol name with its version as ID.
23268 priv_->id_ = env.intern(s->get_id_string());
23269
23270 if (!virtual_member_suffix.empty())
23271 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
23272 }
23273 else if (!get_linkage_name().empty())
23274 priv_->id_= env.intern(get_linkage_name());
23275 else
23276 priv_->id_ = env.intern(get_pretty_representation());
23277 }
23278 return priv_->id_;
23279}
23280
23281/// Test if two function declarations are aliases.
23282///
23283/// Two functions declarations are aliases if their symbols are
23284/// aliases, in the ELF sense.
23285///
23286/// @param f1 the first function to consider.
23287///
23288/// @param f2 the second function to consider.
23289///
23290/// @return true iff @p f1 is an alias of @p f2
23291bool
23293{
23294 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
23295
23296 if (!s1 || !s2)
23297 return false;
23298
23299 return elf_symbols_alias(s1, s2);
23300}
23301
23302/// This implements the ir_traversable_base::traverse pure virtual
23303/// function.
23304///
23305/// @param v the visitor used on the current instance.
23306///
23307/// @return true if the entire IR node tree got traversed, false
23308/// otherwise.
23309bool
23311{
23312 if (visiting())
23313 return true;
23314
23315 if (v.visit_begin(this))
23316 {
23317 visiting(true);
23318 if (type_base_sptr t = get_type())
23319 t->traverse(v);
23320 visiting(false);
23321 }
23322 return v.visit_end(this);
23323}
23324
23325/// Destructor of the @ref function_decl type.
23327{delete priv_;}
23328
23329/// A deep comparison operator for a shared pointer to @ref function_decl
23330///
23331/// This function compares to shared pointers to @ref function_decl by
23332/// looking at the pointed-to instances of @ref function_dec
23333/// comparing them too. If the two pointed-to objects are equal then
23334/// this function returns true.
23335///
23336/// @param l the left-hand side argument of the equality operator.
23337///
23338/// @param r the right-hand side argument of the equality operator.
23339///
23340/// @return true iff @p l equals @p r.
23341bool
23343{
23344 if (l.get() == r.get())
23345 return true;
23346 if (!!l != !!r)
23347 return false;
23348
23349 return *l == *r;
23350}
23351
23352/// A deep inequality operator for smart pointers to functions.
23353///
23354/// @param l the left-hand side argument of the inequality operator.
23355///
23356/// @pram r the right-hand side argument of the inequality operator.
23357///
23358/// @return true iff @p is not equal to @p r.
23359bool
23361{return !operator==(l, r);}
23362
23363// <function_decl definitions>
23364
23365// <function_decl::parameter definitions>
23366
23367struct function_decl::parameter::priv
23368{
23369 type_base_wptr type_;
23370 unsigned index_;
23371 bool variadic_marker_;
23372
23373 priv()
23374 : index_(),
23375 variadic_marker_()
23376 {}
23377
23378 priv(type_base_sptr type,
23379 unsigned index,
23380 bool variadic_marker)
23381 : type_(type),
23382 index_(index),
23383 variadic_marker_(variadic_marker)
23384 {}
23385};// end struct function_decl::parameter::priv
23386
23387function_decl::parameter::parameter(const type_base_sptr type,
23388 unsigned index,
23389 const string& name,
23390 const location& loc,
23391 bool is_variadic)
23392 : type_or_decl_base(type->get_environment(),
23393 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23394 decl_base(type->get_environment(), name, loc),
23395 priv_(new priv(type, index, is_variadic))
23396{
23397 runtime_type_instance(this);
23398}
23399
23400function_decl::parameter::parameter(const type_base_sptr type,
23401 unsigned index,
23402 const string& name,
23403 const location& loc,
23404 bool is_variadic,
23405 bool is_artificial)
23406 : type_or_decl_base(type->get_environment(),
23407 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23408 decl_base(type->get_environment(), name, loc),
23409 priv_(new priv(type, index, is_variadic))
23410{
23411 runtime_type_instance(this);
23412 set_is_artificial(is_artificial);
23413}
23414
23415function_decl::parameter::parameter(const type_base_sptr type,
23416 const string& name,
23417 const location& loc,
23418 bool is_variadic,
23419 bool is_artificial)
23420 : type_or_decl_base(type->get_environment(),
23421 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23422 decl_base(type->get_environment(), name, loc),
23423 priv_(new priv(type, 0, is_variadic))
23424{
23425 runtime_type_instance(this);
23426 set_is_artificial(is_artificial);
23427}
23428
23429function_decl::parameter::parameter(const type_base_sptr type,
23430 unsigned index,
23431 bool variad)
23432 : type_or_decl_base(type->get_environment(),
23433 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23434 decl_base(type->get_environment(), "", location()),
23435 priv_(new priv(type, index, variad))
23436{
23437 runtime_type_instance(this);
23438}
23439
23440function_decl::parameter::~parameter() = default;
23441
23442const type_base_sptr
23443function_decl::parameter::get_type()const
23444{return priv_->type_.lock();}
23445
23446/// @return a copy of the type name of the parameter.
23447interned_string
23449{
23450 const environment& env = get_environment();
23451
23452 type_base_sptr t = get_type();
23453 string str;
23454 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
23455 str = "...";
23456 else
23457 {
23458 ABG_ASSERT(t);
23460 }
23461 return env.intern(str);
23462}
23463
23464/// @return a copy of the pretty representation of the type of the
23465/// parameter.
23466const string
23468{
23469 type_base_sptr t = get_type();
23470 string str;
23471 if (get_variadic_marker()
23472 || get_environment().is_variadic_parameter_type(t))
23473 str = "...";
23474 else
23475 {
23476 ABG_ASSERT(t);
23478 }
23479 return str;
23480}
23481
23482/// Get a name uniquely identifying the parameter in the function.
23483///
23484///@return the unique parm name id.
23487{
23488 const environment& env = get_environment();
23489
23490
23491 std::ostringstream o;
23492 o << "parameter-" << get_index();
23493
23494 return env.intern(o.str());
23495}
23496
23497unsigned
23498function_decl::parameter::get_index() const
23499{return priv_->index_;}
23500
23501void
23502function_decl::parameter::set_index(unsigned i)
23503{priv_->index_ = i;}
23504
23505
23506bool
23507function_decl::parameter::get_variadic_marker() const
23508{return priv_->variadic_marker_;}
23509
23510/// Compares two instances of @ref function_decl::parameter.
23511///
23512/// If the two intances are different, set a bitfield to give some
23513/// insight about the kind of differences there are.
23514///
23515/// @param l the first artifact of the comparison.
23516///
23517/// @param r the second artifact of the comparison.
23518///
23519/// @param k a pointer to a bitfield that gives information about the
23520/// kind of changes there are between @p l and @p r. This one is set
23521/// iff @p k is non-null and the function returns false.
23522///
23523/// Please note that setting k to a non-null value does have a
23524/// negative performance impact because even if @p l and @p r are not
23525/// equal, the function keeps up the comparison in order to determine
23526/// the different kinds of ways in which they are different.
23527///
23528/// @return true if @p l equals @p r, false otherwise.
23529bool
23531 const function_decl::parameter& r,
23532 change_kind* k)
23533{
23534 bool result = true;
23535
23536 if ((l.get_variadic_marker() != r.get_variadic_marker())
23537 || (l.get_index() != r.get_index())
23538 || (!!l.get_type() != !!r.get_type()))
23539 {
23540 result = false;
23541 if (k)
23542 {
23543 if (l.get_index() != r.get_index())
23545 if (l.get_variadic_marker() != r.get_variadic_marker()
23546 || !!l.get_type() != !!r.get_type())
23548 }
23549 else
23551 }
23552
23553 type_base_sptr l_type = l.get_type();
23554 type_base_sptr r_type = r.get_type();
23555
23556 if (l_type != r_type)
23557 {
23558 result = false;
23559 if (k)
23560 {
23561 if (!types_have_similar_structure(l_type, r_type))
23563 else
23564 *k |= SUBTYPE_CHANGE_KIND;
23565 }
23566 else
23568 }
23569
23570 ABG_RETURN(result);
23571}
23572
23573bool
23574function_decl::parameter::operator==(const parameter& o) const
23575{return equals(*this, o, 0);}
23576
23577bool
23578function_decl::parameter::operator==(const decl_base& o) const
23579{
23580 const function_decl::parameter* p =
23581 dynamic_cast<const function_decl::parameter*>(&o);
23582 if (!p)
23583 return false;
23584 return function_decl::parameter::operator==(*p);
23585}
23586
23587/// Non-member equality operator for @ref function_decl::parameter.
23588///
23589/// @param l the left-hand side of the equality operator
23590///
23591/// @param r the right-hand side of the equality operator
23592///
23593/// @return true iff @p l and @p r equals.
23594bool
23597{
23598 if (!!l != !!r)
23599 return false;
23600 if (!l)
23601 return true;
23602 return *l == *r;
23603}
23604
23605/// Non-member inequality operator for @ref function_decl::parameter.
23606///
23607/// @param l the left-hand side of the equality operator
23608///
23609/// @param r the right-hand side of the equality operator
23610///
23611/// @return true iff @p l and @p r different.
23612bool
23616
23617/// Traverse the diff sub-tree under the current instance
23618/// function_decl.
23619///
23620/// @param v the visitor to invoke on each diff node of the sub-tree.
23621///
23622/// @return true if the traversing has to keep going on, false
23623/// otherwise.
23624bool
23626{
23627 if (visiting())
23628 return true;
23629
23630 if (v.visit_begin(this))
23631 {
23632 visiting(true);
23633 if (type_base_sptr t = get_type())
23634 t->traverse(v);
23635 visiting(false);
23636 }
23637 return v.visit_end(this);
23638}
23639
23640/// Compute the qualified name of the parameter.
23641///
23642/// @param internal set to true if the call is intended for an
23643/// internal use (for technical use inside the library itself), false
23644/// otherwise. If you don't know what this is for, then set it to
23645/// false.
23646///
23647/// @param qn the resulting qualified name.
23648void
23650 bool /*internal*/) const
23651{qualified_name = get_name();}
23652
23653/// Compute and return a copy of the pretty representation of the
23654/// current function parameter.
23655///
23656/// @param internal set to true if the call is intended to get a
23657/// representation of the decl (or type) for the purpose of canonical
23658/// type comparison. This is mainly used in the function
23659/// type_base::get_canonical_type_for().
23660///
23661/// In other words if the argument for this parameter is true then the
23662/// call is meant for internal use (for technical use inside the
23663/// library itself), false otherwise. If you don't know what this is
23664/// for, then set it to false.
23665///
23666/// @return a copy of the textual representation of the current
23667/// function parameter.
23668string
23670 bool qualified_name) const
23671{
23672 const environment& env = get_environment();
23673
23674 string type_repr;
23675 type_base_sptr t = get_type();
23676 if (!t)
23677 type_repr = "void";
23678 else if (env.is_variadic_parameter_type(t))
23679 type_repr = "...";
23680 else
23681 type_repr = ir::get_type_name(t, qualified_name, internal);
23682
23683 string result = type_repr;
23684 string parm_name = get_name_id();
23685
23686 if (!parm_name.empty())
23687 result += " " + parm_name;
23688
23689 return result;
23690}
23691
23692// </function_decl::parameter definitions>
23693
23694// <class_or_union definitions>
23695
23696/// A Constructor for instances of @ref class_or_union
23697///
23698/// @param env the environment we are operating from.
23699///
23700/// @param name the identifier of the class.
23701///
23702/// @param size_in_bits the size of an instance of @ref
23703/// class_or_union, expressed in bits
23704///
23705/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23706/// expressed in bits.
23707///
23708/// @param locus the source location of declaration point this class.
23709///
23710/// @param vis the visibility of instances of @ref class_or_union.
23711///
23712/// @param mem_types the vector of member types of this instance of
23713/// @ref class_or_union.
23714///
23715/// @param data_members the vector of data members of this instance of
23716/// @ref class_or_union.
23717///
23718/// @param member_fns the vector of member functions of this instance
23719/// of @ref class_or_union.
23720class_or_union::class_or_union(const environment& env, const string& name,
23721 size_t size_in_bits, size_t align_in_bits,
23722 const location& locus, visibility vis,
23723 member_types& mem_types,
23725 member_functions& member_fns)
23726 : type_or_decl_base(env,
23727 ABSTRACT_TYPE_BASE
23728 | ABSTRACT_DECL_BASE
23729 | ABSTRACT_SCOPE_TYPE_DECL
23730 | ABSTRACT_SCOPE_DECL),
23731 decl_base(env, name, locus, name, vis),
23732 type_base(env, size_in_bits, align_in_bits),
23733 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23734 priv_(new priv(data_members, member_fns))
23735{
23736 for (member_types::iterator i = mem_types.begin();
23737 i != mem_types.end();
23738 ++i)
23741
23742 for (data_members::iterator i = data_members.begin();
23743 i != data_members.end();
23744 ++i)
23745 if (!has_scope(*i))
23746 add_decl_to_scope(*i, this);
23747
23748 for (member_functions::iterator i = member_fns.begin();
23749 i != member_fns.end();
23750 ++i)
23751 if (!has_scope(static_pointer_cast<decl_base>(*i)))
23752 add_decl_to_scope(*i, this);
23753}
23754
23755/// A constructor for instances of @ref class_or_union.
23756///
23757/// @param env the environment we are operating from.
23758///
23759/// @param name the name of the class.
23760///
23761/// @param size_in_bits the size of an instance of @ref
23762/// class_or_union, expressed in bits
23763///
23764/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23765/// expressed in bits.
23766///
23767/// @param locus the source location of declaration point this class.
23768///
23769/// @param vis the visibility of instances of @ref class_or_union.
23770class_or_union::class_or_union(const environment& env, const string& name,
23771 size_t size_in_bits, size_t align_in_bits,
23772 const location& locus, visibility vis)
23773 : type_or_decl_base(env,
23774 ABSTRACT_TYPE_BASE
23775 | ABSTRACT_DECL_BASE
23776 | ABSTRACT_SCOPE_TYPE_DECL
23777 | ABSTRACT_SCOPE_DECL),
23778 decl_base(env, name, locus, name, vis),
23779 type_base(env, size_in_bits, align_in_bits),
23780 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23781 priv_(new priv)
23782{}
23783
23784/// Constructor of the @ref class_or_union type.
23785///
23786/// @param env the @ref environment we are operating from.
23787///
23788/// @param name the name of the @ref class_or_union.
23789///
23790/// @param is_declaration_only a boolean saying whether the instance
23791/// represents a declaration only, or not.
23792class_or_union::class_or_union(const environment& env, const string& name,
23793 bool is_declaration_only)
23794 : type_or_decl_base(env,
23795 ABSTRACT_TYPE_BASE
23796 | ABSTRACT_DECL_BASE
23797 | ABSTRACT_SCOPE_TYPE_DECL
23798 | ABSTRACT_SCOPE_DECL),
23799 decl_base(env, name, location(), name),
23800 type_base(env, 0, 0),
23801 scope_type_decl(env, name, 0, 0, location()),
23802 priv_(new priv)
23803{
23804 set_is_declaration_only(is_declaration_only);
23805}
23806
23807/// Return the hash value of the current IR node.
23808///
23809/// Note that upon the first invocation, this member functions
23810/// computes the hash value and returns it. Subsequent invocations
23811/// just return the hash value that was previously calculated.
23812///
23813/// @return the hash value of the current IR node.
23814hash_t
23816{
23817 class_or_union::hash do_hash;
23818 hash_t h = do_hash(this);
23819 return h;
23820}
23821
23822/// This implements the ir_traversable_base::traverse pure virtual
23823/// function.
23824///
23825/// @param v the visitor used on the member nodes of the translation
23826/// unit during the traversal.
23827///
23828/// @return true if the entire IR node tree got traversed, false
23829/// otherwise.
23830bool
23832{
23833 if (v.type_node_has_been_visited(this))
23834 return true;
23835
23836 if (visiting())
23837 return true;
23838
23839 if (v.visit_begin(this))
23840 {
23841 visiting(true);
23842 bool stop = false;
23843
23844 if (!stop)
23845 for (data_members::const_iterator i = get_data_members().begin();
23846 i != get_data_members().end();
23847 ++i)
23848 if (!(*i)->traverse(v))
23849 {
23850 stop = true;
23851 break;
23852 }
23853
23854 if (!stop)
23855 for (member_functions::const_iterator i= get_member_functions().begin();
23856 i != get_member_functions().end();
23857 ++i)
23858 if (!(*i)->traverse(v))
23859 {
23860 stop = true;
23861 break;
23862 }
23863
23864 if (!stop)
23865 for (member_types::const_iterator i = get_member_types().begin();
23866 i != get_member_types().end();
23867 ++i)
23868 if (!(*i)->traverse(v))
23869 {
23870 stop = true;
23871 break;
23872 }
23873
23874 if (!stop)
23875 for (member_function_templates::const_iterator i =
23877 i != get_member_function_templates().end();
23878 ++i)
23879 if (!(*i)->traverse(v))
23880 {
23881 stop = true;
23882 break;
23883 }
23884
23885 if (!stop)
23886 for (member_class_templates::const_iterator i =
23888 i != get_member_class_templates().end();
23889 ++i)
23890 if (!(*i)->traverse(v))
23891 {
23892 stop = true;
23893 break;
23894 }
23895 visiting(false);
23896 }
23897
23898 bool result = v.visit_end(this);
23900 return result;
23901}
23902
23903/// Destrcutor of the @ref class_or_union type.
23905{delete priv_;}
23906
23907/// Add a member declaration to the current instance of class_or_union.
23908/// The member declaration can be either a member type, data member,
23909/// member function, or member template.
23910///
23911/// @param d the member declaration to add.
23912decl_base_sptr
23913class_or_union::add_member_decl(const decl_base_sptr& d)
23914{return insert_member_decl(d);}
23915
23916/// Remove a given decl from the current @ref class_or_union scope.
23917///
23918/// Note that only type declarations are supported by this method for
23919/// now. Support for the other kinds of declaration is left as an
23920/// exercise for the interested reader of the code.
23921///
23922/// @param decl the declaration to remove from this @ref
23923/// class_or_union scope.
23924void
23926{
23927 type_base_sptr t = is_type(decl);
23928
23929 // For now we want to support just removing types from classes. For
23930 // other kinds of IR node, we need more work.
23931 ABG_ASSERT(t);
23932
23934}
23935
23936/// Fixup the members of the type of an anonymous data member.
23937///
23938/// Walk all data members of (the type of) a given anonymous data
23939/// member and set a particular property of the relationship between
23940/// each data member and its containing type.
23941///
23942/// That property records the fact that the data member belongs to the
23943/// anonymous data member we consider.
23944///
23945/// In the future, if there are other properties of this relationship
23946/// to set in this manner, they ought to be added here.
23947///
23948/// @param anon_dm the anonymous data member to consider.
23949void
23951{
23952 class_or_union * anon_dm_type =
23954 if (!anon_dm_type)
23955 return;
23956
23957 for (class_or_union::data_members::const_iterator it =
23958 anon_dm_type->get_non_static_data_members().begin();
23959 it != anon_dm_type->get_non_static_data_members().end();
23960 ++it)
23961 {
23962 dm_context_rel *rel =
23963 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
23964 ABG_ASSERT(rel);
23965 rel->set_anonymous_data_member(anon_dm.get());
23966 }
23967}
23968
23969/// Getter of the alignment of the @ref class_or_union type.
23970///
23971/// If this @ref class_or_union is a declaration of a definition that
23972/// is elsewhere, then the size of the definition is returned.
23973///
23974/// @return the alignment of the @ref class_or_union type.
23975size_t
23984
23985/// Setter of the alignment of the class type.
23986///
23987/// If this class is a declaration of a definition that is elsewhere,
23988/// then the new alignment is set to the definition.
23989///
23990/// @param s the new alignment.
23991void
24000
24001/// Setter of the size of the @ref class_or_union type.
24002///
24003/// If this @ref class_or_union is a declaration of a definition that
24004/// is elsewhere, then the new size is set to the definition.
24005///
24006/// @param s the new size.
24007void
24016
24017/// Getter of the size of the @ref class_or_union type.
24018///
24019/// If this @ref class_or_union is a declaration of a definition that
24020/// is elsewhere, then the size of the definition is returned.
24021///
24022/// @return the size of the @ref class_or_union type.
24023size_t
24032
24033/// Get the number of anonymous member classes contained in this
24034/// class.
24035///
24036/// @return the number of anonymous member classes contained in this
24037/// class.
24038size_t
24040{
24041 int result = 0;
24042 for (member_types::const_iterator it = get_member_types().begin();
24043 it != get_member_types().end();
24044 ++it)
24045 if (class_decl_sptr t = is_class_type(*it))
24046 if (t->get_is_anonymous())
24047 ++result;
24048
24049 return result;
24050}
24051
24052/// Get the number of anonymous member unions contained in this class.
24053///
24054/// @return the number of anonymous member unions contained in this
24055/// class.
24056size_t
24058{
24059 int result = 0;
24060 for (member_types::const_iterator it = get_member_types().begin();
24061 it != get_member_types().end();
24062 ++it)
24063 if (union_decl_sptr t = is_union_type(*it))
24064 if (t->get_is_anonymous())
24065 ++result;
24066
24067 return result;
24068}
24069
24070/// Get the number of anonymous member enums contained in this class.
24071///
24072/// @return the number of anonymous member enums contained in this
24073/// class.
24074size_t
24076{
24077 int result = 0;
24078 for (member_types::const_iterator it = get_member_types().begin();
24079 it != get_member_types().end();
24080 ++it)
24081 if (enum_type_decl_sptr t = is_enum_type(*it))
24082 if (t->get_is_anonymous())
24083 ++result;
24084
24085 return result;
24086}
24087
24088/// Add a data member to the current instance of class_or_union.
24089///
24090/// @param v a var_decl to add as a data member. A proper
24091/// class_or_union::data_member is created from @p v and added to the
24092/// class_or_union. This var_decl should not have been already added
24093/// to a scope.
24094///
24095/// @param access the access specifier for the data member.
24096///
24097/// @param is_laid_out whether the data member was laid out. That is,
24098/// if its offset has been computed. In the pattern of a class
24099/// template for instance, this would be set to false.
24100///
24101/// @param is_static whether the data memer is static.
24102///
24103/// @param offset_in_bits if @p is_laid_out is true, this is the
24104/// offset of the data member, expressed (oh, surprise) in bits.
24105void
24107 bool is_laid_out, bool is_static,
24108 size_t offset_in_bits)
24109{
24110 ABG_ASSERT(!has_scope(v));
24111
24112 priv_->data_members_.push_back(v);
24114 set_data_member_is_laid_out(v, is_laid_out);
24115 set_data_member_offset(v, offset_in_bits);
24116 set_member_access_specifier(v, access);
24117 set_member_is_static(v, is_static);
24118
24119 // Add the variable to the set of static or non-static data members,
24120 // if it's not already in there.
24121 bool is_already_in = false;
24122 if (is_static)
24123 {
24124 for (const auto& s_dm: priv_->static_data_members_)
24125 {
24126 if (s_dm == v)
24127 {
24128 is_already_in = true;
24129 break;
24130 }
24131 }
24132 if (!is_already_in)
24133 priv_->static_data_members_.push_back(v);
24134 }
24135 else
24136 {
24137 // If this is a non-static variable, add it to the set of
24138 // non-static variables, if it's not already in there.
24139 for (data_members::const_iterator i =
24140 priv_->non_static_data_members_.begin();
24141 i != priv_->non_static_data_members_.end();
24142 ++i)
24143 if (*i == v)
24144 {
24145 is_already_in = true;
24146 break;
24147 }
24148 if (!is_already_in)
24149 priv_->non_static_data_members_.push_back(v);
24150 }
24151
24152 // If v is an anonymous data member, then fixup its data members.
24153 // For now, the only thing the fixup does is to make the data
24154 // members of the anonymous data member be aware of their containing
24155 // anonymous data member. That is helpful to compute the absolute
24156 // bit offset of each of the members of the anonymous data member.
24158}
24159
24160/// Get the data members of this @ref class_or_union.
24161///
24162/// @return a vector of the data members of this @ref class_or_union.
24165{return priv_->data_members_;}
24166
24167/// Find a data member of a given name in the current @ref class_or_union.
24168///
24169/// @param name the name of the data member to find in the current
24170/// @ref class_or_union.
24171///
24172/// @return a pointer to the @ref var_decl that represents the data
24173/// member to find inside the current @ref class_or_union.
24174const var_decl_sptr
24175class_or_union::find_data_member(const string& name) const
24176{
24177 for (data_members::const_iterator i = get_data_members().begin();
24178 i != get_data_members().end();
24179 ++i)
24180 if ((*i)->get_name() == name)
24181 return *i;
24182
24183 // We haven't found a data member with the name 'name'. Let's look
24184 // closer again, this time in our anonymous data members.
24185 for (data_members::const_iterator i = get_data_members().begin();
24186 i != get_data_members().end();
24187 ++i)
24189 {
24190 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
24191 ABG_ASSERT(type);
24192 if (var_decl_sptr data_member = type->find_data_member(name))
24193 return data_member;
24194 }
24195
24196 return var_decl_sptr();
24197}
24198
24199/// Find an anonymous data member in the class.
24200///
24201/// @param v the anonymous data member to find.
24202///
24203/// @return the anonymous data member found, or nil if none was found.
24204const var_decl_sptr
24206{
24207 if (!v->get_name().empty())
24208 return var_decl_sptr();
24209
24210 for (data_members::const_iterator it = get_non_static_data_members().begin();
24211 it != get_non_static_data_members().end();
24212 ++it)
24213 {
24214 if (is_anonymous_data_member(*it))
24215 if ((*it)->get_pretty_representation(/*internal=*/false, true)
24216 == v->get_pretty_representation(/*internal=*/false, true))
24217 return *it;
24218 }
24219
24220 return var_decl_sptr();
24221}
24222
24223/// Find a given data member.
24224///
24225/// This function takes a @ref var_decl as an argument. If it has a
24226/// non-empty name, then it tries to find a data member which has the
24227/// same name as the argument.
24228///
24229/// If it has an empty name, then the @ref var_decl is considered as
24230/// an anonymous data member. In that case, this function tries to
24231/// find an anonymous data member which type equals that of the @ref
24232/// var_decl argument.
24233///
24234/// @param v this carries either the name of the data member we need
24235/// to look for, or the type of the anonymous data member we are
24236/// looking for.
24237const var_decl_sptr
24239{
24240 if (!v)
24241 return var_decl_sptr();
24242
24243 if (v->get_name().empty())
24245
24246 return find_data_member(v->get_name());
24247}
24248
24249
24250/// Get the non-static data members of this @ref class_or_union.
24251///
24252/// @return a vector of the non-static data members of this @ref
24253/// class_or_union.
24256{return priv_->non_static_data_members_;}
24257
24258/// Get the static data memebers of this @ref class_or_union.
24259///
24260/// @return a vector of the static data members of this @ref
24261/// class_or_union.
24264{return priv_->static_data_members_;}
24265
24266/// Add a member function.
24267///
24268/// @param f the new member function to add.
24269///
24270/// @param a the access specifier to use for the new member function.
24271///
24272/// @param is_static whether the new member function is static.
24273///
24274/// @param is_ctor whether the new member function is a constructor.
24275///
24276/// @param is_dtor whether the new member function is a destructor.
24277///
24278/// @param is_const whether the new member function is const.
24279void
24282 bool is_static, bool is_ctor,
24283 bool is_dtor, bool is_const)
24284{
24285 ABG_ASSERT(!has_scope(f));
24286
24288
24289 set_member_function_is_ctor(f, is_ctor);
24290 set_member_function_is_dtor(f, is_dtor);
24292 set_member_is_static(f, is_static);
24293 set_member_function_is_const(f, is_const);
24294
24295 priv_->member_functions_.push_back(f);
24296
24297 // Update the map of linkage name -> member functions. It's useful,
24298 // so that class_or_union::find_member_function() can function.
24299 if (!f->get_linkage_name().empty())
24300 priv_->mem_fns_map_[f->get_linkage_name()] = f;
24301}
24302
24303/// Get the member functions of this @ref class_or_union.
24304///
24305/// @return a vector of the member functions of this @ref
24306/// class_or_union.
24309{return priv_->member_functions_;}
24310
24311/// Find a method, using its linkage name as a key.
24312///
24313/// @param linkage_name the linkage name of the method to find.
24314///
24315/// @return the method found, or nil if none was found.
24316const method_decl*
24317class_or_union::find_member_function(const string& linkage_name) const
24318{
24319 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
24320}
24321
24322/// Find a method, using its linkage name as a key.
24323///
24324/// @param linkage_name the linkage name of the method to find.
24325///
24326/// @return the method found, or nil if none was found.
24328class_or_union::find_member_function(const string& linkage_name)
24329{
24330 string_mem_fn_sptr_map_type::const_iterator i =
24331 priv_->mem_fns_map_.find(linkage_name);
24332 if (i == priv_->mem_fns_map_.end())
24333 return 0;
24334 return i->second.get();
24335}
24336
24337/// Find a method, using its linkage name as a key.
24338///
24339/// @param linkage_name the linkage name of the method to find.
24340///
24341/// @return the method found, or nil if none was found.
24342method_decl_sptr
24344{
24345 string_mem_fn_sptr_map_type::const_iterator i =
24346 priv_->mem_fns_map_.find(linkage_name);
24347 if (i == priv_->mem_fns_map_.end())
24348 return 0;
24349 return i->second;
24350}
24351
24352/// Find a method (member function) using its signature (pretty
24353/// representation) as a key.
24354///
24355/// @param s the signature of the method.
24356///
24357/// @return the method found, or nil if none was found.
24358const method_decl*
24360{
24361 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
24362}
24363
24364/// Find a method (member function) using its signature (pretty
24365/// representation) as a key.
24366///
24367/// @param s the signature of the method.
24368///
24369/// @return the method found, or nil if none was found.
24372{
24373 string_mem_fn_ptr_map_type::const_iterator i =
24374 priv_->signature_2_mem_fn_map_.find(s);
24375 if (i == priv_->signature_2_mem_fn_map_.end())
24376 return 0;
24377 return i->second;
24378}
24379
24380/// Get the member function templates of this class.
24381///
24382/// @return a vector of the member function templates of this class.
24383const member_function_templates&
24385{return priv_->member_function_templates_;}
24386
24387/// Get the member class templates of this class.
24388///
24389/// @return a vector of the member class templates of this class.
24390const member_class_templates&
24392{return priv_->member_class_templates_;}
24393
24394/// Append a member function template to the @ref class_or_union.
24395///
24396/// @param m the member function template to append.
24397void
24398class_or_union::add_member_function_template(member_function_template_sptr m)
24399{
24400 decl_base* c = m->as_function_tdecl()->get_scope();
24401 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24402 /// error message or something like a structured error.
24403 priv_->member_function_templates_.push_back(m);
24404 if (!c)
24405 scope_decl::add_member_decl(m->as_function_tdecl());
24406}
24407
24408/// Append a member class template to the @ref class_or_union.
24409///
24410/// @param m the member function template to append.
24411void
24413{
24414 decl_base* c = m->as_class_tdecl()->get_scope();
24415 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24416 /// error message or something like a structured error.
24417 m->set_scope(this);
24418 priv_->member_class_templates_.push_back(m);
24419 if (!c)
24420 scope_decl::add_member_decl(m->as_class_tdecl());
24421}
24422
24423///@return true iff the current instance has no member.
24424bool
24426{
24427 return (get_member_types().empty()
24428 && priv_->data_members_.empty()
24429 && priv_->member_functions_.empty()
24430 && priv_->member_function_templates_.empty()
24431 && priv_->member_class_templates_.empty());
24432}
24433
24434/// Insert a data member to this @ref class_or_union type.
24435///
24436/// @param d the data member to insert.
24437///
24438/// @return the decl @p that got inserted.
24439decl_base_sptr
24441{
24442 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
24443 {
24444 add_data_member(v, public_access,
24445 /*is_laid_out=*/false,
24446 /*is_static=*/true,
24447 /*offset_in_bits=*/0);
24448 d = v;
24449 }
24450 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24451 add_member_function(f, public_access,
24452 /*is_static=*/false,
24453 /*is_ctor=*/false,
24454 /*is_dtor=*/false,
24455 /*is_const=*/false);
24456 else if (member_function_template_sptr f =
24457 dynamic_pointer_cast<member_function_template>(d))
24459 else if (member_class_template_sptr c =
24460 dynamic_pointer_cast<member_class_template>(d))
24462 else
24464
24465 return d;
24466}
24467
24468/// Equality operator.
24469///
24470/// @param other the other @ref class_or_union to compare against.
24471///
24472/// @return true iff @p other equals the current @ref class_or_union.
24473bool
24475{
24476 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
24477 if (!op)
24478 return false;
24479
24480 // If this is a decl-only type (and thus with no canonical type),
24481 // use the canonical type of the definition, if any.
24482 const class_or_union *l = 0;
24484 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
24485 if (l == 0)
24486 l = this;
24487
24488 // Likewise for the other class.
24489 const class_or_union *r = 0;
24490 if (op->get_is_declaration_only())
24491 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
24492 if (r == 0)
24493 r = op;
24494
24495 return try_canonical_compare(l, r);
24496}
24497
24498/// Equality operator.
24499///
24500/// @param other the other @ref class_or_union to compare against.
24501///
24502/// @return true iff @p other equals the current @ref class_or_union.
24503bool
24505{
24506 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24507 if (!o)
24508 return false;
24509 return *this == *o;
24510}
24511
24512/// Equality operator.
24513///
24514/// @param other the other @ref class_or_union to compare against.
24515///
24516/// @return true iff @p other equals the current @ref class_or_union.
24517bool
24518class_or_union::operator==(const class_or_union& other) const
24519{
24520 const decl_base& o = other;
24522}
24523
24524/// Compares two instances of @ref class_or_union.
24525///
24526/// If the two intances are different, set a bitfield to give some
24527/// insight about the kind of differences there are.
24528///
24529/// @param l the first artifact of the comparison.
24530///
24531/// @param r the second artifact of the comparison.
24532///
24533/// @param k a pointer to a bitfield that gives information about the
24534/// kind of changes there are between @p l and @p r. This one is set
24535/// iff it's non-null and if the function returns false.
24536///
24537/// Please note that setting k to a non-null value does have a
24538/// negative performance impact because even if @p l and @p r are not
24539/// equal, the function keeps up the comparison in order to determine
24540/// the different kinds of ways in which they are different.
24541///
24542/// @return true if @p l equals @p r, false otherwise.
24543bool
24544equals(const class_or_union& l, const class_or_union& r, change_kind* k)
24545{
24546 // if one of the classes is declaration-only, look through it to
24547 // get its definition.
24548 bool l_is_decl_only = l.get_is_declaration_only();
24549 bool r_is_decl_only = r.get_is_declaration_only();
24550 if (l_is_decl_only || r_is_decl_only)
24551 {
24552 const class_or_union* def1 = l_is_decl_only
24554 : &l;
24555
24556 const class_or_union* def2 = r_is_decl_only
24558 : &r;
24559
24560 if (!def1 || !def2)
24561 {
24562 if (!l.get_is_anonymous()
24563 && !r.get_is_anonymous()
24564 && l_is_decl_only && r_is_decl_only
24566 // The two decl-only classes differ from their size. A
24567 // true decl-only class should not have a size property to
24568 // begin with. This comes from a DWARF oddity and can
24569 // results in a false positive, so let's not consider that
24570 // change.
24571 return true;
24572
24576 {
24577 const interned_string& q1 = l.get_scoped_name();
24578 const interned_string& q2 = r.get_scoped_name();
24579 if (q1 == q2)
24580 // Not using RETURN(true) here, because that causes
24581 // performance issues. We don't need to do
24582 // l.priv_->unmark_as_being_compared({l,r}) here because
24583 // we haven't marked l or r as being compared yet, and
24584 // doing so has a peformance cost that shows up on
24585 // performance profiles for *big* libraries.
24586 return true;
24587 else
24588 {
24589 if (k)
24591 // Not using RETURN(true) here, because that causes
24592 // performance issues. We don't need to do
24593 // l.priv_->unmark_as_being_compared({l,r}) here because
24594 // we haven't marked l or r as being compared yet, and
24595 // doing so has a peformance cost that shows up on
24596 // performance profiles for *big* libraries.
24598 }
24599 }
24600 else // A decl-only class is considered different from a
24601 // class definition of the same name.
24602 {
24603 if (!!def1 != !!def2)
24604 {
24605 if (k)
24608 }
24609
24610 // both definitions are empty
24611 if (!(l.decl_base::operator==(r)
24612 && l.type_base::operator==(r)))
24613 {
24614 if (k)
24617 }
24618
24619 return true;
24620 }
24621 }
24622
24623 bool val = *def1 == *def2;
24624 if (!val)
24625 if (k)
24627 ABG_RETURN(val);
24628 }
24629
24630 // No need to go further if the classes have different names or
24631 // different size / alignment.
24632 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
24633 {
24634 if (k)
24637 }
24638
24639 if (types_defined_same_linux_kernel_corpus_public(l, r))
24640 return true;
24641
24642 //TODO: Maybe remove this (cycle detection and canonical type
24643 //propagation handling) from here and have it only in the equal
24644 //overload for class_decl and union_decl because this one ( the
24645 //equal overload for class_or_union) is just a sub-routine of these
24646 //two above.
24647#define RETURN(value) \
24648 return return_comparison_result(l, r, value);
24649
24651
24653
24654 bool result = true;
24655
24656 //compare data_members
24657 {
24658 if (l.get_non_static_data_members().size()
24659 != r.get_non_static_data_members().size())
24660 {
24661 result = false;
24662 if (k)
24664 else
24665 RETURN(result);
24666 }
24667
24668 for (class_or_union::data_members::const_iterator
24669 d0 = l.get_non_static_data_members().begin(),
24670 d1 = r.get_non_static_data_members().begin();
24671 (d0 != l.get_non_static_data_members().end()
24672 && d1 != r.get_non_static_data_members().end());
24673 ++d0, ++d1)
24674 if (**d0 != **d1)
24675 {
24676 result = false;
24677 if (k)
24678 {
24679 // Report any representation change as being local.
24680 if (!types_have_similar_structure((*d0)->get_type(),
24681 (*d1)->get_type())
24682 || (*d0)->get_type() == (*d1)->get_type())
24684 else
24685 *k |= SUBTYPE_CHANGE_KIND;
24686 }
24687 else
24688 RETURN(result);
24689 }
24690 }
24691
24692 // Do not compare member functions. DWARF does not necessarily
24693 // all the member functions, be they virtual or not, in all
24694 // translation units. So we cannot have a clear view of them, per
24695 // class
24696
24697 // compare member function templates
24698 {
24699 if (l.get_member_function_templates().size()
24700 != r.get_member_function_templates().size())
24701 {
24702 result = false;
24703 if (k)
24705 else
24706 RETURN(result);
24707 }
24708
24709 for (member_function_templates::const_iterator
24710 fn_tmpl_it0 = l.get_member_function_templates().begin(),
24711 fn_tmpl_it1 = r.get_member_function_templates().begin();
24712 fn_tmpl_it0 != l.get_member_function_templates().end()
24713 && fn_tmpl_it1 != r.get_member_function_templates().end();
24714 ++fn_tmpl_it0, ++fn_tmpl_it1)
24715 if (**fn_tmpl_it0 != **fn_tmpl_it1)
24716 {
24717 result = false;
24718 if (k)
24719 {
24721 break;
24722 }
24723 else
24724 RETURN(result);
24725 }
24726 }
24727
24728 // compare member class templates
24729 {
24730 if (l.get_member_class_templates().size()
24731 != r.get_member_class_templates().size())
24732 {
24733 result = false;
24734 if (k)
24736 else
24737 RETURN(result);
24738 }
24739
24740 for (member_class_templates::const_iterator
24741 cl_tmpl_it0 = l.get_member_class_templates().begin(),
24742 cl_tmpl_it1 = r.get_member_class_templates().begin();
24743 cl_tmpl_it0 != l.get_member_class_templates().end()
24744 && cl_tmpl_it1 != r.get_member_class_templates().end();
24745 ++cl_tmpl_it0, ++cl_tmpl_it1)
24746 if (**cl_tmpl_it0 != **cl_tmpl_it1)
24747 {
24748 result = false;
24749 if (k)
24750 {
24752 break;
24753 }
24754 else
24755 RETURN(result);
24756 }
24757 }
24758
24759 RETURN(result);
24760#undef RETURN
24761}
24762
24763
24764/// Copy a method of a @ref class_or_union into a new @ref
24765/// class_or_union.
24766///
24767/// @param t the @ref class_or_union into which the method is to be copied.
24768///
24769/// @param method the method to copy into @p t.
24770///
24771/// @return the resulting newly copied method.
24772method_decl_sptr
24773copy_member_function(class_or_union_sptr t,
24774 const method_decl_sptr& method)
24775{return copy_member_function(t, method.get());}
24776
24777
24778/// Copy a method of a @ref class_or_union into a new @ref
24779/// class_or_union.
24780///
24781/// @param t the @ref class_or_union into which the method is to be copied.
24782///
24783/// @param method the method to copy into @p t.
24784///
24785/// @return the resulting newly copied method.
24786method_decl_sptr
24787copy_member_function(class_or_union_sptr t, const method_decl* method)
24788{
24789 ABG_ASSERT(t);
24790 ABG_ASSERT(method);
24791
24792 method_type_sptr old_type = method->get_type();
24793 ABG_ASSERT(old_type);
24794 method_type_sptr new_type(new method_type(old_type->get_return_type(),
24795 t,
24796 old_type->get_parameters(),
24797 old_type->get_is_const(),
24798 old_type->get_size_in_bits(),
24799 old_type->get_alignment_in_bits()));
24800 t->get_translation_unit()->bind_function_type_life_time(new_type);
24801
24802 method_decl_sptr
24803 new_method(new method_decl(method->get_name(),
24804 new_type,
24805 method->is_declared_inline(),
24806 method->get_location(),
24807 method->get_linkage_name(),
24808 method->get_visibility(),
24809 method->get_binding()));
24810 new_method->set_symbol(method->get_symbol());
24811
24812 if (class_decl_sptr class_type = is_class_type(t))
24813 class_type->add_member_function(new_method,
24817 get_member_is_static(*method),
24821 else
24822 t->add_member_function(new_method,
24824 get_member_is_static(*method),
24828 return new_method;
24829}
24830
24831/// Copy a data member of a @ref class_or_union into a new @ref
24832/// class_or_union.
24833///
24834/// @param t the @ref class_or_union into which the data member is to
24835/// be copied.
24836///
24837/// @param variable the data member to copy into @p t.
24838///
24839/// @return the resulting newly copied method.
24841copy_member_variable(class_or_union_sptr t, const var_decl* variable)
24842{
24843 ABG_ASSERT(variable);
24844 ABG_ASSERT(is_data_member(variable));
24845 ABG_ASSERT(t);
24846 ABG_ASSERT(!t->find_data_member(variable->get_name()));
24847
24848 type_base_sptr old_type = variable->get_type();
24849
24850 var_decl_sptr new_variable(new var_decl(variable->get_name(),
24851 old_type,
24852 variable->get_location(),
24853 variable->get_linkage_name(),
24854 variable->get_visibility(),
24855 variable->get_binding()));
24856
24857 size_t offset_in_bits = 0;
24858 if (get_data_member_is_laid_out(*variable))
24859 offset_in_bits = get_data_member_offset(*variable);
24860
24861 t->add_data_member(new_variable,
24862 get_member_access_specifier(*variable),
24863 get_data_member_is_laid_out(*variable),
24864 get_member_is_static(*variable),
24865 offset_in_bits);
24866
24867 return new_variable;
24868}
24869
24870/// Copy a data member of a @ref class_or_union into a new @ref
24871/// class_or_union.
24872///
24873/// @param t the @ref class_or_union into which the data member is to
24874/// be copied.
24875///
24876/// @param variable the data member to copy into @p t.
24877///
24878/// @return the resulting newly copied method.
24880copy_member_variable(class_or_union_sptr t, const var_decl_sptr& variable)
24881{return copy_member_variable(t, variable.get());}
24882
24883/// Copy a data member of a @ref class_or_union into a new @ref
24884/// class_or_union.
24885///
24886/// @param t the @ref class_or_union into which the data member is to
24887/// be copied.
24888///
24889/// @param variable the data member to copy into @p t.
24890///
24891/// @return the resulting newly copied method.
24894{return copy_member_variable(static_pointer_cast<class_or_union>(t), variable);}
24895// </class_or_union definitions>
24896
24897// <class_decl definitions>
24898
24899static void
24900sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24901
24902/// The private data for the class_decl type.
24903struct class_decl::priv
24904{
24905 base_specs bases_;
24906 unordered_map<string, base_spec_sptr> bases_map_;
24907 member_functions virtual_mem_fns_;
24908 virtual_mem_fn_map_type virtual_mem_fns_map_;
24909 bool is_struct_;
24910
24911 priv()
24912 : is_struct_(false)
24913 {}
24914
24915 priv(bool is_struct, class_decl::base_specs& bases)
24916 : bases_(bases),
24917 is_struct_(is_struct)
24918 {
24919 }
24920
24921 priv(bool is_struct)
24922 : is_struct_(is_struct)
24923 {}
24924};// end struct class_decl::priv
24925
24926/// A Constructor for instances of \ref class_decl
24927///
24928/// @param env the environment we are operating from.
24929///
24930/// @param name the identifier of the class.
24931///
24932/// @param size_in_bits the size of an instance of class_decl, expressed
24933/// in bits
24934///
24935/// @param align_in_bits the alignment of an instance of class_decl,
24936/// expressed in bits.
24937///
24938/// @param locus the source location of declaration point this class.
24939///
24940/// @param vis the visibility of instances of class_decl.
24941///
24942/// @param bases the vector of base classes for this instance of class_decl.
24943///
24944/// @param mbrs the vector of member types of this instance of
24945/// class_decl.
24946///
24947/// @param data_mbrs the vector of data members of this instance of
24948/// class_decl.
24949///
24950/// @param mbr_fns the vector of member functions of this instance of
24951/// class_decl.
24952class_decl::class_decl(const environment& env, const string& name,
24953 size_t size_in_bits, size_t align_in_bits,
24954 bool is_struct, const location& locus,
24955 visibility vis, base_specs& bases,
24956 member_types& mbr_types,
24957 data_members& data_mbrs,
24958 member_functions& mbr_fns)
24959 : type_or_decl_base(env,
24960 CLASS_TYPE
24961 | ABSTRACT_TYPE_BASE
24962 | ABSTRACT_DECL_BASE
24963 | ABSTRACT_SCOPE_TYPE_DECL
24964 | ABSTRACT_SCOPE_DECL),
24965 decl_base(env, name, locus, name, vis),
24966 type_base(env, size_in_bits, align_in_bits),
24967 class_or_union(env, name, size_in_bits, align_in_bits,
24968 locus, vis, mbr_types, data_mbrs, mbr_fns),
24969 priv_(new priv(is_struct, bases))
24970{
24972}
24973
24974/// A Constructor for instances of @ref class_decl
24975///
24976/// @param env the environment we are operating from.
24977///
24978/// @param name the identifier of the class.
24979///
24980/// @param size_in_bits the size of an instance of class_decl, expressed
24981/// in bits
24982///
24983/// @param align_in_bits the alignment of an instance of class_decl,
24984/// expressed in bits.
24985///
24986/// @param locus the source location of declaration point this class.
24987///
24988/// @param vis the visibility of instances of class_decl.
24989///
24990/// @param bases the vector of base classes for this instance of class_decl.
24991///
24992/// @param mbrs the vector of member types of this instance of
24993/// class_decl.
24994///
24995/// @param data_mbrs the vector of data members of this instance of
24996/// class_decl.
24997///
24998/// @param mbr_fns the vector of member functions of this instance of
24999/// class_decl.
25000///
25001/// @param is_anonymous whether the newly created instance is
25002/// anonymous.
25003class_decl::class_decl(const environment& env, const string& name,
25004 size_t size_in_bits, size_t align_in_bits,
25005 bool is_struct, const location& locus,
25006 visibility vis, base_specs& bases,
25007 member_types& mbr_types, data_members& data_mbrs,
25008 member_functions& mbr_fns, bool is_anonymous)
25009 : type_or_decl_base(env,
25010 CLASS_TYPE
25011 | ABSTRACT_TYPE_BASE
25012 | ABSTRACT_DECL_BASE
25013 | ABSTRACT_SCOPE_TYPE_DECL
25014 | ABSTRACT_SCOPE_DECL),
25015 decl_base(env, name, locus,
25016 // If the class is anonymous then by default it won't
25017 // have a linkage name. Also, the anonymous class does
25018 // have an internal-only unique name that is generally
25019 // not taken into account when comparing classes; such a
25020 // unique internal-only name, when used as a linkage
25021 // name might introduce spurious comparison false
25022 // negatives.
25023 /*linkage_name=*/is_anonymous ? string() : name,
25024 vis),
25025 type_base(env, size_in_bits, align_in_bits),
25026 class_or_union(env, name, size_in_bits, align_in_bits,
25027 locus, vis, mbr_types, data_mbrs, mbr_fns),
25028 priv_(new priv(is_struct, bases))
25029{
25031 set_is_anonymous(is_anonymous);
25032}
25033
25034/// A constructor for instances of class_decl.
25035///
25036/// @param env the environment we are operating from.
25037///
25038/// @param name the name of the class.
25039///
25040/// @param size_in_bits the size of an instance of class_decl, expressed
25041/// in bits
25042///
25043/// @param align_in_bits the alignment of an instance of class_decl,
25044/// expressed in bits.
25045///
25046/// @param locus the source location of declaration point this class.
25047///
25048/// @param vis the visibility of instances of class_decl.
25049class_decl::class_decl(const environment& env, const string& name,
25050 size_t size_in_bits, size_t align_in_bits,
25051 bool is_struct, const location& locus,
25052 visibility vis)
25053 : type_or_decl_base(env,
25054 CLASS_TYPE
25055 | ABSTRACT_TYPE_BASE
25056 | ABSTRACT_DECL_BASE
25057 | ABSTRACT_SCOPE_TYPE_DECL
25058 | ABSTRACT_SCOPE_DECL),
25059 decl_base(env, name, locus, name, vis),
25060 type_base(env, size_in_bits, align_in_bits),
25061 class_or_union(env, name, size_in_bits, align_in_bits,
25062 locus, vis),
25063 priv_(new priv(is_struct))
25064{
25066}
25067
25068/// A constructor for instances of @ref class_decl.
25069///
25070/// @param env the environment we are operating from.
25071///
25072/// @param name the name of the class.
25073///
25074/// @param size_in_bits the size of an instance of class_decl, expressed
25075/// in bits
25076///
25077/// @param align_in_bits the alignment of an instance of class_decl,
25078/// expressed in bits.
25079///
25080/// @param locus the source location of declaration point this class.
25081///
25082/// @param vis the visibility of instances of class_decl.
25083///
25084/// @param is_anonymous whether the newly created instance is
25085/// anonymous.
25086class_decl:: class_decl(const environment& env, const string& name,
25087 size_t size_in_bits, size_t align_in_bits,
25088 bool is_struct, const location& locus,
25089 visibility vis, bool is_anonymous)
25090 : type_or_decl_base(env,
25091 CLASS_TYPE
25092 | ABSTRACT_TYPE_BASE
25093 | ABSTRACT_DECL_BASE
25094 | ABSTRACT_SCOPE_TYPE_DECL
25095 | ABSTRACT_SCOPE_DECL),
25096 decl_base(env, name, locus,
25097 // If the class is anonymous then by default it won't
25098 // have a linkage name. Also, the anonymous class does
25099 // have an internal-only unique name that is generally
25100 // not taken into account when comparing classes; such a
25101 // unique internal-only name, when used as a linkage
25102 // name might introduce spurious comparison false
25103 // negatives.
25104 /*linkage_name=*/ is_anonymous ? string() : name,
25105 vis),
25106 type_base(env, size_in_bits, align_in_bits),
25107 class_or_union(env, name, size_in_bits, align_in_bits,
25108 locus, vis),
25109 priv_(new priv(is_struct))
25110{
25112 set_is_anonymous(is_anonymous);
25113}
25114
25115/// A constuctor for instances of class_decl that represent a
25116/// declaration without definition.
25117///
25118/// @param env the environment we are operating from.
25119///
25120/// @param name the name of the class.
25121///
25122/// @param is_declaration_only a boolean saying whether the instance
25123/// represents a declaration only, or not.
25124class_decl::class_decl(const environment& env, const string& name,
25125 bool is_struct, bool is_declaration_only)
25126 : type_or_decl_base(env,
25127 CLASS_TYPE
25128 | ABSTRACT_TYPE_BASE
25129 | ABSTRACT_DECL_BASE
25130 | ABSTRACT_SCOPE_TYPE_DECL
25131 | ABSTRACT_SCOPE_DECL),
25132 decl_base(env, name, location(), name),
25133 type_base(env, 0, 0),
25134 class_or_union(env, name, is_declaration_only),
25135 priv_(new priv(is_struct))
25136{
25138}
25139
25140/// This method is invoked automatically right after the current
25141/// instance of @ref class_decl has been canonicalized.
25142///
25143/// Currently, the only thing it does is to sort the virtual member
25144/// functions vector.
25145void
25147{
25149
25150 for (class_decl::virtual_mem_fn_map_type::iterator i =
25151 priv_->virtual_mem_fns_map_.begin();
25152 i != priv_->virtual_mem_fns_map_.end();
25153 ++i)
25154 sort_virtual_member_functions(i->second);
25155}
25156
25157/// Set the "is-struct" flag of the class.
25158///
25159/// @param f the new value of the flag.
25160void
25162{priv_->is_struct_ = f;}
25163
25164/// Test if the class is a struct.
25165///
25166/// @return true iff the class is a struct.
25167bool
25169{return priv_->is_struct_;}
25170
25171/// Add a base specifier to this class.
25172///
25173/// @param b the new base specifier.
25174void
25176{
25177 priv_->bases_.push_back(b);
25178 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
25179}
25180
25181/// Get the base specifiers for this class.
25182///
25183/// @return a vector of the base specifiers.
25186{return priv_->bases_;}
25187
25188/// Find a base class of a given qualified name for the current class.
25189///
25190/// @param qualified_name the qualified name of the base class to look for.
25191///
25192/// @return a pointer to the @ref class_decl that represents the base
25193/// class of name @p qualified_name, if found.
25195class_decl::find_base_class(const string& qualified_name) const
25196{
25197 unordered_map<string, base_spec_sptr>::iterator i =
25198 priv_->bases_map_.find(qualified_name);
25199
25200 if (i != priv_->bases_map_.end())
25201 return i->second->get_base_class();
25202
25203 return class_decl_sptr();
25204}
25205
25206/// Get the virtual member functions of this class.
25207///
25208/// @param return a vector of the virtual member functions of this
25209/// class.
25212{return priv_->virtual_mem_fns_;}
25213
25214/// Get the map that associates a virtual table offset to the virtual
25215/// member functions with that virtual table offset.
25216///
25217/// Usually, there should be a 1:1 mapping between a given vtable
25218/// offset and virtual member functions of that vtable offset. But
25219/// because of some implementation details, there can be several C++
25220/// destructor functions that are *generated* by compilers, for a
25221/// given destructor that is defined in the source code. If the
25222/// destructor is virtual then those generated functions have some
25223/// DWARF attributes in common with the constructor that the user
25224/// actually defined in its source code. Among those attributes are
25225/// the vtable offset of the destructor.
25226///
25227/// @return the map that associates a virtual table offset to the
25228/// virtual member functions with that virtual table offset.
25231{return priv_->virtual_mem_fns_map_;}
25232
25233/// Sort the virtual member functions by their virtual index.
25234void
25236{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
25237
25238/// Getter of the pretty representation of the current instance of
25239/// @ref class_decl.
25240///
25241/// @param internal set to true if the call is intended to get a
25242/// representation of the decl (or type) for the purpose of canonical
25243/// type comparison. This is mainly used in the function
25244/// type_base::get_canonical_type_for().
25245///
25246/// In other words if the argument for this parameter is true then the
25247/// call is meant for internal use (for technical use inside the
25248/// library itself), false otherwise. If you don't know what this is
25249/// for, then set it to false.
25250///
25251/// @param qualified_name if true, names emitted in the pretty
25252/// representation are fully qualified.
25253///
25254/// @return the pretty representaion for a class_decl.
25255string
25257 bool qualified_name) const
25258{
25259 string cl = "class ";
25260 if (!internal && is_struct())
25261 cl = "struct ";
25262
25263 // When computing the pretty representation for internal purposes,
25264 // if an anonymous class is named by a typedef, then consider that
25265 // it has a name, which is the typedef name.
25266 if (get_is_anonymous())
25267 {
25268 if (internal && !get_name().empty())
25269 return cl + get_type_name(this, qualified_name, /*internal=*/true);
25271 /*one_line=*/true,
25272 internal);
25273
25274 }
25275
25276 string result = cl;
25277 if (qualified_name)
25278 result += get_qualified_name(internal);
25279 else
25280 result += get_name();
25281
25282 return result;
25283}
25284
25285decl_base_sptr
25286class_decl::insert_member_decl(decl_base_sptr d)
25287{
25288 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
25289 add_member_function(f, public_access,
25290 /*is_virtual=*/false,
25291 /*vtable_offset=*/0,
25292 /*is_static=*/false,
25293 /*is_ctor=*/false,
25294 /*is_dtor=*/false,
25295 /*is_const=*/false);
25296 else
25298
25299 return d;
25300}
25301
25302/// The private data structure of class_decl::base_spec.
25303struct class_decl::base_spec::priv
25304{
25305 class_decl_wptr base_class_;
25306 long offset_in_bits_;
25307 bool is_virtual_;
25308
25309 priv(const class_decl_sptr& cl,
25310 long offset_in_bits,
25311 bool is_virtual)
25312 : base_class_(cl),
25313 offset_in_bits_(offset_in_bits),
25314 is_virtual_(is_virtual)
25315 {}
25316};
25317
25318/// Constructor for base_spec instances.
25319///
25320/// @param base the base class to consider
25321///
25322/// @param a the access specifier of the base class.
25323///
25324/// @param offset_in_bits if positive or null, represents the offset
25325/// of the base in the layout of its containing type.. If negative,
25326/// means that the current base is not laid out in its containing type.
25327///
25328/// @param is_virtual if true, means that the current base class is
25329/// virtual in it's containing type.
25330class_decl::base_spec::base_spec(const class_decl_sptr& base,
25332 long offset_in_bits,
25333 bool is_virtual)
25334 : type_or_decl_base(base->get_environment(),
25335 ABSTRACT_DECL_BASE),
25336 decl_base(base->get_environment(), base->get_name(), base->get_location(),
25337 base->get_linkage_name(), base->get_visibility()),
25338 member_base(a),
25339 priv_(new priv(base, offset_in_bits, is_virtual))
25340{
25342 set_qualified_name(base->get_qualified_name());
25343}
25344
25345/// Return the hash value of the current IR node.
25346///
25347/// Note that upon the first invocation, this member functions
25348/// computes the hash value and returns it. Subsequent invocations
25349/// just return the hash value that was previously calculated.
25350///
25351/// @return the hash value of the current IR node.
25352hash_t
25354{
25356 return h;
25357}
25358
25359/// Get the base class referred to by the current base class
25360/// specifier.
25361///
25362/// @return the base class.
25365{return priv_->base_class_.lock();}
25366
25367/// Getter of the "is-virtual" proprerty of the base class specifier.
25368///
25369/// @return true iff this specifies a virtual base class.
25370bool
25372{return priv_->is_virtual_;}
25373
25374/// Getter of the offset of the base.
25375///
25376/// @return the offset of the base.
25377long
25379{return priv_->offset_in_bits_;}
25380
25381/// Traverses an instance of @ref class_decl::base_spec, visiting all
25382/// the sub-types and decls that it might contain.
25383///
25384/// @param v the visitor that is used to visit every IR sub-node of
25385/// the current node.
25386///
25387/// @return true if either
25388/// - all the children nodes of the current IR node were traversed
25389/// and the calling code should keep going with the traversing.
25390/// - or the current IR node is already being traversed.
25391/// Otherwise, returning false means that the calling code should not
25392/// keep traversing the tree.
25393bool
25395{
25396 if (visiting())
25397 return true;
25398
25399 if (v.visit_begin(this))
25400 {
25401 visiting(true);
25402 get_base_class()->traverse(v);
25403 visiting(false);
25404 }
25405
25406 return v.visit_end(this);
25407}
25408
25409/// Constructor for base_spec instances.
25410///
25411/// Note that this constructor is for clients that don't support RTTI
25412/// and that have a base class of type_base, but of dynamic type
25413/// class_decl.
25414///
25415/// @param base the base class to consider. Must be a pointer to an
25416/// instance of class_decl
25417///
25418/// @param a the access specifier of the base class.
25419///
25420/// @param offset_in_bits if positive or null, represents the offset
25421/// of the base in the layout of its containing type.. If negative,
25422/// means that the current base is not laid out in its containing type.
25423///
25424/// @param is_virtual if true, means that the current base class is
25425/// virtual in it's containing type.
25426class_decl::base_spec::base_spec(const type_base_sptr& base,
25428 long offset_in_bits,
25429 bool is_virtual)
25430 : type_or_decl_base(base->get_environment(),
25431 ABSTRACT_DECL_BASE),
25432 decl_base(base->get_environment(), get_type_declaration(base)->get_name(),
25436 member_base(a),
25437 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
25438 offset_in_bits,
25439 is_virtual))
25440{
25442}
25443
25444class_decl::base_spec::~base_spec() = default;
25445
25446/// Compares two instances of @ref class_decl::base_spec.
25447///
25448/// If the two intances are different, set a bitfield to give some
25449/// insight about the kind of differences there are.
25450///
25451/// @param l the first artifact of the comparison.
25452///
25453/// @param r the second artifact of the comparison.
25454///
25455/// @param k a pointer to a bitfield that gives information about the
25456/// kind of changes there are between @p l and @p r. This one is set
25457/// iff @p k is non-null and the function returns false.
25458///
25459/// Please note that setting k to a non-null value does have a
25460/// negative performance impact because even if @p l and @p r are not
25461/// equal, the function keeps up the comparison in order to determine
25462/// the different kinds of ways in which they are different.
25463///
25464/// @return true if @p l equals @p r, false otherwise.
25465bool
25467 const class_decl::base_spec& r,
25468 change_kind* k)
25469{
25470 if (!l.member_base::operator==(r))
25471 {
25472 if (k)
25475 }
25476
25478}
25479
25480/// Comparison operator for @ref class_decl::base_spec.
25481///
25482/// @param other the instance of @ref class_decl::base_spec to compare
25483/// against.
25484///
25485/// @return true if the current instance of @ref class_decl::base_spec
25486/// equals @p other.
25487bool
25488class_decl::base_spec::operator==(const decl_base& other) const
25489{
25490 const class_decl::base_spec* o =
25491 dynamic_cast<const class_decl::base_spec*>(&other);
25492
25493 if (!o)
25494 return false;
25495
25496 return equals(*this, *o, 0);
25497}
25498
25499/// Comparison operator for @ref class_decl::base_spec.
25500///
25501/// @param other the instance of @ref class_decl::base_spec to compare
25502/// against.
25503///
25504/// @return true if the current instance of @ref class_decl::base_spec
25505/// equals @p other.
25506bool
25507class_decl::base_spec::operator==(const member_base& other) const
25508{
25509 const class_decl::base_spec* o =
25510 dynamic_cast<const class_decl::base_spec*>(&other);
25511 if (!o)
25512 return false;
25513
25514 return operator==(static_cast<const decl_base&>(*o));
25515}
25516
25517mem_fn_context_rel::~mem_fn_context_rel()
25518{
25519}
25520
25521/// A constructor for instances of method_decl.
25522///
25523/// @param name the name of the method.
25524///
25525/// @param type the type of the method.
25526///
25527/// @param declared_inline whether the method was
25528/// declared inline or not.
25529///
25530/// @param locus the source location of the method.
25531///
25532/// @param linkage_name the mangled name of the method.
25533///
25534/// @param vis the visibility of the method.
25535///
25536/// @param bind the binding of the method.
25537method_decl::method_decl(const string& name,
25538 method_type_sptr type,
25539 bool declared_inline,
25540 const location& locus,
25541 const string& linkage_name,
25542 visibility vis,
25543 binding bind)
25545 METHOD_DECL
25546 | ABSTRACT_DECL_BASE
25547 |FUNCTION_DECL),
25548 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25549 function_decl(name, static_pointer_cast<function_type>(type),
25550 declared_inline, locus, linkage_name, vis, bind)
25551{
25553 set_context_rel(new mem_fn_context_rel(0));
25554 set_member_function_is_const(*this, type->get_is_const());
25555}
25556
25557/// A constructor for instances of method_decl.
25558///
25559/// @param name the name of the method.
25560///
25561/// @param type the type of the method. Must be an instance of
25562/// method_type.
25563///
25564/// @param declared_inline whether the method was
25565/// declared inline or not.
25566///
25567/// @param locus the source location of the method.
25568///
25569/// @param linkage_name the mangled name of the method.
25570///
25571/// @param vis the visibility of the method.
25572///
25573/// @param bind the binding of the method.
25574method_decl::method_decl(const string& name,
25575 function_type_sptr type,
25576 bool declared_inline,
25577 const location& locus,
25578 const string& linkage_name,
25579 visibility vis,
25580 binding bind)
25582 METHOD_DECL
25583 | ABSTRACT_DECL_BASE
25584 | FUNCTION_DECL),
25585 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25586 function_decl(name, static_pointer_cast<function_type>
25587 (dynamic_pointer_cast<method_type>(type)),
25588 declared_inline, locus, linkage_name, vis, bind)
25589{
25591 set_context_rel(new mem_fn_context_rel(0));
25592}
25593
25594/// A constructor for instances of method_decl.
25595///
25596/// @param name the name of the method.
25597///
25598/// @param type the type of the method. Must be an instance of
25599/// method_type.
25600///
25601/// @param declared_inline whether the method was
25602/// declared inline or not.
25603///
25604/// @param locus the source location of the method.
25605///
25606/// @param linkage_name the mangled name of the method.
25607///
25608/// @param vis the visibility of the method.
25609///
25610/// @param bind the binding of the method.
25611method_decl::method_decl(const string& name,
25612 type_base_sptr type,
25613 bool declared_inline,
25614 const location& locus,
25615 const string& linkage_name,
25616 visibility vis,
25617 binding bind)
25619 METHOD_DECL
25620 | ABSTRACT_DECL_BASE
25621 | FUNCTION_DECL),
25622 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25623 function_decl(name, static_pointer_cast<function_type>
25624 (dynamic_pointer_cast<method_type>(type)),
25625 declared_inline, locus, linkage_name, vis, bind)
25626{
25628 set_context_rel(new mem_fn_context_rel(0));
25629}
25630
25631/// Set the linkage name of the method.
25632///
25633/// @param l the new linkage name of the method.
25634void
25636{
25637 string old_lname = get_linkage_name();
25639 // Update the linkage_name -> member function map of the containing
25640 // class declaration.
25641 if (!l.empty())
25642 {
25644 class_or_union_sptr cl = t->get_class_type();
25645 method_decl_sptr m(this, sptr_utils::noop_deleter());
25646 cl->priv_->mem_fns_map_[l] = m;
25647 if (!old_lname.empty() && l != old_lname)
25648 {
25649 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
25650 {
25651 ABG_ASSERT(m.get() == this);
25652 cl->priv_->mem_fns_map_.erase(old_lname);
25653 }
25654 }
25655 }
25656}
25657
25658method_decl::~method_decl()
25659{}
25660
25661const method_type_sptr
25663{
25664 method_type_sptr result;
25666 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
25667 return result;
25668}
25669
25670/// Set the containing class of a method_decl.
25671///
25672/// @param scope the new containing class_decl.
25673void
25674method_decl::set_scope(scope_decl* scope)
25675{
25676 if (!get_context_rel())
25677 set_context_rel(new mem_fn_context_rel(scope));
25678 else
25679 get_context_rel()->set_scope(scope);
25680}
25681
25682/// Equality operator for @ref method_decl_sptr.
25683///
25684/// This is a deep equality operator, as it compares the @ref
25685/// method_decl that is pointed-to by the smart pointer.
25686///
25687/// @param l the left-hand side argument of the equality operator.
25688///
25689/// @param r the righ-hand side argument of the equality operator.
25690///
25691/// @return true iff @p l equals @p r.
25692bool
25693operator==(const method_decl_sptr& l, const method_decl_sptr& r)
25694{
25695 if (l.get() == r.get())
25696 return true;
25697 if (!!l != !!r)
25698 return false;
25699
25700 return *l == *r;
25701}
25702
25703/// Inequality operator for @ref method_decl_sptr.
25704///
25705/// This is a deep equality operator, as it compares the @ref
25706/// method_decl that is pointed-to by the smart pointer.
25707///
25708/// @param l the left-hand side argument of the equality operator.
25709///
25710/// @param r the righ-hand side argument of the equality operator.
25711///
25712/// @return true iff @p l differs from @p r.
25713bool
25714operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
25715{return !operator==(l, r);}
25716
25717/// Test if a function_decl is actually a method_decl.
25718///
25719///@param d the @ref function_decl to consider.
25720///
25721/// @return the method_decl sub-object of @p d if inherits
25722/// a method_decl type.
25725{
25726 return dynamic_cast<method_decl*>
25727 (const_cast<type_or_decl_base*>(d));
25728}
25729
25730/// Test if a function_decl is actually a method_decl.
25731///
25732///@param d the @ref function_decl to consider.
25733///
25734/// @return the method_decl sub-object of @p d if inherits
25735/// a method_decl type.
25739
25740/// Test if a function_decl is actually a method_decl.
25741///
25742///@param d the @ref function_decl to consider.
25743///
25744/// @return the method_decl sub-object of @p d if inherits
25745/// a method_decl type.
25746method_decl_sptr
25748{return dynamic_pointer_cast<method_decl>(d);}
25749
25750/// A "less than" functor to sort a vector of instances of
25751/// method_decl that are virtual.
25752struct virtual_member_function_less_than
25753{
25754 /// The less than operator. First, it sorts the methods by their
25755 /// vtable index. If they have the same vtable index, it sorts them
25756 /// by the name of their ELF symbol. If they don't have elf
25757 /// symbols, it sorts them by considering their pretty
25758 /// representation.
25759 ///
25760 /// Note that this method expects virtual methods.
25761 ///
25762 /// @param f the first method to consider.
25763 ///
25764 /// @param s the second method to consider.
25765 ///
25766 /// @return true if method @p is less than method @s.
25767 bool
25768 operator()(const method_decl& f,
25769 const method_decl& s)
25770 {
25773
25774 ssize_t f_offset = get_member_function_vtable_offset(f);
25775 ssize_t s_offset = get_member_function_vtable_offset(s);
25776 if (f_offset != s_offset) return f_offset < s_offset;
25777
25778 string fn, sn;
25779 // Try the linkage names (important for destructors).
25780 fn = f.get_linkage_name();
25781 sn = s.get_linkage_name();
25782 if (fn != sn) return fn < sn;
25783
25784 // If the functions have symbols, then compare their symbol-id
25785 // string.
25786 elf_symbol_sptr f_sym = f.get_symbol();
25787 elf_symbol_sptr s_sym = s.get_symbol();
25788 if ((!f_sym) != (!s_sym)) return !f_sym;
25789 if (f_sym && s_sym)
25790 {
25791 fn = f_sym->get_id_string();
25792 sn = s_sym->get_id_string();
25793 if (fn != sn) return fn < sn;
25794 }
25795
25796 // None of the functions have symbols or linkage names that
25797 // distinguish them, so compare their pretty representation.
25800 if (fn != sn) return fn < sn;
25801
25802 /// If it's just the file paths that are different then sort them
25803 /// too.
25804 string fn_filepath, sn_filepath;
25805 unsigned line = 0, column = 0;
25806 location fn_loc = f.get_location(), sn_loc = s.get_location();
25807 if (fn_loc)
25808 fn_loc.expand(fn_filepath, line, column);
25809 if (sn_loc)
25810 sn_loc.expand(sn_filepath, line, column);
25811 return fn_filepath < sn_filepath;
25812 }
25813
25814 /// The less than operator. First, it sorts the methods by their
25815 /// vtable index. If they have the same vtable index, it sorts them
25816 /// by the name of their ELF symbol. If they don't have elf
25817 /// symbols, it sorts them by considering their pretty
25818 /// representation.
25819 ///
25820 /// Note that this method expects to take virtual methods.
25821 ///
25822 /// @param f the first method to consider.
25823 ///
25824 /// @param s the second method to consider.
25825 bool
25826 operator()(const method_decl_sptr f,
25827 const method_decl_sptr s)
25828 {return operator()(*f, *s);}
25829}; // end struct virtual_member_function_less_than
25830
25831/// Sort a vector of instances of virtual member functions.
25832///
25833/// @param mem_fns the vector of member functions to sort.
25834static void
25835sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25836{
25837 virtual_member_function_less_than lt;
25838 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25839}
25840
25841/// Add a member function to the current instance of @ref class_or_union.
25842///
25843/// @param f a method_decl to add to the current class. This function
25844/// should not have been already added to a scope.
25845///
25846/// @param access the access specifier for the member function to add.
25847///
25848/// @param is_virtual if this is true then it means the function @p f
25849/// is a virtual function. That also means that the current instance
25850/// of @ref class_or_union is actually an instance of @ref class_decl.
25851///
25852/// @param vtable_offset the offset of the member function in the
25853/// virtual table. This parameter is taken into account only if @p
25854/// is_virtual is true.
25855///
25856/// @param is_static whether the member function is static.
25857///
25858/// @param is_ctor whether the member function is a constructor.
25859///
25860/// @param is_dtor whether the member function is a destructor.
25861///
25862/// @param is_const whether the member function is const.
25863void
25866 bool is_virtual,
25867 size_t vtable_offset,
25868 bool is_static, bool is_ctor,
25869 bool is_dtor, bool is_const)
25870{
25871 add_member_function(f, a, is_static, is_ctor,
25872 is_dtor, is_const);
25873
25874 if (class_decl* klass = is_class_type(this))
25875 {
25876 if (is_virtual)
25877 {
25878 set_member_function_virtuality(f, is_virtual, vtable_offset);
25879 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25880 }
25881 }
25882}
25883
25884/// When a virtual member function has seen its virtualness set by
25885/// set_member_function_is_virtual(), this function ensures that the
25886/// member function is added to the specific vectors and maps of
25887/// virtual member function of its class.
25888///
25889/// @param method the method to fixup.
25890void
25891fixup_virtual_member_function(method_decl_sptr method)
25892{
25893 if (!method || !get_member_function_is_virtual(method))
25894 return;
25895
25896 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25897
25898 class_decl::member_functions::const_iterator m;
25899 for (m = klass->priv_->virtual_mem_fns_.begin();
25900 m != klass->priv_->virtual_mem_fns_.end();
25901 ++m)
25902 if (m->get() == method.get()
25903 || (*m)->get_linkage_name() == method->get_linkage_name())
25904 break;
25905 if (m == klass->priv_->virtual_mem_fns_.end())
25906 klass->priv_->virtual_mem_fns_.push_back(method);
25907
25908 // Build or udpate the map that associates a vtable offset to the
25909 // number of virtual member functions that "point" to it.
25910 ssize_t voffset = get_member_function_vtable_offset(method);
25911 if (voffset == -1)
25912 return;
25913
25914 class_decl::virtual_mem_fn_map_type::iterator i =
25915 klass->priv_->virtual_mem_fns_map_.find(voffset);
25916 if (i == klass->priv_->virtual_mem_fns_map_.end())
25917 {
25918 class_decl::member_functions virtual_mem_fns_at_voffset;
25919 virtual_mem_fns_at_voffset.push_back(method);
25920 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25921 }
25922 else
25923 {
25924 for (m = i->second.begin() ; m != i->second.end(); ++m)
25925 if (m->get() == method.get()
25926 || (*m)->get_linkage_name() == method->get_linkage_name())
25927 break;
25928 if (m == i->second.end())
25929 i->second.push_back(method);
25930 }
25931}
25932
25933/// Return true iff the class has no entity in its scope.
25934bool
25936{return priv_->bases_.empty() && has_no_member();}
25937
25938/// Test if the current instance of @ref class_decl has virtual member
25939/// functions.
25940///
25941/// @return true iff the current instance of @ref class_decl has
25942/// virtual member functions.
25943bool
25946
25947/// Test if the current instance of @ref class_decl has at least one
25948/// virtual base.
25949///
25950/// @return true iff the current instance of @ref class_decl has a
25951/// virtual member function.
25952bool
25954{
25955 for (base_specs::const_iterator b = get_base_specifiers().begin();
25956 b != get_base_specifiers().end();
25957 ++b)
25958 if ((*b)->get_is_virtual()
25959 || (*b)->get_base_class()->has_virtual_bases())
25960 return true;
25961
25962 return false;
25963}
25964
25965/// Test if the current instance has a vtable.
25966///
25967/// This is only valid for a C++ program.
25968///
25969/// Basically this function checks if the class has either virtual
25970/// functions, or virtual bases.
25971bool
25973{
25975 || has_virtual_bases())
25976 return true;
25977 return false;
25978}
25979
25980/// Get the highest vtable offset of all the virtual methods of the
25981/// class.
25982///
25983/// @return the highest vtable offset of all the virtual methods of
25984/// the class.
25985ssize_t
25987{
25988 ssize_t offset = -1;
25989 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
25990 get_virtual_mem_fns_map().begin();
25991 e != get_virtual_mem_fns_map().end();
25992 ++e)
25993 if (e->first > offset)
25994 offset = e->first;
25995
25996 return offset;
25997}
25998
25999/// Return the hash value of the current IR node.
26000///
26001/// Note that upon the first invocation, this member functions
26002/// computes the hash value and returns it. Subsequent invocations
26003/// just return the hash value that was previously calculated.
26004///
26005/// @return the hash value of the current IR node.
26006hash_t
26008{
26010 return h;
26011}
26012
26013/// Test if two methods are equal without taking their symbol or
26014/// linkage name into account.
26015///
26016/// @param f the first method.
26017///
26018/// @param s the second method.
26019///
26020/// @return true iff @p f equals @p s without taking their linkage
26021/// name or symbol into account.
26022static bool
26023methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
26024 const method_decl_sptr& s)
26025{
26026 method_decl_sptr first = f, second = s;
26027 elf_symbol_sptr saved_first_elf_symbol =
26028 first->get_symbol();
26029 elf_symbol_sptr saved_second_elf_symbol =
26030 second->get_symbol();
26031 interned_string saved_first_linkage_name =
26032 first->get_linkage_name();
26033 interned_string saved_second_linkage_name =
26034 second->get_linkage_name();
26035
26036 first->set_symbol(elf_symbol_sptr());
26037 first->set_linkage_name("");
26038 second->set_symbol(elf_symbol_sptr());
26039 second->set_linkage_name("");
26040
26041 bool equal = *first == *second;
26042
26043 first->set_symbol(saved_first_elf_symbol);
26044 first->set_linkage_name(saved_first_linkage_name);
26045 second->set_symbol(saved_second_elf_symbol);
26046 second->set_linkage_name(saved_second_linkage_name);
26047
26048 return equal;
26049}
26050
26051/// Test if a given method is equivalent to at least of other method
26052/// that is in a vector of methods.
26053///
26054/// Note that "equivalent" here means being equal without taking the
26055/// linkage name or the symbol of the methods into account.
26056///
26057/// This is a sub-routine of the 'equals' function that compares @ref
26058/// class_decl.
26059///
26060/// @param method the method to compare.
26061///
26062/// @param fns the vector of functions to compare @p method against.
26063///
26064/// @return true iff @p is equivalent to at least one method in @p
26065/// fns.
26066static bool
26067method_matches_at_least_one_in_vector(const method_decl_sptr& method,
26069{
26070 for (class_decl::member_functions::const_iterator i = fns.begin();
26071 i != fns.end();
26072 ++i)
26073 // Note that the comparison must be done in this order: method ==
26074 // *i This is to keep the consistency of the comparison. It's
26075 // important especially when doing type canonicalization. The
26076 // already canonicalize type is the left operand, and the type
26077 // being canonicalized is the right operand. This comes from the
26078 // code in type_base::get_canonical_type_for().
26079 if (methods_equal_modulo_elf_symbol(method, *i))
26080 return true;
26081
26082 return false;
26083}
26084
26085/// Compares two instances of @ref class_decl.
26086///
26087/// If the two intances are different, set a bitfield to give some
26088/// insight about the kind of differences there are.
26089///
26090/// @param l the first artifact of the comparison.
26091///
26092/// @param r the second artifact of the comparison.
26093///
26094/// @param k a pointer to a bitfield that gives information about the
26095/// kind of changes there are between @p l and @p r. This one is set
26096/// iff @p k is non-null and the function returns false.
26097///
26098/// Please note that setting k to a non-null value does have a
26099/// negative performance impact because even if @p l and @p r are not
26100/// equal, the function keeps up the comparison in order to determine
26101/// the different kinds of ways in which they are different.
26102///
26103/// @return true if @p l equals @p r, false otherwise.
26104bool
26105equals(const class_decl& l, const class_decl& r, change_kind* k)
26106{
26107 {
26108 // First of all, let's see if these two types haven't already been
26109 // compared. If so, and if the result of the comparison has been
26110 // cached, let's just re-use it, rather than comparing them all
26111 // over again.
26112 bool result = false;
26113 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26114 ABG_RETURN(result);
26115 }
26116
26117 // if one of the classes is declaration-only then we take a fast
26118 // path here.
26120 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
26121 static_cast<const class_or_union&>(r),
26122 k));
26123
26124 bool result = true;
26125 if (!equals(static_cast<const class_or_union&>(l),
26126 static_cast<const class_or_union&>(r),
26127 k))
26128 {
26129 result = false;
26130 if (!k)
26131 ABG_RETURN(result);
26132 }
26133
26135
26137
26138#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
26139
26140 // Compare bases.
26141 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
26142 {
26143 result = false;
26144 if (k)
26146 else
26147 RETURN(result);
26148 }
26149
26150 for (class_decl::base_specs::const_iterator
26151 b0 = l.get_base_specifiers().begin(),
26152 b1 = r.get_base_specifiers().begin();
26153 (b0 != l.get_base_specifiers().end()
26154 && b1 != r.get_base_specifiers().end());
26155 ++b0, ++b1)
26156 if (*b0 != *b1)
26157 {
26158 result = false;
26159 if (k)
26160 {
26161 if (!types_have_similar_structure((*b0)->get_base_class().get(),
26162 (*b1)->get_base_class().get()))
26164 else
26165 *k |= SUBTYPE_CHANGE_KIND;
26166 break;
26167 }
26168 RETURN(result);
26169 }
26170
26171 // Compare virtual member functions
26172
26173 // We look at the map that associates a given vtable offset to a
26174 // vector of virtual member functions that point to that offset.
26175 //
26176 // This is because there are cases where several functions can
26177 // point to the same virtual table offset.
26178 //
26179 // This is usually the case for virtual destructors. Even though
26180 // there can be only one virtual destructor declared in source
26181 // code, there are actually potentially up to three generated
26182 // functions for that destructor. Some of these generated
26183 // functions can be clones of other functions that are among those
26184 // generated ones. In any cases, they all have the same
26185 // properties, including the vtable offset property.
26186
26187 // So, there should be the same number of different vtable
26188 // offsets, the size of two maps must be equals.
26189 if (l.get_virtual_mem_fns_map().size()
26190 != r.get_virtual_mem_fns_map().size())
26191 {
26192 result = false;
26193 if (k)
26195 else
26196 RETURN(result);
26197 }
26198
26199 // Then, each virtual member function of a given vtable offset in
26200 // the first class type, must match an equivalent virtual member
26201 // function of a the same vtable offset in the second class type.
26202 //
26203 // By "match", I mean that the two virtual member function should
26204 // be equal if we don't take into account their symbol name or
26205 // their linkage name. This is because two destructor functions
26206 // clones (for instance) might have different linkage name, but
26207 // are still equivalent if their other properties are the same.
26208 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
26209 l.get_virtual_mem_fns_map().begin();
26210 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
26211 ++first_v_fn_entry)
26212 {
26213 unsigned voffset = first_v_fn_entry->first;
26214 const class_decl::member_functions& first_vfns =
26215 first_v_fn_entry->second;
26216
26217 const class_decl::virtual_mem_fn_map_type::const_iterator
26218 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
26219
26220 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
26221 {
26222 result = false;
26223 if (k)
26225 RETURN(result);
26226 }
26227
26228 const class_decl::member_functions& second_vfns =
26229 second_v_fn_entry->second;
26230
26231 bool matches = false;
26232 for (class_decl::member_functions::const_iterator i =
26233 first_vfns.begin();
26234 i != first_vfns.end();
26235 ++i)
26236 if (method_matches_at_least_one_in_vector(*i, second_vfns))
26237 {
26238 matches = true;
26239 break;
26240 }
26241
26242 if (!matches)
26243 {
26244 result = false;
26245 if (k)
26246 *k |= SUBTYPE_CHANGE_KIND;
26247 else
26248 RETURN(result);
26249 }
26250 }
26251
26252 RETURN(result);
26253#undef RETURN
26254}
26255
26256/// Copy a method of a class into a new class.
26257///
26258/// @param klass the class into which the method is to be copied.
26259///
26260/// @param method the method to copy into @p klass.
26261///
26262/// @return the resulting newly copied method.
26263method_decl_sptr
26264copy_member_function(class_decl_sptr clazz, const method_decl_sptr& f)
26265{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26266
26267/// Copy a method of a class into a new class.
26268///
26269/// @param klass the class into which the method is to be copied.
26270///
26271/// @param method the method to copy into @p klass.
26272///
26273/// @return the resulting newly copied method.
26274method_decl_sptr
26276{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26277
26278/// Comparison operator for @ref class_decl.
26279///
26280/// @param other the instance of @ref class_decl to compare against.
26281///
26282/// @return true iff the current instance of @ref class_decl equals @p
26283/// other.
26284bool
26286{
26287 const class_decl* op = is_class_type(&other);
26288 if (!op)
26289 {
26290 if (class_or_union* cou = is_class_or_union_type(&other))
26291 return class_or_union::operator==(*cou);
26292 return false;
26293 }
26294
26295 // If this is a decl-only type (and thus with no canonical type),
26296 // use the canonical type of the definition, if any.
26297 const class_decl *l = 0;
26299 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
26300 if (l == 0)
26301 l = this;
26302
26303 ABG_ASSERT(l);
26304
26305 // Likewise for the other type.
26306 const class_decl *r = 0;
26307 if (op->get_is_declaration_only())
26308 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
26309 if (r == 0)
26310 r = op;
26311
26312 ABG_ASSERT(r);
26313
26314 return try_canonical_compare(l, r);
26315}
26316
26317/// Equality operator for class_decl.
26318///
26319/// Re-uses the equality operator that takes a decl_base.
26320///
26321/// @param other the other class_decl to compare against.
26322///
26323/// @return true iff the current instance equals the other one.
26324bool
26326{
26327 const decl_base* o = is_decl(&other);
26328 if (!o)
26329 return false;
26330 return *this == *o;
26331}
26332
26333/// Equality operator for class_decl.
26334///
26335/// Re-uses the equality operator that takes a decl_base.
26336///
26337/// @param other the other class_decl to compare against.
26338///
26339/// @return true iff the current instance equals the other one.
26340bool
26341class_decl::operator==(const class_or_union& other) const
26342{
26343 const decl_base& o = other;
26344 return *this == o;
26345}
26346
26347/// Comparison operator for @ref class_decl.
26348///
26349/// @param other the instance of @ref class_decl to compare against.
26350///
26351/// @return true iff the current instance of @ref class_decl equals @p
26352/// other.
26353bool
26354class_decl::operator==(const class_decl& other) const
26355{
26356 const decl_base& o = other;
26357 return *this == o;
26358}
26359
26360/// Turn equality of shared_ptr of class_decl into a deep equality;
26361/// that is, make it compare the pointed to objects too.
26362///
26363/// @param l the shared_ptr of class_decl on left-hand-side of the
26364/// equality.
26365///
26366/// @param r the shared_ptr of class_decl on right-hand-side of the
26367/// equality.
26368///
26369/// @return true if the class_decl pointed to by the shared_ptrs are
26370/// equal, false otherwise.
26371bool
26373{
26374 if (l.get() == r.get())
26375 return true;
26376 if (!!l != !!r)
26377 return false;
26378
26379 return *l == *r;
26380}
26381
26382/// Turn inequality of shared_ptr of class_decl into a deep equality;
26383/// that is, make it compare the pointed to objects too.
26384///
26385/// @param l the shared_ptr of class_decl on left-hand-side of the
26386/// equality.
26387///
26388/// @param r the shared_ptr of class_decl on right-hand-side of the
26389/// equality.
26390///
26391/// @return true if the class_decl pointed to by the shared_ptrs are
26392/// different, false otherwise.
26393bool
26395{return !operator==(l, r);}
26396
26397/// Turn equality of shared_ptr of class_or_union into a deep
26398/// equality; that is, make it compare the pointed to objects too.
26399///
26400/// @param l the left-hand-side operand of the operator
26401///
26402/// @param r the right-hand-side operand of the operator.
26403///
26404/// @return true iff @p l equals @p r.
26405bool
26406operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
26407{
26408 if (l.get() == r.get())
26409 return true;
26410 if (!!l != !!r)
26411 return false;
26412
26413 return *l == *r;
26414}
26415
26416/// Turn inequality of shared_ptr of class_or_union into a deep
26417/// equality; that is, make it compare the pointed to objects too.
26418///
26419/// @param l the left-hand-side operand of the operator
26420///
26421/// @param r the right-hand-side operand of the operator.
26422///
26423/// @return true iff @p l is different from @p r.
26424bool
26425operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
26426{return !operator==(l, r);}
26427
26428/// This implements the ir_traversable_base::traverse pure virtual
26429/// function.
26430///
26431/// @param v the visitor used on the current instance and on its
26432/// members.
26433///
26434/// @return true if the entire IR node tree got traversed, false
26435/// otherwise.
26436bool
26438{
26439 if (v.type_node_has_been_visited(this))
26440 return true;
26441
26442 if (visiting())
26443 return true;
26444
26445 if (v.visit_begin(this))
26446 {
26447 visiting(true);
26448 bool stop = false;
26449
26450 for (base_specs::const_iterator i = get_base_specifiers().begin();
26451 i != get_base_specifiers().end();
26452 ++i)
26453 {
26454 if (!(*i)->traverse(v))
26455 {
26456 stop = true;
26457 break;
26458 }
26459 }
26460
26461 if (!stop)
26462 for (data_members::const_iterator i = get_data_members().begin();
26463 i != get_data_members().end();
26464 ++i)
26465 if (!(*i)->traverse(v))
26466 {
26467 stop = true;
26468 break;
26469 }
26470
26471 if (!stop)
26472 for (member_functions::const_iterator i= get_member_functions().begin();
26473 i != get_member_functions().end();
26474 ++i)
26475 if (!(*i)->traverse(v))
26476 {
26477 stop = true;
26478 break;
26479 }
26480
26481 if (!stop)
26482 for (member_types::const_iterator i = get_member_types().begin();
26483 i != get_member_types().end();
26484 ++i)
26485 if (!(*i)->traverse(v))
26486 {
26487 stop = true;
26488 break;
26489 }
26490
26491 if (!stop)
26492 for (member_function_templates::const_iterator i =
26494 i != get_member_function_templates().end();
26495 ++i)
26496 if (!(*i)->traverse(v))
26497 {
26498 stop = true;
26499 break;
26500 }
26501
26502 if (!stop)
26503 for (member_class_templates::const_iterator i =
26505 i != get_member_class_templates().end();
26506 ++i)
26507 if (!(*i)->traverse(v))
26508 {
26509 stop = true;
26510 break;
26511 }
26512 visiting(false);
26513 }
26514
26515 bool result = v.visit_end(this);
26517 return result;
26518}
26519
26520/// Destructor of the @ref class_decl type.
26522{delete priv_;}
26523
26524context_rel::~context_rel()
26525{}
26526
26527bool
26528member_base::operator==(const member_base& o) const
26529{
26531 && get_is_static() == o.get_is_static());
26532}
26533
26534/// Equality operator for smart pointers to @ref
26535/// class_decl::base_specs.
26536///
26537/// This compares the pointed-to objects.
26538///
26539/// @param l the first instance to consider.
26540///
26541/// @param r the second instance to consider.
26542///
26543/// @return true iff @p l equals @p r.
26544bool
26547{
26548 if (l.get() == r.get())
26549 return true;
26550 if (!!l != !!r)
26551 return false;
26552
26553 return *l == static_cast<const decl_base&>(*r);
26554}
26555
26556/// Inequality operator for smart pointers to @ref
26557/// class_decl::base_specs.
26558///
26559/// This compares the pointed-to objects.
26560///
26561/// @param l the first instance to consider.
26562///
26563/// @param r the second instance to consider.
26564///
26565/// @return true iff @p l is different from @p r.
26566bool
26569{return !operator==(l, r);}
26570
26571/// Test if an ABI artifact is a class base specifier.
26572///
26573/// @param tod the ABI artifact to consider.
26574///
26575/// @return a pointer to the @ref class_decl::base_spec sub-object of
26576/// @p tod iff it's a class base specifier.
26579{
26580 return dynamic_cast<class_decl::base_spec*>
26581 (const_cast<type_or_decl_base*>(tod));
26582}
26583
26584/// Test if an ABI artifact is a class base specifier.
26585///
26586/// @param tod the ABI artifact to consider.
26587///
26588/// @return a pointer to the @ref class_decl::base_spec sub-object of
26589/// @p tod iff it's a class base specifier.
26592{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
26593
26594bool
26595member_function_template::operator==(const member_base& other) const
26596{
26597 try
26598 {
26599 const member_function_template& o =
26600 dynamic_cast<const member_function_template&>(other);
26601
26602 if (!(is_constructor() == o.is_constructor()
26603 && is_const() == o.is_const()
26604 && member_base::operator==(o)))
26605 return false;
26606
26607 if (function_tdecl_sptr ftdecl = as_function_tdecl())
26608 {
26609 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
26610 if (other_ftdecl)
26611 return ftdecl->function_tdecl::operator==(*other_ftdecl);
26612 }
26613 }
26614 catch(...)
26615 {}
26616 return false;
26617}
26618
26619/// Equality operator for smart pointers to @ref
26620/// member_function_template. This is compares the
26621/// pointed-to instances.
26622///
26623/// @param l the first instance to consider.
26624///
26625/// @param r the second instance to consider.
26626///
26627/// @return true iff @p l equals @p r.
26628bool
26629operator==(const member_function_template_sptr& l,
26630 const member_function_template_sptr& r)
26631{
26632 if (l.get() == r.get())
26633 return true;
26634 if (!!l != !!r)
26635 return false;
26636
26637 return *l == *r;
26638}
26639
26640/// Inequality operator for smart pointers to @ref
26641/// member_function_template. This is compares the pointed-to
26642/// instances.
26643///
26644/// @param l the first instance to consider.
26645///
26646/// @param r the second instance to consider.
26647///
26648/// @return true iff @p l equals @p r.
26649bool
26650operator!=(const member_function_template_sptr& l,
26651 const member_function_template_sptr& r)
26652{return !operator==(l, r);}
26653
26654/// This implements the ir_traversable_base::traverse pure virtual
26655/// function.
26656///
26657/// @param v the visitor used on the current instance and on its
26658/// underlying function template.
26659///
26660/// @return true if the entire IR node tree got traversed, false
26661/// otherwise.
26662bool
26664{
26665 if (visiting())
26666 return true;
26667
26668 if (v.visit_begin(this))
26669 {
26670 visiting(true);
26671 if (function_tdecl_sptr f = as_function_tdecl())
26672 f->traverse(v);
26673 visiting(false);
26674 }
26675 return v.visit_end(this);
26676}
26677
26678/// Equality operator of the the @ref member_class_template class.
26679///
26680/// @param other the other @ref member_class_template to compare against.
26681///
26682/// @return true iff the current instance equals @p other.
26683bool
26684member_class_template::operator==(const member_base& other) const
26685{
26686 try
26687 {
26688 const member_class_template& o =
26689 dynamic_cast<const member_class_template&>(other);
26690
26691 if (!member_base::operator==(o))
26692 return false;
26693
26694 return as_class_tdecl()->class_tdecl::operator==(o);
26695 }
26696 catch(...)
26697 {return false;}
26698}
26699
26700/// Equality operator of the the @ref member_class_template class.
26701///
26702/// @param other the other @ref member_class_template to compare against.
26703///
26704/// @return true iff the current instance equals @p other.
26705bool
26706member_class_template::operator==(const decl_base& other) const
26707{
26708 if (!decl_base::operator==(other))
26709 return false;
26710 return as_class_tdecl()->class_tdecl::operator==(other);
26711}
26712
26713/// Comparison operator for the @ref member_class_template
26714/// type.
26715///
26716/// @param other the other instance of @ref
26717/// member_class_template to compare against.
26718///
26719/// @return true iff the two instances are equal.
26720bool
26721member_class_template::operator==(const member_class_template& other) const
26722{
26723 const decl_base* o = dynamic_cast<const decl_base*>(&other);
26724 return *this == *o;
26725}
26726
26727/// Comparison operator for the @ref member_class_template
26728/// type.
26729///
26730/// @param l the first argument of the operator.
26731///
26732/// @param r the second argument of the operator.
26733///
26734/// @return true iff the two instances are equal.
26735bool
26736operator==(const member_class_template_sptr& l,
26737 const member_class_template_sptr& r)
26738{
26739 if (l.get() == r.get())
26740 return true;
26741 if (!!l != !!r)
26742 return false;
26743
26744 return *l == *r;
26745}
26746
26747/// Inequality operator for the @ref member_class_template
26748/// type.
26749///
26750/// @param l the first argument of the operator.
26751///
26752/// @param r the second argument of the operator.
26753///
26754/// @return true iff the two instances are equal.
26755bool
26756operator!=(const member_class_template_sptr& l,
26757 const member_class_template_sptr& r)
26758{return !operator==(l, r);}
26759
26760/// This implements the ir_traversable_base::traverse pure virtual
26761/// function.
26762///
26763/// @param v the visitor used on the current instance and on the class
26764/// pattern of the template.
26765///
26766/// @return true if the entire IR node tree got traversed, false
26767/// otherwise.
26768bool
26770{
26771 if (visiting())
26772 return true;
26773
26774 if (v.visit_begin(this))
26775 {
26776 visiting(true);
26777 if (class_tdecl_sptr t = as_class_tdecl())
26778 t->traverse(v);
26779 visiting(false);
26780 }
26781 return v.visit_end(this);
26782}
26783
26784/// Streaming operator for class_decl::access_specifier.
26785///
26786/// @param o the output stream to serialize the access specifier to.
26787///
26788/// @param a the access specifier to serialize.
26789///
26790/// @return the output stream.
26791std::ostream&
26792operator<<(std::ostream& o, access_specifier a)
26793{
26794 string r;
26795
26796 switch (a)
26797 {
26798 case no_access:
26799 r = "none";
26800 break;
26801 case private_access:
26802 r = "private";
26803 break;
26804 case protected_access:
26805 r = "protected";
26806 break;
26807 case public_access:
26808 r= "public";
26809 break;
26810 };
26811 o << r;
26812 return o;
26813}
26814
26815/// Sets the static-ness property of a class member.
26816///
26817/// @param d the class member to set the static-ness property for.
26818/// Note that this must be a class member otherwise the function
26819/// aborts the current process.
26820///
26821/// @param s this must be true if the member is to be static, false
26822/// otherwise.
26823void
26824set_member_is_static(decl_base& d, bool s)
26825{
26827
26829 ABG_ASSERT(c);
26830
26831 c->set_is_static(s);
26832
26833 scope_decl* scope = d.get_scope();
26834
26835 if (class_or_union* cl = is_class_or_union_type(scope))
26836 {
26837 if (var_decl* v = is_var_decl(&d))
26838 {
26839 // First, find v in the set of data members.
26840 var_decl_sptr var;
26841 for (const auto& dm : cl->get_data_members())
26842 if (dm->get_name() == v->get_name())
26843 {
26844 var = dm;
26845 break;
26846 }
26847 if (!var)
26848 return;
26849
26850 if (s)
26851 {
26852 // remove from the non-static data members
26853 for (class_decl::data_members::iterator i =
26854 cl->priv_->non_static_data_members_.begin();
26855 i != cl->priv_->non_static_data_members_.end();
26856 ++i)
26857 {
26858 if ((*i)->get_name() == v->get_name())
26859 {
26860 cl->priv_->non_static_data_members_.erase(i);
26861 break;
26862 }
26863 }
26864
26865 // If it's not in the static data members, then add it
26866 // there.
26867 bool already_in_static_dms = false;
26868 for (const auto& s_dm : cl->priv_->static_data_members_)
26869 if (s_dm->get_name() == v->get_name())
26870 {
26871 already_in_static_dms = true;
26872 break;
26873 }
26874 if (!already_in_static_dms)
26875 cl->priv_->static_data_members_.push_back(var);
26876 }
26877 else // is non-static
26878 {
26879 // Remove from the static data members.
26880 for (class_or_union::data_members::iterator i =
26881 cl->priv_->static_data_members_.begin();
26882 i != cl->priv_->static_data_members_.end();
26883 ++i)
26884 if ((*i)->get_name() == v->get_name())
26885 {
26886 cl->priv_->static_data_members_.erase(i);
26887 break;
26888 }
26889
26890 // If it's not already in the non-static data members
26891 // then add it there.
26892 bool is_already_in_non_static_data_members = false;
26893 for (const auto& ns_dm : cl->priv_->non_static_data_members_)
26894 if (ns_dm->get_name() == v->get_name())
26895 {
26896 is_already_in_non_static_data_members = true;
26897 break;
26898 }
26899 if (!is_already_in_non_static_data_members)
26900 cl->priv_->non_static_data_members_.push_back(var);
26901 }
26902 }
26903 }
26904}
26905
26906/// Sets the static-ness property of a class member.
26907///
26908/// @param d the class member to set the static-ness property for.
26909/// Note that this must be a class member otherwise the function
26910/// aborts the current process.
26911///
26912/// @param s this must be true if the member is to be static, false
26913/// otherwise.
26914void
26915set_member_is_static(const decl_base_sptr& d, bool s)
26916{set_member_is_static(*d, s);}
26917
26918// </class_decl>
26919
26920// <union_decl>
26921
26922/// Constructor for the @ref union_decl type.
26923///
26924/// @param env the @ref environment we are operating from.
26925///
26926/// @param name the name of the union type.
26927///
26928/// @param size_in_bits the size of the union, in bits.
26929///
26930/// @param locus the location of the type.
26931///
26932/// @param vis the visibility of instances of @ref union_decl.
26933///
26934/// @param mbr_types the member types of the union.
26935///
26936/// @param data_mbrs the data members of the union.
26937///
26938/// @param member_fns the member functions of the union.
26939union_decl::union_decl(const environment& env, const string& name,
26940 size_t size_in_bits, const location& locus,
26941 visibility vis, member_types& mbr_types,
26942 data_members& data_mbrs, member_functions& member_fns)
26943 : type_or_decl_base(env,
26944 UNION_TYPE
26945 | ABSTRACT_TYPE_BASE
26946 | ABSTRACT_DECL_BASE),
26947 decl_base(env, name, locus, name, vis),
26948 type_base(env, size_in_bits, 0),
26949 class_or_union(env, name, size_in_bits, 0,
26950 locus, vis, mbr_types, data_mbrs, member_fns)
26951{
26953}
26954
26955/// Constructor for the @ref union_decl type.
26956///
26957/// @param env the @ref environment we are operating from.
26958///
26959/// @param name the name of the union type.
26960///
26961/// @param size_in_bits the size of the union, in bits.
26962///
26963/// @param locus the location of the type.
26964///
26965/// @param vis the visibility of instances of @ref union_decl.
26966///
26967/// @param mbr_types the member types of the union.
26968///
26969/// @param data_mbrs the data members of the union.
26970///
26971/// @param member_fns the member functions of the union.
26972///
26973/// @param is_anonymous whether the newly created instance is
26974/// anonymous.
26975union_decl::union_decl(const environment& env, const string& name,
26976 size_t size_in_bits, const location& locus,
26977 visibility vis, member_types& mbr_types,
26978 data_members& data_mbrs, member_functions& member_fns,
26979 bool is_anonymous)
26980 : type_or_decl_base(env,
26981 UNION_TYPE
26982 | ABSTRACT_TYPE_BASE
26983 | ABSTRACT_DECL_BASE),
26984 decl_base(env, name, locus,
26985 // If the class is anonymous then by default it won't
26986 // have a linkage name. Also, the anonymous class does
26987 // have an internal-only unique name that is generally
26988 // not taken into account when comparing classes; such a
26989 // unique internal-only name, when used as a linkage
26990 // name might introduce spurious comparison false
26991 // negatives.
26992 /*linkage_name=*/is_anonymous ? string() : name,
26993 vis),
26994 type_base(env, size_in_bits, 0),
26995 class_or_union(env, name, size_in_bits, 0,
26996 locus, vis, mbr_types, data_mbrs, member_fns)
26997{
26999 set_is_anonymous(is_anonymous);
27000}
27001
27002/// Constructor for the @ref union_decl type.
27003///
27004/// @param env the @ref environment we are operating from.
27005///
27006/// @param name the name of the union type.
27007///
27008/// @param size_in_bits the size of the union, in bits.
27009///
27010/// @param locus the location of the type.
27011///
27012/// @param vis the visibility of instances of @ref union_decl.
27013union_decl::union_decl(const environment& env, const string& name,
27014 size_t size_in_bits, const location& locus,
27015 visibility vis)
27016 : type_or_decl_base(env,
27017 UNION_TYPE
27018 | ABSTRACT_TYPE_BASE
27019 | ABSTRACT_DECL_BASE
27020 | ABSTRACT_SCOPE_TYPE_DECL
27021 | ABSTRACT_SCOPE_DECL),
27022 decl_base(env, name, locus, name, vis),
27023 type_base(env, size_in_bits, 0),
27024 class_or_union(env, name, size_in_bits,
27025 0, locus, vis)
27026{
27028}
27029
27030/// Constructor for the @ref union_decl type.
27031///
27032/// @param env the @ref environment we are operating from.
27033///
27034/// @param name the name of the union type.
27035///
27036/// @param size_in_bits the size of the union, in bits.
27037///
27038/// @param locus the location of the type.
27039///
27040/// @param vis the visibility of instances of @ref union_decl.
27041///
27042/// @param is_anonymous whether the newly created instance is
27043/// anonymous.
27044union_decl::union_decl(const environment& env, const string& name,
27045 size_t size_in_bits, const location& locus,
27046 visibility vis, bool is_anonymous)
27047 : type_or_decl_base(env,
27048 UNION_TYPE
27049 | ABSTRACT_TYPE_BASE
27050 | ABSTRACT_DECL_BASE
27051 | ABSTRACT_SCOPE_TYPE_DECL
27052 | ABSTRACT_SCOPE_DECL),
27053 decl_base(env, name, locus,
27054 // If the class is anonymous then by default it won't
27055 // have a linkage name. Also, the anonymous class does
27056 // have an internal-only unique name that is generally
27057 // not taken into account when comparing classes; such a
27058 // unique internal-only name, when used as a linkage
27059 // name might introduce spurious comparison false
27060 // negatives.
27061 /*linkage_name=*/is_anonymous ? string() : name,
27062 vis),
27063 type_base(env, size_in_bits, 0),
27064 class_or_union(env, name, size_in_bits,
27065 0, locus, vis)
27066{
27068 set_is_anonymous(is_anonymous);
27069}
27070
27071/// Constructor for the @ref union_decl type.
27072///
27073/// @param env the @ref environment we are operating from.
27074///
27075/// @param name the name of the union type.
27076///
27077/// @param is_declaration_only a boolean saying whether the instance
27078/// represents a declaration only, or not.
27079union_decl::union_decl(const environment& env,
27080 const string& name,
27081 bool is_declaration_only)
27082 : type_or_decl_base(env,
27083 UNION_TYPE
27084 | ABSTRACT_TYPE_BASE
27085 | ABSTRACT_DECL_BASE
27086 | ABSTRACT_SCOPE_TYPE_DECL
27087 | ABSTRACT_SCOPE_DECL),
27088 decl_base(env, name, location(), name),
27089 type_base(env, 0, 0),
27090 class_or_union(env, name, is_declaration_only)
27091{
27093}
27094
27095/// Return the hash value of the current IR node.
27096///
27097/// Note that upon the first invocation, this member functions
27098/// computes the hash value and returns it. Subsequent invocations
27099/// just return the hash value that was previously calculated.
27100///
27101/// @return the hash value of the current IR node.
27102hash_t
27104{
27106 return h;
27107}
27108
27109/// Getter of the pretty representation of the current instance of
27110/// @ref union_decl.
27111///
27112/// @param internal set to true if the call is intended to get a
27113/// representation of the decl (or type) for the purpose of canonical
27114/// type comparison. This is mainly used in the function
27115/// type_base::get_canonical_type_for().
27116///
27117/// In other words if the argument for this parameter is true then the
27118/// call is meant for internal use (for technical use inside the
27119/// library itself), false otherwise. If you don't know what this is
27120/// for, then set it to false.
27121///
27122/// @param qualified_name if true, names emitted in the pretty
27123/// representation are fully qualified.
27124///
27125/// @return the pretty representaion for a union_decl.
27126string
27128 bool qualified_name) const
27129{
27130 string repr;
27131 if (get_is_anonymous())
27132 {
27133 if (internal && !get_name().empty())
27134 repr = string("union ") +
27135 get_type_name(this, qualified_name, /*internal=*/true);
27136 else
27138 /*one_line=*/true,
27139 internal);
27140 }
27141 else
27142 {
27143 repr = "union ";
27144 if (qualified_name)
27145 repr += get_qualified_name(internal);
27146 else
27147 repr += get_name();
27148 }
27149
27150 return repr;
27151}
27152
27153/// Comparison operator for @ref union_decl.
27154///
27155/// @param other the instance of @ref union_decl to compare against.
27156///
27157/// @return true iff the current instance of @ref union_decl equals @p
27158/// other.
27159bool
27161{
27162 const union_decl* op = dynamic_cast<const union_decl*>(&other);
27163 if (!op)
27164 return false;
27165 return try_canonical_compare(this, op);
27166}
27167
27168/// Equality operator for union_decl.
27169///
27170/// Re-uses the equality operator that takes a decl_base.
27171///
27172/// @param other the other union_decl to compare against.
27173///
27174/// @return true iff the current instance equals the other one.
27175bool
27177{
27178 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27179 if (!o)
27180 return false;
27181 return *this == *o;
27182}
27183
27184/// Equality operator for union_decl.
27185///
27186/// Re-uses the equality operator that takes a decl_base.
27187///
27188/// @param other the other union_decl to compare against.
27189///
27190/// @return true iff the current instance equals the other one.
27191bool
27192union_decl::operator==(const class_or_union&other) const
27193{
27194 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27195 return *this == *o;
27196}
27197
27198/// Comparison operator for @ref union_decl.
27199///
27200/// @param other the instance of @ref union_decl to compare against.
27201///
27202/// @return true iff the current instance of @ref union_decl equals @p
27203/// other.
27204bool
27205union_decl::operator==(const union_decl& other) const
27206{
27207 const decl_base& o = other;
27208 return *this == o;
27209}
27210
27211/// This implements the ir_traversable_base::traverse pure virtual
27212/// function.
27213///
27214/// @param v the visitor used on the current instance and on its
27215/// members.
27216///
27217/// @return true if the entire IR node tree got traversed, false
27218/// otherwise.
27219bool
27221{
27222 if (v.type_node_has_been_visited(this))
27223 return true;
27224
27225 if (visiting())
27226 return true;
27227
27228 if (v.visit_begin(this))
27229 {
27230 visiting(true);
27231 bool stop = false;
27232
27233 if (!stop)
27234 for (data_members::const_iterator i = get_data_members().begin();
27235 i != get_data_members().end();
27236 ++i)
27237 if (!(*i)->traverse(v))
27238 {
27239 stop = true;
27240 break;
27241 }
27242
27243 if (!stop)
27244 for (member_functions::const_iterator i= get_member_functions().begin();
27245 i != get_member_functions().end();
27246 ++i)
27247 if (!(*i)->traverse(v))
27248 {
27249 stop = true;
27250 break;
27251 }
27252
27253 if (!stop)
27254 for (member_types::const_iterator i = get_member_types().begin();
27255 i != get_member_types().end();
27256 ++i)
27257 if (!(*i)->traverse(v))
27258 {
27259 stop = true;
27260 break;
27261 }
27262
27263 if (!stop)
27264 for (member_function_templates::const_iterator i =
27266 i != get_member_function_templates().end();
27267 ++i)
27268 if (!(*i)->traverse(v))
27269 {
27270 stop = true;
27271 break;
27272 }
27273
27274 if (!stop)
27275 for (member_class_templates::const_iterator i =
27277 i != get_member_class_templates().end();
27278 ++i)
27279 if (!(*i)->traverse(v))
27280 {
27281 stop = true;
27282 break;
27283 }
27284 visiting(false);
27285 }
27286
27287 bool result = v.visit_end(this);
27289 return result;
27290}
27291
27292/// Destructor of the @ref union_decl type.
27295
27296/// Compares two instances of @ref union_decl.
27297///
27298/// If the two intances are different, set a bitfield to give some
27299/// insight about the kind of differences there are.
27300///
27301/// @param l the first artifact of the comparison.
27302///
27303/// @param r the second artifact of the comparison.
27304///
27305/// @param k a pointer to a bitfield that gives information about the
27306/// kind of changes there are between @p l and @p r. This one is set
27307/// iff @p k is non-null and the function returns false.
27308///
27309/// Please note that setting k to a non-null value does have a
27310/// negative performance impact because even if @p l and @p r are not
27311/// equal, the function keeps up the comparison in order to determine
27312/// the different kinds of ways in which they are different.
27313///
27314/// @return true if @p l equals @p r, false otherwise.
27315bool
27317{
27318
27320
27321 {
27322 // First of all, let's see if these two types haven't already been
27323 // compared. If so, and if the result of the comparison has been
27324 // cached, let's just re-use it, rather than comparing them all
27325 // over again.
27326 bool result = false;
27327 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
27328 ABG_RETURN(result);
27329 }
27330
27331 bool result = equals(static_cast<const class_or_union&>(l),
27332 static_cast<const class_or_union&>(r),
27333 k);
27334
27336}
27337
27338/// Copy a method of a @ref union_decl into a new @ref
27339/// union_decl.
27340///
27341/// @param t the @ref union_decl into which the method is to be copied.
27342///
27343/// @param method the method to copy into @p t.
27344///
27345/// @return the resulting newly copied method.
27346method_decl_sptr
27347copy_member_function(union_decl_sptr union_type,
27348 const method_decl_sptr& f)
27349{return copy_member_function(union_type, f.get());}
27350
27351/// Copy a method of a @ref union_decl into a new @ref
27352/// union_decl.
27353///
27354/// @param t the @ref union_decl into which the method is to be copied.
27355///
27356/// @param method the method to copy into @p t.
27357///
27358/// @return the resulting newly copied method.
27359method_decl_sptr
27360copy_member_function(union_decl_sptr union_type,
27361 const method_decl* f)
27362{
27363 const class_or_union_sptr t = union_type;
27364 return copy_member_function(t, f);
27365}
27366
27367/// Turn equality of shared_ptr of union_decl into a deep equality;
27368/// that is, make it compare the pointed to objects too.
27369///
27370/// @param l the left-hand-side operand of the operator
27371///
27372/// @param r the right-hand-side operand of the operator.
27373///
27374/// @return true iff @p l equals @p r.
27375bool
27376operator==(const union_decl_sptr& l, const union_decl_sptr& r)
27377{
27378 if (l.get() == r.get())
27379 return true;
27380 if (!!l != !!r)
27381 return false;
27382
27383 return *l == *r;
27384}
27385
27386/// Turn inequality of shared_ptr of union_decl into a deep equality;
27387/// that is, make it compare the pointed to objects too.
27388///
27389/// @param l the left-hand-side operand of the operator
27390///
27391/// @param r the right-hand-side operand of the operator.
27392///
27393/// @return true iff @p l is different from @p r.
27394bool
27395operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
27396{return !operator==(l, r);}
27397// </union_decl>
27398
27399// <template_decl stuff>
27400
27401/// Data type of the private data of the @template_decl type.
27402class template_decl::priv
27403{
27404 friend class template_decl;
27405
27406 std::list<template_parameter_sptr> parms_;
27407public:
27408
27409 priv()
27410 {}
27411}; // end class template_decl::priv
27412
27413/// Add a new template parameter to the current instance of @ref
27414/// template_decl.
27415///
27416/// @param p the new template parameter to add.
27417void
27419{priv_->parms_.push_back(p);}
27420
27421/// Get the list of template parameters of the current instance of
27422/// @ref template_decl.
27423///
27424/// @return the list of template parameters.
27425const std::list<template_parameter_sptr>&
27427{return priv_->parms_;}
27428
27429/// Constructor.
27430///
27431/// @param env the environment we are operating from.
27432///
27433/// @param name the name of the template decl.
27434///
27435/// @param locus the source location where the template declaration is
27436/// defined.
27437///
27438/// @param vis the visibility of the template declaration.
27439template_decl::template_decl(const environment& env,
27440 const string& name,
27441 const location& locus,
27442 visibility vis)
27443 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
27444 decl_base(env, name, locus, /*mangled_name=*/"", vis),
27445 priv_(new priv)
27446{
27448}
27449
27450/// Destructor.
27453
27454/// Equality operator.
27455///
27456/// @param o the other instance to compare against.
27457///
27458/// @return true iff @p equals the current instance.
27459bool
27460template_decl::operator==(const decl_base& o) const
27461{
27462 const template_decl* other = dynamic_cast<const template_decl*>(&o);
27463 if (!other)
27464 return false;
27465 return *this == *other;
27466}
27467
27468/// Equality operator.
27469///
27470/// @param o the other instance to compare against.
27471///
27472/// @return true iff @p equals the current instance.
27473bool
27474template_decl::operator==(const template_decl& o) const
27475{
27476 try
27477 {
27478 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
27479 for (t0 = get_template_parameters().begin(),
27480 t1 = o.get_template_parameters().begin();
27481 (t0 != get_template_parameters().end()
27482 && t1 != o.get_template_parameters().end());
27483 ++t0, ++t1)
27484 {
27485 if (**t0 != **t1)
27486 return false;
27487 }
27488
27489 if (t0 != get_template_parameters().end()
27490 || t1 != o.get_template_parameters().end())
27491 return false;
27492
27493 return true;
27494 }
27495 catch(...)
27496 {return false;}
27497}
27498
27499// </template_decl stuff>
27500
27501//<template_parameter>
27502
27503/// The type of the private data of the @ref template_parameter type.
27504class template_parameter::priv
27505{
27506 friend class template_parameter;
27507
27508 unsigned index_;
27509 template_decl_wptr template_decl_;
27510 mutable bool hashing_started_;
27511 mutable bool comparison_started_;
27512
27513 priv();
27514
27515public:
27516
27517 priv(unsigned index, template_decl_sptr enclosing_template_decl)
27518 : index_(index),
27519 template_decl_(enclosing_template_decl),
27520 hashing_started_(),
27521 comparison_started_()
27522 {}
27523}; // end class template_parameter::priv
27524
27525template_parameter::template_parameter(unsigned index,
27526 template_decl_sptr enclosing_template)
27527 : priv_(new priv(index, enclosing_template))
27528 {}
27529
27530unsigned
27531template_parameter::get_index() const
27532{return priv_->index_;}
27533
27535template_parameter::get_enclosing_template_decl() const
27536{return priv_->template_decl_.lock();}
27537
27538
27539bool
27540template_parameter::operator==(const template_parameter& o) const
27541{
27542 if (get_index() != o.get_index())
27543 return false;
27544
27545 if (priv_->comparison_started_)
27546 return true;
27547
27548 bool result = false;
27549
27550 // Avoid inifite loops due to the fact that comparison the enclosing
27551 // template decl might lead to comparing this very same template
27552 // parameter with another one ...
27553 priv_->comparison_started_ = true;
27554
27555 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
27556 ;
27557 else if (get_enclosing_template_decl()
27558 && (*get_enclosing_template_decl()
27559 != *o.get_enclosing_template_decl()))
27560 ;
27561 else
27562 result = true;
27563
27564 priv_->comparison_started_ = false;
27565
27566 return result;
27567}
27568
27569/// Inequality operator.
27570///
27571/// @param other the other instance to compare against.
27572///
27573/// @return true iff the other instance is different from the current
27574/// one.
27575bool
27576template_parameter::operator!=(const template_parameter& other) const
27577{return !operator==(other);}
27578
27579/// Destructor.
27582
27583/// The type of the private data of the @ref type_tparameter type.
27584class type_tparameter::priv
27585{
27586 friend class type_tparameter;
27587}; // end class type_tparameter::priv
27588
27589/// Constructor of the @ref type_tparameter type.
27590///
27591/// @param index the index the type template parameter.
27592///
27593/// @param enclosing_tdecl the enclosing template declaration.
27594///
27595/// @param name the name of the template parameter.
27596///
27597/// @param locus the location of the declaration of this type template
27598/// parameter.
27599type_tparameter::type_tparameter(unsigned index,
27600 template_decl_sptr enclosing_tdecl,
27601 const string& name,
27602 const location& locus)
27603 : type_or_decl_base(enclosing_tdecl->get_environment(),
27604 ABSTRACT_DECL_BASE
27605 | ABSTRACT_TYPE_BASE
27606 | BASIC_TYPE),
27607 decl_base(enclosing_tdecl->get_environment(), name, locus),
27608 type_base(enclosing_tdecl->get_environment(), 0, 0),
27609 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
27610 template_parameter(index, enclosing_tdecl),
27611 priv_(new priv)
27612{
27614}
27615
27616/// Equality operator.
27617///
27618/// @param other the other template type parameter to compare against.
27619///
27620/// @return true iff @p other equals the current instance.
27621bool
27623{
27624 if (!type_decl::operator==(other))
27625 return false;
27626
27627 try
27628 {
27629 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27630 return template_parameter::operator==(o);
27631 }
27632 catch (...)
27633 {return false;}
27634}
27635
27636/// Equality operator.
27637///
27638/// @param other the other template type parameter to compare against.
27639///
27640/// @return true iff @p other equals the current instance.
27641bool
27642type_tparameter::operator==(const type_decl& other) const
27643{
27644 if (!type_decl::operator==(other))
27645 return false;
27646
27647 try
27648 {
27649 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27650 return template_parameter::operator==(o);
27651 }
27652 catch (...)
27653 {return false;}
27654}
27655
27656/// Equality operator.
27657///
27658/// @param other the other template type parameter to compare against.
27659///
27660/// @return true iff @p other equals the current instance.
27661bool
27663{
27664 if (!decl_base::operator==(other))
27665 return false;
27666
27667 try
27668 {
27669 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27670 return template_parameter::operator==(o);
27671 }
27672 catch (...)
27673 {return false;}
27674}
27675
27676/// Equality operator.
27677///
27678/// @param other the other template type parameter to compare against.
27679///
27680/// @return true iff @p other equals the current instance.
27681bool
27682type_tparameter::operator==(const template_parameter& other) const
27683{
27684 try
27685 {
27686 const type_base& o = dynamic_cast<const type_base&>(other);
27687 return *this == o;
27688 }
27689 catch(...)
27690 {return false;}
27691}
27692
27693/// Equality operator.
27694///
27695/// @param other the other template type parameter to compare against.
27696///
27697/// @return true iff @p other equals the current instance.
27698bool
27699type_tparameter::operator==(const type_tparameter& other) const
27700{return *this == static_cast<const type_base&>(other);}
27701
27702type_tparameter::~type_tparameter()
27703{}
27704
27705/// The type of the private data of the @ref non_type_tparameter type.
27706class non_type_tparameter::priv
27707{
27708 friend class non_type_tparameter;
27709
27710 type_base_wptr type_;
27711
27712 priv();
27713
27714public:
27715
27716 priv(type_base_sptr type)
27717 : type_(type)
27718 {}
27719}; // end class non_type_tparameter::priv
27720
27721/// The constructor for the @ref non_type_tparameter type.
27722///
27723/// @param index the index of the template parameter.
27724///
27725/// @param enclosing_tdecl the enclosing template declaration that
27726/// holds this parameter parameter.
27727///
27728/// @param name the name of the template parameter.
27729///
27730/// @param type the type of the template parameter.
27731///
27732/// @param locus the location of the declaration of this template
27733/// parameter.
27734non_type_tparameter::non_type_tparameter(unsigned index,
27735 template_decl_sptr enclosing_tdecl,
27736 const string& name,
27737 type_base_sptr type,
27738 const location& locus)
27739 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
27740 decl_base(type->get_environment(), name, locus, ""),
27741 template_parameter(index, enclosing_tdecl),
27742 priv_(new priv(type))
27743{
27745}
27746
27747/// Getter for the type of the template parameter.
27748///
27749/// @return the type of the template parameter.
27750const type_base_sptr
27752{return priv_->type_.lock();}
27753
27754
27755bool
27756non_type_tparameter::operator==(const decl_base& other) const
27757{
27758 if (!decl_base::operator==(other))
27759 return false;
27760
27761 try
27762 {
27763 const non_type_tparameter& o =
27764 dynamic_cast<const non_type_tparameter&>(other);
27765 return (template_parameter::operator==(o)
27766 && get_type() == o.get_type());
27767 }
27768 catch(...)
27769 {return false;}
27770}
27771
27772bool
27774{
27775 try
27776 {
27777 const decl_base& o = dynamic_cast<const decl_base&>(other);
27778 return *this == o;
27779 }
27780 catch(...)
27781 {return false;}
27782}
27783
27784non_type_tparameter::~non_type_tparameter()
27785{}
27786
27787// <template_tparameter stuff>
27788
27789/// Type of the private data of the @ref template_tparameter type.
27790class template_tparameter::priv
27791{
27792}; //end class template_tparameter::priv
27793
27794/// Constructor for the @ref template_tparameter.
27795///
27796/// @param index the index of the template parameter.
27797///
27798/// @param enclosing_tdecl the enclosing template declaration.
27799///
27800/// @param name the name of the template parameter.
27801///
27802/// @param locus the location of the declaration of the template
27803/// parameter.
27804template_tparameter::template_tparameter(unsigned index,
27805 template_decl_sptr enclosing_tdecl,
27806 const string& name,
27807 const location& locus)
27808 : type_or_decl_base(enclosing_tdecl->get_environment(),
27809 ABSTRACT_DECL_BASE
27810 | ABSTRACT_TYPE_BASE
27811 | BASIC_TYPE),
27812 decl_base(enclosing_tdecl->get_environment(), name, locus),
27813 type_base(enclosing_tdecl->get_environment(), 0, 0),
27814 type_decl(enclosing_tdecl->get_environment(), name,
27815 0, 0, locus, name, VISIBILITY_DEFAULT),
27816 type_tparameter(index, enclosing_tdecl, name, locus),
27817 template_decl(enclosing_tdecl->get_environment(), name, locus),
27818 priv_(new priv)
27819{
27821}
27822
27823/// Equality operator.
27824///
27825/// @param other the other template parameter to compare against.
27826///
27827/// @return true iff @p other equals the current instance.
27828bool
27830{
27831 try
27832 {
27833 const template_tparameter& o =
27834 dynamic_cast<const template_tparameter&>(other);
27835 return (type_tparameter::operator==(o)
27836 && template_decl::operator==(o));
27837 }
27838 catch(...)
27839 {return false;}
27840}
27841
27842/// Equality operator.
27843///
27844/// @param other the other template parameter to compare against.
27845///
27846/// @return true iff @p other equals the current instance.
27847bool
27849{
27850 try
27851 {
27852 const template_tparameter& o =
27853 dynamic_cast<const template_tparameter&>(other);
27854 return (type_tparameter::operator==(o)
27855 && template_decl::operator==(o));
27856 }
27857 catch(...)
27858 {return false;}
27859}
27860
27861bool
27863{
27864 try
27865 {
27866 const template_tparameter& other =
27867 dynamic_cast<const template_tparameter&>(o);
27868 return *this == static_cast<const type_base&>(other);
27869 }
27870 catch(...)
27871 {return false;}
27872}
27873
27874bool
27875template_tparameter::operator==(const template_decl& o) const
27876{
27877 try
27878 {
27879 const template_tparameter& other =
27880 dynamic_cast<const template_tparameter&>(o);
27881 return type_base::operator==(other);
27882 }
27883 catch(...)
27884 {return false;}
27885}
27886
27887template_tparameter::~template_tparameter()
27888{}
27889
27890// </template_tparameter stuff>
27891
27892// <type_composition stuff>
27893
27894/// The type of the private data of the @ref type_composition type.
27895class type_composition::priv
27896{
27897 friend class type_composition;
27898
27899 type_base_wptr type_;
27900
27901 // Forbid this.
27902 priv();
27903
27904public:
27905
27906 priv(type_base_wptr type)
27907 : type_(type)
27908 {}
27909}; //end class type_composition::priv
27910
27911/// Constructor for the @ref type_composition type.
27912///
27913/// @param index the index of the template type composition.
27914///
27915/// @param tdecl the enclosing template parameter that owns the
27916/// composition.
27917///
27918/// @param t the resulting type.
27919type_composition::type_composition(unsigned index,
27920 template_decl_sptr tdecl,
27921 type_base_sptr t)
27923 ABSTRACT_DECL_BASE),
27924 decl_base(tdecl->get_environment(), "", location()),
27925 template_parameter(index, tdecl),
27926 priv_(new priv(t))
27927{
27929}
27930
27931/// Getter for the resulting composed type.
27932///
27933/// @return the composed type.
27934const type_base_sptr
27936{return priv_->type_.lock();}
27937
27938/// Setter for the resulting composed type.
27939///
27940/// @param t the composed type.
27941void
27943{priv_->type_ = t;}
27944
27945type_composition::~type_composition()
27946{}
27947
27948// </type_composition stuff>
27949
27950//</template_parameter stuff>
27951
27952// <function_template>
27953
27954class function_tdecl::priv
27955{
27956 friend class function_tdecl;
27957
27958 function_decl_sptr pattern_;
27959 binding binding_;
27960
27961 priv();
27962
27963public:
27964
27965 priv(function_decl_sptr pattern, binding bind)
27966 : pattern_(pattern), binding_(bind)
27967 {}
27968
27969 priv(binding bind)
27970 : binding_(bind)
27971 {}
27972}; // end class function_tdecl::priv
27973
27974/// Constructor for a function template declaration.
27975///
27976/// @param env the environment we are operating from.
27977///
27978/// @param locus the location of the declaration.
27979///
27980/// @param vis the visibility of the declaration. This is the
27981/// visibility the functions instantiated from this template are going
27982/// to have.
27983///
27984/// @param bind the binding of the declaration. This is the binding
27985/// the functions instantiated from this template are going to have.
27986function_tdecl::function_tdecl(const environment& env,
27987 const location& locus,
27988 visibility vis,
27989 binding bind)
27990 : type_or_decl_base(env,
27991 ABSTRACT_DECL_BASE
27992 | TEMPLATE_DECL
27993 | ABSTRACT_SCOPE_DECL),
27994 decl_base(env, "", locus, "", vis),
27995 template_decl(env, "", locus, vis),
27996 scope_decl(env, "", locus),
27997 priv_(new priv(bind))
27998{
28000}
28001
28002/// Constructor for a function template declaration.
28003///
28004/// @param pattern the pattern of the template.
28005///
28006/// @param locus the location of the declaration.
28007///
28008/// @param vis the visibility of the declaration. This is the
28009/// visibility the functions instantiated from this template are going
28010/// to have.
28011///
28012/// @param bind the binding of the declaration. This is the binding
28013/// the functions instantiated from this template are going to have.
28014function_tdecl::function_tdecl(function_decl_sptr pattern,
28015 const location& locus,
28016 visibility vis,
28017 binding bind)
28019 ABSTRACT_DECL_BASE
28020 | TEMPLATE_DECL
28021 | ABSTRACT_SCOPE_DECL),
28022 decl_base(pattern->get_environment(), pattern->get_name(), locus,
28023 pattern->get_name(), vis),
28024 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28025 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28026 priv_(new priv(pattern, bind))
28027{
28029}
28030
28031/// Set a new pattern to the function template.
28032///
28033/// @param p the new pattern.
28034void
28036{
28037 priv_->pattern_ = p;
28038 add_decl_to_scope(p, this);
28039 set_name(p->get_name());
28040}
28041
28042/// Get the pattern of the function template.
28043///
28044/// @return the pattern.
28047{return priv_->pattern_;}
28048
28049/// Get the binding of the function template.
28050///
28051/// @return the binding
28054{return priv_->binding_;}
28055
28056/// Comparison operator for the @ref function_tdecl type.
28057///
28058/// @param other the other instance of @ref function_tdecl to compare against.
28059///
28060/// @return true iff the two instance are equal.
28061bool
28063{
28064 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
28065 if (o)
28066 return *this == *o;
28067 return false;
28068}
28069
28070/// Comparison operator for the @ref function_tdecl type.
28071///
28072/// @param other the other instance of @ref function_tdecl to compare against.
28073///
28074/// @return true iff the two instance are equal.
28075bool
28076function_tdecl::operator==(const template_decl& other) const
28077{
28078 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
28079 if (o)
28080 return *this == *o;
28081 return false;
28082}
28083
28084/// Comparison operator for the @ref function_tdecl type.
28085///
28086/// @param o the other instance of @ref function_tdecl to compare against.
28087///
28088/// @return true iff the two instance are equal.
28089bool
28090function_tdecl::operator==(const function_tdecl& o) const
28091{
28092 if (!(get_binding() == o.get_binding()
28093 && template_decl::operator==(o)
28094 && scope_decl::operator==(o)
28095 && !!get_pattern() == !!o.get_pattern()))
28096 return false;
28097
28098 if (get_pattern())
28099 return (*get_pattern() == *o.get_pattern());
28100
28101 return true;
28102}
28103
28104/// This implements the ir_traversable_base::traverse pure virtual
28105/// function.
28106///
28107/// @param v the visitor used on the current instance and on the
28108/// function pattern of the template.
28109///
28110/// @return true if the entire IR node tree got traversed, false
28111/// otherwise.
28112bool
28114{
28115 if (visiting())
28116 return true;
28117
28118 if (!v.visit_begin(this))
28119 {
28120 visiting(true);
28121 if (get_pattern())
28122 get_pattern()->traverse(v);
28123 visiting(false);
28124 }
28125 return v.visit_end(this);
28126}
28127
28128function_tdecl::~function_tdecl()
28129{}
28130
28131// </function_template>
28132
28133// <class template>
28134
28135/// Type of the private data of the the @ref class_tdecl type.
28136class class_tdecl::priv
28137{
28138 friend class class_tdecl;
28139 class_decl_sptr pattern_;
28140
28141public:
28142
28143 priv()
28144 {}
28145
28146 priv(class_decl_sptr pattern)
28147 : pattern_(pattern)
28148 {}
28149}; // end class class_tdecl::priv
28150
28151/// Constructor for the @ref class_tdecl type.
28152///
28153/// @param env the environment we are operating from.
28154///
28155/// @param locus the location of the declaration of the class_tdecl
28156/// type.
28157///
28158/// @param vis the visibility of the instance of class instantiated
28159/// from this template.
28160class_tdecl::class_tdecl(const environment& env,
28161 const location& locus,
28162 visibility vis)
28163 : type_or_decl_base(env,
28164 ABSTRACT_DECL_BASE
28165 | TEMPLATE_DECL
28166 | ABSTRACT_SCOPE_DECL),
28167 decl_base(env, "", locus, "", vis),
28168 template_decl(env, "", locus, vis),
28169 scope_decl(env, "", locus),
28170 priv_(new priv)
28171{
28173}
28174
28175/// Constructor for the @ref class_tdecl type.
28176///
28177/// @param pattern The details of the class template. This must NOT be a
28178/// null pointer. If you really this to be null, please use the
28179/// constructor above instead.
28180///
28181/// @param locus the source location of the declaration of the type.
28182///
28183/// @param vis the visibility of the instances of class instantiated
28184/// from this template.
28185class_tdecl::class_tdecl(class_decl_sptr pattern,
28186 const location& locus,
28187 visibility vis)
28189 ABSTRACT_DECL_BASE
28190 | TEMPLATE_DECL
28191 | ABSTRACT_SCOPE_DECL),
28192 decl_base(pattern->get_environment(), pattern->get_name(),
28193 locus, pattern->get_name(), vis),
28194 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28195 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28196 priv_(new priv(pattern))
28197{
28199}
28200
28201/// Setter of the pattern of the template.
28202///
28203/// @param p the new template.
28204void
28206{
28207 priv_->pattern_ = p;
28208 add_decl_to_scope(p, this);
28209 set_name(p->get_name());
28210}
28211
28212/// Getter of the pattern of the template.
28213///
28214/// @return p the new template.
28217{return priv_->pattern_;}
28218
28219bool
28221{
28222 try
28223 {
28224 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28225
28226 if (!(template_decl::operator==(o)
28227 && scope_decl::operator==(o)
28228 && !!get_pattern() == !!o.get_pattern()))
28229 return false;
28230
28231 if (!get_pattern() || !o.get_pattern())
28232 return true;
28233
28234 return get_pattern()->decl_base::operator==(*o.get_pattern());
28235 }
28236 catch(...) {}
28237 return false;
28238}
28239
28240bool
28241class_tdecl::operator==(const template_decl& other) const
28242{
28243 try
28244 {
28245 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28246 return *this == static_cast<const decl_base&>(o);
28247 }
28248 catch(...)
28249 {return false;}
28250}
28251
28252bool
28254{return *this == static_cast<const decl_base&>(o);}
28255
28256/// This implements the ir_traversable_base::traverse pure virtual
28257/// function.
28258///
28259/// @param v the visitor used on the current instance and on the class
28260/// pattern of the template.
28261///
28262/// @return true if the entire IR node tree got traversed, false
28263/// otherwise.
28264bool
28266{
28267 if (visiting())
28268 return true;
28269
28270 if (v.visit_begin(this))
28271 {
28272 visiting(true);
28273 if (class_decl_sptr pattern = get_pattern())
28274 pattern->traverse(v);
28275 visiting(false);
28276 }
28277 return v.visit_end(this);
28278}
28279
28280class_tdecl::~class_tdecl()
28281{}
28282
28283/// This visitor checks if a given type as non-canonicalized sub
28284/// types.
28285class non_canonicalized_subtype_detector : public ir::ir_node_visitor
28286{
28287 type_base* type_;
28288 type_base* has_non_canonical_type_;
28289
28290private:
28291 non_canonicalized_subtype_detector();
28292
28293public:
28294 non_canonicalized_subtype_detector(type_base* type)
28295 : type_(type),
28296 has_non_canonical_type_()
28297 {}
28298
28299 /// Return true if the visitor detected that there is a
28300 /// non-canonicalized sub-type.
28301 ///
28302 /// @return true if the visitor detected that there is a
28303 /// non-canonicalized sub-type.
28304 type_base*
28305 has_non_canonical_type() const
28306 {return has_non_canonical_type_;}
28307
28308 /// The intent of this visitor handler is to avoid looking into
28309 /// sub-types of member functions of the type we are traversing.
28310 bool
28311 visit_begin(function_decl* f)
28312 {
28313 // Do not look at sub-types of non-virtual member functions.
28314 if (is_member_function(f)
28316 return false;
28317 return true;
28318 }
28319
28320 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
28321 /// the 'has_non_canonical_type' flag. And in any case, when
28322 /// visiting a sub-type, do not visit its children nodes. So this
28323 /// function only goes to the level below the level of the top-most
28324 /// type.
28325 ///
28326 /// @return true if we are at the same level as the top-most type,
28327 /// otherwise return false.
28328 bool
28329 visit_begin(type_base* t)
28330 {
28331 if (t != type_)
28332 {
28333 if (!t->get_canonical_type())
28334 // We are looking a sub-type of 'type_' which has no
28335 // canonical type. So tada! we found one! Get out right
28336 // now with the trophy.
28337 has_non_canonical_type_ = t;
28338
28339 return false;
28340 }
28341 return true;
28342 }
28343
28344 /// When we are done visiting a sub-type, if it's been flagged as
28345 /// been non-canonicalized, then stop the traversing.
28346 ///
28347 /// Otherwise, keep going.
28348 ///
28349 /// @return false iff the sub-type that has been visited is
28350 /// non-canonicalized.
28351 bool
28352 visit_end(type_base* )
28353 {
28354 if (has_non_canonical_type_)
28355 return false;
28356 return true;
28357 }
28358}; //end class non_canonicalized_subtype_detector
28359
28360/// Test if a type has sub-types that are non-canonicalized.
28361///
28362/// @param t the type which sub-types to consider.
28363///
28364/// @return true if a type has sub-types that are non-canonicalized.
28365type_base*
28367{
28368 if (!t)
28369 return 0;
28370
28371 non_canonicalized_subtype_detector v(t.get());
28372 t->traverse(v);
28373 return v.has_non_canonical_type();
28374}
28375
28376/// Tests if the change of a given type effectively comes from just
28377/// its sub-types. That is, if the type has changed but its type name
28378/// hasn't changed, then the change of the type mostly likely is a
28379/// sub-type change.
28380///
28381/// @param t_v1 the first version of the type.
28382///
28383/// @param t_v2 the second version of the type.
28384///
28385/// @return true iff the type changed and the change is about its
28386/// sub-types.
28387bool
28388type_has_sub_type_changes(const type_base_sptr t_v1,
28389 const type_base_sptr t_v2)
28390{
28391 type_base_sptr t1 = strip_typedef(t_v1);
28392 type_base_sptr t2 = strip_typedef(t_v2);
28393
28394 string repr1 = get_pretty_representation(t1, /*internal=*/false),
28395 repr2 = get_pretty_representation(t2, /*internal=*/false);
28396 return (t1 != t2 && repr1 == repr2);
28397}
28398
28399/// Make sure that the life time of a given (smart pointer to a) type
28400/// is the same as the life time of the libabigail library.
28401///
28402/// @param t the type to consider.
28403void
28404keep_type_alive(type_base_sptr t)
28405{
28406 const environment& env = t->get_environment();
28407 env.priv_->extra_live_types_.push_back(t);
28408}
28409
28410/// Hash an ABI artifact that is either a type or a decl.
28411///
28412/// This function intends to provides the fastest possible hashing for
28413/// types and decls, while being completely correct.
28414///
28415/// Note that if the artifact is a type and if it has a canonical
28416/// type, the hash value is going to be the pointer value of the
28417/// canonical type. Otherwise, this function computes a hash value
28418/// for the type by recursively walking the type members. This last
28419/// code path is possibly *very* slow and should only be used when
28420/// only handful of types are going to be hashed.
28421///
28422/// If the artifact is a decl, then a combination of the hash of its
28423/// type and the hash of the other properties of the decl is computed.
28424///
28425/// @param tod the type or decl to hash.
28426///
28427/// @return the resulting hash value.
28428size_t
28430{
28431 hash_t result = 0;
28432
28433 if (tod == 0)
28434 ;
28435 else if (const type_base* t = is_type(tod))
28436 result = hash_type(t);
28437 else if (const decl_base* d = is_decl(tod))
28438 {
28439 if (const scope_decl* s = is_scope_decl(d))
28440 {
28441 if (const global_scope* g = is_global_scope(s))
28442 result = reinterpret_cast<size_t>(g);
28443 else
28444 result = reinterpret_cast<size_t>(s);
28445 }
28446 else if (var_decl* v = is_var_decl(d))
28447 {
28448 ABG_ASSERT(v->get_type());
28449 hash_t h = hash_type_or_decl(v->get_type());
28450 string repr = v->get_pretty_representation(/*internal=*/true);
28451 std::hash<string> hash_string;
28452 h = hashing::combine_hashes(h, hash_string(repr));
28453 result = h;
28454 }
28455 else if (function_decl* f = is_function_decl(d))
28456 {
28457 ABG_ASSERT(f->get_type());
28458 hash_t h = hash_type_or_decl(f->get_type());
28459 string repr = f->get_pretty_representation(/*internal=*/true);
28460 std::hash<string> hash_string;
28461 h = hashing::combine_hashes(h, hash_string(repr));
28462 result = h;
28463 }
28465 {
28466 type_base_sptr parm_type = p->get_type();
28467 ABG_ASSERT(parm_type);
28468 std::hash<bool> hash_bool;
28469 std::hash<unsigned> hash_unsigned;
28470 hash_t h = hash_type_or_decl(parm_type);
28471 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
28472 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
28473 result = h;
28474 }
28475 else if (class_decl::base_spec *bs = is_class_base_spec(d))
28476 {
28477 member_base::hash hash_member;
28478 std::hash<size_t> hash_size;
28479 std::hash<bool> hash_bool;
28480 type_base_sptr type = bs->get_base_class();
28481 hash_t h = hash_type_or_decl(type);
28482 h = hashing::combine_hashes(h, hash_member(*bs));
28483 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
28484 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
28485 result = h;
28486 }
28487 else
28488 // This is a *really* *SLOW* path. If it shows up in a
28489 // performance profile, I bet it'd be a good idea to try to
28490 // avoid it altogether.
28491 // TODO: recode this function or get rid of it altogethe.
28492 abort();
28493 }
28494 else
28495 // We should never get here.
28496 abort();
28497 return *result;
28498}
28499
28500/// Hash an ABI artifact that is a type.
28501///
28502/// This function intends to provides the fastest possible hashing for
28503/// types while being completely correct.
28504///
28505/// Note that if the type artifact has a canonical type, the hash
28506/// value is going to be the pointer value of the canonical type.
28507/// Otherwise, this function computes a hash value for the type by
28508/// recursively walking the type members. This last code path is
28509/// possibly *very* slow and should only be used when only handful of
28510/// types are going to be hashed.
28511///
28512/// @param t the type or decl to hash.
28513///
28514/// @return the resulting hash value.
28515size_t
28517{return hash_as_canonical_type_or_constant(t);}
28518
28519/// Hash an ABI artifact that is either a type of a decl.
28520///
28521/// @param tod the ABI artifact to hash.
28522///
28523/// @return the hash value of the ABI artifact.
28524size_t
28526{return hash_type_or_decl(tod.get());}
28527
28528/// Get the hash value associated to an IR node.
28529///
28530/// Unlike type_or_decl_base::hash_value(), if the IR has no
28531/// associated hash value, an empty hash value is returned.
28532///
28533/// @param artefact the IR node to consider.
28534///
28535/// @return the hash value stored on the IR node or an empty hash if
28536/// no hash value is stored in the @p artefact.
28537hash_t
28538peek_hash_value(const type_or_decl_base& artefact)
28539{
28540 const type_or_decl_base* artefactp = &artefact;
28541 if (decl_base *d = is_decl(artefactp))
28542 {
28544 if (d->type_or_decl_base::priv_->get_hashing_state()
28546 return d->type_or_decl_base::priv_->hash_value_;
28547 }
28548 else if (artefact.priv_->get_hashing_state() == hashing::HASHING_FINISHED_STATE)
28549 return artefact.priv_->hash_value_;
28550
28551 return hash_t();
28552}
28553
28554/// Test if a given type is allowed to be non canonicalized
28555///
28556/// This is a subroutine of hash_as_canonical_type_or_constant.
28557///
28558/// For now, the only types allowed to be non canonicalized in the
28559/// system are (typedefs & pointers to) decl-only class/union, the
28560/// void type and variadic parameter types.
28561///
28562/// @return true iff @p t is a one of the only types allowed to be
28563/// non-canonicalized in the system.
28564bool
28566{
28567 if (!t)
28568 return true;
28569
28570 return (// The IR nodes for the types below are unique across the
28571 // entire ABI corpus. Thus, no need to canonicalize them.
28572 // Maybe we could say otherwise and canonicalize them once
28573 // for all so that they can be removed from here.
28575
28576 // An IR node for the types below can be equal to several
28577 // other types (i.e, a decl-only type t equals a fully
28578 // defined type of the same name in ODR-supported
28579 // languages). Hence, they can't be given a canonical type.
28580 //
28581 // TODO: Maybe add a mode that would detect ODR violations
28582 // that would make a decl-only type co-exists with several
28583 // different definitions of the type in the ABI corpus.
28586 /*look_through_decl_only=*/true)
28588
28589}
28590
28591/// Test if a type is unique in the entire environment.
28592///
28593/// Examples of unique types are void, void* and variadic parameter
28594/// types.
28595///
28596/// @param t the type to test for.
28597///
28598/// @return true iff the type @p t is unique in the entire
28599/// environment.
28600bool
28601is_unique_type(const type_base_sptr& t)
28602{return is_unique_type(t.get());}
28603
28604/// Test if a type is unique in the entire environment.
28605///
28606/// Examples of unique types are void, void* and variadic parameter
28607/// types.
28608///
28609/// @param t the type to test for.
28610///
28611/// @return true iff the type @p t is unique in the entire
28612/// environment.
28613bool
28615{
28616 if (!t)
28617 return false;
28618
28619 const environment& env = t->get_environment();
28620 return (env.is_void_type(t)
28621 || env.is_void_pointer_type(t)
28622 || env.is_variadic_parameter_type(t));
28623}
28624
28625/// For a given type, return its exemplar type.
28626///
28627/// For a given type, its exemplar type is either its canonical type
28628/// or the canonical type of the definition type of a given
28629/// declaration-only type. If the neither of those two types exist,
28630/// then the exemplar type is the given type itself.
28631///
28632/// @param type the input to consider.
28633///
28634/// @return the exemplar type.
28635type_base*
28637{
28638 if (decl_base * decl = is_decl(type))
28639 {
28640 // Make sure we get the real definition of a decl-only type.
28641 decl = look_through_decl_only(decl);
28642 type = is_type(decl);
28643 ABG_ASSERT(type);
28644 }
28645 type_base *exemplar = type->get_naked_canonical_type();
28646 if (!exemplar)
28647 {
28648 // The type has no canonical type. Let's be sure that it's one
28649 // of those rare types that are allowed to be non canonicalized
28650 // in the system.
28651 exemplar = const_cast<type_base*>(type);
28653 }
28654 return exemplar;
28655}
28656
28657/// Test if a given type is allowed to be non canonicalized
28658///
28659/// This is a subroutine of hash_as_canonical_type_or_constant.
28660///
28661/// For now, the only types allowed to be non canonicalized in the
28662/// system are decl-only class/union and the void type.
28663///
28664/// @return true iff @p t is a one of the only types allowed to be
28665/// non-canonicalized in the system.
28666bool
28667is_non_canonicalized_type(const type_base_sptr& t)
28668{return is_non_canonicalized_type(t.get());}
28669
28670/// Hash a type by either returning the pointer value of its canonical
28671/// type or by returning a constant if the type doesn't have a
28672/// canonical type.
28673///
28674/// This is a subroutine of hash_type.
28675///
28676/// @param t the type to consider.
28677///
28678/// @return the hash value.
28679static size_t
28680hash_as_canonical_type_or_constant(const type_base *t)
28681{
28682 type_base *canonical_type = 0;
28683
28684 if (t)
28685 canonical_type = t->get_naked_canonical_type();
28686
28687 if (!canonical_type)
28688 {
28689 // If the type doesn't have a canonical type, maybe it's because
28690 // it's a declaration-only type? If that's the case, let's try
28691 // to get the canonical type of the definition of this
28692 // declaration.
28693 decl_base *decl = is_decl(t);
28694 if (decl
28695 && decl->get_is_declaration_only()
28697 {
28698 type_base *definition =
28700 ABG_ASSERT(definition);
28701 canonical_type = definition->get_naked_canonical_type();
28702 }
28703 }
28704
28705 if (canonical_type)
28706 return reinterpret_cast<size_t>(canonical_type);
28707
28708 // If we reached this point, it means we are seeing a
28709 // non-canonicalized type. It must be a decl-only class or a void
28710 // type, otherwise it means that for some weird reason, the type
28711 // hasn't been canonicalized. It should be!
28713
28714 return 0xDEADBABE;
28715}
28716
28717/// Test if the pretty representation of a given @ref function_decl is
28718/// lexicographically less then the pretty representation of another
28719/// @ref function_decl.
28720///
28721/// @param f the first @ref function_decl to consider for comparison.
28722///
28723/// @param s the second @ref function_decl to consider for comparison.
28724///
28725/// @return true iff the pretty representation of @p f is
28726/// lexicographically less than the pretty representation of @p s.
28727bool
28729{
28732
28733 if (fr != sr)
28734 return fr < sr;
28735
28736 fr = f.get_pretty_representation(/*internal=*/true),
28737 sr = s.get_pretty_representation(/*internal=*/true);
28738
28739 if (fr != sr)
28740 return fr < sr;
28741
28742 if (f.get_symbol())
28743 fr = f.get_symbol()->get_id_string();
28744 else if (!f.get_linkage_name().empty())
28745 fr = f.get_linkage_name();
28746
28747 if (s.get_symbol())
28748 sr = s.get_symbol()->get_id_string();
28749 else if (!s.get_linkage_name().empty())
28750 sr = s.get_linkage_name();
28751
28752 return fr < sr;
28753}
28754
28755/// Test if two types have similar structures, even though they are
28756/// (or can be) different.
28757///
28758/// const and volatile qualifiers are completely ignored.
28759///
28760/// typedef are resolved to their definitions; their names are ignored.
28761///
28762/// Two indirect types (pointers or references) have similar structure
28763/// if their underlying types are of the same kind and have the same
28764/// name. In the indirect types case, the size of the underlying type
28765/// does not matter.
28766///
28767/// Two direct types (i.e, non indirect) have a similar structure if
28768/// they have the same kind, name and size. Two class types have
28769/// similar structure if they have the same name, size, and if the
28770/// types of their data members have similar types.
28771///
28772/// @param first the first type to consider.
28773///
28774/// @param second the second type to consider.
28775///
28776/// @param indirect_type whether to do an indirect comparison
28777///
28778/// @return true iff @p first and @p second have similar structures.
28779bool
28780types_have_similar_structure(const type_base_sptr& first,
28781 const type_base_sptr& second,
28782 bool indirect_type)
28783{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
28784
28785/// Test if two types have similar structures, even though they are
28786/// (or can be) different.
28787///
28788/// const and volatile qualifiers are completely ignored.
28789///
28790/// typedef are resolved to their definitions; their names are ignored.
28791///
28792/// Two indirect types (pointers, references or arrays) have similar
28793/// structure if their underlying types are of the same kind and have
28794/// the same name. In the indirect types case, the size of the
28795/// underlying type does not matter.
28796///
28797/// Two direct types (i.e, non indirect) have a similar structure if
28798/// they have the same kind, name and size. Two class types have
28799/// similar structure if they have the same name, size, and if the
28800/// types of their data members have similar types.
28801///
28802/// @param first the first type to consider.
28803///
28804/// @param second the second type to consider.
28805///
28806/// @param indirect_type if true, then consider @p first and @p
28807/// second as being underlying types of indirect types. Meaning that
28808/// their size does not matter.
28809///
28810/// @return true iff @p first and @p second have similar structures.
28811bool
28813 const type_base* second,
28814 bool indirect_type)
28815{
28816 if (!!first != !!second)
28817 return false;
28818
28819 if (!first)
28820 return false;
28821
28822 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
28823 first = peel_qualified_or_typedef_type(first);
28824 second = peel_qualified_or_typedef_type(second);
28825
28826 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
28827 // various ty2 below cannot be null.
28828 if (typeid(*first) != typeid(*second))
28829 return false;
28830
28831 // Peel off matching pointers.
28832 if (const pointer_type_def* ty1 = is_pointer_type(first))
28833 {
28834 const pointer_type_def* ty2 = is_pointer_type(second);
28835 return types_have_similar_structure(ty1->get_pointed_to_type(),
28836 ty2->get_pointed_to_type(),
28837 /*indirect_type=*/true);
28838 }
28839
28840 // Peel off matching references.
28841 if (const reference_type_def* ty1 = is_reference_type(first))
28842 {
28843 const reference_type_def* ty2 = is_reference_type(second);
28844 if (ty1->is_lvalue() != ty2->is_lvalue())
28845 return false;
28846 return types_have_similar_structure(ty1->get_pointed_to_type(),
28847 ty2->get_pointed_to_type(),
28848 /*indirect_type=*/true);
28849 }
28850
28851 // Peel off matching pointer-to-member types.
28852 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28853 {
28854 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28855 return (types_have_similar_structure(ty1->get_member_type(),
28856 ty2->get_member_type(),
28857 /*indirect_type=*/true)
28858 && types_have_similar_structure(ty1->get_containing_type(),
28859 ty2->get_containing_type(),
28860 /*indirect_type=*/true));
28861 }
28862
28863 if (const type_decl* ty1 = is_type_decl(first))
28864 {
28865 const type_decl* ty2 = is_type_decl(second);
28866 if (!indirect_type)
28867 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28868 return false;
28869
28870 return ty1->get_name() == ty2->get_name();
28871 }
28872
28873 if (const enum_type_decl* ty1 = is_enum_type(first))
28874 {
28875 const enum_type_decl* ty2 = is_enum_type(second);
28876 if (!indirect_type)
28877 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28878 return false;
28879
28880 return (get_name(ty1->get_underlying_type())
28881 == get_name(ty2->get_underlying_type()));
28882 }
28883
28884 if (const class_decl* ty1 = is_class_type(first))
28885 {
28886 const class_decl* ty2 = is_class_type(second);
28887 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28888 && ty1->get_name() != ty2->get_name())
28889 return false;
28890
28891 if (!indirect_type)
28892 {
28893 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28894 || (ty1->get_non_static_data_members().size()
28895 != ty2->get_non_static_data_members().size()))
28896 return false;
28897
28898 for (class_or_union::data_members::const_iterator
28899 i = ty1->get_non_static_data_members().begin(),
28900 j = ty2->get_non_static_data_members().begin();
28901 (i != ty1->get_non_static_data_members().end()
28902 && j != ty2->get_non_static_data_members().end());
28903 ++i, ++j)
28904 {
28905 var_decl_sptr dm1 = *i;
28906 var_decl_sptr dm2 = *j;
28907 if (!types_have_similar_structure(dm1->get_type().get(),
28908 dm2->get_type().get(),
28909 indirect_type))
28910 return false;
28911 }
28912 }
28913
28914 return true;
28915 }
28916
28917 if (const union_decl* ty1 = is_union_type(first))
28918 {
28919 const union_decl* ty2 = is_union_type(second);
28920 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28921 && ty1->get_name() != ty2->get_name())
28922 return false;
28923
28924 if (!indirect_type)
28925 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
28926
28927 return true;
28928 }
28929
28930 if (const array_type_def* ty1 = is_array_type(first))
28931 {
28932 const array_type_def* ty2 = is_array_type(second);
28933 if (!indirect_type)
28934 {
28935 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
28936 || ty1->get_dimension_count() != ty2->get_dimension_count())
28937 return false;
28938
28939 // Handle int[5][2] vs int[2][5] ...
28940 //
28941 // 6.2.5/20 of
28942 // https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
28943 // says:
28944 //
28945 // "Array types are characterized by their element
28946 // type and by the number of elements in the array"
28947 //
28948 // and 6.5.2.1/3 says:
28949 //
28950 // "arrays are stored in row-major order (last subscript
28951 // varies fastest)."
28952 //
28953 // So, let's ensure that all dimensions (sub-ranges) have
28954 // the same length.
28955
28956 for (auto r1 = ty1->get_subranges().begin(),
28957 r2 = ty1->get_subranges().begin();
28958 (r1 != ty1->get_subranges().end()
28959 && r2 != ty2->get_subranges().end());
28960 ++r1, ++r2)
28961 if ((*r1)->get_length() != (*r2)->get_length())
28962 return false;
28963 }
28964
28965 // ... then compare the elements of the arrays.
28966 if (!types_have_similar_structure(ty1->get_element_type(),
28967 ty2->get_element_type(),
28968 /*indirect_type=*/true))
28969 return false;
28970
28971 return true;
28972 }
28973
28974 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
28975 {
28977 if (ty1->get_upper_bound() != ty2->get_upper_bound()
28978 || ty1->get_lower_bound() != ty2->get_lower_bound()
28979 || ty1->get_language() != ty2->get_language()
28980 || !types_have_similar_structure(ty1->get_underlying_type(),
28981 ty2->get_underlying_type(),
28982 indirect_type))
28983 return false;
28984
28985 return true;
28986 }
28987
28988 if (const function_type* ty1 = is_function_type(first))
28989 {
28990 const function_type* ty2 = is_function_type(second);
28991 if (!types_have_similar_structure(ty1->get_return_type(),
28992 ty2->get_return_type(),
28993 indirect_type))
28994 return false;
28995
28996 if (ty1->get_parameters().size() != ty2->get_parameters().size())
28997 return false;
28998
28999 for (function_type::parameters::const_iterator
29000 i = ty1->get_parameters().begin(),
29001 j = ty2->get_parameters().begin();
29002 (i != ty1->get_parameters().end()
29003 && j != ty2->get_parameters().end());
29004 ++i, ++j)
29005 if (!types_have_similar_structure((*i)->get_type(),
29006 (*j)->get_type(),
29007 indirect_type))
29008 return false;
29009
29010 return true;
29011 }
29012
29013 // All kinds of type should have been handled at this point.
29015
29016 return false;
29017}
29018
29019/// Look for a data member of a given class, struct or union type and
29020/// return it.
29021///
29022/// The data member is designated by its name.
29023///
29024/// @param type the class, struct or union type to consider.
29025///
29026/// @param dm_name the name of the data member to lookup.
29027///
29028/// @return the data member iff it was found in @type or NULL if no
29029/// data member with that name was found.
29030const var_decl*
29032 const char* dm_name)
29033
29034{
29036 if (!cou)
29037 return 0;
29038
29039 return cou->find_data_member(dm_name).get();
29040}
29041
29042/// Look for a data member of a given class, struct or union type and
29043/// return it.
29044///
29045/// The data member is designated by its name.
29046///
29047/// @param type the class, struct or union type to consider.
29048///
29049/// @param dm the data member to lookup.
29050///
29051/// @return the data member iff it was found in @type or NULL if no
29052/// data member with that name was found.
29053const var_decl_sptr
29054lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
29055{
29056 class_or_union_sptr cou = is_class_or_union_type(type);
29057 if (!cou)
29058 return var_decl_sptr();
29059
29060 return cou->find_data_member(dm);
29061}
29062
29063/// Get the function parameter designated by its index.
29064///
29065/// Note that the first function parameter has index 0.
29066///
29067/// @param fun the function to consider.
29068///
29069/// @param parm_index the index of the function parameter to get.
29070///
29071/// @return the function parameter designated by its index, of NULL if
29072/// no function parameter with that index was found.
29075 unsigned parm_index)
29076{
29078 if (!fn)
29079 return 0;
29080
29081 const function_decl::parameters &parms = fn->get_type()->get_parameters();
29082 if (parms.size() <= parm_index)
29083 return 0;
29084
29085 return parms[parm_index].get();
29086}
29087
29088/// Build the internal name of the underlying type of an enum.
29089///
29090/// @param base_name the (unqualified) name of the enum the underlying
29091/// type is destined to.
29092///
29093/// @param is_anonymous true if the underlying type of the enum is to
29094/// be anonymous.
29095string
29097 bool is_anonymous,
29098 uint64_t size)
29099{
29100 std::ostringstream o;
29101
29102 if (is_anonymous)
29103 o << "unnamed-enum";
29104 else
29105 o << "enum-" << base_name;
29106
29107 o << "-underlying-type-" << size;
29108
29109 return o.str();
29110}
29111
29112/// Find the first data member of a class or union which name matches
29113/// a regular expression.
29114///
29115/// @param t the class or union to consider.
29116///
29117/// @param r the regular expression to consider.
29118///
29119/// @return the data member matched by @p r or nil if none was found.
29122 const regex::regex_t_sptr& r)
29123{
29124 for (auto data_member : t.get_data_members())
29125 {
29126 if (regex::match(r, data_member->get_name()))
29127 return data_member;
29128 }
29129
29130 return var_decl_sptr();
29131}
29132
29133/// Find the last data member of a class or union which name matches
29134/// a regular expression.
29135///
29136/// @param t the class or union to consider.
29137///
29138/// @param r the regular expression to consider.
29139///
29140/// @return the data member matched by @p r or nil if none was found.
29144{
29145 auto d = t.get_data_members().rbegin();
29146 auto e = t.get_data_members().rend();
29147 for (; d != e; ++d)
29148 {
29149 if (regex::match(regex, (*d)->get_name()))
29150 return *d;
29151 }
29152
29153 return var_decl_sptr();
29154}
29155
29156/// Emit the pretty representation of the parameters of a function
29157/// type.
29158///
29159/// @param fn_type the function type to consider.
29160///
29161/// @param o the output stream to emit the pretty representation to.
29162///
29163/// @param qualified if true, emit fully qualified names.
29164///
29165/// @param internal if true, then the result is to be used for the
29166/// purpose of type canonicalization.
29167static void
29168stream_pretty_representation_of_fn_parms(const function_type& fn_type,
29169 ostream& o, bool qualified,
29170 bool internal)
29171{
29172 o << "(";
29173 if (fn_type.get_parameters().empty())
29174 o << "void";
29175 else
29176 {
29177 type_base_sptr type;
29178 auto end = fn_type.get_parameters().end();
29179 auto first_parm = fn_type.get_first_non_implicit_parm();
29181 const environment& env = fn_type.get_environment();
29182 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
29183 {
29184 if (i != first_parm)
29185 o << ", ";
29186 parm = *i;
29187 type = parm->get_type();
29188 // If the type is a decl-only class, union or enum that has a
29189 // definition, use the definition instead. That definition
29190 // is what is going to be serialized out in ABIXML anyway,
29191 // so use that for consistency.
29192 if (decl_base_sptr def = look_through_decl_only(is_decl(type)))
29193 type = is_type(def);
29194 if (env.is_variadic_parameter_type(type))
29195 o << "...";
29196 else
29197 o << get_type_name(type, qualified, internal);
29198 }
29199 }
29200 o << ")";
29201}
29202
29203/// When constructing the name of a pointer to function type, add the
29204/// return type to the left of the existing type identifier, and the
29205/// parameters declarator to the right.
29206///
29207/// This function considers the name of the type as an expression.
29208///
29209/// The resulting type expr is going to be made of three parts:
29210/// left_expr inner_expr right_expr.
29211///
29212/// Suppose we want to build the type expression representing:
29213///
29214/// "an array of pointer to function taking a char parameter and
29215/// returning an int".
29216///
29217/// It's going to look like:
29218///
29219/// int(*a[])(char);
29220///
29221/// Suppose the caller of this function started to emit the inner
29222/// "a[]" part of the expression already. It thus calls this
29223/// function with that input "a[]" part. We consider that "a[]" as
29224/// the "type identifier".
29225///
29226/// So the inner_expr is going to be "(*a[])".
29227///
29228/// The left_expr part is "int". The right_expr part is "(char)".
29229///
29230/// In other words, this function adds the left_expr and right_expr to
29231/// the inner_expr. left_expr and right_expr are called "outer
29232/// pointer to function type expression".
29233///
29234/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29235/// array_declaration_name()
29236///
29237/// @param p the pointer to function type to consider.
29238///
29239/// @param input the type-id to use as the inner expression of the
29240/// overall pointer-to-function type expression
29241///
29242/// @param qualified if true then use qualified names in the resulting
29243/// type name.
29244///
29245/// @param internal if true then the resulting type name is going to
29246/// be used for type canonicalization purposes.
29247///
29248/// @return the name of the pointer to function type.
29249static string
29250add_outer_pointer_to_fn_type_expr(const type_base* p,
29251 const string& input,
29252 bool qualified, bool internal)
29253{
29254 if (!p)
29255 return "";
29256
29257 function_type_sptr pointed_to_fn;
29258 string star_or_ref;
29259
29260 if (const pointer_type_def* ptr = is_pointer_type(p))
29261 {
29262 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
29263 star_or_ref= "*";
29264 }
29265 else if (const reference_type_def* ref = is_reference_type(p))
29266 {
29267 star_or_ref = "&";
29268 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
29269 }
29270
29271 if (!pointed_to_fn)
29272 return "";
29273
29274 if (pointed_to_fn->priv_->is_pretty_printing())
29275 // We have just detected a cycle while walking the sub-tree of
29276 // this function type for the purpose of printing its
29277 // representation. We need to get out of here pronto or else
29278 // we'll be spinning endlessly.
29279 return "";
29280
29281 // Let's mark thie function type to signify that we started walking
29282 // its subtree. This is to detect potential cycles and avoid
29283 // looping endlessly.
29284 pointed_to_fn->priv_->set_is_pretty_printing();
29285
29286 std::ostringstream left, right, inner;
29287
29288 inner << "(" << star_or_ref << input << ")";
29289
29290 type_base_sptr type;
29291 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
29292 qualified, internal);
29293
29294 type_base_sptr return_type = pointed_to_fn->get_return_type();
29295 string result;
29296
29297 if (is_npaf_type(return_type)
29298 || !(is_pointer_to_function_type(return_type)
29299 || is_pointer_to_array_type(return_type)))
29300 {
29301 if (return_type)
29302 left << get_type_name(return_type, qualified, internal);
29303 result = left.str() + " " + inner.str() + right.str();
29304 }
29305 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
29306 {
29307 string inner_string = inner.str() + right.str();
29308 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
29309 qualified, internal);
29310 }
29311 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
29312 {
29313 string inner_string = inner.str() + right.str();
29314 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29315 qualified, internal);
29316 }
29317 else
29319
29320 // Lets unmark this function type to signify that we are done
29321 // walking its subtree. This was to detect potential cycles and
29322 // avoid looping endlessly.
29323 pointed_to_fn->priv_->unset_is_pretty_printing();
29324 return result;
29325}
29326
29327/// When constructing the name of a pointer to function type, add the
29328/// return type to the left of the existing type identifier, and the
29329/// parameters declarator to the right.
29330///
29331/// This function considers the name of the type as an expression.
29332///
29333/// The resulting type expr is going to be made of three parts:
29334/// left_expr inner_expr right_expr.
29335///
29336/// Suppose we want to build the type expression representing:
29337///
29338/// "an array of pointer to function taking a char parameter and
29339/// returning an int".
29340///
29341/// It's going to look like:
29342///
29343/// int(*a[])(char);
29344///
29345/// Suppose the caller of this function started to emit the inner
29346/// "a[]" part of the expression already. It thus calls this
29347/// function with that input "a[]" part. We consider that "a[]" as
29348/// the "type identifier".
29349///
29350/// So the inner_expr is going to be "(*a[])".
29351///
29352/// The left_expr part is "int". The right_expr part is "(char)".
29353///
29354/// In other words, this function adds the left_expr and right_expr to
29355/// the inner_expr. left_expr and right_expr are called "outer
29356/// pointer to function type expression".
29357///
29358/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29359/// array_declaration_name()
29360///
29361/// @param p the pointer to function type to consider.
29362///
29363/// @param input the type-id to use as the inner expression of the
29364/// overall pointer-to-function type expression
29365///
29366/// @param qualified if true then use qualified names in the resulting
29367/// type name.
29368///
29369/// @param internal if true then the resulting type name is going to
29370/// be used for type canonicalization purposes.
29371///
29372/// @return the name of the pointer to function type.
29373static string
29374add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
29375 const string& input,
29376 bool qualified, bool internal)
29377{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
29378
29379/// When constructing the name of a pointer to array type, add the
29380/// array element type type to the left of the existing type
29381/// identifier, and the array declarator part to the right.
29382///
29383/// This function considers the name of the type as an expression.
29384///
29385/// The resulting type expr is going to be made of three parts:
29386/// left_expr inner_expr right_expr.
29387///
29388/// Suppose we want to build the type expression representing:
29389///
29390/// "a pointer to an array of int".
29391///
29392/// It's going to look like:
29393///
29394/// int(*foo)[];
29395///
29396/// Suppose the caller of this function started to emit the inner
29397/// "foo" part of the expression already. It thus calls this function
29398/// with that input "foo" part. We consider that "foo" as the "type
29399/// identifier".
29400///
29401/// So we are passed an input string that is "foo" and it's going to
29402/// be turned into the inner_expr part, which is going to be "(*foo)".
29403///
29404/// The left_expr part is "int". The right_expr part is "[]".
29405///
29406/// In other words, this function adds the left_expr and right_expr to
29407/// the inner_expr. left_expr and right_expr are called "outer
29408/// pointer to array type expression".
29409///
29410/// The model of this function was taken from the article "Reading C
29411/// type declaration", from Steve Friedl at
29412/// http://unixwiz.net/techtips/reading-cdecl.html.
29413///
29414/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29415/// array_declaration_name()
29416///
29417/// @param p the pointer to array type to consider.
29418///
29419/// @param input the type-id to start from as the inner part of the
29420/// final type name.
29421///
29422/// @param qualified if true then use qualified names in the resulting
29423/// type name.
29424///
29425/// @param internal if true then the resulting type name is going to
29426/// be used for type canonicalization purposes.
29427///
29428/// @return the name of the pointer to array type.
29429static string
29430add_outer_pointer_to_array_type_expr(const type_base* p,
29431 const string& input, bool qualified,
29432 bool internal)
29433{
29434 if (!p)
29435 return "";
29436
29437 string star_or_ref;
29438 type_base_sptr pointed_to_type;
29439
29440 if (const pointer_type_def *ptr = is_pointer_type(p))
29441 {
29442 pointed_to_type = ptr->get_pointed_to_type();
29443 star_or_ref = "*";
29444 }
29445 else if (const reference_type_def *ref = is_reference_type(p))
29446 {
29447 pointed_to_type = ref->get_pointed_to_type();
29448 star_or_ref = "&";
29449 }
29450
29451 array_type_def_sptr array = is_array_type(pointed_to_type);
29452 if (!array)
29453 return "";
29454
29455 std::ostringstream left, right, inner;
29456 inner << "(" << star_or_ref << input << ")";
29457 right << array->get_subrange_representation();
29458 string result;
29459
29460 type_base_sptr array_element_type = array->get_element_type();
29461
29462 if (is_npaf_type(array_element_type)
29463 || !(is_pointer_to_function_type(array_element_type)
29464 || is_pointer_to_array_type(array_element_type)))
29465 {
29466 left << get_type_name(array_element_type, qualified, internal);
29467 result = left.str() + inner.str() + right.str();
29468 }
29469 else if (pointer_type_def_sptr p =
29470 is_pointer_to_function_type(array_element_type))
29471 {
29472 string r = inner.str() + right.str();
29473 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
29474 }
29475 else if (pointer_type_def_sptr p =
29476 is_pointer_to_array_type(array_element_type))
29477 {
29478 string inner_string = inner.str() + right.str();
29479 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29480 qualified, internal);
29481 }
29482 else
29484
29485 return result;
29486}
29487
29488/// When constructing the name of a pointer to array type, add the
29489/// array element type type to the left of the existing type
29490/// identifier, and the array declarator part to the right.
29491///
29492/// This function considers the name of the type as an expression.
29493///
29494/// The resulting type expr is going to be made of three parts:
29495/// left_expr inner_expr right_expr.
29496///
29497/// Suppose we want to build the type expression representing:
29498///
29499/// "a pointer to an array of int".
29500///
29501/// It's going to look like:
29502///
29503/// int(*foo)[];
29504///
29505/// Suppose the caller of this function started to emit the inner
29506/// "foo" part of the expression already. It thus calls this function
29507/// with that input "foo" part. We consider that "foo" as the "type
29508/// identifier".
29509///
29510/// So we are passed an input string that is "foo" and it's going to
29511/// be turned into the inner_expr part, which is going to be "(*foo)".
29512///
29513/// The left_expr part is "int". The right_expr part is "[]".
29514///
29515/// In other words, this function adds the left_expr and right_expr to
29516/// the inner_expr. left_expr and right_expr are called "outer
29517/// pointer to array type expression".
29518///
29519/// The model of this function was taken from the article "Reading C
29520/// type declaration", from Steve Friedl at
29521/// http://unixwiz.net/techtips/reading-cdecl.html.
29522///
29523/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29524/// array_declaration_name()
29525///
29526/// @param p the pointer to array type to consider.
29527///
29528/// @param input the type-id to start from as the inner part of the
29529/// final type name.
29530///
29531/// @param qualified if true then use qualified names in the resulting
29532/// type name.
29533///
29534/// @param internal if true then the resulting type name is going to
29535/// be used for type canonicalization purposes.
29536///
29537/// @return the name of the pointer to array type.
29538static string
29539add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
29540 const string& input, bool qualified,
29541 bool internal)
29542{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
29543 input, qualified, internal);}
29544
29545/// When constructing the name of a pointer to mebmer type, add the
29546/// return type to the left of the existing type identifier, and the
29547/// parameters declarator to the right.
29548///
29549/// This function considers the name of the type as an expression.
29550///
29551/// The resulting type expr is going to be made of three parts:
29552/// left_expr inner_expr right_expr.
29553///
29554/// Suppose we want to build the type expression representing:
29555///
29556/// "an array of pointer to member function (of a containing struct
29557/// X) taking a char parameter and returning an int".
29558///
29559/// It's going to look like:
29560///
29561/// int (X::* a[])(char);
29562///
29563/// Suppose the caller of this function started to emit the inner
29564/// "a[]" part of the expression already. It thus calls this
29565/// function with that input "a[]" part. We consider that "a[]" as
29566/// the "type identifier".
29567///
29568/// So the inner_expr is going to be "(X::* a[])".
29569///
29570/// The left_expr part is "int". The right_expr part is "(char)".
29571///
29572/// In other words, this function adds the left_expr and right_expr to
29573/// the inner_expr. left_expr and right_expr are called "outer
29574/// pointer to member type expression".
29575///
29576/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29577///
29578/// @param p the pointer to member type to consider.
29579///
29580/// @param input the type-id to use as the inner expression of the
29581/// overall pointer-to-member type expression
29582///
29583/// @param qualified if true then use qualified names in the resulting
29584/// type name.
29585///
29586/// @param internal if true then the resulting type name is going to
29587/// be used for type canonicalization purposes.
29588///
29589/// @return the name of the pointer to member type.
29590static string
29591add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
29592 const string& input, bool qualified,
29593 bool internal)
29594{
29595 if (!p)
29596 return "";
29597
29598 std::ostringstream left, right, inner;
29599 type_base_sptr void_type = p->get_environment().get_void_type();
29600 string containing_type_name = get_type_name(p->get_containing_type(),
29601 qualified, internal);
29602 type_base_sptr mbr_type = p->get_member_type();
29603 string result;
29604 if (function_type_sptr fn_type = is_function_type(mbr_type))
29605 {
29606 inner << "(" << containing_type_name << "::*" << input << ")";
29607 stream_pretty_representation_of_fn_parms(*fn_type, right,
29608 qualified, internal);
29609 type_base_sptr return_type = fn_type->get_return_type();
29610 if (!return_type)
29611 return_type = void_type;
29612 if (is_npaf_type(return_type)
29613 || !(is_pointer_to_function_type(return_type)
29614 || is_pointer_to_array_type(return_type)
29615 || is_pointer_to_ptr_to_mbr_type(return_type)
29616 || is_ptr_to_mbr_type(return_type)))
29617 {
29618 left << get_type_name(return_type, qualified, internal) << " ";;
29619 result = left.str() + inner.str() + right.str();
29620 }
29621 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
29622 {
29623 string inner_str = inner.str() + right.str();
29624 result = pointer_declaration_name(p, inner_str, qualified, internal);
29625 }
29626 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
29627 {
29628 string inner_str = inner.str() + right.str();
29629 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
29630 qualified, internal);
29631 }
29632 else
29634 }
29635 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
29636 {
29637 inner << "(" << containing_type_name << "::*" << input << ")";
29638 stream_pretty_representation_of_fn_parms(*fn_type, right,
29639 qualified, internal);
29640 string inner_str = inner.str() + right.str();
29641 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
29642 qualified, internal);
29643 }
29644 else
29645 {
29646 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
29647 inner << containing_type_name << "::*" << input;
29648 result = left.str()+ inner.str();
29649 }
29650
29651 return result;
29652}
29653
29654/// Test if two decls have different names.
29655///
29656/// Note that this function takes into account decls whose names are
29657/// relevant from an ABI standpoint. For instance, function parameter
29658/// names are not relevant in that context.
29659///
29660/// @param d1 the first declaration to consider.
29661///
29662/// @param d2 the second declaration to consider.
29663///
29664/// @return true if d1 and d2 have different names.
29665bool
29667{
29668 string d1_name, d2_name;
29669
29670 const decl_base *d1 = dynamic_cast<const decl_base*>(a1);
29671 if (d1 == 0)
29672 return false;
29673
29674 const decl_base *d2 = dynamic_cast<const decl_base*>(a2);
29675 if (d2 == 0)
29676 return false;
29677
29679 // Name changes for fn parms are irrelevant.
29680 return false;
29681
29682 d1_name = d1->get_qualified_name();
29683 d2_name = d2->get_qualified_name();
29684
29685 return d1_name != d2_name;
29686}
29687
29688/// Test if two decls have different names.
29689///
29690/// @param d1 the first declaration to consider.
29691///
29692/// @param d2 the second declaration to consider.
29693///
29694/// @return true if d1 and d2 have different names.
29695bool
29697 const type_or_decl_base_sptr& d2)
29698{return decl_name_changed(d1.get(), d2.get());}
29699
29700/// Test if a diff node carries a change whereby two integral types
29701/// have different names in a harmless way.
29702///
29703/// Basically, if the integral type name change is accompanied by a
29704/// size change then the change is considered harmful. If there are
29705/// modifiers change, the change is considered harmful.
29706bool
29708 const type_base_sptr& s)
29709{
29710 if (is_decl(f)
29711 && is_decl(s)
29712 && ((is_integral_type(f) && is_integral_type(s))
29713 || (is_decl(f)->get_name().empty()
29714 && is_type_decl(f)
29715 && is_integral_type(s))
29716 || (is_decl(s)->get_name().empty()
29717 && is_type_decl(s)
29718 && is_integral_type(f)))
29720 && (f->get_size_in_bits() == s->get_size_in_bits())
29721 && (f->get_alignment_in_bits() == s->get_alignment_in_bits()))
29722 return true;
29723
29724 return false;
29725}
29726
29727/// Test if a diff node carries a change whereby two integral types
29728/// have different names in a harmless way.
29729///
29730/// Basically, if the integral type name change is accompanied by a
29731/// size change then the change is considered harmful. If there are
29732/// modifiers change, the change is considered harmful.
29733bool
29735 const decl_base_sptr& s)
29737
29738
29739/// When constructing the name of a pointer to mebmer type, add the
29740/// return type to the left of the existing type identifier, and the
29741/// parameters declarator to the right.
29742///
29743/// This function considers the name of the type as an expression.
29744///
29745/// The resulting type expr is going to be made of three parts:
29746/// left_expr inner_expr right_expr.
29747///
29748/// Suppose we want to build the type expression representing:
29749///
29750/// "an array of pointer to member function (of a containing struct
29751/// X) taking a char parameter and returning an int".
29752///
29753/// It's going to look like:
29754///
29755/// int (X::* a[])(char);
29756///
29757/// Suppose the caller of this function started to emit the inner
29758/// "a[]" part of the expression already. It thus calls this
29759/// function with that input "a[]" part. We consider that "a[]" as
29760/// the "type identifier".
29761///
29762/// So the inner_expr is going to be "(X::* a[])".
29763///
29764/// The left_expr part is "int". The right_expr part is "(char)".
29765///
29766/// In other words, this function adds the left_expr and right_expr to
29767/// the inner_expr. left_expr and right_expr are called "outer
29768/// pointer to member type expression".
29769///
29770/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29771///
29772/// @param p the pointer to member type to consider.
29773///
29774/// @param input the type-id to use as the inner expression of the
29775/// overall pointer-to-member type expression
29776///
29777/// @param qualified if true then use qualified names in the resulting
29778/// type name.
29779///
29780/// @param internal if true then the resulting type name is going to
29781/// be used for type canonicalization purposes.
29782///
29783/// @return the name of the pointer to member type.
29784static string
29785add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
29786 const string& input, bool qualified,
29787 bool internal)
29788{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
29789
29790/// This adds the outer parts of a pointer to a pointer-to-member
29791/// expression.
29792///
29793/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
29794/// learn more about this function, which is similar.
29795///
29796/// This is a sub-routine of @ref pointer_declaration_name().
29797///
29798/// @param a pointer (or reference) to a pointer-to-member type.
29799///
29800/// @param input the inner type-id to add the outer parts to.
29801///
29802/// @param qualified if true then use qualified names in the resulting
29803/// type name.
29804///
29805/// @param internal if true then the resulting type name is going to
29806/// be used for type canonicalization purposes.
29807static string
29808add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
29809 const string& input, bool qualified,
29810 bool internal)
29811{
29812 if (!p)
29813 return "";
29814
29815 string star_or_ref;
29816 type_base_sptr pointed_to_type;
29817
29818 if (const pointer_type_def* ptr = is_pointer_type(p))
29819 {
29820 pointed_to_type = ptr->get_pointed_to_type();
29821 star_or_ref = "*";
29822 }
29823 else if (const reference_type_def* ref = is_reference_type(p))
29824 {
29825 pointed_to_type= ref->get_pointed_to_type();
29826 star_or_ref = "&";
29827 }
29828
29829 if (!pointed_to_type)
29830 return "";
29831
29832 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
29833 is_ptr_to_mbr_type(pointed_to_type);
29834 if (!pointed_to_ptr_to_mbr)
29835 return "";
29836
29837 std::ostringstream inner;
29838 inner << star_or_ref << input;
29839 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
29840 inner.str(),
29841 qualified, internal);
29842 return result;
29843}
29844
29845/// Emit the name of a pointer declaration.
29846///
29847/// @param the pointer to consider.
29848///
29849/// @param idname the name of the variable that has @p as a type or
29850/// the id of the type. If it's empty then the resulting name is
29851/// going to be the abstract name of the type.
29852///
29853/// @param qualified if true then the type name is going to be
29854/// fully qualified.
29855///
29856/// @param internal if true then the type name is going to be used for
29857/// type canonicalization purposes.
29858static interned_string
29859pointer_declaration_name(const type_base* ptr,
29860 const string& idname,
29861 bool qualified, bool internal)
29862{
29863 if (!ptr)
29864 return interned_string();
29865
29866 type_base_sptr pointed_to_type;
29867 string star_or_ref;
29868 if (const pointer_type_def* p = is_pointer_type(ptr))
29869 {
29870 pointed_to_type = p->get_pointed_to_type();
29871 star_or_ref = "*";
29872 }
29873 else if (const reference_type_def* p = is_reference_type(ptr))
29874 {
29875 pointed_to_type = p->get_pointed_to_type();
29876 star_or_ref = "&";
29877 }
29878
29879 if (!pointed_to_type)
29880 return interned_string();
29881
29882 string result;
29883 if (is_npaf_type(pointed_to_type)
29884 || !(is_function_type(pointed_to_type)
29885 || is_array_type(pointed_to_type)
29886 || is_ptr_to_mbr_type(pointed_to_type)))
29887 {
29888 result = get_type_name(pointed_to_type,
29889 qualified,
29890 internal)
29891 + star_or_ref;
29892
29893 if (!idname.empty())
29894 result += idname;
29895 }
29896 else
29897 {
29898 // derived type
29899 if (is_function_type(pointed_to_type))
29900 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29901 qualified, internal);
29902 else if (is_array_type(pointed_to_type))
29903 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29904 qualified, internal);
29905 else if (is_ptr_to_mbr_type(pointed_to_type))
29906 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29907 qualified, internal);
29908 else
29910 }
29911 return ptr->get_environment().intern(result);
29912}
29913
29914
29915/// Emit the name of a pointer declaration.
29916///
29917/// @param the pointer to consider.
29918///
29919/// @param the name of the variable that has @p as a type. If it's
29920/// empty then the resulting name is going to be the abstract name of
29921/// the type.
29922///
29923/// @param qualified if true then the type name is going to be
29924/// fully qualified.
29925///
29926/// @param internal if true then the type name is going to be used for
29927/// type canonicalization purposes.
29928static interned_string
29929pointer_declaration_name(const type_base_sptr& ptr,
29930 const string& variable_name,
29931 bool qualified, bool internal)
29932{return pointer_declaration_name(ptr.get(), variable_name,
29933 qualified, internal);}
29934
29935/// Emit the name of a array declaration.
29936///
29937/// @param the array to consider.
29938///
29939/// @param the name of the variable that has @p as a type. If it's
29940/// empty then the resulting name is going to be the abstract name of
29941/// the type.
29942///
29943/// @param qualified if true then the type name is going to be
29944/// fully qualified.
29945///
29946/// @param internal if true then the type name is going to be used for
29947/// type canonicalization purposes.
29948static interned_string
29949array_declaration_name(const array_type_def* array,
29950 const string& variable_name,
29951 bool qualified, bool internal)
29952{
29953 if (!array)
29954 return interned_string();
29955
29956 type_base_sptr e_type = array->get_element_type();
29957 string e_type_repr =
29958 (e_type
29959 ? get_type_name(e_type, qualified, internal)
29960 : string("void"));
29961
29962 string result;
29963 if (is_ada_language(array->get_language()))
29964 {
29965 std::ostringstream o;
29966 if (!variable_name.empty())
29967 o << variable_name << " is ";
29968 o << "array ("
29969 << array->get_subrange_representation()
29970 << ") of " << e_type_repr;
29971 result = o.str();
29972 }
29973 else
29974 {
29975 if (is_npaf_type(e_type)
29976 || !(is_pointer_to_function_type(e_type)
29977 || is_pointer_to_array_type(e_type)
29978 || is_pointer_to_ptr_to_mbr_type(e_type)
29979 || is_ptr_to_mbr_type(e_type)))
29980 {
29981 result = e_type_repr;
29982 if (!variable_name.empty())
29983 result += variable_name;
29984 result += array->get_subrange_representation();
29985 }
29986 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
29987 {
29988 string s = variable_name + array->get_subrange_representation();
29989 result = pointer_declaration_name(p, s, qualified, internal);
29990 }
29991 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
29992 {
29993 string s = variable_name + array->get_subrange_representation();
29994 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
29995 }
29996 else
29998 }
29999 return array->get_environment().intern(result);
30000}
30001
30002/// Emit the name of a array declaration.
30003///
30004/// @param the array to consider.
30005///
30006/// @param the name of the variable that has @p as a type. If it's
30007/// empty then the resulting name is going to be the abstract name of
30008/// the type.
30009///
30010/// @param qualified if true then the type name is going to be
30011/// fully qualified.
30012///
30013/// @param internal if true then the type name is going to be used for
30014/// type canonicalization purposes.
30015static interned_string
30016array_declaration_name(const array_type_def_sptr& array,
30017 const string& variable_name,
30018 bool qualified, bool internal)
30019{return array_declaration_name(array.get(), variable_name,
30020 qualified, internal);}
30021
30022/// Emit the name of a pointer-to-member declaration.
30023///
30024/// @param ptr the pointer-to-member to consider.
30025///
30026/// @param variable_name the name of the variable that has @p as a
30027/// type. If it's empty then the resulting name is going to be the
30028/// abstract name of the type.
30029///
30030/// @param qualified if true then the type name is going to be
30031/// fully qualified.
30032///
30033/// @param internal if true then the type name is going to be used for
30034/// type canonicalization purposes.
30035static interned_string
30036ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
30037 const string& variable_name,
30038 bool qualified, bool internal)
30039{
30040 if (!ptr)
30041 return interned_string();
30042
30043 string input = variable_name;
30044 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
30045 qualified, internal);
30046 return ptr->get_environment().intern(result);
30047}
30048
30049/// Emit the name of a pointer-to-member declaration.
30050///
30051/// @param ptr the pointer-to-member to consider.
30052///
30053/// @param variable_name the name of the variable that has @p as a
30054/// type. If it's empty then the resulting name is going to be the
30055/// abstract name of the type.
30056///
30057/// @param qualified if true then the type name is going to be
30058/// fully qualified.
30059///
30060/// @param internal if true then the type name is going to be used for
30061/// type canonicalization purposes.
30062static interned_string
30063ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
30064 const string& variable_name,
30065 bool qualified, bool internal)
30066{
30067 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
30068 qualified, internal);
30069}
30070
30071/// Sort types right before hashing and canonicalizing them.
30072///
30073/// @param types the vector of types to sort.
30074void
30079
30080bool
30083
30084// <ir_node_visitor stuff>
30085
30086/// The private data structure of the ir_node_visitor type.
30087struct ir_node_visitor::priv
30088{
30089 pointer_set visited_ir_nodes;
30091
30092 priv()
30094 {}
30095}; // end struct ir_node_visitory::priv
30096
30097/// Default Constructor of the ir_node_visitor type.
30099 : priv_(new priv)
30100{}
30101
30102ir_node_visitor::~ir_node_visitor() = default;
30103
30104/// Set if the walker using this visitor is allowed to re-visit a type
30105/// node that was previously visited or not.
30106///
30107/// @param f if true, then the walker using this visitor is allowed to
30108/// re-visit a type node that was previously visited.
30109void
30111{priv_->allow_visiting_already_visited_type_node = f;}
30112
30113/// Get if the walker using this visitor is allowed to re-visit a type
30114/// node that was previously visited or not.
30115///
30116/// @return true iff the walker using this visitor is allowed to
30117/// re-visit a type node that was previously visited.
30118bool
30120{return priv_->allow_visiting_already_visited_type_node;}
30121
30122/// Mark a given type node as having been visited.
30123///
30124/// Note that for this function to work, the type node must have been
30125/// canonicalized. Otherwise the process is aborted.
30126///
30127/// @param p the type to mark as having been visited.
30128void
30130{
30132 return;
30133
30134 if (p == 0 || type_node_has_been_visited(p))
30135 return;
30136
30137 type_base* canonical_type = p->get_naked_canonical_type();
30139 {
30140 ABG_ASSERT(!canonical_type);
30141 canonical_type = p;
30142 }
30143 ABG_ASSERT(canonical_type);
30144
30145 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
30146 priv_->visited_ir_nodes.insert(canonical_ptr_value);
30147}
30148
30149/// Un-mark all visited type nodes.
30150///
30151/// That is, no type node is going to be considered as having been
30152/// visited anymore.
30153///
30154/// In other words, after invoking this funciton,
30155/// ir_node_visitor::type_node_has_been_visited() is going to return
30156/// false on all type nodes.
30157void
30159{priv_->visited_ir_nodes.clear();}
30160
30161/// Test if a given type node has been marked as visited.
30162///
30163/// @param p the type node to consider.
30164///
30165/// @return true iff the type node @p p has been marked as visited by
30166/// the function ir_node_visitor::mark_type_node_as_visited.
30167bool
30169{
30171 return false;
30172
30173 if (p == 0)
30174 return false;
30175
30176 type_base *canonical_type = p->get_naked_canonical_type();
30178 {
30179 ABG_ASSERT(!canonical_type);
30180 canonical_type = p;
30181 }
30182 ABG_ASSERT(canonical_type);
30183
30184 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
30185 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
30186 if (it == priv_->visited_ir_nodes.end())
30187 return false;
30188
30189 return true;
30190}
30191
30192bool
30193ir_node_visitor::visit_begin(decl_base*)
30194{return true;}
30195
30196bool
30197ir_node_visitor::visit_end(decl_base*)
30198{return true;}
30199
30200bool
30201ir_node_visitor::visit_begin(scope_decl*)
30202{return true;}
30203
30204bool
30205ir_node_visitor::visit_end(scope_decl*)
30206{return true;}
30207
30208bool
30209ir_node_visitor::visit_begin(type_base*)
30210{return true;}
30211
30212bool
30213ir_node_visitor::visit_end(type_base*)
30214{return true;}
30215
30216bool
30217ir_node_visitor::visit_begin(scope_type_decl* t)
30218{return visit_begin(static_cast<type_base*>(t));}
30219
30220bool
30221ir_node_visitor::visit_end(scope_type_decl* t)
30222{return visit_end(static_cast<type_base*>(t));}
30223
30224bool
30225ir_node_visitor::visit_begin(type_decl* t)
30226{return visit_begin(static_cast<type_base*>(t));}
30227
30228bool
30229ir_node_visitor::visit_end(type_decl* t)
30230{return visit_end(static_cast<type_base*>(t));}
30231
30232bool
30233ir_node_visitor::visit_begin(namespace_decl* d)
30234{return visit_begin(static_cast<decl_base*>(d));}
30235
30236bool
30237ir_node_visitor::visit_end(namespace_decl* d)
30238{return visit_end(static_cast<decl_base*>(d));}
30239
30240bool
30241ir_node_visitor::visit_begin(qualified_type_def* t)
30242{return visit_begin(static_cast<type_base*>(t));}
30243
30244bool
30245ir_node_visitor::visit_end(qualified_type_def* t)
30246{return visit_end(static_cast<type_base*>(t));}
30247
30248bool
30249ir_node_visitor::visit_begin(pointer_type_def* t)
30250{return visit_begin(static_cast<type_base*>(t));}
30251
30252bool
30253ir_node_visitor::visit_end(pointer_type_def* t)
30254{return visit_end(static_cast<type_base*>(t));}
30255
30256bool
30257ir_node_visitor::visit_begin(reference_type_def* t)
30258{return visit_begin(static_cast<type_base*>(t));}
30259
30260bool
30261ir_node_visitor::visit_end(reference_type_def* t)
30262{return visit_end(static_cast<type_base*>(t));}
30263
30264bool
30265ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
30266{return visit_begin(static_cast<type_base*>(t));}
30267
30268bool
30269ir_node_visitor::visit_end(ptr_to_mbr_type* t)
30270{return visit_end(static_cast<type_base*>(t));}
30271
30272bool
30273ir_node_visitor::visit_begin(array_type_def* t)
30274{return visit_begin(static_cast<type_base*>(t));}
30275
30276bool
30277ir_node_visitor::visit_end(array_type_def* t)
30278{return visit_end(static_cast<type_base*>(t));}
30279
30280bool
30281ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
30282{return visit_begin(static_cast<type_base*>(t));}
30283
30284bool
30285ir_node_visitor::visit_end(array_type_def::subrange_type* t)
30286{return visit_end(static_cast<type_base*>(t));}
30287
30288bool
30289ir_node_visitor::visit_begin(enum_type_decl* t)
30290{return visit_begin(static_cast<type_base*>(t));}
30291
30292bool
30293ir_node_visitor::visit_end(enum_type_decl* t)
30294{return visit_end(static_cast<type_base*>(t));}
30295
30296bool
30297ir_node_visitor::visit_begin(typedef_decl* t)
30298{return visit_begin(static_cast<type_base*>(t));}
30299
30300bool
30301ir_node_visitor::visit_end(typedef_decl* t)
30302{return visit_end(static_cast<type_base*>(t));}
30303
30304bool
30305ir_node_visitor::visit_begin(function_type* t)
30306{return visit_begin(static_cast<type_base*>(t));}
30307
30308bool
30309ir_node_visitor::visit_end(function_type* t)
30310{return visit_end(static_cast<type_base*>(t));}
30311
30312bool
30313ir_node_visitor::visit_begin(var_decl* d)
30314{return visit_begin(static_cast<decl_base*>(d));}
30315
30316bool
30317ir_node_visitor::visit_end(var_decl* d)
30318{return visit_end(static_cast<decl_base*>(d));}
30319
30320bool
30321ir_node_visitor::visit_begin(function_decl* d)
30322{return visit_begin(static_cast<decl_base*>(d));}
30323
30324bool
30325ir_node_visitor::visit_end(function_decl* d)
30326{return visit_end(static_cast<decl_base*>(d));}
30327
30328bool
30329ir_node_visitor::visit_begin(function_decl::parameter* d)
30330{return visit_begin(static_cast<decl_base*>(d));}
30331
30332bool
30333ir_node_visitor::visit_end(function_decl::parameter* d)
30334{return visit_end(static_cast<decl_base*>(d));}
30335
30336bool
30337ir_node_visitor::visit_begin(function_tdecl* d)
30338{return visit_begin(static_cast<decl_base*>(d));}
30339
30340bool
30341ir_node_visitor::visit_end(function_tdecl* d)
30342{return visit_end(static_cast<decl_base*>(d));}
30343
30344bool
30345ir_node_visitor::visit_begin(class_tdecl* d)
30346{return visit_begin(static_cast<decl_base*>(d));}
30347
30348bool
30349ir_node_visitor::visit_end(class_tdecl* d)
30350{return visit_end(static_cast<decl_base*>(d));}
30351
30352bool
30353ir_node_visitor::visit_begin(class_or_union* t)
30354{return visit_begin(static_cast<type_base*>(t));}
30355
30356bool
30357ir_node_visitor::visit_end(class_or_union* t)
30358{return visit_end(static_cast<type_base*>(t));}
30359
30360bool
30361ir_node_visitor::visit_begin(class_decl* t)
30362{return visit_begin(static_cast<type_base*>(t));}
30363
30364bool
30365ir_node_visitor::visit_end(class_decl* t)
30366{return visit_end(static_cast<type_base*>(t));}
30367
30368bool
30369ir_node_visitor::visit_begin(union_decl* t)
30370{return visit_begin(static_cast<type_base*>(t));}
30371
30372bool
30373ir_node_visitor::visit_end(union_decl* t)
30374{return visit_end(static_cast<type_base*>(t));}
30375
30376bool
30377ir_node_visitor::visit_begin(class_decl::base_spec* d)
30378{return visit_begin(static_cast<decl_base*>(d));}
30379
30380bool
30381ir_node_visitor::visit_end(class_decl::base_spec* d)
30382{return visit_end(static_cast<decl_base*>(d));}
30383
30384bool
30385ir_node_visitor::visit_begin(member_function_template* d)
30386{return visit_begin(static_cast<decl_base*>(d));}
30387
30388bool
30389ir_node_visitor::visit_end(member_function_template* d)
30390{return visit_end(static_cast<decl_base*>(d));}
30391
30392bool
30393ir_node_visitor::visit_begin(member_class_template* d)
30394{return visit_begin(static_cast<decl_base*>(d));}
30395
30396bool
30397ir_node_visitor::visit_end(member_class_template* d)
30398{return visit_end(static_cast<decl_base*>(d));}
30399
30400// </ir_node_visitor stuff>
30401
30402// <debugging facilities>
30403
30404/// Generate a different string at each invocation.
30405///
30406/// @return the resulting string.
30407static string
30408get_next_string()
30409{
30410 static __thread size_t counter;
30411 ++counter;
30412 std::ostringstream o;
30413 o << counter;
30414 return o.str();
30415}
30416
30417/// A hashing functor for a @ref function_decl
30418struct function_decl_hash
30419{
30420 size_t operator()(const function_decl* f) const
30421 {return reinterpret_cast<size_t>(f);}
30422
30423 size_t operator()(const function_decl_sptr& f) const
30424 {return operator()(f.get());}
30425};
30426
30427/// Convenience typedef for a hash map of pointer to function_decl and
30428/// string.
30429typedef unordered_map<const function_decl*, string,
30430 function_decl_hash,
30432
30433/// Return a string associated to a given function. Two functions
30434/// that compare equal would yield the same string, as far as this
30435/// routine is concerned. And two functions that are different would
30436/// yield different strings.
30437///
30438/// This is used to debug core diffing issues on functions. The
30439/// sequence of strings can be given to the 'testdiff2' program that
30440/// is in the tests/ directory of the source tree, to reproduce core
30441/// diffing issues on string and thus ease the debugging.
30442///
30443/// @param fn the function to generate a string for.
30444///
30445/// @param m the function_decl* <-> string map to be used by this
30446/// function to generate strings associated to a function.
30447///
30448/// @return the resulting string.
30449static const string&
30450fn_to_str(const function_decl* fn,
30452{
30453 fns_to_str_map_type::const_iterator i = m.find(fn);
30454 if (i != m.end())
30455 return i->second;
30456 string s = get_next_string();
30457 return m[fn]= s;
30458}
30459
30460/// Generate a sequence of string that matches a given sequence of
30461/// function. In the resulting sequence, each function is "uniquely
30462/// representated" by a string. For instance, if the same function "foo"
30463/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
30464/// we don't care about the actual string) would appear at index 1 and 3.
30465///
30466/// @param begin the beginning of the sequence of functions to consider.
30467///
30468/// @param end the end of the sequence of functions. This points to
30469/// one-passed-the-end of the actual sequence.
30470///
30471/// @param m the function_decl* <-> string map to be used by this
30472/// function to generate strings associated to a function.
30473///
30474/// @param o the output stream where to emit the generated list of
30475/// strings to.
30476static void
30480 std::ostream& o)
30481{
30483 for (i = begin; i != end; ++i)
30484 o << "'" << fn_to_str(*i, m) << "' ";
30485}
30486
30487/// For each sequence of functions given in argument, generate a
30488/// sequence of string that matches a given sequence of function. In
30489/// the resulting sequence, each function is "uniquely representated"
30490/// by a string. For instance, if the same function "foo" appears at
30491/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30492/// care about the actual string) would appear at index 1 and 3.
30493///
30494/// @param a_begin the beginning of the sequence of functions to consider.
30495///
30496/// @param a_end the end of the sequence of functions. This points to
30497/// one-passed-the-end of the actual sequence.
30498///
30499/// @param b_begin the beginning of the second sequence of functions
30500/// to consider.
30501///
30502/// @param b_end the end of the second sequence of functions.
30503///
30504/// @param m the function_decl* <-> string map to be used by this
30505/// function to generate strings associated to a function.
30506///
30507/// @param o the output stream where to emit the generated list of
30508/// strings to.
30509static void
30510fns_to_str(vector<function_decl*>::const_iterator a_begin,
30511 vector<function_decl*>::const_iterator a_end,
30512 vector<function_decl*>::const_iterator b_begin,
30513 vector<function_decl*>::const_iterator b_end,
30515 std::ostream& o)
30516{
30517 fns_to_str(a_begin, a_end, m, o);
30518 o << "->|<- ";
30519 fns_to_str(b_begin, b_end, m, o);
30520 o << "\n";
30521}
30522
30523/// For each sequence of functions given in argument, generate a
30524/// sequence of string that matches a given sequence of function. In
30525/// the resulting sequence, each function is "uniquely representated"
30526/// by a string. For instance, if the same function "foo" appears at
30527/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30528/// care about the actual string) would appear at index 1 and 3.
30529///
30530/// @param a_begin the beginning of the sequence of functions to consider.
30531///
30532/// @param a_end the end of the sequence of functions. This points to
30533/// one-passed-the-end of the actual sequence.
30534///
30535/// @param b_begin the beginning of the second sequence of functions
30536/// to consider.
30537///
30538/// @param b_end the end of the second sequence of functions.
30539///
30540/// @param o the output stream where to emit the generated list of
30541/// strings to.
30542void
30547 std::ostream& o)
30548{
30550 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
30551}
30552
30553// </debugging facilities>
30554
30555// </class template>
30556
30557}// end namespace ir
30558}//end namespace abigail
30559
30560namespace
30561{
30562
30563/// Update the qualified parent name, qualified name and scoped name
30564/// of a tree decl node.
30565///
30566/// @return true if the tree walking should continue, false otherwise.
30567///
30568/// @param d the tree node to take in account.
30569bool
30570qualified_name_setter::do_update(abigail::ir::decl_base* d)
30571{
30572 std::string parent_qualified_name;
30573 abigail::ir::scope_decl* parent = d->get_scope();
30574 if (parent)
30575 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
30576 else
30577 d->priv_->qualified_parent_name_ = abigail::interned_string();
30578
30579 const abigail::ir::environment& env = d->get_environment();
30580
30581 if (!d->priv_->qualified_parent_name_.empty())
30582 {
30583 if (d->get_name().empty())
30584 d->priv_->qualified_name_ = abigail::interned_string();
30585 else
30586 {
30587 d->priv_->qualified_name_ =
30588 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
30589 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
30590 }
30591 }
30592 // Make sure the internal qualified name (used for type
30593 // canonicalization puroses) is always the qualified name. For
30594 // integral/real types however, only the non qualified type is used.
30595 if (!is_integral_type(d))
30596 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
30597
30598 if (d->priv_->scoped_name_.empty())
30599 {
30600 if (parent
30601 && !parent->get_is_anonymous()
30602 && !parent->get_name().empty())
30603 d->priv_->scoped_name_ =
30604 env.intern(parent->get_name() + "::" + d->get_name());
30605 else
30606 d->priv_->scoped_name_ =
30607 env.intern(d->get_name());
30608 }
30609
30610 if (!is_scope_decl(d))
30611 return false;
30612
30613 return true;
30614}
30615
30616/// This is called when we start visiting a decl node, during the
30617/// udpate of the qualified name of a given sub-tree.
30618///
30619/// @param d the decl node we are visiting.
30620///
30621/// @return true iff the traversal should keep going.
30622bool
30623qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
30624{return do_update(d);}
30625
30626/// This is called when we start visiting a type node, during the
30627/// udpate of the qualified name of a given sub-tree.
30628///
30629/// @param d the decl node we are visiting.
30630///
30631/// @return true iff the traversal should keep going.
30632bool
30633qualified_name_setter::visit_begin(abigail::ir::type_base* t)
30634{
30635 if (abigail::ir::decl_base* d = get_type_declaration(t))
30636 return do_update(d);
30637 return false;
30638}
30639}// end anonymous namespace.
This header declares filters for the diff trees resulting from comparing ABI Corpora.
The private data and functions of the corpus type.
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
#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:1743
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:1145
#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:1031
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.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
This type abstracts the configuration information of the library.
Definition abg-config.h:18
Abstraction of a function parameter.
Definition abg-ir.h:3325
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a parameter.
Definition abg-ir.h:3177
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:96
const char * get_string(const char *s) const
Get a pointer to the interned string which has a given value.
Definition abg-ir.cc:106
interned_string create_string(const std::string &)
Create an interned string with a given value.
Definition abg-ir.cc:123
interned_string_pool()
Default constructor.
Definition abg-ir.cc:83
~interned_string_pool()
Destructor.
Definition abg-ir.cc:132
The abstraction of an interned string.
bool empty() const
Test if the current instance of interned_string is empty.
void clear()
Clear the string.
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:2589
void set_signed(int64_t v)
Setter of the bound value as signed.
Definition abg-ir.cc:19262
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:19230
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:19223
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition abg-ir.cc:19237
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition abg-ir.cc:19274
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition abg-ir.cc:19245
bound_value()
Default constructor of the bound_value class.
Definition abg-ir.cc:19195
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition abg-ir.cc:19252
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
Definition abg-ir.h:2574
void set_lower_bound(int64_t lb)
Setter of the lower bound.
Definition abg-ir.cc:19453
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition abg-ir.cc:19480
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition abg-ir.cc:19446
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:19420
string as_string() const
Return a string representation of the sub range.
Definition abg-ir.cc:19502
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19401
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:19702
bool operator!=(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:19641
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition abg-ir.cc:19432
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:19412
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:19597
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition abg-ir.cc:19439
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:19680
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition abg-ir.cc:19525
uint64_t get_length() const
Getter of the length of the subrange type.
Definition abg-ir.cc:19463
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition abg-ir.cc:19495
The abstraction of an array type.
Definition abg-ir.h:2548
virtual bool is_non_finite() const
Definition abg-ir.cc:20119
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:20149
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19809
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition abg-ir.cc:20080
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition abg-ir.cc:20095
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition abg-ir.h:2566
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:20212
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition abg-ir.cc:20239
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:20058
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition abg-ir.h:2569
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:19862
translation_unit::language get_language() const
Get the language of the array.
Definition abg-ir.cc:20047
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition abg-ir.cc:20105
Abstraction of a base specifier in a class declaration.
Definition abg-ir.h:4354
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition abg-ir.cc:25364
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition abg-ir.cc:25371
long get_offset_in_bits() const
Getter of the offset of the base.
Definition abg-ir.cc:25378
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:25353
virtual bool traverse(ir_node_visitor &)
Traverses an instance of base_spec, visiting all the sub-types and decls that it might contain.
Definition abg-ir.cc:25394
virtual bool operator==(const decl_base &) const
Comparison operator for base_spec.
Definition abg-ir.cc:25488
Abstracts a class declaration.
Definition abg-ir.h:4164
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition abg-ir.cc:26105
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition abg-ir.cc:25161
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition abg-ir.cc:25944
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:25230
bool is_struct() const
Test if the class is a struct.
Definition abg-ir.cc:25168
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:26007
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition abg-ir.cc:25185
virtual ~class_decl()
Destructor of the class_decl type.
Definition abg-ir.cc:26521
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:25146
bool has_vtable() const
Test if the current instance has a vtable.
Definition abg-ir.cc:25972
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition abg-ir.cc:25986
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition abg-ir.cc:25953
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26437
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition abg-ir.h:4182
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition abg-ir.cc:25175
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition abg-ir.cc:25211
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition abg-ir.cc:25235
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition abg-ir.cc:26285
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:25195
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition abg-ir.cc:25935
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition abg-ir.h:4183
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:25256
The base type of class_decl and union_decl.
Definition abg-ir.h:3967
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition abg-ir.cc:24039
void add_member_function(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:24280
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:24205
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition abg-ir.cc:24308
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition abg-ir.cc:23925
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition abg-ir.cc:24384
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition abg-ir.cc:24024
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition abg-ir.cc:24057
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition abg-ir.cc:24398
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition abg-ir.h:3999
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition abg-ir.h:3998
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition abg-ir.cc:24164
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:23815
void add_data_member(var_decl_sptr v, access_specifier a, 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:24106
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:24359
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:24343
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition abg-ir.cc:24008
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition abg-ir.cc:24440
virtual decl_base_sptr add_member_decl(const decl_base_sptr &)
Add a member declaration to the current instance of class_or_union. The member declaration can be eit...
Definition abg-ir.cc:23913
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:23831
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition abg-ir.cc:24412
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Definition abg-ir.cc:24255
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:24317
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
Definition abg-ir.cc:24263
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:23950
vector< var_decl_sptr > data_members
Convenience typedef.
Definition abg-ir.h:3997
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition abg-ir.cc:23904
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:24474
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition abg-ir.cc:26824
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition abg-ir.cc:23976
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition abg-ir.cc:24391
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition abg-ir.cc:23992
vector< type_base_sptr > member_types
Convenience typedef.
Definition abg-ir.h:3996
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition abg-ir.cc:24075
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:24175
Abstract a class template.
Definition abg-ir.h:3787
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition abg-ir.cc:28216
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition abg-ir.cc:28205
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:28265
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:28220
The abstraction of the relationship between an entity and its containing scope (its context)....
Definition abg-ir.h:1285
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition abg-corpus.h:25
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
Definition abg-corpus.h:45
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:1585
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
Definition abg-ir.cc:16340
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:5012
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition abg-ir.cc:5227
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
Definition abg-ir.cc:4901
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition abg-ir.cc:4799
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition abg-ir.cc:4530
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:4592
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:5582
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition abg-ir.cc:4960
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition abg-ir.cc:4774
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:4996
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition abg-ir.cc:4830
void clear_qualified_name()
Clear the qualified name of this decl.
Definition abg-ir.cc:4523
virtual void set_name(const string &n)
Setter for the name of the decl.
Definition abg-ir.cc:4662
const location & get_location() const
Get the location of a given declaration.
Definition abg-ir.cc:4612
binding
ELF binding.
Definition abg-ir.h:1636
typedef_decl_sptr get_naming_typedef() const
Getter for the naming typedef of the current decl.
Definition abg-ir.cc:4722
virtual const interned_string & get_name() const
Getter for the name of the current decl.
Definition abg-ir.cc:4818
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition abg-ir.cc:5254
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition abg-ir.cc:4514
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition abg-ir.cc:4564
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition abg-ir.cc:4675
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *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:8457
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition abg-ir.cc:4952
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:4980
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition abg-ir.cc:5551
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition abg-ir.cc:4740
void set_location(const location &l)
Set the location for a given declaration.
Definition abg-ir.cc:4650
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition abg-ir.cc:4685
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition abg-ir.cc:4791
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition abg-ir.cc:4557
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition abg-ir.cc:5145
visibility get_visibility() const
Getter for the visibility of the decl.
Definition abg-ir.cc:4784
visibility
ELF visibility.
Definition abg-ir.h:1626
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition abg-ir.cc:5003
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:5243
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition abg-ir.cc:4968
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition abg-ir.cc:4767
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:5522
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:6648
virtual ~decl_base()
Destructor of the decl_base type.
Definition abg-ir.cc:5231
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:5216
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:4811
bool get_is_anonymous_or_has_anonymous_parent() const
Definition abg-ir.cc:4708
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition abg-ir.cc:4697
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:4584
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition abg-ir.cc:4543
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:4853
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition abg-ir.h:2993
const var_decl * 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:3351
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition abg-ir.cc:3361
The abstraction of the version of an ELF symbol.
Definition abg-ir.h:1232
version & operator=(const version &o)
Assign a version to the current one.
Definition abg-ir.cc:3264
bool operator==(const version &o) const
Compares the current version against another one.
Definition abg-ir.cc:3246
bool is_default() const
Getter for the 'is_default' property of the version.
Definition abg-ir.cc:3226
const string & str() const
Getter for the version name.
Definition abg-ir.cc:3212
bool operator!=(const version &o) const
Inequality operator.
Definition abg-ir.cc:3255
Abstraction of an elf symbol.
Definition abg-ir.h:961
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
Definition abg-ir.cc:2342
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:2665
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition abg-ir.cc:2560
type get_type() const
Getter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2176
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
Definition abg-ir.cc:2397
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2321
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition abg-ir.cc:2426
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
Definition abg-ir.cc:2166
bool is_suppressed() const
Getter for the 'is-suppressed' property.
Definition abg-ir.cc:2358
binding
The binding of a symbol.
Definition abg-ir.h:978
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
Definition abg-ir.cc:2433
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:2686
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2211
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
Definition abg-ir.cc:2571
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition abg-ir.cc:2450
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition abg-ir.cc:2367
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
Definition abg-ir.cc:2299
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
Definition abg-ir.cc:2496
void set_size(size_t)
Setter of the size of the symbol.
Definition abg-ir.cc:2197
const string & get_name() const
Getter for the name of the elf_symbol.
Definition abg-ir.cc:2159
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2204
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:2752
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
Definition abg-ir.cc:2290
type
The type of a symbol.
Definition abg-ir.h:965
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
Definition abg-ir.cc:2225
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
Definition abg-ir.cc:2328
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2236
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
Definition abg-ir.cc:2811
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition abg-ir.cc:2411
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition abg-ir.cc:2335
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:2063
visibility
The visibility of the symbol.
Definition abg-ir.h:987
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition abg-ir.cc:2218
bool is_common_symbol() const
Return true if the symbol is a common one.
Definition abg-ir.cc:2529
void set_index(size_t)
Setter for the index.
Definition abg-ir.cc:2152
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2244
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
Definition abg-ir.cc:2545
size_t get_index() const
Getter for the index.
Definition abg-ir.cc:2145
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition abg-ir.cc:2616
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:2643
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
Definition abg-ir.cc:2138
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2183
bool is_public() const
Test if the current instance of elf_symbol is public or not.
Definition abg-ir.cc:2274
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2313
size_t get_size() const
Getter of the size of the symbol.
Definition abg-ir.cc:2190
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
Definition abg-ir.cc:2252
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
Definition abg-ir.cc:2349
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition abg-ir.cc:2418
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:2797
The abstraction of an enumerator.
Definition abg-ir.h:2871
enumerator()
Default constructor of the enumerator type.
Definition abg-ir.cc:20843
bool operator!=(const enumerator &other) const
Inequality operator.
Definition abg-ir.cc:20903
void set_name(const string &n)
Setter for the name of enumerator.
Definition abg-ir.cc:20945
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition abg-ir.cc:20967
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition abg-ir.cc:20912
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition abg-ir.cc:20974
void set_value(int64_t v)
Setter for the value of enumerator.
Definition abg-ir.cc:20960
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:20929
int64_t get_value() const
Getter for the value of enumerator.
Definition abg-ir.cc:20953
bool operator==(const enumerator &other) const
Equality operator.
Definition abg-ir.cc:20890
enumerator & operator=(const enumerator &)
Assignment operator of the enumerator type.
Definition abg-ir.cc:20874
Abstracts a declaration for an enum type.
Definition abg-ir.h:2785
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition abg-ir.h:2801
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:20312
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition abg-ir.cc:20473
const enumerators & get_enumerators() const
Definition abg-ir.cc:20325
bool find_enumerator_by_value(int64_t value, enum_type_decl::enumerator &result)
Find an enumerator by its value.
Definition abg-ir.cc:20371
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition abg-ir.cc:20337
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:20451
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition abg-ir.cc:20320
bool find_enumerator_by_name(const string &name, enum_type_decl::enumerator &result)
Find an enumerator by its name.
Definition abg-ir.cc:20395
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:20764
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:20426
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition abg-ir.h:148
bool decl_only_class_equals_definition() const
Getter of the "decl-only-class-equals-definition" flag.
Definition abg-ir.cc:3598
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:3665
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:158
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:3745
const vector< type_base_sptr > * get_canonical_types(const char *name) const
Get the vector of canonical types which have a given "stringrepresentation".
Definition abg-ir.cc:3882
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:3475
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:3697
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition abg-ir.cc:3526
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:3494
const config & get_config() const
Getter of the general configuration object.
Definition abg-ir.cc:3735
environment()
Default constructor of the environment type.
Definition abg-ir.cc:3376
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition abg-ir.cc:3538
type_base * get_canonical_type(const char *name, unsigned index)
Get a given canonical type which has a given "stringrepresentation".
Definition abg-ir.cc:3905
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:3513
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:3634
virtual ~environment()
Destructor for the environment type.
Definition abg-ir.cc:3381
bool canonicalization_started() const
Getter of a flag saying if the canonicalization process has started or not.
Definition abg-ir.cc:3565
interned_string intern(const string &) const
Do intern a string.
Definition abg-ir.cc:3728
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:3771
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition abg-ir.cc:3389
Abstraction of a function parameter.
Definition abg-ir.h:3325
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition abg-ir.cc:23649
interned_string get_type_name() const
Definition abg-ir.cc:23448
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition abg-ir.cc:23486
const string get_type_pretty_representation() const
Definition abg-ir.cc:23467
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition abg-ir.cc:23625
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:23669
Abstraction for a function declaration.
Definition abg-ir.h:3155
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a parameter.
Definition abg-ir.h:3177
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:22849
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition abg-ir.cc:22920
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:23310
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition abg-ir.cc:23000
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition abg-ir.cc:23225
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition abg-ir.cc:22886
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition abg-ir.cc:22905
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:22712
const type_base_sptr get_return_type() const
Definition abg-ir.cc:22981
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition abg-ir.cc:23013
const std::vector< parameter_sptr > & get_parameters() const
Definition abg-ir.cc:22986
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition abg-ir.cc:22993
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition abg-ir.cc:22942
virtual ~function_decl()
Destructor of the function_decl type.
Definition abg-ir.cc:23326
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:22958
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition abg-ir.cc:23211
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3180
bool is_declared_inline() const
Test if the function was declared inline.
Definition abg-ir.cc:22965
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:22781
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:23241
Abstract a function template declaration.
Definition abg-ir.h:3742
binding get_binding() const
Get the binding of the function template.
Definition abg-ir.cc:28053
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition abg-ir.cc:28035
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition abg-ir.cc:28046
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:28113
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition abg-ir.cc:28062
Abstraction of a function type.
Definition abg-ir.h:3410
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a parameter.
Definition abg-ir.h:3420
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:21954
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:22373
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition abg-ir.cc:22061
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:22270
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:21861
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition abg-ir.cc:22332
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:22046
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition abg-ir.cc:22023
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition abg-ir.cc:22290
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:22002
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition abg-ir.cc:21965
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition abg-ir.cc:21973
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:22248
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition abg-ir.cc:21982
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3422
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:22356
This abstracts the global scope of a given translation unit.
Definition abg-ir.h:1982
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition abg-ir.h:4801
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:30119
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition abg-ir.cc:30168
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition abg-ir.cc:30158
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition abg-ir.cc:30098
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition abg-ir.cc:30129
The entry point to manage locations.
Definition abg-ir.h:449
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:507
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:530
The source location of a token.
Definition abg-ir.h:307
bool get_is_artificial() const
Test if the location is artificial.
Definition abg-ir.h:348
unsigned get_value() const
Get the value of the location.
Definition abg-ir.h:395
string expand(void) const
Expand the location into a string.
Definition abg-ir.cc:472
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
Definition abg-ir.cc:452
Abstraction of a member function context relationship. This relates a member function to its parent c...
Definition abg-ir.h:4487
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition abg-ir.h:4565
bool is_const() const
Getter for the 'is-const' property.
Definition abg-ir.h:4600
size_t vtable_offset() const
Getter for the vtable offset property.
Definition abg-ir.h:4545
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition abg-ir.h:4582
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition abg-ir.h:3829
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition abg-ir.h:3849
bool get_is_static() const
Definition abg-ir.h:3861
Abstracts a member class template template.
Definition abg-ir.h:4692
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition abg-ir.cc:26684
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26769
Abstract a member function template.
Definition abg-ir.h:4637
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26663
Abstraction of the declaration of a method.
Definition abg-ir.h:3877
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition abg-ir.cc:25635
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition abg-ir.cc:6545
const method_type_sptr get_type() const
Definition abg-ir.cc:25662
Abstracts the type of a class member function.
Definition abg-ir.h:3496
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:22574
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:22555
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition abg-ir.cc:22606
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition abg-ir.cc:22621
virtual ~method_type()
The destructor of method_type.
Definition abg-ir.cc:22654
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:22598
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition abg-ir.cc:22565
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition abg-ir.cc:22613
The abstraction of a namespace declaration.
Definition abg-ir.h:2207
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:17461
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17492
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition abg-ir.cc:17395
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition abg-ir.cc:17447
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:17433
Abstracts non type template parameters.
Definition abg-ir.h:3652
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition abg-ir.cc:27751
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:27756
The abstraction of a pointer type.
Definition abg-ir.h:2350
void set_pointed_to_type(const type_base_sptr &)
Set the pointed-to type of the pointer.
Definition abg-ir.cc:18154
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:18280
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18144
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:18071
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:18374
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition abg-ir.cc:18216
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition abg-ir.cc:18260
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition abg-ir.cc:18267
The abstraction of a pointer-to-member type.
Definition abg-ir.h:2485
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:19044
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
Definition abg-ir.cc:18954
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18967
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:18987
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition abg-ir.cc:19028
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:19095
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition abg-ir.cc:18978
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition abg-ir.cc:19120
The abstraction of a qualified type.
Definition abg-ir.h:2236
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:17797
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition abg-ir.cc:17922
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition abg-ir.cc:17661
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:17649
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:17910
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition abg-ir.h:2255
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:17587
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition abg-ir.cc:17901
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17870
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition abg-ir.cc:17896
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition abg-ir.cc:17915
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition abg-ir.cc:17741
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition abg-ir.cc:17564
The internal representation of an integral type.
Definition abg-ir-priv.h:49
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the real_type.
Definition abg-ir.cc:16837
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition abg-ir.cc:16860
base_type get_base_type() const
Getter of the base type of the real_type.
Definition abg-ir.cc:16823
bool operator==(const real_type &) const
Equality operator for the real_type.
Definition abg-ir.cc:16847
real_type()
Default constructor of the real_type.
Definition abg-ir.cc:16793
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
Definition abg-ir-priv.h:89
@ LONG_LONG_MODIFIER
The "long long" modifier.
@ LONG_MODIFIER
The "long" modifier.
Definition abg-ir-priv.h:98
@ SIGNED_MODIFIER
The "signed" modifier.
Definition abg-ir-priv.h:92
@ UNSIGNED_MODIFIER
The "unsigned" modier.
Definition abg-ir-priv.h:94
@ SHORT_MODIFIER
The "short" modifier.
Definition abg-ir-priv.h:96
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:57
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
Definition abg-ir-priv.h:73
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
Definition abg-ir-priv.h:71
@ FLOAT_BASE_TYPE
The "float" base type.
Definition abg-ir-priv.h:67
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
Definition abg-ir-priv.h:63
@ CHAR_BASE_TYPE
The "char" base type.
Definition abg-ir-priv.h:61
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
Definition abg-ir-priv.h:69
@ INT_BASE_TYPE
The "int" base type.
Definition abg-ir-priv.h:59
@ ARRAY_SIZE_BASE_TYPE
The aray size type used by Clang.
Definition abg-ir-priv.h:79
@ DOUBLE_BASE_TYPE
The "double" base type.
Definition abg-ir-priv.h:65
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the real_type.
Definition abg-ir.cc:16830
Abstracts a reference type.
Definition abg-ir.h:2416
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:18703
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18566
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:18468
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:18825
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:18576
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition abg-ir.cc:18645
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:18804
A declaration that introduces a scope.
Definition abg-ir.h:1853
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
Definition abg-ir.cc:7928
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition abg-ir.cc:8137
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition abg-ir.cc:8095
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition abg-ir.cc:8112
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition abg-ir.cc:7946
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition abg-ir.cc:7981
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:7995
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:8427
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition abg-ir.cc:8070
decl_base_sptr insert_member_decl(decl_base_sptr member, declarations::iterator before)
Insert a member decl to this scope, right before an element pointed to by a given iterator....
Definition abg-ir.cc:8205
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:7864
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:8379
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition abg-ir.cc:8230
virtual decl_base_sptr add_member_decl(const 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:8041
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:8081
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition abg-ir.cc:7888
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:7852
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition abg-ir.cc:8156
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *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:8457
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:8333
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition abg-ir.cc:7906
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition abg-ir.cc:7964
A type that introduces a scope.
Definition abg-ir.h:2184
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:17354
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition abg-ir.cc:17316
The base class of templates.
Definition abg-ir.h:3557
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:27426
virtual ~template_decl()
Destructor.
Definition abg-ir.cc:27451
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:27418
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:27460
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition abg-ir.h:3589
virtual ~template_parameter()
Destructor.
Definition abg-ir.cc:27580
bool operator!=(const template_parameter &) const
Inequality operator.
Definition abg-ir.cc:27576
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:27829
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
Definition abg-ir.h:695
void set_address_size(char)
Setter of the address size in this translation unit.
Definition abg-ir.cc:1426
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:1341
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:1458
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
Definition abg-ir.cc:1468
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
Definition abg-ir.cc:1384
char get_address_size() const
Getter of the address size in this translation unit.
Definition abg-ir.cc:1419
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:1322
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
Definition abg-ir.cc:1368
void set_language(language l)
Setter of the language of the source code of the translation unit.
Definition abg-ir.cc:1285
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:1494
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
Definition abg-ir.cc:1221
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Definition abg-ir.cc:1408
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:1442
const std::string & get_path() const
Get the path of the current translation unit.
Definition abg-ir.cc:1298
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:1333
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
Definition abg-ir.cc:1392
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
Definition abg-ir.cc:1309
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
Definition abg-ir.cc:1528
language
The language of the translation unit.
Definition abg-ir.h:708
bool operator!=(const translation_unit &) const
Inequality operator.
Definition abg-ir.cc:1483
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
Definition abg-ir.cc:1264
const environment & get_environment() const
Getter of the environment of the current translation_unit.
Definition abg-ir.cc:1271
const type_maps & get_types() const
Getter of the types of the current translation_unit.
Definition abg-ir.cc:1248
language get_language() const
Getter of the language of the source code of the translation unit.
Definition abg-ir.cc:1278
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:2003
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
Definition abg-ir.cc:16423
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition abg-ir.cc:16399
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition abg-ir.cc:16502
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:16369
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:16528
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:16094
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition abg-ir.cc:16495
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition abg-ir.cc:16488
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition abg-ir.cc:16478
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition abg-ir.cc:16516
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition abg-ir.cc:16509
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition abg-ir.cc:16383
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition abg-ir.h:3720
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition abg-ir.cc:27935
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition abg-ir.cc:27942
A basic type declaration that introduces no scope.
Definition abg-ir.h:2118
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:17148
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:16988
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17227
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:17086
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:17042
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:17207
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
Definition abg-ir.h:602
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:651
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:754
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:705
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:609
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:623
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:719
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:637
bool empty() const
Test if the type_maps is empty.
Definition abg-ir.cc:577
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:664
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:684
const vector< type_base_wptr > & get_types_sorted_by_name() const
Getter of all types types sorted by their pretty representation.
Definition abg-ir.cc:1157
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:677
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:595
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 subrange...
Definition abg-ir.cc:740
The base class of both types and declarations.
Definition abg-ir.h:1406
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:4285
friend hash_t peek_hash_value(const type_or_decl_base &)
Get the hash value associated to an IR node.
Definition abg-ir.cc:28538
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:4098
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition abg-ir.cc:4087
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition abg-ir.cc:4245
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition abg-ir.cc:4252
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition abg-ir.cc:4277
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition abg-ir.cc:11184
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:4198
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition abg-ir.cc:4121
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:4110
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition abg-ir.cc:4310
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition abg-ir.cc:4141
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:4176
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10757
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition abg-ir.cc:4227
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:1418
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition abg-ir.cc:4209
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition abg-ir.cc:10830
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:4302
Abstracts a type template parameter.
Definition abg-ir.h:3618
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:27622
The abstraction of a typedef declaration.
Definition abg-ir.h:2925
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:21229
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition abg-ir.cc:21214
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition abg-ir.cc:21069
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:21056
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:21261
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition abg-ir.cc:21207
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:21149
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition abg-ir.cc:21086
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:21190
Abstracts a union type declaration.
Definition abg-ir.h:4412
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:27103
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:27220
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition abg-ir.cc:27160
virtual ~union_decl()
Destructor of the union_decl type.
Definition abg-ir.cc:27293
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:27127
Abstracts a variable declaration.
Definition abg-ir.h:3058
binding get_binding() const
Getter of the binding of the variable.
Definition abg-ir.cc:21375
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition abg-ir.cc:21357
void set_binding(binding b)
Setter of the binding of the variable.
Definition abg-ir.cc:21382
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition abg-ir.cc:6206
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition abg-ir.cc:21420
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:21671
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition abg-ir.cc:21368
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:6351
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition abg-ir.cc:21350
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:21833
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:21810
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition abg-ir.cc:21397
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:21413
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition abg-ir.cc:21606
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:21701
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:21625
A type used to time various part of the libabigail system.
bool stop()
Stop the timer.
bool start()
Start the timer.
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...
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
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 given IR node started and is now done. If an ABI artifact is in this state,...
Definition abg-hash.h:61
real_type::modifiers_type operator~(real_type::modifiers_type l)
Bitwise one's complement operator for real_type::modifiers_type.
Definition abg-ir.cc:16585
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
Definition abg-fwd.h:235
const type_base_sptr lookup_type_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a type in a scope.
Definition abg-ir.cc:12968
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition abg-ir.cc:28565
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition abg-ir.cc:6461
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition abg-ir.cc:7271
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
Definition abg-ir.cc:28538
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:12455
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
Definition abg-fwd.h:221
size_t hash_type(const type_base *t)
Hash an ABI artifact that is a type.
Definition abg-ir.cc:28516
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:12319
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:5788
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:6161
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:12106
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:5582
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:11564
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:10149
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition abg-fwd.h:269
access_specifier
Access specifier for class members.
Definition abg-ir.h:917
size_t get_canonical_type_index(const type_base &t)
Getter of the canonical type index of a given type.
Definition abg-ir.cc:345
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:14036
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition abg-ir.cc:23292
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:11546
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:15835
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
Definition abg-fwd.h:289
bool maybe_update_types_lookup_map< function_type >(const function_type_sptr &type, istring_type_base_wptrs_map_type &types_map, bool)
This is the specialization for type function_type of the function template:
Definition abg-ir.cc:14708
weak_ptr< function_type > function_type_wptr
Convenience typedef for a weak pointer on a function_type.
Definition abg-fwd.h:216
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:14198
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition abg-ir.cc:6585
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
Definition abg-fwd.h:142
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
Definition abg-ir.cc:8807
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:25891
void pop_composite_type_comparison_operands(const type_base &left, const type_base &right)
Pop a pair of operands from the stack of operands to the current type comparison.
Definition abg-ir.cc:332
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:19942
const scope_decl * is_scope_decl(const decl_base *d)
Test if a declaration is a scope_decl.
Definition abg-ir.cc:5452
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition abg-ir.cc:7622
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:11797
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition abg-ir.cc:10817
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition abg-ir.cc:5879
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition abg-ir.cc:10691
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
Definition abg-ir.cc:1540
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
Definition abg-fwd.h:128
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:7180
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:26578
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition abg-ir.cc:5406
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:12225
T * maybe_get_canonical_type(T *t)
Get the canonical type of a given type T* as a T*.
Definition abg-ir.cc:894
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition abg-ir.h:926
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:13595
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition abg-ir.cc:28636
bool type_originates_from_corpus(type_base_sptr t, corpus_sptr &c)
Test if a type originates from a corpus.
Definition abg-ir.cc:378
bool parse_real_type(const string &type_name, real_type &type)
Parse a real type from a string.
Definition abg-ir.cc:16778
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition abg-ir.cc:8482
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:10214
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition abg-ir.cc:7555
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
Definition abg-ir.h:1361
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
Definition abg-ir.h:1365
@ 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:1381
@ 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:1370
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:29142
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:11721
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:5725
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:13330
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:9691
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition abg-ir.cc:5486
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:1849
weak_ptr< class_decl > class_decl_wptr
Convenience typedef for a weak pointer on a class_decl.
Definition abg-fwd.h:202
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:12345
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
Definition abg-ir.cc:1085
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
Definition abg-ir.h:127
void debug_comp_stack(const environment &env)
Emit a trace of the two comparison operands stack on the standard error stream.
Definition abg-ir.cc:10199
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:5822
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition abg-ir.cc:11175
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:15281
void set_member_function_virtuality(function_decl &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
Definition abg-ir.cc:6722
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition abg-fwd.h:244
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:13620
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:11359
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:9293
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
Definition abg-ir.cc:10868
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:14223
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:7340
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:6065
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition abg-ir.cc:10977
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:6121
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:13899
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition abg-ir.cc:6489
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition abg-ir.cc:7229
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:12786
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:28780
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:314
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:11406
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:10031
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:12037
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:5749
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition abg-fwd.h:193
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:7416
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:6545
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:6922
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:989
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:3071
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition abg-ir.cc:12088
hash_t set_or_get_cached_hash_value(const T &tod)
Set the hash value of an IR node and return it.
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:10919
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10797
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:11977
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:11868
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:8693
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition abg-ir.cc:5551
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:11128
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition abg-ir.cc:11021
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
Definition abg-ir.h:105
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition abg-ir.cc:6323
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:14066
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition abg-ir.cc:9840
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition abg-fwd.h:210
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition abg-fwd.h:167
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:15364
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:2943
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:7124
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:21481
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:12495
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:13570
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:12166
void sort_types(const canonical_type_sptr_set_type &types, vector< type_base_sptr > &result)
Sort types in a hopefully stable manner.
Definition abg-ir.cc:3455
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:11624
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:7518
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:11661
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:3152
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition abg-ir.cc:1808
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:13823
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:6574
decl_base_sptr insert_decl_into_scope(decl_base_sptr decl, scope_decl::declarations::iterator before, scope_decl *scope)
Inserts a declaration into a given scope, before a given IR child node of the scope.
Definition abg-ir.cc:8501
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:3372
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:11110
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:148
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:28728
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
Definition abg-ir.cc:2867
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:10660
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
Definition abg-ir.cc:8550
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition abg-fwd.h:256
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:239
const location & get_natural_or_artificial_location(const decl_base *decl)
Get the non-artificial (natural) location of a decl.
Definition abg-ir.cc:10059
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:28429
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:24773
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
Definition abg-ir.cc:12248
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition abg-fwd.h:264
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:3104
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:120
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:12724
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition abg-fwd.h:136
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:5997
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:29707
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:11760
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:30431
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition abg-ir.cc:12254
bool try_canonical_compare(const T *l, const T *r)
Compare two types by comparing their canonical types if present.
Definition abg-ir.cc:914
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
Definition abg-ir.cc:12985
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:28366
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:157
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:12678
void push_composite_type_comparison_operands(const type_base &left, const type_base &right)
Push a pair of operands on the stack of operands of the current type comparison, during type canonica...
Definition abg-ir.cc:311
const type_base_sptr lookup_type(const interned_string &fqn, const translation_unit &tu)
Lookup a type in a translation unit.
Definition abg-ir.cc:12901
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
Definition abg-ir.cc:1824
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:10734
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition abg-ir.cc:5145
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:6351
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:12532
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:3129
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:11061
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition abg-ir.h:929
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition abg-ir.cc:6517
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:9048
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition abg-fwd.h:226
void maybe_update_types_lookup_map(const type_decl_sptr &basic_type)
Update the map that associates the fully qualified name of a basic type with the type itself.
Definition abg-ir.cc:14738
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:20487
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
Definition abg-ir.cc:7308
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:1670
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:14528
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:6236
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition abg-ir.cc:6280
shared_ptr< ir_traversable_base > ir_traversable_base_sptr
Convenience typedef for a shared pointer to ir_traversable_base.
Definition abg-fwd.h:109
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
Definition abg-ir.cc:6375
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:29074
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition abg-ir.cc:12069
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
Definition abg-ir.cc:1792
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10757
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:28404
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:25724
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:12830
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition abg-ir.cc:5471
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:9515
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *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:8457
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:29096
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:10904
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:5522
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition abg-fwd.h:175
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:6174
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:6787
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition abg-ir.cc:6191
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
Definition abg-ir.h:99
void sort_types_for_hash_computing_and_c14n(IteratorType begin, IteratorType end)
Sort types before hashing (and then canonicalizing) them.
class_or_union * is_at_class_scope(const decl_base_sptr decl)
Tests whether a given decl is at class scope.
Definition abg-ir.cc:10614
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:6648
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:11489
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:9812
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:6037
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition abg-ir.cc:8773
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:11529
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition abg-ir.cc:10510
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
Definition abg-fwd.h:181
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:11286
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:9125
bool is_function_template_pattern(const shared_ptr< decl_base > decl)
Test whether a decl is the pattern of a function template.
Definition abg-ir.cc:12120
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:11928
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition abg-ir.cc:11455
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition abg-ir.cc:10078
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:12600
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:7070
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:13854
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:24841
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:9078
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
Definition abg-fwd.h:306
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:12204
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:12850
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
Definition abg-ir.cc:10559
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:8663
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:6337
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:11581
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition abg-ir.cc:5620
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:29121
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:13803
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition abg-ir.cc:10236
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:11216
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition abg-ir.cc:26824
type_base_sptr canonicalize(type_base_sptr t, bool do_log, bool show_stats)
Compute the canonical type of a given type.
Definition abg-ir.cc:16261
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:12133
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:9215
weak_ptr< template_decl > template_decl_wptr
Convenience typedef for a weak pointer to template_decl.
Definition abg-fwd.h:309
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:29031
interned_string get_function_id_or_pretty_representation(const function_decl *fn)
Get the ID of a function, or, if the ID can designate several different functions,...
Definition abg-ir.cc:9187
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition abg-fwd.h:161
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition abg-ir.cc:7597
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:13691
bool compare_using_locations(const decl_base *f, const decl_base *s)
Compare decls using their locations.
Definition abg-ir.cc:3420
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:10269
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:13262
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:10098
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:121
bool return_comparison_result(T &l, T &r, bool value)
Return the result of the comparison of two (sub) types.
Definition abg-ir.cc:1127
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition abg-fwd.h:284
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
Definition abg-ir.cc:1833
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
Definition abg-ir.cc:15438
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition abg-ir.cc:28601
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:10404
void mark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being compared.
Definition abg-ir.cc:1050
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:8842
const scope_decl * get_top_most_scope_under(const decl_base *decl, const scope_decl *scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
Definition abg-ir.cc:8594
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:7675
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:1868
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:9026
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:29666
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition abg-ir.cc:10682
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:14161
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:10705
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:3162
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:28388
bool maybe_update_types_lookup_map< class_decl >(const class_decl_sptr &class_type, istring_type_base_wptrs_map_type &map, bool use_type_name_as_key)
This is the specialization for type class_decl of the function template:
Definition abg-ir.cc:14646
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:11898
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:11848
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:12638
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:11601
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:947
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:12565
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:11427
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
Definition abg-ir.cc:8739
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:3403
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:11958
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition abg-fwd.h:294
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:7365
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:15468
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
Definition abg-ir.cc:10587
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
Definition abg-ir.cc:10937
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition abg-ir.cc:5424
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:5076
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition abg-ir.cc:6402
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:6432
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:11395
Namespace for regex types and functions.
Definition abg-regex.cc:54
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:87
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.
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
Definition abg-ir.cc:151
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
Definition abg-ir.cc:185
unordered_map< string, string * > pool_map_type
Convenience typedef for a map of string -> string*.
Definition abg-ir.cc:73
A functor to hash instances of interned_string.
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:7790
Hasher for the class_or_union type.
Definition abg-hash.h:250
bool is_printing_flat_representation() const
Getter of the 'is_printing_flat_representation_' boolean.
void unset_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to false.
void set_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to true.
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.
Equality functor for instances of function_decl.
Definition abg-ir.h:4762
The hashing functor for function_type.
Definition abg-hash.h:217
The type of the private data of the function_type type.
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:30081
The hashing functor for member_base.
Definition abg-hash.h:243
Private type to hold private members of translation_unit.
Hash functor for instances of type_base.
Definition abg-hash.h:111
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:2096
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.