libabigail
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-2025 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
355{return get_canonical_type_index(*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;
1162 vector<type_base_wptr>::const_iterator j;
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.
1263const vector<function_type_sptr>&
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
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
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
1529{return get_global_scope()->traverse(v);}
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,
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
2546{
2548 return bool(get_next_common_instance());
2549}
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.
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
2694 vector<elf_symbol_sptr> aliases;
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{
2720 vector<elf_symbol_sptr> aliases;
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
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
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 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2881 i != symtab.end();
2882 ++i)
2883 for (elf_symbols::const_iterator j = i->second.begin();
2884 j != i->second.end();
2885 ++j)
2886 {
2887 if (**j == sym)
2888 for (elf_symbol_sptr s = (*j)->get_next_alias();
2889 s && !s->is_main_symbol();
2890 s = s->get_next_alias())
2891 aliases.push_back(s);
2892 else
2893 for (elf_symbol_sptr s = (*j)->get_next_alias();
2894 s && !s->is_main_symbol();
2895 s = s->get_next_alias())
2896 if (*s == sym)
2897 aliases.push_back(*j);
2898 }
2899}
2900
2901/// Test if two symbols alias.
2902///
2903/// @param s1 the first symbol to consider.
2904///
2905/// @param s2 the second symbol to consider.
2906///
2907/// @return true if @p s1 aliases @p s2.
2908bool
2910{
2911 if (!!s1 != !!s2)
2912 return false;
2913 if (s1 == s2)
2914 return true;
2915 return elf_symbols_alias(*s1, *s2);
2916}
2917
2918/// Test if two symbols alias.
2919///
2920/// @param s1 the first symbol to consider.
2921///
2922/// @param s2 the second symbol to consider.
2923///
2924/// @return true if @p s1 aliases @p s2.
2925bool
2927{return elf_symbols_alias(s1.get(), s2.get());}
2928
2929/// Serialize an instance of @ref symbol_type and stream it to a given
2930/// output stream.
2931///
2932/// @param o the output stream to serialize the symbole type to.
2933///
2934/// @param t the symbol type to serialize.
2935std::ostream&
2936operator<<(std::ostream& o, elf_symbol::type t)
2937{
2938 string repr;
2939
2940 switch (t)
2941 {
2942 case elf_symbol::NOTYPE_TYPE:
2943 repr = "unspecified symbol type";
2944 break;
2945 case elf_symbol::OBJECT_TYPE:
2946 repr = "variable symbol type";
2947 break;
2948 case elf_symbol::FUNC_TYPE:
2949 repr = "function symbol type";
2950 break;
2951 case elf_symbol::SECTION_TYPE:
2952 repr = "section symbol type";
2953 break;
2954 case elf_symbol::FILE_TYPE:
2955 repr = "file symbol type";
2956 break;
2957 case elf_symbol::COMMON_TYPE:
2958 repr = "common data object symbol type";
2959 break;
2960 case elf_symbol::TLS_TYPE:
2961 repr = "thread local data object symbol type";
2962 break;
2963 case elf_symbol::GNU_IFUNC_TYPE:
2964 repr = "indirect function symbol type";
2965 break;
2966 default:
2967 {
2968 std::ostringstream s;
2969 s << "unknown symbol type (" << (char)t << ')';
2970 repr = s.str();
2971 }
2972 break;
2973 }
2974
2975 o << repr;
2976 return o;
2977}
2978
2979/// Serialize an instance of @ref symbol_binding and stream it to a
2980/// given output stream.
2981///
2982/// @param o the output stream to serialize the symbole type to.
2983///
2984/// @param b the symbol binding to serialize.
2985std::ostream&
2986operator<<(std::ostream& o, elf_symbol::binding b)
2987{
2988 string repr;
2989
2990 switch (b)
2991 {
2992 case elf_symbol::LOCAL_BINDING:
2993 repr = "local binding";
2994 break;
2995 case elf_symbol::GLOBAL_BINDING:
2996 repr = "global binding";
2997 break;
2998 case elf_symbol::WEAK_BINDING:
2999 repr = "weak binding";
3000 break;
3001 case elf_symbol::GNU_UNIQUE_BINDING:
3002 repr = "GNU unique binding";
3003 break;
3004 default:
3005 {
3006 std::ostringstream s;
3007 s << "unknown binding (" << (unsigned char) b << ")";
3008 repr = s.str();
3009 }
3010 break;
3011 }
3012
3013 o << repr;
3014 return o;
3015}
3016
3017/// Serialize an instance of @ref elf_symbol::visibility and stream it
3018/// to a given output stream.
3019///
3020/// @param o the output stream to serialize the symbole type to.
3021///
3022/// @param v the symbol visibility to serialize.
3023std::ostream&
3024operator<<(std::ostream& o, elf_symbol::visibility v)
3025{
3026 string repr;
3027
3028 switch (v)
3029 {
3030 case elf_symbol::DEFAULT_VISIBILITY:
3031 repr = "default visibility";
3032 break;
3033 case elf_symbol::PROTECTED_VISIBILITY:
3034 repr = "protected visibility";
3035 break;
3036 case elf_symbol::HIDDEN_VISIBILITY:
3037 repr = "hidden visibility";
3038 break;
3039 case elf_symbol::INTERNAL_VISIBILITY:
3040 repr = "internal visibility";
3041 break;
3042 default:
3043 {
3044 std::ostringstream s;
3045 s << "unknown visibility (" << (unsigned char) v << ")";
3046 repr = s.str();
3047 }
3048 break;
3049 }
3050
3051 o << repr;
3052 return o;
3053}
3054
3055/// Convert a string representing a symbol type into an
3056/// elf_symbol::type.
3057///
3058///@param s the string to convert.
3059///
3060///@param t the resulting elf_symbol::type.
3061///
3062/// @return true iff the conversion completed successfully.
3063bool
3065{
3066 if (s == "no-type")
3067 t = elf_symbol::NOTYPE_TYPE;
3068 else if (s == "object-type")
3069 t = elf_symbol::OBJECT_TYPE;
3070 else if (s == "func-type")
3071 t = elf_symbol::FUNC_TYPE;
3072 else if (s == "section-type")
3073 t = elf_symbol::SECTION_TYPE;
3074 else if (s == "file-type")
3075 t = elf_symbol::FILE_TYPE;
3076 else if (s == "common-type")
3077 t = elf_symbol::COMMON_TYPE;
3078 else if (s == "tls-type")
3079 t = elf_symbol::TLS_TYPE;
3080 else if (s == "gnu-ifunc-type")
3081 t = elf_symbol::GNU_IFUNC_TYPE;
3082 else
3083 return false;
3084
3085 return true;
3086}
3087
3088/// Convert a string representing a an elf symbol binding into an
3089/// elf_symbol::binding.
3090///
3091/// @param s the string to convert.
3092///
3093/// @param b the resulting elf_symbol::binding.
3094///
3095/// @return true iff the conversion completed successfully.
3096bool
3098{
3099 if (s == "local-binding")
3100 b = elf_symbol::LOCAL_BINDING;
3101 else if (s == "global-binding")
3102 b = elf_symbol::GLOBAL_BINDING;
3103 else if (s == "weak-binding")
3104 b = elf_symbol::WEAK_BINDING;
3105 else if (s == "gnu-unique-binding")
3106 b = elf_symbol::GNU_UNIQUE_BINDING;
3107 else
3108 return false;
3109
3110 return true;
3111}
3112
3113/// Convert a string representing a an elf symbol visibility into an
3114/// elf_symbol::visibility.
3115///
3116/// @param s the string to convert.
3117///
3118/// @param b the resulting elf_symbol::visibility.
3119///
3120/// @return true iff the conversion completed successfully.
3121bool
3123{
3124 if (s == "default-visibility")
3125 v = elf_symbol::DEFAULT_VISIBILITY;
3126 else if (s == "protected-visibility")
3127 v = elf_symbol::PROTECTED_VISIBILITY;
3128 else if (s == "hidden-visibility")
3129 v = elf_symbol::HIDDEN_VISIBILITY;
3130 else if (s == "internal-visibility")
3131 v = elf_symbol::INTERNAL_VISIBILITY;
3132 else
3133 return false;
3134
3135 return true;
3136}
3137
3138/// Test if the type of an ELF symbol denotes a function symbol.
3139///
3140/// @param t the type of the ELF symbol.
3141///
3142/// @return true iff elf symbol type @p t denotes a function symbol
3143/// type.
3144bool
3146{return t == elf_symbol::FUNC_TYPE;}
3147
3148/// Test if the type of an ELF symbol denotes a function symbol.
3149///
3150/// @param t the type of the ELF symbol.
3151///
3152/// @return true iff elf symbol type @p t denotes a function symbol
3153/// type.
3154bool
3156{return t == elf_symbol::OBJECT_TYPE;}
3157
3158// <elf_symbol::version stuff>
3159
3160struct elf_symbol::version::priv
3161{
3162 string version_;
3163 bool is_default_;
3164
3165 priv()
3166 : is_default_(false)
3167 {}
3168
3169 priv(const string& v,
3170 bool d)
3171 : version_(v),
3172 is_default_(d)
3173 {}
3174}; // end struct elf_symbol::version::priv
3175
3176elf_symbol::version::version()
3177 : priv_(new priv)
3178{}
3179
3180/// @param v the name of the version.
3181///
3182/// @param is_default true if this is a default version.
3183elf_symbol::version::version(const string& v,
3184 bool is_default)
3185 : priv_(new priv(v, is_default))
3186{}
3187
3188elf_symbol::version::version(const elf_symbol::version& v)
3189 : priv_(new priv(v.str(), v.is_default()))
3190{
3191}
3192
3193elf_symbol::version::~version() = default;
3194
3195/// Cast the version_type into a string that is its name.
3196///
3197/// @return the name of the version.
3198elf_symbol::version::operator const string&() const
3199{return priv_->version_;}
3200
3201/// Getter for the version name.
3202///
3203/// @return the version name.
3204const string&
3206{return priv_->version_;}
3207
3208/// Setter for the version name.
3209///
3210/// @param s the version name.
3211void
3213{priv_->version_ = s;}
3214
3215/// Getter for the 'is_default' property of the version.
3216///
3217/// @return true iff this is a default version.
3218bool
3220{return priv_->is_default_;}
3221
3222/// Setter for the 'is_default' property of the version.
3223///
3224/// @param f true if this is the default version.
3225void
3227{priv_->is_default_ = f;}
3228
3229bool
3230elf_symbol::version::is_empty() const
3231{return str().empty();}
3232
3233/// Compares the current version against another one.
3234///
3235/// @param o the other version to compare the current one to.
3236///
3237/// @return true iff the current version equals @p o.
3238bool
3240{return str() == o.str();}
3241
3242/// Inequality operator.
3243///
3244/// @param o the version to compare against the current one.
3245///
3246/// @return true iff both versions are different.
3247bool
3249{return !operator==(o);}
3250
3251/// Assign a version to the current one.
3252///
3253/// @param o the other version to assign to this one.
3254///
3255/// @return a reference to the assigned version.
3258{
3259 str(o.str());
3260 is_default(o.is_default());
3261 return *this;
3262}
3263
3264// </elf_symbol::version stuff>
3265
3266// </elf_symbol stuff>
3267
3268// <class dm_context_rel stuff>
3269struct dm_context_rel::priv
3270{
3271 bool is_laid_out_;
3272 size_t offset_in_bits_;
3273 var_decl* anonymous_data_member_;
3274
3275 priv(bool is_static = false)
3276 : is_laid_out_(!is_static),
3277 offset_in_bits_(0),
3278 anonymous_data_member_()
3279 {}
3280
3281 priv(bool is_laid_out, size_t offset_in_bits)
3282 : is_laid_out_(is_laid_out),
3283 offset_in_bits_(offset_in_bits),
3284 anonymous_data_member_()
3285 {}
3286}; //end struct dm_context_rel::priv
3287
3288dm_context_rel::dm_context_rel()
3289 : context_rel(),
3290 priv_(new priv)
3291{}
3292
3293dm_context_rel::dm_context_rel(scope_decl* s,
3294 bool is_laid_out,
3295 size_t offset_in_bits,
3297 bool is_static)
3298 : context_rel(s, a, is_static),
3299 priv_(new priv(is_laid_out, offset_in_bits))
3300{}
3301
3302dm_context_rel::dm_context_rel(scope_decl* s)
3303 : context_rel(s),
3304 priv_(new priv())
3305{}
3306
3307bool
3308dm_context_rel::get_is_laid_out() const
3309{return priv_->is_laid_out_;}
3310
3311void
3312dm_context_rel::set_is_laid_out(bool f)
3313{priv_->is_laid_out_ = f;}
3314
3315size_t
3316dm_context_rel::get_offset_in_bits() const
3317{return priv_->offset_in_bits_;}
3318
3319void
3320dm_context_rel::set_offset_in_bits(size_t o)
3321{priv_->offset_in_bits_ = o;}
3322
3323bool
3324dm_context_rel::operator==(const dm_context_rel& o) const
3325{
3326 if (!context_rel::operator==(o))
3327 return false;
3328
3329 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3330 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3331}
3332
3333bool
3334dm_context_rel::operator!=(const dm_context_rel& o) const
3335{return !operator==(o);}
3336
3337/// Return a non-nil value if this data member context relationship
3338/// has an anonymous data member. That means, if the data member this
3339/// relation belongs to is part of an anonymous data member.
3340///
3341/// @return the containing anonymous data member of this data member
3342/// relationship. Nil if there is none.
3343const var_decl*
3345{return priv_->anonymous_data_member_;}
3346
3347/// Set the containing anonymous data member of this data member
3348/// context relationship. That means that the data member this
3349/// relation belongs to is part of an anonymous data member.
3350///
3351/// @param anon_dm the containing anonymous data member of this data
3352/// member relationship. Nil if there is none.
3353void
3355{priv_->anonymous_data_member_ = anon_dm;}
3356
3357dm_context_rel::~dm_context_rel()
3358{}
3359// </class dm_context_rel stuff>
3360
3361// <environment stuff>
3362
3363/// Convenience typedef for a map of interned_string -> bool.
3364typedef unordered_map<interned_string,
3366
3367
3368/// Default constructor of the @ref environment type.
3370 :priv_(new priv)
3371{}
3372
3373/// Destructor for the @ref environment type.
3375{}
3376
3377/// Getter the map of canonical types.
3378///
3379/// @return the map of canonical types. The key of the map is the
3380/// hash of the canonical type and its value if the canonical type.
3383{return priv_->canonical_types_;}
3384
3385/// Getter the map of canonical types.
3386///
3387/// @return the map of canonical types. The key of the map is the
3388/// hash of the canonical type and its value if the canonical type.
3391{return const_cast<environment*>(this)->get_canonical_types_map();}
3392
3393/// Helper to detect if a type is either a reference, a pointer, or a
3394/// qualified type.
3395bool
3397{
3398 if (is_pointer_type(t)
3399 || is_reference_type(t)
3400 || is_qualified_type(t))
3401 return true;
3402 return false;
3403}
3404
3405/// Compare decls using their locations.
3406///
3407/// @param f the first decl to compare.
3408///
3409/// @param s the second decl to compare.
3410///
3411/// @return true if @p f compares less than @p s.
3412bool
3414 const decl_base *s)
3415{
3416 // If a decl has artificial location, then use that one over the
3417 // natural one.
3420
3421 ABG_ASSERT(fl.get_value() && sl.get_value());
3422 if (fl.get_is_artificial() == sl.get_is_artificial())
3423 {
3424 // The locations of the two artfifacts have the same
3425 // artificial-ness so they can be compared.
3426 string p1, p2;
3427 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3428 fl.expand(p1, l1, c1);
3429 sl.expand(p2, l2, c2);
3430 if (p1 != p2)
3431 return p1 < p2;
3432 if (l1 != l2)
3433 return l1 < l2;
3434 if (c1 != c2)
3435 return c1 < c2;
3436 }
3437
3438 return (get_pretty_representation(f, /*internal=*/false)
3439 < get_pretty_representation(s, /*internal=*/false));
3440}
3441
3442/// Sort types in a hopefully stable manner.
3443///
3444/// @param types a set of types with canonical types to sort.
3445///
3446/// @param result the resulting sorted vector.
3447void
3449 vector<type_base_sptr>& result)
3450{
3451 for (auto t: types)
3452 result.push_back(t);
3453
3454 type_topo_comp comp;
3455 std::stable_sort(result.begin(), result.end(), comp);
3456}
3457
3458/// Get the unique @ref type_decl that represents a "void" type for
3459/// the current environment. This node must be the only one
3460/// representing a void type in the system.
3461///
3462/// Note that upon first use of this IR node (by the relevant
3463/// front-end, for instance) it must be added to a scope using e.g,
3464/// the @ref add_decl_to_scope() function.
3465///
3466/// @return the @ref type_decl that represents a "void" type.
3467const type_base_sptr&
3469{
3470 if (!priv_->void_type_)
3471 priv_->void_type_.reset(new type_decl(*this,
3472 intern("void"),
3473 0, 0, location()));
3474 return priv_->void_type_;
3475}
3476
3477/// Getter of the "pointer-to-void" IR node that is shared across the
3478/// ABI corpus. This node must be the only one representing a void
3479/// pointer type in the system.
3480///
3481/// Note that upon first use of this IR node (by the relevant
3482/// front-end, for instance) it must be added to a scope using e.g,
3483/// the @ref add_decl_to_scope() function.
3484///
3485/// @return the "pointer-to-void" IR node.
3486const type_base_sptr&
3488{
3489 if (!priv_->void_pointer_type_)
3490 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3491 0, 0, location()));
3492 return priv_->void_pointer_type_;
3493}
3494
3495/// Get a @ref type_decl instance that represents a the type of a
3496/// variadic function parameter. This node must be the only one
3497/// representing a variadic parameter type in the system.
3498///
3499/// Note that upon first use of this IR node (by the relevant
3500/// front-end, for instance) it must be added to a scope using e.g,
3501/// the @ref add_decl_to_scope() function.
3502///
3503/// @return the Get a @ref type_decl instance that represents a the
3504/// type of a variadic function parameter.
3505const type_base_sptr&
3507{
3508 if (!priv_->variadic_marker_type_)
3509 priv_->variadic_marker_type_.
3511 0, 0, location()));
3512 return priv_->variadic_marker_type_;
3513}
3514
3515/// Getter of the name of the variadic parameter type.
3516///
3517/// @return the name of the variadic parameter type.
3518string&
3520{
3521 static string variadic_parameter_type_name = "variadic parameter type";
3522 return variadic_parameter_type_name;
3523}
3524
3525/// Test if the canonicalization of types created out of the current
3526/// environment is done.
3527///
3528/// @return true iff the canonicalization of types created out of the current
3529/// environment is done.
3530bool
3532{return priv_->canonicalization_is_done_;}
3533
3534/// Set a flag saying if the canonicalization of types created out of
3535/// the current environment is done or not.
3536///
3537/// Note that this function must only be called by internal code of
3538/// the library that creates ABI artifacts (e.g, read an abi corpus
3539/// from elf or from our own xml format and creates representations of
3540/// types out of it) and thus needs to canonicalize types to speed-up
3541/// further type comparison.
3542///
3543/// @param f the new value of the flag.
3544void
3546{
3547 priv_->canonicalization_is_done_ = f;
3548 if (priv_->canonicalization_is_done_)
3550}
3551
3552/// Getter of a flag saying if the canonicalization process has
3553/// started or not.
3554///
3555/// @return the flag saying if the canonicalization process has
3556/// started or not.
3557bool
3559{return priv_->canonicalization_started_;}
3560
3561/// Setter of a flag saying if the canonicalization process has
3562/// started or not.
3563///
3564/// @param f the new value of the flag saying if the canonicalization
3565/// process has started or not.
3566void
3568{priv_->canonicalization_started_ = f;}
3569
3570/// Getter of the "decl-only-class-equals-definition" flag.
3571///
3572/// Usually, a declaration-only class named 'struct foo' compares
3573/// equal to any class definition named "struct foo'. This is at
3574/// least true for C++.
3575///
3576/// In C, though, because there can be multiple definitions of 'struct
3577/// foo' in the binary, a declaration-only "struct foo" might be
3578/// considered to *NOT* resolve to any of the struct foo defined. In
3579/// that case, the declaration-only "struct foo" is considered
3580/// different from the definitions.
3581///
3582/// This flag controls the behaviour of the comparison of an
3583/// unresolved decl-only class against a definition of the same name.
3584///
3585/// If set to false, the the declaration equals the definition. If
3586/// set to false, then the decalration is considered different from
3587/// the declaration.
3588///
3589/// @return the value of the "decl-only-class-equals-definition" flag.
3590bool
3592{return priv_->decl_only_class_equals_definition_;}
3593
3594/// Setter of the "decl-only-class-equals-definition" flag.
3595///
3596/// Usually, a declaration-only class named 'struct foo' compares
3597/// equal to any class definition named "struct foo'. This is at
3598/// least true for C++.
3599///
3600/// In C, though, because there can be multiple definitions of 'struct
3601/// foo' in the binary, a declaration-only "struct foo" might be
3602/// considered to *NOT* resolve to any of the struct foo defined. In
3603/// that case, the declaration-only "struct foo" is considered
3604/// different from the definitions.
3605///
3606/// This flag controls the behaviour of the comparison of an
3607/// unresolved decl-only class against a definition of the same name.
3608///
3609/// If set to false, the the declaration equals the definition. If
3610/// set to false, then the decalration is considered different from
3611/// the declaration.
3612///
3613/// @param the new value of the "decl-only-class-equals-definition"
3614/// flag.
3615void
3617{priv_->decl_only_class_equals_definition_ = f;}
3618
3619/// Test if a given type is a void type as defined in the current
3620/// environment.
3621///
3622/// @param t the type to consider.
3623///
3624/// @return true iff @p t is a void type as defined in the current
3625/// environment.
3626bool
3627environment::is_void_type(const type_base_sptr& t) const
3628{
3629 if (!t)
3630 return false;
3631 return is_void_type(t.get());
3632}
3633
3634/// Test if a given type is a void type as defined in the current
3635/// environment.
3636///
3637/// @param t the type to consider.
3638///
3639/// @return true iff @p t is a void type as defined in the current
3640/// environment.
3641bool
3643{
3644 if (!t)
3645 return false;
3646 return (t == get_void_type().get()
3647 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3648}
3649
3650/// Test if a given type is the same as the void pointer type of the
3651/// environment.
3652///
3653/// @param t the IR type to test.
3654///
3655/// @return true iff @p t is the void pointer returned by
3656/// environment::get_void_pointer_type().
3657bool
3658environment::is_void_pointer_type(const type_base_sptr& t) const
3659{
3660 if (!t)
3661 return false;
3662
3663 return t.get() == get_void_pointer_type().get();
3664}
3665
3666/// Test if a given type is the same as the void pointer type of the
3667/// environment.
3668///
3669/// @param t the IR type to test.
3670///
3671/// @return true iff @p t is the void pointer returned by
3672/// environment::get_void_pointer_type().
3673bool
3675{
3676 if (!t)
3677 return false;
3678
3679 return t == get_void_pointer_type().get();
3680}
3681
3682/// Test if a type is a variadic parameter type as defined in the
3683/// current environment.
3684///
3685/// @param t the type to consider.
3686///
3687/// @return true iff @p t is a variadic parameter type as defined in
3688/// the current environment.
3689bool
3691{
3692 if (!t)
3693 return false;
3694 return t == get_variadic_parameter_type().get();
3695}
3696
3697/// Test if a type is a variadic parameter type as defined in the
3698/// current environment.
3699///
3700/// @param t the type to consider.
3701///
3702/// @return true iff @p t is a variadic parameter type as defined in
3703/// the current environment.
3704bool
3705environment::is_variadic_parameter_type(const type_base_sptr& t) const
3706{return is_variadic_parameter_type(t.get());}
3707
3708/// Do intern a string.
3709///
3710/// If a value of this string already exists in the interned string
3711/// pool of the current environment, then this function returns a new
3712/// interned_string pointing to that already existing string.
3713/// Otherwise, a new string is created, stored in the interned string
3714/// pool and a new interned_string instance is created to point to
3715/// that new intrerned string, and it's return.
3716///
3717/// @param s the value of the string to intern.
3718///
3719/// @return the interned string.
3721environment::intern(const string& s) const
3722{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3723
3724/// Getter of the general configuration object.
3725///
3726/// @return the configuration object.
3727const config&
3729{return priv_->config_;}
3730
3731/// Getter for a property that says if the user actually did set the
3732/// analyze_exported_interfaces_only() property. If not, it means
3733/// the default behaviour prevails.
3734///
3735/// @return tru iff the user did set the
3736/// analyze_exported_interfaces_only() property.
3737bool
3739{return priv_->analyze_exported_interfaces_only_.has_value();}
3740
3741/// Setter for the property that controls if we are to restrict the
3742/// analysis to the types that are only reachable from the exported
3743/// interfaces only, or if the set of types should be more broad than
3744/// that. Typically, we'd restrict the analysis to types reachable
3745/// from exported interfaces only (stricto sensu, that would really be
3746/// only the types that are part of the ABI of well designed
3747/// libraries) for performance reasons.
3748///
3749/// @param f the value of the flag.
3750void
3752{priv_->analyze_exported_interfaces_only_ = f;}
3753
3754/// Getter for the property that controls if we are to restrict the
3755/// analysis to the types that are only reachable from the exported
3756/// interfaces only, or if the set of types should be more broad than
3757/// that. Typically, we'd restrict the analysis to types reachable
3758/// from exported interfaces only (stricto sensu, that would really be
3759/// only the types that are part of the ABI of well designed
3760/// libraries) for performance reasons.
3761///
3762/// @param f the value of the flag.
3763bool
3765{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3766
3767#ifdef WITH_DEBUG_SELF_COMPARISON
3768/// Setter of the corpus of the input corpus of the self comparison
3769/// that takes place when doing "abidw --debug-abidiff <binary>".
3770///
3771/// The first invocation of this function sets the first corpus of the
3772/// self comparison. The second invocation of this very same function
3773/// sets the second corpus of the self comparison. That second corpus
3774/// is supposed to come from the abixml serialization of the first
3775/// corpus.
3776///
3777/// @param c the corpus of the input binary or the corpus of the
3778/// abixml serialization of the initial binary input.
3779void
3780environment::set_self_comparison_debug_input(const corpus_sptr& c)
3781{
3782 self_comparison_debug_is_on(true);
3783 if (priv_->first_self_comparison_corpus_.expired())
3784 priv_->first_self_comparison_corpus_ = c;
3785 else if (priv_->second_self_comparison_corpus_.expired()
3786 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3787 priv_->second_self_comparison_corpus_ = c;
3788}
3789
3790/// Getter for the corpora of the input binary and the intermediate
3791/// abixml of the self comparison that takes place when doing
3792/// 'abidw --debug-abidiff <binary>'.
3793///
3794/// @param first_corpus output parameter that is set to the corpus of
3795/// the input corpus.
3796///
3797/// @param second_corpus output parameter that is set to the corpus of
3798/// the second corpus.
3799void
3800environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3801 corpus_sptr& second_corpus)
3802{
3803 first_corpus = priv_->first_self_comparison_corpus_.lock();
3804 second_corpus = priv_->second_self_comparison_corpus_.lock();
3805}
3806
3807/// Turn on/off the self comparison debug mode.
3808///
3809/// @param f true iff the self comparison debug mode is turned on.
3810void
3811environment::self_comparison_debug_is_on(bool f)
3812{priv_->self_comparison_debug_on_ = f;}
3813
3814/// Test if we are in the process of the 'self-comparison
3815/// debugging' as triggered by 'abidw --debug-abidiff' command.
3816///
3817/// @return true if self comparison debug is on.
3818bool
3819environment::self_comparison_debug_is_on() const
3820{return priv_->self_comparison_debug_on_;}
3821#endif
3822
3823#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3824/// Set the "type canonicalization debugging" mode, triggered by using
3825/// the command: "abidw --debug-tc".
3826///
3827/// @param flag if true then the type canonicalization debugging mode
3828/// is enabled.
3829void
3830environment::debug_type_canonicalization_is_on(bool flag)
3831{priv_->debug_type_canonicalization_ = flag;}
3832
3833/// Getter of the "type canonicalization debugging" mode, triggered by
3834/// using the command: "abidw --debug-tc".
3835///
3836/// @return true iff the type canonicalization debugging mode is
3837/// enabled.
3838bool
3839environment::debug_type_canonicalization_is_on() const
3840{return priv_->debug_type_canonicalization_;}
3841
3842/// Setter of the "DIE canonicalization debugging" mode, triggered by
3843/// using the command: "abidw --debug-dc".
3844///
3845/// @param flag true iff the DIE canonicalization debugging mode is
3846/// enabled.
3847void
3848environment::debug_die_canonicalization_is_on(bool flag)
3849{priv_->debug_die_canonicalization_ = flag;}
3850
3851/// Getter of the "DIE canonicalization debugging" mode, triggered by
3852/// using the command: "abidw --debug-dc".
3853///
3854/// @return true iff the DIE canonicalization debugging mode is
3855/// enabled.
3856bool
3857environment::debug_die_canonicalization_is_on() const
3858{return priv_->debug_die_canonicalization_;}
3859#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3860
3861/// Get the vector of canonical types which have a given "string
3862/// representation".
3863///
3864/// @param 'name', the textual representation of the type as returned
3865/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3866/// /*qualified=*/true)
3867///
3868/// This is useful to for debugging purposes as it's handy to use from
3869/// inside a debugger like GDB.
3870///
3871/// @return a pointer to the vector of canonical types having the
3872/// representation @p name, or nullptr if no type with that
3873/// representation exists.
3874const vector<type_base_sptr>*
3876{
3877 auto ti = get_canonical_types_map().find(name);
3878 if (ti == get_canonical_types_map().end())
3879 return nullptr;
3880 return &ti->second;
3881}
3882
3883/// Get a given canonical type which has a given "string
3884/// representation".
3885///
3886/// @param 'name', the textual representation of the type as returned
3887/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3888/// /*qualified=*/true).
3889///
3890/// @param index, the index of the type in the vector of types that
3891/// all have the same textual representation @p 'name'. That vector
3892/// is returned by the function environment::get_canonical_types().
3893///
3894/// @return the canonical type which has the representation @p name,
3895/// and which is at index @p index in the vector of canonical types
3896/// having that same textual representation.
3897type_base*
3898environment::get_canonical_type(const char* name, unsigned index)
3899{
3900 const vector<type_base_sptr> *types = get_canonical_types(name);
3901 if (!types ||index >= types->size())
3902 return nullptr;
3903 return (*types)[index].get();
3904}
3905
3906#ifdef WITH_DEBUG_SELF_COMPARISON
3907/// Get the set of abixml type-id and the pointer value of the
3908/// (canonical) type it's associated to.
3909///
3910/// This is useful for debugging purposes, especially in the context
3911/// of the use of the command:
3912/// 'abidw --debug-abidiff <binary>'.
3913///
3914/// @return the set of abixml type-id and the pointer value of the
3915/// (canonical) type it's associated to.
3916const unordered_map<string, uintptr_t>&
3917environment::get_type_id_canonical_type_map() const
3918{return priv_->get_type_id_canonical_type_map();}
3919
3920/// Get the set of abixml type-id and the pointer value of the
3921/// (canonical) type it's associated to.
3922///
3923/// This is useful for debugging purposes, especially in the context
3924/// of the use of the command:
3925/// 'abidw --debug-abidiff <binary>'.
3926///
3927/// @return the set of abixml type-id and the pointer value of the
3928/// (canonical) type it's associated to.
3929unordered_map<string, uintptr_t>&
3930environment::get_type_id_canonical_type_map()
3931{return priv_->get_type_id_canonical_type_map();}
3932
3933/// Getter of the map that associates the values of type pointers to
3934/// their type-id strings.
3935///
3936/// Note that this map is populated at abixml reading time, (by
3937/// build_type()) when a given XML element representing a type is
3938/// read into a corresponding abigail::ir::type_base.
3939///
3940/// This is used only for the purpose of debugging the
3941/// self-comparison process. That is, when invoking "abidw
3942/// --debug-abidiff".
3943///
3944/// @return the map that associates the values of type pointers to
3945/// their type-id strings.
3946const unordered_map<uintptr_t, string>&
3947environment::get_pointer_type_id_map() const
3948{return priv_->get_pointer_type_id_map();}
3949
3950/// Getter of the map that associates the values of type pointers to
3951/// their type-id strings.
3952///
3953/// Note that this map is populated at abixml reading time, (by
3954/// build_type()) when a given XML element representing a type is
3955/// read into a corresponding abigail::ir::type_base.
3956///
3957/// This is used only for the purpose of debugging the
3958/// self-comparison process. That is, when invoking "abidw
3959/// --debug-abidiff".
3960///
3961/// @return the map that associates the values of type pointers to
3962/// their type-id strings.
3963unordered_map<uintptr_t, string>&
3964environment::get_pointer_type_id_map()
3965{return priv_->get_pointer_type_id_map();}
3966
3967/// Getter of the type-id that corresponds to the value of a pointer
3968/// to abigail::ir::type_base that was created from the abixml reader.
3969///
3970/// That value is retrieved from the map returned from
3971/// environment::get_pointer_type_id_map().
3972///
3973/// That map is populated at abixml reading time, (by build_type())
3974/// when a given XML element representing a type is read into a
3975/// corresponding abigail::ir::type_base.
3976///
3977/// This is used only for the purpose of debugging the
3978/// self-comparison process. That is, when invoking "abidw
3979/// --debug-abidiff".
3980///
3981/// @return the type-id strings that corresponds
3982string
3983environment::get_type_id_from_pointer(uintptr_t ptr) const
3984{return priv_->get_type_id_from_pointer(ptr);}
3985
3986/// Getter of the type-id that corresponds to the value of an
3987/// abigail::ir::type_base that was created from the abixml reader.
3988///
3989/// That value is retrieved from the map returned from
3990/// environment::get_pointer_type_id_map().
3991///
3992/// That map is populated at abixml reading time, (by build_type())
3993/// when a given XML element representing a type is read into a
3994/// corresponding abigail::ir::type_base.
3995///
3996/// This is used only for the purpose of debugging the
3997/// self-comparison process. That is, when invoking "abidw
3998/// --debug-abidiff".
3999///
4000/// @return the type-id strings that corresponds
4001string
4002environment::get_type_id_from_type(const type_base *t) const
4003{return priv_->get_type_id_from_type(t);}
4004
4005/// Getter of the canonical type of the artifact designated by a
4006/// type-id.
4007///
4008/// That type-id was generated by the abixml writer at the emitting
4009/// time of the abixml file. The corresponding canonical type was
4010/// stored in the map returned by
4011/// environment::get_type_id_canonical_type_map().
4012///
4013/// This is useful for debugging purposes, especially in the context
4014/// of the use of the command:
4015/// 'abidw --debug-abidiff <binary>'.
4016///
4017/// @return the set of abixml type-id and the pointer value of the
4018/// (canonical) type it's associated to.
4019uintptr_t
4020environment::get_canonical_type_from_type_id(const char* type_id) const
4021{return priv_->get_canonical_type_from_type_id(type_id);}
4022#endif
4023
4024// </environment stuff>
4025
4026// <type_or_decl_base stuff>
4027
4028/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4029/// bitmap type.
4033{
4034 return static_cast<type_or_decl_base::type_or_decl_kind>
4035 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4036}
4037
4038/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4039/// bitmap type.
4043{
4044 l = l | r;
4045 return l;
4046}
4047
4048/// bitwise "AND" operator for the
4049/// type_or_decl_base::type_or_decl_kind bitmap type.
4053{
4054 return static_cast<type_or_decl_base::type_or_decl_kind>
4055 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4056}
4057
4058/// bitwise "A&=" operator for the
4059/// type_or_decl_base::type_or_decl_kind bitmap type.
4063{
4064 l = l & r;
4065 return l;
4066}
4067
4068/// Constructor of @ref type_or_decl_base.
4069///
4070/// @param the environment the current ABI artifact is constructed
4071/// from.
4072///
4073/// @param k the runtime identifier bitmap of the type being built.
4074type_or_decl_base::type_or_decl_base(const environment& e,
4075 enum type_or_decl_kind k)
4076 :priv_(new priv(e, k))
4077{}
4078
4079/// The destructor of the @ref type_or_decl_base type.
4081{}
4082
4083/// Getter of the flag that says if the artefact is artificial.
4084///
4085/// Being artificial means it was not explicitely mentionned in the
4086/// source code, but was rather artificially created by the compiler
4087/// or libabigail.
4088///
4089/// @return true iff the declaration is artificial.
4090bool
4092{return priv_->is_artificial_;}
4093
4094/// Setter of the flag that says if the artefact is artificial.
4095///
4096/// Being artificial means the artefact was not explicitely
4097/// mentionned in the source code, but was rather artificially created
4098/// by the compiler or by libabigail.
4099///
4100/// @param f the new value of the flag that says if the artefact is
4101/// artificial.
4102void
4104{priv_->is_artificial_ = f;}
4105
4106/// Getter for the "kind" property of @ref type_or_decl_base type.
4107///
4108/// This property holds the identifier bitmap of the runtime type of
4109/// an ABI artifact.
4110///
4111/// @return the runtime type identifier bitmap of the current ABI
4112/// artifact.
4115{return priv_->kind();}
4116
4117/// Setter for the "kind" property of @ref type_or_decl_base type.
4118///
4119/// This property holds the identifier bitmap of the runtime type of
4120/// an ABI artifact.
4121///
4122/// @param the runtime type identifier bitmap of the current ABI
4123/// artifact.
4124void
4126{priv_->kind(k);}
4127
4128/// Getter of the pointer to the runtime type sub-object of the
4129/// current instance.
4130///
4131/// @return the pointer to the runtime type sub-object of the current
4132/// instance.
4133const void*
4135{return priv_->rtti_;}
4136
4137/// Getter of the pointer to the runtime type sub-object of the
4138/// current instance.
4139///
4140/// @return the pointer to the runtime type sub-object of the current
4141/// instance.
4142void*
4144{return priv_->rtti_;}
4145
4146/// Setter of the pointer to the runtime type sub-object of the
4147/// current instance.
4148///
4149/// @param i the new pointer to the runtime type sub-object of the
4150/// current instance.
4151void
4153{
4154 priv_->rtti_ = i;
4155 if (type_base* t = dynamic_cast<type_base*>(this))
4156 priv_->type_or_decl_ptr_ = t;
4157 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4158 priv_->type_or_decl_ptr_ = d;
4159}
4160
4161/// Getter of the pointer to either the type_base sub-object of the
4162/// current instance if it's a type, or to the decl_base sub-object of
4163/// the current instance if it's a decl.
4164///
4165/// @return the pointer to either the type_base sub-object of the
4166/// current instance if it's a type, or to the decl_base sub-object of
4167/// the current instance if it's a decl.
4168const void*
4170{return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4171
4172/// Getter of 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.
4175///
4176/// @return the pointer to either the type_base sub-object of the
4177/// current instance if it's a type, or to the decl_base sub-object of
4178/// the current instance if it's a decl.
4179void*
4181{return priv_->type_or_decl_ptr_;}
4182
4183/// Return the hash value of the current IR node.
4184///
4185/// Note that upon the first invocation, this member functions
4186/// computes the hash value and returns it. Subsequent invocations
4187/// just return the hash value that was previously calculated.
4188///
4189/// @return the hash value of the current IR node.
4190hash_t
4192{return priv_->hash_value_;}
4193
4194void
4195type_or_decl_base::set_hash_value(hash_t h) const
4196{priv_->set_hash_value(h);}
4197
4198/// Getter of the environment of the current ABI artifact.
4199///
4200/// @return the environment of the artifact.
4201const environment&
4203{return priv_->env_;}
4204
4205/// Setter of the artificial location of the artificat.
4206///
4207/// The artificial location is a location that was artificially
4208/// generated by libabigail, not generated by the original emitter of
4209/// the ABI meta-data. For instance, when reading an XML element from
4210/// an abixml file, the artificial location is the source location of
4211/// the XML element within the file, not the value of the
4212/// 'location'property that might be carried by the element.
4213///
4214/// Artificial locations might be useful to ensure that abixml emitted
4215/// by the abixml writer are sorted the same way as the input abixml
4216/// read by the reader.
4217///
4218/// @param l the new artificial location.
4219void
4221{priv_->artificial_location_ = l;}
4222
4223/// Getter of the artificial location of the artifact.
4224///
4225/// The artificial location is a location that was artificially
4226/// generated by libabigail, not generated by the original emitter of
4227/// the ABI meta-data. For instance, when reading an XML element from
4228/// an abixml file, the artificial location is the source location of
4229/// the XML element within the file, not the value of the
4230/// 'location'property that might be carried by the element.
4231///
4232/// Artificial locations might be useful to ensure that the abixml
4233/// emitted by the abixml writer is sorted the same way as the input
4234/// abixml read by the reader.
4235///
4236/// @return the new artificial location.
4237location&
4239{return priv_->artificial_location_;}
4240
4241/// Test if the current ABI artifact carries an artificial location.
4242///
4243/// @return true iff the current ABI artifact carries an artificial location.
4244bool
4246{
4247 return (priv_->artificial_location_
4248 && priv_->artificial_location_.get_is_artificial());
4249}
4250
4251/// Get the @ref corpus this ABI artifact belongs to.
4252///
4253/// @return the corpus this ABI artifact belongs to, or nil if it
4254/// belongs to none for now.
4255corpus*
4257{
4259 if (!tu)
4260 return 0;
4261 return tu->get_corpus();
4262}
4263
4264
4265/// Get the @ref corpus this ABI artifact belongs to.
4266///
4267/// @return the corpus this ABI artifact belongs to, or nil if it
4268/// belongs to none for now.
4269const corpus*
4271{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4272
4273/// Set the @ref translation_unit this ABI artifact belongs to.
4274///
4275/// Note that adding an ABI artifact to a containining on should
4276/// invoke this member function.
4277void
4279{priv_->translation_unit_ = tu;}
4280
4281
4282/// Get the @ref translation_unit this ABI artifact belongs to.
4283///
4284/// @return the translation unit this ABI artifact belongs to, or nil
4285/// if belongs to none for now.
4288{return priv_->translation_unit_;}
4289
4290/// Get the @ref translation_unit this ABI artifact belongs to.
4291///
4292/// @return the translation unit this ABI artifact belongs to, or nil
4293/// if belongs to none for now.
4294const translation_unit*
4296{return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4297
4298/// Traverse the the ABI artifact.
4299///
4300/// @param v the visitor used to traverse the sub-tree nodes of the
4301/// artifact.
4302bool
4304{return true;}
4305
4306/// Non-member equality operator for the @type_or_decl_base type.
4307///
4308/// @param lr the left-hand operand of the equality.
4309///
4310/// @param rr the right-hand operatnr of the equality.
4311///
4312/// @return true iff @p lr equals @p rr.
4313bool
4315{
4316 const type_or_decl_base* l = &lr;
4317 const type_or_decl_base* r = &rr;
4318
4319 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4320 *dr = dynamic_cast<const decl_base*>(r);
4321
4322 if (!!dl != !!dr)
4323 return false;
4324
4325 if (dl && dr)
4326 return *dl == *dr;
4327
4328 const type_base* tl = dynamic_cast<const type_base*>(l),
4329 *tr = dynamic_cast<const type_base*>(r);
4330
4331 if (!!tl != !!tr)
4332 return false;
4333
4334 if (tl && tr)
4335 return *tl == *tr;
4336
4337 return false;
4338}
4339
4340/// Non-member equality operator for the @type_or_decl_base type.
4341///
4342/// @param l the left-hand operand of the equality.
4343///
4344/// @param r the right-hand operatnr of the equality.
4345///
4346/// @return true iff @p l equals @p r.
4347bool
4349{
4350 if (!! l != !!r)
4351 return false;
4352
4353 if (!l)
4354 return true;
4355
4356 return *r == *l;
4357}
4358
4359/// Non-member inequality operator for the @type_or_decl_base type.
4360///
4361/// @param l the left-hand operand of the equality.
4362///
4363/// @param r the right-hand operator of the equality.
4364///
4365/// @return true iff @p l is different from @p r.
4366bool
4368{return !operator==(l, r);}
4369
4370// </type_or_decl_base stuff>
4371
4372// <Decl definition>
4373
4374struct decl_base::priv
4375{
4376 bool in_pub_sym_tab_;
4377 bool is_anonymous_;
4378 location location_;
4379 context_rel *context_;
4380 interned_string name_;
4381 interned_string qualified_parent_name_;
4382 // This temporary qualified name is the cache used for the qualified
4383 // name before the type associated to this decl (if applicable) is
4384 // canonicalized. Once the type is canonicalized, the cached use is
4385 // the data member qualified_parent_name_ above.
4386 interned_string temporary_qualified_name_;
4387 // This is the fully qualified name of the decl. It contains the
4388 // name of the decl and the qualified name of its scope. So if in
4389 // the parent scopes of the decl, there is one anonymous struct,
4390 // somewhere in the name, there is going to by an
4391 // __anonymous_struct__ string, even if the anonymous struct is not
4392 // the direct containing scope of this decl.
4393 interned_string qualified_name_;
4394 interned_string temporary_internal_qualified_name_;
4395 interned_string internal_qualified_name_;
4396 interned_string internal_cached_repr_;
4397 interned_string cached_repr_;
4398 // Unline qualified_name_, scoped_name_ contains the name of the
4399 // decl and the name of its scope; not the qualified name of the
4400 // scope.
4401 interned_string scoped_name_;
4402 interned_string linkage_name_;
4403 visibility visibility_;
4404 decl_base_sptr declaration_;
4405 decl_base_wptr definition_of_declaration_;
4406 decl_base* naked_definition_of_declaration_;
4407 bool is_declaration_only_;
4408 typedef_decl_sptr naming_typedef_;
4409
4410 priv()
4411 : in_pub_sym_tab_(false),
4412 is_anonymous_(true),
4413 context_(),
4414 visibility_(VISIBILITY_DEFAULT),
4415 naked_definition_of_declaration_(),
4416 is_declaration_only_(false)
4417 {}
4418
4419 priv(interned_string name, interned_string linkage_name, visibility vis)
4420 : in_pub_sym_tab_(false),
4421 context_(),
4422 name_(name),
4423 qualified_name_(name),
4424 linkage_name_(linkage_name),
4425 visibility_(vis),
4426 naked_definition_of_declaration_(),
4427 is_declaration_only_(false)
4428 {
4429 is_anonymous_ = name_.empty();
4430 }
4431
4432 ~priv()
4433 {
4434 delete context_;
4435 }
4436};// end struct decl_base::priv
4437
4438/// Constructor for the @ref decl_base type.
4439///
4440/// @param e the environment the current @ref decl_base is being
4441/// created in.
4442///
4443/// @param name the name of the declaration.
4444///
4445/// @param locus the location where to find the declaration in the
4446/// source code.
4447///
4448/// @param linkage_name the linkage name of the declaration.
4449///
4450/// @param vis the visibility of the declaration.
4451decl_base::decl_base(const environment& e,
4452 const string& name,
4453 const location& locus,
4454 const string& linkage_name,
4455 visibility vis)
4456 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4457 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4458{
4459 set_location(locus);
4460}
4461
4462/// Constructor.
4463///
4464/// @param e the environment this instance of @ref decl_base is
4465/// created in.
4466///
4467/// @param name the name of the declaration being constructed.
4468///
4469/// @param locus the source location of the declaration being constructed.
4470///
4471/// @param linkage_name the linkage name of the declaration being
4472/// constructed.
4473///
4474/// @param vis the visibility of the declaration being constructed.
4475decl_base::decl_base(const environment& e,
4476 const interned_string& name,
4477 const location& locus,
4478 const interned_string& linkage_name,
4479 visibility vis)
4480 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4481 priv_(new priv(name, linkage_name, vis))
4482{
4483 set_location(locus);
4484}
4485
4486/// Constructor for the @ref decl_base type.
4487///
4488///@param environment the environment this instance of @ref decl_base
4489/// is being constructed in.
4490///
4491/// @param l the location where to find the declaration in the source
4492/// code.
4493decl_base::decl_base(const environment& e, const location& l)
4494 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4495 priv_(new priv())
4496{
4497 set_location(l);
4498}
4499
4500/// Getter for the qualified name.
4501///
4502/// Unlike decl_base::get_qualified_name() this doesn't try to update
4503/// the qualified name.
4504///
4505/// @return the qualified name.
4506const interned_string&
4508{return priv_->qualified_name_;}
4509
4510/// Clear the qualified name of this decl.
4511///
4512/// This is useful to ensure that the cache for the qualified name of
4513/// the decl is refreshed right after type canonicalization, for
4514/// instance.
4515void
4517{priv_->qualified_name_.clear();}
4518
4519/// Setter for the qualified name.
4520///
4521/// @param n the new qualified name.
4522void
4524{priv_->qualified_name_ = n;}
4525
4526/// Getter of the temporary qualified name of the current declaration.
4527///
4528/// This temporary qualified name is used as a qualified name cache by
4529/// the type for which this is the declaration (when applicable)
4530/// before the type is canonicalized. Once the type is canonicalized,
4531/// it's the result of decl_base::peek_qualified_name() that becomes
4532/// the qualified name cached.
4533///
4534/// @return the temporary qualified name.
4535const interned_string&
4537{return priv_->temporary_qualified_name_;}
4538
4539/// Setter for the temporary qualified name of the current
4540/// declaration.
4541///
4542///@param n the new temporary qualified name.
4543///
4544/// This temporary qualified name is used as a qualified name cache by
4545/// the type for which this is the declaration (when applicable)
4546/// before the type is canonicalized. Once the type is canonicalized,
4547/// it's the result of decl_base::peek_qualified_name() that becomes
4548/// the qualified name cached.
4549void
4551{priv_->temporary_qualified_name_ = n;}
4552
4553///Getter for the context relationship.
4554///
4555///@return the context relationship for the current decl_base.
4556const context_rel*
4558{return priv_->context_;}
4559
4560///Getter for the context relationship.
4561///
4562///@return the context relationship for the current decl_base.
4565{return priv_->context_;}
4566
4567void
4568decl_base::set_context_rel(context_rel *c)
4569{priv_->context_ = c;}
4570
4571/// Test if the decl is defined in a ELF symbol table as a public
4572/// symbol.
4573///
4574/// @return true iff the decl is defined in a ELF symbol table as a
4575/// public symbol.
4576bool
4578{return priv_->in_pub_sym_tab_;}
4579
4580/// Set the flag saying if this decl is from a symbol that is in
4581/// a public symbols table, defined as public (global or weak).
4582///
4583/// @param f the new flag value.
4584void
4586{priv_->in_pub_sym_tab_ = f;}
4587
4588/// Get the location of a given declaration.
4589///
4590/// The location is an abstraction for the tripplet {file path,
4591/// line, column} that defines where the declaration appeared in the
4592/// source code.
4593///
4594/// To get the value of the tripplet {file path, line, column} from
4595/// the @ref location, you need to use the
4596/// location_manager::expand_location() method.
4597///
4598/// The instance of @ref location_manager that you want is
4599/// accessible from the instance of @ref translation_unit that the
4600/// current instance of @ref decl_base belongs to, via a call to
4601/// translation_unit::get_loc_mgr().
4602///
4603/// @return the location of the current instance of @ref decl_base.
4604const location&
4606{return priv_->location_;}
4607
4608/// Set the location for a given declaration.
4609///
4610/// The location is an abstraction for the tripplet {file path,
4611/// line, column} that defines where the declaration appeared in the
4612/// source code.
4613///
4614/// To create a location from a tripplet {file path, line, column},
4615/// you need to use the method @ref
4616/// location_manager::create_new_location().
4617///
4618/// Note that there can be two kinds of location. An artificial
4619/// location and a non-artificial one. The non-artificial location is
4620/// the one emitted by the original emitter of the ABI artifact, for
4621/// instance, if the ABI artifact comes from debug info, then the
4622/// source location that is present in the debug info represent a
4623/// non-artificial location. When looking at an abixml file on the
4624/// other hand, the value of the 'location' attribute of an XML
4625/// element describing an artifact is the non-artificial location.
4626/// The artificial location is the location (line number from the
4627/// beginning of the file) of the XML element within the abixml file.
4628///
4629/// So, if the location that is being set is artificial, note that the
4630/// type_or_decl_base::has_artificial_location() method of this decl will
4631/// subsequently return true and that artificial location will have to
4632/// be retrieved using type_or_decl_base::get_artificial_location().
4633/// If the location is non-artificial however,
4634/// type_or_decl_base::has_artificial_location() will subsequently
4635/// return false and the non-artificial location will have to be
4636/// retrieved using decl_base::get_location().
4637///
4638/// The instance of @ref location_manager that you want is
4639/// accessible from the instance of @ref translation_unit that the
4640/// current instance of @ref decl_base belongs to, via a call to
4641/// translation_unit::get_loc_mgr().
4642void
4644{
4645 if (l.get_is_artificial())
4647 else
4648 priv_->location_ = l;
4649}
4650
4651/// Setter for the name of the decl.
4652///
4653/// @param n the new name to set.
4654void
4655decl_base::set_name(const string& n)
4656{
4657 priv_->name_ = get_environment().intern(n);
4658 priv_->is_anonymous_ = n.empty();
4659}
4660
4661/// Test if the current declaration is anonymous.
4662///
4663/// Being anonymous means that the declaration was created without a
4664/// name. This can usually happen for enum or struct types.
4665///
4666/// @return true iff the type is anonymous.
4667bool
4669{return priv_->is_anonymous_;}
4670
4671/// Set the "is_anonymous" flag of the current declaration.
4672///
4673/// Being anonymous means that the declaration was created without a
4674/// name. This can usually happen for enum or struct types.
4675///
4676/// @param f the new value of the flag.
4677void
4679{priv_->is_anonymous_ = f;}
4680
4681
4682/// Get the "has_anonymous_parent" flag of the current declaration.
4683///
4684/// Having an anoymous parent means having a anonymous parent scope
4685/// (containing type or namespace) which is either direct or indirect.
4686///
4687/// @return true iff the current decl has a direct or indirect scope
4688/// which is anonymous.
4689bool
4691{
4692 scope_decl *scope = get_scope();
4693 if (!scope)
4694 return false;
4695 return scope->get_is_anonymous();
4696}
4697
4698/// @return the logical "OR" of decl_base::get_is_anonymous() and
4699/// decl_base::get_has_anonymous_parent().
4700bool
4703
4704/// Getter for the naming typedef of the current decl.
4705///
4706/// Consider the C idiom:
4707///
4708/// typedef struct {int member;} foo_type;
4709///
4710/// In that idiom, foo_type is the naming typedef of the anonymous
4711/// struct that is declared.
4712///
4713/// @return the naming typedef, if any. Otherwise, returns nil.
4716{return priv_->naming_typedef_;}
4717
4718/// Set the naming typedef of the current instance of @ref decl_base.
4719///
4720/// Consider the C idiom:
4721///
4722/// typedef struct {int member;} foo_type;
4723///
4724/// In that idiom, foo_type is the naming typedef of the anonymous
4725/// struct that is declared.
4726///
4727/// After completion of this function, the decl will not be considered
4728/// anonymous anymore. It's name is going to be the name of the
4729/// naming typedef.
4730///
4731/// @param typedef_type the new naming typedef.
4732void
4734{
4735 // A naming typedef is usually for an anonymous type.
4737 // Whe the typedef-named decl is saved into abixml, it's
4738 // not anonymous anymore. Its name is the typedef name.
4739 // So when we read it back, we must still be able to
4740 // apply the naming typedef to the decl.
4741 || t->get_name() == get_name());
4742 // Only non canonicalized types can be edited this way.
4743 ABG_ASSERT(is_type(this)
4744 && is_type(this)->get_naked_canonical_type() == nullptr);
4745
4746 priv_->naming_typedef_ = t;
4747 set_name(t->get_name());
4748 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4749 set_qualified_name(get_environment().intern(qualified_name));
4750 set_is_anonymous(false);
4751 // Now that the qualified type of the decl has changed, let's update
4752 // the qualified names of the member types of this decls.
4753 update_qualified_name(this);
4754}
4755
4756/// Getter for the mangled name.
4757///
4758/// @return the new mangled name.
4759const interned_string&
4761{return priv_->linkage_name_;}
4762
4763/// Setter for the linkage name.
4764///
4765/// @param m the new linkage name.
4766void
4768{
4769 const environment& env = get_environment();
4770 priv_->linkage_name_ = env.intern(m);
4771}
4772
4773/// Getter for the visibility of the decl.
4774///
4775/// @return the new visibility.
4778{return priv_->visibility_;}
4779
4780/// Setter for the visibility of the decl.
4781///
4782/// @param v the new visibility.
4783void
4785{priv_->visibility_ = v;}
4786
4787/// Return the type containing the current decl, if any.
4788///
4789/// @return the type that contains the current decl, or NULL if there
4790/// is none.
4793{
4794 if (priv_->context_)
4795 return priv_->context_->get_scope();
4796 return 0;
4797}
4798
4799/// Return a copy of the qualified name of the parent of the current
4800/// decl.
4801///
4802/// @return the newly-built qualified name of the of the current decl.
4803const interned_string&
4805{return priv_->qualified_parent_name_;}
4806
4807/// Getter for the name of the current decl.
4808///
4809/// @return the name of the current decl.
4810const interned_string&
4812{return priv_->name_;}
4813
4814/// Compute the qualified name of the decl.
4815///
4816/// @param qn the resulting qualified name.
4817///
4818/// @param internal set to true if the call is intended for an
4819/// internal use (for technical use inside the library itself), false
4820/// otherwise. If you don't know what this is for, then set it to
4821/// false.
4822void
4824{qn = get_qualified_name(internal);}
4825
4826/// Get the pretty representatin of the current declaration.
4827///
4828///
4829/// @param internal set to true if the call is intended to get a
4830/// representation of the decl (or type) for the purpose of canonical
4831/// type comparison. This is mainly used in the function
4832/// type_base::get_canonical_type_for().
4833///
4834/// In other words if the argument for this parameter is true then the
4835/// call is meant for internal use (for technical use inside the
4836/// library itself), false otherwise. If you don't know what this is
4837/// for, then set it to false.
4838///
4839/// @param qualified_name if true, names emitted in the pretty
4840/// representation are fully qualified.
4841///
4842/// @return the default pretty representation for a decl. This is
4843/// basically the fully qualified name of the decl optionally prefixed
4844/// with a meaningful string to add context for the user.
4845string
4847 bool qualified_name) const
4848{
4849 if (internal
4850 && get_is_anonymous()
4851 && has_generic_anonymous_internal_type_name(this))
4852 {
4853 // We are looking at an anonymous enum, union or class and we
4854 // want an *internal* pretty representation for it. All
4855 // anonymous types of this kind in the same namespace must have
4856 // the same internal representation for type canonicalization to
4857 // work properly.
4858 //
4859 // OK, in practise, we are certainly looking at an enum because
4860 // classes and unions should have their own overloaded virtual
4861 // member function for this.
4862 string name = get_generic_anonymous_internal_type_name(this);
4863 if (qualified_name && !get_qualified_parent_name().empty())
4864 name = get_qualified_parent_name() + "::" + name;
4865 return name;
4866 }
4867
4868 if (qualified_name)
4869 return get_qualified_name(internal);
4870 return get_name();
4871}
4872
4873/// Get the pretty representation of the current decl.
4874///
4875/// The pretty representation is retrieved from a cache. If the cache
4876/// is empty, this function computes the pretty representation, put it
4877/// in the cache and returns it.
4878///
4879/// Please note that if this function is called too early in the life
4880/// cycle of the decl (before it is fully constructed), then the
4881/// pretty representation that is cached is going to represent a
4882/// non-complete (and thus wrong) representation of the decl. Thus
4883/// this function must be called only once the decl is fully
4884/// constructed.
4885///
4886/// @param internal if true, then the pretty representation is to be
4887/// used for purpuses that are internal to the libabigail library
4888/// itself. If you don't know what this means, then you probably
4889/// should set this parameter to "false".
4890///
4891/// @return a reference to a cached @ref interned_string holding the
4892/// pretty representation of the current decl.
4893const interned_string&
4895{
4896 if (internal)
4897 {
4898 if (priv_->internal_cached_repr_.empty())
4899 {
4900 string r = ir::get_pretty_representation(this, internal);
4901 priv_->internal_cached_repr_ = get_environment().intern(r);
4902 }
4903 return priv_->internal_cached_repr_;
4904 }
4905
4906 if (priv_->cached_repr_.empty())
4907 {
4908 string r = ir::get_pretty_representation(this, internal);
4909 priv_->cached_repr_ = get_environment().intern(r);
4910 }
4911
4912 return priv_->cached_repr_;
4913}
4914
4915/// Return the qualified name of the decl.
4916///
4917/// This is the fully qualified name of the decl. It's made of the
4918/// concatenation of the name of the decl with the qualified name of
4919/// its scope.
4920///
4921/// Note that the value returned by this function is computed by @ref
4922/// update_qualified_name when the decl is added to its scope.
4923///
4924/// @param internal set to true if the call is intended for an
4925/// internal use (for technical use inside the library itself), false
4926/// otherwise. If you don't know what this is for, then set it to
4927/// false.
4928///
4929/// @return the resulting qualified name.
4930const interned_string&
4931decl_base::get_qualified_name(bool /*internal*/) const
4932{return priv_->qualified_name_;}
4933
4934/// Return the scoped name of the decl.
4935///
4936/// This is made of the concatenation of the name of the decl with the
4937/// name of its scope. It doesn't contain the qualified name of its
4938/// scope, unlike what is returned by decl_base::get_qualified_name.
4939///
4940/// Note that the value returned by this function is computed by @ref
4941/// update_qualified_name when the decl is added to its scope.
4942///
4943/// @return the scoped name of the decl.
4944const interned_string&
4946{return priv_->scoped_name_;}
4947
4948/// If this @ref decl_base is a definition, get its earlier
4949/// declaration.
4950///
4951/// @return the earlier declaration of the class, if any.
4952const decl_base_sptr
4954{return priv_->declaration_;}
4955
4956/// set the earlier declaration of this @ref decl_base definition.
4957///
4958/// @param d the earlier declaration to set. Note that it's set only
4959/// if it's a pure declaration.
4960void
4962{
4963 if (d && d->get_is_declaration_only())
4964 priv_->declaration_ = d;
4965}
4966
4967
4968/// If this @ref decl_base is declaration-only, get its definition, if
4969/// any.
4970///
4971/// @return the definition of this decl-only @ref decl_base.
4972const decl_base_sptr
4974{return priv_->definition_of_declaration_.lock();}
4975
4976/// If this @ref decl_base is declaration-only, get its definition,
4977/// if any.
4978///
4979/// Note that this function doesn't return a smart pointer, but rather
4980/// the underlying pointer managed by the smart pointer. So it's as
4981/// fast as possible. This getter is to be used in code paths that
4982/// are proven to be performance hot spots; especially, when comparing
4983/// sensitive types like enums, classes or unions. Those are compared
4984/// extremely frequently and thus, their access to the definition of
4985/// declaration must be fast.
4986///
4987/// @return the definition of the declaration.
4988const decl_base*
4990{return priv_->naked_definition_of_declaration_;}
4991
4992/// Test if a @ref decl_base is a declaration-only decl.
4993///
4994/// @return true iff the current @ref decl_base is declaration-only.
4995bool
4997{return priv_->is_declaration_only_;}
4998
4999/// Set a flag saying if the @ref enum_type_decl is a declaration-only
5000/// @ref enum_type_decl.
5001///
5002/// @param f true if the @ref enum_type_decl is a declaration-only
5003/// @ref enum_type_decl.
5004void
5006{
5007 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5008
5009 priv_->is_declaration_only_ = f;
5010
5011 if (update_types_lookup_map)
5012 if (scope_decl* s = get_scope())
5013 {
5014 scope_decl::declarations::iterator i;
5015 if (s->find_iterator_for_member(this, i))
5017 else
5019 }
5020}
5021
5024{
5025 return static_cast<change_kind>(static_cast<unsigned>(l)
5026 | static_cast<unsigned>(r));
5027}
5028
5031{
5032 return static_cast<change_kind>(static_cast<unsigned>(l)
5033 & static_cast<unsigned>(r));
5034}
5035
5038{
5039 l = l | r;
5040 return l;
5041}
5042
5045{
5046 l = l & r;
5047 return l;
5048}
5049
5050/// Compare the properties that belong to the "is-a-member-relation"
5051/// of a decl.
5052///
5053/// For instance, access specifiers are part of the
5054/// "is-a-member-relation" of a decl.
5055///
5056/// This comparison however doesn't take decl names into account. So
5057/// typedefs for instance are decls that we want to compare with this
5058/// function.
5059///
5060/// This function is a sub-routine of the more general 'equals'
5061/// overload for instances of decl_base.
5062///
5063/// @param l the left-hand side operand of the comparison.
5064///
5065/// @param r the right-hand side operand of the comparison.
5066///
5067/// @return true iff @p l compare equals, as a member decl, to @p r.
5068bool
5070 const decl_base& r,
5071 change_kind* k)
5072{
5073 bool result = true;
5074 if (is_member_decl(l) && is_member_decl(r))
5075 {
5076 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5077 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5078
5079 access_specifier la = no_access, ra = no_access;
5080 bool member_types_or_functions =
5081 ((is_type(l) && is_type(r))
5082 || (is_function_decl(l) && is_function_decl(r)));
5083
5084 if (member_types_or_functions)
5085 {
5086 // Access specifiers on member types in DWARF is not
5087 // reliable; in the same DSO, the same struct can be either
5088 // a class or a struct, and the access specifiers of its
5089 // member types are not necessarily given, so they
5090 // effectively can be considered differently, again, in the
5091 // same DSO. So, here, let's avoid considering those!
5092 // during comparison.
5093 la = r1->get_access_specifier();
5094 ra = r2->get_access_specifier();
5095 r1->set_access_specifier(no_access);
5096 r2->set_access_specifier(no_access);
5097 }
5098
5099 bool rels_are_different = *r1 != *r2;
5100
5101 if (member_types_or_functions)
5102 {
5103 // restore the access specifiers.
5104 r1->set_access_specifier(la);
5105 r2->set_access_specifier(ra);
5106 }
5107
5108 if (rels_are_different)
5109 {
5110 result = false;
5111 if (k)
5113 }
5114 }
5115 ABG_RETURN(result);
5116}
5117
5118/// Compares two instances of @ref decl_base.
5119///
5120/// If the two intances are different, set a bitfield to give some
5121/// insight about the kind of differences there are.
5122///
5123/// @param l the first artifact of the comparison.
5124///
5125/// @param r the second artifact of the comparison.
5126///
5127/// @param k a pointer to a bitfield that gives information about the
5128/// kind of changes there are between @p l and @p r. This one is set
5129/// iff it's non-null and if the function returns false.
5130///
5131/// Please note that setting k to a non-null value does have a
5132/// negative performance impact because even if @p l and @p r are not
5133/// equal, the function keeps up the comparison in order to determine
5134/// the different kinds of ways in which they are different.
5135///
5136/// @return true if @p l equals @p r, false otherwise.
5137bool
5138equals(const decl_base& l, const decl_base& r, change_kind* k)
5139{
5140 bool result = true;
5141 const interned_string &l_linkage_name = l.get_linkage_name();
5142 const interned_string &r_linkage_name = r.get_linkage_name();
5143 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5144 {
5145 if (l_linkage_name != r_linkage_name)
5146 {
5147 // Linkage names are different. That usually means the two
5148 // decls are different, unless we are looking at two
5149 // function declarations which have two different symbols
5150 // that are aliases of each other.
5151 const function_decl *f1 = is_function_decl(&l),
5152 *f2 = is_function_decl(&r);
5153 if (f1 && f2 && function_decls_alias(*f1, *f2))
5154 ;// The two functions are aliases, so they are not
5155 // different.
5156 else
5157 {
5158 result = false;
5159 if (k)
5161 else
5163 }
5164 }
5165 }
5166
5167 if (r.get_is_anonymous() && l.get_is_anonymous())
5168 // We are looking at too anonymous types (or two members of
5169 // anonymous types) with one not yet been added to the IR. That
5170 // means we want to compare just the object part of the
5171 // anonymous type and not their qualified names. This is used
5172 // when looking up an anonymous type inside a class type.
5173 ABG_RETURN(result);
5174
5175 // This is the name of the decls that we want to compare.
5176 interned_string ln = l.get_name(), rn = r.get_name();
5177
5178 /// If both of the current decls have an anonymous scope then let's
5179 /// compare their name component by component by properly handling
5180 /// anonymous scopes. That's the slow path.
5181 ///
5182 /// Otherwise, let's just compare their name, the obvious way.
5183 /// That's the fast path because in that case the names are
5184 /// interned_string and comparing them is much faster.
5185 bool decls_are_same = (ln == rn);
5186
5187 if (!decls_are_same)
5188 {
5189 result = false;
5190 if (k)
5192 else
5194 }
5195
5196 result &= maybe_compare_as_member_decls(l, r, k);
5197
5198 ABG_RETURN(result);
5199}
5200
5201/// Return true iff the two decls have the same name.
5202///
5203/// This function doesn't test if the scopes of the the two decls are
5204/// equal.
5205///
5206/// Note that this virtual function is to be implemented by classes
5207/// that extend the \p decl_base class.
5208bool
5210{return equals(*this, other, 0);}
5211
5212/// Inequality operator.
5213///
5214/// @param other to other instance of @ref decl_base to compare the
5215/// current instance to.
5216///
5217/// @return true iff the current instance of @ref decl_base is
5218/// different from @p other.
5219bool
5221{return !operator==(other);}
5222
5223/// Destructor of the @ref decl_base type.
5225{delete priv_;}
5226
5227/// This implements the ir_traversable_base::traverse pure virtual
5228/// function.
5229///
5230/// @param v the visitor used on the member nodes of the translation
5231/// unit during the traversal.
5232///
5233/// @return true if the entire IR node tree got traversed, false
5234/// otherwise.
5235bool
5237{
5238 // Do nothing in the base class.
5239 return true;
5240}
5241
5242/// Setter of the scope of the current decl.
5243///
5244/// Note that the decl won't hold a reference on the scope. It's
5245/// rather the scope that holds a reference on its members.
5246void
5248{
5249 if (!priv_->context_)
5250 priv_->context_ = new context_rel(scope);
5251 else
5252 priv_->context_->set_scope(scope);
5253}
5254
5255// </decl_base definition>
5256
5257/// Streaming operator for the decl_base::visibility.
5258///
5259/// @param o the output stream to serialize the visibility to.
5260///
5261/// @param v the visibility to serialize.
5262///
5263/// @return the output stream.
5264std::ostream&
5265operator<<(std::ostream& o, decl_base::visibility v)
5266{
5267 string r;
5268 switch (v)
5269 {
5270 case decl_base::VISIBILITY_NONE:
5271 r = "none";
5272 break;
5273 case decl_base::VISIBILITY_DEFAULT:
5274 r = "default";
5275 break;
5276 case decl_base::VISIBILITY_PROTECTED:
5277 r = "protected";
5278 break;
5279 case decl_base::VISIBILITY_HIDDEN:
5280 r = "hidden";
5281 break;
5282 case decl_base::VISIBILITY_INTERNAL:
5283 r = "internal";
5284 break;
5285 }
5286 return o;
5287}
5288
5289/// Streaming operator for decl_base::binding.
5290///
5291/// @param o the output stream to serialize the visibility to.
5292///
5293/// @param b the binding to serialize.
5294///
5295/// @return the output stream.
5296std::ostream&
5297operator<<(std::ostream& o, decl_base::binding b)
5298{
5299 string r;
5300 switch (b)
5301 {
5302 case decl_base::BINDING_NONE:
5303 r = "none";
5304 break;
5305 case decl_base::BINDING_LOCAL:
5306 r = "local";
5307 break;
5308 case decl_base::BINDING_GLOBAL:
5309 r = "global";
5310 break;
5311 case decl_base::BINDING_WEAK:
5312 r = "weak";
5313 break;
5314 }
5315 o << r;
5316 return o;
5317}
5318
5319/// Turn equality of shared_ptr of decl_base into a deep equality;
5320/// that is, make it compare the pointed to objects, not just the
5321/// pointers.
5322///
5323/// @param l the shared_ptr of decl_base on left-hand-side of the
5324/// equality.
5325///
5326/// @param r the shared_ptr of decl_base on right-hand-side of the
5327/// equality.
5328///
5329/// @return true if the decl_base pointed to by the shared_ptrs are
5330/// equal, false otherwise.
5331bool
5332operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5333{
5334 if (l.get() == r.get())
5335 return true;
5336 if (!!l != !!r)
5337 return false;
5338
5339 return *l == *r;
5340}
5341
5342/// Inequality operator of shared_ptr of @ref decl_base.
5343///
5344/// This is a deep equality operator, that is, it compares the
5345/// pointed-to objects, rather than just the pointers.
5346///
5347/// @param l the left-hand-side operand.
5348///
5349/// @param r the right-hand-side operand.
5350///
5351/// @return true iff @p l is different from @p r.
5352bool
5353operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5354{return !operator==(l, r);}
5355
5356/// Turn equality of shared_ptr of type_base into a deep equality;
5357/// that is, make it compare the pointed to objects too.
5358///
5359/// @param l the shared_ptr of type_base on left-hand-side of the
5360/// equality.
5361///
5362/// @param r the shared_ptr of type_base on right-hand-side of the
5363/// equality.
5364///
5365/// @return true if the type_base pointed to by the shared_ptrs are
5366/// equal, false otherwise.
5367bool
5368operator==(const type_base_sptr& l, const type_base_sptr& r)
5369{
5370 if (l.get() == r.get())
5371 return true;
5372 if (!!l != !!r)
5373 return false;
5374
5375 return *l == *r;
5376}
5377
5378/// Turn inequality of shared_ptr of type_base into a deep equality;
5379/// that is, make it compare the pointed to objects..
5380///
5381/// @param l the shared_ptr of type_base on left-hand-side of the
5382/// equality.
5383///
5384/// @param r the shared_ptr of type_base on right-hand-side of the
5385/// equality.
5386///
5387/// @return true iff the type_base pointed to by the shared_ptrs are
5388/// different.
5389bool
5390operator!=(const type_base_sptr& l, const type_base_sptr& r)
5391{return !operator==(l, r);}
5392
5393/// Tests if a declaration has got a scope.
5394///
5395/// @param d the declaration to consider.
5396///
5397/// @return true if the declaration has got a scope, false otherwise.
5398bool
5400{return (d.get_scope());}
5401
5402/// Tests if a declaration has got a scope.
5403///
5404/// @param d the declaration to consider.
5405///
5406/// @return true if the declaration has got a scope, false otherwise.
5407bool
5408has_scope(const decl_base_sptr d)
5409{return has_scope(*d.get());}
5410
5411/// Tests if a declaration is a class member.
5412///
5413/// @param d the declaration to consider.
5414///
5415/// @return true if @p d is a class member, false otherwise.
5416bool
5417is_member_decl(const decl_base_sptr d)
5418{return is_at_class_scope(d) || is_method_decl(d);}
5419
5420/// Tests if a declaration is a class member.
5421///
5422/// @param d the declaration to consider.
5423///
5424/// @return true if @p d is a class member, false otherwise.
5425bool
5427{return is_at_class_scope(d) || is_method_decl(d);}
5428
5429/// Tests if a declaration is a class member.
5430///
5431/// @param d the declaration to consider.
5432///
5433/// @return true if @p d is a class member, false otherwise.
5434bool
5436{return is_at_class_scope(d) || is_method_decl(d);}
5437
5438/// Test if a declaration is a @ref scope_decl.
5439///
5440/// @param d the declaration to take in account.
5441///
5442/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5443/// if d is a @ref scope_decl.
5444const scope_decl*
5446{return dynamic_cast<const scope_decl*>(d);}
5447
5448/// Test if a declaration is a @ref scope_decl.
5449///
5450/// @param d the declaration to take in account.
5451///
5452/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5453/// if d is a @ref scope_decl.
5455is_scope_decl(const decl_base_sptr& d)
5456{return dynamic_pointer_cast<scope_decl>(d);}
5457
5458/// Tests if a type is a class member.
5459///
5460/// @param t the type to consider.
5461///
5462/// @return true if @p t is a class member type, false otherwise.
5463bool
5464is_member_type(const type_base_sptr& t)
5465{
5466 decl_base_sptr d = get_type_declaration(t);
5467 return is_member_decl(d);
5468}
5469
5470/// Test if a type is user-defined.
5471///
5472/// A type is considered user-defined if it's a
5473/// struct/class/union/enum that is *NOT* artificial.
5474///
5475/// @param t the type to consider.
5476///
5477/// @return true iff the type @p t is user-defined.
5478bool
5480{
5481 if (t == 0)
5482 return false;
5483
5485 decl_base *d = is_decl(t);
5486
5488 && d && !d->get_is_artificial())
5489 return true;
5490
5491 return false;
5492}
5493
5494/// Test if a type is user-defined.
5495///
5496/// A type is considered user-defined if it's a
5497/// struct/class/union/enum.
5498///
5499///
5500/// @param t the type to consider.
5501///
5502/// @return true iff the type @p t is user-defined.
5503bool
5504is_user_defined_type(const type_base_sptr& t)
5505{return is_user_defined_type(t.get());}
5506
5507/// Gets the access specifier for a class member.
5508///
5509/// @param d the declaration of the class member to consider. Note
5510/// that this must be a class member otherwise the function aborts the
5511/// current process.
5512///
5513/// @return the access specifier for the class member @p d.
5516{
5518
5519 const context_rel* c = d.get_context_rel();
5520 ABG_ASSERT(c);
5521
5522 return c->get_access_specifier();
5523}
5524
5525/// Gets the access specifier for a class member.
5526///
5527/// @param d the declaration of the class member to consider. Note
5528/// that this must be a class member otherwise the function aborts the
5529/// current process.
5530///
5531/// @return the access specifier for the class member @p d.
5533get_member_access_specifier(const decl_base_sptr& d)
5534{return get_member_access_specifier(*d);}
5535
5536/// Sets the access specifier for a class member.
5537///
5538/// @param d the class member to set the access specifier for. Note
5539/// that this must be a class member otherwise the function aborts the
5540/// current process.
5541///
5542/// @param a the new access specifier to set the class member to.
5543void
5546{
5548
5550 ABG_ASSERT(c);
5551
5552 c->set_access_specifier(a);
5553}
5554
5555/// Sets the access specifier for a class member.
5556///
5557/// @param d the class member to set the access specifier for. Note
5558/// that this must be a class member otherwise the function aborts the
5559/// current process.
5560///
5561/// @param a the new access specifier to set the class member to.
5562void
5563set_member_access_specifier(const decl_base_sptr& d,
5566
5567/// Gets a flag saying if a class member is static or not.
5568///
5569/// @param d the declaration for the class member to consider. Note
5570/// that this must be a class member otherwise the function aborts the
5571/// current process.
5572///
5573/// @return true if the class member @p d is static, false otherwise.
5574bool
5576{
5578
5579 const context_rel* c = d.get_context_rel();
5580 ABG_ASSERT(c);
5581
5582 return c->get_is_static();
5583}
5584
5585/// Gets a flag saying if a class member is static or not.
5586///
5587/// @param d the declaration for the class member to consider. Note
5588/// that this must be a class member otherwise the function aborts the
5589/// current process.
5590///
5591/// @return true if the class member @p d is static, false otherwise.
5592bool
5594{return get_member_is_static(*d);}
5595
5596/// Gets a flag saying if a class member is static or not.
5597///
5598/// @param d the declaration for the class member to consider. Note
5599/// that this must be a class member otherwise the function aborts the
5600/// current process.
5601///
5602/// @return true if the class member @p d is static, false otherwise.
5603bool
5604get_member_is_static(const decl_base_sptr& d)
5605{return get_member_is_static(*d);}
5606
5607/// Test if a var_decl is a data member.
5608///
5609/// @param v the var_decl to consider.
5610///
5611/// @return true if @p v is data member, false otherwise.
5612bool
5614{return is_at_class_scope(v);}
5615
5616/// Test if a var_decl is a data member.
5617///
5618/// @param v the var_decl to consider.
5619///
5620/// @return true if @p v is data member, false otherwise.
5621bool
5623{return is_data_member(*v);}
5624
5625/// Test if a var_decl is a data member.
5626///
5627/// @param v the var_decl to consider.
5628///
5629/// @return true if @p v is data member, false otherwise.
5630bool
5632{return is_at_class_scope(d);}
5633
5634/// Test if a decl is a data member.
5635///
5636/// @param d the decl to consider.
5637///
5638/// @return a pointer to the data member iff @p d is a data member, or
5639/// a null pointer.
5641is_data_member(const decl_base_sptr& d)
5642{
5643 if (var_decl_sptr v = is_var_decl(d))
5644 {
5645 if (is_data_member(v))
5646 return v;
5647 }
5648 return var_decl_sptr();
5649}
5650
5651/// Test if a decl is a data member.
5652///
5653/// @param d the decl to consider.
5654///
5655/// @return a pointer to the data member iff @p d is a data member, or
5656/// a null pointer.
5659{
5660 if (var_decl_sptr v = is_var_decl(d))
5661 {
5662 if (is_data_member(v))
5663 return v;
5664 }
5665 return var_decl_sptr();
5666}
5667
5668/// Test if a decl is a data member.
5669///
5670/// @param d the decl to consider.
5671///
5672/// @return a pointer to the data member iff @p d is a data member, or
5673/// a null pointer.
5674var_decl*
5676{
5677 if (var_decl *v = is_var_decl(d))
5678 if (is_data_member(v))
5679 return v;
5680 return 0;
5681}
5682
5683/// Test if a decl is a data member.
5684///
5685/// @param d the decl to consider.
5686///
5687/// @return a pointer to the data member iff @p d is a data member, or
5688/// a null pointer.
5689var_decl*
5691{
5692 if (var_decl *v = is_var_decl(d))
5693 if (is_data_member(v))
5694 return v;
5695 return 0;
5696}
5697
5698/// Get the first non-anonymous data member of a given anonymous data
5699/// member.
5700///
5701/// E.g:
5702///
5703/// struct S
5704/// {
5705/// union // <-- for this anonymous data member, the function
5706/// // returns a.
5707/// {
5708/// int a;
5709/// charb;
5710/// };
5711/// };
5712///
5713/// @return anon_dm the anonymous data member to consider.
5714///
5715/// @return the first non-anonymous data member of @p anon_dm. If no
5716/// data member was found then this function returns @p anon_dm.
5717const var_decl_sptr
5719{
5720 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5721 return anon_dm;
5722
5723 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5724 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5725
5726 if (is_anonymous_data_member(first))
5728
5729 return first;
5730}
5731
5732/// In the context of a given class or union, this function returns
5733/// the data member that is located after a given data member.
5734///
5735/// @param klass the class or union to consider.
5736///
5737/// @param the data member to consider.
5738///
5739/// @return the data member that is located right after @p
5740/// data_member.
5741const var_decl_sptr
5743 const var_decl_sptr &data_member)
5744{
5745 if (!klass ||!data_member)
5746 return var_decl_sptr();
5747
5748 for (class_or_union::data_members::const_iterator it =
5749 klass->get_non_static_data_members().begin();
5750 it != klass->get_non_static_data_members().end();
5751 ++it)
5752 if (**it == *data_member)
5753 {
5754 ++it;
5755 if (it != klass->get_non_static_data_members().end())
5757 break;
5758 }
5759
5760 return var_decl_sptr();
5761}
5762
5763/// In the context of a given class or union, this function returns
5764/// the data member that is located after a given data member.
5765///
5766/// @param klass the class or union to consider.
5767///
5768/// @param the data member to consider.
5769///
5770/// @return the data member that is located right after @p
5771/// data_member.
5772const var_decl_sptr
5773get_next_data_member(const class_or_union_sptr& klass,
5774 const var_decl_sptr &data_member)
5775{return get_next_data_member(klass.get(), data_member);}
5776
5777/// Get the last data member of a class type.
5778///
5779/// @param klass the class type to consider.
5782{return klass.get_non_static_data_members().back();}
5783
5784/// Get the last data member of a class type.
5785///
5786/// @param klass the class type to consider.
5789{return get_last_data_member(*klass);}
5790
5791/// Get the last data member of a class type.
5792///
5793/// @param klass the class type to consider.
5795get_last_data_member(const class_or_union_sptr &klass)
5796{return get_last_data_member(klass.get());}
5797
5798/// Collect all the non-anonymous data members of a class or union type.
5799///
5800/// If the class contains any anonymous data member, this function
5801/// looks through it to collect the non-anonymous data members that it
5802/// contains. The function also also looks through the base classes
5803/// of the current type.
5804///
5805/// @param cou the class or union type to consider.
5806///
5807/// @param dms output parameter. This is populated by the function
5808/// with a map containing the non-anonymous data members that were
5809/// collected. The key of the map is the name of the data member.
5810/// This is set iff the function returns true.
5811///
5812/// @return true iff at least one non-anonymous data member was
5813/// collected.
5814bool
5817{
5818 if (!cou)
5819 return false;
5820
5821 bool result = false;
5822 class_decl* klass = is_class_type(cou);
5823 if (klass)
5824 // First look into base classes for data members.
5826 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
5827
5828 // Then look into our data members
5829 for (var_decl_sptr member : cou->get_non_static_data_members())
5830 {
5831 if (is_anonymous_data_member(member))
5832 {
5833 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
5834 ABG_ASSERT(cl);
5835 result |= collect_non_anonymous_data_members(cl.get(), dms);
5836 }
5837 else
5838 {
5839 dms[member->get_name()] = member;
5840 result = true;
5841 }
5842 }
5843 return true;
5844}
5845
5846/// Collect all the non-anonymous data members of a class or union type.
5847///
5848/// If the class contains any anonymous data member, this function
5849/// looks through it to collect the non-anonymous data members that it
5850/// contains. The function also also looks through the base classes
5851/// of the current type.
5852///
5853/// @param cou the class or union type to consider.
5854///
5855/// @param dms output parameter. This is populated by the function
5856/// with a map containing the non-anonymous data members that were
5857/// collected. The key of the map is the name of the data member.
5858/// This is set iff the function returns true.
5859///
5860/// @return true iff at least one non-anonymous data member was
5861/// collected.
5862bool
5864{return collect_non_anonymous_data_members(cou.get(), dms);}
5865
5866/// Test if a decl is an anonymous data member.
5867///
5868/// @param d the decl to consider.
5869///
5870/// @return true iff @p d is an anonymous data member.
5871bool
5873{return is_anonymous_data_member(&d);}
5874
5875/// Test if a decl is an anonymous data member.
5876///
5877/// @param d the decl to consider.
5878///
5879/// @return the var_decl representing the data member iff @p d is an
5880/// anonymous data member.
5881const var_decl*
5883{
5884 if (const var_decl* v = is_data_member(d))
5885 {
5887 return v;
5888 }
5889 return 0;
5890}
5891
5892/// Test if a decl is an anonymous data member.
5893///
5894/// @param d the decl to consider.
5895///
5896/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5897/// it's an anonymous data member. Otherwise returns a nil pointer.
5898const var_decl*
5900{
5901 if (const var_decl* v = is_data_member(d))
5902 {
5904 return v;
5905 }
5906 return 0;
5907}
5908
5909/// Test if a decl is an anonymous data member.
5910///
5911/// @param d the decl to consider.
5912///
5913/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5914/// it's an anonymous data member. Otherwise returns a nil pointer.
5917{
5918 if (var_decl_sptr v = is_data_member(d))
5919 {
5921 return v;
5922 }
5923 return var_decl_sptr();
5924}
5925
5926/// Test if a decl is an anonymous data member.
5927///
5928/// @param d the decl to consider.
5929///
5930/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5931/// it's an anonymous data member. Otherwise returns a nil pointer.
5933is_anonymous_data_member(const decl_base_sptr& d)
5934{
5935 if (var_decl_sptr v = is_data_member(d))
5936 return is_anonymous_data_member(v);
5937 return var_decl_sptr();
5938}
5939
5940/// Test if a @ref var_decl is an anonymous data member.
5941///
5942/// @param d the @ref var_decl to consider.
5943///
5944/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5945/// it's an anonymous data member. Otherwise returns a nil pointer.
5948{
5949 if (is_anonymous_data_member(d.get()))
5950 return d;
5951 return var_decl_sptr();
5952}
5953
5954/// Test if a @ref var_decl is an anonymous data member.
5955///
5956/// @param d the @ref var_decl to consider.
5957///
5958/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5959/// it's an anonymous data member. Otherwise returns a nil pointer.
5960const var_decl*
5962{
5963 if (d && is_anonymous_data_member(*d))
5964 return d;
5965 return 0;
5966}
5967
5968/// Test if a @ref var_decl is an anonymous data member.
5969///
5970/// @param d the @ref var_decl to consider.
5971///
5972/// @return true iff @p d is an anonymous data member.
5973bool
5975{
5976 return (is_data_member(d)
5977 && d.get_is_anonymous()
5978 && d.get_name().empty()
5980}
5981
5982/// Test if a @ref var_decl is a data member belonging to an anonymous
5983/// type.
5984///
5985/// @param d the @ref var_decl to consider.
5986///
5987/// @return true iff @p d is a data member belonging to an anonymous
5988/// type.
5989bool
5991{
5992 if (is_data_member(d))
5993 {
5994 scope_decl* scope = d.get_scope();
5995 if (scope && scope->get_is_anonymous())
5996 return true;
5997 }
5998 return false;
5999}
6000
6001/// Test if a @ref var_decl is a data member belonging to an anonymous
6002/// type.
6003///
6004/// @param d the @ref var_decl to consider.
6005///
6006/// @return true iff @p d is a data member belonging to an anonymous
6007/// type.
6008bool
6011
6012/// Test if a @ref var_decl is a data member belonging to an anonymous
6013/// type.
6014///
6015/// @param d the @ref var_decl to consider.
6016///
6017/// @return true iff @p d is a data member belonging to an anonymous
6018/// type.
6019bool
6022
6023/// Get the @ref class_or_union type of a given anonymous data member.
6024///
6025/// @param d the anonymous data member to consider.
6026///
6027/// @return the @ref class_or_union type of the anonymous data member
6028/// @p d.
6031{
6032 if ((d = is_anonymous_data_member(d)))
6033 return is_class_or_union_type(d->get_type().get());
6034 return 0;
6035}
6036
6037/// Get the @ref class_or_union type of a given anonymous data member.
6038///
6039/// @param d the anonymous data member to consider.
6040///
6041/// @return the @ref class_or_union type of the anonymous data member
6042/// @p d.
6043class_or_union_sptr
6045{
6047 return is_class_or_union_type(d.get_type());
6048 return class_or_union_sptr();
6049}
6050
6051/// Test if a data member has annonymous type or not.
6052///
6053/// @param d the data member to consider.
6054///
6055/// @return the anonymous class or union type iff @p turns out to have
6056/// an anonymous type. Otherwise, returns nil.
6057const class_or_union_sptr
6059{
6060 if (is_data_member(d))
6061 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6062 if (cou->get_is_anonymous())
6063 return cou;
6064
6065 return class_or_union_sptr();
6066}
6067
6068/// Test if a data member has annonymous type or not.
6069///
6070/// @param d the data member to consider.
6071///
6072/// @return the anonymous class or union type iff @p turns out to have
6073/// an anonymous type. Otherwise, returns nil.
6074const class_or_union_sptr
6076{
6077 if (d)
6079 return class_or_union_sptr();
6080}
6081
6082/// Test if a data member has annonymous type or not.
6083///
6084/// @param d the data member to consider.
6085///
6086/// @return the anonymous class or union type iff @p turns out to have
6087/// an anonymous type. Otherwise, returns nil.
6088const class_or_union_sptr
6090{return data_member_has_anonymous_type(d.get());}
6091
6092/// Get the @ref class_or_union type of a given anonymous data member.
6093///
6094/// @param d the anonymous data member to consider.
6095///
6096/// @return the @ref class_or_union type of the anonymous data member
6097/// @p d.
6098class_or_union_sptr
6100{
6102 return is_class_or_union_type(v->get_type());
6103 return class_or_union_sptr();
6104}
6105
6106/// Test if a given anonymous data member exists in a class or union.
6107///
6108/// @param anon_dm the anonymous data member to consider.
6109///
6110/// @param clazz the class to consider.
6111///
6112/// @return true iff @p anon_dm exists in the @clazz.
6113bool
6115 const class_or_union& clazz)
6116{
6117 if (!anon_dm.get_is_anonymous()
6118 || !is_class_or_union_type(anon_dm.get_type()))
6119 return false;
6120
6121 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6122 ABG_ASSERT(cl);
6123
6124 // Look for the presence of each data member of anon_dm in clazz.
6125 //
6126 // If one data member of anon_dm is not present in clazz, then the
6127 // data member anon_dm is considered to not exist in clazz.
6128 for (auto anon_dm_m : cl->get_non_static_data_members())
6129 {
6130 // If the data member anon_dm_m is not an anonymous data member,
6131 // it's easy to look for it.
6132 if (!is_anonymous_data_member(anon_dm_m))
6133 {
6134 if (!clazz.find_data_member(anon_dm_m->get_name()))
6135 return false;
6136 }
6137 // If anon_dm_m is itself an anonymous data member then recurse
6138 else
6139 {
6140 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6141 return false;
6142 }
6143 }
6144
6145 return true;
6146}
6147
6148/// Test if a given decl is anonymous or has a naming typedef.
6149///
6150/// @param d the decl to consider.
6151///
6152/// @return true iff @p d is anonymous or has a naming typedef.
6153bool
6155{
6156 if (d.get_is_anonymous() || d.get_naming_typedef())
6157 return true;
6158 return false;
6159}
6160
6161/// Set the offset of a data member into its containing class.
6162///
6163/// @param m the data member to consider.
6164///
6165/// @param o the offset, in bits.
6166void
6168{
6170
6171 dm_context_rel* ctxt_rel =
6172 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6173 ABG_ASSERT(ctxt_rel);
6174
6175 ctxt_rel->set_offset_in_bits(o);
6176}
6177
6178/// Get the offset of a data member.
6179///
6180/// @param m the data member to consider.
6181///
6182/// @return the offset (in bits) of @p m in its containing class.
6183uint64_t
6185{
6187 const dm_context_rel* ctxt_rel =
6188 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6189 ABG_ASSERT(ctxt_rel);
6190 return ctxt_rel->get_offset_in_bits();
6191}
6192
6193/// Get the offset of a data member.
6194///
6195/// @param m the data member to consider.
6196///
6197/// @return the offset (in bits) of @p m in its containing class.
6198uint64_t
6200{return get_data_member_offset(*m);}
6201
6202/// Get the offset of a data member.
6203///
6204/// @param m the data member to consider.
6205///
6206/// @return the offset (in bits) of @p m in its containing class.
6207uint64_t
6208get_data_member_offset(const decl_base_sptr d)
6209{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6210
6211/// Get the offset of the non-static data member that comes after a
6212/// given one.
6213///
6214/// If there is no data member after after the one given to this
6215/// function (maybe because the given one is the last data member of
6216/// the class type) then the function return false.
6217///
6218/// @param klass the class to consider.
6219///
6220/// @param dm the data member before the one we want to retrieve.
6221///
6222/// @param offset out parameter. This parameter is set by the
6223/// function to the offset of the data member that comes right after
6224/// the data member @p dm, iff the function returns true.
6225///
6226/// @return true iff the data member coming right after @p dm was
6227/// found.
6228bool
6230 const var_decl_sptr& dm,
6231 uint64_t& offset)
6232{
6233 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6234 if (!next_dm)
6235 return false;
6236 offset = get_data_member_offset(next_dm);
6237 return true;
6238}
6239
6240/// Get the offset of the non-static data member that comes after a
6241/// given one.
6242///
6243/// If there is no data member after after the one given to this
6244/// function (maybe because the given one is the last data member of
6245/// the class type) then the function return false.
6246///
6247/// @param klass the class to consider.
6248///
6249/// @param dm the data member before the one we want to retrieve.
6250///
6251/// @param offset out parameter. This parameter is set by the
6252/// function to the offset of the data member that comes right after
6253/// the data member @p dm, iff the function returns true.
6254///
6255/// @return true iff the data member coming right after @p dm was
6256/// found.
6257bool
6258get_next_data_member_offset(const class_or_union_sptr& klass,
6259 const var_decl_sptr& dm,
6260 uint64_t& offset)
6261{return get_next_data_member_offset(klass.get(), dm, offset);}
6262
6263/// Get the absolute offset of a data member.
6264///
6265/// If the data member is part of an anonymous data member then this
6266/// returns the absolute offset -- relative to the beginning of the
6267/// containing class of the anonymous data member.
6268///
6269/// @param m the data member to consider.
6270///
6271/// @return the aboslute offset of the data member @p m.
6272uint64_t
6274{
6276 const dm_context_rel* ctxt_rel =
6277 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6278 ABG_ASSERT(ctxt_rel);
6279
6280 const var_decl *containing_anonymous_data_member =
6281 ctxt_rel->get_anonymous_data_member();
6282
6283 uint64_t containing_anonymous_data_member_offset = 0;
6284 if (containing_anonymous_data_member)
6285 containing_anonymous_data_member_offset =
6286 get_absolute_data_member_offset(*containing_anonymous_data_member);
6287
6288 return (ctxt_rel->get_offset_in_bits()
6289 +
6290 containing_anonymous_data_member_offset);
6291}
6292
6293/// Get the absolute offset of a data member.
6294///
6295/// If the data member is part of an anonymous data member then this
6296/// returns the absolute offset -- relative to the beginning of the
6297/// containing class of the anonymous data member.
6298///
6299/// @param m the data member to consider.
6300///
6301/// @return the aboslute offset of the data member @p m.
6302uint64_t
6304{
6305 if (!m)
6306 return 0;
6308}
6309
6310/// Get the size of a given variable.
6311///
6312/// @param v the variable to consider.
6313///
6314/// @return the size of variable @p v.
6315uint64_t
6317{
6318 type_base_sptr t = v->get_type();
6319 ABG_ASSERT(t);
6320
6321 return t->get_size_in_bits();
6322}
6323
6324/// Set a flag saying if a data member is laid out.
6325///
6326/// @param m the data member to consider.
6327///
6328/// @param l true if @p m is to be considered as laid out.
6329void
6331{
6333 dm_context_rel* ctxt_rel =
6334 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6335 ctxt_rel->set_is_laid_out(l);
6336}
6337
6338/// Test whether a data member is laid out.
6339///
6340/// @param m the data member to consider.
6341///
6342/// @return true if @p m is laid out, false otherwise.
6343bool
6345{
6347 const dm_context_rel* ctxt_rel =
6348 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6349
6350 return ctxt_rel->get_is_laid_out();
6351}
6352
6353/// Test whether a data member is laid out.
6354///
6355/// @param m the data member to consider.
6356///
6357/// @return true if @p m is laid out, false otherwise.
6358bool
6360{return get_data_member_is_laid_out(*m);}
6361
6362/// Test whether a function_decl is a member function.
6363///
6364/// @param f the function_decl to test.
6365///
6366/// @return true if @p f is a member function, false otherwise.
6367bool
6369{return is_member_decl(f);}
6370
6371/// Test whether a function_decl is a member function.
6372///
6373/// @param f the function_decl to test.
6374///
6375/// @return true if @p f is a member function, false otherwise.
6376bool
6378{return is_member_decl(*f);}
6379
6380/// Test whether a function_decl is a member function.
6381///
6382/// @param f the function_decl to test.
6383///
6384/// @return true if @p f is a member function, false otherwise.
6385bool
6387{return is_member_decl(*f);}
6388
6389/// Test whether a member function is a constructor.
6390///
6391/// @param f the member function to test.
6392///
6393/// @return true if @p f is a constructor, false otherwise.
6394bool
6396{
6398
6399 const method_decl* m = is_method_decl(&f);
6400 ABG_ASSERT(m);
6401
6402 const mem_fn_context_rel* ctxt =
6403 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6404
6405 return ctxt->is_constructor();
6406}
6407
6408/// Test whether a member function is a constructor.
6409///
6410/// @param f the member function to test.
6411///
6412/// @return true if @p f is a constructor, false otherwise.
6413bool
6415{return get_member_function_is_ctor(*f);}
6416
6417
6418/// Setter for the is_ctor property of the member function.
6419///
6420/// @param f the member function to set.
6421///
6422/// @param f the new boolean value of the is_ctor property. Is true
6423/// if @p f is a constructor, false otherwise.
6424void
6426{
6428
6429 method_decl* m = is_method_decl(&f);
6430 ABG_ASSERT(m);
6431
6432 mem_fn_context_rel* ctxt =
6433 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6434
6435 ctxt->is_constructor(c);
6436}
6437
6438/// Setter for the is_ctor property of the member function.
6439///
6440/// @param f the member function to set.
6441///
6442/// @param f the new boolean value of the is_ctor property. Is true
6443/// if @p f is a constructor, false otherwise.
6444void
6447
6448/// Test whether a member function is a destructor.
6449///
6450/// @param f the function to test.
6451///
6452/// @return true if @p f is a destructor, false otherwise.
6453bool
6455{
6457
6458 const method_decl* m = is_method_decl(&f);
6459 ABG_ASSERT(m);
6460
6461 const mem_fn_context_rel* ctxt =
6462 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6463
6464 return ctxt->is_destructor();
6465}
6466
6467/// Test whether a member function is a destructor.
6468///
6469/// @param f the function to test.
6470///
6471/// @return true if @p f is a destructor, false otherwise.
6472bool
6474{return get_member_function_is_dtor(*f);}
6475
6476/// Set the destructor-ness property of a member function.
6477///
6478/// @param f the function to set.
6479///
6480/// @param d true if @p f is a destructor, false otherwise.
6481void
6483{
6485
6486 method_decl* m = is_method_decl(&f);
6487 ABG_ASSERT(m);
6488
6489 mem_fn_context_rel* ctxt =
6490 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6491
6492 ctxt->is_destructor(d);
6493}
6494
6495/// Set the destructor-ness property of a member function.
6496///
6497/// @param f the function to set.
6498///
6499/// @param d true if @p f is a destructor, false otherwise.
6500void
6503
6504/// Test whether a member function is const.
6505///
6506/// @param f the function to test.
6507///
6508/// @return true if @p f is const, false otherwise.
6509bool
6511{
6513
6514 const method_decl* m = is_method_decl(&f);
6515 ABG_ASSERT(m);
6516
6517 const mem_fn_context_rel* ctxt =
6518 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6519
6520 return ctxt->is_const();
6521}
6522
6523/// Test whether a member function is const.
6524///
6525/// @param f the function to test.
6526///
6527/// @return true if @p f is const, false otherwise.
6528bool
6530{return get_member_function_is_const(*f);}
6531
6532/// set the const-ness property of a member function.
6533///
6534/// @param f the function to set.
6535///
6536/// @param is_const the new value of the const-ness property of @p f
6537void
6539{
6541
6542 method_decl* m = is_method_decl(&f);
6543 ABG_ASSERT(m);
6544
6545 mem_fn_context_rel* ctxt =
6546 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6547
6548 ctxt->is_const(is_const);
6549}
6550
6551/// set the const-ness property of a member function.
6552///
6553/// @param f the function to set.
6554///
6555/// @param is_const the new value of the const-ness property of @p f
6556void
6558{set_member_function_is_const(*f, is_const);}
6559
6560/// Test if a virtual member function has a vtable offset set.
6561///
6562/// @param f the virtual member function to consider.
6563///
6564/// @return true iff the virtual member function has its vtable offset
6565/// set, i.e, if the vtable offset of @p is different from -1.
6566bool
6568{return get_member_function_vtable_offset(f) != -1;}
6569
6570/// Get the vtable offset of a member function.
6571///
6572/// @param f the member function to consider.
6573///
6574/// @return the vtable offset of @p f. Note that a vtable offset of
6575/// value -1 means that the member function does *NOT* yet have a
6576/// vtable offset associated to it.
6577ssize_t
6579{
6581
6582 const method_decl* m =
6583 dynamic_cast<const method_decl*>(&f);
6584 ABG_ASSERT(m);
6585
6586 const mem_fn_context_rel* ctxt =
6587 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6588
6589 return ctxt->vtable_offset();
6590}
6591
6592/// Get the vtable offset of a member function.
6593///
6594/// @param f the member function to consider.
6595///
6596/// @return the vtable offset of @p f. Note that a vtable offset of
6597/// value -1 means that the member function does *NOT* yet have a
6598/// vtable offset associated to it.
6599ssize_t
6602
6603/// Set the vtable offset of a member function.
6604///
6605/// @param f the member function to consider.
6606///
6607/// @param s the new vtable offset. Please note that a vtable offset
6608/// of value -1 means that the virtual member function does not (yet)
6609/// have any vtable offset associated to it.
6610static void
6611set_member_function_vtable_offset(function_decl& f, ssize_t s)
6612{
6614
6615 method_decl* m = is_method_decl(&f);
6616 ABG_ASSERT(m);
6617
6618 mem_fn_context_rel* ctxt =
6619 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6620
6621 ctxt->vtable_offset(s);
6622}
6623
6624/// Get the vtable offset of a member function.
6625///
6626/// @param f the member function to consider.
6627///
6628/// @param s the new vtable offset. Please note that a vtable offset
6629/// of value -1 means that the virtual member function does not (yet)
6630/// have any vtable offset associated to it.
6631static void
6632set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6633{return set_member_function_vtable_offset(*f, s);}
6634
6635/// Test if a given member function is virtual.
6636///
6637/// @param mem_fn the member function to consider.
6638///
6639/// @return true iff a @p mem_fn is virtual.
6640bool
6642{
6644
6645 const method_decl* m =
6646 dynamic_cast<const method_decl*>(&f);
6647 ABG_ASSERT(m);
6648
6649 const mem_fn_context_rel* ctxt =
6650 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6651
6652 return ctxt->is_virtual();
6653}
6654
6655/// Test if a given member function is virtual.
6656///
6657/// @param mem_fn the member function to consider.
6658///
6659/// @return true iff a @p mem_fn is virtual.
6660bool
6662{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6663
6664/// Test if a given member function is virtual.
6665///
6666/// @param mem_fn the member function to consider.
6667///
6668/// @return true iff a @p mem_fn is virtual.
6669bool
6671{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6672
6673/// Set the virtual-ness of a member function.
6674///
6675/// @param f the member function to consider.
6676///
6677/// @param is_virtual set to true if the function is virtual.
6678static void
6679set_member_function_is_virtual(function_decl& f, bool is_virtual)
6680{
6682
6683 method_decl* m = is_method_decl(&f);
6684 ABG_ASSERT(m);
6685
6686 mem_fn_context_rel* ctxt =
6687 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6688
6689 ctxt->is_virtual(is_virtual);
6690}
6691
6692/// Set the virtual-ness of a member function.
6693///
6694/// @param f the member function to consider.
6695///
6696/// @param is_virtual set to true if the function is virtual.
6697static void
6698set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6699{
6700 if (fn)
6701 {
6702 set_member_function_is_virtual(*fn, is_virtual);
6704 }
6705}
6706
6707/// Set the virtual-ness of a member fcuntion
6708///
6709/// @param fn the member function to consider.
6710///
6711/// @param is_virtual whether the function is virtual.
6712///
6713/// @param voffset the virtual offset of the virtual function.
6714void
6716 bool is_virtual,
6717 ssize_t voffset)
6718{
6719 // Setting the offset must come first because the second function
6720 // does assume the voffset is set, in case of virtuality
6721 set_member_function_vtable_offset(fn, voffset);
6722 set_member_function_is_virtual(fn, is_virtual);
6723}
6724
6725/// Set the virtual-ness of a member fcuntion
6726///
6727/// @param fn the member function to consider.
6728///
6729/// @param is_virtual whether the function is virtual.
6730///
6731/// @param voffset the virtual offset of the virtual function.
6732void
6734 bool is_virtual,
6735 ssize_t voffset)
6736{
6737 if (fn)
6738 set_member_function_virtuality(*fn, is_virtual, voffset);
6739}
6740
6741/// Set the virtual-ness of a member fcuntion
6742///
6743/// @param fn the member function to consider.
6744///
6745/// @param is_virtual whether the function is virtual.
6746///
6747/// @param voffset the virtual offset of the virtual function.
6748void
6750 bool is_virtual,
6751 ssize_t voffset)
6752{
6753 set_member_function_vtable_offset(fn, voffset);
6754 set_member_function_is_virtual(fn, is_virtual);
6755}
6756
6757/// Recursively returns the the underlying type of a typedef. The
6758/// return type should not be a typedef of anything anymore.
6759///
6760///
6761/// Also recursively strip typedefs from the sub-types of the type
6762/// given in arguments.
6763///
6764/// Note that this function builds types in which typedefs are
6765/// stripped off. Usually, types are held by their scope, so their
6766/// life time is bound to the life time of their scope. But as this
6767/// function cannot really insert the built type into it's scope, it
6768/// must ensure that the newly built type stays live long enough.
6769///
6770/// So, if the newly built type has a canonical type, this function
6771/// returns the canonical type. Otherwise, this function ensure that
6772/// the newly built type has a life time that is the same as the life
6773/// time of the entire libabigail library.
6774///
6775/// @param type the type to strip the typedefs from.
6776///
6777/// @return the resulting type stripped from its typedefs, or just
6778/// return @p type if it has no typedef in any of its sub-types.
6779type_base_sptr
6780strip_typedef(const type_base_sptr type)
6781{
6782 if (!type)
6783 return type;
6784
6785 // If type is a class type then do not try to strip typedefs from it.
6786 // And if it has no canonical type (which can mean that it's a
6787 // declaration-only class), then, make sure its live for ever and
6788 // return it.
6789 if (class_decl_sptr cl = is_class_type(type))
6790 {
6791 if (!cl->get_canonical_type())
6792 keep_type_alive(type);
6793 return type;
6794 }
6795
6796 const environment& env = type->get_environment();
6797 type_base_sptr t = type;
6798
6799 if (const typedef_decl_sptr ty = is_typedef(t))
6800 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6801 else if (const reference_type_def_sptr ty = is_reference_type(t))
6802 {
6803 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6804 env));
6805 ABG_ASSERT(p);
6806 t.reset(new reference_type_def(p,
6807 ty->is_lvalue(),
6808 ty->get_size_in_bits(),
6809 ty->get_alignment_in_bits(),
6810 ty->get_location()));
6811 }
6812 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6813 {
6814 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6815 env));
6816 ABG_ASSERT(p);
6817 t.reset(new pointer_type_def(p,
6818 ty->get_size_in_bits(),
6819 ty->get_alignment_in_bits(),
6820 ty->get_location()));
6821 }
6822 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6823 {
6824 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6825 env));
6826 ABG_ASSERT(p);
6827 t.reset(new qualified_type_def(p,
6828 ty->get_cv_quals(),
6829 ty->get_location()));
6830 }
6831 else if (const array_type_def_sptr ty = is_array_type(t))
6832 {
6833 type_base_sptr p = strip_typedef(ty->get_element_type());
6834 ABG_ASSERT(p);
6835 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6836 }
6837 else if (const method_type_sptr ty = is_method_type(t))
6838 {
6840 for (function_decl::parameters::const_iterator i =
6841 ty->get_parameters().begin();
6842 i != ty->get_parameters().end();
6843 ++i)
6844 {
6846 type_base_sptr typ = strip_typedef(p->get_type());
6847 ABG_ASSERT(typ);
6849 (new function_decl::parameter(typ,
6850 p->get_index(),
6851 p->get_name(),
6852 p->get_location(),
6853 p->get_variadic_marker(),
6854 p->get_is_artificial()));
6855 parm.push_back(stripped);
6856 }
6857 type_base_sptr p = strip_typedef(ty->get_return_type());
6858 ABG_ASSERT(!!p == !!ty->get_return_type());
6859 t.reset(new method_type(p, ty->get_class_type(),
6860 parm, ty->get_is_const(),
6861 ty->get_size_in_bits(),
6862 ty->get_alignment_in_bits()));
6863 }
6864 else if (const function_type_sptr ty = is_function_type(t))
6865 {
6867 for (function_decl::parameters::const_iterator i =
6868 ty->get_parameters().begin();
6869 i != ty->get_parameters().end();
6870 ++i)
6871 {
6873 type_base_sptr typ = strip_typedef(p->get_type());
6874 ABG_ASSERT(typ);
6876 (new function_decl::parameter(typ,
6877 p->get_index(),
6878 p->get_name(),
6879 p->get_location(),
6880 p->get_variadic_marker(),
6881 p->get_is_artificial()));
6882 parm.push_back(stripped);
6883 }
6884 type_base_sptr p = strip_typedef(ty->get_return_type());
6885 ABG_ASSERT(!!p == !!ty->get_return_type());
6886 t.reset(new function_type(p, parm,
6887 ty->get_size_in_bits(),
6888 ty->get_alignment_in_bits()));
6889 }
6890
6891 if (!t->get_translation_unit())
6892 t->set_translation_unit(type->get_translation_unit());
6893
6894 if (!(type->get_canonical_type() && canonicalize(t)))
6895 keep_type_alive(t);
6896
6897 return t->get_canonical_type() ? t->get_canonical_type() : t;
6898}
6899
6900/// Strip qualification from a qualified type, when it makes sense.
6901///
6902/// DWARF constructs "const reference". This is redundant because a
6903/// reference is always const. It also constructs the useless "const
6904/// void" type. The issue is these redundant types then leak into the
6905/// IR and make for bad diagnostics.
6906///
6907/// This function thus strips the const qualifier from the type in
6908/// that case. It might contain code to strip other cases like this
6909/// in the future.
6910///
6911/// @param t the type to strip const qualification from.
6912///
6913/// @return the stripped type or just return @p t.
6914decl_base_sptr
6915strip_useless_const_qualification(const qualified_type_def_sptr t)
6916{
6917 if (!t)
6918 return t;
6919
6920 decl_base_sptr result = t;
6921 type_base_sptr u = t->get_underlying_type();
6922 const environment& env = t->get_environment();
6923
6924 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6925 && (is_reference_type(u)))
6926 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6927 && env.is_void_type(u))
6928 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6929 // Let's strip the const qualifier because a reference is always
6930 // 'const' and a const void doesn't make sense. They will just
6931 // lead to spurious changes later down the pipeline, that we'll
6932 // have to deal with by doing painful and error-prone editing of
6933 // the diff IR. Dropping that useless and inconsistent artefact
6934 // right here seems to be a good way to go.
6935 result = is_decl(u);
6936
6937 return result;
6938}
6939
6940/// Merge redundant qualifiers from a tree of qualified types.
6941///
6942/// Suppose a tree of qualified types leads to:
6943///
6944/// const virtual const restrict const int;
6945///
6946/// Suppose the IR tree of qualified types ressembles (with C meaning
6947/// const, V meaning virtual and R meaning restrict):
6948///
6949/// [C|V]-->[C|R] -->[C] --> [int].
6950///
6951/// This function walks the IR and remove the redundant CV qualifiers
6952/// so the IR becomes:
6953///
6954/// [C|V] --> [R] --> [] -->[int].
6955///
6956/// Note that the empty qualified type (noted []) represents a
6957/// qualified type with no qualifier. It's rare, but it can exist.
6958/// I've put it here just for the sake of example.
6959///
6960/// The resulting IR thus represents the (merged) type:
6961///
6962/// const virtual restrict int.
6963///
6964/// This function is a sub-routine of the overload @ref
6965/// strip_useless_const_qualification which doesn't return any value.
6966///
6967/// @param t the qualified type to consider.
6968///
6969/// @param redundant_quals the (redundant) qualifiers to be removed
6970/// from the qualifiers of the underlying types of @p t.
6971///
6972/// @return the underlying type of @p t which might have had its
6973/// redundant qualifiers removed.
6974static qualified_type_def_sptr
6975strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6976 qualified_type_def::CV redundant_quals)
6977{
6978 if (!t)
6979 return t;
6980
6981 // We must NOT edit canonicalized types.
6982 ABG_ASSERT(!t->get_canonical_type());
6983
6984 qualified_type_def_sptr underlying_qualified_type =
6985 is_qualified_type(t->get_underlying_type());
6986
6987 // Let's build 'currated qualifiers' that are the qualifiers of the
6988 // current type from which redundant qualifiers are removed.
6989 qualified_type_def::CV currated_quals = t->get_cv_quals();
6990
6991 // Remove the redundant qualifiers from these currated qualifiers
6992 currated_quals &= ~redundant_quals;
6993 t->set_cv_quals(currated_quals);
6994
6995 // The redundant qualifiers, moving forward, is now the union of the
6996 // previous set of redundant qualifiers and the currated qualifiers.
6997 redundant_quals |= currated_quals;
6998
6999 qualified_type_def_sptr result = t;
7000 if (underlying_qualified_type)
7001 // Now remove the redundant qualifiers from the qualified types
7002 // potentially carried by the underlying type.
7003 result =
7004 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
7005 redundant_quals);
7006
7007 return result;
7008}
7009
7010/// Merge redundant qualifiers from a tree of qualified types.
7011///
7012/// Suppose a tree of qualified types leads to:
7013///
7014/// const virtual const restrict const int;
7015///
7016/// Suppose the IR tree of qualified types ressembles (with C meaning
7017/// const, V meaning virtual and R meaning restrict):
7018///
7019/// [C|V]-->[C|R] -->[C] --> [int].
7020///
7021/// This function walks the IR and remove the redundant CV qualifiers
7022/// so the IR becomes:
7023///
7024/// [C|V] --> [R] --> [] -->[int].
7025///
7026/// Note that the empty qualified type (noted []) represents a
7027/// qualified type with no qualifier. It's rare, but it can exist.
7028/// I've put it here just for the sake of example.
7029///
7030/// The resulting IR thus represents the (merged) type:
7031///
7032/// const virtual restrict int.
7033///
7034/// @param t the qualified type to consider. The IR below the
7035/// argument to this parameter will be edited to remove redundant
7036/// qualifiers where applicable.
7037void
7038strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
7039{
7040 if (!t)
7041 return;
7042
7043 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
7044 strip_redundant_quals_from_underyling_types(t, redundant_quals);
7045}
7046
7047/// Return the leaf underlying type node of a @ref typedef_decl node.
7048///
7049/// If the underlying type of a @ref typedef_decl node is itself a
7050/// @ref typedef_decl node, then recursively look at the underlying
7051/// type nodes to get the first one that is not a a @ref typedef_decl
7052/// node. This is what a leaf underlying type node means.
7053///
7054/// Otherwise, if the underlying type node of @ref typedef_decl is
7055/// *NOT* a @ref typedef_decl node, then just return the underlying
7056/// type node.
7057///
7058/// And if the type node considered is not a @ref typedef_decl node,
7059/// then just return it.
7060///
7061/// @return the leaf underlying type node of a @p type.
7062type_base_sptr
7063peel_typedef_type(const type_base_sptr& type)
7064{
7065 typedef_decl_sptr t = is_typedef(type);
7066 if (!t)
7067 return type;
7068
7069 if (is_typedef(t->get_underlying_type()))
7070 return peel_typedef_type(t->get_underlying_type());
7071 return t->get_underlying_type();
7072}
7073
7074/// Return the leaf underlying type node of a @ref typedef_decl node.
7075///
7076/// If the underlying type of a @ref typedef_decl node is itself a
7077/// @ref typedef_decl node, then recursively look at the underlying
7078/// type nodes to get the first one that is not a a @ref typedef_decl
7079/// node. This is what a leaf underlying type node means.
7080///
7081/// Otherwise, if the underlying type node of @ref typedef_decl is
7082/// *NOT* a @ref typedef_decl node, then just return the underlying
7083/// type node.
7084///
7085/// And if the type node considered is not a @ref typedef_decl node,
7086/// then just return it.
7087///
7088/// @return the leaf underlying type node of a @p type.
7089const type_base*
7091{
7092 const typedef_decl* t = is_typedef(type);
7093 if (!t)
7094 return type;
7095
7096 return peel_typedef_type(t->get_underlying_type()).get();
7097}
7098
7099/// Return the leaf pointed-to type node of a @ref pointer_type_def
7100/// node.
7101///
7102/// If the pointed-to type of a @ref pointer_type_def node is itself a
7103/// @ref pointer_type_def node, then recursively look at the
7104/// pointed-to type nodes to get the first one that is not a a @ref
7105/// pointer_type_def node. This is what a leaf pointed-to type node
7106/// means.
7107///
7108/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7109/// *NOT* a @ref pointer_type_def node, then just return the
7110/// pointed-to type node.
7111///
7112/// And if the type node considered is not a @ref pointer_type_def
7113/// node, then just return it.
7114///
7115/// @return the leaf pointed-to type node of a @p type.
7116type_base_sptr
7117peel_pointer_type(const type_base_sptr& type)
7118{
7120 if (!t)
7121 return type;
7122
7123 if (is_pointer_type(t->get_pointed_to_type()))
7124 return peel_pointer_type(t->get_pointed_to_type());
7125 return t->get_pointed_to_type();
7126}
7127
7128/// Return the leaf pointed-to type node of a @ref pointer_type_def
7129/// node.
7130///
7131/// If the pointed-to type of a @ref pointer_type_def node is itself a
7132/// @ref pointer_type_def node, then recursively look at the
7133/// pointed-to type nodes to get the first one that is not a a @ref
7134/// pointer_type_def node. This is what a leaf pointed-to type node
7135/// means.
7136///
7137/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7138/// *NOT* a @ref pointer_type_def node, then just return the
7139/// pointed-to type node.
7140///
7141/// And if the type node considered is not a @ref pointer_type_def
7142/// node, then just return it.
7143///
7144/// @return the leaf pointed-to type node of a @p type.
7145const type_base*
7147{
7148 const pointer_type_def* t = is_pointer_type(type);
7149 if (!t)
7150 return type;
7151
7152 return peel_pointer_type(t->get_pointed_to_type()).get();
7153}
7154
7155/// Return the leaf pointed-to type node of a @ref reference_type_def
7156/// node.
7157///
7158/// If the pointed-to type of a @ref reference_type_def node is itself
7159/// a @ref reference_type_def node, then recursively look at the
7160/// pointed-to type nodes to get the first one that is not a a @ref
7161/// reference_type_def node. This is what a leaf pointed-to type node
7162/// means.
7163///
7164/// Otherwise, if the pointed-to type node of @ref reference_type_def
7165/// is *NOT* a @ref reference_type_def node, then just return the
7166/// pointed-to type node.
7167///
7168/// And if the type node considered is not a @ref reference_type_def
7169/// node, then just return it.
7170///
7171/// @return the leaf pointed-to type node of a @p type.
7172type_base_sptr
7173peel_reference_type(const type_base_sptr& type)
7174{
7176 if (!t)
7177 return type;
7178
7179 if (is_reference_type(t->get_pointed_to_type()))
7180 return peel_reference_type(t->get_pointed_to_type());
7181 return t->get_pointed_to_type();
7182}
7183
7184/// Return the leaf pointed-to type node of a @ref reference_type_def
7185/// node.
7186///
7187/// If the pointed-to type of a @ref reference_type_def node is itself
7188/// a @ref reference_type_def node, then recursively look at the
7189/// pointed-to type nodes to get the first one that is not a a @ref
7190/// reference_type_def node. This is what a leaf pointed-to type node
7191/// means.
7192///
7193/// Otherwise, if the pointed-to type node of @ref reference_type_def
7194/// is *NOT* a @ref reference_type_def node, then just return the
7195/// pointed-to type node.
7196///
7197/// And if the type node considered is not a @ref reference_type_def
7198/// node, then just return it.
7199///
7200/// @return the leaf pointed-to type node of a @p type.
7201const type_base*
7203{
7204 const reference_type_def* t = is_reference_type(type);
7205 if (!t)
7206 return type;
7207
7208 return peel_reference_type(t->get_pointed_to_type()).get();
7209}
7210
7211/// Return the leaf element type of an array.
7212///
7213/// If the element type is itself an array, then recursively return
7214/// the element type of that array itself.
7215///
7216/// @param type the array type to consider. If this is not an array
7217/// type, this type is returned by the function.
7218///
7219/// @return the leaf element type of the array @p type, or, if it's
7220/// not an array type, then just return @p.
7221const type_base_sptr
7222peel_array_type(const type_base_sptr& type)
7223{
7224 const array_type_def_sptr t = is_array_type(type);
7225 if (!t)
7226 return type;
7227
7228 return peel_array_type(t->get_element_type());
7229}
7230
7231/// Return the leaf element type of an array.
7232///
7233/// If the element type is itself an array, then recursively return
7234/// the element type of that array itself.
7235///
7236/// @param type the array type to consider. If this is not an array
7237/// type, this type is returned by the function.
7238///
7239/// @return the leaf element type of the array @p type, or, if it's
7240/// not an array type, then just return @p.
7241const type_base*
7243{
7244 const array_type_def* t = is_array_type(type);
7245 if (!t)
7246 return type;
7247
7248 return peel_array_type(t->get_element_type()).get();
7249}
7250
7251/// Return the leaf underlying type of a qualified type.
7252///
7253/// If the underlying type is itself a qualified type, then
7254/// recursively return the first underlying type of that qualified
7255/// type to return the first underlying type that is not a qualified type.
7256///
7257/// If the underlying type is NOT a qualified type, then just return
7258/// that underlying type.
7259///
7260/// @param type the qualified type to consider.
7261///
7262/// @return the leaf underlying type.
7263const type_base*
7265{
7266 const qualified_type_def* t = is_qualified_type(type);
7267 if (!t)
7268 return type;
7269
7270 return peel_qualified_type(t->get_underlying_type().get());
7271}
7272
7273/// Return the leaf underlying type of a qualified type.
7274///
7275/// If the underlying type is itself a qualified type, then
7276/// recursively return the first underlying type of that qualified
7277/// type to return the first underlying type that is not a qualified type.
7278///
7279/// If the underlying type is NOT a qualified type, then just return
7280/// that underlying type.
7281///
7282/// @param type the qualified type to consider.
7283///
7284/// @return the leaf underlying type.
7285const type_base_sptr
7286peel_qualified_type(const type_base_sptr& type)
7287{
7288 const qualified_type_def_sptr t = is_qualified_type(type);
7289 if (!t)
7290 return type;
7291
7292 return peel_qualified_type(t->get_underlying_type());
7293}
7294
7295/// Test if a given qualified type is const.
7296///
7297/// @pram t the qualified type to consider.
7298///
7299/// @return true iff @p t is a const qualified type.
7300bool
7301is_const_qualified_type(const qualified_type_def_sptr& t)
7302{
7303 if (!t)
7304 return false;
7305
7306 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
7307 return true;
7308
7309 return false;
7310}
7311
7312/// Test if a given type is const-qualified.
7313///
7314/// @pram t the type to consider.
7315///
7316/// @return true iff @p t is a const qualified type.
7317bool
7318is_const_qualified_type(const type_base_sptr& t)
7319{
7320 qualified_type_def_sptr q = is_qualified_type(t);
7321 if (!q)
7322 return false;
7323 return is_const_qualified_type(q);
7324}
7325
7326/// If a qualified type is const, then return its underlying type.
7327///
7328/// @param q the qualified type to consider.
7329///
7330/// @return the underlying type of @p q if it's a const-qualified
7331/// type, otherwise, return @p q itself.
7332type_base_sptr
7333peel_const_qualified_type(const qualified_type_def_sptr& q)
7334{
7335 if (!q)
7336 return q;
7337
7339 return q->get_underlying_type();
7340
7341 return q;
7342}
7343
7344/// Return the leaf underlying type of a qualified or typedef type.
7345///
7346/// If the underlying type is itself a qualified or typedef type, then
7347/// recursively return the first underlying type of that qualified or
7348/// typedef type to return the first underlying type that is not a
7349/// qualified or typedef type.
7350///
7351/// If the underlying type is NOT a qualified nor a typedef type, then
7352/// just return that underlying type.
7353///
7354/// @param type the qualified or typedef type to consider.
7355///
7356/// @return the leaf underlying type.
7357type_base*
7359{
7360 while (is_typedef(type) || is_qualified_type(type))
7361 {
7362 if (const typedef_decl* t = is_typedef(type))
7363 type = peel_typedef_type(t);
7364
7365 if (const qualified_type_def* t = is_qualified_type(type))
7366 type = peel_qualified_type(t);
7367 }
7368
7369 return const_cast<type_base*>(type);
7370}
7371
7372/// Return the leaf underlying type of a qualified or typedef type.
7373///
7374/// If the underlying type is itself a qualified or typedef type, then
7375/// recursively return the first underlying type of that qualified or
7376/// typedef type to return the first underlying type that is not a
7377/// qualified or typedef type.
7378///
7379/// If the underlying type is NOT a qualified nor a typedef type, then
7380/// just return that underlying type.
7381///
7382/// @param type the qualified or typedef type to consider.
7383///
7384/// @return the leaf underlying type.
7385type_base_sptr
7386peel_qualified_or_typedef_type(const type_base_sptr &t)
7387{
7388 type_base_sptr type = t;
7389 while (is_typedef(type) || is_qualified_type(type))
7390 {
7391 if (typedef_decl_sptr t = is_typedef(type))
7392 type = peel_typedef_type(t);
7393
7394 if (qualified_type_def_sptr t = is_qualified_type(type))
7395 type = peel_qualified_type(t);
7396 }
7397
7398 return type;
7399}
7400
7401/// Return the leaf underlying or pointed-to type node of a @ref
7402/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7403/// or @ref array_type_def node.
7404///
7405/// @param type the type to peel.
7406///
7407/// @return the leaf underlying or pointed-to type node of @p type.
7408type_base_sptr
7410{
7411 type_base_sptr typ = type;
7412 while (is_typedef(typ)
7413 || is_pointer_type(typ)
7414 || is_reference_type(typ)
7415 || is_array_type(typ))
7416 {
7417 if (typedef_decl_sptr t = is_typedef(typ))
7418 typ = peel_typedef_type(t);
7419
7421 typ = peel_pointer_type(t);
7422
7424 typ = peel_reference_type(t);
7425
7426 if (const array_type_def_sptr t = is_array_type(typ))
7427 typ = peel_array_type(t);
7428 }
7429
7430 return typ;
7431}
7432
7433/// Return the leaf underlying or pointed-to type node of a @ref
7434/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7435/// node.
7436///
7437/// @param type the type to peel.
7438///
7439/// @return the leaf underlying or pointed-to type node of @p type.
7440type_base*
7442{
7443 while (is_typedef(type)
7444 || is_pointer_type(type)
7445 || is_reference_type(type)
7446 || is_array_type(type))
7447 {
7448 if (const typedef_decl* t = is_typedef(type))
7449 type = peel_typedef_type(t);
7450
7451 if (const pointer_type_def* t = is_pointer_type(type))
7452 type = peel_pointer_type(t);
7453
7454 if (const reference_type_def* t = is_reference_type(type))
7455 type = peel_reference_type(t);
7456
7457 if (const array_type_def* t = is_array_type(type))
7458 type = peel_array_type(t);
7459 }
7460
7461 return const_cast<type_base*>(type);
7462}
7463
7464/// Return the leaf underlying or pointed-to type node of a @ref
7465/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7466/// node.
7467///
7468/// @param type the type to peel.
7469///
7470/// @return the leaf underlying or pointed-to type node of @p type.
7471type_base*
7473 bool peel_qual_type)
7474{
7475 while (is_typedef(type)
7476 || is_pointer_type(type)
7477 || is_reference_type(type)
7478 || is_array_type(type)
7479 || (peel_qual_type && is_qualified_type(type)))
7480 {
7481 if (const typedef_decl* t = is_typedef(type))
7482 type = peel_typedef_type(t);
7483
7484 if (const pointer_type_def* t = is_pointer_type(type))
7485 type = peel_pointer_type(t);
7486
7487 if (const reference_type_def* t = is_reference_type(type))
7488 type = peel_reference_type(t);
7489
7490 if (const array_type_def* t = is_array_type(type))
7491 type = peel_array_type(t);
7492
7493 if (peel_qual_type)
7494 if (const qualified_type_def* t = is_qualified_type(type))
7495 type = peel_qualified_type(t);
7496 }
7497
7498 return const_cast<type_base*>(type);
7499}
7500
7501/// Return the leaf underlying or pointed-to type node of a, @ref
7502/// pointer_type_def, @ref reference_type_def or @ref
7503/// qualified_type_def type node.
7504///
7505/// @param type the type to peel.
7506///
7507/// @param peel_qualified_type if true, also peel qualified types.
7508///
7509/// @return the leaf underlying or pointed-to type node of @p type.
7510type_base*
7512 bool peel_qual_type)
7513{
7514 while (is_pointer_type(type)
7515 || is_reference_type(type)
7516 || is_array_type(type)
7517 || (peel_qual_type && is_qualified_type(type)))
7518 {
7519 if (const pointer_type_def* t = is_pointer_type(type))
7520 type = peel_pointer_type(t);
7521
7522 if (const reference_type_def* t = is_reference_type(type))
7523 type = peel_reference_type(t);
7524
7525 if (const array_type_def* t = is_array_type(type))
7526 type = peel_array_type(t);
7527
7528 if (peel_qual_type)
7529 if (const qualified_type_def* t = is_qualified_type(type))
7530 type = peel_qualified_type(t);
7531 }
7532
7533 return const_cast<type_base*>(type);
7534}
7535
7536/// Clone an array type.
7537///
7538/// Note that the element type of the new array is shared witht the
7539/// old one.
7540///
7541/// @param array the array type to clone.
7542///
7543/// @return a newly built array type. Note that it needs to be added
7544/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7545/// bound to the one of that scope. Otherwise, its lifetime is bound
7546/// to the lifetime of its containing shared pointer.
7549{
7550 vector<array_type_def::subrange_sptr> subranges;
7551
7552 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7553 array->get_subranges().begin();
7554 i != array->get_subranges().end();
7555 ++i)
7556 {
7558 (new array_type_def::subrange_type(array->get_environment(),
7559 (*i)->get_name(),
7560 (*i)->get_lower_bound(),
7561 (*i)->get_upper_bound(),
7562 (*i)->get_underlying_type(),
7563 (*i)->get_location(),
7564 (*i)->get_language()));
7565 subrange->is_non_finite((*i)->is_non_finite());
7566 if (scope_decl *scope = (*i)->get_scope())
7567 add_decl_to_scope(subrange, scope);
7568 subranges.push_back(subrange);
7569 }
7570
7571 array_type_def_sptr result
7572 (new array_type_def(array->get_element_type(),
7573 subranges, array->get_location()));
7574
7575 return result;
7576}
7577
7578/// Clone a typedef type.
7579///
7580/// Note that the underlying type of the newly constructed typedef is
7581/// shared with the old one.
7582///
7583/// @param t the typedef to clone.
7584///
7585/// @return the newly constructed typedef. Note that it needs to be
7586/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7587/// to be bound to the one of that scope. Otherwise, its lifetime is
7588/// bound to the lifetime of its containing shared pointer.
7591{
7592 if (!t)
7593 return t;
7594
7595 typedef_decl_sptr result
7596 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7597 t->get_location(), t->get_linkage_name(),
7598 t->get_visibility()));
7599 return result;
7600}
7601
7602/// Clone a qualifiend type.
7603///
7604/// Note that underlying type of the newly constructed qualified type
7605/// is shared with the old one.
7606///
7607/// @param t the qualified type to clone.
7608///
7609/// @return the newly constructed qualified type. Note that it needs
7610/// to be added to a scope (e.g, using add_decl_to_scope) for its
7611/// lifetime to be bound to the one of that scope. Otherwise, its
7612/// lifetime is bound to the lifetime of its containing shared
7613/// pointer.
7614qualified_type_def_sptr
7615clone_qualified_type(const qualified_type_def_sptr& t)
7616{
7617 if (!t)
7618 return t;
7619
7620 qualified_type_def_sptr result
7621 (new qualified_type_def(t->get_underlying_type(),
7622 t->get_cv_quals(), t->get_location()));
7623
7624 return result;
7625}
7626
7627/// Clone a typedef, an array or a qualified tree.
7628///
7629/// @param type the typedef, array or qualified tree to clone. any
7630/// order.
7631///
7632/// @return the cloned type, or NULL if @type was neither a typedef,
7633/// array nor a qualified type.
7634static type_base_sptr
7635clone_typedef_array_qualified_type(type_base_sptr type)
7636{
7637 if (!type)
7638 return type;
7639
7640 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7641 type_base_sptr result;
7642
7643 if (typedef_decl_sptr t = is_typedef(type))
7644 result = clone_typedef(is_typedef(t));
7645 else if (qualified_type_def_sptr t = is_qualified_type(type))
7646 result = clone_qualified_type(t);
7647 else if (array_type_def_sptr t = is_array_type(type))
7648 result = clone_array(t);
7649 else
7650 return type_base_sptr();
7651
7652 if (scope)
7653 add_decl_to_scope(is_decl(result), scope);
7654
7655 return result;
7656}
7657
7658/// Clone a type tree made of an array or a typedef of array.
7659///
7660/// Note that this can be a tree which root node is a typedef an which
7661/// sub-tree can be any arbitrary combination of typedef, qualified
7662/// type and arrays.
7663///
7664/// @param t the array or typedef of qualified array to consider.
7665///
7666/// @return a clone of @p t.
7667type_base_sptr
7668clone_array_tree(const type_base_sptr t)
7669{
7671
7672 scope_decl* scope = is_decl(t)->get_scope();
7673 type_base_sptr result = clone_typedef_array_qualified_type(t);
7674 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7675
7676 type_base_sptr subtree;
7677 if (typedef_decl_sptr type = is_typedef(result))
7678 {
7679 type_base_sptr s =
7680 clone_typedef_array_qualified_type(type->get_underlying_type());
7681 if (s)
7682 {
7683 subtree = s;
7684 type->set_underlying_type(subtree);
7685 }
7686 }
7687 else if (array_type_def_sptr type = is_array_type(result))
7688 {
7689 type_base_sptr s =
7690 clone_typedef_array_qualified_type(type->get_element_type());
7691 if (s)
7692 {
7693 subtree = s;
7694 type->set_element_type(subtree);
7695 }
7696 }
7697 add_decl_to_scope(is_decl(subtree), scope);
7698
7699 for (;;)
7700 {
7701 if (typedef_decl_sptr t = is_typedef(subtree))
7702 {
7703 type_base_sptr s =
7704 clone_typedef_array_qualified_type(t->get_underlying_type());
7705 if (s)
7706 {
7707 scope_decl* scope =
7708 is_decl(t->get_underlying_type())->get_scope();
7709 ABG_ASSERT(scope);
7710 add_decl_to_scope(is_decl(s), scope);
7711 t->set_underlying_type (s);
7712 subtree = s;
7713 }
7714 else
7715 break;
7716 }
7717 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7718 {
7719 type_base_sptr s =
7720 clone_typedef_array_qualified_type(t->get_underlying_type());
7721 if (s)
7722 {
7723 scope_decl* scope =
7724 is_decl(t->get_underlying_type())->get_scope();
7725 ABG_ASSERT(scope);
7726 add_decl_to_scope(is_decl(s), scope);
7727 t->set_underlying_type(s);
7728 subtree = s;
7729 }
7730 else
7731 break;
7732 }
7733 else if (array_type_def_sptr t = is_array_type(subtree))
7734 {
7735 type_base_sptr e = t->get_element_type();
7736 if (is_typedef(e) || is_qualified_type(e))
7737 {
7738 type_base_sptr s =
7739 clone_typedef_array_qualified_type(e);
7740 if (s)
7741 {
7742 scope_decl* scope = is_decl(e)->get_scope();
7743 ABG_ASSERT(scope);
7744 add_decl_to_scope(is_decl(s), scope);
7745 t->set_element_type(s);
7746 }
7747 else
7748 break;
7749 }
7750 break;
7751 }
7752 else
7753 break;
7754 }
7755 return result;
7756}
7757
7758/// Update the qualified name of a given sub-tree.
7759///
7760/// @param d the sub-tree for which to update the qualified name.
7761static void
7762update_qualified_name(decl_base * d)
7763{
7764 ::qualified_name_setter setter;
7765 d->traverse(setter);
7766}
7767
7768/// Update the qualified name of a given sub-tree.
7769///
7770/// @param d the sub-tree for which to update the qualified name.
7771static void
7772update_qualified_name(decl_base_sptr d)
7773{return update_qualified_name(d.get());}
7774
7775// <scope_decl stuff>
7776
7777/// Hash a type by returning the pointer value of its canonical type.
7778///
7779/// @param l the type to hash.
7780///
7781/// @return the the pointer value of the canonical type of @p l.
7782size_t
7783canonical_type_hash::operator()(const type_base_sptr& l) const
7784{return operator()(l.get());}
7785
7786/// Hash a (canonical) type by returning its pointer value
7787///
7788/// @param l the canonical type to hash.
7789///
7790/// @return the pointer value of the canonical type of @p l.
7791size_t
7793{return reinterpret_cast<size_t>(l);}
7794
7795struct scope_decl::priv
7796{
7797 declarations members_;
7798 declarations sorted_members_;
7799 type_base_sptrs_type member_types_;
7800 type_base_sptrs_type sorted_member_types_;
7801 scopes member_scopes_;
7802 canonical_type_sptr_set_type canonical_types_;
7803 type_base_sptrs_type sorted_canonical_types_;
7804 bool clear_sorted_member_types_cache_ = false;
7805}; // end struct scope_decl::priv
7806
7807/// Constructor of the @ref scope_decl type.
7808///
7809/// @param the environment to use for the new instance.
7810///
7811/// @param the name of the scope decl.
7812///
7813/// @param locus the source location where the scope_decl is defined.
7814///
7815/// @param vis the visibility of the declaration.
7816scope_decl::scope_decl(const environment& env,
7817 const string& name,
7818 const location& locus,
7819 visibility vis)
7820 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7821 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7822 priv_(new priv)
7823{}
7824
7825/// Constructor of the @ref scope_decl type.
7826///
7827/// @param the environment to use for the new instance.
7828///
7829/// @param l the source location where the scope_decl is defined.
7830///
7831/// @param vis the visibility of the declaration.
7832scope_decl::scope_decl(const environment& env, location& l)
7833 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7834 decl_base(env, "", l),
7835 priv_(new priv)
7836{}
7837
7838/// @eturn the set of canonical types of the the current scope.
7841{return priv_->canonical_types_;}
7842
7843/// @eturn the set of canonical types of the the current scope.
7846{return const_cast<scope_decl*>(this)->get_canonical_types();}
7847
7848/// Return a vector of sorted canonical types of the current scope.
7849///
7850/// The types are sorted "almost topologically". That means, they are
7851/// sorted using the lexicographic order of the string representing
7852/// the location their definition point. If a type doesn't have a
7853/// location, then its pretty representation is used.
7854///
7855/// @return a vector of sorted canonical types of the current scope.
7858{
7859 if (priv_->sorted_canonical_types_.empty())
7860 {
7861 for (canonical_type_sptr_set_type::const_iterator e =
7862 get_canonical_types().begin();
7863 e != get_canonical_types().end();
7864 ++e)
7865 priv_->sorted_canonical_types_.push_back(*e);
7866
7867 type_topo_comp comp;
7868 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7869 priv_->sorted_canonical_types_.end(),
7870 comp);
7871 }
7872 return priv_->sorted_canonical_types_;
7873}
7874
7875/// Getter for the member declarations carried by the current @ref
7876/// scope_decl.
7877///
7878/// @return the member declarations carried by the current @ref
7879/// scope_decl.
7882{return priv_->members_;}
7883
7884/// Getter for the member declarations carried by the current @ref
7885/// scope_decl.
7886///
7887/// @return the member declarations carried by the current @ref
7888/// scope_decl.
7891{return priv_->members_;}
7892
7893/// Getter for the sorted member declarations carried by the current
7894/// @ref scope_decl.
7895///
7896/// @return the sorted member declarations carried by the current @ref
7897/// scope_decl. The declarations are sorted topologically.
7900{
7901 decl_topo_comp comp;
7902 if (priv_->sorted_members_.empty())
7903 {
7904 for (declarations::const_iterator i = get_member_decls().begin();
7905 i != get_member_decls().end();
7906 ++i)
7907 priv_->sorted_members_.push_back(*i);
7908
7909 std::stable_sort(priv_->sorted_members_.begin(),
7910 priv_->sorted_members_.end(),
7911 comp);
7912 }
7913 return priv_->sorted_members_;
7914}
7915
7916/// Getter for the number of anonymous classes contained in this
7917/// scope.
7918///
7919/// @return the number of anonymous classes contained in this scope.
7920size_t
7922{
7923 int result = 0;
7924 for (declarations::const_iterator it = get_member_decls().begin();
7925 it != get_member_decls().end();
7926 ++it)
7927 if (class_decl_sptr t = is_class_type(*it))
7928 if (t->get_is_anonymous())
7929 ++result;
7930
7931 return result;
7932}
7933
7934/// Getter for the number of anonymous unions contained in this
7935/// scope.
7936///
7937/// @return the number of anonymous unions contained in this scope.
7938size_t
7940{
7941 int result = 0;
7942 for (declarations::const_iterator it = get_member_decls().begin();
7943 it != get_member_decls().end();
7944 ++it)
7945 if (union_decl_sptr t = is_union_type(*it))
7946 if (t->get_is_anonymous())
7947 ++result;
7948
7949 return result;
7950}
7951
7952/// Getter for the number of anonymous enums contained in this
7953/// scope.
7954///
7955/// @return the number of anonymous enums contained in this scope.
7956size_t
7958{
7959 int result = 0;
7960 for (declarations::const_iterator it = get_member_decls().begin();
7961 it != get_member_decls().end();
7962 ++it)
7963 if (enum_type_decl_sptr t = is_enum_type(*it))
7964 if (t->get_is_anonymous())
7965 ++result;
7966
7967 return result;
7968}
7969
7970/// Getter for the scopes carried by the current scope.
7971///
7972/// @return the scopes carried by the current scope.
7975{return priv_->member_scopes_;}
7976
7977/// Getter for the scopes carried by the current scope.
7978///
7979/// @return the scopes carried by the current scope.
7980const scope_decl::scopes&
7982{return priv_->member_scopes_;}
7983
7984/// Test if the current scope is empty.
7985///
7986/// @return true iff the current scope is empty.
7987bool
7989{
7990 return (get_member_decls().empty()
7991 && get_canonical_types().empty());
7992}
7993
7994/// Set the translation unit of a decl
7995///
7996/// It also perform some IR integrity checks.
7997///
7998/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
7999///
8000/// @param decl the decl to set the translation unit for.
8001///
8002/// @param tu the translation unit to set.
8003static void
8004maybe_set_translation_unit(const decl_base_sptr& decl,
8005 translation_unit* tu)
8006{
8007 ABG_ASSERT(tu);
8008
8009 if (translation_unit* existing_tu = decl->get_translation_unit())
8010 // The decl already belongs to a translation unit.
8011 // Either:
8012 //
8013 // 1/ it's a unique type, in which case we should not add it to
8014 // any translation unique since unique types are "logically"
8015 // supposed to belong to no translation unit in particular, as
8016 // they are unique.
8017 //
8018 // 2/ or the decl was already added to this translation unit.
8019 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
8020 else
8021 decl->set_translation_unit(tu);
8022}
8023
8024/// Add a member decl to this scope. Note that user code should not
8025/// use this, but rather use add_decl_to_scope.
8026///
8027/// Note that this function updates the qualified name of the member
8028/// decl that is added. It also sets the scope of the member. Thus,
8029/// it ABG_ASSERTs that member should not have its scope set, prior to
8030/// calling this function.
8031///
8032/// @param member the new member decl to add to this scope.
8033decl_base_sptr
8034scope_decl::add_member_decl(const decl_base_sptr& member)
8035{
8036 ABG_ASSERT(!has_scope(member));
8037
8038 member->set_scope(this);
8039 priv_->members_.push_back(member);
8040 if (is_type(member))
8041 {
8042 priv_->member_types_.push_back(is_type(member));
8043 priv_->clear_sorted_member_types_cache_ = true;
8044 }
8045
8046 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8047 priv_->member_scopes_.push_back(m);
8048
8049 update_qualified_name(member);
8050
8052 maybe_set_translation_unit(member, tu);
8053
8055
8056 return member;
8057}
8058
8059/// Get the member types of this @ref scope_decl.
8060///
8061/// @return a vector of the member types of this ref class_or_union.
8064{return priv_->member_types_;}
8065
8066/// Find a member type of a given name, inside the current @ref
8067/// scope_decl.
8068///
8069/// @param name the name of the member type to look for.
8070///
8071/// @return a pointer to the @ref type_base that represents the member
8072/// type of name @p name, for the current scope.
8073type_base_sptr
8074scope_decl::find_member_type(const string& name) const
8075{
8076 for (auto t : get_member_types())
8077 if (get_type_name(t, /*qualified*/false) == name)
8078 return t;
8079 return type_base_sptr();
8080}
8081
8082/// Insert a member type.
8083///
8084/// @param t the type to insert in the @ref scope_decl type.
8085///
8086/// @param an iterator right before which @p t has to be inserted.
8087void
8089 declarations::iterator before)
8090{
8091 decl_base_sptr d = get_type_declaration(t);
8092 ABG_ASSERT(d);
8093 ABG_ASSERT(!has_scope(d));
8094
8095 priv_->member_types_.push_back(t);
8096 priv_->clear_sorted_member_types_cache_= true;
8097 insert_member_decl(d, before);
8098}
8099
8100/// Add a member type to the current instance of class_or_union.
8101///
8102/// @param t the member type to add. It must not have been added to a
8103/// scope, otherwise this will violate an ABG_ASSERTion.
8104void
8107
8108/// Add a member type to the current instance of class_or_union.
8109///
8110/// @param t the type to be added as a member type to the current
8111/// instance of class_or_union. An instance of class_or_union::member_type
8112/// will be created out of @p t and and added to the the class.
8113///
8114/// @param a the access specifier for the member type to be created.
8115type_base_sptr
8117{
8118 decl_base_sptr d = get_type_declaration(t);
8119 ABG_ASSERT(d);
8121 add_member_type(t);
8123 return t;
8124}
8125
8126/// Remove a member type from the current @ref class_or_union scope.
8127///
8128/// @param t the type to remove.
8129void
8131{
8132 for (auto i = priv_->member_types_.begin();
8133 i != priv_->member_types_.end();
8134 ++i)
8135 {
8136 if (*((*i)) == *t)
8137 {
8138 priv_->member_types_.erase(i);
8139 return;
8140 }
8141 }
8142}
8143
8144/// Get the sorted member types of this @ref scope_decl
8145///
8146/// @return a vector of the sorted member types of this ref
8147/// class_or_union.
8150{
8151 if (priv_->clear_sorted_member_types_cache_)
8152 {
8153 priv_->sorted_member_types_.clear();
8154 priv_->clear_sorted_member_types_cache_ = false;
8155 }
8156
8157 if (priv_->sorted_member_types_.empty())
8158 {
8159 unordered_set<type_base_sptr> canonical_pointer_types;
8160 for (auto t : get_member_types())
8161 {
8163 priv_->sorted_member_types_.push_back(t);
8164 else if (auto c = t->get_canonical_type())
8165 canonical_pointer_types.insert(c);
8166 else
8167 canonical_pointer_types.insert(t);
8168 }
8169
8170 for (auto t : canonical_pointer_types)
8171 priv_->sorted_member_types_.push_back(t);
8172
8173 type_topo_comp comp;
8174 std::stable_sort(priv_->sorted_member_types_.begin(),
8175 priv_->sorted_member_types_.end(),
8176 comp);
8177 }
8178
8179 const ir::environment& env = get_environment();
8181 priv_->clear_sorted_member_types_cache_ = true;
8182
8183 return priv_->sorted_member_types_;
8184}
8185
8186/// Insert a member decl to this scope, right before an element
8187/// pointed to by a given iterator. Note that user code should not
8188/// use this, but rather use insert_decl_into_scope.
8189///
8190/// Note that this function updates the qualified name of the inserted
8191/// member.
8192///
8193/// @param member the new member decl to add to this scope.
8194///
8195/// @param before an interator pointing to the element before which
8196/// the new member should be inserted.
8197decl_base_sptr
8199 declarations::iterator before)
8200{
8201 ABG_ASSERT(!member->get_scope());
8202
8203 member->set_scope(this);
8204 priv_->members_.insert(before, member);
8205
8206 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8207 priv_-> member_scopes_.push_back(m);
8208
8209 update_qualified_name(member);
8210
8212 maybe_set_translation_unit(member, tu);
8213
8215
8216 return member;
8217}
8218
8219/// Remove a declaration from the current scope.
8220///
8221/// @param member the declaration to remove from the scope.
8222void
8224{
8225 for (declarations::iterator i = priv_->members_.begin();
8226 i != priv_->members_.end();
8227 ++i)
8228 {
8229 if (**i == *member)
8230 {
8231 priv_->members_.erase(i);
8232 // Do not access i after this point as it's invalided by the
8233 // erase call.
8234 break;
8235 }
8236 }
8237
8238 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8239 if (scope)
8240 {
8241 for (scopes::iterator i = priv_->member_scopes_.begin();
8242 i != priv_->member_scopes_.end();
8243 ++i)
8244 {
8245 if (**i == *member)
8246 {
8247 priv_->member_scopes_.erase(i);
8248 break;
8249 }
8250 }
8251 }
8252
8253 member->set_scope(nullptr);
8254 member->set_translation_unit(nullptr);
8255}
8256
8257/// Compares two instances of @ref scope_decl.
8258///
8259/// If the two intances are different, set a bitfield to give some
8260/// insight about the kind of differences there are.
8261///
8262/// @param l the first artifact of the comparison.
8263///
8264/// @param r the second artifact of the comparison.
8265///
8266/// @param k a pointer to a bitfield that gives information about the
8267/// kind of changes there are between @p l and @p r. This one is set
8268/// iff @p k is non-null and the function returns false.
8269///
8270/// Please note that setting k to a non-null value does have a
8271/// negative performance impact because even if @p l and @p r are not
8272/// equal, the function keeps up the comparison in order to determine
8273/// the different kinds of ways in which they are different.
8274///
8275/// @return true if @p l equals @p r, false otherwise.
8276bool
8278{
8279 bool result = true;
8280
8281 if (!l.decl_base::operator==(r))
8282 {
8283 result = false;
8284 if (k)
8286 else
8288 }
8289
8290 scope_decl::declarations::const_iterator i, j;
8291 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8292 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8293 ++i, ++j)
8294 {
8295 if (**i != **j)
8296 {
8297 result = false;
8298 if (k)
8299 {
8300 *k |= SUBTYPE_CHANGE_KIND;
8301 break;
8302 }
8303 else
8305 }
8306 }
8307
8308 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8309 {
8310 result = false;
8311 if (k)
8313 else
8315 }
8316
8317 ABG_RETURN(result);
8318}
8319
8320/// Return true iff both scopes have the same names and have the same
8321/// member decls.
8322///
8323/// This function doesn't check for equality of the scopes of its
8324/// arguments.
8325bool
8327{
8328 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8329 if (!other)
8330 return false;
8331
8332 return equals(*this, *other, 0);
8333}
8334
8335/// Equality operator for @ref scope_decl_sptr.
8336///
8337/// @param l the left hand side operand of the equality operator.
8338///
8339/// @pram r the right hand side operand of the equalify operator.
8340///
8341/// @return true iff @p l equals @p r.
8342bool
8344{
8345 if (!!l != !!r)
8346 return false;
8347 if (l.get() == r.get())
8348 return true;
8349 return *l == *r;
8350}
8351
8352/// Inequality operator for @ref scope_decl_sptr.
8353///
8354/// @param l the left hand side operand of the equality operator.
8355///
8356/// @pram r the right hand side operand of the equalify operator.
8357///
8358/// @return true iff @p l equals @p r.
8359bool
8361{return !operator==(l, r);}
8362
8363/// Find a member of the current scope and return an iterator on it.
8364///
8365/// @param decl the scope member to find.
8366///
8367/// @param i the iterator to set to the member @p decl. This is set
8368/// iff the function returns true.
8369///
8370/// @return true if the member decl was found, false otherwise.
8371bool
8373 declarations::iterator& i)
8374{
8375 if (!decl)
8376 return false;
8377
8378 if (get_member_decls().empty())
8379 {
8380 i = get_member_decls().end();
8381 return false;
8382 }
8383
8384 for (declarations::iterator it = get_member_decls().begin();
8385 it != get_member_decls().end();
8386 ++it)
8387 {
8388 if ((*it).get() == decl)
8389 {
8390 i = it;
8391 return true;
8392 }
8393 }
8394
8395 return false;
8396}
8397
8398/// Find a member of the current scope and return an iterator on it.
8399///
8400/// @param decl the scope member to find.
8401///
8402/// @param i the iterator to set to the member @p decl. This is set
8403/// iff the function returns true.
8404///
8405/// @return true if the member decl was found, false otherwise.
8406bool
8408 declarations::iterator& i)
8409{return find_iterator_for_member(decl.get(), i);}
8410
8411/// This implements the ir_traversable_base::traverse pure virtual
8412/// function.
8413///
8414/// @param v the visitor used on the current instance of scope_decl
8415/// and on its member nodes.
8416///
8417/// @return true if the traversal of the tree should continue, false
8418/// otherwise.
8419bool
8421{
8422 if (visiting())
8423 return true;
8424
8425 if (v.visit_begin(this))
8426 {
8427 visiting(true);
8428 for (scope_decl::declarations::const_iterator i =
8429 get_member_decls().begin();
8430 i != get_member_decls ().end();
8431 ++i)
8432 if (!(*i)->traverse(v))
8433 break;
8434 visiting(false);
8435 }
8436 return v.visit_end(this);
8437}
8438
8439scope_decl::~scope_decl()
8440{}
8441
8442/// Appends a declaration to a given scope, if the declaration
8443/// doesn't already belong to one and if the declaration is not for a
8444/// type that is supposed to be unique.
8445///
8446/// @param decl the declaration to add to the scope
8447///
8448/// @param scope the scope to append the declaration to
8449decl_base_sptr
8450add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8451{
8452 if (!scope)
8453 return decl;
8454
8455 if (scope && decl && !decl->get_scope())
8456 decl = scope->add_member_decl(decl);
8457
8458 return decl;
8459}
8460
8461/// Appends a declaration to a given scope, if the declaration doesn't
8462/// already belong to a scope.
8463///
8464/// @param decl the declaration to add append to the scope
8465///
8466/// @param scope the scope to append the decl to
8467decl_base_sptr
8468add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8469{return add_decl_to_scope(decl, scope.get());}
8470
8471/// Remove a given decl from its scope
8472///
8473/// @param decl the decl to remove from its scope.
8474void
8475remove_decl_from_scope(decl_base_sptr decl)
8476{
8477 if (!decl)
8478 return;
8479
8480 scope_decl* scope = decl->get_scope();
8481 scope->remove_member_decl(decl);
8482}
8483
8484/// Inserts a declaration into a given scope, before a given IR child
8485/// node of the scope.
8486///
8487/// @param decl the declaration to insert into the scope.
8488///
8489/// @param before an iterator pointing to the child IR node before
8490/// which to insert the declaration.
8491///
8492/// @param scope the scope into which to insert the declaration.
8493decl_base_sptr
8494insert_decl_into_scope(decl_base_sptr decl,
8495 scope_decl::declarations::iterator before,
8496 scope_decl* scope)
8497{
8498 if (scope && decl && !decl->get_scope())
8499 {
8500 decl_base_sptr d = scope->insert_member_decl(decl, before);
8501 decl = d;
8502 }
8503 return decl;
8504}
8505
8506/// Inserts a declaration into a given scope, before a given IR child
8507/// node of the scope.
8508///
8509/// @param decl the declaration to insert into the scope.
8510///
8511/// @param before an iterator pointing to the child IR node before
8512/// which to insert the declaration.
8513///
8514/// @param scope the scope into which to insert the declaration.
8515decl_base_sptr
8516insert_decl_into_scope(decl_base_sptr decl,
8517 scope_decl::declarations::iterator before,
8518 scope_decl_sptr scope)
8519{return insert_decl_into_scope(decl, before, scope.get());}
8520
8521/// Constructor of the @ref global_scope type.
8522///
8523/// @param tu the translation unit the scope belongs to.
8524global_scope::global_scope(translation_unit *tu)
8525 : type_or_decl_base(tu->get_environment(),
8526 GLOBAL_SCOPE_DECL
8527 | ABSTRACT_DECL_BASE
8528 | ABSTRACT_SCOPE_DECL),
8529 decl_base(tu->get_environment(), "", location()),
8530 scope_decl(tu->get_environment(), "", location()),
8531 translation_unit_(tu)
8532{
8533 runtime_type_instance(this);
8534}
8535
8536/// return the global scope as seen by a given declaration.
8537///
8538/// @param decl the declaration to consider.
8539///
8540/// @return the global scope of the decl, or a null pointer if the
8541/// decl is not yet added to a translation_unit.
8542const global_scope*
8544{
8545 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8546 return s;
8547
8548 scope_decl* scope = decl.get_scope();
8549 while (scope && !dynamic_cast<global_scope*>(scope))
8550 scope = scope->get_scope();
8551
8552 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8553}
8554
8555/// return the global scope as seen by a given declaration.
8556///
8557/// @param decl the declaration to consider.
8558///
8559/// @return the global scope of the decl, or a null pointer if the
8560/// decl is not yet added to a translation_unit.
8561const global_scope*
8563{return get_global_scope(*decl);}
8564
8565/// Return the global scope as seen by a given declaration.
8566///
8567/// @param decl the declaration to consider.
8568///
8569/// @return the global scope of the decl, or a null pointer if the
8570/// decl is not yet added to a translation_unit.
8571const global_scope*
8572get_global_scope(const shared_ptr<decl_base> decl)
8573{return get_global_scope(decl.get());}
8574
8575/// Return the a scope S containing a given declaration and that is
8576/// right under a given scope P.
8577///
8578/// Note that @p scope must come before @p decl in topological
8579/// order.
8580///
8581/// @param decl the decl for which to find a scope.
8582///
8583/// @param scope the scope under which the resulting scope must be.
8584///
8585/// @return the resulting scope.
8586const scope_decl*
8588 const scope_decl* scope)
8589{
8590 if (!decl)
8591 return 0;
8592
8593 if (scope == 0)
8594 return get_global_scope(decl);
8595
8596 // Handle the case where decl is a scope itself.
8597 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8598 if (!s)
8599 s = decl->get_scope();
8600
8601 if (is_global_scope(s))
8602 return scope;
8603
8604 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8605 // same. The caller needs to be prepared to deal with this case.
8606 if (s == scope)
8607 return s;
8608
8609 while (s && !is_global_scope(s) && s->get_scope() != scope)
8610 s = s->get_scope();
8611
8612 if (!s || is_global_scope(s))
8613 // SCOPE must come before decl in topological order, but I don't
8614 // know how to ensure that ...
8615 return scope;
8616 ABG_ASSERT(s);
8617
8618 return s;
8619}
8620
8621/// Return the a scope S containing a given declaration and that is
8622/// right under a given scope P.
8623///
8624/// @param decl the decl for which to find a scope.
8625///
8626/// @param scope the scope under which the resulting scope must be.
8627///
8628/// @return the resulting scope.
8629const scope_decl*
8630get_top_most_scope_under(const decl_base_sptr decl,
8631 const scope_decl* scope)
8632{return get_top_most_scope_under(decl.get(), scope);}
8633
8634/// Return the a scope S containing a given declaration and that is
8635/// right under a given scope P.
8636///
8637/// @param decl the decl for which to find a scope.
8638///
8639/// @param scope the scope under which the resulting scope must be.
8640///
8641/// @return the resulting scope.
8642const scope_decl*
8643get_top_most_scope_under(const decl_base_sptr decl,
8644 const scope_decl_sptr scope)
8645{return get_top_most_scope_under(decl, scope.get());}
8646
8647// </scope_decl stuff>
8648
8649
8650/// Get the string representation of a CV qualifier bitmap.
8651///
8652/// @param cv_quals the bitmap of CV qualifiers to consider.
8653///
8654/// @return the string representation.
8655string
8657{
8658 string repr;
8659 if (cv_quals & qualified_type_def::CV_RESTRICT)
8660 repr = "restrict";
8661 if (cv_quals & qualified_type_def::CV_CONST)
8662 {
8663 if (!repr.empty())
8664 repr += ' ';
8665 repr += "const";
8666 }
8667 if (cv_quals & qualified_type_def::CV_VOLATILE)
8668 {
8669 if (!repr.empty())
8670 repr += ' ';
8671 repr += "volatile";
8672 }
8673 return repr;
8674}
8675
8676/// Build and return a copy of the name of an ABI artifact that is
8677/// either a type or a decl.
8678///
8679/// @param tod the ABI artifact to get the name for.
8680///
8681/// @param qualified if yes, return the qualified name of @p tod;
8682/// otherwise, return the non-qualified name;
8683///
8684/// @return the name of @p tod.
8685string
8686get_name(const type_or_decl_base *tod, bool qualified)
8687{
8688 string result;
8689
8690 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8691
8692 if (type_base* t = dynamic_cast<type_base*>(a))
8693 result = get_type_name(t, qualified);
8694 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8695 {
8696 if (qualified)
8697 result = d->get_qualified_name();
8698 else
8699 result = d->get_name();
8700 }
8701 else
8702 // We should never reach this point.
8703 abort();
8704
8705 return result;
8706}
8707
8708/// Build and return a copy of the name of an ABI artifact that is
8709/// either a type of a decl.
8710///
8711/// @param tod the ABI artifact to get the name for.
8712///
8713/// @param qualified if yes, return the qualified name of @p tod;
8714/// otherwise, return the non-qualified name;
8715///
8716/// @return the name of @p tod.
8717string
8718get_name(const type_or_decl_base_sptr& tod, bool qualified)
8719{return get_name(tod.get(), qualified);}
8720
8721/// Build and return a qualified name from a name and its scope.
8722///
8723/// The name is supposed to be for an entity that is part of the
8724/// scope.
8725///
8726/// @param the scope to consider.
8727///
8728/// @param name of the name to consider.
8729///
8730/// @return a copy of the string that represents the qualified name.
8731string
8732build_qualified_name(const scope_decl* scope, const string& name)
8733{
8734 if (name.empty())
8735 return "";
8736
8737 string qualified_name;
8738 if (scope)
8739 qualified_name = scope->get_qualified_name();
8740
8741 if (qualified_name.empty())
8742 qualified_name = name;
8743 else
8744 qualified_name = qualified_name + "::" + name;
8745
8746 return qualified_name;
8747}
8748
8749/// Build and return the qualified name of a type in its scope.
8750///
8751/// @param scope the scope of the type to consider.
8752///
8753/// @param type the type to consider.
8754string
8755build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8756{return build_qualified_name(scope, get_name((type)));}
8757
8758// </scope_decl stuff>
8759
8760/// Get the location of the declaration of a given type.
8761///
8762/// @param type the type to consider.
8763///
8764/// @return the location of the declaration of type @p type.
8766get_location(const type_base_sptr& type)
8767{
8768 if (decl_base_sptr decl = get_type_declaration(type))
8769 return get_location(decl);
8770 return location();
8771}
8772
8773/// Get the location of a given declaration.
8774///
8775/// @param decl the declaration to consider.
8776///
8777/// @return the location of the declaration @p decl.
8779get_location(const decl_base_sptr& decl)
8780{
8781 location loc = decl->get_location();
8782 if (!loc)
8783 {
8784 if (class_or_union_sptr c = is_class_or_union_type(decl))
8785 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8786 {
8787 c = is_class_or_union_type(c->get_definition_of_declaration());
8788 loc = c->get_location();
8789 }
8790 }
8791 return loc;
8792}
8793
8794/// Get the scope of a given type.
8795///
8796/// @param t the type to consider.
8797///
8798/// @return the scope of type @p t or 0 if the type has no scope yet.
8801{
8802 if (!t)
8803 return 0;
8804
8806 if (d)
8807 return d->get_scope();
8808 return 0;
8809}
8810
8811/// Get the scope of a given type.
8812///
8813/// @param t the type to consider.
8814///
8815/// @return the scope of type @p t or 0 if the type has no scope yet.
8817get_type_scope(const type_base_sptr& t)
8818{return get_type_scope(t.get());}
8819
8820/// Get the name of a given type and return a copy of it.
8821///
8822/// @param t the type to consider.
8823///
8824/// @param qualified if true then return the qualified name of the
8825/// type.
8826///
8827/// @param internal set to true if the call is intended for an
8828/// internal use (for technical use inside the library itself), false
8829/// otherwise. If you don't know what this is for, then set it to
8830/// false.
8831///
8832/// @return a copy of the type name if the type has a name, or the
8833/// empty string if it does not.
8835get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8836{return get_type_name(t.get(), qualified, internal);}
8837
8838/// Return true iff a decl is for a type type that has a generic
8839/// anonymous internal type name.
8840///
8841/// @param d the decl to considier.
8842///
8843/// @return true iff @p d is for a type type that has a generic
8844/// anonymous internal type name.
8845static bool
8846has_generic_anonymous_internal_type_name(const decl_base *d)
8847{
8848 return (is_class_or_union_type(d)
8849 || is_enum_type(d)
8850 || is_subrange_type(d));
8851}
8852
8853/// Return the generic internal name of an anonymous type.
8854///
8855/// For internal purposes, we want to define a generic name for all
8856/// anonymous types of a certain kind. For instance, all anonymous
8857/// structs will be have a generic name of "__anonymous_struct__", all
8858/// anonymous unions will have a generic name of
8859/// "__anonymous_union__", etc.
8860///
8861/// That generic name can be used as a hash to put all anonymous types
8862/// of a certain kind in the same hash table bucket, for instance.
8863static interned_string
8864get_generic_anonymous_internal_type_name(const decl_base *d)
8865{
8866 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8867
8868 const environment&env = d->get_environment();
8869
8870 interned_string result;
8871 if (is_class_type(d))
8872 result =
8874 else if (is_union_type(d))
8875 result =
8877 else if (is_enum_type(d))
8878 result =
8880 else if (is_subrange_type(d))
8881 result =
8883 else
8885
8886 return result;
8887}
8888
8889/// Get the internal name for a given real type.
8890///
8891/// All real types that have the modifiers 'short, long or long
8892/// long' have the same internal name. This is so that they can all
8893/// have the same canonical type if they are of the same size.
8894/// Otherwise, 'long int' and 'long long int' would have different
8895/// canonical types even though they are equivalent from an ABI point
8896/// of view.
8897///
8898/// @param t the real type to consider
8899///
8900/// @return the internal name for @p t if it's an integral type, or
8901/// the empty string if @p t is not a real type.
8902static string
8903get_internal_real_type_name(const type_base* t)
8904{
8905 string name;
8906 type_decl *type = is_real_type(t);
8907
8908 if (!type)
8909 return name;
8910
8911 real_type int_type;
8912 if (parse_real_type(type->get_name(), int_type))
8913 name = int_type.to_string(/*internal=*/true);
8914
8915 return name;
8916}
8917
8918/// Get the name of a given type and return a copy of it.
8919///
8920/// @param t the type to consider.
8921///
8922/// @param qualified if true then return the qualified name of the
8923/// type.
8924///
8925/// @param internal set to true if the call is intended for an
8926/// internal use (for technical use inside the library itself), false
8927/// otherwise. If you don't know what this is for, then set it to
8928/// false.
8929///
8930/// @return a copy of the type name if the type has a name, or the
8931/// empty string if it does not.
8932interned_string
8933get_type_name(const type_base* t, bool qualified, bool internal)
8934{
8935 const decl_base* d = dynamic_cast<const decl_base*>(t);
8936 if (!d)
8937 {
8938 const function_type* fn_type = is_function_type(t);
8939 ABG_ASSERT(fn_type);
8940 return fn_type->get_cached_name(internal);
8941 }
8942
8943 const environment&env = d->get_environment();
8944
8945 // All anonymous types of a given kind get to have the same internal
8946 // name for internal purpose. This to allow them to be compared
8947 // among themselves during type canonicalization.
8948 if (internal)
8949 {
8950 if (d->get_is_anonymous() && !is_type_decl(t))
8951 {
8952 // Note that anonymous type_decl that are used for
8953 // enumerators are not handled here because they don't have
8954 // generic internal type names.
8955 string r;
8956 r += get_generic_anonymous_internal_type_name(d);
8957 return t->get_environment().intern(r);
8958 }
8959
8960 if (is_typedef(t))
8961 return d->get_name();
8962
8963 if (qualified)
8964 return d->get_qualified_name(internal);
8965
8966 return env.intern(get_internal_real_type_name(t));
8967 }
8968
8969 if (d->get_is_anonymous())
8970 {
8972 return env.intern
8974 /*one_line=*/true,
8975 internal, qualified));
8976 }
8977
8978 if (qualified)
8979 return d->get_qualified_name(internal);
8980 return d->get_name();
8981}
8982
8983/// Get the name of a given type and return a copy of it.
8984///
8985/// @param t the type to consider.
8986///
8987/// @param qualified if true then return the qualified name of the
8988/// type.
8989///
8990/// @param internal set to true if the call is intended for an
8991/// internal use (for technical use inside the library itself), false
8992/// otherwise. If you don't know what this is for, then set it to
8993/// false.
8994///
8995/// @return a copy of the type name if the type has a name, or the
8996/// empty string if it does not.
8998get_type_name(const type_base& t, bool qualified, bool internal)
8999{return get_type_name(&t, qualified, internal);}
9000
9001/// Get the name of the pointer to a given type.
9002///
9003/// @param pointed_to_type the pointed-to-type to consider.
9004///
9005/// @param qualified this is true if the resulting name should be of a
9006/// pointer to a *fully-qualified* pointed-to-type.
9007///
9008/// @param internal true if the name is for libabigail-internal
9009/// purposes.
9010///
9011/// @return the name (string representation) of the pointer.
9014 bool qualified, bool internal)
9015{
9016 const environment& env = pointed_to_type.get_environment();
9017 string tn = get_type_name(pointed_to_type, qualified, internal);
9018 tn = tn + "*";
9019
9020 return env.intern(tn);
9021}
9022
9023/// Get the name of the reference to a given type.
9024///
9025/// @param pointed_to_type the pointed-to-type to consider.
9026///
9027/// @param qualified this is true if the resulting name should be of a
9028/// reference to a *fully-qualified* pointed-to-type.
9029///
9030/// @param internal true if the name is for libabigail-internal
9031/// purposes.
9032///
9033/// @return the name (string representation) of the reference.
9036 bool lvalue_reference,
9037 bool qualified, bool internal)
9038{
9039 const environment& env = pointed_to_type.get_environment();
9040
9041 string name = get_type_name(pointed_to_type, qualified, internal);
9042 if (lvalue_reference)
9043 name = name + "&";
9044 else
9045 name = name + "&&";
9046
9047 return env.intern(name);
9048}
9049
9050/// Get the name of a qualified type, given the underlying type and
9051/// its qualifiers.
9052///
9053/// @param underlying_type the underlying type to consider.
9054///
9055/// @param quals the CV qualifiers of the name.
9056///
9057/// @param qualified true if we should consider the fully qualified
9058/// name of @p underlying_type.
9059///
9060/// @param internal true if the result is to be used for
9061/// libabigail-internal purposes.
9062///
9063/// @return the name (string representation) of the qualified type.
9065get_name_of_qualified_type(const type_base_sptr& underlying_type,
9067 bool qualified, bool internal)
9068{
9069 const environment& env = underlying_type->get_environment();
9070
9071 string quals_repr = get_string_representation_of_cv_quals(quals);
9072 string name = get_type_name(underlying_type, qualified, internal);
9073
9074 if (quals_repr.empty() && internal)
9075 // We are asked to return the internal name, that might be used
9076 // for type canonicalization. For that canonicalization, we need
9077 // to make a difference between a no-op qualified type which
9078 // underlying type is foo (the qualified type is named "none
9079 // foo"), and the name of foo, which is just "foo".
9080 //
9081 // Please remember that this has to be kept in sync with what is
9082 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
9083 // change this code here, please change that code there too.
9084 quals_repr = "";
9085
9086 if (!quals_repr.empty())
9087 {
9088 if (is_pointer_type(peel_qualified_type(underlying_type))
9089 || is_reference_type(peel_qualified_type(underlying_type)))
9090 {
9091 name += " ";
9092 name += quals_repr;
9093 }
9094 else
9095 name = quals_repr + " " + name;
9096 }
9097
9098 return env.intern(name);
9099}
9100
9101/// Get the name of a given function type and return a copy of it.
9102///
9103/// @param fn_type the function type to consider.
9104///
9105/// @param internal set to true if the call is intended for an
9106/// internal use (for technical use inside the library itself), false
9107/// otherwise. If you don't know what this is for, then set it to
9108/// false.
9109///
9110/// @return a copy of the function type name
9113 bool internal)
9114{return get_function_type_name(fn_type.get(), internal);}
9115
9116/// Get the name of a given function type and return a copy of it.
9117///
9118/// @param fn_type the function type to consider.
9119///
9120/// @param internal set to true if the call is intended for an
9121/// internal use (for technical use inside the library itself), false
9122/// otherwise. If you don't know what this is for, then set it to
9123/// false.
9124///
9125/// @return a copy of the function type name
9128 bool internal)
9129{
9130 ABG_ASSERT(fn_type);
9131
9132 if (const method_type* method = is_method_type(fn_type))
9133 return get_method_type_name(method, internal);
9134
9135 return get_function_type_name(*fn_type, internal);
9136}
9137
9138/// Get the name of a given function type and return a copy of it.
9139///
9140/// @param fn_type the function type to consider.
9141///
9142/// @param internal set to true if the call is intended for an
9143/// internal use (for technical use inside the library itself), false
9144/// otherwise. If you don't know what this is for, then set it to
9145/// false.
9146///
9147/// @return a copy of the function type name
9150 bool internal)
9151{
9152 std::ostringstream o;
9153 // When the function name is used for internal purposes (e.g, for
9154 // canonicalization), we want its representation to stay the same,
9155 // regardless of typedefs. So let's strip typedefs from the return
9156 // type.
9157 type_base_sptr return_type = fn_type.get_return_type();
9158 const environment& env = fn_type.get_environment();
9159
9160 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
9161 stream_pretty_representation_of_fn_parms(fn_type, o,
9162 /*qualified=*/true,
9163 internal);
9164 return env.intern(o.str());
9165}
9166
9167/// Get the ID of a function, or, if the ID can designate several
9168/// different functions, get its pretty representation.
9169///
9170/// @param fn the function to consider
9171///
9172/// @return the function ID of pretty representation of @p fn.
9175{
9176 ABG_ASSERT(fn);
9177
9178 interned_string result = fn->get_environment().intern(fn->get_id());
9179
9180 if (const corpus *c = fn->get_corpus())
9181 {
9183 c->get_exported_decls_builder();
9184 if (b->fn_id_maps_to_several_fns(fn))
9185 result = fn->get_environment().intern(fn->get_pretty_representation());
9186 }
9187
9188 return result;
9189}
9190
9191/// Get the name of a given method type and return a copy of it.
9192///
9193/// @param fn_type the function type to consider.
9194///
9195/// @param internal set to true if the call is intended for an
9196/// internal use (for technical use inside the library itself), false
9197/// otherwise. If you don't know what this is for, then set it to
9198/// false.
9199///
9200/// @return a copy of the function type name
9203 bool internal)
9204{return get_method_type_name(fn_type.get(), internal);}
9205
9206/// Get the name of a given method type and return a copy of it.
9207///
9208/// @param fn_type the function type to consider.
9209///
9210/// @param internal set to true if the call is intended for an
9211/// internal use (for technical use inside the library itself), false
9212/// otherwise. If you don't know what this is for, then set it to
9213/// false.
9214///
9215/// @return a copy of the function type name
9218 bool internal)
9219{
9220 if (fn_type)
9221 return get_method_type_name(*fn_type, internal);
9222
9223 return interned_string();
9224}
9225
9226/// Get the name of a given method type and return a copy of it.
9227///
9228/// @param fn_type the function type to consider.
9229///
9230/// @param internal set to true if the call is intended for an
9231/// internal use (for technical use inside the library itself), false
9232/// otherwise. If you don't know what this is for, then set it to
9233/// false.
9234///
9235/// @return a copy of the function type name
9238 bool internal)
9239{
9240 std::ostringstream o;
9241 // When the function name is used for internal purposes (e.g, for
9242 // canonicalization), we want its representation to stay the same,
9243 // regardless of typedefs. So let's strip typedefs from the return
9244 // type.
9245 type_base_sptr return_type = fn_type.get_return_type();
9246
9247 const environment& env = fn_type.get_environment();
9248
9249 if (return_type)
9250 o << get_type_name(return_type, /*qualified=*/true, internal);
9251 else
9252 // There are still some abixml files out there in which "void"
9253 // can be expressed as an empty type.
9254 o << "void";
9255
9256 class_or_union_sptr class_type = fn_type.get_class_type();
9257 ABG_ASSERT(class_type);
9258
9259 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9260 stream_pretty_representation_of_fn_parms(fn_type, o,
9261 /*qualified=*/true,
9262 internal);
9263
9264 return env.intern(o.str());
9265}
9266
9267/// Build and return a copy of the pretty representation of an ABI
9268/// artifact that could be either a type of a decl.
9269///
9270/// param tod the ABI artifact to consider.
9271///
9272/// @param internal set to true if the call is intended for an
9273/// internal use (for technical use inside the library itself), false
9274/// otherwise. If you don't know what this is for, then set it to
9275/// false.
9276///
9277/// @return a copy of the pretty representation of an ABI artifact
9278/// that could be either a type of a decl.
9279string
9281{
9282 string result;
9283
9284 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9285 result = get_pretty_representation(t, internal);
9286 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9287 result = get_pretty_representation(d, internal);
9288 else
9289 // We should never reach this point
9290 abort();
9291
9292 return result;
9293}
9294
9295/// Build and return a copy of the pretty representation of an ABI
9296/// artifact that could be either a type of a decl.
9297///
9298/// param tod the ABI artifact to consider.
9299///
9300/// @param internal set to true if the call is intended for an
9301/// internal use (for technical use inside the library itself), false
9302/// otherwise. If you don't know what this is for, then set it to
9303/// false.
9304///
9305/// @return a copy of the pretty representation of an ABI artifact
9306/// that could be either a type of a decl.
9307string
9309{return get_pretty_representation(tod.get(), internal);}
9310
9311/// Get a copy of the pretty representation of a decl.
9312///
9313/// @param d the decl to consider.
9314///
9315/// @param internal set to true if the call is intended for an
9316/// internal use (for technical use inside the library itself), false
9317/// otherwise. If you don't know what this is for, then set it to
9318/// false.
9319///
9320/// @return the pretty representation of the decl.
9321string
9322get_pretty_representation(const decl_base* d, bool internal)
9323{
9324 if (!d)
9325 return "";
9326 return d->get_pretty_representation(internal);
9327}
9328
9329/// Get a copy of the pretty representation of a type.
9330///
9331/// @param d the type to consider.
9332///
9333/// @param internal set to true if the call is intended for an
9334/// internal use (for technical use inside the library itself), false
9335/// otherwise. If you don't know what this is for, then set it to
9336/// false.
9337///
9338/// @return the pretty representation of the type.
9339string
9340get_pretty_representation(const type_base* t, bool internal)
9341{
9342 if (!t)
9343 return "void";
9344 if (const function_type* fn_type = is_function_type(t))
9345 return get_pretty_representation(fn_type, internal);
9346
9347 const decl_base* d = get_type_declaration(t);
9348 ABG_ASSERT(d);
9349 return get_pretty_representation(d, internal);
9350}
9351
9352/// Get a copy of the pretty representation of a decl.
9353///
9354/// @param d the decl to consider.
9355///
9356/// @param internal set to true if the call is intended for an
9357/// internal use (for technical use inside the library itself), false
9358/// otherwise. If you don't know what this is for, then set it to
9359/// false.
9360///
9361/// @return the pretty representation of the decl.
9362string
9363get_pretty_representation(const decl_base_sptr& d, bool internal)
9364{return get_pretty_representation(d.get(), internal);}
9365
9366/// Get a copy of the pretty representation of a type.
9367///
9368/// @param d the type to consider.
9369///
9370/// @param internal set to true if the call is intended for an
9371/// internal use (for technical use inside the library itself), false
9372/// otherwise. If you don't know what this is for, then set it to
9373/// false.
9374///
9375/// @return the pretty representation of the type.
9376string
9377get_pretty_representation(const type_base_sptr& t, bool internal)
9378{return get_pretty_representation(t.get(), internal);}
9379
9380/// Get the pretty representation of a function type.
9381///
9382/// @param fn_type the function type to consider.
9383///
9384/// @param internal set to true if the call is intended for an
9385/// internal use (for technical use inside the library itself), false
9386/// otherwise. If you don't know what this is for, then set it to
9387/// false.
9388///
9389/// @return the string represenation of the function type.
9390string
9392 bool internal)
9393{return get_pretty_representation(fn_type.get(), internal);}
9394
9395/// Get the pretty representation of a function type.
9396///
9397/// @param fn_type the function type to consider.
9398///
9399/// @param internal set to true if the call is intended for an
9400/// internal use (for technical use inside the library itself), false
9401/// otherwise. If you don't know what this is for, then set it to
9402/// false.
9403///
9404/// @return the string represenation of the function type.
9405string
9406get_pretty_representation(const function_type* fn_type, bool internal)
9407{
9408 if (!fn_type)
9409 return "void";
9410
9411 if (const method_type* method = is_method_type(fn_type))
9412 return get_pretty_representation(method, internal);
9413
9414 return get_pretty_representation(*fn_type, internal);
9415}
9416
9417/// Get the pretty representation of a function type.
9418///
9419/// @param fn_type the function type to consider.
9420///
9421/// @param internal set to true if the call is intended for an
9422/// internal use (for technical use inside the library itself), false
9423/// otherwise. If you don't know what this is for, then set it to
9424/// false.
9425///
9426/// @return the string represenation of the function type.
9427string
9428get_pretty_representation(const function_type& fn_type, bool internal)
9429{
9430 std::ostringstream o;
9431 o << "function type " << get_function_type_name(fn_type, internal);
9432 return o.str();
9433}
9434
9435/// Get the pretty representation of a method type.
9436///
9437/// @param method the method type to consider.
9438///
9439/// @param internal set to true if the call is intended for an
9440/// internal use (for technical use inside the library itself), false
9441/// otherwise. If you don't know what this is for, then set it to
9442/// false.
9443///
9444/// @return the string represenation of the method type.
9445string
9446get_pretty_representation(const method_type& method, bool internal)
9447{
9448 std::ostringstream o;
9449 o << "method type " << get_method_type_name(method, internal);
9450 return o.str();
9451}
9452
9453/// Get the pretty representation of a method type.
9454///
9455/// @param method the method type to consider.
9456///
9457/// @param internal set to true if the call is intended for an
9458/// internal use (for technical use inside the library itself), false
9459/// otherwise. If you don't know what this is for, then set it to
9460/// false.
9461///
9462/// @return the string represenation of the method type.
9463string
9464get_pretty_representation(const method_type* method, bool internal)
9465{
9466 if (!method)
9467 return "void";
9468 return get_pretty_representation(*method, internal);
9469}
9470
9471/// Get the pretty representation of a method type.
9472///
9473/// @param method the method type to consider.
9474///
9475/// @param internal set to true if the call is intended for an
9476/// internal use (for technical use inside the library itself), false
9477/// otherwise. If you don't know what this is for, then set it to
9478/// false.
9479///
9480/// @return the string represenation of the method type.
9481string
9483{return get_pretty_representation(method.get(), internal);}
9484
9485/// Get the flat representation of an instance of @ref class_or_union
9486/// type.
9487///
9488/// The flat representation of a given @ref class_or_union type is the
9489/// actual definition of the type, for instance:
9490///
9491/// struct foo {int a; char b;}
9492///
9493///@param cou the instance of @ref class_or_union to consider.
9494///
9495///@param indent the identation spaces to use in the representation.
9496///
9497///@param one_line if true, then the flat representation stands on one
9498///line. Otherwise, it stands on multiple lines.
9499///
9500///@return the resulting flat representation.
9501string
9503 const string& indent,
9504 bool one_line,
9505 bool internal,
9506 bool qualified_names)
9507{
9508 string repr;
9509 string local_indent = " ";
9510
9511 if (class_decl* clazz = is_class_type(&cou))
9512 {
9513 repr = indent;
9514 if (!internal && clazz->is_struct())
9515 repr += "struct";
9516 else
9517 repr += "class";
9518 }
9519 else if (is_union_type(cou))
9520 repr = indent + "union";
9521 else
9522 return "";
9523
9524 repr += " ";
9525
9526 string name = cou.get_qualified_name();
9527
9528 if (!cou.get_is_anonymous())
9529 repr += name;
9530
9531 if (cou.priv_->is_printing_flat_representation())
9532 {
9533 // We have just detected a cycle while walking the sub-tree
9534 // of this class or union type for the purpose of printing
9535 // its flat representation. We need to get out of here
9536 // pronto or else we'll be spinning endlessly.
9537 repr += "{}";
9538 return repr;
9539 }
9540
9541 // Let's mark this class or union type to signify that we started
9542 // walking its sub-tree. This is to detect potential cycles and
9543 // avoid looping endlessly.
9545
9546 repr += "{";
9547
9548 if (!one_line)
9549 repr += "\n";
9550
9551 string real_indent;
9553 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9554 dm != dmems.end();
9555 ++dm)
9556 {
9557 if (dm != dmems.begin())
9558 {
9559 if (one_line)
9560 real_indent = " ";
9561 else
9562 real_indent = "\n" + indent + local_indent;
9563 }
9564
9566 repr +=
9569 real_indent, one_line, internal, qualified_names);
9570 else
9571 {
9572 if (one_line)
9573 {
9574 if (dm != dmems.begin())
9575 repr += real_indent;
9576 repr += (*dm)->get_pretty_representation(internal,
9577 qualified_names);
9578 }
9579 else
9580 repr +=
9581 real_indent+ (*dm)->get_pretty_representation(internal,
9582 qualified_names);
9583 }
9584 repr += ";";
9585 }
9586
9587 if (one_line)
9588 repr += "}";
9589 else
9590 repr += indent + "}";
9591
9592 // Let's unmark this class or union type to signify that we are done
9593 // walking its sub-tree. This was to detect potential cycles and
9594 // avoid looping endlessly.
9596
9597 return repr;
9598}
9599
9600/// Get the flat representation of an instance of @ref class_or_union
9601/// type.
9602///
9603/// The flat representation of a given @ref class_or_union type is the
9604/// actual definition of the type, for instance:
9605///
9606/// struct foo {int a; char b;}
9607///
9608///@param cou the instance of @ref class_or_union to consider.
9609///
9610///@param indent the identation spaces to use in the representation.
9611///
9612///@param one_line if true, then the flat representation stands on one
9613///line. Otherwise, it stands on multiple lines.
9614///
9615///@return the resulting flat representation.
9616string
9618 const string& indent,
9619 bool one_line,
9620 bool internal,
9621 bool qualified_names)
9622{
9623 if (cou)
9624 return get_class_or_union_flat_representation(*cou, indent, one_line,
9625 internal, qualified_names);
9626 return "";
9627}
9628
9629/// Get the flat representation of an instance of @ref class_or_union
9630/// type.
9631///
9632/// The flat representation of a given @ref class_or_union type is the
9633/// actual definition of the type, for instance:
9634///
9635/// struct foo {int a; char b;}
9636///
9637///@param cou the instance of @ref class_or_union to consider.
9638///
9639///@param indent the identation spaces to use in the representation.
9640///
9641///@param one_line if true, then the flat representation stands on one
9642///line. Otherwise, it stands on multiple lines.
9643///
9644///@return the resulting flat representation.
9645string
9646get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9647 const string& indent,
9648 bool one_line,
9649 bool internal,
9650 bool qualified_names)
9652 indent,
9653 one_line,
9654 internal,
9655 qualified_names);}
9656
9657/// Get the flat representation of an instance of @ref enum_type_decl
9658/// type.
9659///
9660/// The flat representation of a given @ref enum_type_decl type is the
9661/// actual definition of the type, for instance:
9662///
9663/// enum {E_0 =0, E_1 = 1}
9664///
9665///@param enum_type the enum type to consider.
9666///
9667///@param indent the identation spaces to use in the representation.
9668///
9669///@param one_line if true, then the flat representation stands on one
9670///line. Otherwise, it stands on multiple lines.
9671///
9672///@param qualified_names use qualified names when applicable.
9673///Typically, if this is true, the name of the enum is going to be
9674///qualified.
9675///
9676///@return the resulting flat representation.
9677string
9679 const string& indent, bool one_line,
9680 bool qualified_names)
9681{
9682 string repr;
9683 std::ostringstream o;
9684 string local_indent = " ";
9685
9686 repr = indent + "enum ";
9687
9688 if (!enum_type.get_is_anonymous())
9689 o << (qualified_names
9690 ? enum_type.get_qualified_name()
9691 : enum_type.get_name()) + " ";
9692
9693 o << "{";
9694
9695 if (!one_line)
9696 o << "\n";
9697
9698 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9699 {
9700 if (!one_line)
9701 o << "\n" + indent;
9702
9703 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9704 }
9705
9706 if (!one_line)
9707 o << "\n" + indent << "}";
9708 else
9709 o << "}";
9710
9711 repr =o.str();
9712
9713 return repr;
9714}
9715
9716/// Get the flat representation of an instance of @ref enum_type_decl
9717/// type.
9718///
9719/// The flat representation of a given @ref enum_type_decl type is the
9720/// actual definition of the type, for instance:
9721///
9722/// enum {E_0 =0, E_1 = 1}
9723///
9724///@param enum_type the enum type to consider.
9725///
9726///@param indent the identation spaces to use in the representation.
9727///
9728///@param one_line if true, then the flat representation stands on one
9729///line. Otherwise, it stands on multiple lines.
9730///
9731///@param qualified_names use qualified names when applicable.
9732///Typically, if this is true, the name of the enum is going to be
9733///qualified.
9734///
9735///@return the resulting flat representation.
9736string
9738 const string& indent, bool one_line,
9739 bool qualified_names)
9740{
9741 if (!enum_type)
9742 return "";
9743
9744 return get_enum_flat_representation(*enum_type, indent,
9745 one_line, qualified_names);
9746}
9747
9748/// Get the flat representation of an instance of @ref enum_type_decl
9749/// type.
9750///
9751/// The flat representation of a given @ref enum_type_decl type is the
9752/// actual definition of the type, for instance:
9753///
9754/// enum {E_0 =0, E_1 = 1}
9755///
9756///@param enum_type the enum type to consider.
9757///
9758///@param indent the identation spaces to use in the representation.
9759///
9760///@param one_line if true, then the flat representation stands on one
9761///line. Otherwise, it stands on multiple lines.
9762///
9763///@param qualified_names use qualified names when applicable.
9764///Typically, if this is true, the name of the enum is going to be
9765///qualified.
9766///
9767///@return the resulting flat representation.
9768string
9770 const string& indent, bool one_line,
9771 bool qualified_names)
9772{
9773 return get_enum_flat_representation(enum_type.get(),
9774 indent, one_line,
9775 qualified_names);
9776}
9777
9778/// Get the flat representation of an instance of @ref enum_type_decl
9779/// type.
9780///
9781/// The flat representation of a given @ref enum_type_decl type is the
9782/// actual definition of the type, for instance:
9783///
9784/// enum {E_0 =0, E_1 = 1}
9785///
9786///@param enum_type the enum type to consider.
9787///
9788///@param indent the identation spaces to use in the representation.
9789///
9790///@param one_line if true, then the flat representation stands on one
9791///line. Otherwise, it stands on multiple lines.
9792///
9793///@param qualified_names use qualified names when applicable.
9794///Typically, if this is true, the name of the enum is going to be
9795///qualified.
9796///
9797///@return the resulting flat representation.
9798string
9800 const string& indent,
9801 bool one_line,
9802 bool internal,
9803 bool qualified_name)
9804
9805{
9806 string repr;
9807 if (const class_or_union* cou = is_class_or_union_type(&coe))
9808 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9809 internal, qualified_name);
9810 else if (const enum_type_decl* enom = is_enum_type(&coe))
9811 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9812
9813 return repr;
9814}
9815
9816/// Get the textual representation of a type for debugging purposes.
9817///
9818/// If the type is a class/union, this shows the data members, virtual
9819/// member functions, size, pointer value of its canonical type, etc.
9820/// Otherwise, this just shows the name of the artifact as returned by
9821/// type_or_decl_base:get_pretty_representation().
9822///
9823/// @param artifact the artifact to show a debugging representation of.
9824///
9825/// @return a debugging string representation of @p artifact.
9826string
9828{
9829 string nil_str;
9830 if (!artifact)
9831 return nil_str;
9832
9833 class_or_union * c = is_class_or_union_type(artifact);
9834 if (c)
9835 {
9836 class_decl *clazz = is_class_type(c);
9837 string name = c->get_qualified_name();
9838 std::ostringstream o;
9839 if (clazz)
9840 {
9841 if (clazz->is_struct())
9842 o << "struct ";
9843 else
9844 o << "class ";
9845 }
9846 else if (is_union_type(c))
9847 o << "union ";
9848 o << name;
9849
9850 if (clazz)
9851 {
9852 if (!clazz->get_base_specifiers().empty())
9853 o << " :" << std::endl;
9854 for (auto &b : clazz->get_base_specifiers())
9855 {
9856 o << " ";
9857 if (b->get_is_virtual())
9858 o << "virtual ";
9859 o << b->get_base_class()->get_qualified_name()
9860 << " // hash: ";
9861 hash_t h = peek_hash_value(*b->get_base_class());
9862 if (h)
9863 o << std::hex << *h << std::dec;
9864 else
9865 o << "none";
9866 o << std::endl;
9867 }
9868 }
9869 o << std::endl
9870 << "{"
9871 << " // size in bits: " << c->get_size_in_bits() << "\n"
9872 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9873 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9874 << " // translation unit: "
9875 << (c->get_translation_unit()
9877 : nil_str)
9878 << std::endl
9879 << " // @: " << std::hex << is_type(c)
9880 << ", @canonical: " << c->get_canonical_type().get() << std::dec << "\n"
9881 << " // hash: " ;
9882
9883 hash_t h = peek_hash_value(*c);
9884 if (h)
9885 o << std::hex << *h << std::dec;
9886 else
9887 o << "none";
9888 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*c);
9889 o << "\n\n";
9890
9891
9892 for (auto member_type : c->get_sorted_member_types())
9893 {
9894 o << " "
9895 << member_type->get_pretty_representation(/*internal=*/false,
9896 /*qualified=*/false)
9897 << ";";
9898 if (member_type->get_canonical_type())
9899 {
9900 o << " // uses canonical type: '@"
9901 << std::hex << member_type->get_canonical_type().get() << "'";
9902 o << " / h:";
9903 hash_t h = peek_hash_value(*member_type);
9904 o << std::hex << *h << std::dec;
9905 if (get_canonical_type_index(*member_type))
9906 o << "#" << get_canonical_type_index(*member_type);
9907 }
9908 o << "\n";
9909 }
9910
9911 if (!c->get_sorted_member_types().empty())
9912 o << std::endl;
9913
9914 for (auto m : c->get_data_members())
9915 {
9916 type_base_sptr t = m->get_type();
9918
9919 o << " "
9920 << m->get_pretty_representation(/*internal=*/false,
9921 /*qualified=*/false)
9922 << ";";
9923
9924 if (t && t->get_canonical_type())
9925 o << " // uses canonical type '@"
9926 << std::hex << t->get_canonical_type().get() << "'";
9927
9928 o << "/ h:";
9929 hash_t h = peek_hash_value(*m->get_type());
9930 if (h)
9931 o << std::hex << *h << std::dec;
9932 else
9933 o << "none";
9934 o << std::endl;
9935 }
9936
9937 if (!c->get_data_members().empty())
9938 o << std::endl;
9939
9940 if (clazz && clazz->has_vtable())
9941 {
9942 o << " // virtual member functions\n\n";
9943 for (auto f : clazz->get_virtual_mem_fns())
9944 {
9945 o << " " << f->get_pretty_representation(/*internal=*/false,
9946 /*qualified=*/false)
9947 << " // voffset: " << get_member_function_vtable_offset(f)
9948 << ", h: ";
9949 hash_t h = peek_hash_value(*f->get_type());
9950 if (h)
9951 o << std::hex << *h << std::dec;
9952 else
9953 o << "none";
9954 o << ";" << std::endl;
9955 }
9956 }
9957
9958 o << "};" << std::endl;
9959
9960 return o.str();
9961 }
9962 else if (const enum_type_decl* e = is_enum_type(artifact))
9963 {
9964 string name = e->get_qualified_name();
9965 std::ostringstream o;
9966 o << "enum " << name
9967 << " : "
9968 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9969 true)
9970 << "\n"
9971 << "{\n"
9972 << " // size in bits: " << e->get_size_in_bits() << "\n"
9973 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9974 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9975 << " // translation unit: "
9976 << e->get_translation_unit()->get_absolute_path() << "\n"
9977 << " // @: " << std::hex << is_type(e)
9978 << ", @canonical: " << e->get_canonical_type().get() << std::dec << "\n"
9979 << " // hash: ";
9980
9981 hash_t h = peek_hash_value(*e);
9982 if (h)
9983 o << std::hex << *h << std::dec;
9984 else
9985 o << "none";
9986 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*e);
9987 o << "\n\n";
9988
9989 for (const auto &enom : e->get_enumerators())
9990 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9991
9992 o << "};\n";
9993
9994 return o.str();
9995 }
9996 else if (type_base *t = is_type(artifact))
9997 {
9998 std::ostringstream o;
9999 o << t->get_pretty_representation(/*internal=*/true,
10000 /*qualified=*/true)
10001 << " // cti: " << get_canonical_type_index(*t)
10002 << "\n";
10003 return o.str();
10004 }
10005
10006 return artifact->get_pretty_representation(/*internal=*/true,
10007 /*qualified=*/true);
10008}
10009
10010/// Get a given data member, referred to by its name, of a class type.
10011///
10012/// @param clazz the class to consider.
10013///
10014/// @param member_name name of the data member to get.
10015///
10016/// @return the resulting data member or nullptr if none was found.
10018get_data_member(class_or_union *clazz, const char* member_name)
10019{
10020 if (!clazz)
10021 return var_decl_sptr();
10022 return clazz->find_data_member(member_name);
10023}
10024
10025/// Get a given data member, referred to by its name, of a class type.
10026///
10027/// @param clazz the class to consider.
10028///
10029/// @param member_name name of the data member to get.
10030///
10031/// @return the resulting data member or nullptr if none was found.
10033get_data_member(type_base *clazz, const char* member_name)
10034{return get_data_member(is_class_or_union_type(clazz), member_name);}
10035
10036/// Get the non-artificial (natural) location of a decl.
10037///
10038/// If the decl doesn't have a natural location then return its
10039/// artificial one.
10040///
10041/// @param decl the decl to consider.
10042///
10043/// @return the natural location @p decl if it has one; otherwise,
10044/// return its artificial one.
10045const location&
10047{
10048 ABG_ASSERT(decl);
10049
10050 if (decl->get_location())
10051 return decl->get_location();
10052 return decl->get_artificial_location();
10053}
10054
10055/// Get the artificial location of a decl.
10056///
10057/// If the decl doesn't have an artificial location then return its
10058/// natural one.
10059///
10060/// @param decl the decl to consider.
10061///
10062/// @return the artificial location @p decl if it has one; otherwise,
10063/// return its natural one.
10064const location&
10066{
10067 ABG_ASSERT(decl);
10068
10069 if (decl->has_artificial_location())
10070 return decl->get_artificial_location();
10071 return decl->get_location();
10072}
10073
10074/// Emit a textual representation of an artifact to std error stream
10075/// for debugging purposes.
10076///
10077/// This is useful to invoke from within a command line debugger like
10078/// GDB to help make sense of a given ABI artifact.
10079///
10080/// @param artifact the ABI artifact to emit the debugging
10081/// representation for.
10082///
10083/// @return the artifact @p artifact.
10085debug(const type_or_decl_base* artifact)
10086{
10087 std::cerr << get_debug_representation(artifact) << std::endl;
10088 return const_cast<type_or_decl_base*>(artifact);
10089}
10090
10091/// Emit a textual representation of an artifact to std error stream
10092/// for debugging purposes.
10093///
10094/// This is useful to invoke from within a command line debugger like
10095/// GDB to help make sense of a given ABI artifact.
10096///
10097/// @param artifact the ABI artifact to emit the debugging
10098/// representation for.
10099///
10100/// @return the artifact @p artifact.
10101type_base*
10102debug(const type_base* artifact)
10103{
10104 debug(static_cast<const type_or_decl_base*>(artifact));
10105 return const_cast<type_base*>(artifact);
10106}
10107
10108/// Emit a textual representation of an artifact to std error stream
10109/// for debugging purposes.
10110///
10111/// This is useful to invoke from within a command line debugger like
10112/// GDB to help make sense of a given ABI artifact.
10113///
10114/// @param artifact the ABI artifact to emit the debugging
10115/// representation for.
10116///
10117/// @return the artifact @p artifact.
10118decl_base*
10119debug(const decl_base* artifact)
10120{
10121 debug(static_cast<const type_or_decl_base*>(artifact));
10122 return const_cast<decl_base*>(artifact);
10123}
10124
10125/// Test if two ABI artifacts are equal.
10126///
10127/// This can be useful when used from the command line of a debugger
10128/// like GDB.
10129///
10130/// @param l the first ABI artifact to consider in the comparison.
10131///
10132/// @param r the second ABI artifact to consider in the comparison.
10133///
10134/// @return true iff @p l equals @p r.
10135bool
10137{
10138 if (!!l != !!r)
10139 return false;
10140 if (!l && !r)
10141 return true;
10142
10143 return (*l == *r);
10144}
10145
10146/// Emit a trace of a comparison operand stack.
10147///
10148/// @param vect the operand stack to emit the trace for.
10149///
10150/// @param o the output stream to emit the trace to.
10151static void
10152debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10153{
10154 for (auto t : vect)
10155 {
10156 o << "|" << t->get_pretty_representation()
10157 << "@" << std::hex << t << std::dec;
10158 }
10159 if (!vect.empty())
10160 o << "|";
10161}
10162
10163/// Construct a trace of the two comparison operand stacks.
10164///
10165/// @param the environment in which the comparison operand stacks are.
10166///
10167/// @return a string representing the trace.
10168static string
10169print_comp_stack(const environment& env)
10170{
10171 std::ostringstream o;
10172 o << "left-operands: ";
10173 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10174 o << "\n" << "right-operands: ";
10175 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10176 o << "\n";
10177 return o.str();
10178}
10179
10180/// Emit a trace of the two comparison operands stack on the standard
10181/// error stream.
10182///
10183/// @param env the environment the comparison operands stack belong
10184/// to.
10185void
10187{
10188 std::cerr << print_comp_stack(env);
10189 std::cerr << std::endl;
10190}
10191
10192/// By looking at the language of the TU a given ABI artifact belongs
10193/// to, test if the ONE Definition Rule should apply.
10194///
10195/// To date, it applies to c++, java and ada.
10196///
10197/// @param artifact the ABI artifact to consider.
10198///
10199/// @return true iff the One Definition Rule should apply.
10200bool
10202{
10203 if (!artifact.get_translation_unit())
10204 return false;
10205
10207 artifact.get_translation_unit()->get_language();
10208
10210 || is_java_language(l)
10211 || is_ada_language(l))
10212 return true;
10213
10214 return false;
10215}
10216
10217/// Get the declaration for a given type.
10218///
10219/// @param t the type to consider.
10220///
10221/// @return the declaration for the type to return.
10222const decl_base*
10224{return dynamic_cast<const decl_base*>(t);}
10225
10226/// Get the declaration for a given type.
10227///
10228/// @param t the type to consider.
10229///
10230/// @return the declaration for the type to return.
10231decl_base*
10233{return dynamic_cast<decl_base*>(t);}
10234
10235/// Get the declaration for a given type.
10236///
10237/// @param t the type to consider.
10238///
10239/// @return the declaration for the type to return.
10240decl_base_sptr
10241get_type_declaration(const type_base_sptr t)
10242{return dynamic_pointer_cast<decl_base>(t);}
10243
10244/// Test if two classes have the same layout.
10245///
10246/// Test if all the types and offsets of the members are equal,
10247/// regardless of their access modifiers.
10248///
10249/// @param f the first class to take into account.
10250///
10251/// @param s the second class to take into account.
10252///
10253/// @return true iff @p s and @p f are class types with the same
10254/// layout.
10255bool
10256classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
10257{
10260
10261 if (!fc
10262 || !sc
10263 || (fc->get_qualified_name() != sc->get_qualified_name())
10264 || (fc->get_size_in_bits() != sc->get_size_in_bits())
10265 || (fc->get_data_members().size() != sc->get_data_members().size()))
10266 return false;
10267
10268 if (*fc == *sc)
10269 return true;
10270
10271 // Compare the types and offsets of data members one by one.
10272 for (auto f_decl_it = fc->get_data_members().begin(),
10273 s_decl_it = sc->get_data_members().begin();
10274 (f_decl_it != fc->get_data_members().end()
10275 && s_decl_it != sc->get_data_members().end());
10276 ++f_decl_it, ++s_decl_it)
10277 {
10278 var_decl_sptr dm1 = *f_decl_it, dm2 = *s_decl_it;
10279 type_base_sptr dm1_type = dm1->get_type(), dm2_type = dm2->get_type();
10280
10281 if (*dm1_type != *dm2_type
10283 return false;
10284 }
10285
10286 // Compare the layout of base types
10287 for (auto f_bs_it = fc->get_base_specifiers().begin(),
10288 s_bs_it = sc->get_base_specifiers().end();
10289 (f_bs_it != fc->get_base_specifiers().end()
10290 && s_bs_it != sc->get_base_specifiers().end());
10291 ++f_bs_it, ++s_bs_it)
10292 {
10293 class_decl::base_spec_sptr f_bs = *f_bs_it, s_bs = *s_bs_it;
10294 if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
10295 || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
10296 return false;
10297
10298 class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
10299 if (!classes_have_same_layout(fb, sb))
10300 return false;
10301 }
10302
10303 if (fc->has_vtable() != sc->has_vtable())
10304 return false;
10305
10306 // Compare virtual function types
10307 if (fc->has_vtable())
10308 {
10309 if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
10310 // Some virtual member function got removed. Bad.
10311 return false;
10312
10313 for (auto it1 = fc->get_virtual_mem_fns().begin(),
10314 it2 = sc->get_virtual_mem_fns().begin();
10315 (it1 != fc->get_virtual_mem_fns().end()
10316 && it2 != sc->get_virtual_mem_fns().end());
10317 ++it1, ++it2)
10318 {
10319 method_decl_sptr method1 = *it1;
10320 method_decl_sptr method2 = *it2;
10321
10324 || types_are_compatible(method1->get_type(),
10325 method2->get_type()))
10326 return false;
10327 }
10328 }
10329
10330 return true;
10331}
10332
10333/// Test if two types are equal modulo a typedef or CV qualifiers.
10334///
10335/// Type A and B are compatible if
10336///
10337/// - A and B are equal
10338/// - or A and B are integral types with harmless name change
10339/// - or if one type is a typedef of the other one.
10340/// - or if one type is the CV qualified version of the other
10341/// - or if A and B are classes with the same layout.
10342/// - or if A and B are pointers, references or arrays of
10343/// compatible types
10344///
10345/// @param type1 the first type to consider.
10346///
10347/// @param type2 the second type to consider.
10348///
10349/// @return true iff @p type1 and @p type2 are compatible.
10350bool
10351types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
10352{
10353 if (!type1 || !type2)
10354 return false;
10355
10356 if (type1 == type2 || *type1 == *type2)
10357 return true;
10358
10359 type_base_sptr t1 = peel_qualified_or_typedef_type(type1);
10360 type_base_sptr t2 = peel_qualified_or_typedef_type(type2);
10361
10362 if (t1 && t2 && *t1 == *t2)
10363 return true;
10364
10366 return true;
10367
10368 if (is_pointer_type(t1) && is_pointer_type(t2))
10369 {
10370 t1 = is_pointer_type(t1)->get_pointed_to_type();
10371 t2 = is_pointer_type(t2)->get_pointed_to_type();
10372 return types_are_compatible(t1, t2);
10373 }
10374
10375 if (is_reference_type(t1) && is_reference_type(t2))
10376 {
10377 t1 = is_reference_type(t1)->get_pointed_to_type();
10378 t2 = is_reference_type(t2)->get_pointed_to_type();
10379 return types_are_compatible(t1, t2);
10380 }
10381
10382 if (is_array_type(t1) && is_array_type(t2))
10383 {
10386 type_base_sptr e1 = a1->get_element_type();
10387 type_base_sptr e2 = a2->get_element_type();
10390
10391 if ((a1->get_size_in_bits() != a2->get_size_in_bits())
10392 || (a1->get_dimension_count() != a2->get_dimension_count())
10393 || !types_are_compatible(e1, e2))
10394 return false;
10395
10396 return true;
10397 }
10398
10399 if (function_type_sptr fn_type1 = is_function_type(t1))
10400 if (function_type_sptr fn_type2 = is_function_type(t2))
10401 {
10402 // Compare return types
10403 if (!types_are_compatible(fn_type1->get_return_type(),
10404 fn_type2->get_return_type()))
10405 return false;
10406
10407 // Compare parameter types, omitting the implicit parameter to
10408 // avoid infinite recursion when we are being called from
10409 // classes_have_same_layout on classes with virtual member
10410 // functions.
10411 if (fn_type1->get_parameters().size()
10412 != fn_type2->get_parameters().size())
10413 return false;
10414
10415 for (auto p1 = fn_type1->get_first_non_implicit_parm(),
10416 p2 = fn_type2->get_first_non_implicit_parm();
10417 (p1 != fn_type1->get_parameters().end()
10418 && p2 != fn_type2->get_parameters().end());
10419 ++p1, ++p2)
10420 if (!types_are_compatible((*p1)->get_type(),
10421 (*p2)->get_type()))
10422 return false;
10423 }
10424
10425 if (classes_have_same_layout(t1, t2))
10426 return true;
10427
10428 return false;
10429}
10430
10431/// Test if two types are equal modulo a typedef.
10432///
10433/// Type A and B are compatible if
10434///
10435/// - A and B are equal
10436/// - or if one type is a typedef of the other one.
10437///
10438/// @param type1 the declaration of the first type to consider.
10439///
10440/// @param type2 the declaration of the second type to consider.
10441///
10442/// @return true iff @p type1 and @p type2 are compatible.
10443bool
10444types_are_compatible(const decl_base_sptr d1,
10445 const decl_base_sptr d2)
10446{return types_are_compatible(is_type(d1), is_type(d2));}
10447
10448/// Return the translation unit a declaration belongs to.
10449///
10450/// @param decl the declaration to consider.
10451///
10452/// @return the resulting translation unit, or null if the decl is not
10453/// yet added to a translation unit.
10456{
10457 translation_unit* result =
10458 const_cast<translation_unit*>(t.get_translation_unit());
10459
10460 if (result)
10461 return result;
10462
10463 if (decl_base* decl = is_decl(&t))
10464 {
10465 scope_decl* scope = decl->get_scope();
10466 while (scope)
10467 {
10468 result = scope->get_translation_unit();
10469 if (result)
10470 break;
10471 scope = scope->get_scope();
10472 }
10473 }
10474
10475 return result;
10476}
10477
10478/// Return the translation unit a declaration belongs to.
10479///
10480/// @param decl the declaration to consider.
10481///
10482/// @return the resulting translation unit, or null if the decl is not
10483/// yet added to a translation unit.
10486{return decl ? get_translation_unit(*decl) : nullptr;}
10487
10488/// Return the translation unit a declaration belongs to.
10489///
10490/// @param decl the declaration to consider.
10491///
10492/// @return the resulting translation unit, or null if the decl is not
10493/// yet added to a translation unit.
10496{return get_translation_unit(decl.get());}
10497
10498/// Tests whether if a given scope is the global scope.
10499///
10500/// @param scope the scope to consider.
10501///
10502/// @return true iff the current scope is the global one.
10503bool
10505{return !!dynamic_cast<const global_scope*>(&scope);}
10506
10507/// Tests whether if a given scope is the global scope.
10508///
10509/// @param scope the scope to consider.
10510///
10511/// @return the @ref global_scope* representing the scope @p scope or
10512/// 0 if @p scope is not a global scope.
10513const global_scope*
10515{return dynamic_cast<const global_scope*>(scope);}
10516
10517/// Tests whether if a given scope is the global scope.
10518///
10519/// @param scope the scope to consider.
10520///
10521/// @return true iff the current scope is the global one.
10522bool
10523is_global_scope(const shared_ptr<scope_decl>scope)
10524{return is_global_scope(scope.get());}
10525
10526/// Tests whether a given declaration is at global scope.
10527///
10528/// @param decl the decl to consider.
10529///
10530/// @return true iff decl is at global scope.
10531bool
10533{return (is_global_scope(decl.get_scope()));}
10534
10535/// Tests whether a given declaration is at global scope.
10536///
10537/// @param decl the decl to consider.
10538///
10539/// @return true iff decl is at global scope.
10540bool
10541is_at_global_scope(const decl_base_sptr decl)
10542{return (decl && is_global_scope(decl->get_scope()));}
10543
10544/// Tests whether a given declaration is at global scope.
10545///
10546/// @param decl the decl to consider.
10547///
10548/// @return true iff decl is at global scope.
10549bool
10551{return is_at_global_scope(*decl);}
10552
10553/// Tests whether a given decl is at class scope.
10554///
10555/// @param decl the decl to consider.
10556///
10557/// @return true iff decl is at class scope.
10559is_at_class_scope(const decl_base_sptr decl)
10560{return is_at_class_scope(decl.get());}
10561
10562/// Tests whether a given decl is at class scope.
10563///
10564/// @param decl the decl to consider.
10565///
10566/// @return true iff decl is at class scope.
10569{
10570 if (!decl)
10571 return 0;
10572
10573 return is_at_class_scope(*decl);
10574}
10575
10576/// Tests whether a given decl is at class scope.
10577///
10578/// @param decl the decl to consider.
10579///
10580/// @return true iff decl is at class scope.
10583{
10584 scope_decl* scope = decl.get_scope();
10585 if (class_or_union* cl = is_class_type(scope))
10586 return cl;
10587 if (class_or_union* cl = is_union_type(scope))
10588 return cl;
10589 return 0;
10590}
10591
10592/// Find a data member inside an anonymous data member.
10593///
10594/// An anonymous data member has a type which is a class or union.
10595/// This function looks for a data member inside the type of that
10596/// anonymous data member.
10597///
10598/// @param anon_dm the anonymous data member to consider.
10599///
10600/// @param name the name of the data member to look for.
10603 const string& name)
10604{
10605 const class_or_union* containing_class_or_union =
10607
10608 if (!containing_class_or_union)
10609 return var_decl_sptr();
10610
10611 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10612 return result;
10613}
10614
10615/// Tests whether a given decl is at template scope.
10616///
10617/// Note that only template parameters , types that are compositions,
10618/// and template patterns (function or class) can be at template scope.
10619///
10620/// @param decl the decl to consider.
10621///
10622/// @return true iff the decl is at template scope.
10623bool
10624is_at_template_scope(const shared_ptr<decl_base> decl)
10625{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10626
10627/// Tests whether a decl is a template parameter.
10628///
10629/// @param decl the decl to consider.
10630///
10631/// @return true iff decl is a template parameter.
10632bool
10633is_template_parameter(const shared_ptr<decl_base> decl)
10634{
10635 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10636 || dynamic_pointer_cast<non_type_tparameter>(decl)
10637 || dynamic_pointer_cast<template_tparameter>(decl)));
10638}
10639
10640/// Test whether a declaration is a @ref function_decl.
10641///
10642/// @param d the declaration to test for.
10643///
10644/// @return a shared pointer to @ref function_decl if @p d is a @ref
10645/// function_decl. Otherwise, a nil shared pointer.
10648{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10649
10650/// Test whether a declaration is a @ref function_decl.
10651///
10652/// @param d the declaration to test for.
10653///
10654/// @return true if @p d is a function_decl.
10655bool
10657{return is_function_decl(&d);}
10658
10659/// Test whether a declaration is a @ref function_decl.
10660///
10661/// @param d the declaration to test for.
10662///
10663/// @return a shared pointer to @ref function_decl if @p d is a @ref
10664/// function_decl. Otherwise, a nil shared pointer.
10667{return dynamic_pointer_cast<function_decl>(d);}
10668
10669/// Test whether a declaration is a @ref function_decl.
10670///
10671/// @param d the declaration to test for.
10672///
10673/// @return a pointer to @ref function_decl if @p d is a @ref
10674/// function_decl. Otherwise, a nil shared pointer.
10677{
10678 return dynamic_cast<function_decl::parameter*>
10679 (const_cast<type_or_decl_base*>(tod));
10680}
10681
10682/// Test whether an ABI artifact is a @ref function_decl.
10683///
10684/// @param tod the declaration to test for.
10685///
10686/// @return a pointer to @ref function_decl if @p d is a @ref
10687/// function_decl. Otherwise, a nil shared pointer.
10690{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10691
10692/// Test if an ABI artifact is a declaration.
10693///
10694/// @param d the artifact to consider.
10695///
10696/// @param return the declaration sub-object of @p d if it's a
10697/// declaration, or NULL if it is not.
10698decl_base*
10700{
10701 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10702 {
10703 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10704 // The artifact is a decl-only (like a function or a
10705 // variable). That is, it's not a type that also has a
10706 // declaration. In this case, we are in the fast path and we
10707 // have a pointer to the decl sub-object handy. Just return
10708 // it ...
10709 return reinterpret_cast<decl_base*>
10710 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10711
10712 // ... Otherwise, we are in the slow path, which is that the
10713 // artifact is a type which has a declaration. In that case,
10714 // let's use the slow dynamic_cast because we don't have the
10715 // pointer to the decl sub-object handily present.
10716 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10717 }
10718 return 0;
10719}
10720
10721/// Test if an ABI artifact is a declaration.
10722///
10723/// @param d the artifact to consider.
10724///
10725/// @param return the declaration sub-object of @p d if it's a
10726/// declaration, or NULL if it is not.
10727decl_base_sptr
10729{return dynamic_pointer_cast<decl_base>(d);}
10730
10731/// Test if an ABI artifact is a declaration.
10732///
10733/// This is done using a slow path that uses dynamic_cast.
10734///
10735/// @param d the artifact to consider.
10736///
10737/// @param return the declaration sub-object of @p d if it's a
10738decl_base*
10740{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10741
10742/// Test if an ABI artifact is a declaration.
10743///
10744/// This is done using a slow path that uses dynamic_cast.
10745///
10746/// @param d the artifact to consider.
10747///
10748/// @param return the declaration sub-object of @p d if it's a
10749decl_base_sptr
10751{return dynamic_pointer_cast<decl_base>(t);}
10752
10753/// Test whether a declaration is a type.
10754///
10755/// @param d the IR artefact to test for.
10756///
10757/// @return true if the artifact is a type, false otherwise.
10758bool
10760{
10761 if (dynamic_cast<const type_base*>(&tod))
10762 return true;
10763 return false;
10764}
10765
10766/// Test whether a declaration is a type.
10767///
10768/// @param d the IR artefact to test for.
10769///
10770/// @return true if the artifact is a type, false otherwise.
10771type_base*
10773{
10774 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10775 return reinterpret_cast<type_base*>
10776 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10777
10778 return 0;
10779}
10780
10781/// Test whether a declaration is a type.
10782///
10783/// @param d the IR artefact to test for.
10784///
10785/// @return true if the artifact is a type, false otherwise.
10786type_base_sptr
10788{return dynamic_pointer_cast<type_base>(tod);}
10789
10790/// Test whether a declaration is a type.
10791///
10792/// @param d the declaration to test for.
10793///
10794/// @return true if the declaration is a type, false otherwise.
10795
10796/// Test if a given type is anonymous.
10797///
10798/// Note that this function considers that an anonymous class that is
10799/// named by a typedef is not anonymous anymore. This is the C idiom:
10800///
10801/// typedef struct {int member;} s_type;
10802///
10803/// The typedef s_type becomes the name of the originally anonymous
10804/// struct.
10805///
10806/// @param t the type to consider.
10807///
10808/// @return true iff @p t is anonymous.
10809bool
10811{
10812 const decl_base* d = get_type_declaration(t);
10813 if (d)
10814 if (d->get_is_anonymous())
10815 {
10817 {
10818 // An anonymous class that is named by a typedef is not
10819 // considered anonymous anymore.
10820 if (!cou->get_naming_typedef())
10821 return true;
10822 }
10823 else
10824 return true;
10825 }
10826 return false;
10827}
10828
10829/// Test if a given type is anonymous.
10830///
10831/// @param t the type to consider.
10832///
10833/// @return true iff @p t is anonymous.
10834bool
10835is_anonymous_type(const type_base_sptr& t)
10836{return is_anonymous_type(t.get());}
10837
10838/// Test if a type is a neither a pointer, an array nor a function
10839/// type.
10840///
10841/// @param t the type to consider.
10842///
10843/// @return true if the @p t is NOT a pointer, an array nor a
10844/// function.
10845bool
10846is_npaf_type(const type_base_sptr& t)
10847{
10848 if (!(is_pointer_type(t)
10849 || is_array_type(t)
10850 || is_function_type(t)
10851 || is_ptr_to_mbr_type(t)))
10852 return true;
10853 return false;
10854}
10855
10856/// Test whether a type is a type_decl (a builtin type).
10857///
10858/// @return the type_decl* for @t if it's type_decl, otherwise, return
10859/// nil.
10860const type_decl*
10862{return dynamic_cast<const type_decl*>(t);}
10863
10864/// Test whether a type is a type_decl (a builtin type).
10865///
10866/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10867/// return nil.
10870{return dynamic_pointer_cast<type_decl>(t);}
10871
10872/// Test if a type is a real type.
10873///
10874/// @param t the type to test.
10875///
10876/// @return the real type @p t can be converted to, or nil if @p
10877/// is not a real type.
10878type_decl*
10880{
10881 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10882 if (!type)
10883 return nullptr;
10884
10885 real_type int_type;
10886 if (!parse_real_type(type->get_name(), int_type))
10887 return nullptr;
10888
10889 return type;
10890}
10891
10892/// Test if a type is a real type.
10893///
10894/// @param t the type to test.
10895///
10896/// @return the real type @p t can be converted to, or nil if @p is
10897/// not a real type.
10900{
10901 const type_decl_sptr type = is_type_decl(t);
10902 if (!type)
10903 return type_decl_sptr();
10904
10905 real_type int_type;
10906 if (!parse_real_type(type->get_name(), int_type))
10907 return type_decl_sptr();
10908
10909 return type;
10910}
10911
10912/// Test if a type is an integral type.
10913///
10914/// @param t the type to test.
10915///
10916/// @return the integral type @p t can be converted to, or nil if @p
10917/// is not an integral type.
10918type_decl*
10920{
10921 type_decl* type = is_real_type(t);
10922 if (!type)
10923 return nullptr;
10924
10925 real_type rt;
10926 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10929 return nullptr;
10930
10931 return type;
10932}
10933
10934/// Test if a type is an integral type.
10935///
10936/// @param t the type to test.
10937///
10938/// @return the integral type @p t can be converted to, or nil if @p
10939/// is not an integral type.
10942{
10943 type_decl_sptr type = is_real_type(t);
10944 if (!type)
10945 return type;
10946
10947 real_type rt;
10948 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10951 return type_decl_sptr();
10952
10953 return type;
10954}
10955
10956/// Test whether a type is a typedef.
10957///
10958/// @param t the type to test for.
10959///
10960/// @return the typedef declaration of the @p t, or NULL if it's not a
10961/// typedef.
10964{return dynamic_pointer_cast<typedef_decl>(t);}
10965
10966/// Test whether a type is a typedef.
10967///
10968/// @param t the declaration of the type to test for.
10969///
10970/// @return the typedef declaration of the @p t, or NULL if it's not a
10971/// typedef.
10972const typedef_decl*
10974{return dynamic_cast<const typedef_decl*>(t);}
10975
10976/// Test whether a type is a typedef.
10977///
10978/// @param t the declaration of the type to test for.
10979///
10980/// @return the typedef declaration of the @p t, or NULL if it's not a
10981/// typedef.
10984{return dynamic_cast<typedef_decl*>(t);}
10985
10986/// Test whether a type is a typedef.
10987///
10988/// @param t the declaration of the type to test for.
10989///
10990/// @return the typedef declaration of the @p t, or NULL if it's not a
10991/// typedef.
10992const typedef_decl*
10994{return dynamic_cast<const typedef_decl*>(t);}
10995/// Test if a type is an enum. This function looks through typedefs.
10996///
10997/// @parm t the type to consider.
10998///
10999/// @return the enum_decl if @p t is an @ref enum_decl or null
11000/// otherwise.
11002is_compatible_with_enum_type(const type_base_sptr& t)
11003{
11004 if (!t)
11005 return enum_type_decl_sptr();
11006
11007 // Normally we should strip typedefs entirely, but this is
11008 // potentially costly, especially on binaries with huge changesets
11009 // like the Linux Kernel. So we just get the leaf types for now.
11010 //
11011 // Maybe there should be an option by which users accepts to pay the
11012 // CPU usage toll in exchange for finer filtering?
11013
11014 // type_base_sptr ty = strip_typedef(t);
11015 type_base_sptr ty = peel_typedef_type(t);;
11016 return is_enum_type(ty);
11017}
11018
11019/// Test if a type is an enum. This function looks through typedefs.
11020///
11021/// @parm t the type to consider.
11022///
11023/// @return the enum_decl if @p t is an @ref enum_decl or null
11024/// otherwise.
11026is_compatible_with_enum_type(const decl_base_sptr& t)
11028
11029/// Test if a decl is an enum_type_decl
11030///
11031/// @param d the decl to test for.
11032///
11033/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
11034const enum_type_decl*
11036{return dynamic_cast<const enum_type_decl*>(d);}
11037
11038/// Test if a decl is an enum_type_decl
11039///
11040/// @param d the decl to test for.
11041///
11042/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
11045{return dynamic_pointer_cast<enum_type_decl>(d);}
11046
11047/// Test if a type is a class. This function looks through typedefs.
11048///
11049/// @parm t the type to consider.
11050///
11051/// @return the class_decl if @p t is a class_decl or null otherwise.
11053is_compatible_with_class_type(const type_base_sptr& t)
11054{
11055 if (!t)
11056 return class_decl_sptr();
11057
11058 // Normally we should strip typedefs entirely, but this is
11059 // potentially costly, especially on binaries with huge changesets
11060 // like the Linux Kernel. So we just get the leaf types for now.
11061 //
11062 // Maybe there should be an option by which users accepts to pay the
11063 // CPU usage toll in exchange for finer filtering?
11064
11065 // type_base_sptr ty = strip_typedef(t);
11066 type_base_sptr ty = peel_typedef_type(t);
11067 return is_class_type(ty);
11068}
11069
11070/// Test if a type is a class. This function looks through typedefs.
11071///
11072/// @parm t the type to consider.
11073///
11074/// @return the class_decl if @p t is a class_decl or null otherwise.
11076is_compatible_with_class_type(const decl_base_sptr& t)
11078
11079/// Test whether a type is a class.
11080///
11081/// @parm t the type to consider.
11082///
11083/// @return true iff @p t is a class_decl.
11084bool
11086{return is_class_type(&t);}
11087
11088/// Test whether a type is a class.
11089///
11090/// @parm t the type to consider.
11091///
11092/// @return the class_decl if @p t is a class_decl or null otherwise.
11095{
11096 if (!t)
11097 return 0;
11098
11099 if (t->kind() & type_or_decl_base::CLASS_TYPE)
11100 return reinterpret_cast<class_decl*>
11101 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
11102
11103 return 0;
11104}
11105
11106/// Test whether a type is a class.
11107///
11108/// @parm t the type to consider.
11109///
11110/// @return the class_decl if @p t is a class_decl or null otherwise.
11113{return dynamic_pointer_cast<class_decl>(d);}
11114
11115/// Test if the last data member of a class is an array with
11116/// non-finite data member.
11117///
11118/// The flexible data member idiom is a well known C idiom:
11119/// https://en.wikipedia.org/wiki/Flexible_array_member.
11120///
11121/// @param klass the class to consider.
11122///
11123/// @return the data member which type is a flexible array, if any, or
11124/// nil.
11127{
11128 var_decl_sptr nil;
11130 if (dms.empty())
11131 return nil;
11132
11133 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11134 {// The type of the last data member is an array.
11135 if (array->is_non_finite())
11136 // The array has a non-finite size. We are thus looking at a
11137 // flexible array data member. Let's return it.
11138 return dms.back();
11139 }
11140
11141 return nil;
11142}
11143
11144/// Test if the last data member of a class is an array with
11145/// non-finite data member.
11146///
11147/// The flexible data member idiom is a well known C idiom:
11148/// https://en.wikipedia.org/wiki/Flexible_array_member.
11149///
11150/// @param klass the class to consider.
11151///
11152/// @return the data member which type is a flexible array, if any, or
11153/// nil.
11156{
11157 if (!klass)
11158 return var_decl_sptr();
11159
11160 return has_flexible_array_data_member(*klass);
11161}
11162
11163/// Test if the last data member of a class is an array with
11164/// non-finite data member.
11165///
11166/// The flexible data member idiom is a well known C idiom:
11167/// https://en.wikipedia.org/wiki/Flexible_array_member.
11168///
11169/// @param klass the class to consider.
11170///
11171/// @return the data member which type is a flexible array, if any, or
11172/// nil.
11175{return has_flexible_array_data_member(klass.get());}
11176
11177/// Test if the last data member of a class is an array with
11178/// one element.
11179///
11180/// An array with one element is a way to mimic the flexible data
11181/// member idiom that was later standardized in C99.
11182///
11183/// To learn more about the flexible data member idiom, please
11184/// consider reading :
11185/// https://en.wikipedia.org/wiki/Flexible_array_member.
11186///
11187/// The various ways of representing that idiom pre-standardization
11188/// are presented in this article:
11189/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11190///
11191/// @param klass the class to consider.
11192///
11193/// @return the data member which type is a fake flexible array, if
11194/// any, or nil.
11197{
11198 var_decl_sptr nil;
11200 if (dms.empty())
11201 return nil;
11202
11203 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11204 {// The type of the last data member is an array.
11205 if (array->get_subranges().size() == 1
11206 && array->get_subranges()[0]->get_length() == 1)
11207 // The array has a size of one. We are thus looking at a
11208 // "fake" flexible array data member. Let's return it.
11209 return dms.back();
11210 }
11211
11212 return nil;
11213}
11214
11215/// Test if the last data member of a class is an array with
11216/// one element.
11217///
11218/// An array with one element is a way to mimic the flexible data
11219/// member idiom that was later standardized in C99.
11220///
11221/// To learn more about the flexible data member idiom, please
11222/// consider reading :
11223/// https://en.wikipedia.org/wiki/Flexible_array_member.
11224///
11225/// The various ways of representing that idiom pre-standardization
11226/// are presented in this article:
11227/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11228///
11229/// @param klass the class to consider.
11230///
11231/// @return the data member which type is a fake flexible array, if
11232/// any, or nil.
11236
11237/// Test if the last data member of a class is an array with
11238/// one element.
11239///
11240/// An array with one element is a way to mimic the flexible data
11241/// member idiom that was later standardized in C99.
11242///
11243/// To learn more about the flexible data member idiom, please
11244/// consider reading :
11245/// https://en.wikipedia.org/wiki/Flexible_array_member.
11246///
11247/// The various ways of representing that idiom pre-standardization
11248/// are presented in this article:
11249/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11250///
11251/// @param klass the class to consider.
11252///
11253/// @return the data member which type is a fake flexible array, if
11254/// any, or nil.
11257{return has_fake_flexible_array_data_member(klass.get());}
11258
11259/// Test wheter a type is a declaration-only class.
11260///
11261/// @param t the type to considier.
11262///
11263/// @param look_through_decl_only if true, then look through the
11264/// decl-only class to see if it actually has a class definition in
11265/// the same ABI corpus.
11266///
11267/// @return true iff @p t is a declaration-only class.
11268bool
11271{
11272 if (class_or_union *klass = is_class_or_union_type(t))
11273 {
11275 klass = look_through_decl_only_class(klass);
11276 return klass->get_is_declaration_only();
11277 }
11278 return false;
11279}
11280
11281/// Test wheter a type is a declaration-only class.
11282///
11283/// @param t the type to considier.
11284///
11285/// @param look_through_decl_only if true, then look through the
11286/// decl-only class to see if it actually has a class definition in
11287/// the same ABI corpus.
11288///
11289/// @return true iff @p t is a declaration-only class.
11290bool
11294
11295/// Test wheter a type is a declaration-only class.
11296///
11297/// @param t the type to considier.
11298///
11299/// @param look_through_decl_only if true, then look through the
11300/// decl-only class to see if it actually has a class definition in
11301/// the same ABI corpus.
11302///
11303/// @return true iff @p t is a declaration-only class.
11304bool
11305is_declaration_only_class_type(const type_base_sptr& t,
11308
11309/// Test if a type is a @ref class_or_union.
11310///
11311/// @param t the type to consider.
11312///
11313/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11314/// nil otherwise.
11317{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
11318
11319/// Test if a type is a @ref class_or_union.
11320///
11321/// @param t the type to consider.
11322///
11323/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11324/// nil otherwise.
11325shared_ptr<class_or_union>
11326is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
11327{return dynamic_pointer_cast<class_or_union>(t);}
11328
11329/// Test if two class or union types are of the same kind.
11330///
11331/// @param first the first type to consider.
11332///
11333/// @param second the second type to consider.
11334///
11335/// @return true iff @p first is of the same kind as @p second.
11336bool
11338 const class_or_union* second)
11339{
11340 if ((is_class_type(first) && is_class_type(second))
11341 || (is_union_type(first) && is_union_type(second)))
11342 return true;
11343
11344 return false;
11345}
11346
11347/// Test if two class or union types are of the same kind.
11348///
11349/// @param first the first type to consider.
11350///
11351/// @param second the second type to consider.
11352///
11353/// @return true iff @p first is of the same kind as @p second.
11354bool
11355class_or_union_types_of_same_kind(const class_or_union_sptr& first,
11356 const class_or_union_sptr& second)
11357{return class_or_union_types_of_same_kind(first.get(), second.get());}
11358
11359/// Test if a type is a @ref union_decl.
11360///
11361/// @param t the type to consider.
11362///
11363/// @return true iff @p t is a union_decl.
11364bool
11366{return is_union_type(&t);}
11367
11368/// Test if a type is a @ref union_decl.
11369///
11370/// @param t the type to consider.
11371///
11372/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11373/// otherwise.
11376{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
11377
11378/// Test if a type is a @ref union_decl.
11379///
11380/// @param t the type to consider.
11381///
11382/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11383/// otherwise.
11384union_decl_sptr
11385is_union_type(const shared_ptr<type_or_decl_base>& t)
11386{return dynamic_pointer_cast<union_decl>(t);}
11387
11388/// Test whether a type is a pointer_type_def.
11389///
11390/// @param t the type to test.
11391///
11392/// @param look_through_decl_only if this is true, then look through
11393/// qualified types to see if the underlying type is a
11394/// pointer_type_def.
11395///
11396/// @return the @ref pointer_type_def_sptr if @p t is a
11397/// pointer_type_def, null otherwise.
11398const pointer_type_def*
11400 bool look_through_qualifiers)
11401{
11402 if (!t)
11403 return 0;
11404
11405 const type_base* type = is_type(t);
11406 if (look_through_qualifiers)
11407 type = peel_qualified_type(is_type(t));
11408
11409 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11410}
11411
11412/// Test whether a type is a pointer_type_def.
11413///
11414/// @param t the type to test.
11415///
11416/// @param look_through_decl_only if this is true, then look through
11417/// qualified types to see if the underlying type is a
11418/// pointer_type_def.
11419///
11420/// @return the @ref pointer_type_def_sptr if @p t is a
11421/// pointer_type_def, null otherwise.
11424 bool look_through_qualifiers)
11425{
11426 type_base_sptr type = is_type(t);
11427 if (look_through_qualifiers)
11428 type = peel_qualified_type(type);
11429 return dynamic_pointer_cast<pointer_type_def>(type);
11430}
11431
11432/// Test if a type is a pointer to function type.
11433///
11434/// @param t the type to consider.
11435///
11436/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11437/// function type.
11439is_pointer_to_function_type(const type_base_sptr& t)
11440{
11442 {
11443 if (is_function_type(p->get_pointed_to_type()))
11444 return p;
11445 }
11446 return pointer_type_def_sptr();
11447}
11448
11449/// Test if a type is a pointer to array type.
11450///
11451/// @param t the type to consider.
11452///
11453/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11454/// type.
11456is_pointer_to_array_type(const type_base_sptr& t)
11457{
11459 {
11460 if (is_array_type(p->get_pointed_to_type()))
11461 return p;
11462 }
11463 return pointer_type_def_sptr();
11464}
11465
11466/// Test if we are looking at a pointer to a
11467/// neither-a-pointer-to-an-array-nor-a-function type.
11468///
11469/// @param t the type to consider.
11470///
11471/// @return the @ref pointer_type_def_sptr type iff @p t is a
11472/// neither-a-pointer-an-array-nor-a-function type.
11474is_pointer_to_npaf_type(const type_base_sptr& t)
11475{
11477 {
11478 if (is_npaf_type(p->get_pointed_to_type()))
11479 return p;
11480 }
11481 return pointer_type_def_sptr();
11482}
11483
11484/// Test if we are looking at a pointer to pointer to member type.
11485///
11486/// @param t the type to consider.
11487///
11488/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11489/// to pointer to member type.
11491is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11492{
11494 {
11495 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11496 return p;
11497 }
11498 return pointer_type_def_sptr();
11499}
11500
11501/// Test if a type is a typedef, pointer or reference to a decl-only
11502/// class/union.
11503///
11504/// This looks into qualified types too.
11505///
11506/// @param t the type to consider.
11507///
11508/// @return true iff @p t is a type is a typedef, pointer or reference
11509/// to a decl-only class/union.
11510bool
11512{
11513 const type_base * type =
11514 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11515
11517 /*look_through_decl_only=*/true))
11518 return true;
11519
11520 return false;
11521}
11522
11523/// Test if a type is a typedef of a class or union type, or a typedef
11524/// of a qualified class or union type.
11525///
11526/// Note that if the type is directly a class or union type, the
11527/// function returns true as well.
11528///
11529/// @param t the type to consider.
11530///
11531/// @return true iff @p t is a typedef of a class or union type, or a
11532/// typedef of a qualified class or union type.
11533bool
11535{
11536 if (!t)
11537 return false;
11538
11541 return true;
11542
11543return false;
11544}
11545
11546/// Test if a type is a typedef of a class or union type, or a typedef
11547/// of a qualified class or union type.
11548///
11549/// Note that if the type is directly a class or union type, the
11550/// function returns true as well.
11551///
11552/// @param t the type to consider.
11553///
11554/// @return true iff @p t is a typedef of a class or union type, or a
11555/// typedef of a qualified class or union type.
11556bool
11559
11560/// Test whether a type is a reference_type_def.
11561///
11562/// @param t the type to test.
11563///
11564/// @param look_through_decl_only if this is true, then look through
11565/// qualified types to see if the underlying type is a
11566/// reference_type_def.
11567///
11568/// @return the @ref reference_type_def_sptr if @p t is a
11569/// reference_type_def, null otherwise.
11572 bool look_through_qualifiers)
11573{
11574 const type_base* type = is_type(t);
11575 if (!type)
11576 return nullptr;
11577
11578 if (look_through_qualifiers)
11579 type = peel_qualified_type(type);
11580 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11581}
11582
11583/// Test whether a type is a reference_type_def.
11584///
11585/// @param t the type to test.
11586///
11587/// @param look_through_decl_only if this is true, then look through
11588/// qualified types to see if the underlying type is a
11589/// reference_type_def.
11590///
11591/// @return the @ref reference_type_def_sptr if @p t is a
11592/// reference_type_def, null otherwise.
11593const reference_type_def*
11595 bool look_through_qualifiers)
11596{
11597 const type_base* type = is_type(t);
11598
11599 if (look_through_qualifiers)
11600 type = peel_qualified_type(type);
11601 return dynamic_cast<const reference_type_def*>(type);
11602}
11603
11604/// Test whether a type is a reference_type_def.
11605///
11606/// @param t the type to test.
11607///
11608/// @param look_through_decl_only if this is true, then look through
11609/// qualified types to see if the underlying type is a
11610/// reference_type_def.
11611///
11612/// @return the @ref reference_type_def_sptr if @p t is a
11613/// reference_type_def, null otherwise.
11616 bool look_through_qualifiers)
11617{
11618 type_base_sptr type = is_type(t);
11619 if (look_through_qualifiers)
11620 type = peel_qualified_type(type);
11621 return dynamic_pointer_cast<reference_type_def>(type);
11622}
11623
11624/// Test whether a type is a @ref ptr_to_mbr_type.
11625///
11626/// @param t the type to test.
11627///
11628/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11629/// ptr_to_mbr_type type, null otherwise.
11630const ptr_to_mbr_type*
11632 bool look_through_qualifiers)
11633{
11634 const type_base* type = is_type(t);
11635 if (look_through_qualifiers)
11636 type = peel_qualified_type(type);
11637 return dynamic_cast<const ptr_to_mbr_type*>(type);
11638}
11639
11640/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11641///
11642/// @param t the type to test.
11643///
11644/// @param look_through_decl_only if this is true, then look through
11645/// qualified types to see if the underlying type is a
11646/// ptr_to_mbr_type..
11647///
11648/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11649/// ptr_to_mbr_type type, null otherwise.
11652 bool look_through_qualifiers)
11653{
11654 type_base_sptr type = is_type(t);
11655 if (look_through_qualifiers)
11656 type = peel_qualified_type(type);
11657 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11658}
11659
11660/// Test if a type is equivalent to a pointer to void type.
11661///
11662/// Note that this looks trough typedefs or CV qualifiers to look for
11663/// the void pointer.
11664///
11665/// @param type the type to consider.
11666///
11667/// @return the actual void pointer if @p is eqivalent to a void
11668/// pointer or NULL if it's not.
11669const type_base*
11671{
11672 type = peel_qualified_or_typedef_type(type);
11673
11674 const pointer_type_def * t = is_pointer_type(type);
11675 if (!t)
11676 return 0;
11677
11678 // Look through typedefs in the pointed-to type as well.
11679 type_base * ty = t->get_pointed_to_type().get();
11681 if (ty && ty->get_environment().is_void_type(ty))
11682 return ty;
11683
11684 return 0;
11685}
11686
11687/// Test if a type is equivalent to a pointer to void type.
11688///
11689/// Note that this looks trough typedefs or CV qualifiers to look for
11690/// the void pointer.
11691///
11692/// @param type the type to consider.
11693///
11694/// @return the actual void pointer if @p is eqivalent to a void
11695/// pointer or NULL if it's not.
11696const type_base*
11698{return is_void_pointer_type_equivalent(&type);}
11699
11700/// Test if a type is a pointer to void type.
11701///
11702/// @param type the type to consider.
11703///
11704/// @return the actual void pointer if @p is a void pointer or NULL if
11705/// it's not.
11706const type_base*
11708{
11709 if (!t)
11710 return nullptr;
11711
11712 if (t->get_environment().get_void_pointer_type().get() == t)
11713 return t;
11714
11715 const pointer_type_def* ptr = is_pointer_type(t);
11716 if (!ptr)
11717 return nullptr;
11718
11720 return t;
11721
11722 return nullptr;
11723}
11724
11725/// Test if a type is a pointer to void type.
11726///
11727/// @param type the type to consider.
11728///
11729/// @return the actual void pointer if @p is a void pointer or NULL if
11730/// it's not.
11731const type_base_sptr
11732is_void_pointer_type(const type_base_sptr& t)
11733{
11734 type_base_sptr nil;
11735 if (!t)
11736 return nil;
11737
11738 if (t->get_environment().get_void_pointer_type().get() == t.get())
11739 return t;
11740
11741 const pointer_type_def* ptr = is_pointer_type(t.get());
11742 if (!ptr)
11743 return nil;
11744
11745 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11746 return t;
11747
11748 return nil;
11749}
11750
11751/// Test whether a type is a reference_type_def.
11752///
11753/// @param t the type to test.
11754///
11755/// @return the @ref reference_type_def_sptr if @p t is a
11756/// reference_type_def, null otherwise.
11759{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11760
11761/// Test whether a type is a qualified_type_def.
11762///
11763/// @param t the type to test.
11764///
11765/// @return the @ref qualified_type_def_sptr if @p t is a
11766/// qualified_type_def, null otherwise.
11767qualified_type_def_sptr
11769{return dynamic_pointer_cast<qualified_type_def>(t);}
11770
11771/// Test whether a type is a function_type.
11772///
11773/// @param t the type to test.
11774///
11775/// @return the @ref function_type_sptr if @p t is a
11776/// function_type, null otherwise.
11779{return dynamic_pointer_cast<function_type>(t);}
11780
11781/// Test whether a type is a function_type.
11782///
11783/// @param t the type to test.
11784///
11785/// @return the @ref function_type_sptr if @p t is a
11786/// function_type, null otherwise.
11789{return dynamic_cast<function_type*>(t);}
11790
11791/// Test whether a type is a function_type.
11792///
11793/// @param t the type to test.
11794///
11795/// @return the @ref function_type_sptr if @p t is a
11796/// function_type, null otherwise.
11797const function_type*
11799{return dynamic_cast<const function_type*>(t);}
11800
11801/// Test whether a type is a method_type.
11802///
11803/// @param t the type to test.
11804///
11805/// @return the @ref method_type_sptr if @p t is a
11806/// method_type, null otherwise.
11809{return dynamic_pointer_cast<method_type>(t);}
11810
11811/// Test whether a type is a method_type.
11812///
11813/// @param t the type to test.
11814///
11815/// @return the @ref method_type_sptr if @p t is a
11816/// method_type, null otherwise.
11817const method_type*
11819{return dynamic_cast<const method_type*>(t);}
11820
11821/// Test whether a type is a method_type.
11822///
11823/// @param t the type to test.
11824///
11825/// @return the @ref method_type_sptr if @p t is a
11826/// method_type, null otherwise.
11829{return dynamic_cast<method_type*>(t);}
11830
11831/// If a class (or union) is a decl-only class, get its definition.
11832/// Otherwise, just return the initial class.
11833///
11834/// @param the_class the class (or union) to consider.
11835///
11836/// @return either the definition of the class, or the class itself.
11840
11841/// If a class (or union) is a decl-only class, get its definition.
11842/// Otherwise, just return the initial class.
11843///
11844/// @param the_class the class (or union) to consider.
11845///
11846/// @return either the definition of the class, or the class itself.
11847class_or_union_sptr
11850
11851/// If a class (or union) is a decl-only class, get its definition.
11852/// Otherwise, just return the initial class.
11853///
11854/// @param klass the class (or union) to consider.
11855///
11856/// @return either the definition of the class, or the class itself.
11857class_or_union_sptr
11858look_through_decl_only_class(class_or_union_sptr klass)
11860
11861/// If an enum is a decl-only enum, get its definition.
11862/// Otherwise, just return the initial enum.
11863///
11864/// @param the_enum the enum to consider.
11865///
11866/// @return either the definition of the enum, or the enum itself.
11869{return is_enum_type(look_through_decl_only(the_enum));}
11870
11871/// If an enum is a decl-only enum, get its definition.
11872/// Otherwise, just return the initial enum.
11873///
11874/// @param enom the enum to consider.
11875///
11876/// @return either the definition of the enum, or the enum itself.
11879{return is_enum_type(look_through_decl_only(enom));}
11880
11881/// If a decl is decl-only get its definition. Otherwise, just return nil.
11882///
11883/// @param d the decl to consider.
11884///
11885/// @return either the definition of the decl, or nil.
11886decl_base_sptr
11888{
11889 decl_base_sptr decl;
11892
11893 if (!decl)
11894 return decl;
11895
11896 while (decl->get_is_declaration_only()
11897 && decl->get_definition_of_declaration())
11898 decl = decl->get_definition_of_declaration();
11899
11900 return decl;
11901}
11902
11903/// If a decl is decl-only enum, get its definition. Otherwise, just
11904/// return the initial decl.
11905///
11906/// @param d the decl to consider.
11907///
11908/// @return either the definition of the enum, or the decl itself.
11909decl_base*
11911{
11912 if (!d)
11913 return d;
11914
11915 decl_base* result = look_through_decl_only(*d).get();
11916 if (!result)
11917 result = d;
11918
11919 return result;
11920}
11921
11922/// If a decl is decl-only get its definition. Otherwise, just return nil.
11923///
11924/// @param d the decl to consider.
11925///
11926/// @return either the definition of the decl, or nil.
11927decl_base_sptr
11928look_through_decl_only(const decl_base_sptr& d)
11929{
11930 if (!d)
11931 return d;
11932
11933 decl_base_sptr result = look_through_decl_only(*d);
11934 if (!result)
11935 result = d;
11936
11937 return result;
11938}
11939
11940/// If a type is is decl-only, then get its definition. Otherwise,
11941/// just return the initial type.
11942///
11943/// @param d the decl to consider.
11944///
11945/// @return either the definition of the decl, or the initial type.
11946type_base*
11948{
11949 decl_base* d = is_decl(t);
11950 if (!d)
11951 return t;
11953 return is_type(d);
11954}
11955
11956/// If a type is is decl-only, then get its definition. Otherwise,
11957/// just return the initial type.
11958///
11959/// @param d the decl to consider.
11960///
11961/// @return either the definition of the decl, or the initial type.
11962type_base_sptr
11963look_through_decl_only_type(const type_base_sptr& t)
11964{
11965 decl_base_sptr d = is_decl(t);
11966 if (!d)
11967 return t;
11969 return is_type(d);
11970}
11971
11972/// Tests if a declaration is a variable declaration.
11973///
11974/// @param decl the decl to test.
11975///
11976/// @return the var_decl_sptr iff decl is a variable declaration; nil
11977/// otherwise.
11978var_decl*
11980{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
11981
11982/// Tests if a declaration is a variable declaration.
11983///
11984/// @param decl the decl to test.
11985///
11986/// @return the var_decl_sptr iff decl is a variable declaration; nil
11987/// otherwise.
11990{return dynamic_pointer_cast<var_decl>(decl);}
11991
11992/// Tests if a declaration is a namespace declaration.
11993///
11994/// @param d the decalration to consider.
11995///
11996/// @return the namespace declaration if @p d is a namespace.
11998is_namespace(const decl_base_sptr& d)
11999{return dynamic_pointer_cast<namespace_decl>(d);}
12000
12001/// Tests if a declaration is a namespace declaration.
12002///
12003/// @param d the decalration to consider.
12004///
12005/// @return the namespace declaration if @p d is a namespace.
12008{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
12009
12010/// Tests whether a decl is a template parameter composition type.
12011///
12012/// @param decl the declaration to consider.
12013///
12014/// @return true iff decl is a template parameter composition type.
12015bool
12016is_template_parm_composition_type(const shared_ptr<decl_base> decl)
12017{
12018 return (decl
12019 && is_at_template_scope(decl)
12020 && is_type(decl)
12021 && !is_template_parameter(decl));
12022}
12023
12024/// Test whether a decl is the pattern of a function template.
12025///
12026/// @param decl the decl to consider.
12027///
12028/// @return true iff decl is the pattern of a function template.
12029bool
12030is_function_template_pattern(const shared_ptr<decl_base> decl)
12031{
12032 return (decl
12033 && dynamic_pointer_cast<function_decl>(decl)
12034 && dynamic_cast<template_decl*>(decl->get_scope()));
12035}
12036
12037/// Test if a type is an array_type_def.
12038///
12039/// @param type the type to consider.
12040///
12041/// @return true iff @p type is an array_type_def.
12044 bool look_through_qualifiers)
12045{
12046 const type_base* t = is_type(type);
12047
12048 if (look_through_qualifiers)
12049 t = peel_qualified_type(t);
12050 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
12051}
12052
12053/// Test if a type is an array_type_def.
12054///
12055/// @param type the type to consider.
12056///
12057/// @return true iff @p type is an array_type_def.
12060 bool look_through_qualifiers)
12061{
12062 type_base_sptr t = is_type(type);
12063
12064 if (look_through_qualifiers)
12065 t = peel_qualified_type(t);
12066 return dynamic_pointer_cast<array_type_def>(t);
12067}
12068
12069/// Tests if the element of a given array is a qualified type.
12070///
12071/// @param array the array type to consider.
12072///
12073/// @return the qualified element of the array iff it's a qualified
12074/// type. Otherwise, return a nil object.
12075qualified_type_def_sptr
12077{
12078 if (!array)
12079 return qualified_type_def_sptr();
12080
12081 return is_qualified_type(array->get_element_type());
12082}
12083
12084/// Test if an array type is an array to a qualified element type.
12085///
12086/// @param type the array type to consider.
12087///
12088/// @return true the array @p type iff it's an array to a qualified
12089/// element type.
12091is_array_of_qualified_element(const type_base_sptr& type)
12092{
12093 if (array_type_def_sptr array = is_array_type(type))
12095 return array;
12096
12097 return array_type_def_sptr();
12098}
12099
12100/// Test if a type is a typedef of an array.
12101///
12102/// Note that the function looks through qualified and typedefs types
12103/// of the underlying type of the current typedef. In other words, if
12104/// we are looking at a typedef of a CV-qualified array, or at a
12105/// typedef of a CV-qualified typedef of an array, this function will
12106/// still return TRUE.
12107///
12108/// @param t the type to consider.
12109///
12110/// @return true if t is a typedef which underlying type is an array.
12111/// That array might be either cv-qualified array or a typedef'ed
12112/// array, or a combination of both.
12114is_typedef_of_array(const type_base_sptr& t)
12115{
12116 array_type_def_sptr result;
12117
12118 if (typedef_decl_sptr typdef = is_typedef(t))
12119 {
12120 type_base_sptr u =
12121 peel_qualified_or_typedef_type(typdef->get_underlying_type());
12122 result = is_array_type(u);
12123 }
12124
12125 return result;
12126}
12127
12128/// Test if a type is an array_type_def::subrange_type.
12129///
12130/// @param type the type to consider.
12131///
12132/// @return the array_type_def::subrange_type which @p type is a type
12133/// of, or nil if it's not of that type.
12136{
12137 return dynamic_cast<array_type_def::subrange_type*>
12138 (const_cast<type_or_decl_base*>(type));
12139}
12140
12141/// Test if a type is an array_type_def::subrange_type.
12142///
12143/// @param type the type to consider.
12144///
12145/// @return the array_type_def::subrange_type which @p type is a type
12146/// of, or nil if it's not of that type.
12149{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
12150
12151/// Tests whether a decl is a template.
12152///
12153/// @param decl the decl to consider.
12154///
12155/// @return true iff decl is a function template, class template, or
12156/// template template parameter.
12157bool
12158is_template_decl(const decl_base_sptr& decl)
12159{return decl && dynamic_pointer_cast<template_decl>(decl);}
12160
12161/// This enum describe the kind of entity to lookup, while using the
12162/// lookup API.
12164{
12165 LOOKUP_ENTITY_TYPE,
12166 LOOKUP_ENTITY_VAR,
12167};
12168
12169/// Find the first relevant delimiter (the "::" string) in a fully
12170/// qualified C++ type name, starting from a given position. The
12171/// delimiter returned separates a type name from the name of its
12172/// context.
12173///
12174/// This is supposed to work correctly on names in cases like this:
12175///
12176/// foo<ns1::name1, ns2::name2>
12177///
12178/// In that case when called with with parameter @p begin set to 0, no
12179/// delimiter is returned, because the type name in this case is:
12180/// 'foo<ns1::name1, ns2::name2>'.
12181///
12182/// But in this case:
12183///
12184/// foo<p1, bar::name>::some_type
12185///
12186/// The "::" returned is the one right before 'some_type'.
12187///
12188/// @param fqn the fully qualified name of the type to consider.
12189///
12190/// @param begin the position from which to look for the delimiter.
12191///
12192/// @param delim_pos out parameter. Is set to the position of the
12193/// delimiter iff the function returned true.
12194///
12195/// @return true iff the function found and returned the delimiter.
12196static bool
12197find_next_delim_in_cplus_type(const string& fqn,
12198 size_t begin,
12199 size_t& delim_pos)
12200{
12201 int angle_count = 0;
12202 bool found = false;
12203 size_t i = begin;
12204 for (; i < fqn.size(); ++i)
12205 {
12206 if (fqn[i] == '<')
12207 ++angle_count;
12208 else if (fqn[i] == '>')
12209 --angle_count;
12210 else if (i + 1 < fqn.size()
12211 && !angle_count
12212 && fqn[i] == ':'
12213 && fqn[i+1] == ':')
12214 {
12215 delim_pos = i;
12216 found = true;
12217 break;
12218 }
12219 }
12220 return found;
12221}
12222
12223/// Decompose a fully qualified name into the list of its components.
12224///
12225/// @param fqn the fully qualified name to decompose.
12226///
12227/// @param comps the resulting list of component to fill.
12228void
12229fqn_to_components(const string& fqn,
12230 list<string>& comps)
12231{
12232 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
12233 do
12234 {
12235 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
12236 comp_end = fqn_size;
12237
12238 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
12239 comps.push_back(comp);
12240
12241 comp_begin = comp_end + 2;
12242 if (comp_begin >= fqn_size)
12243 break;
12244 } while (true);
12245}
12246
12247/// Turn a set of qualified name components (that name a type) into a
12248/// qualified name string.
12249///
12250/// @param comps the name components
12251///
12252/// @return the resulting string, which would be the qualified name of
12253/// a type.
12254string
12255components_to_type_name(const list<string>& comps)
12256{
12257 string result;
12258 for (list<string>::const_iterator c = comps.begin();
12259 c != comps.end();
12260 ++c)
12261 if (c == comps.begin())
12262 result = *c;
12263 else
12264 result += "::" + *c;
12265 return result;
12266}
12267
12268/// This predicate returns true if a given container iterator points
12269/// to the last element of the container, false otherwise.
12270///
12271/// @tparam T the type of the container of the iterator.
12272///
12273/// @param container the container the iterator points into.
12274///
12275/// @param i the iterator to consider.
12276///
12277/// @return true iff the iterator points to the last element of @p
12278/// container.
12279template<typename T>
12280static bool
12281iterator_is_last(T& container,
12282 typename T::const_iterator i)
12283{
12284 typename T::const_iterator next = i;
12285 ++next;
12286 return (next == container.end());
12287}
12288
12289//--------------------------------
12290// <type and decls lookup stuff>
12291// ------------------------------
12292
12293/// Lookup all the type*s* that have a given fully qualified name.
12294///
12295/// @param type_name the fully qualified name of the type to
12296/// lookup.
12297///
12298/// @param type_map the map to look into.
12299///
12300/// @return the vector containing the types named @p type_name. If
12301/// the lookup didn't yield any type, then this function returns nil.
12302static const type_base_wptrs_type*
12303lookup_types_in_map(const interned_string& type_name,
12304 const istring_type_base_wptrs_map_type& type_map)
12305{
12306 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12307 if (i != type_map.end())
12308 return &i->second;
12309 return 0;
12310}
12311
12312/// Lookup a type (with a given name) in a map that associates a type
12313/// name to a type. If there are several types with a given name,
12314/// then try to return the first one that is not decl-only.
12315/// Otherwise, return the last of such types, that is, the last one
12316/// that got registered.
12317///
12318/// @tparam TypeKind the type of the type this function is supposed to
12319/// return.
12320///
12321/// @param type_name the name of the type to lookup.
12322///
12323/// @param type_map the map in which to look.
12324///
12325/// @return a shared_ptr to the type found. If no type was found or
12326/// if the type found was not of type @p TypeKind then the function
12327/// returns nil.
12328template <class TypeKind>
12329static shared_ptr<TypeKind>
12330lookup_type_in_map(const interned_string& type_name,
12331 const istring_type_base_wptrs_map_type& type_map)
12332{
12333 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12334 if (i != type_map.end())
12335 {
12336 // Walk the types that have the name "type_name" and return the
12337 // first one that is not declaration-only ...
12338 for (auto j : i->second)
12339 {
12340 type_base_sptr t(j);
12341 decl_base_sptr d = is_decl(t);
12342 if (d && !d->get_is_declaration_only())
12343 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12344 }
12345 // ... or return the last type with the name "type_name" that
12346 // was recorded. It's likely to be declaration-only if we
12347 // reached this point.
12348 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12349 }
12350 return shared_ptr<TypeKind>();
12351}
12352
12353/// Lookup a basic type from a translation unit.
12354///
12355/// This is done by looking the type up in the type map that is
12356/// maintained in the translation unit. So this is as fast as
12357/// possible.
12358///
12359/// @param type_name the name of the basic type to look for.
12360///
12361/// @param tu the translation unit to look into.
12362///
12363/// @return the basic type found or nil if no basic type was found.
12366{
12367 return lookup_type_in_map<type_decl>(type_name,
12368 tu.get_types().basic_types());
12369}
12370
12371/// Lookup a basic type from a translation unit.
12372///
12373/// This is done by looking the type up in the type map that is
12374/// maintained in the translation unit. So this is as fast as
12375/// possible.
12376///
12377/// @param type_name the name of the basic type to look for.
12378///
12379/// @param tu the translation unit to look into.
12380///
12381/// @return the basic type found or nil if no basic type was found.
12383lookup_basic_type(const string& type_name, const translation_unit& tu)
12384{
12385 const environment& env = tu.get_environment();
12386
12387 interned_string s = env.intern(type_name);
12388 return lookup_basic_type(s, tu);
12389}
12390
12391/// Lookup a class type from a translation unit.
12392///
12393/// This is done by looking the type up in the type map that is
12394/// maintained in the translation unit. So this is as fast as
12395/// possible.
12396///
12397/// @param fqn the fully qualified name of the class type node to look
12398/// up.
12399///
12400/// @param tu the translation unit to perform lookup from.
12401///
12402/// @return the declaration of the class type IR node found, NULL
12403/// otherwise.
12405lookup_class_type(const string& fqn, const translation_unit& tu)
12406{
12407 const environment& env = tu.get_environment();
12408 interned_string s = env.intern(fqn);
12409 return lookup_class_type(s, tu);
12410}
12411
12412/// Lookup a class type from a translation unit.
12413///
12414/// This is done by looking the type up in the type map that is
12415/// maintained in the translation unit. So this is as fast as
12416/// possible.
12417///
12418/// @param type_name the name of the class type to look for.
12419///
12420/// @param tu the translation unit to look into.
12421///
12422/// @return the class type found or nil if no class type was found.
12425{
12426 return lookup_type_in_map<class_decl>(type_name,
12427 tu.get_types().class_types());
12428}
12429
12430/// Lookup a union type from a translation unit.
12431///
12432/// This is done by looking the type up in the type map that is
12433/// maintained in the translation unit. So this is as fast as
12434/// possible.
12435///
12436/// @param type_name the name of the union type to look for.
12437///
12438/// @param tu the translation unit to look into.
12439///
12440/// @return the union type found or nil if no union type was found.
12441union_decl_sptr
12443{
12444 return lookup_type_in_map<union_decl>(type_name,
12445 tu.get_types().union_types());
12446}
12447
12448/// Lookup a union type from a translation unit.
12449///
12450/// This is done by looking the type up in the type map that is
12451/// maintained in the translation unit. So this is as fast as
12452/// possible.
12453///
12454/// @param fqn the fully qualified name of the type to lookup.
12455///
12456/// @param tu the translation unit to look into.
12457///
12458/// @return the union type found or nil if no union type was found.
12459union_decl_sptr
12460lookup_union_type(const string& fqn, const translation_unit& tu)
12461{
12462 const environment& env = tu.get_environment();
12463 interned_string s = env.intern(fqn);
12464 return lookup_union_type(s, tu);
12465}
12466
12467/// Lookup a union type in a given corpus, from its location.
12468///
12469/// @param loc the location of the union type to look for.
12470///
12471/// @param corp the corpus to look it from.
12472///
12473/// @return the resulting union_decl.
12474union_decl_sptr
12476{
12479 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12480
12481 return result;
12482}
12483
12484/// Lookup a union type in a given corpus, from its location.
12485///
12486/// @param loc the location of the union type to look for.
12487///
12488/// @param corp the corpus to look it from.
12489///
12490/// @return the resulting union_decl.
12491union_decl_sptr
12492lookup_union_type_per_location(const string& loc, const corpus& corp)
12493{
12494 const environment& env = corp.get_environment();
12495 return lookup_union_type_per_location(env.intern(loc), corp);
12496}
12497
12498/// Lookup an enum type from a translation unit.
12499///
12500/// This is done by looking the type up in the type map that is
12501/// maintained in the translation unit. So this is as fast as
12502/// possible.
12503///
12504/// @param type_name the name of the enum type to look for.
12505///
12506/// @param tu the translation unit to look into.
12507///
12508/// @return the enum type found or nil if no enum type was found.
12511{
12512 return lookup_type_in_map<enum_type_decl>(type_name,
12513 tu.get_types().enum_types());
12514}
12515
12516/// Lookup an enum type from a translation unit.
12517///
12518/// This is done by looking the type up in the type map that is
12519/// maintained in the translation unit. So this is as fast as
12520/// possible.
12521///
12522/// @param type_name the name of the enum type to look for.
12523///
12524/// @param tu the translation unit to look into.
12525///
12526/// @return the enum type found or nil if no enum type was found.
12528lookup_enum_type(const string& type_name, const translation_unit& tu)
12529{
12530 const environment& env = tu.get_environment();
12531 interned_string s = env.intern(type_name);
12532 return lookup_enum_type(s, tu);
12533}
12534
12535/// Lookup a typedef type from a translation unit.
12536///
12537/// This is done by looking the type up in the type map that is
12538/// maintained in the translation unit. So this is as fast as
12539/// possible.
12540///
12541/// @param type_name the name of the typedef type to look for.
12542///
12543/// @param tu the translation unit to look into.
12544///
12545/// @return the typedef type found or nil if no typedef type was
12546/// found.
12549 const translation_unit& tu)
12550{
12551 return lookup_type_in_map<typedef_decl>(type_name,
12552 tu.get_types().typedef_types());
12553}
12554
12555/// Lookup a typedef type from a translation unit.
12556///
12557/// This is done by looking the type up in the type map that is
12558/// maintained in the translation unit. So this is as fast as
12559/// possible.
12560///
12561/// @param type_name the name of the typedef type to look for.
12562///
12563/// @param tu the translation unit to look into.
12564///
12565/// @return the typedef type found or nil if no typedef type was
12566/// found.
12568lookup_typedef_type(const string& type_name, const translation_unit& tu)
12569{
12570 const environment& env = tu.get_environment();
12571 interned_string s = env.intern(type_name);
12572 return lookup_typedef_type(s, tu);
12573}
12574
12575/// Lookup a qualified type from a translation unit.
12576///
12577/// This is done by looking the type up in the type map that is
12578/// maintained in the translation unit. So this is as fast as
12579/// possible.
12580///
12581/// @param type_name the name of the qualified type to look for.
12582///
12583/// @param tu the translation unit to look into.
12584///
12585/// @return the qualified type found or nil if no qualified type was
12586/// found.
12587qualified_type_def_sptr
12589 const translation_unit& tu)
12590{
12591 const type_maps& m = tu.get_types();
12592 return lookup_type_in_map<qualified_type_def>(type_name,
12593 m.qualified_types());
12594}
12595
12596/// Lookup a qualified type from a translation unit.
12597///
12598/// This is done by looking the type up in the type map that is
12599/// maintained in the translation unit. So this is as fast as
12600/// possible.
12601///
12602/// @param underlying_type the underying type of the qualified type to
12603/// look up.
12604///
12605/// @param quals the CV-qualifiers of the qualified type to look for.
12606///
12607/// @param tu the translation unit to look into.
12608///
12609/// @return the qualified type found or nil if no qualified type was
12610/// found.
12611qualified_type_def_sptr
12612lookup_qualified_type(const type_base_sptr& underlying_type,
12614 const translation_unit& tu)
12615{
12616 interned_string type_name = get_name_of_qualified_type(underlying_type,
12617 quals);
12618 return lookup_qualified_type(type_name, tu);
12619}
12620
12621/// Lookup a pointer type from a translation unit.
12622///
12623/// This is done by looking the type up in the type map that is
12624/// maintained in the translation unit. So this is as fast as
12625/// possible.
12626///
12627/// @param type_name the name of the pointer type to look for.
12628///
12629/// @param tu the translation unit to look into.
12630///
12631/// @return the pointer type found or nil if no pointer type was
12632/// found.
12635 const translation_unit& tu)
12636{
12637 const type_maps& m = tu.get_types();
12638 return lookup_type_in_map<pointer_type_def>(type_name,
12639 m.pointer_types());
12640}
12641
12642/// Lookup a pointer type from a translation unit.
12643///
12644/// This is done by looking the type up in the type map that is
12645/// maintained in the translation unit. So this is as fast as
12646/// possible.
12647///
12648/// @param type_name the name of the pointer type to look for.
12649///
12650/// @param tu the translation unit to look into.
12651///
12652/// @return the pointer type found or nil if no pointer type was
12653/// found.
12655lookup_pointer_type(const string& type_name, const translation_unit& tu)
12656{
12657 const environment& env = tu.get_environment();
12658 interned_string s = env.intern(type_name);
12659 return lookup_pointer_type(s, tu);
12660}
12661
12662/// Lookup a pointer type from a translation unit.
12663///
12664/// This is done by looking the type up in the type map that is
12665/// maintained in the translation unit. So this is as fast as
12666/// possible.
12667///
12668/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12669///
12670/// @param tu the translation unit to look into.
12671///
12672/// @return the pointer type found or nil if no pointer type was
12673/// found.
12675lookup_pointer_type(const type_base_sptr& pointed_to_type,
12676 const translation_unit& tu)
12677{
12678 type_base_sptr t = look_through_decl_only_type(pointed_to_type);
12680 return lookup_pointer_type(type_name, tu);
12681}
12682
12683/// Lookup a reference type from a translation unit.
12684///
12685/// This is done by looking the type up in the type map that is
12686/// maintained in the translation unit. So this is as fast as
12687/// possible.
12688///
12689/// @param type_name the name of the reference type to look for.
12690///
12691/// @param tu the translation unit to look into.
12692///
12693/// @return the reference type found or nil if no reference type was
12694/// found.
12697 const translation_unit& tu)
12698{
12699 const type_maps& m = tu.get_types();
12700 return lookup_type_in_map<reference_type_def>(type_name,
12701 m.reference_types());
12702}
12703
12704/// Lookup a reference type from a translation unit.
12705///
12706/// This is done by looking the type up in the type map that is
12707/// maintained in the translation unit. So this is as fast as
12708/// possible.
12709///
12710/// @param pointed_to_type the pointed-to-type of the reference to
12711/// look up.
12712///
12713/// @param tu the translation unit to look into.
12714///
12715/// @return the reference type found or nil if no reference type was
12716/// found.
12718lookup_reference_type(const type_base_sptr& pointed_to_type,
12719 bool lvalue_reference,
12720 const translation_unit& tu)
12721{
12722 interned_string type_name =
12724 lvalue_reference);
12725 return lookup_reference_type(type_name, tu);
12726}
12727
12728/// Lookup an array type from a translation unit.
12729///
12730/// This is done by looking the type up in the type map that is
12731/// maintained in the translation unit. So this is as fast as
12732/// possible.
12733///
12734/// @param type_name the name of the array type to look for.
12735///
12736/// @param tu the translation unit to look into.
12737///
12738/// @return the array type found or nil if no array type was found.
12741 const translation_unit& tu)
12742{
12743 const type_maps& m = tu.get_types();
12744 return lookup_type_in_map<array_type_def>(type_name,
12745 m.array_types());
12746}
12747
12748/// Lookup a function type from a translation unit.
12749///
12750/// This is done by looking the type up in the type map that is
12751/// maintained in the translation unit. So this is as fast as
12752/// possible.
12753///
12754/// @param type_name the name of the type to lookup.
12755///
12756/// @param tu the translation unit to look into.
12757///
12758/// @return the function type found, or NULL of none was found.
12761 const translation_unit& tu)
12762{
12763 const type_maps& m = tu.get_types();
12764 return lookup_type_in_map<function_type>(type_name,
12765 m.function_types());
12766}
12767
12768/// Lookup a function type from a translation unit.
12769///
12770/// This walks all the function types held by the translation unit and
12771/// compare their sub-type *names*. If the names match then return
12772/// the function type found in the translation unit.
12773///
12774/// @param t the function type to look for.
12775///
12776/// @param tu the translation unit to look into.
12777///
12778/// @return the function type found, or NULL of none was found.
12781 const translation_unit& tu)
12782{
12783 interned_string type_name = get_type_name(t);
12784 return lookup_function_type(type_name, tu);
12785}
12786
12787/// Lookup a function type from a translation unit.
12788///
12789/// This is done by looking the type up in the type map that is
12790/// maintained in the translation unit. So this is as fast as
12791/// possible.
12792///
12793/// @param t the function type to look for.
12794///
12795/// @param tu the translation unit to look into.
12796///
12797/// @return the function type found, or NULL of none was found.
12800 const translation_unit& tu)
12801{return lookup_function_type(*t, tu);}
12802
12803/// Lookup a type in a translation unit.
12804///
12805/// @param fqn the fully qualified name of the type to lookup.
12806///
12807/// @param tu the translation unit to consider.
12808///
12809/// @return the declaration of the type if found, NULL otherwise.
12810const type_base_sptr
12812 const translation_unit& tu)
12813{
12814 type_base_sptr result;
12815 ((result = lookup_typedef_type(fqn, tu))
12816 || (result = lookup_class_type(fqn, tu))
12817 || (result = lookup_union_type(fqn, tu))
12818 || (result = lookup_enum_type(fqn, tu))
12819 || (result = lookup_qualified_type(fqn, tu))
12820 || (result = lookup_pointer_type(fqn, tu))
12821 || (result = lookup_reference_type(fqn, tu))
12822 || (result = lookup_array_type(fqn, tu))
12823 || (result = lookup_function_type(fqn, tu))
12824 || (result = lookup_basic_type(fqn, tu)));
12825
12826 return result;
12827}
12828
12829/// Lookup a type in a translation unit, starting from the global
12830/// namespace.
12831///
12832/// @param fqn the fully qualified name of the type to lookup.
12833///
12834/// @param tu the translation unit to consider.
12835///
12836/// @return the declaration of the type if found, NULL otherwise.
12837type_base_sptr
12838lookup_type(const string& fqn, const translation_unit& tu)
12839{
12840 const environment&env = tu.get_environment();
12841 interned_string ifqn = env.intern(fqn);
12842 return lookup_type(ifqn, tu);
12843}
12844
12845/// Lookup a type from a translation unit.
12846///
12847/// @param fqn the components of the fully qualified name of the node
12848/// to look up.
12849///
12850/// @param tu the translation unit to perform lookup from.
12851///
12852/// @return the declaration of the IR node found, NULL otherwise.
12853const type_base_sptr
12854lookup_type(const type_base_sptr type,
12855 const translation_unit& tu)
12856{
12857 interned_string type_name = get_type_name(type);
12858 return lookup_type(type_name, tu);
12859}
12860
12861/// Lookup a type in a scope.
12862///
12863/// This is really slow as it walks the member types of the scope in
12864/// sequence to find the type with a given name.
12865///
12866/// If possible, users should prefer looking up types from the
12867/// enclosing translation unit or even ABI corpus because both the
12868/// translation unit and the corpus have a map of type, indexed by
12869/// their name. Looking up a type from those maps is thus much
12870/// faster.
12871///
12872/// @param fqn the fully qualified name of the type to lookup.
12873///
12874/// @param skope the scope to look into.
12875///
12876/// @return the declaration of the type if found, NULL otherwise.
12877const type_base_sptr
12878lookup_type_in_scope(const string& fqn,
12879 const scope_decl_sptr& skope)
12880{
12881 list<string> comps;
12882 fqn_to_components(fqn, comps);
12883 return lookup_type_in_scope(comps, skope);
12884}
12885
12886/// Lookup a @ref var_decl in a scope.
12887///
12888/// @param fqn the fuly qualified name of the @var_decl to lookup.
12889///
12890/// @param skope the scope to look into.
12891///
12892/// @return the declaration of the @ref var_decl if found, NULL
12893/// otherwise.
12894const decl_base_sptr
12896 const scope_decl_sptr& skope)
12897{
12898 list<string> comps;
12899 fqn_to_components(fqn, comps);
12900 return lookup_var_decl_in_scope(comps, skope);
12901}
12902
12903/// A generic function (template) to get the name of a node, whatever
12904/// node it is. This has to be specialized for the kind of node we
12905/// want.
12906///
12907/// Note that a node is a member of a scope.
12908///
12909/// @tparam NodeKind the kind of node to consider.
12910///
12911/// @param node the node to get the name from.
12912///
12913/// @return the name of the node.
12914template<typename NodeKind>
12915static const interned_string&
12916get_node_name(shared_ptr<NodeKind> node);
12917
12918/// Gets the name of a class_decl node.
12919///
12920/// @param node the decl_base node to get the name from.
12921///
12922/// @return the name of the node.
12923template<>
12924const interned_string&
12926{return node->get_name();}
12927
12928/// Gets the name of a type_base node.
12929///
12930/// @param node the type_base node to get the name from.
12931///
12932/// @return the name of the node.
12933template<>
12934const interned_string&
12935get_node_name(type_base_sptr node)
12936{return get_type_declaration(node)->get_name();}
12937
12938/// Gets the name of a var_decl node.
12939///
12940/// @param node the var_decl node to get the name from.
12941///
12942/// @return the name of the node.
12943template<>
12944const interned_string&
12946{return node->get_name();}
12947
12948/// Generic function to get the declaration of a given node, whatever
12949/// it is. There has to be specializations for the kind of the nodes
12950/// we want to support.
12951///
12952/// @tparam NodeKind the type of the node we are looking at.
12953///
12954/// @return the declaration.
12955template<typename NodeKind>
12956static decl_base_sptr
12957convert_node_to_decl(shared_ptr<NodeKind> node);
12958
12959/// Lookup a node in a given scope.
12960///
12961/// @tparam the type of the node to lookup.
12962///
12963/// @param fqn the components of the fully qualified name of the node
12964/// to lookup.
12965///
12966/// @param skope the scope to look into.
12967///
12968/// @return the declaration of the looked up node, or NULL if it
12969/// wasn't found.
12970template<typename NodeKind>
12971static const type_or_decl_base_sptr
12972lookup_node_in_scope(const list<string>& fqn,
12973 const scope_decl_sptr& skope)
12974{
12975 type_or_decl_base_sptr resulting_decl;
12976 shared_ptr<NodeKind> node;
12977 bool it_is_last = false;
12978 scope_decl_sptr cur_scope = skope, new_scope, scope;
12979
12980 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
12981 {
12982 new_scope.reset();
12983 it_is_last = iterator_is_last(fqn, c);
12984 for (scope_decl::declarations::const_iterator m =
12985 cur_scope->get_member_decls().begin();
12986 m != cur_scope->get_member_decls().end();
12987 ++m)
12988 {
12989 if (!it_is_last)
12990 {
12991 // looking for a scope
12992 scope = dynamic_pointer_cast<scope_decl>(*m);
12993 if (scope && scope->get_name() == *c)
12994 {
12995 new_scope = scope;
12996 break;
12997 }
12998 }
12999 else
13000 {
13001 //looking for a final type.
13002 node = dynamic_pointer_cast<NodeKind>(*m);
13003 if (node && get_node_name(node) == *c)
13004 {
13005 if (class_decl_sptr cl =
13006 dynamic_pointer_cast<class_decl>(node))
13007 if (cl->get_is_declaration_only()
13008 && !cl->get_definition_of_declaration())
13009 continue;
13010 resulting_decl = node;
13011 break;
13012 }
13013 }
13014 }
13015 if (!new_scope && !resulting_decl)
13016 return decl_base_sptr();
13017 cur_scope = new_scope;
13018 }
13019 ABG_ASSERT(resulting_decl);
13020 return resulting_decl;
13021}
13022
13023/// lookup a type in a scope.
13024///
13025///
13026/// This is really slow as it walks the member types of the scope in
13027/// sequence to find the type with a given name.
13028///
13029/// If possible, users should prefer looking up types from the
13030/// enclosing translation unit or even ABI corpus because both the
13031/// translation unit and the corpus have a map of type, indexed by
13032/// their name. Looking up a type from those maps is thus much
13033/// faster.
13034///
13035/// @param comps the components of the fully qualified name of the
13036/// type to lookup.
13037///
13038/// @param skope the scope to look into.
13039///
13040/// @return the declaration of the type found.
13041const type_base_sptr
13042lookup_type_in_scope(const list<string>& comps,
13043 const scope_decl_sptr& scope)
13044{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
13045
13046/// lookup a type in a scope.
13047///
13048/// This is really slow as it walks the member types of the scope in
13049/// sequence to find the type with a given name.
13050///
13051/// If possible, users should prefer looking up types from the
13052/// enclosing translation unit or even ABI corpus because both the
13053/// translation unit and the corpus have a map of type, indexed by
13054/// their name. Looking up a type from those maps is thus much
13055/// faster.
13056///
13057/// @param type the type to look for.
13058///
13059/// @param access_path a vector of scopes the path of scopes to follow
13060/// before reaching the scope into which to look for @p type. Note
13061/// that the deepest scope (the one immediately containing @p type) is
13062/// at index 0 of this vector, and the top-most scope is the last
13063/// element of the vector.
13064///
13065/// @param scope the top-most scope into which to look for @p type.
13066///
13067/// @return the scope found in @p scope, or NULL if it wasn't found.
13068static const type_base_sptr
13070 const vector<scope_decl*>& access_path,
13071 const scope_decl* scope)
13072{
13073 vector<scope_decl*> a = access_path;
13074 type_base_sptr result;
13075
13076 scope_decl* first_scope = 0;
13077 if (!a.empty())
13078 {
13079 first_scope = a.back();
13080 ABG_ASSERT(first_scope->get_name() == scope->get_name());
13081 a.pop_back();
13082 }
13083
13084 if (a.empty())
13085 {
13086 interned_string n = get_type_name(type, false);
13087 for (scope_decl::declarations::const_iterator i =
13088 scope->get_member_decls().begin();
13089 i != scope->get_member_decls().end();
13090 ++i)
13091 if (is_type(*i) && (*i)->get_name() == n)
13092 {
13093 result = is_type(*i);
13094 break;
13095 }
13096 }
13097 else
13098 {
13099 first_scope = a.back();
13100 interned_string scope_name, cur_scope_name = first_scope->get_name();
13101 for (scope_decl::scopes::const_iterator i =
13102 scope->get_member_scopes().begin();
13103 i != scope->get_member_scopes().end();
13104 ++i)
13105 {
13106 scope_name = (*i)->get_name();
13107 if (scope_name == cur_scope_name)
13108 {
13109 result = lookup_type_in_scope(type, a, (*i).get());
13110 break;
13111 }
13112 }
13113 }
13114 return result;
13115}
13116
13117/// lookup a type in a scope.
13118///
13119/// This is really slow as it walks the member types of the scope in
13120/// sequence to find the type with a given name.
13121///
13122/// If possible, users should prefer looking up types from the
13123/// enclosing translation unit or even ABI corpus because both the
13124/// translation unit and the corpus have a map of type, indexed by
13125/// their name. Looking up a type from those maps is thus much
13126/// faster.
13127///
13128/// @param type the type to look for.
13129///
13130/// @param scope the top-most scope into which to look for @p type.
13131///
13132/// @return the scope found in @p scope, or NULL if it wasn't found.
13133static const type_base_sptr
13134lookup_type_in_scope(const type_base_sptr type,
13135 const scope_decl* scope)
13136{
13137 if (!type || is_function_type(type))
13138 return type_base_sptr();
13139
13140 decl_base_sptr type_decl = get_type_declaration(type);
13141 ABG_ASSERT(type_decl);
13142 vector<scope_decl*> access_path;
13143 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
13144 {
13145 access_path.push_back(s);
13146 if (is_global_scope(s))
13147 break;
13148 }
13149 return lookup_type_in_scope(*type, access_path, scope);
13150}
13151
13152/// Lookup a type from a translation unit by walking the scopes of the
13153/// translation unit in sequence and looking into them.
13154///
13155/// This is really slow as it walks the member types of the scopes in
13156/// sequence to find the type with a given name.
13157///
13158/// If possible, users should prefer looking up types from the
13159/// translation unit or even ABI corpus in a more direct way, by using
13160/// the lookup_type() functins.
13161///
13162///
13163/// This is because both the translation unit and the corpus have a
13164/// map of types, indexed by their name. Looking up a type from those
13165/// maps is thus much faster. @param fqn the components of the fully
13166/// qualified name of the node to look up.
13167///
13168/// @param tu the translation unit to perform lookup from.
13169///
13170/// @return the declaration of the IR node found, NULL otherwise.
13171const type_base_sptr
13172lookup_type_through_scopes(const type_base_sptr type,
13173 const translation_unit& tu)
13174{
13175 if (function_type_sptr fn_type = is_function_type(type))
13176 return lookup_function_type(fn_type, tu);
13177 return lookup_type_in_scope(type, tu.get_global_scope().get());
13178}
13179
13180/// lookup a var_decl in a scope.
13181///
13182/// @param comps the components of the fully qualified name of the
13183/// var_decl to lookup.
13184///
13185/// @param skope the scope to look into.
13186const decl_base_sptr
13187lookup_var_decl_in_scope(const std::list<string>& comps,
13188 const scope_decl_sptr& skope)
13189{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
13190
13191/// Lookup an IR node from a translation unit.
13192///
13193/// @tparam NodeKind the type of the IR node to lookup from the
13194/// translation unit.
13195///
13196/// @param fqn the components of the fully qualified name of the node
13197/// to look up.
13198///
13199/// @param tu the translation unit to perform lookup from.
13200///
13201/// @return the declaration of the IR node found, NULL otherwise.
13202template<typename NodeKind>
13203static const type_or_decl_base_sptr
13204lookup_node_in_translation_unit(const list<string>& fqn,
13205 const translation_unit& tu)
13206{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
13207
13208/// Lookup a type from a translation unit by walking its scopes in
13209/// sequence and by looking into them.
13210///
13211/// This is much slower than using the lookup_type() function.
13212///
13213/// @param fqn the components of the fully qualified name of the node
13214/// to look up.
13215///
13216/// @param tu the translation unit to perform lookup from.
13217///
13218/// @return the declaration of the IR node found, NULL otherwise.
13219type_base_sptr
13220lookup_type_through_scopes(const list<string>& fqn,
13221 const translation_unit& tu)
13222{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
13223
13224
13225/// Lookup a class type from a translation unit by walking its scopes
13226/// in sequence and by looking into them.
13227///
13228/// This is much slower than using the lookup_class_type() function
13229/// because it walks all the scopes of the translation unit in
13230/// sequence and lookup the types to find one that has a given name.
13231///
13232/// @param fqn the components of the fully qualified name of the class
13233/// type node to look up.
13234///
13235/// @param tu the translation unit to perform lookup from.
13236///
13237/// @return the declaration of the class type IR node found, NULL
13238/// otherwise.
13240lookup_class_type_through_scopes(const list<string>& fqn,
13241 const translation_unit& tu)
13242{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
13243
13244/// Lookup a basic type from all the translation units of a given
13245/// corpus.
13246///
13247/// @param fqn the components of the fully qualified name of the basic
13248/// type node to look up.
13249///
13250/// @param tu the translation unit to perform lookup from.
13251///
13252/// @return the declaration of the basic type IR node found, NULL
13253/// otherwise.
13254static type_decl_sptr
13255lookup_basic_type_through_translation_units(const interned_string& type_name,
13256 const corpus& abi_corpus)
13257{
13258 type_decl_sptr result;
13259
13260 for (translation_units::const_iterator tu =
13261 abi_corpus.get_translation_units().begin();
13262 tu != abi_corpus.get_translation_units().end();
13263 ++tu)
13264 if ((result = lookup_basic_type(type_name, **tu)))
13265 break;
13266
13267 return result;
13268}
13269
13270/// Lookup a union type from all the translation units of a given
13271/// corpus.
13272///
13273/// @param fqn the components of the fully qualified name of the union
13274/// type node to look up.
13275///
13276/// @param tu the translation unit to perform lookup from.
13277///
13278/// @return the declaration of the union type IR node found, NULL
13279/// otherwise.
13280static union_decl_sptr
13281lookup_union_type_through_translation_units(const interned_string& type_name,
13282 const corpus & abi_corpus)
13283{
13284 union_decl_sptr result;
13285
13286 for (translation_units::const_iterator tu =
13287 abi_corpus.get_translation_units().begin();
13288 tu != abi_corpus.get_translation_units().end();
13289 ++tu)
13290 if ((result = lookup_union_type(type_name, **tu)))
13291 break;
13292
13293 return result;
13294}
13295
13296/// Lookup an enum type from all the translation units of a given
13297/// corpus.
13298///
13299/// @param fqn the components of the fully qualified name of the enum
13300/// type node to look up.
13301///
13302/// @param tu the translation unit to perform lookup from.
13303///
13304/// @return the declaration of the enum type IR node found, NULL
13305/// otherwise.
13307lookup_enum_type_through_translation_units(const interned_string& type_name,
13308 const corpus & abi_corpus)
13309{
13310 enum_type_decl_sptr result;
13311
13312 for (translation_units::const_iterator tu =
13313 abi_corpus.get_translation_units().begin();
13314 tu != abi_corpus.get_translation_units().end();
13315 ++tu)
13316 if ((result = lookup_enum_type(type_name, **tu)))
13317 break;
13318
13319 return result;
13320}
13321
13322/// Lookup a typedef type definition in all the translation units of a
13323/// given ABI corpus.
13324///
13325/// @param @param qn the fully qualified name of the typedef type to lookup.
13326///
13327/// @param abi_corpus the ABI corpus which to look the type up in.
13328///
13329/// @return the type definition if any was found, or a NULL pointer.
13330static typedef_decl_sptr
13331lookup_typedef_type_through_translation_units(const interned_string& type_name,
13332 const corpus & abi_corpus)
13333{
13334 typedef_decl_sptr result;
13335
13336 for (translation_units::const_iterator tu =
13337 abi_corpus.get_translation_units().begin();
13338 tu != abi_corpus.get_translation_units().end();
13339 ++tu)
13340 if ((result = lookup_typedef_type(type_name, **tu)))
13341 break;
13342
13343 return result;
13344}
13345
13346/// Lookup a qualified type definition in all the translation units of a
13347/// given ABI corpus.
13348///
13349/// @param @param qn the fully qualified name of the qualified type to
13350/// lookup.
13351///
13352/// @param abi_corpus the ABI corpus which to look the type up in.
13353///
13354/// @return the type definition if any was found, or a NULL pointer.
13355static qualified_type_def_sptr
13356lookup_qualified_type_through_translation_units(const interned_string& t_name,
13357 const corpus & abi_corpus)
13358{
13359 qualified_type_def_sptr result;
13360
13361 for (translation_units::const_iterator tu =
13362 abi_corpus.get_translation_units().begin();
13363 tu != abi_corpus.get_translation_units().end();
13364 ++tu)
13365 if ((result = lookup_qualified_type(t_name, **tu)))
13366 break;
13367
13368 return result;
13369}
13370
13371/// Lookup a pointer type definition in all the translation units of a
13372/// given ABI corpus.
13373///
13374/// @param @param qn the fully qualified name of the pointer type to
13375/// lookup.
13376///
13377/// @param abi_corpus the ABI corpus which to look the type up in.
13378///
13379/// @return the type definition if any was found, or a NULL pointer.
13381lookup_pointer_type_through_translation_units(const interned_string& type_name,
13382 const corpus & abi_corpus)
13383{
13384 pointer_type_def_sptr result;
13385
13386 for (translation_units::const_iterator tu =
13387 abi_corpus.get_translation_units().begin();
13388 tu != abi_corpus.get_translation_units().end();
13389 ++tu)
13390 if ((result = lookup_pointer_type(type_name, **tu)))
13391 break;
13392
13393 return result;
13394}
13395
13396/// Lookup a reference type definition in all the translation units of a
13397/// given ABI corpus.
13398///
13399/// @param @param qn the fully qualified name of the reference type to
13400/// lookup.
13401///
13402/// @param abi_corpus the ABI corpus which to look the type up in.
13403///
13404/// @return the type definition if any was found, or a NULL pointer.
13406lookup_reference_type_through_translation_units(const interned_string& t_name,
13407 const corpus & abi_corpus)
13408{
13410
13411 for (translation_units::const_iterator tu =
13412 abi_corpus.get_translation_units().begin();
13413 tu != abi_corpus.get_translation_units().end();
13414 ++tu)
13415 if ((result = lookup_reference_type(t_name, **tu)))
13416 break;
13417
13418 return result;
13419}
13420
13421/// Lookup a array type definition in all the translation units of a
13422/// given ABI corpus.
13423///
13424/// @param @param qn the fully qualified name of the array type to
13425/// lookup.
13426///
13427/// @param abi_corpus the ABI corpus which to look the type up in.
13428///
13429/// @return the type definition if any was found, or a NULL pointer.
13431lookup_array_type_through_translation_units(const interned_string& type_name,
13432 const corpus & abi_corpus)
13433{
13434 array_type_def_sptr result;
13435
13436 for (translation_units::const_iterator tu =
13437 abi_corpus.get_translation_units().begin();
13438 tu != abi_corpus.get_translation_units().end();
13439 ++tu)
13440 if ((result = lookup_array_type(type_name, **tu)))
13441 break;
13442
13443 return result;
13444}
13445
13446/// Lookup a function type definition in all the translation units of
13447/// a given ABI corpus.
13448///
13449/// @param @param qn the fully qualified name of the function type to
13450/// lookup.
13451///
13452/// @param abi_corpus the ABI corpus which to look the type up in.
13453///
13454/// @return the type definition if any was found, or a NULL pointer.
13455static function_type_sptr
13456lookup_function_type_through_translation_units(const interned_string& type_name,
13457 const corpus & abi_corpus)
13458{
13459 function_type_sptr result;
13460
13461 for (translation_units::const_iterator tu =
13462 abi_corpus.get_translation_units().begin();
13463 tu != abi_corpus.get_translation_units().end();
13464 ++tu)
13465 if ((result = lookup_function_type(type_name, **tu)))
13466 break;
13467
13468 return result;
13469}
13470
13471/// Lookup a type definition in all the translation units of a given
13472/// ABI corpus.
13473///
13474/// @param @param qn the fully qualified name of the type to lookup.
13475///
13476/// @param abi_corpus the ABI corpus which to look the type up in.
13477///
13478/// @return the type definition if any was found, or a NULL pointer.
13479type_base_sptr
13481 const corpus& abi_corpus)
13482{
13483 type_base_sptr result;
13484
13485 for (translation_units::const_iterator tu =
13486 abi_corpus.get_translation_units().begin();
13487 tu != abi_corpus.get_translation_units().end();
13488 ++tu)
13489 if ((result = lookup_type(qn, **tu)))
13490 break;
13491
13492 return result;
13493}
13494
13495/// Lookup a type from a given translation unit present in a give corpus.
13496///
13497/// @param type_name the name of the type to look for.
13498///
13499/// @parm tu_path the path of the translation unit to consider.
13500///
13501/// @param corp the corpus to consider.
13502///
13503/// @return the resulting type, if any.
13504type_base_sptr
13506 const string& tu_path,
13507 const corpus& corp)
13508{
13509 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13510 if (i == corp.priv_->path_tu_map.end())
13511 return type_base_sptr();
13512
13513 translation_unit_sptr tu = i->second;
13514 ABG_ASSERT(tu);
13515
13516 type_base_sptr t = lookup_type(type_name, *tu);
13517 return t;
13518}
13519
13520/// Look into an ABI corpus for a function type.
13521///
13522/// @param fn_type the function type to be looked for in the ABI
13523/// corpus.
13524///
13525/// @param corpus the ABI corpus into which to look for the function
13526/// type.
13527///
13528/// @return the function type found in the corpus.
13531 const corpus& corpus)
13532{
13533 ABG_ASSERT(fn_t);
13534
13535 function_type_sptr result;
13536
13537 if ((result = lookup_function_type(fn_t, corpus)))
13538 return result;
13539
13540 for (translation_units::const_iterator i =
13541 corpus.get_translation_units().begin();
13542 i != corpus.get_translation_units().end();
13543 ++i)
13545 **i)))
13546 return result;
13547
13548 return result;
13549}
13550
13551/// Look into a given corpus to find a type which has the same
13552/// qualified name as a giventype.
13553///
13554/// If the per-corpus type map is non-empty (because the corpus allows
13555/// the One Definition Rule) then the type islooked up in that
13556/// per-corpus type map. Otherwise, the type is looked-up in each
13557/// translation unit.
13558///
13559/// @param t the type which has the same qualified name as the type we
13560/// are looking for.
13561///
13562/// @param corp the ABI corpus to look into for the type.
13564lookup_basic_type(const type_decl& t, const corpus& corp)
13565{return lookup_basic_type(t.get_name(), corp);}
13566
13567/// Look into a given corpus to find a basic type which has a given
13568/// qualified name.
13569///
13570/// If the per-corpus type map is non-empty (because the corpus allows
13571/// the One Definition Rule) then the type islooked up in that
13572/// per-corpus type map. Otherwise, the type is looked-up in each
13573/// translation unit.
13574///
13575/// @param qualified_name the qualified name of the basic type to look
13576/// for.
13577///
13578/// @param corp the corpus to look into.
13580lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13581{
13583 type_decl_sptr result;
13584
13585 if (!m.empty())
13586 result = lookup_type_in_map<type_decl>(qualified_name, m);
13587 else
13588 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13589
13590 return result;
13591}
13592
13593/// Lookup a @ref type_decl type from a given corpus, by its location.
13594///
13595/// @param loc the location to consider.
13596///
13597/// @param corp the corpus to consider.
13598///
13599/// @return the resulting basic type, if any.
13602 const corpus &corp)
13603{
13606 type_decl_sptr result;
13607
13608 result = lookup_type_in_map<type_decl>(loc, m);
13609
13610 return result;
13611}
13612
13613/// Lookup a @ref type_decl type from a given corpus, by its location.
13614///
13615/// @param loc the location to consider.
13616///
13617/// @param corp the corpus to consider.
13618///
13619/// @return the resulting basic type, if any.
13621lookup_basic_type_per_location(const string &loc, const corpus &corp)
13622{
13623 const environment& env = corp.get_environment();
13624 return lookup_basic_type_per_location(env.intern(loc), corp);
13625}
13626
13627/// Look into a given corpus to find a basic type which has a given
13628/// qualified name.
13629///
13630/// If the per-corpus type map is non-empty (because the corpus allows
13631/// the One Definition Rule) then the type islooked up in that
13632/// per-corpus type map. Otherwise, the type is looked-up in each
13633/// translation unit.
13634///
13635/// @param qualified_name the qualified name of the basic type to look
13636/// for.
13637///
13638/// @param corp the corpus to look into.
13640lookup_basic_type(const string& qualified_name, const corpus& corp)
13641{
13642 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13643 corp);
13644}
13645
13646/// Look into a given corpus to find a class type which has the same
13647/// qualified name as a given type.
13648///
13649/// If the per-corpus type map is non-empty (because the corpus allows
13650/// the One Definition Rule) then the type islooked up in that
13651/// per-corpus type map. Otherwise, the type is looked-up in each
13652/// translation unit.
13653///
13654/// @param t the class decl type which has the same qualified name as
13655/// the type we are looking for.
13656///
13657/// @param corp the corpus to look into.
13660{
13662 return lookup_class_type(s, corp);
13663}
13664
13665/// Look into a given corpus to find a class type which has a given
13666/// qualified name.
13667///
13668/// If the per-corpus type map is non-empty (because the corpus allows
13669/// the One Definition Rule) then the type islooked up in that
13670/// per-corpus type map. Otherwise, the type is looked-up in each
13671/// translation unit.
13672///
13673/// @param qualified_name the qualified name of the type to look for.
13674///
13675/// @param corp the corpus to look into.
13677lookup_class_type(const string& qualified_name, const corpus& corp)
13678{
13679 interned_string s = corp.get_environment().intern(qualified_name);
13680 return lookup_class_type(s, corp);
13681}
13682
13683/// Look into a given corpus to find a class type which has a given
13684/// qualified name.
13685///
13686/// If the per-corpus type map is non-empty (because the corpus allows
13687/// the One Definition Rule) then the type islooked up in that
13688/// per-corpus type map. Otherwise, the type is looked-up in each
13689/// translation unit.
13690///
13691/// @param qualified_name the qualified name of the type to look for.
13692///
13693/// @param corp the corpus to look into.
13695lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13696{
13698
13699 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13700
13701 return result;
13702}
13703
13704/// Look into a given corpus to find the class type*s* that have a
13705/// given qualified name.
13706///
13707/// @param qualified_name the qualified name of the type to look for.
13708///
13709/// @param corp the corpus to look into.
13710///
13711/// @return the vector of class types named @p qualified_name.
13713lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13714{
13716
13717 return lookup_types_in_map(qualified_name, m);
13718}
13719
13720/// Look into a given corpus to find the class type*s* that have a
13721/// given qualified name and that are declaration-only.
13722///
13723/// @param qualified_name the qualified name of the type to look for.
13724///
13725/// @param corp the corpus to look into.
13726///
13727/// @param result the vector of decl-only class types named @p
13728/// qualified_name. This is populated iff the function returns true.
13729///
13730/// @return true iff @p result was populated with the decl-only
13731/// classes named @p qualified_name.
13732bool
13734 const corpus& corp,
13735 type_base_wptrs_type& result)
13736{
13738
13739 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13740 if (!v)
13741 return false;
13742
13743 for (auto type : *v)
13744 {
13745 type_base_sptr t(type);
13747 if (c->get_is_declaration_only()
13748 && !c->get_definition_of_declaration())
13749 result.push_back(type);
13750 }
13751
13752 return !result.empty();
13753}
13754
13755/// Look into a given corpus to find the union type*s* that have a
13756/// given qualified name.
13757///
13758/// @param qualified_name the qualified name of the type to look for.
13759///
13760/// @param corp the corpus to look into.
13761///
13762/// @return the vector of union types named @p qualified_name.
13764lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13765{
13767
13768 return lookup_types_in_map(qualified_name, m);
13769}
13770
13771/// Look into a given corpus to find the class type*s* that have a
13772/// given qualified name.
13773///
13774/// @param qualified_name the qualified name of the type to look for.
13775///
13776/// @param corp the corpus to look into.
13777///
13778/// @return the vector of class types which name is @p qualified_name.
13780lookup_class_types(const string& qualified_name, const corpus& corp)
13781{
13782 interned_string s = corp.get_environment().intern(qualified_name);
13783 return lookup_class_types(s, corp);
13784}
13785
13786/// Look into a given corpus to find the union types that have a given
13787/// qualified name.
13788///
13789/// @param qualified_name the qualified name of the type to look for.
13790///
13791/// @param corp the corpus to look into.
13792///
13793/// @return the vector of union types which name is @p qualified_name.
13795lookup_union_types(const string& qualified_name, const corpus& corp)
13796{
13797 interned_string s = corp.get_environment().intern(qualified_name);
13798 return lookup_union_types(s, corp);
13799}
13800
13801/// Look up a @ref class_decl from a given corpus by its location.
13802///
13803/// @param loc the location to consider.
13804///
13805/// @param corp the corpus to consider.
13806///
13807/// @return the resulting class decl, if any.
13810 const corpus& corp)
13811{
13814 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13815
13816 return result;
13817}
13818
13819/// Look up a @ref class_decl from a given corpus by its location.
13820///
13821/// @param loc the location to consider.
13822///
13823/// @param corp the corpus to consider.
13824///
13825/// @return the resulting class decl, if any.
13827lookup_class_type_per_location(const string &loc, const corpus &corp)
13828{
13829 const environment& env = corp.get_environment();
13830 return lookup_class_type_per_location(env.intern(loc), corp);
13831}
13832
13833/// Look into a given corpus to find a union type which has a given
13834/// qualified name.
13835///
13836/// If the per-corpus type map is non-empty (because the corpus allows
13837/// the One Definition Rule) then the type islooked up in that
13838/// per-corpus type map. Otherwise, the type is looked-up in each
13839/// translation unit.
13840///
13841/// @param qualified_name the qualified name of the type to look for.
13842///
13843/// @param corp the corpus to look into.
13844union_decl_sptr
13845lookup_union_type(const interned_string& type_name, const corpus& corp)
13846{
13848
13849 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13850 if (!result)
13851 result = lookup_union_type_through_translation_units(type_name, corp);
13852
13853 return result;
13854}
13855
13856/// Look into a given corpus to find a union type which has a given
13857/// qualified name.
13858///
13859/// If the per-corpus type map is non-empty (because the corpus allows
13860/// the One Definition Rule) then the type islooked up in that
13861/// per-corpus type map. Otherwise, the type is looked-up in each
13862/// translation unit.
13863///
13864/// @param qualified_name the qualified name of the type to look for.
13865///
13866/// @param corp the corpus to look into.
13867union_decl_sptr
13868lookup_union_type(const string& type_name, const corpus& corp)
13869{
13870 interned_string s = corp.get_environment().intern(type_name);
13871 return lookup_union_type(s, corp);
13872}
13873
13874/// Look into a given corpus to find an enum type which has the same
13875/// qualified name as a given enum type.
13876///
13877/// If the per-corpus type map is non-empty (because the corpus allows
13878/// the One Definition Rule) then the type islooked up in that
13879/// per-corpus type map. Otherwise, the type is looked-up in each
13880/// translation unit.
13881///
13882/// @param t the enum type which has the same qualified name as the
13883/// type we are looking for.
13884///
13885/// @param corp the corpus to look into.
13888{
13890 return lookup_enum_type(s, corp);
13891}
13892
13893/// Look into a given corpus to find an enum type which has a given
13894/// qualified name.
13895///
13896/// If the per-corpus type map is non-empty (because the corpus allows
13897/// the One Definition Rule) then the type islooked up in that
13898/// per-corpus type map. Otherwise, the type is looked-up in each
13899/// translation unit.
13900///
13901/// @param qualified_name the qualified name of the enum type to look
13902/// for.
13903///
13904/// @param corp the corpus to look into.
13906lookup_enum_type(const string& qualified_name, const corpus& corp)
13907{
13908 interned_string s = corp.get_environment().intern(qualified_name);
13909 return lookup_enum_type(s, corp);
13910}
13911
13912/// Look into a given corpus to find an enum type which has a given
13913/// qualified name.
13914///
13915/// If the per-corpus type map is non-empty (because the corpus allows
13916/// the One Definition Rule) then the type islooked up in that
13917/// per-corpus type map. Otherwise, the type is looked-up in each
13918/// translation unit.
13919///
13920/// @param qualified_name the qualified name of the enum type to look
13921/// for.
13922///
13923/// @param corp the corpus to look into.
13925lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
13926{
13928
13929 enum_type_decl_sptr result =
13930 lookup_type_in_map<enum_type_decl>(qualified_name, m);
13931 if (!result)
13932 result = lookup_enum_type_through_translation_units(qualified_name, corp);
13933
13934 return result;
13935}
13936
13937/// Look into a given corpus to find the enum type*s* that have a
13938/// given qualified name.
13939///
13940/// @param qualified_name the qualified name of the type to look for.
13941///
13942/// @param corp the corpus to look into.
13943///
13944/// @return the vector of enum types that which name is @p qualified_name.
13946lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
13947{
13949
13950 return lookup_types_in_map(qualified_name, m);
13951}
13952
13953/// Look into a given corpus to find the enum type*s* that have a
13954/// given qualified name.
13955///
13956/// @param qualified_name the qualified name of the type to look for.
13957///
13958/// @param corp the corpus to look into.
13959///
13960/// @return the vector of enum types that which name is @p qualified_name.
13962lookup_enum_types(const string& qualified_name, const corpus& corp)
13963{
13964 interned_string s = corp.get_environment().intern(qualified_name);
13965 return lookup_enum_types(s, corp);
13966}
13967
13968/// Look up an @ref enum_type_decl from a given corpus, by its location.
13969///
13970/// @param loc the location to consider.
13971///
13972/// @param corp the corpus to look the type from.
13973///
13974/// @return the resulting enum type, if any.
13977{
13980 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
13981
13982 return result;
13983}
13984
13985/// Look up an @ref enum_type_decl from a given corpus, by its location.
13986///
13987/// @param loc the location to consider.
13988///
13989/// @param corp the corpus to look the type from.
13990///
13991/// @return the resulting enum type, if any.
13993lookup_enum_type_per_location(const string &loc, const corpus &corp)
13994{
13995 const environment& env = corp.get_environment();
13996 return lookup_enum_type_per_location(env.intern(loc), corp);
13997}
13998
13999/// Look into a given corpus to find a typedef type which has the
14000/// same qualified name as a given typedef type.
14001///
14002/// If the per-corpus type map is non-empty (because the corpus allows
14003/// the One Definition Rule) then the type islooked up in that
14004/// per-corpus type map. Otherwise, the type is looked-up in each
14005/// translation unit.
14006///
14007/// @param t the typedef type which has the same qualified name as the
14008/// typedef type we are looking for.
14009///
14010/// @param corp the corpus to look into.
14013{
14015 return lookup_typedef_type(s, corp);
14016}
14017
14018/// Look into a given corpus to find a typedef type which has the
14019/// same qualified name as a given typedef type.
14020///
14021/// If the per-corpus type map is non-empty (because the corpus allows
14022/// the One Definition Rule) then the type islooked up in that
14023/// per-corpus type map. Otherwise, the type is looked-up in each
14024/// translation unit.
14025///
14026/// @param t the typedef type which has the same qualified name as the
14027/// typedef type we are looking for.
14028///
14029/// @param corp the corpus to look into.
14031lookup_typedef_type(const string& qualified_name, const corpus& corp)
14032{
14033 interned_string s = corp.get_environment().intern(qualified_name);
14034 return lookup_typedef_type(s, corp);
14035}
14036
14037/// Look into a given corpus to find a typedef type which has a
14038/// given qualified name.
14039///
14040/// If the per-corpus type map is non-empty (because the corpus allows
14041/// the One Definition Rule) then the type islooked up in that
14042/// per-corpus type map. Otherwise, the type is looked-up in each
14043/// translation unit.
14044///
14045/// @param qualified_name the qualified name of the typedef type to
14046/// look for.
14047///
14048/// @param corp the corpus to look into.
14050lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
14051{
14053
14054 typedef_decl_sptr result =
14055 lookup_type_in_map<typedef_decl>(qualified_name, m);
14056 if (!result)
14057 result = lookup_typedef_type_through_translation_units(qualified_name,
14058 corp);
14059
14060 return result;
14061}
14062
14063/// Lookup a @ref typedef_decl from a corpus, by its location.
14064///
14065/// @param loc the location to consider.
14066///
14067/// @param corp the corpus to consider.
14068///
14069/// @return the typedef_decl found, if any.
14072{
14075 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
14076
14077 return result;
14078}
14079
14080/// Lookup a @ref typedef_decl from a corpus, by its location.
14081///
14082/// @param loc the location to consider.
14083///
14084/// @param corp the corpus to consider.
14085///
14086/// @return the typedef_decl found, if any.
14088lookup_typedef_type_per_location(const string &loc, const corpus &corp)
14089{
14090 const environment& env = corp.get_environment();
14091 return lookup_typedef_type_per_location(env.intern(loc), corp);
14092}
14093
14094/// Look into a corpus to find a class, union or typedef type which
14095/// has a given qualified name.
14096///
14097/// If the per-corpus type map is non-empty (because the corpus allows
14098/// the One Definition Rule) then the type islooked up in that
14099/// per-corpus type map. Otherwise, the type is looked-up in each
14100/// translation unit.
14101///
14102/// @param qualified_name the name of the type to find.
14103///
14104/// @param corp the corpus to look into.
14105///
14106/// @return the typedef or class type found.
14107type_base_sptr
14108lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
14109{
14110 type_base_sptr result = lookup_class_type(qualified_name, corp);
14111 if (!result)
14112 result = lookup_union_type(qualified_name, corp);
14113
14114 if (!result)
14115 result = lookup_typedef_type(qualified_name, corp);
14116 return result;
14117}
14118
14119/// Look into a corpus to find a class, typedef or enum type which has
14120/// a given qualified name.
14121///
14122/// If the per-corpus type map is non-empty (because the corpus allows
14123/// the One Definition Rule) then the type islooked up in that
14124/// per-corpus type map. Otherwise, the type is looked-up in each
14125/// translation unit.
14126///
14127/// @param qualified_name the qualified name of the type to look for.
14128///
14129/// @param corp the corpus to look into.
14130///
14131/// @return the typedef, class or enum type found.
14132type_base_sptr
14133lookup_class_typedef_or_enum_type(const string& qualified_name,
14134 const corpus& corp)
14135{
14136 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
14137 if (!result)
14138 result = lookup_enum_type(qualified_name, corp);
14139
14140 return result;
14141}
14142
14143/// Look into a given corpus to find a qualified type which has the
14144/// same qualified name as a given type.
14145///
14146/// @param t the type which has the same qualified name as the
14147/// qualified type we are looking for.
14148///
14149/// @param corp the corpus to look into.
14150///
14151/// @return the qualified type found.
14152qualified_type_def_sptr
14154{
14156 return lookup_qualified_type(s, corp);
14157}
14158
14159/// Look into a given corpus to find a qualified type which has a
14160/// given qualified name.
14161///
14162/// @param qualified_name the qualified name of the type to look for.
14163///
14164/// @param corp the corpus to look into.
14165///
14166/// @return the type found.
14167qualified_type_def_sptr
14168lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
14169{
14171 corp.get_types().qualified_types();
14172
14173 qualified_type_def_sptr result =
14174 lookup_type_in_map<qualified_type_def>(qualified_name, m);
14175
14176 if (!result)
14177 result = lookup_qualified_type_through_translation_units(qualified_name,
14178 corp);
14179
14180 return result;
14181}
14182
14183/// Look into a given corpus to find a pointer type which has the same
14184/// qualified name as a given pointer type.
14185///
14186/// @param t the pointer type which has the same qualified name as the
14187/// type we are looking for.
14188///
14189/// @param corp the corpus to look into.
14190///
14191/// @return the pointer type found.
14194{
14196 return lookup_pointer_type(s, corp);
14197}
14198
14199/// Look into a given corpus to find a pointer type which has a given
14200/// qualified name.
14201///
14202/// If the per-corpus type map is non-empty (because the corpus allows
14203/// the One Definition Rule) then the type islooked up in that
14204/// per-corpus type map. Otherwise, the type is looked-up in each
14205/// translation unit.
14206///
14207/// @param qualified_name the qualified name of the pointer type to
14208/// look for.
14209///
14210/// @param corp the corpus to look into.
14211///
14212/// @return the pointer type found.
14214lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
14215{
14217
14218 pointer_type_def_sptr result =
14219 lookup_type_in_map<pointer_type_def>(qualified_name, m);
14220 if (!result)
14221 result = lookup_pointer_type_through_translation_units(qualified_name,
14222 corp);
14223
14224 return result;
14225}
14226
14227/// Look into a given corpus to find a reference type which has the
14228/// same qualified name as a given reference type.
14229///
14230/// If the per-corpus type map is non-empty (because the corpus allows
14231/// the One Definition Rule) then the type islooked up in that
14232/// per-corpus type map. Otherwise, the type is looked-up in each
14233/// translation unit.
14234///
14235/// @param t the reference type which has the same qualified name as
14236/// the reference type we are looking for.
14237///
14238/// @param corp the corpus to look into.
14239///
14240/// @return the reference type found.
14243{
14245 return lookup_reference_type(s, corp);
14246}
14247
14248/// Look into a given corpus to find a reference type which has a
14249/// given qualified name.
14250///
14251/// If the per-corpus type map is non-empty (because the corpus allows
14252/// the One Definition Rule) then the type islooked up in that
14253/// per-corpus type map. Otherwise, the type is looked-up in each
14254/// translation unit.
14255///
14256/// @param qualified_name the qualified name of the reference type to
14257/// look for.
14258///
14259/// @param corp the corpus to look into.
14260///
14261/// @return the reference type found.
14263lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
14264{
14266 corp.get_types().reference_types();
14267
14269 lookup_type_in_map<reference_type_def>(qualified_name, m);
14270 if (!result)
14271 result = lookup_reference_type_through_translation_units(qualified_name,
14272 corp);
14273
14274 return result;
14275}
14276
14277/// Look into a given corpus to find an array type which has a given
14278/// qualified name.
14279///
14280/// If the per-corpus type map is non-empty (because the corpus allows
14281/// the One Definition Rule) then the type islooked up in that
14282/// per-corpus type map. Otherwise, the type is looked-up in each
14283/// translation unit.
14284///
14285/// @param qualified_name the qualified name of the array type to look
14286/// for.
14287///
14288/// @param corp the corpus to look into.
14289///
14290/// @return the array type found.
14293{
14295 return lookup_array_type(s, corp);
14296}
14297
14298/// Look into a given corpus to find an array type which has the same
14299/// qualified name as a given array type.
14300///
14301/// If the per-corpus type map is non-empty (because the corpus allows
14302/// the One Definition Rule) then the type islooked up in that
14303/// per-corpus type map. Otherwise, the type is looked-up in each
14304/// translation unit.
14305///
14306/// @param t the type which has the same qualified name as the type we
14307/// are looking for.
14308///
14309/// @param corp the corpus to look into.
14310///
14311/// @return the type found.
14313lookup_array_type(const interned_string& qualified_name, const corpus& corp)
14314{
14316
14317 array_type_def_sptr result =
14318 lookup_type_in_map<array_type_def>(qualified_name, m);
14319 if (!result)
14320 result = lookup_array_type_through_translation_units(qualified_name, corp);
14321
14322 return result;
14323}
14324
14325/// Look into a given corpus to find a function type which has the same
14326/// qualified name as a given function type.
14327///
14328/// If the per-corpus type map is non-empty (because the corpus allows
14329/// the One Definition Rule) then the type islooked up in that
14330/// per-corpus type map. Otherwise, the type is looked-up in each
14331/// translation unit.
14332///
14333/// @param t the function type which has the same qualified name as
14334/// the function type we are looking for.
14335///
14336/// @param corp the corpus to look into.
14337///
14338/// @return the function type found.
14341{
14342 interned_string type_name = get_type_name(t);
14343 return lookup_function_type(type_name, corp);
14344}
14345
14346/// Look into a given corpus to find a function type which has the same
14347/// qualified name as a given function type.
14348///
14349/// If the per-corpus type map is non-empty (because the corpus allows
14350/// the One Definition Rule) then the type islooked up in that
14351/// per-corpus type map. Otherwise, the type is looked-up in each
14352/// translation unit.
14353///
14354/// @param t the function type which has the same qualified name as
14355/// the function type we are looking for.
14356///
14357/// @param corp the corpus to look into.
14358///
14359/// @return the function type found.
14362 const corpus& corpus)
14363{
14364 if (fn_t)
14365 return lookup_function_type(*fn_t, corpus);
14366 return function_type_sptr();
14367}
14368
14369/// Look into a given corpus to find a function type which has a given
14370/// qualified name.
14371///
14372/// If the per-corpus type map is non-empty (because the corpus allows
14373/// the One Definition Rule) then the type islooked up in that
14374/// per-corpus type map. Otherwise, the type is looked-up in each
14375/// translation unit.
14376///
14377/// @param qualified_name the qualified name of the function type to
14378/// look for.
14379///
14380/// @param corp the corpus to look into.
14381///
14382/// @return the function type found.
14384lookup_function_type(const interned_string& qualified_name, const corpus& corp)
14385{
14387
14388 function_type_sptr result =
14389 lookup_type_in_map<function_type>(qualified_name, m);
14390 if (!result)
14391 result = lookup_function_type_through_translation_units(qualified_name,
14392 corp);
14393
14394 return result;
14395}
14396
14397/// Look into a given corpus to find a type which has a given
14398/// qualified name.
14399///
14400/// If the per-corpus type map is non-empty (because the corpus allows
14401/// the One Definition Rule) then the type islooked up in that
14402/// per-corpus type map. Otherwise, the type is looked-up in each
14403/// translation unit.
14404///
14405/// @param qualified_name the qualified name of the function type to
14406/// look for.
14407///
14408/// @param corp the corpus to look into.
14409///
14410/// @return the function type found.
14411type_base_sptr
14412lookup_type(const interned_string& n, const corpus& corp)
14413{
14414 type_base_sptr result;
14415
14416 ((result = lookup_basic_type(n, corp))
14417 || (result = lookup_class_type(n, corp))
14418 || (result = lookup_union_type(n, corp))
14419 || (result = lookup_enum_type(n, corp))
14420 || (result = lookup_typedef_type(n, corp))
14421 || (result = lookup_qualified_type(n, corp))
14422 || (result = lookup_pointer_type(n, corp))
14423 || (result = lookup_reference_type(n, corp))
14424 || (result = lookup_array_type(n, corp))
14425 || (result= lookup_function_type(n, corp)));
14426
14427 return result;
14428}
14429
14430/// Lookup a type from a corpus, by its location.
14431///
14432/// @param loc the location to consider.
14433///
14434/// @param corp the corpus to look the type from.
14435///
14436/// @return the resulting type, if any found.
14437type_base_sptr
14439{
14440 // TODO: finish this.
14441
14442 //TODO: when we fully support types indexed by their location, this
14443 //function should return a vector of types because at each location,
14444 //there can be several types that are defined (yay, C and C++,
14445 //*sigh*).
14446
14447 type_base_sptr result;
14448 ((result = lookup_basic_type_per_location(loc, corp))
14449 || (result = lookup_class_type_per_location(loc, corp))
14450 || (result = lookup_union_type_per_location(loc, corp))
14451 || (result = lookup_enum_type_per_location(loc, corp))
14452 || (result = lookup_typedef_type_per_location(loc, corp)));
14453
14454 return result;
14455}
14456
14457/// Look into a given corpus to find a type
14458///
14459/// If the per-corpus type map is non-empty (because the corpus allows
14460/// the One Definition Rule) then the type islooked up in that
14461/// per-corpus type map. Otherwise, the type is looked-up in each
14462/// translation unit.
14463///
14464/// @param qualified_name the qualified name of the function type to
14465/// look for.
14466///
14467/// @param corp the corpus to look into.
14468///
14469/// @return the function type found.
14470type_base_sptr
14471lookup_type(const type_base&t, const corpus& corp)
14472{
14474 return lookup_type(n, corp);
14475}
14476
14477/// Look into a given corpus to find a type
14478///
14479/// If the per-corpus type map is non-empty (because the corpus allows
14480/// the One Definition Rule) then the type islooked up in that
14481/// per-corpus type map. Otherwise, the type is looked-up in each
14482/// translation unit.
14483///
14484/// @param qualified_name the qualified name of the function type to
14485/// look for.
14486///
14487/// @param corp the corpus to look into.
14488///
14489/// @return the function type found.
14490type_base_sptr
14491lookup_type(const type_base_sptr&t, const corpus& corp)
14492{
14493 if (t)
14494 return lookup_type(*t, corp);
14495 return type_base_sptr();
14496}
14497
14498/// Update the map that associates a fully qualified name of a given
14499/// type to that type.
14500///
14501///
14502/// @param type the type we are considering.
14503///
14504/// @param types_map the map to update. It's a map that assciates a
14505/// fully qualified name of a type to the type itself.
14506///
14507/// @param use_type_name_as_key if true, use the name of the type as
14508/// the key to look it up later. If false, then use the location of
14509/// the type as a key to look it up later.
14510///
14511/// @return true iff the type was added to the map.
14512template<typename TypeKind>
14513bool
14514maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14516 bool use_type_name_as_key = true)
14517{
14519
14520 if (use_type_name_as_key)
14521 s = get_type_name(type);
14522 else if (location l = type->get_location())
14523 {
14524 string str = l.expand();
14525 s = type->get_environment().intern(str);
14526 }
14527
14528 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14529 bool result = false;
14530
14531 if (i == types_map.end())
14532 {
14533 types_map[s].push_back(type);
14534 result = true;
14535 }
14536 else
14537 i->second.push_back(type);
14538
14539 return result;
14540}
14541
14542/// This is the specialization for type @ref class_decl of the
14543/// function template:
14544///
14545/// maybe_update_types_lookup_map<T>(scope_decl*,
14546/// const shared_ptr<T>&,
14547/// istring_type_base_wptrs_map_type&)
14548///
14549/// @param class_type the type to consider.
14550///
14551/// @param types_map the type map to update.
14552///
14553/// @return true iff the type was added to the map.
14554template<>
14555bool
14558 bool use_type_name_as_key)
14559{
14560 class_decl_sptr type = class_type;
14561
14562 bool update_qname_map = true;
14563 if (type->get_is_declaration_only())
14564 {
14565 // Let's try to look through decl-only classes to get their
14566 // definition. But if the class doesn't have a definition then
14567 // we'll keep it.
14568 if (class_decl_sptr def =
14569 is_class_type(class_type->get_definition_of_declaration()))
14570 type = def;
14571 }
14572
14573 if (!update_qname_map)
14574 return false;
14575
14577 if (use_type_name_as_key)
14578 {
14579 string qname = type->get_qualified_name();
14580 s = type->get_environment().intern(qname);
14581 }
14582 else if (location l = type->get_location())
14583 {
14584 string str = l.expand();
14585 s = type->get_environment().intern(str);
14586 }
14587
14588 bool result = false;
14589 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14590 if (i == map.end())
14591 {
14592 map[s].push_back(type);
14593 result = true;
14594 }
14595 else
14596 i->second.push_back(type);
14597
14598 return result;
14599}
14600
14601/// This is the specialization for type @ref function_type of the
14602/// function template:
14603///
14604/// maybe_update_types_lookup_map<T>(scope_decl*,
14605/// const shared_ptr<T>&,
14606/// istring_type_base_wptrs_map_type&)
14607///
14608/// @param scope the scope of the type to consider.
14609///
14610/// @param class_type the type to consider.
14611///
14612/// @param types_map the type map to update.
14613///
14614/// @return true iff the type was added to the map.
14615template<>
14616bool
14618(const function_type_sptr& type,
14620 bool /*use_type_name_as_key*/)
14621{
14622 bool result = false;
14624 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14625 if (i == types_map.end())
14626 {
14627 types_map[s].push_back(type);
14628 result = true;
14629 }
14630 else
14631 i->second.push_back(type);
14632
14633 return result;
14634}
14635
14636/// Update the map that associates the fully qualified name of a basic
14637/// type with the type itself.
14638///
14639/// The per-translation unit type map is updated if no type with this
14640/// name was already existing in that map.
14641///
14642/// If no type with this name did already exist in the per-corpus type
14643/// map, then that per-corpus type map is updated. Otherwise, that
14644/// type is erased from that per-corpus map.
14645///
14646/// @param basic_type the basic type to consider.
14647void
14649{
14650 if (translation_unit *tu = basic_type->get_translation_unit())
14651 maybe_update_types_lookup_map<type_decl>
14652 (basic_type, tu->get_types().basic_types());
14653
14654 if (corpus *type_corpus = basic_type->get_corpus())
14655 {
14656 maybe_update_types_lookup_map<type_decl>
14657 (basic_type,
14658 type_corpus->priv_->get_types().basic_types());
14659
14660 maybe_update_types_lookup_map<type_decl>
14661 (basic_type,
14662 type_corpus->get_type_per_loc_map().basic_types(),
14663 /*use_type_name_as_key*/false);
14664
14665 if (corpus *group = type_corpus->get_group())
14666 {
14667 maybe_update_types_lookup_map<type_decl>
14668 (basic_type,
14669 group->priv_->get_types().basic_types());
14670
14671 maybe_update_types_lookup_map<type_decl>
14672 (basic_type,
14673 group->get_type_per_loc_map().basic_types(),
14674 /*use_type_name_as_key*/false);
14675 }
14676 }
14677
14678}
14679
14680/// Update the map that associates the fully qualified name of a class
14681/// type with the type itself.
14682///
14683/// The per-translation unit type map is updated if no type with this
14684/// name was already existing in that map.
14685///
14686/// If no type with this name did already exist in the per-corpus type
14687/// map, then that per-corpus type map is updated. Otherwise, that
14688/// type is erased from that per-corpus map.
14689///
14690/// @param class_type the class type to consider.
14691void
14693{
14694 if (translation_unit *tu = class_type->get_translation_unit())
14696 (class_type, tu->get_types().class_types());
14697
14698 if (corpus *type_corpus = class_type->get_corpus())
14699 {
14701 (class_type,
14702 type_corpus->priv_->get_types().class_types());
14703
14705 (class_type,
14706 type_corpus->get_type_per_loc_map().class_types(),
14707 /*use_type_name_as_key*/false);
14708
14709 if (corpus *group = type_corpus->get_group())
14710 {
14712 (class_type,
14713 group->priv_->get_types().class_types());
14714
14716 (class_type,
14717 group->get_type_per_loc_map().class_types(),
14718 /*use_type_name_as_key*/false);
14719 }
14720 }
14721}
14722
14723/// Update the map that associates the fully qualified name of a union
14724/// type with the type itself.
14725///
14726/// The per-translation unit type map is updated if no type with this
14727/// name was already existing in that map.
14728///
14729/// If no type with this name did already exist in the per-corpus type
14730/// map, then that per-corpus type map is updated. Otherwise, that
14731/// type is erased from that per-corpus map.
14732///
14733/// @param union_type the union type to consider.
14734void
14735maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14736{
14737 if (translation_unit *tu = union_type->get_translation_unit())
14738 maybe_update_types_lookup_map<union_decl>
14739 (union_type, tu->get_types().union_types());
14740
14741 if (corpus *type_corpus = union_type->get_corpus())
14742 {
14743 maybe_update_types_lookup_map<union_decl>
14744 (union_type,
14745 type_corpus->priv_->get_types().union_types());
14746
14747 maybe_update_types_lookup_map<union_decl>
14748 (union_type,
14749 type_corpus->get_type_per_loc_map().union_types(),
14750 /*use_type_name_as_key*/false);
14751
14752 if (corpus *group = type_corpus->get_group())
14753 {
14754 maybe_update_types_lookup_map<union_decl>
14755 (union_type,
14756 group->priv_->get_types().union_types());
14757
14758 maybe_update_types_lookup_map<union_decl>
14759 (union_type,
14760 group->get_type_per_loc_map().union_types(),
14761 /*use_type_name_as_key*/false);
14762 }
14763 }
14764}
14765
14766/// Update the map that associates the fully qualified name of an enum
14767/// type with the type itself.
14768///
14769/// The per-translation unit type map is updated if no type with this
14770/// name was already existing in that map.
14771///
14772/// If no type with this name did already exist in the per-corpus type
14773/// map, then that per-corpus type map is updated. Otherwise, that
14774/// type is erased from that per-corpus map.
14775///
14776/// @param enum_type the type to consider.
14777void
14779{
14780 if (translation_unit *tu = enum_type->get_translation_unit())
14781 maybe_update_types_lookup_map<enum_type_decl>
14782 (enum_type, tu->get_types().enum_types());
14783
14784 if (corpus *type_corpus = enum_type->get_corpus())
14785 {
14786 maybe_update_types_lookup_map<enum_type_decl>
14787 (enum_type,
14788 type_corpus->priv_->get_types().enum_types());
14789
14790 maybe_update_types_lookup_map<enum_type_decl>
14791 (enum_type,
14792 type_corpus->get_type_per_loc_map().enum_types(),
14793 /*use_type_name_as_key*/false);
14794
14795 if (corpus *group = type_corpus->get_group())
14796 {
14797 maybe_update_types_lookup_map<enum_type_decl>
14798 (enum_type,
14799 group->priv_->get_types().enum_types());
14800
14801 maybe_update_types_lookup_map<enum_type_decl>
14802 (enum_type,
14803 group->get_type_per_loc_map().enum_types(),
14804 /*use_type_name_as_key*/false);
14805 }
14806 }
14807
14808}
14809
14810/// Update the map that associates the fully qualified name of a
14811/// typedef type with the type itself.
14812///
14813/// The per-translation unit type map is updated if no type with this
14814/// name was already existing in that map.
14815///
14816/// If no type with this name did already exist in the per-corpus type
14817/// map, then that per-corpus type map is updated. Otherwise, that
14818/// type is erased from that per-corpus map.
14819///
14820/// @param typedef_type the type to consider.
14821void
14823{
14824 if (translation_unit *tu = typedef_type->get_translation_unit())
14825 maybe_update_types_lookup_map<typedef_decl>
14826 (typedef_type, tu->get_types().typedef_types());
14827
14828 if (corpus *type_corpus = typedef_type->get_corpus())
14829 {
14830 maybe_update_types_lookup_map<typedef_decl>
14831 (typedef_type,
14832 type_corpus->priv_->get_types().typedef_types());
14833
14834 maybe_update_types_lookup_map<typedef_decl>
14835 (typedef_type,
14836 type_corpus->get_type_per_loc_map().typedef_types(),
14837 /*use_type_name_as_key*/false);
14838
14839 if (corpus *group = type_corpus->get_group())
14840 {
14841 maybe_update_types_lookup_map<typedef_decl>
14842 (typedef_type,
14843 group->priv_->get_types().typedef_types());
14844
14845 maybe_update_types_lookup_map<typedef_decl>
14846 (typedef_type,
14847 group->get_type_per_loc_map().typedef_types(),
14848 /*use_type_name_as_key*/false);
14849 }
14850 }
14851}
14852
14853/// Update the map that associates the fully qualified name of a
14854/// qualified type with the type itself.
14855///
14856/// The per-translation unit type map is updated if no type with this
14857/// name was already existing in that map.
14858///
14859/// If no type with this name did already exist in the per-corpus type
14860/// map, then that per-corpus type map is updated. Otherwise, that
14861/// type is erased from that per-corpus map.
14862///
14863/// @param qualified_type the type to consider.
14864void
14865maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14866{
14867 if (translation_unit *tu = qualified_type->get_translation_unit())
14868 maybe_update_types_lookup_map<qualified_type_def>
14869 (qualified_type, tu->get_types().qualified_types());
14870
14871 if (corpus *type_corpus = qualified_type->get_corpus())
14872 {
14873 maybe_update_types_lookup_map<qualified_type_def>
14874 (qualified_type,
14875 type_corpus->priv_->get_types().qualified_types());
14876
14877 if (corpus *group = type_corpus->get_group())
14878 {
14879 maybe_update_types_lookup_map<qualified_type_def>
14880 (qualified_type,
14881 group->priv_->get_types().qualified_types());
14882 }
14883 }
14884}
14885
14886/// Update the map that associates the fully qualified name of a
14887/// pointer type with the type itself.
14888///
14889/// The per-translation unit type map is updated if no type with this
14890/// name was already existing in that map.
14891///
14892/// If no type with this name did already exist in the per-corpus type
14893/// map, then that per-corpus type map is updated. Otherwise, that
14894/// type is erased from that per-corpus map.
14895///
14896/// @param pointer_type the type to consider.
14897void
14899{
14900 if (translation_unit *tu = pointer_type->get_translation_unit())
14901 maybe_update_types_lookup_map<pointer_type_def>
14902 (pointer_type, tu->get_types().pointer_types());
14903
14904 if (corpus *type_corpus = pointer_type->get_corpus())
14905 {
14906 maybe_update_types_lookup_map<pointer_type_def>
14907 (pointer_type,
14908 type_corpus->priv_->get_types().pointer_types());
14909
14910 if (corpus *group = type_corpus->get_group())
14911 {
14912 maybe_update_types_lookup_map<pointer_type_def>
14913 (pointer_type,
14914 group->priv_->get_types().pointer_types());
14915 }
14916 }
14917}
14918
14919/// Update the map that associates the fully qualified name of a
14920/// pointer-to-member type with the type itself.
14921///
14922/// The per-translation unit type map is updated if no type with this
14923/// name was already existing in that map.
14924///
14925/// If no type with this name did already exist in the per-corpus type
14926/// map, then that per-corpus type map is updated. Otherwise, that
14927/// type is erased from that per-corpus map.
14928///
14929/// @param ptr_to_mbr_type the type to consider.
14930void
14932{
14933 if (translation_unit *tu = ptr_to_member->get_translation_unit())
14934 maybe_update_types_lookup_map<ptr_to_mbr_type>
14935 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
14936
14937 if (corpus *type_corpus = ptr_to_member->get_corpus())
14938 {
14939 maybe_update_types_lookup_map<ptr_to_mbr_type>
14940 (ptr_to_member,
14941 type_corpus->priv_->get_types().ptr_to_mbr_types());
14942
14943 if (corpus *group = type_corpus->get_group())
14944 {
14945 maybe_update_types_lookup_map<ptr_to_mbr_type>
14946 (ptr_to_member,
14947 group->priv_->get_types().ptr_to_mbr_types());
14948 }
14949 }
14950}
14951
14952/// Update the map that associates the fully qualified name of a
14953/// reference type with the type itself.
14954///
14955/// The per-translation unit type map is updated if no type with this
14956/// name was already existing in that map.
14957///
14958/// If no type with this name did already exist in the per-corpus type
14959/// map, then that per-corpus type map is updated. Otherwise, that
14960/// type is erased from that per-corpus map.
14961///
14962/// @param reference_type the type to consider.
14963void
14965{
14966 if (translation_unit *tu = reference_type->get_translation_unit())
14967 maybe_update_types_lookup_map<reference_type_def>
14968 (reference_type, tu->get_types().reference_types());
14969
14970 if (corpus *type_corpus = reference_type->get_corpus())
14971 {
14972 maybe_update_types_lookup_map<reference_type_def>
14973 (reference_type,
14974 type_corpus->priv_->get_types().reference_types());
14975
14976 if (corpus *group = type_corpus->get_group())
14977 {
14978 maybe_update_types_lookup_map<reference_type_def>
14979 (reference_type,
14980 group->priv_->get_types().reference_types());
14981 }
14982 }
14983}
14984
14985/// Update the map that associates the fully qualified name of a type
14986/// with the type itself.
14987///
14988/// The per-translation unit type map is updated if no type with this
14989/// name was already existing in that map.
14990///
14991/// If no type with this name did already exist in the per-corpus type
14992/// map, then that per-corpus type map is updated. Otherwise, that
14993/// type is erased from that per-corpus map.
14994///
14995/// @param array_type the type to consider.
14996void
14998{
14999 if (translation_unit *tu = array_type->get_translation_unit())
15000 maybe_update_types_lookup_map<array_type_def>
15001 (array_type, tu->get_types().array_types());
15002
15003 if (corpus *type_corpus = array_type->get_corpus())
15004 {
15005 maybe_update_types_lookup_map<array_type_def>
15006 (array_type,
15007 type_corpus->priv_->get_types().array_types());
15008
15009 maybe_update_types_lookup_map<array_type_def>
15010 (array_type,
15011 type_corpus->get_type_per_loc_map().array_types(),
15012 /*use_type_name_as_key*/false);
15013
15014 if (corpus *group = type_corpus->get_group())
15015 {
15016 maybe_update_types_lookup_map<array_type_def>
15017 (array_type,
15018 group->priv_->get_types().array_types());
15019
15020 maybe_update_types_lookup_map<array_type_def>
15021 (array_type,
15022 group->get_type_per_loc_map().array_types(),
15023 /*use_type_name_as_key*/false);
15024 }
15025 }
15026}
15027
15028/// Update the map that associates the fully qualified name of a type
15029/// with the type itself.
15030///
15031/// The per-translation unit type map is updated if no type with this
15032/// name was already existing in that map.
15033///
15034/// If no type with this name did already exist in the per-corpus type
15035/// map, then that per-corpus type map is updated. Otherwise, that
15036/// type is erased from that per-corpus map.
15037///
15038/// @param subrange_type the type to consider.
15039void
15041(const array_type_def::subrange_sptr& subrange_type)
15042{
15043 if (translation_unit *tu = subrange_type->get_translation_unit())
15044 maybe_update_types_lookup_map<array_type_def::subrange_type>
15045 (subrange_type, tu->get_types().subrange_types());
15046
15047 if (corpus *type_corpus = subrange_type->get_corpus())
15048 {
15049 maybe_update_types_lookup_map<array_type_def::subrange_type>
15050 (subrange_type,
15051 type_corpus->priv_->get_types().subrange_types());
15052
15053 maybe_update_types_lookup_map<array_type_def::subrange_type>
15054 (subrange_type,
15055 type_corpus->get_type_per_loc_map().subrange_types(),
15056 /*use_type_name_as_key*/false);
15057
15058 if (corpus *group = subrange_type->get_corpus())
15059 {
15060 maybe_update_types_lookup_map<array_type_def::subrange_type>
15061 (subrange_type,
15062 group->priv_->get_types().subrange_types());
15063
15064 maybe_update_types_lookup_map<array_type_def::subrange_type>
15065 (subrange_type,
15066 group->get_type_per_loc_map().subrange_types(),
15067 /*use_type_name_as_key*/false);
15068 }
15069 }
15070}
15071
15072/// Update the map that associates the fully qualified name of a
15073/// function type with the type itself.
15074///
15075/// The per-translation unit type map is updated if no type with this
15076/// name was already existing in that map.
15077///
15078/// If no type with this name did already exist in the per-corpus type
15079/// map, then that per-corpus type map is updated. Otherwise, that
15080/// type is erased from that per-corpus map.
15081///
15082/// @param scope the scope of the function type.
15083/// @param fn_type the type to consider.
15084void
15086{
15087 if (translation_unit *tu = fn_type->get_translation_unit())
15089 (fn_type, tu->get_types().function_types());
15090
15091 if (corpus *type_corpus = fn_type->get_corpus())
15092 {
15094 (fn_type,
15095 type_corpus->priv_->get_types().function_types());
15096
15097 if (corpus *group = fn_type->get_corpus())
15098 {
15100 (fn_type,
15101 group->priv_->get_types().function_types());
15102 }
15103 }
15104}
15105
15106/// Update the map that associates the fully qualified name of a type
15107/// declaration with the type itself.
15108///
15109/// The per-translation unit type map is updated if no type with this
15110/// name was already existing in that map.
15111///
15112/// If no type with this name did already exist in the per-corpus type
15113/// map, then that per-corpus type map is updated. Otherwise, that
15114/// type is erased from that per-corpus map.
15115///
15116/// @param decl the declaration of the type to consider.
15117void
15118maybe_update_types_lookup_map(const decl_base_sptr& decl)
15119{
15120 if (!is_type(decl))
15121 return;
15122
15123 if (type_decl_sptr basic_type = is_type_decl(decl))
15125 else if (class_decl_sptr class_type = is_class_type(decl))
15127 else if (union_decl_sptr union_type = is_union_type(decl))
15129 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
15131 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
15132 maybe_update_types_lookup_map(typedef_type);
15133 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
15134 maybe_update_types_lookup_map(qualified_type);
15135 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
15136 maybe_update_types_lookup_map(pointer_type);
15137 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
15138 maybe_update_types_lookup_map(ptr_to_member);
15139 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
15140 maybe_update_types_lookup_map(reference_type);
15141 else if (array_type_def_sptr array_type = is_array_type(decl))
15143 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
15144 maybe_update_types_lookup_map(subrange_type);
15145 else if (function_type_sptr fn_type = is_function_type(decl))
15147 else
15149}
15150
15151/// Update the map that associates the fully qualified name of a type
15152/// with the type itself.
15153///
15154/// The per-translation unit type map is updated if no type with this
15155/// name was already existing in that map.
15156///
15157/// If no type with this name did already exist in the per-corpus type
15158/// map, then that per-corpus type map is updated. Otherwise, that
15159/// type is erased from that per-corpus map.
15160///
15161/// @param type the type to consider.
15162void
15163maybe_update_types_lookup_map(const type_base_sptr& type)
15164{
15165 if (decl_base_sptr decl = get_type_declaration(type))
15167 else if (function_type_sptr fn_type = is_function_type(type))
15169 else
15171}
15172
15173//--------------------------------
15174// </type and decls lookup stuff>
15175// ------------------------------
15176
15177/// In a translation unit, lookup a given type or synthesize it if
15178/// it's a qualified type.
15179///
15180/// So this function first looks the type up in the translation unit.
15181/// If it's found, then OK, it's returned. Otherwise, if it's a
15182/// qualified, reference or pointer or function type (a composite
15183/// type), lookup the underlying type, synthesize the type we want
15184/// from it and return it.
15185///
15186/// If the underlying types is not not found, then give up and return
15187/// nil.
15188///
15189/// @return the type that was found or the synthesized type.
15190type_base_sptr
15191synthesize_type_from_translation_unit(const type_base_sptr& type,
15192 translation_unit& tu)
15193{
15194 type_base_sptr result;
15195
15196 result = lookup_type(type, tu);
15197
15198 if (!result)
15199 {
15200 if (qualified_type_def_sptr qual = is_qualified_type(type))
15201 {
15202 type_base_sptr underlying_type =
15203 synthesize_type_from_translation_unit(qual->get_underlying_type(),
15204 tu);
15205 if (underlying_type)
15206 {
15207 result.reset(new qualified_type_def(underlying_type,
15208 qual->get_cv_quals(),
15209 qual->get_location()));
15210 }
15211 }
15212 else if (pointer_type_def_sptr p = is_pointer_type(type))
15213 {
15214 type_base_sptr pointed_to_type =
15215 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
15216 tu);
15217 if (pointed_to_type)
15218 {
15219 result.reset(new pointer_type_def(pointed_to_type,
15220 p->get_size_in_bits(),
15221 p->get_alignment_in_bits(),
15222 p->get_location()));
15223 }
15224 }
15225 else if (reference_type_def_sptr r = is_reference_type(type))
15226 {
15227 type_base_sptr pointed_to_type =
15228 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
15229 if (pointed_to_type)
15230 {
15231 result.reset(new reference_type_def(pointed_to_type,
15232 r->is_lvalue(),
15233 r->get_size_in_bits(),
15234 r->get_alignment_in_bits(),
15235 r->get_location()));
15236 }
15237 }
15238 else if (function_type_sptr f = is_function_type(type))
15240
15241 if (result)
15242 {
15244 canonicalize(result);
15245 }
15246 }
15247
15248 if (result)
15249 tu.priv_->synthesized_types_.push_back(result);
15250
15251 return result;
15252}
15253
15254/// In a translation unit, lookup the sub-types that make up a given
15255/// function type and if the sub-types are all found, synthesize and
15256/// return a function_type with them.
15257///
15258/// This function is like lookup_function_type_in_translation_unit()
15259/// execept that it constructs the function type from the sub-types
15260/// found in the translation, rather than just looking for the
15261/// function types held by the translation unit. This can be useful
15262/// if the translation unit doesnt hold the function type we are
15263/// looking for (i.e, lookup_function_type_in_translation_unit()
15264/// returned NULL) but we still want to see if the sub-types of the
15265/// function types are present in the translation unit.
15266///
15267/// @param fn_type the function type to consider.
15268///
15269/// @param tu the translation unit to look into.
15270///
15271/// @return the resulting synthesized function type if all its
15272/// sub-types have been found, NULL otherwise.
15275 translation_unit& tu)
15276{
15278
15279 const environment& env = tu.get_environment();
15280
15281 type_base_sptr return_type = fn_type.get_return_type();
15282 type_base_sptr result_return_type;
15283 if (!return_type || env.is_void_type(return_type))
15284 result_return_type = env.get_void_type();
15285 else
15286 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
15287 if (!result_return_type)
15288 return nil;
15289
15291 type_base_sptr parm_type;
15293 for (function_type::parameters::const_iterator i =
15294 fn_type.get_parameters().begin();
15295 i != fn_type.get_parameters().end();
15296 ++i)
15297 {
15298 type_base_sptr t = (*i)->get_type();
15299 parm_type = synthesize_type_from_translation_unit(t, tu);
15300 if (!parm_type)
15301 return nil;
15302 parm.reset(new function_decl::parameter(parm_type,
15303 (*i)->get_index(),
15304 (*i)->get_name(),
15305 (*i)->get_location(),
15306 (*i)->get_variadic_marker(),
15307 (*i)->get_is_artificial()));
15308 parms.push_back(parm);
15309 }
15310
15311 class_or_union_sptr class_type;
15312 const method_type* method = is_method_type(&fn_type);
15313 if (method)
15314 {
15315 class_type = is_class_or_union_type
15317 ABG_ASSERT(class_type);
15318 }
15319
15320 function_type_sptr result_fn_type;
15321
15322 if (class_type)
15323 result_fn_type.reset(new method_type(result_return_type,
15324 class_type,
15325 parms,
15326 method->get_is_const(),
15327 fn_type.get_size_in_bits(),
15328 fn_type.get_alignment_in_bits()));
15329 else
15330 result_fn_type.reset(new function_type(result_return_type,
15331 parms,
15332 fn_type.get_size_in_bits(),
15333 fn_type.get_alignment_in_bits()));
15334
15335 tu.priv_->synthesized_types_.push_back(result_fn_type);
15336 tu.bind_function_type_life_time(result_fn_type);
15337
15338 canonicalize(result_fn_type);
15339 return result_fn_type;
15340}
15341
15342/// Demangle a C++ mangled name and return the resulting string
15343///
15344/// @param mangled_name the C++ mangled name to demangle.
15345///
15346/// @return the resulting mangled name.
15347string
15348demangle_cplus_mangled_name(const string& mangled_name)
15349{
15350 if (mangled_name.empty())
15351 return "";
15352
15353 size_t l = 0;
15354 int status = 0;
15355 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15356 NULL, &l, &status);
15357 string demangled_name = mangled_name;
15358 if (str)
15359 {
15360 ABG_ASSERT(status == 0);
15361 demangled_name = str;
15362 free(str);
15363 str = 0;
15364 }
15365 return demangled_name;
15366}
15367
15368/// Return either the type given in parameter if it's non-null, or the
15369/// void type.
15370///
15371/// @param t the type to consider.
15372///
15373/// @param env the environment to use. If NULL, just abort the
15374/// process.
15375///
15376/// @return either @p t if it is non-null, or the void type.
15377type_base_sptr
15378type_or_void(const type_base_sptr t, const environment& env)
15379{
15380 type_base_sptr r;
15381
15382 if (t)
15383 r = t;
15384 else
15385 r = type_base_sptr(env.get_void_type());
15386
15387 return r;
15388}
15389
15390global_scope::~global_scope()
15391{
15392}
15393
15394/// Test if two types are eligible to the "Linux Kernel Fast Type
15395/// Comparison Optimization", a.k.a LKFTCO.
15396///
15397/// Two types T1 and T2 (who are presumably of the same name and kind)
15398/// are eligible to the LKFTCO if they fulfill the following criteria/
15399///
15400/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15401/// either class, union or enums.
15402///
15403/// 2/ They are defined in the same translation unit.
15404///
15405/// @param t1 the first type to consider.
15406///
15407/// @param t2 the second type to consider.
15408///
15409/// @return true iff t1 and t2 are eligible to the LKFTCO.
15410static bool
15411types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15412 const type_base& t2)
15413{
15414 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15415 string t1_file_path, t2_file_path;
15416
15417 /// If the t1 (and t2) are classes/unions/enums from the same linux
15418 /// kernel corpus, let's move on. Otherwise bail out.
15419 if (!(t1_corpus && t2_corpus
15420 && t1_corpus == t2_corpus
15421 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15422 && (is_class_or_union_type(&t1)
15423 || is_enum_type(&t1))))
15424 return false;
15425
15426 class_or_union *c1 = 0, *c2 = 0;
15427 c1 = is_class_or_union_type(&t1);
15428 c2 = is_class_or_union_type(&t2);
15429
15430 // Two anonymous class types with no naming typedefs cannot be
15431 // eligible to this optimization.
15432 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15433 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15434 return false;
15435
15436 // Two anonymous classes with naming typedefs should have the same
15437 // typedef name.
15438 if (c1
15439 && c2
15440 && c1->get_is_anonymous() && c1->get_naming_typedef()
15441 && c2->get_is_anonymous() && c2->get_naming_typedef())
15442 if (c1->get_naming_typedef()->get_name()
15443 != c2->get_naming_typedef()->get_name())
15444 return false;
15445
15446 // Two anonymous enum types cannot be eligible to this optimization.
15447 if (const enum_type_decl *e1 = is_enum_type(&t1))
15448 if (const enum_type_decl *e2 = is_enum_type(&t2))
15449 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15450 return false;
15451
15452 // Look through declaration-only types. That is, get the associated
15453 // definition type.
15456
15457 if (c1 && c2)
15458 {
15459 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15460 {
15461 if (c1->get_environment().decl_only_class_equals_definition())
15462 // At least one of classes/union is declaration-only.
15463 // Because we are in a context in which a declaration-only
15464 // class/union is equal to all definitions of that
15465 // class/union, we can assume that the two types are
15466 // equal.
15467 return true;
15468 }
15469 }
15470
15471 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15472 return false;
15473
15474 // Look at the file names of the locations of t1 and t2. If they
15475 // are equal, then t1 and t2 are defined in the same file.
15476 {
15477 location l;
15478
15479 if (c1)
15480 l = c1->get_location();
15481 else
15482 l = dynamic_cast<const decl_base&>(t1).get_location();
15483
15484 unsigned line = 0, col = 0;
15485 if (l)
15486 l.expand(t1_file_path, line, col);
15487 if (c2)
15488 l = c2->get_location();
15489 else
15490 l = dynamic_cast<const decl_base&>(t2).get_location();
15491 if (l)
15492 l.expand(t2_file_path, line, col);
15493 }
15494
15495 if (t1_file_path.empty() || t2_file_path.empty())
15496 return false;
15497
15498 if (t1_file_path == t2_file_path)
15499 return true;
15500
15501 return false;
15502}
15503
15504
15505/// Compare a type T against a canonical type.
15506///
15507/// This function is called during the canonicalization process of the
15508/// type T. T is called the "candidate type" because it's in the
15509/// process of being canonicalized. Meaning, it's going to be
15510/// compared to a canonical type C. If T equals C, then the canonical
15511/// type of T is C.
15512///
15513/// The purpose of this function is to allow the debugging of the
15514/// canonicalization of T, if that debugging is activated by
15515/// configuring the libabigail package with
15516/// --enable-debug-type-canonicalization and by running "abidw
15517/// --debug-tc". In that case, T is going to be compared to C twice:
15518/// once with canonical equality and once with structural equality.
15519/// The two comparisons must be equal. Otherwise, the
15520/// canonicalization process is said to be faulty and this function
15521/// aborts.
15522///
15523/// This is a sub-routine of type_base::get_canonical_type_for.
15524///
15525/// @param canonical_type the canonical type to compare the candidate
15526/// type against.
15527///
15528/// @param candidate_type the candidate type to compare against the
15529/// canonical type.
15530///
15531/// @return true iff @p canonical_type equals @p candidate_type.
15532///
15533static bool
15534compare_types_during_canonicalization(const type_base& canonical_type,
15535 const type_base& candidate_type)
15536{
15537#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15538 const environment& env = canonical_type.get_environment();
15539 if (env.debug_type_canonicalization_is_on())
15540 {
15541 bool canonical_equality = false, structural_equality = false;
15542 env.priv_->allow_type_comparison_results_caching(false);
15543 env.priv_->use_canonical_type_comparison_ = false;
15544 structural_equality = canonical_type == candidate_type;
15545 env.priv_->use_canonical_type_comparison_ = true;
15546 canonical_equality = canonical_type == candidate_type;
15547 env.priv_->allow_type_comparison_results_caching(true);
15548 if (canonical_equality != structural_equality)
15549 {
15550 std::cerr << "structural & canonical equality different for type: "
15551 << canonical_type.get_pretty_representation(true, true)
15552 << std::endl;
15554 }
15555 return structural_equality;
15556 }
15557#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15558 return canonical_type == candidate_type;
15559}
15560
15561/// Compare a canonical type against a candidate canonical type.
15562///
15563/// This is ultimately a sub-routine of the
15564/// type_base::get_canonical_type_for().
15565///
15566/// The goal of this function is to ease debugging because it can be
15567/// called from within type_base::get_canonical_type_for() from the
15568/// prompt of the debugger (with some breakpoint appropriately set) to
15569/// debug the comparison that happens during type canonicalization,
15570/// between a candidate type being canonicalized, and an existing
15571/// canonical type that is registered in the system, in as returned by
15572/// environment::get_canonical_types()
15573///
15574/// @param canonical_type the canonical type to consider.
15575///
15576/// @param candidate_type the candidate type that is being
15577/// canonicalized, and thus compared to @p canonical_type.
15578///
15579/// @return true iff @p canonical_type compares equal to @p
15580/// candidate_type.
15581static bool
15582compare_canonical_type_against_candidate(const type_base& canonical_type,
15583 const type_base& candidate_type)
15584{
15585 environment& env = const_cast<environment&>(canonical_type.get_environment());
15586
15587 // Before the "*it == it" comparison below is done, let's
15588 // perform on-the-fly-canonicalization. For C types, let's
15589 // consider that an unresolved struct declaration 'struct S'
15590 // is different from a definition 'struct S'. This is
15591 // because normally, at this point all the declarations of
15592 // struct S that are compatible with the definition of
15593 // struct S have already been resolved to that definition,
15594 // during the DWARF parsing. The remaining unresolved
15595 // declaration are thus considered different. With this
15596 // setup we can properly handle cases of two *different*
15597 // struct S being defined in the same binary (in different
15598 // translation units), and a third struct S being only
15599 // declared as an opaque type in a third translation unit of
15600 // its own, with no definition in there. In that case, the
15601 // declaration-only struct S should be left alone and not
15602 // resolved to any of the two definitions of struct S.
15603 bool saved_decl_only_class_equals_definition =
15604 env.decl_only_class_equals_definition();
15605
15606 // Compare types by considering that decl-only classes don't
15607 // equal their definition.
15608 env.decl_only_class_equals_definition(false);
15609 env.priv_->allow_type_comparison_results_caching(true);
15610 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15611 candidate_type)
15612 || compare_types_during_canonicalization(canonical_type,
15613 candidate_type));
15614 // Restore the state of the on-the-fly-canonicalization and
15615 // the decl-only-class-being-equal-to-a-matching-definition
15616 // flags.
15617 env.priv_->clear_type_comparison_results_cache();
15618 env.priv_->allow_type_comparison_results_caching(false);
15619 env.decl_only_class_equals_definition
15620 (saved_decl_only_class_equals_definition);
15621 return equal;
15622}
15623
15624/// Compare a canonical type against a candidate canonical type.
15625///
15626/// This is ultimately a sub-routine of the
15627/// type_base::get_canonical_type_for().
15628///
15629/// The goal of this function is to ease debugging because it can be
15630/// called from within type_base::get_canonical_type_for() from the
15631/// prompt of the debugger (with some breakpoint appropriately set) to
15632/// debug the comparison that happens during type canonicalization,
15633/// between a candidate type being canonicalized, and an existing
15634/// canonical type that is registered in the system, in as returned by
15635/// environment::get_canonical_types()
15636///
15637/// @param canonical_type the canonical type to consider.
15638///
15639/// @param candidate_type the candidate type that is being
15640/// canonicalized, and thus compared to @p canonical_type.
15641///
15642/// @return true iff @p canonical_type compares equal to @p
15643/// candidate_type.
15644static bool
15645compare_canonical_type_against_candidate(const type_base* canonical_type,
15646 const type_base* candidate_type)
15647{
15648 return compare_canonical_type_against_candidate(*canonical_type,
15649 *candidate_type);
15650}
15651
15652/// Compare a canonical type against a candidate canonical type.
15653///
15654/// This is ultimately a sub-routine of the
15655/// type_base::get_canonical_type_for().
15656///
15657/// The goal of this function is to ease debugging because it can be
15658/// called from within type_base::get_canonical_type_for() from the
15659/// prompt of the debugger (with some breakpoint appropriately set) to
15660/// debug the comparison that happens during type canonicalization,
15661/// between a candidate type being canonicalized, and an existing
15662/// canonical type that is registered in the system, in as returned by
15663/// environment::get_canonical_types()
15664///
15665/// @param canonical_type the canonical type to consider.
15666///
15667/// @param candidate_type the candidate type that is being
15668/// canonicalized, and thus compared to @p canonical_type.
15669///
15670/// @return true iff @p canonical_type compares equal to @p
15671/// candidate_type.
15672static bool
15673compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15674 const type_base_sptr& candidate_type)
15675{
15676 return compare_canonical_type_against_candidate(canonical_type.get(),
15677 candidate_type.get());
15678}
15679
15680/// Test if a candidate for type canonicalization coming from ABIXML
15681/// matches a canonical type by first looking at their hash values.
15682///
15683/// If the two hash values are equal then the candidate is
15684/// structurally compared to the canonical type. If the two hashes
15685/// are different then the two types are considered different and the
15686/// function returns nullptr.
15687///
15688/// If the candidate doesn't come from ABIXML then the function
15689/// returns nullptr.
15690///
15691/// @param cncls the vector of canonical types to consider.
15692///
15693/// @param type the candidate to consider for canonicalization.
15694///
15695/// @return the canonical type from @p cncls that matches the
15696/// candidate @p type.
15697static type_base_sptr
15698candidate_matches_a_canonical_type_hash(const vector<type_base_sptr>& cncls,
15699 type_base& type)
15700{
15701 if (type.get_corpus()
15702 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
15703 && peek_hash_value(type))
15704 {
15705 // The candidate type comes from ABIXML and does have a stashed
15706 // hash value coming from the ABIXML.
15707
15708 // Let's see if we find a potential canonical type whose hash
15709 // matches the stashed hash and whose canonical type index
15710 // matches it too.
15711 for (const auto& c : cncls)
15712 if (peek_hash_value(type) == peek_hash_value(*c))
15714 // We found a potential canonical type which hash matches the
15715 // stashed hash of the candidate type. Let's compare them to
15716 // see if they match.
15717 if (compare_canonical_type_against_candidate(*c, type))
15718 return c;
15719
15720 // Let's do the same things, but just consideing hash values.
15721 for (const auto& c : cncls)
15722 if (peek_hash_value(type) == peek_hash_value(*c))
15723 // We found a potential canonical type which hash matches the
15724 // stashed hash of the candidate type. Let's compare them to
15725 // see if they match.
15726 if (compare_canonical_type_against_candidate(*c, type))
15727 return c;
15728 }
15729
15730 return nullptr;
15731}
15732
15733/// Test if we should attempt to compute a hash value for a given
15734/// type.
15735///
15736/// For now this function returns true only for types originating from
15737/// ELF. For types originating from ABIXML, for instance, the
15738/// function return false, meaning that types originating from ABIXML
15739/// should NOT be hashed.
15740///
15741/// @param t the type to consider.
15742///
15743/// @return true iff @p type should be considered for hashing.
15744bool
15746{
15747 if (t.get_corpus()
15748 && (t.get_corpus()->get_origin() & corpus::ELF_ORIGIN))
15749 return true;
15750 return false;
15751}
15752
15753/// Compute the canonical type for a given instance of @ref type_base.
15754///
15755/// Consider two types T and T'. The canonical type of T, denoted
15756/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15757/// otherwise, to compare two types, one just needs to compare their
15758/// canonical types using pointer equality. That makes type
15759/// comparison faster than the structural comparison performed by the
15760/// abigail::ir::equals() overloads.
15761///
15762/// If there is not yet any canonical type for @p t, then @p t is its
15763/// own canonical type. Otherwise, this function returns the
15764/// canonical type of @p t which is the canonical type that has the
15765/// same hash value as @p t and that structurally equals @p t. Note
15766/// that after invoking this function, the life time of the returned
15767/// canonical time is then equals to the life time of the current
15768/// process.
15769///
15770/// @param t a smart pointer to instance of @ref type_base we want to
15771/// compute a canonical type for.
15772///
15773/// @return the canonical type for the current instance of @ref
15774/// type_base.
15775type_base_sptr
15776type_base::get_canonical_type_for(type_base_sptr t)
15777{
15778 if (!t)
15779 return t;
15780
15781 environment& env = const_cast<environment&>(t->get_environment());
15782
15784 // This type should not be canonicalized!
15785 return type_base_sptr();
15786
15787 if (is_decl(t))
15789
15790 // Look through decl-only types (classes, unions and enums)
15791 bool decl_only_class_equals_definition =
15793
15794 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15795
15796 // In the context of types from C++ or languages where we assume the
15797 // "One Definition Rule", we assume that a declaration-only
15798 // non-anonymous class equals all fully defined classes of the same
15799 // name.
15800 //
15801 // Otherwise, all classes, including declaration-only classes are
15802 // canonicalized and only canonical comparison is going to be used
15803 // in the system.
15804 if (decl_only_class_equals_definition)
15805 if (class_or_union)
15807 return type_base_sptr();
15808
15809 class_decl_sptr is_class = is_class_type(t);
15810 if (t->get_canonical_type())
15811 return t->get_canonical_type();
15812
15813 // For classes and union, ensure that an anonymous class doesn't
15814 // have a linkage name. If it does in the future, then me must be
15815 // mindful that the linkage name respects the type identity
15816 // constraints which states that "if two linkage names are different
15817 // then the two types are different".
15821
15822 // We want the pretty representation of the type, but for an
15823 // internal use, not for a user-facing purpose.
15824 //
15825 // If two classe types Foo are declared, one as a class and the
15826 // other as a struct, but are otherwise equivalent, we want their
15827 // pretty representation to be the same. Hence the 'internal'
15828 // argument of ir::get_pretty_representation() is set to true here.
15829 // So in this case, the pretty representation of Foo is going to be
15830 // "class Foo", regardless of its struct-ness. This also applies to
15831 // composite types which would have "class Foo" as a sub-type.
15832 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15833
15834 // If 't' already has a canonical type 'inside' its corpus
15835 // (t_corpus), then this variable is going to contain that canonical
15836 // type.
15837 type_base_sptr canonical_type_present_in_corpus;
15840
15841 type_base_sptr result;
15842 environment::canonical_types_map_type::iterator i = types.find(repr);
15843
15844 if (i == types.end())
15845 {
15846 vector<type_base_sptr> v;
15847 v.push_back(t);
15848 types[repr] = v;
15849 result = t;
15850 }
15851 else
15852 {
15853 vector<type_base_sptr> &v = i->second;
15854 // Look at the canonical types and if the current candidate type
15855 // coming from abixml has the same hash as one of the canonical
15856 // types, then compare the current candidate with the one with a
15857 // matching hash.
15858 result = candidate_matches_a_canonical_type_hash(v, *t);
15859
15860 // Let's compare 't' structurally (i.e, compare its sub-types
15861 // recursively) against the canonical types of the system. If it
15862 // equals a given canonical type C, then it means C is the
15863 // canonical type of 't'. Otherwise, if 't' is different from
15864 // all the canonical types of the system, then it means 't' is a
15865 // canonical type itself.
15866 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15867 !result && it != v.rend();
15868 ++it)
15869 {
15870 bool equal = compare_canonical_type_against_candidate(*it, t);
15871 if (equal)
15872 {
15873 result = *it;
15874 break;
15875 }
15876 }
15877#ifdef WITH_DEBUG_SELF_COMPARISON
15878 if (env.self_comparison_debug_is_on())
15879 {
15880 // So we are debugging the canonicalization process,
15881 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15882 corpus_sptr corp1, corp2;
15883 env.get_self_comparison_debug_inputs(corp1, corp2);
15884 if (corp1 && corp2 && type_originates_from_corpus(t, corp2)
15885 && corp1->get_origin() != corp2->get_origin()
15886 && corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
15887 {
15888 // If 't' comes from the second corpus, then it *must*
15889 // be equal to its matching canonical type coming from
15890 // the first corpus because the second corpus is the
15891 // abixml representation of the first corpus. In other
15892 // words, all types coming from the second corpus must
15893 // have canonical types coming from the first corpus.
15894 if (result)
15895 {
15896 if (!env.priv_->
15897 check_canonical_type_from_abixml_during_self_comp(t,
15898 result))
15899 {
15900 // The canonical type of the type re-read from abixml
15901 // type doesn't match the canonical type that was
15902 // initially serialized down.
15903 uintptr_t should_have_canonical_type = 0;
15904 string type_id = env.get_type_id_from_type(t.get());
15905 if (type_id.empty())
15906 type_id = "type-id-<not-found>";
15907 else
15908 should_have_canonical_type =
15909 env.get_canonical_type_from_type_id(type_id.c_str());
15910 std::cerr << "error: wrong canonical type for '"
15911 << repr
15912 << "' / type: @"
15913 << std::hex
15914 << t.get()
15915 << "/ canon: @"
15916 << result.get()
15917 << ", type-id: '"
15918 << type_id
15919 << "'. Should have had canonical type: "
15920 << std::hex
15921 << should_have_canonical_type
15922 << std::dec
15923 << std::endl;
15924 }
15925 }
15926 else //!result
15927 {
15928 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
15929 string type_id = env.get_type_id_from_pointer(ptr_val);
15930 if (type_id.empty())
15931 type_id = "type-id-<not-found>";
15932 // We are in the case where 't' is different from all
15933 // the canonical types of the same name that come from
15934 // the first corpus.
15935 //
15936 // If 't' indeed comes from the second corpus then this
15937 // clearly is a canonicalization failure.
15938 //
15939 // There was a problem either during the serialization
15940 // of 't' into abixml, or during the de-serialization
15941 // from abixml into abigail::ir. Further debugging is
15942 // needed to determine what that root cause problem is.
15943 //
15944 // Note that the first canonicalization problem of this
15945 // kind must be fixed before looking at the subsequent
15946 // ones, because the later might well just be
15947 // consequences of the former.
15948 std::cerr << "error: wrong induced canonical type for '"
15949 << repr
15950 << "' from second corpus"
15951 << ", ptr: " << std::hex << t.get()
15952 << " type-id: " << type_id
15953 << " /hash="
15954 << *t->hash_value()
15955 << std::dec
15956 << std::endl;
15957 }
15958 }
15959 if (result)
15960 {
15961 if (!is_type_decl(t))
15962 if (hash_t t_hash = peek_hash_value(*t))
15963 if (hash_t result_hash = peek_hash_value(*result))
15964 if (t_hash != result_hash)
15965 {
15966 std::cerr << "error: type hash mismatch"
15967 << " between type: '"
15968 << repr
15969 << "' @ "
15970 << std::hex
15971 << t.get()
15972 << "/hash="
15973 << *t->hash_value()
15974 << " and its computed canonical type @"
15975 << std::hex
15976 << result.get()
15977 << "/hash="
15978 << std::hex
15979 << *result->hash_value()
15980 << std::dec
15981 << std::endl;
15982 }
15983 }
15984 }
15985#endif //WITH_DEBUG_SELF_COMPARISON
15986
15987 if (!result)
15988 {
15989 v.push_back(t);
15990 result = t;
15991 // we need to generate a canonical type index to sort these
15992 // types that have the same representation and potentially
15993 // same hash value but are canonically different.
15994 t->priv_->canonical_type_index = v.size();
15995 }
15996 }
15997
15998 return result;
15999}
16000
16001/// This method is invoked automatically right after the current
16002/// instance of @ref class_decl has been canonicalized.
16003void
16005{}
16006
16007/// This is a subroutine of the canonicalize() function.
16008///
16009/// When the canonical type C of type T has just been computed, there
16010/// can be cases where T has member functions that C doesn't have.
16011///
16012/// This is possible because non virtual member functions are not
16013/// taken in account when comparing two types.
16014///
16015/// In that case, this function updates C so that it contains the
16016/// member functions.
16017///
16018/// There can also be cases where C has a method M which is not linked
16019/// to any underlying symbol, whereas in T, M is to link to an
16020/// underlying symbol. In that case, this function updates M in C so
16021/// that it's linked to the same underlying symbol as for M in T.
16022static void
16023maybe_adjust_canonical_type(const type_base_sptr& canonical,
16024 const type_base_sptr& type)
16025{
16026 if (type->get_naked_canonical_type())
16027 return;
16028
16029 class_decl_sptr canonical_class = is_class_type(canonical);
16030
16031 if (class_decl_sptr cl = is_class_type(type))
16032 {
16034 if (canonical_class
16035 && canonical_class.get() != cl.get())
16036 {
16037 // Set symbols of member functions that might be missing
16038 // theirs.
16039 for (class_decl::member_functions::const_iterator i =
16040 cl->get_member_functions().begin();
16041 i != cl->get_member_functions().end();
16042 ++i)
16043 if ((*i)->get_symbol())
16044 {
16045 if (method_decl *m = canonical_class->
16046 find_member_function((*i)->get_linkage_name()))
16047 {
16048 elf_symbol_sptr s1 = (*i)->get_symbol();
16049 if (s1 && !m->get_symbol())
16050 // Method 'm' in the canonical type is not
16051 // linked to the underlying symbol of '*i'.
16052 // Let's link it now. have th
16053 m->set_symbol(s1);
16054 }
16055 else
16056 if (canonical_class->get_corpus()
16057 && cl->get_corpus()
16058 && (cl->get_corpus() == canonical_class->get_corpus()))
16059 // There is a member function defined and publicly
16060 // exported in the other class and the canonical
16061 // class doesn't have that member function. This
16062 // should not have happened! For instance, the
16063 // DWARF reader does merge the member functions of
16064 // classes having the same name so that all of them
16065 // end-up having the same member functions. What's
16066 // going on here?
16068 }
16069
16070 // Set symbols of static data members that might be missing
16071 // theirs.
16072 for (const auto& data_member : cl->get_data_members())
16073 {
16074 if (!get_member_is_static(data_member))
16075 continue;
16076 elf_symbol_sptr sym = data_member->get_symbol();
16077 if (!sym)
16078 continue;
16079 const auto& canonical_data_member =
16080 canonical_class->find_data_member(data_member->get_name());
16081 if (!canonical_data_member)
16082 // Hmmh, maybe we
16083 // should consider
16084 // static data members
16085 // when comparing two
16086 // classes for the
16087 // purpose of type
16088 // canonicalization?
16089 continue;
16090 if (!canonical_data_member->get_symbol())
16091 canonical_data_member->set_symbol(sym);
16092 }
16093 }
16094 }
16095
16096 // Make sure the virtual member functions with exported symbols are
16097 // all added to the set of exported functions of the corpus.
16098
16099 // If we are looking at a non-canonicalized class (for instance, a
16100 // decl-only class that has virtual member functions), let's pretend
16101 // it does have a canonical class so that we can perform the
16102 // necessary virtual member function adjustments
16103 if (class_decl_sptr cl = is_class_type(type))
16105 {
16106 ABG_ASSERT(!canonical_class);
16107 canonical_class = cl;
16108 }
16109
16110 if (canonical_class)
16111 {
16112 if (auto abi_corpus = canonical_class->get_corpus())
16113 {
16114 for (auto& fn : canonical_class->get_member_functions())
16115 {
16116 if (elf_symbol_sptr sym = fn->get_symbol())
16117 {
16118 if (sym->is_defined() && sym->is_public())
16119 {
16120 fn->set_is_in_public_symbol_table(true);
16121 auto b = abi_corpus->get_exported_decls_builder();
16122 b->maybe_add_fn_to_exported_fns(fn.get());
16123 }
16124 else if (!sym->is_defined())
16125 abi_corpus->get_undefined_functions().insert(fn.get());
16126 }
16127 }
16128 }
16129 }
16130
16131 // If an artificial function type equals a non-artfificial one in
16132 // the system, then the canonical type of both should be deemed
16133 // non-artificial. This is important because only non-artificial
16134 // canonical function types are emitted out into abixml, so if don't
16135 // do this we risk missing to emit some function types.
16136 if (is_function_type(type))
16137 if (type->get_is_artificial() != canonical->get_is_artificial())
16138 canonical->set_is_artificial(false);
16139}
16140
16141/// Compute the canonical type of a given type.
16142///
16143/// It means that after invoking this function, comparing the intance
16144/// instance @ref type_base and another one (on which
16145/// type_base::enable_canonical_equality() would have been invoked as
16146/// well) is performed by just comparing the pointer values of the
16147/// canonical types of both types. That equality comparison is
16148/// supposedly faster than structural comparison of the types.
16149///
16150/// @param t a smart pointer to the instance of @ref type_base for
16151/// which to compute the canonical type. After this call,
16152/// t->get_canonical_type() will return the newly computed canonical
16153/// type.
16154///
16155/// @param do_log if true then logs are emitted about canonicalization
16156/// progress.
16157///
16158/// @param show_stats if true and if @p do_log is true as well, then
16159/// more detailed logs are emitted about canonicalization.
16160///
16161/// @return the canonical type computed for @p t.
16162type_base_sptr
16163canonicalize(type_base_sptr t, bool do_log, bool show_stats)
16164{
16165 if (!t)
16166 return t;
16167
16168 if (t->get_canonical_type())
16169 return t->get_canonical_type();
16170
16171 if (do_log && show_stats)
16172 std::cerr << "Canonicalization of type '"
16173 << t->get_pretty_representation(true, true)
16174 << "/@#" << std::hex << t.get() << ": ";
16175
16177
16178 if (do_log && show_stats)
16179 tmr.start();
16180 type_base_sptr canonical = type_base::get_canonical_type_for(t);
16181
16182 if (do_log && show_stats)
16183 tmr.stop();
16184
16185 if (do_log && show_stats)
16186 std::cerr << tmr << "\n";
16187
16188 maybe_adjust_canonical_type(canonical, t);
16189
16190 t->priv_->canonical_type = canonical;
16191 t->priv_->naked_canonical_type = canonical.get();
16192
16193 if (canonical)
16194 if (!t->priv_->canonical_type_index)
16195 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
16196
16197 if (class_decl_sptr cl = is_class_type(t))
16198 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
16199 if ((canonical = d->get_canonical_type()))
16200 {
16201 d->priv_->canonical_type = canonical;
16202 d->priv_->naked_canonical_type = canonical.get();
16203 }
16204
16205 if (canonical)
16206 {
16207 if (decl_base_sptr d = is_decl_slow(canonical))
16208 {
16209 scope_decl *scope = d->get_scope();
16210 // Add the canonical type to the set of canonical types
16211 // belonging to its scope.
16212 if (scope)
16213 {
16214 if (is_type(scope))
16215 // The scope in question is itself a type (e.g, a class
16216 // or union). Let's call that type ST. We want to add
16217 // 'canonical' to the set of canonical types belonging
16218 // to ST.
16219 if (type_base_sptr c = is_type(scope)->get_canonical_type())
16220 // We want to add 'canonical' to the set of
16221 // canonical types belonging to the canonical type
16222 // of ST. That way, just looking at the canonical
16223 // type of ST is enough to get the types that belong
16224 // to the scope of the class of equivalence of ST.
16225 scope = is_scope_decl(is_decl(c)).get();
16226 scope->get_canonical_types().insert(canonical);
16227 }
16228 // else, if the type doesn't have a scope, it's not meant to be
16229 // emitted. This can be the case for the result of the
16230 // function strip_typedef, for instance.
16231 }
16232 }
16233
16234 t->on_canonical_type_set();
16235 return canonical;
16236}
16237
16238/// Set the definition of this declaration-only @ref decl_base.
16239///
16240/// @param d the new definition to set.
16241void
16243{
16245 priv_->definition_of_declaration_ = d;
16246 if (type_base *t = is_type(this))
16247 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
16248 t->priv_->canonical_type = canonical_type;
16249
16250 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
16251}
16252
16253/// The constructor of @ref type_base.
16254///
16255/// @param s the size of the type, in bits.
16256///
16257/// @param a the alignment of the type, in bits.
16258type_base::type_base(const environment& e, size_t s, size_t a)
16259 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
16260 priv_(new priv(s, a))
16261{}
16262
16263/// Return the hash value of the current IR node.
16264///
16265/// Note that upon the first invocation, this member functions
16266/// computes the hash value and returns it. Subsequent invocations
16267/// just return the hash value that was previously calculated.
16268///
16269/// @return the hash value of the current IR node.
16270hash_t
16272{
16273 type_base::hash do_hash;
16274 return do_hash(this);
16275}
16276
16277/// Getter of the canonical type of the current instance of @ref
16278/// type_base.
16279///
16280/// @return a smart pointer to the canonical type of the current
16281/// intance of @ref type_base, or an empty smart pointer if the
16282/// current instance of @ref type_base doesn't have any canonical
16283/// type.
16284type_base_sptr
16286{return priv_->canonical_type.lock();}
16287
16288/// Getter of the canonical type pointer.
16289///
16290/// Note that this function doesn't return a smart pointer, but rather
16291/// the underlying pointer managed by the smart pointer. So it's as
16292/// fast as possible. This getter is to be used in code paths that
16293/// are proven to be performance hot spots; especially, when comparing
16294/// sensitive types like class, function, pointers and reference
16295/// types. Those are compared extremely frequently and thus, their
16296/// accessing the canonical type must be fast.
16297///
16298/// @return the canonical type pointer, not managed by a smart
16299/// pointer.
16300type_base*
16302{return priv_->naked_canonical_type;}
16303
16304/// Get the pretty representation of the current type.
16305///
16306/// The pretty representation is retrieved from a cache. If the cache
16307/// is empty, this function computes the pretty representation, put it
16308/// in the cache and returns it.
16309///
16310/// Please note that if this function is called too early in the life
16311/// cycle of the type (before the type is fully constructed), then the
16312/// pretty representation that is cached is going to represent a
16313/// non-complete (and thus wrong) representation of the type. Thus
16314/// this function must be called only once the type is fully
16315/// constructed.
16316///
16317/// @param internal if true, then the pretty representation is to be
16318/// used for purpuses that are internal to the libabigail library
16319/// itself. If you don't know what this means, then you probably
16320/// should set this parameter to "false".
16321///
16322/// @return a reference to a cached @ref interned_string holding the
16323/// pretty representation of the current type.
16324const interned_string&
16326{
16327 if (internal)
16328 {
16329 if (priv_->internal_cached_repr_.empty())
16330 {
16331 string r = ir::get_pretty_representation(this, internal);
16332 priv_->internal_cached_repr_ = get_environment().intern(r);
16333 }
16334 return priv_->internal_cached_repr_;
16335 }
16336
16337 if (priv_->cached_repr_.empty())
16338 {
16339 string r = ir::get_pretty_representation(this, internal);
16340 priv_->cached_repr_ = get_environment().intern(r);
16341 }
16342
16343 return priv_->cached_repr_;
16344}
16345
16346/// Compares two instances of @ref type_base.
16347///
16348/// If the two intances are different, set a bitfield to give some
16349/// insight about the kind of differences there are.
16350///
16351/// @param l the first artifact of the comparison.
16352///
16353/// @param r the second artifact of the comparison.
16354///
16355/// @param k a pointer to a bitfield that gives information about the
16356/// kind of changes there are between @p l and @p r. This one is set
16357/// iff @p is non-null and if the function returns false.
16358///
16359/// Please note that setting k to a non-null value does have a
16360/// negative performance impact because even if @p l and @p r are not
16361/// equal, the function keeps up the comparison in order to determine
16362/// the different kinds of ways in which they are different.
16363///
16364/// @return true if @p l equals @p r, false otherwise.
16365bool
16366equals(const type_base& l, const type_base& r, change_kind* k)
16367{
16368 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
16370 if (!result)
16371 if (k)
16373 ABG_RETURN(result);
16374}
16375
16376/// Return true iff both type declarations are equal.
16377///
16378/// Note that this doesn't test if the scopes of both types are equal.
16379bool
16381{return equals(*this, other, 0);}
16382
16383/// Inequality operator.
16384///
16385///@param other the instance of @ref type_base to compare the current
16386/// instance against.
16387///
16388/// @return true iff the current instance is different from @p other.
16389bool
16391{return !operator==(other);}
16392
16393/// Setter for the size of the type.
16394///
16395/// @param s the new size -- in bits.
16396void
16398{priv_->size_in_bits = s;}
16399
16400/// Getter for the size of the type.
16401///
16402/// @return the size in bits of the type.
16403size_t
16405{return priv_->size_in_bits;}
16406
16407/// Setter for the alignment of the type.
16408///
16409/// @param a the new alignment -- in bits.
16410void
16412{priv_->alignment_in_bits = a;}
16413
16414/// Getter for the alignment of the type.
16415///
16416/// @return the alignment of the type in bits.
16417size_t
16419{return priv_->alignment_in_bits;}
16420
16421/// Default implementation of traversal for types. This function does
16422/// nothing. It must be implemented by every single new type that is
16423/// written.
16424///
16425/// Please look at e.g, class_decl::traverse() for an example of how
16426/// to implement this.
16427///
16428/// @param v the visitor used to visit the type.
16429bool
16431{
16432 if (v.type_node_has_been_visited(this))
16433 return true;
16434
16435 v.visit_begin(this);
16436 bool result = v.visit_end(this);
16438
16439 return result;
16440}
16441
16442type_base::~type_base()
16443{delete priv_;}
16444
16445// </type_base definitions>
16446
16447// <real_type definitions>
16448
16449/// Bitwise OR operator for real_type::modifiers_type.
16450///
16451/// @param l the left-hand side operand.
16452///
16453/// @param r the right-hand side operand.
16454///
16455/// @return the result of the bitwise OR.
16458{
16459 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16460 |
16461 static_cast<unsigned>(r));
16462}
16463
16464/// Bitwise AND operator for real_type::modifiers_type.
16465///
16466/// @param l the left-hand side operand.
16467///
16468/// @param r the right-hand side operand.
16469///
16470/// @return the result of the bitwise AND.
16473{
16474 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16475 &
16476 static_cast<unsigned>(r));
16477}
16478
16479/// Bitwise one's complement operator for real_type::modifiers_type.
16480///
16481/// @param l the left-hand side operand.
16482///
16483/// @param r the right-hand side operand.
16484///
16485/// @return the result of the bitwise one's complement operator.
16488{
16489 return static_cast<real_type::modifiers_type>(~static_cast<unsigned>(l));
16490}
16491
16492/// Bitwise |= operator for real_type::modifiers_type.
16493///
16494/// @param l the left-hand side operand.
16495///
16496/// @param r the right-hand side operand.
16497///
16498/// @return the result of the bitwise |=.
16501{
16502 l = l | r;
16503 return l;
16504}
16505
16506/// Bitwise &= operator for real_type::modifiers_type.
16507///
16508/// @param l the left-hand side operand.
16509///
16510/// @param r the right-hand side operand.
16511///
16512/// @return the result of the bitwise &=.
16515{
16516 l = l & r;
16517 return l;
16518}
16519
16520/// Parse a word containing one real type modifier.
16521///
16522/// A word is considered to be a string of characters that doesn't
16523/// contain any white space.
16524///
16525/// @param word the word to parse. It is considered to be a string of
16526/// characters that doesn't contain any white space.
16527///
16528/// @param modifiers out parameter. It's set by this function to the
16529/// parsed modifier iff the function returned true.
16530///
16531/// @return true iff @word was successfully parsed.
16532static bool
16533parse_real_type_modifier(const string& word,
16534 real_type::modifiers_type &modifiers)
16535{
16536 if (word == "signed")
16537 modifiers |= real_type::SIGNED_MODIFIER;
16538 else if (word == "unsigned")
16539 modifiers |= real_type::UNSIGNED_MODIFIER;
16540 else if (word == "short")
16541 modifiers |= real_type::SHORT_MODIFIER;
16542 else if (word == "long")
16543 modifiers |= real_type::LONG_MODIFIER;
16544 else if (word == "long long")
16545 modifiers |= real_type::LONG_LONG_MODIFIER;
16546 else
16547 return false;
16548
16549 return true;
16550}
16551
16552/// Parse a base type of a real type from a string.
16553///
16554/// @param type_name the type name to parse.
16555///
16556/// @param base out parameter. This is set to the resulting base type
16557/// parsed, iff the function returned true.
16558///
16559/// @return true iff the function could successfully parse the base
16560/// type.
16561static bool
16562parse_base_real_type(const string& type_name,
16564{
16565 if (type_name == "int")
16567 else if (type_name == "char")
16569 else if (type_name == "bool" || type_name == "_Bool")
16571 else if (type_name == "double")
16573 else if (type_name =="float")
16575 else if (type_name == "char16_t")
16577 else if (type_name == "char32_t")
16579 else if (type_name == "wchar_t")
16581 else if (type_name == "__ARRAY_SIZE_TYPE__")
16583 else if (type_name == "sizetype")
16584 base = real_type::SIZE_BASE_TYPE;
16585 else if (type_name == "ssizetype")
16586 base = real_type::SSIZE_BASE_TYPE;
16587 else if (type_name == "bitsizetype")
16588 base = real_type::BIT_SIZE_BASE_TYPE;
16589 else if (type_name == "sbitsizetype")
16590 base = real_type::SBIT_SIZE_BASE_TYPE;
16591 else
16592 return false;
16593
16594 return true;
16595}
16596
16597/// Parse a real type from a string.
16598///
16599/// @param type_name the string containing the real type to parse.
16600///
16601/// @param base out parameter. Is set by this function to the base
16602/// type of the real type, iff the function returned true.
16603///
16604/// @param modifiers out parameter If set by this function to the
16605/// modifier of the real type, iff the function returned true.
16606///
16607/// @return true iff the function could parse a real type from @p
16608/// type_name.
16609static bool
16610parse_real_type(const string& type_name,
16612 real_type::modifiers_type& modifiers)
16613{
16614 string input = type_name;
16615 string::size_type len = input.length();
16616 string::size_type cur_pos = 0, prev_pos = 0;
16617 string cur_word, prev_word;
16618 bool ok = false;
16619
16620 while (cur_pos < len)
16621 {
16622 if (cur_pos < len && isspace(input[cur_pos]))
16623 do
16624 ++cur_pos;
16625 while (cur_pos < len && isspace(input[cur_pos]));
16626
16627 prev_pos = cur_pos;
16628 cur_pos = input.find(' ', prev_pos);
16629 prev_word = cur_word;
16630 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16631
16632 if (cur_pos < len
16633 && cur_word == "long"
16634 && prev_word != "long")
16635 {
16636 if (cur_pos < len && isspace(input[cur_pos]))
16637 do
16638 ++cur_pos;
16639 while (cur_pos < len && isspace(input[cur_pos]));
16640 prev_pos = cur_pos;
16641
16642 cur_pos = input.find(' ', prev_pos);
16643 string saved_prev_word = prev_word;
16644 prev_word = cur_word;
16645 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16646 if (cur_word == "long")
16647 cur_word = "long long";
16648 else
16649 {
16650 cur_pos = prev_pos;
16651 cur_word = prev_word;
16652 prev_word = saved_prev_word;
16653 }
16654 }
16655
16656 if (!parse_real_type_modifier(cur_word, modifiers))
16657 {
16658 if (!parse_base_real_type(cur_word, base))
16659 return false;
16660 else
16661 ok = true;
16662 }
16663 else
16664 ok = true;
16665 }
16666
16667 return ok;
16668}
16669
16670/// Parse a real type from a string.
16671///
16672/// @param str the string containing the real type to parse.
16673///
16674///@param type the resulting @ref real_type. Is set to the result
16675///of the parse, iff the function returns true.
16676///
16677/// @return true iff the function could parse a real type from @p
16678/// str.
16679bool
16680parse_real_type(const string& str, real_type& type)
16681{
16683 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16684
16685 if (!parse_real_type(str, base_type, modifiers))
16686 return false;
16687
16688 // So this is a real type.
16689 real_type int_type(base_type, modifiers);
16690 type = int_type;
16691 return true;
16692}
16693
16694/// Default constructor of the @ref real_type.
16696 : base_(INT_BASE_TYPE),
16697 modifiers_(NO_MODIFIER)
16698{}
16699
16700/// Constructor of the @ref real_type.
16701///
16702/// @param b the base type of the real type.
16703///
16704/// @param m the modifiers of the real type.
16706 : base_(b), modifiers_(m)
16707{}
16708
16709/// Constructor of the @ref real_type.
16710///
16711/// @param the name of the real type to parse to initialize the
16712/// current instance of @ref real_type.
16713real_type::real_type(const string& type_name)
16714 : base_(INT_BASE_TYPE),
16715 modifiers_(NO_MODIFIER)
16716{
16717 bool could_parse = parse_real_type(type_name, base_, modifiers_);
16718 ABG_ASSERT(could_parse);
16719}
16720
16721/// Getter of the base type of the @ref real_type.
16722///
16723/// @return the base type of the @ref real_type.
16726{return base_;}
16727
16728/// Getter of the modifiers bitmap of the @ref real_type.
16729///
16730/// @return the modifiers bitmap of the @ref real_type.
16733{return modifiers_;}
16734
16735/// Setter of the modifiers bitmap of the @ref real_type.
16736///
16737/// @param m the new modifiers.
16738void
16740{modifiers_ = m;}
16741
16742/// Equality operator for the @ref real_type.
16743///
16744/// @param other the other real type to compare against.
16745///
16746/// @return true iff @p other equals the current instance of @ref
16747/// real_type.
16748bool
16750{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16751
16752/// Return the string representation of the current instance of @ref
16753/// real_type.
16754///
16755/// @param internal if true the string representation is to be used
16756/// for internal purposes. In general, it means it's for type
16757/// canonicalization purposes.
16758///
16759/// @return the string representation of the current instance of @ref
16760/// real_type.
16761string
16762real_type::to_string(bool internal) const
16763{
16764 string result;
16765
16766 // Look at modifiers ...
16767 if (modifiers_ & SIGNED_MODIFIER)
16768 result += "signed ";
16769 if (modifiers_ & UNSIGNED_MODIFIER)
16770 result += "unsigned ";
16771 if (!internal)
16772 {
16773 // For canonicalization purposes, we won't emit the "short, long, or
16774 // long long" modifiers. This is because on some platforms, "long
16775 // int" and "long long int" might have the same size. In those
16776 // cases, we want the two types to be equivalent if they have the
16777 // same size. If they don't have the same internal string
16778 // representation, they'd automatically have different canonical
16779 // types and thus be canonically different.
16780 if (modifiers_ & SHORT_MODIFIER)
16781 result += "short ";
16782 if (modifiers_ & LONG_MODIFIER)
16783 result += "long ";
16784 if (modifiers_ & LONG_LONG_MODIFIER)
16785 result += "long long ";
16786 }
16787
16788 // ... and look at base types.
16789 if (base_ == INT_BASE_TYPE)
16790 result += "int";
16791 else if (base_ == CHAR_BASE_TYPE)
16792 result += "char";
16793 else if (base_ == BOOL_BASE_TYPE)
16794 result += "bool";
16795 else if (base_ == DOUBLE_BASE_TYPE)
16796 result += "double";
16797 else if (base_ == FLOAT_BASE_TYPE)
16798 result += "float";
16799 else if (base_ == CHAR16_T_BASE_TYPE)
16800 result += "char16_t";
16801 else if (base_ == CHAR32_T_BASE_TYPE)
16802 result += "char32_t";
16803 else if (base_ == WCHAR_T_BASE_TYPE)
16804 result += "wchar_t";
16805 else if (base_ == ARRAY_SIZE_BASE_TYPE)
16806 result += "__ARRAY_SIZE_TYPE__";
16807 else if (base_ == SIZE_BASE_TYPE)
16808 result += "sizetype";
16809 else if (base_ == SSIZE_BASE_TYPE)
16810 result += "ssizetype";
16811 else if (base_ == BIT_SIZE_BASE_TYPE)
16812 result += "bitsizetype";
16813 else if (base_ == SBIT_SIZE_BASE_TYPE)
16814 result += "sbitsizetype";
16815 return result;
16816}
16817
16818/// Convert the current instance of @ref real_type into its string
16819/// representation.
16820///
16821/// @return the string representation of the current instance of @ref
16822/// real_type.
16823real_type::operator string() const
16824{return to_string();}
16825
16826// </real_type definitions>
16827
16828//<type_decl definitions>
16829
16830/// Constructor.
16831///
16832/// @param env the environment we are operating from.
16833///
16834/// @param name the name of the type declaration.
16835///
16836/// @param size_in_bits the size of the current type_decl, in bits.
16837///
16838/// @param alignment_in_bits the alignment of the current typ, in
16839/// bits.
16840///
16841/// @param locus the source location of the current type declaration.
16842///
16843/// @param linkage_name the linkage_name of the current type declaration.
16844///
16845/// @param vis the visibility of the type declaration.
16846type_decl::type_decl(const environment& env,
16847 const string& name,
16848 size_t size_in_bits,
16849 size_t alignment_in_bits,
16850 const location& locus,
16851 const string& linkage_name,
16852 visibility vis)
16853
16854 : type_or_decl_base(env,
16855 BASIC_TYPE
16856 | ABSTRACT_TYPE_BASE
16857 | ABSTRACT_DECL_BASE),
16858 decl_base(env, name, locus, linkage_name, vis),
16859 type_base(env, size_in_bits, alignment_in_bits)
16860{
16862
16864 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16865 real_type int_type(base_type, modifiers);
16866 if (parse_real_type(name, int_type))
16867 {
16868 // Convert the real_type into its canonical string
16869 // representation.
16870 string real_type_name = int_type;
16871
16872 // Set the name of this type_decl to the canonical string
16873 // representation above
16874 set_name(real_type_name);
16876
16877 if (!get_linkage_name().empty())
16878 set_linkage_name(real_type_name);
16879 }
16880}
16881
16882/// Return the hash value of the current IR node.
16883///
16884/// Note that upon the first invocation, this member functions
16885/// computes the hash value and returns it. Subsequent invocations
16886/// just return the hash value that was previously calculated.
16887///
16888/// @return the hash value of the current IR node.
16889hash_t
16891{
16893 return h;
16894}
16895
16896/// Compares two instances of @ref type_decl.
16897///
16898/// If the two intances are different, set a bitfield to give some
16899/// insight about the kind of differences there are.
16900///
16901/// @param l the first artifact of the comparison.
16902///
16903/// @param r the second artifact of the comparison.
16904///
16905/// @param k a pointer to a bitfield that gives information about the
16906/// kind of changes there are between @p l and @p r. This one is set
16907/// iff @p k is non-null and the function returns false.
16908///
16909/// Please note that setting k to a non-null value does have a
16910/// negative performance impact because even if @p l and @p r are not
16911/// equal, the function keeps up the comparison in order to determine
16912/// the different kinds of ways in which they are different.
16913///
16914/// @return true if @p l equals @p r, false otherwise.
16915bool
16916equals(const type_decl& l, const type_decl& r, change_kind* k)
16917{
16918 bool result = false;
16919
16920 // Consider the types as decls to compare their decls-related
16921 // properties.
16922 result = equals(static_cast<const decl_base&>(l),
16923 static_cast<const decl_base&>(r),
16924 k);
16925 if (!k && !result)
16927
16928 // Now consider the types a "types' to compare their size-related
16929 // properties.
16930 result &= equals(static_cast<const type_base&>(l),
16931 static_cast<const type_base&>(r),
16932 k);
16933 ABG_RETURN(result);
16934}
16935
16936/// Return true if both types equals.
16937///
16938/// This operator re-uses the overload that takes a decl_base.
16939///
16940/// Note that this does not check the scopes of any of the types.
16941///
16942/// @param o the other type_decl to check agains.
16943bool
16945{
16946 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16947 if (!other)
16948 return false;
16949 return *this == *other;
16950}
16951
16952/// Return true if both types equals.
16953///
16954/// Note that this does not check the scopes of any of the types.
16955///
16956/// @param o the other type_decl to check against.
16957bool
16959{
16960 const type_decl* other = dynamic_cast<const type_decl*>(&o);
16961 if (!other)
16962 return false;
16963 return try_canonical_compare(this, other);
16964}
16965
16966/// Return true if both types equals.
16967///
16968/// Note that this does not check the scopes of any of the types.
16969///
16970/// @param o the other type_decl to check against.
16971///
16972/// @return true iff the current isntance equals @p o
16973bool
16975{
16976 const decl_base& other = o;
16977 return *this == other;
16978}
16979
16980/// Return true if both types equals.
16981///
16982/// Note that this does not check the scopes of any of the types.
16983///
16984/// @param o the other type_decl to check against.
16985///
16986/// @return true iff the current isntance equals @p o
16987bool
16989{return !operator==(o);}
16990
16991/// Return true if both types equals.
16992///
16993/// Note that this does not check the scopes of any of the types.
16994///
16995/// @param o the other type_decl to check against.
16996///
16997/// @return true iff the current isntance equals @p o
16998bool
17000{return !operator==(o);}
17001
17002/// Inequality operator.
17003///
17004/// @param o the other type to compare against.
17005///
17006/// @return true iff the current instance is different from @p o.
17007bool
17009{return !operator==(o);}
17010
17011/// Equality operator for @ref type_decl_sptr.
17012///
17013/// @param l the first operand to compare.
17014///
17015/// @param r the second operand to compare.
17016///
17017/// @return true iff @p l equals @p r.
17018bool
17020{
17021 if (!!l != !!r)
17022 return false;
17023 if (l.get() == r.get())
17024 return true;
17025 return *l == *r;
17026}
17027
17028/// Inequality operator for @ref type_decl_sptr.
17029///
17030/// @param l the first operand to compare.
17031///
17032/// @param r the second operand to compare.
17033///
17034/// @return true iff @p l is different from @p r.
17035bool
17037{return !operator==(l, r);}
17038
17039/// Implementation for the virtual qualified name builder for @ref
17040/// type_decl.
17041///
17042/// @param qualified_name the output parameter to hold the resulting
17043/// qualified name.
17044///
17045/// @param internal set to true if the call is intended for an
17046/// internal use (for technical use inside the library itself), false
17047/// otherwise. If you don't know what this is for, then set it to
17048/// false.
17049void
17051 bool internal) const
17052{qualified_name = get_qualified_name(internal);}
17053
17054/// Implementation for the virtual qualified name builder for @ref
17055/// type_decl.
17056///
17057/// @param qualified_name the output parameter to hold the resulting
17058/// qualified name.
17059///
17060/// @param internal set to true if the call is intended for an
17061/// internal use (for technical use inside the library itself), false
17062/// otherwise. If you don't know what this is for, then set it to
17063/// false.
17064const interned_string&
17066{
17067 const environment& env = get_environment();
17068
17069
17070 if (internal)
17071 if (is_real_type(this))
17072 {
17074 {
17075 if (decl_base::priv_->internal_qualified_name_.empty())
17076 decl_base::priv_->internal_qualified_name_ =
17077 env.intern(get_internal_real_type_name(this));
17078 return decl_base::priv_->internal_qualified_name_;
17079 }
17080 else
17081 {
17082 decl_base::priv_->temporary_internal_qualified_name_ =
17083 env.intern(get_internal_real_type_name(this));
17084 return decl_base::priv_->temporary_internal_qualified_name_;
17085 }
17086 }
17087
17088 return decl_base::get_qualified_name(/*internal=*/false);
17089}
17090
17091/// Get the pretty representation of the current instance of @ref
17092/// type_decl.
17093///
17094/// @param internal set to true if the call is intended to get a
17095/// representation of the decl (or type) for the purpose of canonical
17096/// type comparison. This is mainly used in the function
17097/// type_base::get_canonical_type_for().
17098///
17099/// In other words if the argument for this parameter is true then the
17100/// call is meant for internal use (for technical use inside the
17101/// library itself), false otherwise. If you don't know what this is
17102/// for, then set it to false.
17103///
17104/// @param qualified_name if true, names emitted in the pretty
17105/// representation are fully qualified.
17106///
17107/// @return the pretty representatin of the @ref type_decl.
17108string
17110 bool qualified_name) const
17111{
17112 if (internal)
17113 if (is_real_type(this))
17114 return get_internal_real_type_name(this);
17115
17116 if (qualified_name)
17117 return get_qualified_name(internal);
17118 return get_name();
17119}
17120
17121/// This implements the ir_traversable_base::traverse pure virtual
17122/// function.
17123///
17124/// @param v the visitor used on the current instance.
17125///
17126/// @return true if the entire IR node tree got traversed, false
17127/// otherwise.
17128bool
17130{
17131 if (v.type_node_has_been_visited(this))
17132 return true;
17133
17134 v.visit_begin(this);
17135 bool result = v.visit_end(this);
17137
17138 return result;
17139}
17140
17141type_decl::~type_decl()
17142{}
17143//</type_decl definitions>
17144
17145// <scope_type_decl definitions>
17146
17147/// Constructor.
17148///
17149/// @param env the environment we are operating from.
17150///
17151/// @param name the name of the type.
17152///
17153/// @param size_in_bits the size of the type, in bits.
17154///
17155/// @param alignment_in_bits the alignment of the type, in bits.
17156///
17157/// @param locus the source location where the type is defined.
17158///
17159/// @param vis the visibility of the type.
17160scope_type_decl::scope_type_decl(const environment& env,
17161 const string& name,
17162 size_t size_in_bits,
17163 size_t alignment_in_bits,
17164 const location& locus,
17165 visibility vis)
17166 : type_or_decl_base(env,
17167 ABSTRACT_SCOPE_TYPE_DECL
17168 | ABSTRACT_TYPE_BASE
17169 | ABSTRACT_DECL_BASE),
17170 decl_base(env, name, locus, "", vis),
17171 type_base(env, size_in_bits, alignment_in_bits),
17172 scope_decl(env, name, locus)
17173{}
17174
17175/// Compares two instances of @ref scope_type_decl.
17176///
17177/// If the two intances are different, set a bitfield to give some
17178/// insight about the kind of differences there are.
17179///
17180/// @param l the first artifact of the comparison.
17181///
17182/// @param r the second artifact of the comparison.
17183///
17184/// @param k a pointer to a bitfield that gives information about the
17185/// kind of changes there are between @p l and @p r. This one is set
17186/// iff @p k is non-null and the function returns false.
17187///
17188/// Please note that setting k to a non-null value does have a
17189/// negative performance impact because even if @p l and @p r are not
17190/// equal, the function keeps up the comparison in order to determine
17191/// the different kinds of ways in which they are different.
17192///
17193/// @return true if @p l equals @p r, false otherwise.
17194bool
17196{
17197 bool result = equals(static_cast<const scope_decl&>(l),
17198 static_cast<const scope_decl&>(r),
17199 k);
17200
17201 if (!k && !result)
17203
17204 result &= equals(static_cast<const type_base&>(l),
17205 static_cast<const type_base&>(r),
17206 k);
17207
17208 ABG_RETURN(result);
17209}
17210
17211/// Equality operator between two scope_type_decl.
17212///
17213/// Note that this function does not consider the scope of the scope
17214/// types themselves.
17215///
17216/// @return true iff both scope types are equal.
17217bool
17219{
17220 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
17221 if (!other)
17222 return false;
17223 return try_canonical_compare(this, other);
17224}
17225
17226/// Equality operator between two scope_type_decl.
17227///
17228/// This re-uses the equality operator that takes a decl_base.
17229///
17230/// @param o the other scope_type_decl to compare against.
17231///
17232/// @return true iff both scope types are equal.
17233bool
17235{
17236 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17237 if (!other)
17238 return false;
17239
17240 return *this == *other;
17241}
17242
17243/// Traverses an instance of @ref scope_type_decl, visiting all the
17244/// sub-types and decls that it might contain.
17245///
17246/// @param v the visitor that is used to visit every IR sub-node of
17247/// the current node.
17248///
17249/// @return true if either
17250/// - all the children nodes of the current IR node were traversed
17251/// and the calling code should keep going with the traversing.
17252/// - or the current IR node is already being traversed.
17253/// Otherwise, returning false means that the calling code should not
17254/// keep traversing the tree.
17255bool
17257{
17258 if (visiting())
17259 return true;
17260
17261 if (v.type_node_has_been_visited(this))
17262 return true;
17263
17264 if (v.visit_begin(this))
17265 {
17266 visiting(true);
17267 for (scope_decl::declarations::const_iterator i =
17268 get_member_decls().begin();
17269 i != get_member_decls ().end();
17270 ++i)
17271 if (!(*i)->traverse(v))
17272 break;
17273 visiting(false);
17274 }
17275
17276 bool result = v.visit_end(this);
17278
17279 return result;
17280}
17281
17282scope_type_decl::~scope_type_decl()
17283{}
17284// </scope_type_decl definitions>
17285
17286// <namespace_decl>
17287
17288/// Constructor.
17289///
17290/// @param the environment we are operatin from.
17291///
17292/// @param name the name of the namespace.
17293///
17294/// @param locus the source location where the namespace is defined.
17295///
17296/// @param vis the visibility of the namespace.
17298 const string& name,
17299 const location& locus,
17300 visibility vis)
17301 // We need to call the constructor of decl_base directly here
17302 // because it is virtually inherited by scope_decl. Note that we
17303 // just implicitely call the default constructor for scope_decl
17304 // here, as what we really want is to initialize the decl_base
17305 // subobject. Wow, virtual inheritance is useful, but setting it
17306 // up is ugly.
17307 : type_or_decl_base(env,
17308 NAMESPACE_DECL
17309 | ABSTRACT_DECL_BASE
17310 | ABSTRACT_SCOPE_DECL),
17311 decl_base(env, name, locus, "", vis),
17312 scope_decl(env, name, locus)
17313{
17315}
17316
17317/// Build and return a copy of the pretty representation of the
17318/// namespace.
17319///
17320/// @param internal set to true if the call is intended to get a
17321/// representation of the decl (or type) for the purpose of canonical
17322/// type comparison. This is mainly used in the function
17323/// type_base::get_canonical_type_for().
17324///
17325/// In other words if the argument for this parameter is true then the
17326/// call is meant for internal use (for technical use inside the
17327/// library itself), false otherwise. If you don't know what this is
17328/// for, then set it to false.
17329///
17330/// @param qualified_name if true, names emitted in the pretty
17331/// representation are fully qualified.
17332///
17333/// @return a copy of the pretty representation of the namespace.
17334string
17336 bool qualified_name) const
17337{
17338 string r =
17339 "namespace " + scope_decl::get_pretty_representation(internal,
17340 qualified_name);
17341 return r;
17342}
17343
17344/// Return true iff both namespaces and their members are equal.
17345///
17346/// Note that this function does not check if the scope of these
17347/// namespaces are equal.
17348bool
17350{
17351 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
17352 if (!other)
17353 return false;
17354 return scope_decl::operator==(*other);
17355}
17356
17357/// Test if the current namespace_decl is empty or contains empty
17358/// namespaces itself.
17359///
17360/// @return true iff the current namespace_decl is empty or contains
17361/// empty itself.
17362bool
17364{
17365 if (is_empty())
17366 return true;
17367
17368 for (declarations::const_iterator i = get_member_decls().begin();
17369 i != get_member_decls().end();
17370 ++i)
17371 {
17372 if (!is_namespace(*i))
17373 return false;
17374
17376 ABG_ASSERT(ns);
17377
17378 if (!ns->is_empty_or_has_empty_sub_namespaces())
17379 return false;
17380 }
17381
17382 return true;
17383}
17384
17385/// This implements the ir_traversable_base::traverse pure virtual
17386/// function.
17387///
17388/// @param v the visitor used on the current instance and on its
17389/// member nodes.
17390///
17391/// @return true if the entire IR node tree got traversed, false
17392/// otherwise.
17393bool
17395{
17396 if (visiting())
17397 return true;
17398
17399 if (v.visit_begin(this))
17400 {
17401 visiting(true);
17402 scope_decl::declarations::const_iterator i;
17403 for (i = get_member_decls().begin();
17404 i != get_member_decls ().end();
17405 ++i)
17406 {
17408 dynamic_pointer_cast<ir_traversable_base>(*i);
17409 if (t)
17410 if (!t->traverse (v))
17411 break;
17412 }
17413 visiting(false);
17414 }
17415 return v.visit_end(this);
17416}
17417
17418namespace_decl::~namespace_decl()
17419{
17420}
17421
17422// </namespace_decl>
17423
17424// <qualified_type_def>
17425
17426/// Type of the private data of qualified_type_def.
17427class qualified_type_def::priv
17428{
17429 friend class qualified_type_def;
17430
17431 qualified_type_def::CV cv_quals_;
17432 // Before the type is canonicalized, this is used as a temporary
17433 // internal name.
17434 interned_string temporary_internal_name_;
17435 // Once the type is canonicalized, this is used as the internal
17436 // name.
17437 interned_string internal_name_;
17438 weak_ptr<type_base> underlying_type_;
17439
17440 priv()
17441 : cv_quals_(CV_NONE)
17442 {}
17443
17444 priv(qualified_type_def::CV quals,
17445 type_base_sptr t)
17446 : cv_quals_(quals),
17447 underlying_type_(t)
17448 {}
17449
17450 priv(qualified_type_def::CV quals)
17451 : cv_quals_(quals)
17452 {}
17453};// end class qualified_type_def::priv
17454
17455/// Build the name of the current instance of qualified type.
17456///
17457/// @param fully_qualified if true, build a fully qualified name.
17458///
17459/// @param internal set to true if the call is intended for an
17460/// internal use (for technical use inside the library itself), false
17461/// otherwise. If you don't know what this is for, then set it to
17462/// false.
17463///
17464/// @return a copy of the newly-built name.
17465string
17466qualified_type_def::build_name(bool fully_qualified, bool internal) const
17467{
17468 type_base_sptr t = get_underlying_type();
17469 if (!t)
17470 // The qualified type might temporarily have no underlying type,
17471 // especially during the construction of the type, while the
17472 // underlying type is not yet constructed. In that case, let's do
17473 // like if the underlying type is the 'void' type.
17475
17477 fully_qualified,
17478 internal);
17479}
17480
17481/// This function is automatically invoked whenever an instance of
17482/// this type is canonicalized.
17483///
17484/// It's an overload of the virtual type_base::on_canonical_type_set.
17485///
17486/// We put here what is thus meant to be executed only at the point of
17487/// type canonicalization.
17488void
17491
17492/// Constructor of the qualified_type_def
17493///
17494/// @param type the underlying type
17495///
17496/// @param quals a bitfield representing the const/volatile qualifiers
17497///
17498/// @param locus the location of the qualified type definition
17499qualified_type_def::qualified_type_def(type_base_sptr type,
17500 CV quals,
17501 const location& locus)
17502 : type_or_decl_base(type->get_environment(),
17503 QUALIFIED_TYPE
17504 | ABSTRACT_TYPE_BASE
17505 | ABSTRACT_DECL_BASE),
17506 type_base(type->get_environment(), type->get_size_in_bits(),
17507 type->get_alignment_in_bits()),
17508 decl_base(type->get_environment(), "", locus, "",
17509 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
17510 priv_(new priv(quals, type))
17511{
17513 interned_string name = type->get_environment().intern(build_name(false));
17514 set_name(name);
17515}
17516
17517/// Constructor of the qualified_type_def
17518///
17519/// @param env the environment of the type.
17520///
17521/// @param quals a bitfield representing the const/volatile qualifiers
17522///
17523/// @param locus the location of the qualified type definition
17524qualified_type_def::qualified_type_def(const environment& env,
17525 CV quals,
17526 const location& locus)
17527 : type_or_decl_base(env,
17528 QUALIFIED_TYPE
17529 | ABSTRACT_TYPE_BASE
17530 | ABSTRACT_DECL_BASE),
17531 type_base(env, /*size_in_bits=*/0,
17532 /*alignment_in_bits=*/0),
17533 decl_base(env, "", locus, ""),
17534 priv_(new priv(quals))
17535{
17537 // We don't yet have an underlying type. So for naming purpose,
17538 // let's temporarily pretend the underlying type is 'void'.
17539 interned_string name = env.intern("void");
17540 set_name(name);
17541}
17542
17543/// Return the hash value of the current IR node.
17544///
17545/// Note that upon the first invocation, this member functions
17546/// computes the hash value and returns it. Subsequent invocations
17547/// just return the hash value that was previously calculated.
17548///
17549/// @return the hash value of the current IR node.
17550hash_t
17552{
17554 return h;
17555}
17556
17557/// Get the size of the qualified type def.
17558///
17559/// This is an overload for type_base::get_size_in_bits().
17560///
17561/// @return the size of the qualified type.
17562size_t
17564{
17565 size_t s = 0;
17566 if (type_base_sptr ut = get_underlying_type())
17567 {
17568 // We do have the underlying type properly set, so let's make
17569 // the size of the qualified type match the size of its
17570 // underlying type.
17571 s = ut->get_size_in_bits();
17572 if (s != type_base::get_size_in_bits())
17573 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
17574 }
17576}
17577
17578/// Compares two instances of @ref qualified_type_def.
17579///
17580/// If the two intances are different, set a bitfield to give some
17581/// insight about the kind of differences there are.
17582///
17583/// @param l the first artifact of the comparison.
17584///
17585/// @param r the second artifact of the comparison.
17586///
17587/// @param k a pointer to a bitfield that gives information about the
17588/// kind of changes there are between @p l and @p r. This one is set
17589/// iff @p k is non-null and the function returns false.
17590///
17591/// Please note that setting k to a non-null value does have a
17592/// negative performance impact because even if @p l and @p r are not
17593/// equal, the function keeps up the comparison in order to determine
17594/// the different kinds of ways in which they are different.
17595///
17596/// @return true if @p l equals @p r, false otherwise.
17597bool
17599{
17600 bool result = true;
17601 if (l.get_cv_quals() != r.get_cv_quals())
17602 {
17603 result = false;
17604 if (k)
17606 else
17608 }
17609
17611 {
17612 result = false;
17613 if (k)
17614 {
17616 r.get_underlying_type().get()))
17617 // Underlying type changes in which the structure of the
17618 // type changed are considered local changes to the
17619 // qualified type.
17621 else
17622 *k |= SUBTYPE_CHANGE_KIND;
17623 }
17624 else
17625 // okay strictly speaking this is not necessary, but I am
17626 // putting it here to maintenance; that is, so that adding
17627 // subsequent clauses needed to compare two qualified types
17628 // later still works.
17630 }
17631
17632 ABG_RETURN(result);
17633}
17634
17635/// Equality operator for qualified types.
17636///
17637/// Note that this function does not check for equality of the scopes.
17638///
17639///@param o the other qualified type to compare against.
17640///
17641/// @return true iff both qualified types are equal.
17642bool
17644{
17645 const qualified_type_def* other =
17646 dynamic_cast<const qualified_type_def*>(&o);
17647 if (!other)
17648 return false;
17649 return try_canonical_compare(this, other);
17650}
17651
17652/// Equality operator for qualified types.
17653///
17654/// Note that this function does not check for equality of the scopes.
17655/// Also, this re-uses the equality operator above that takes a
17656/// decl_base.
17657///
17658///@param o the other qualified type to compare against.
17659///
17660/// @return true iff both qualified types are equal.
17661bool
17663{
17664 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17665 if (!other)
17666 return false;
17667 return *this == *other;
17668}
17669
17670/// Equality operator for qualified types.
17671///
17672/// Note that this function does not check for equality of the scopes.
17673/// Also, this re-uses the equality operator above that takes a
17674/// decl_base.
17675///
17676///@param o the other qualified type to compare against.
17677///
17678/// @return true iff both qualified types are equal.
17679bool
17681{
17682 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17683 if (!other)
17684 return false;
17685 return *this == *other;
17686}
17687
17688/// Implementation for the virtual qualified name builder for @ref
17689/// qualified_type_def.
17690///
17691/// @param qualified_name the output parameter to hold the resulting
17692/// qualified name.
17693///
17694/// @param internal set to true if the call is intended for an
17695/// internal use (for technical use inside the library itself), false
17696/// otherwise. If you don't know what this is for, then set it to
17697/// false.
17698void
17700 bool internal) const
17701{qualified_name = get_qualified_name(internal);}
17702
17703/// Implementation of the virtual qualified name builder/getter.
17704///
17705/// @param internal set to true if the call is intended for an
17706/// internal use (for technical use inside the library itself), false
17707/// otherwise. If you don't know what this is for, then set it to
17708/// false.
17709///
17710/// @return the resulting qualified name.
17711const interned_string&
17713{
17714 const environment& env = get_environment();
17715
17716
17717 if (!get_canonical_type())
17718 {
17719 // The type hasn't been canonicalized yet. We want to return a
17720 // temporary name that is not cached because the structure of
17721 // this type (and so its name) can change until its
17722 // canonicalized.
17723 if (internal)
17724 {
17725 // We are asked to return a temporary *internal* name.
17726 // Lets compute it and return a reference to where it's
17727 // stored.
17728 if (priv_->temporary_internal_name_.empty())
17729 priv_->temporary_internal_name_ =
17730 env.intern(build_name(true, /*internal=*/true));
17731 return priv_->temporary_internal_name_;
17732 }
17733 else
17734 {
17735 // We are asked to return a temporary non-internal name.
17737 (env.intern(build_name(true, /*internal=*/false)));
17739 }
17740 }
17741 else
17742 {
17743 // The type has already been canonicalized. We want to return
17744 // the definitive name and cache it.
17745 if (internal)
17746 {
17747 if (priv_->internal_name_.empty())
17748 priv_->internal_name_ =
17749 env.intern(build_name(/*qualified=*/true,
17750 /*internal=*/true));
17751 return priv_->internal_name_;
17752 }
17753 else
17754 {
17755 if (peek_qualified_name().empty())
17757 (env.intern(build_name(/*qualified=*/true,
17758 /*internal=*/false)));
17759 return peek_qualified_name();
17760 }
17761 }
17762}
17763
17764/// This implements the ir_traversable_base::traverse pure virtual
17765/// function.
17766///
17767/// @param v the visitor used on the current instance.
17768///
17769/// @return true if the entire IR node tree got traversed, false
17770/// otherwise.
17771bool
17773{
17774 if (v.type_node_has_been_visited(this))
17775 return true;
17776
17777 if (visiting())
17778 return true;
17779
17780 if (v.visit_begin(this))
17781 {
17782 visiting(true);
17783 if (type_base_sptr t = get_underlying_type())
17784 t->traverse(v);
17785 visiting(false);
17786 }
17787 bool result = v.visit_end(this);
17789 return result;
17790}
17791
17792qualified_type_def::~qualified_type_def()
17793{
17794}
17795
17796/// Getter of the const/volatile qualifier bit field
17799{return priv_->cv_quals_;}
17800
17801/// Setter of the const/value qualifiers bit field
17802void
17804{priv_->cv_quals_ = cv_quals;}
17805
17806/// Compute and return the string prefix or suffix representing the
17807/// qualifiers hold by the current instance of @ref
17808/// qualified_type_def.
17809///
17810/// @return the newly-built cv string.
17811string
17813{return get_string_representation_of_cv_quals(priv_->cv_quals_);}
17814
17815/// Getter of the underlying type
17816type_base_sptr
17818{return priv_->underlying_type_.lock();}
17819
17820/// Setter of the underlying type.
17821///
17822/// @param t the new underlying type.
17823void
17825{
17826 ABG_ASSERT(t);
17827 priv_->underlying_type_ = t;
17828 // Now we need to update other properties that depend on the new underlying type.
17829 set_size_in_bits(t->get_size_in_bits());
17830 set_alignment_in_bits(t->get_alignment_in_bits());
17832 set_name(name);
17833 if (scope_decl* s = get_scope())
17834 {
17835 // Now that the name has been updated, we need to update the
17836 // lookup maps accordingly.
17837 scope_decl::declarations::iterator i;
17838 if (s->find_iterator_for_member(this, i))
17840 else
17842 }
17843}
17844
17845/// Non-member equality operator for @ref qualified_type_def
17846///
17847/// @param l the left-hand side of the equality operator
17848///
17849/// @param r the right-hand side of the equality operator
17850///
17851/// @return true iff @p l and @p r equals.
17852bool
17853operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17854{
17855 if (l.get() == r.get())
17856 return true;
17857 if (!!l != !!r)
17858 return false;
17859
17860 return *l == *r;
17861}
17862
17863/// Non-member inequality operator for @ref qualified_type_def
17864///
17865/// @param l the left-hand side of the equality operator
17866///
17867/// @param r the right-hand side of the equality operator
17868///
17869/// @return true iff @p l and @p r equals.
17870bool
17871operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17872{return ! operator==(l, r);}
17873
17874/// Overloaded bitwise OR operator for cv qualifiers.
17877{
17878 return static_cast<qualified_type_def::CV>
17879 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17880}
17881
17882/// Overloaded bitwise |= operator for cv qualifiers.
17885{
17886 l = l | r;
17887 return l;
17888}
17889
17890/// Overloaded bitwise &= operator for cv qualifiers.
17893{
17894 l = l & r;
17895 return l;
17896}
17897
17898/// Overloaded bitwise AND operator for CV qualifiers.
17901{
17902 return static_cast<qualified_type_def::CV>
17903 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17904}
17905
17906/// Overloaded bitwise inverting operator for CV qualifiers.
17909{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17910
17911/// Streaming operator for qualified_type_decl::CV
17912///
17913/// @param o the output stream to serialize the cv qualifier to.
17914///
17915/// @param cv the cv qualifier to serialize.
17916///
17917/// @return the output stream used.
17918std::ostream&
17919operator<<(std::ostream& o, qualified_type_def::CV cv)
17920{
17921 string str;
17922
17923 switch (cv)
17924 {
17925 case qualified_type_def::CV_NONE:
17926 str = "none";
17927 break;
17928 case qualified_type_def::CV_CONST:
17929 str = "const";
17930 break;
17931 case qualified_type_def::CV_VOLATILE:
17932 str = "volatile";
17933 break;
17934 case qualified_type_def::CV_RESTRICT:
17935 str = "restrict";
17936 break;
17937 }
17938
17939 o << str;
17940 return o;
17941}
17942
17943// </qualified_type_def>
17944
17945//<pointer_type_def definitions>
17946
17947/// Private data structure of the @ref pointer_type_def.
17948struct pointer_type_def::priv
17949{
17950 type_base_wptr pointed_to_type_;
17951 type_base* naked_pointed_to_type_;
17952 interned_string internal_qualified_name_;
17953 interned_string temp_internal_qualified_name_;
17954
17955 priv(const type_base_sptr& t)
17956 : pointed_to_type_(type_or_void(t, t->get_environment())),
17957 naked_pointed_to_type_(t.get())
17958 {}
17959
17960 priv()
17961 : naked_pointed_to_type_()
17962 {}
17963}; //end struct pointer_type_def
17964
17965/// This function is automatically invoked whenever an instance of
17966/// this type is canonicalized.
17967///
17968/// It's an overload of the virtual type_base::on_canonical_type_set.
17969///
17970/// We put here what is thus meant to be executed only at the point of
17971/// type canonicalization.
17972void
17975
17976
17977///Constructor of @ref pointer_type_def.
17978///
17979/// @param pointed_to the pointed-to type.
17980///
17981/// @param size_in_bits the size of the type, in bits.
17982///
17983/// @param align_in_bits the alignment of the type, in bits.
17984///
17985/// @param locus the source location where the type was defined.
17986pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
17987 size_t size_in_bits,
17988 size_t align_in_bits,
17989 const location& locus)
17990 : type_or_decl_base(pointed_to->get_environment(),
17991 POINTER_TYPE
17992 | ABSTRACT_TYPE_BASE
17993 | ABSTRACT_DECL_BASE),
17994 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17995 decl_base(pointed_to->get_environment(), "", locus, ""),
17996 priv_(new priv(pointed_to))
17997{
17999 try
18000 {
18001 ABG_ASSERT(pointed_to);
18002 const environment& env = pointed_to->get_environment();
18003 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18004 string name = (pto ? pto->get_name() : string("void")) + "*";
18005 set_name(env.intern(name));
18006 if (pto)
18007 set_visibility(pto->get_visibility());
18008 }
18009 catch (...)
18010 {}
18011}
18012
18013///Constructor of @ref pointer_type_def.
18014///
18015/// @param env the environment of the type.
18016///
18017/// @param size_in_bits the size of the type, in bits.
18018///
18019/// @param align_in_bits the alignment of the type, in bits.
18020///
18021/// @param locus the source location where the type was defined.
18022pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
18023 size_t alignment_in_bits,
18024 const location& locus)
18025 : type_or_decl_base(env,
18026 POINTER_TYPE
18027 | ABSTRACT_TYPE_BASE
18028 | ABSTRACT_DECL_BASE),
18029 type_base(env, size_in_bits, alignment_in_bits),
18030 decl_base(env, "", locus, ""),
18031 priv_(new priv())
18032{
18034 string name = string("void") + "*";
18035 set_name(env.intern(name));
18036}
18037
18038/// Return the hash value of the current IR node.
18039///
18040/// Note that upon the first invocation, this member functions
18041/// computes the hash value and returns it. Subsequent invocations
18042/// just return the hash value that was previously calculated.
18043///
18044/// @return the hash value of the current IR node.
18045hash_t
18047{
18049 return h;
18050}
18051
18052/// Set the pointed-to type of the pointer.
18053///
18054/// @param t the new pointed-to type.
18055void
18057{
18058 ABG_ASSERT(t);
18059 priv_->pointed_to_type_ = t;
18060 priv_->naked_pointed_to_type_ = t.get();
18061
18062 try
18063 {
18064 const environment& env = t->get_environment();
18065 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
18066 string name = (pto ? pto->get_name() : string("void")) + "*";
18067 set_name(env.intern(name));
18068 if (pto)
18069 set_visibility(pto->get_visibility());
18070 }
18071 catch (...)
18072 {}
18073}
18074
18075/// Compares two instances of @ref pointer_type_def.
18076///
18077/// If the two intances are different, set a bitfield to give some
18078/// insight about the kind of differences there are.
18079///
18080/// @param l the first artifact of the comparison.
18081///
18082/// @param r the second artifact of the comparison.
18083///
18084/// @param k a pointer to a bitfield that gives information about the
18085/// kind of changes there are between @p l and @p r. This one is set
18086/// iff @p k is non-null and the function returns false.
18087///
18088/// Please note that setting k to a non-null value does have a
18089/// negative performance impact because even if @p l and @p r are not
18090/// equal, the function keeps up the comparison in order to determine
18091/// the different kinds of ways in which they are different.
18092///
18093/// @return true if @p l equals @p r, false otherwise.
18094bool
18096{
18097 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18098 bool result = p1 == p2;
18099 if (!result)
18100 if (k)
18101 {
18102 if (!types_have_similar_structure(&l, &r))
18103 // pointed-to type changes in which the structure of the
18104 // type changed are considered local changes to the pointer
18105 // type.
18107 *k |= SUBTYPE_CHANGE_KIND;
18108 }
18109
18110 ABG_RETURN(result);
18111}
18112
18113/// Return true iff both instances of pointer_type_def are equal.
18114///
18115/// Note that this function does not check for the scopes of the this
18116/// types.
18117bool
18119{
18120 const pointer_type_def* other = is_pointer_type(&o);
18121 if (!other)
18122 return false;
18123 return try_canonical_compare(this, other);
18124}
18125
18126/// Return true iff both instances of pointer_type_def are equal.
18127///
18128/// Note that this function does not check for the scopes of the
18129/// types.
18130///
18131/// @param other the other type to compare against.
18132///
18133/// @return true iff @p other equals the current instance.
18134bool
18136{
18137 const decl_base* o = is_decl(&other);
18138 if (!o)
18139 return false;
18140 return *this == *o;
18141}
18142
18143/// Return true iff both instances of pointer_type_def are equal.
18144///
18145/// Note that this function does not check for the scopes of the
18146/// types.
18147///
18148/// @param other the other type to compare against.
18149///
18150/// @return true iff @p other equals the current instance.
18151bool
18153{
18154 const decl_base& o = other;
18155 return *this == o;
18156}
18157
18158/// Getter of the pointed-to type.
18159///
18160/// @return the pointed-to type.
18161const type_base_sptr
18163{return priv_->pointed_to_type_.lock();}
18164
18165/// Getter of a naked pointer to the pointed-to type.
18166///
18167/// @return a naked pointed to the pointed-to type.
18168type_base*
18170{return priv_->naked_pointed_to_type_;}
18171
18172/// Build and return the qualified name of the current instance of
18173/// @ref pointer_type_def.
18174///
18175/// @param qn output parameter. The resulting qualified name.
18176///
18177/// @param internal set to true if the call is intended for an
18178/// internal use (for technical use inside the library itself), false
18179/// otherwise. If you don't know what this is for, then set it to
18180/// false.
18181void
18183{qn = get_qualified_name(internal);}
18184
18185/// Build, cache and return the qualified name of the current instance
18186/// of @ref pointer_type_def. Subsequent invocations of this function
18187/// return the cached value.
18188///
18189/// Note that this function should work even if the underlying type is
18190/// momentarily empty.
18191///
18192/// @param internal set to true if the call is intended for an
18193/// internal use (for technical use inside the library itself), false
18194/// otherwise. If you don't know what this is for, then set it to
18195/// false.
18196///
18197/// @return the resulting qualified name.
18198const interned_string&
18200{
18201 type_base* pointed_to_type = get_naked_pointed_to_type();
18202 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18203
18204 if (internal)
18205 {
18206 if (get_canonical_type())
18207 {
18208 if (priv_->internal_qualified_name_.empty())
18209 if (pointed_to_type)
18210 priv_->internal_qualified_name_ =
18211 pointer_declaration_name(this,
18212 /*variable_name=*/"",
18213 /*qualified_name=*/
18214 is_typedef(pointed_to_type)
18215 ? false
18216 : true,
18217 /*internal=*/true);
18218 return priv_->internal_qualified_name_;
18219 }
18220 else
18221 {
18222 // As the type hasn't yet been canonicalized, its structure
18223 // (and so its name) can change. So let's invalidate the
18224 // cache where we store its name at each invocation of this
18225 // function.
18226 if (pointed_to_type)
18227 if (priv_->temp_internal_qualified_name_.empty())
18228 priv_->temp_internal_qualified_name_ =
18229 pointer_declaration_name(this,
18230 /*variable_name=*/"",
18231 /*qualified_name=*/
18232 is_typedef(pointed_to_type)
18233 ? false
18234 : true,
18235 /*internal=*/true);
18236 return priv_->temp_internal_qualified_name_;
18237 }
18238 }
18239 else
18240 {
18242 {
18243 if (decl_base::peek_qualified_name().empty())
18245 (pointer_declaration_name(this,
18246 /*variable_name=*/"",
18247 /*qualified_name=*/true,
18248 /*internal=*/false));
18250 }
18251 else
18252 {
18253 // As the type hasn't yet been canonicalized, its structure
18254 // (and so its name) can change. So let's invalidate the
18255 // cache where we store its name at each invocation of this
18256 // function.
18257 if (pointed_to_type)
18259 (pointer_declaration_name(this,
18260 /*variable_name=*/"",
18261 /*qualified_name=*/true,
18262 /*internal=*/false));
18264 }
18265 }
18266}
18267
18268/// This implements the ir_traversable_base::traverse pure virtual
18269/// function.
18270///
18271/// @param v the visitor used on the current instance.
18272///
18273/// @return true if the entire IR node tree got traversed, false
18274/// otherwise.
18275bool
18277{
18278 if (v.type_node_has_been_visited(this))
18279 return true;
18280
18281 if (visiting())
18282 return true;
18283
18284 if (v.visit_begin(this))
18285 {
18286 visiting(true);
18287 if (type_base_sptr t = get_pointed_to_type())
18288 t->traverse(v);
18289 visiting(false);
18290 }
18291
18292 bool result = v.visit_end(this);
18294 return result;
18295}
18296
18297pointer_type_def::~pointer_type_def()
18298{}
18299
18300/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
18301/// equality; that is, make it compare the pointed to objects too.
18302///
18303/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18304/// of the equality.
18305///
18306/// @param r the shared_ptr of @ref pointer_type_def on
18307/// right-hand-side of the equality.
18308///
18309/// @return true if the @ref pointer_type_def pointed to by the
18310/// shared_ptrs are equal, false otherwise.
18311bool
18313{
18314 if (l.get() == r.get())
18315 return true;
18316 if (!!l != !!r)
18317 return false;
18318
18319 return *l == *r;
18320}
18321
18322/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
18323/// equality; that is, make it compare the pointed to objects too.
18324///
18325/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18326/// of the equality.
18327///
18328/// @param r the shared_ptr of @ref pointer_type_def on
18329/// right-hand-side of the equality.
18330///
18331/// @return true iff the @ref pointer_type_def pointed to by the
18332/// shared_ptrs are different.
18333bool
18335{return !operator==(l, r);}
18336
18337// </pointer_type_def definitions>
18338
18339// <reference_type_def definitions>
18340
18341/// Private data structure of the @ref reference_type_def type.
18342struct reference_type_def::priv
18343{
18344
18345 type_base_wptr pointed_to_type_;
18346 bool is_lvalue_;
18347 interned_string internal_qualified_name_;
18348 interned_string temp_internal_qualified_name_;
18349
18350 priv(const type_base_sptr& t, bool is_lvalue)
18351 : pointed_to_type_(type_or_void(t, t->get_environment())),
18352 is_lvalue_(is_lvalue)
18353 {}
18354
18355 priv(bool is_lvalue)
18356 : is_lvalue_(is_lvalue)
18357 {}
18358
18359 priv() = delete;
18360};
18361
18362/// This function is automatically invoked whenever an instance of
18363/// this type is canonicalized.
18364///
18365/// It's an overload of the virtual type_base::on_canonical_type_set.
18366///
18367/// We put here what is thus meant to be executed only at the point of
18368/// type canonicalization.
18369void
18372
18373/// Constructor of the reference_type_def type.
18374///
18375/// @param pointed_to the pointed to type.
18376///
18377/// @param lvalue wether the reference is an lvalue reference. If
18378/// false, the reference is an rvalue one.
18379///
18380/// @param size_in_bits the size of the type, in bits.
18381///
18382/// @param align_in_bits the alignment of the type, in bits.
18383///
18384/// @param locus the source location of the type.
18385reference_type_def::reference_type_def(const type_base_sptr pointed_to,
18386 bool lvalue,
18387 size_t size_in_bits,
18388 size_t align_in_bits,
18389 const location& locus)
18390 : type_or_decl_base(pointed_to->get_environment(),
18391 REFERENCE_TYPE
18392 | ABSTRACT_TYPE_BASE
18393 | ABSTRACT_DECL_BASE),
18394 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18395 decl_base(pointed_to->get_environment(), "", locus, ""),
18396 priv_(new priv(pointed_to, lvalue))
18397{
18399
18400 try
18401 {
18402 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18403 string name;
18404 if (pto)
18405 {
18406 set_visibility(pto->get_visibility());
18407 name = string(pto->get_name()) + "&";
18408 }
18409 else
18410 name = string(get_type_name(is_function_type(pointed_to),
18411 /*qualified_name=*/true)) + "&";
18412
18413 if (!is_lvalue())
18414 name += "&";
18415 const environment& env = pointed_to->get_environment();
18416 set_name(env.intern(name));
18417 }
18418 catch (...)
18419 {}
18420}
18421
18422/// Constructor of the reference_type_def type.
18423///
18424/// This one creates a type that has no pointed-to type, temporarily.
18425/// This is useful for cases where the underlying type is not yet
18426/// available. It can be set later using
18427/// reference_type_def::set_pointed_to_type().
18428///
18429/// @param env the environment of the type.
18430///
18431/// @param lvalue wether the reference is an lvalue reference. If
18432/// false, the reference is an rvalue one.
18433///
18434/// @param size_in_bits the size of the type, in bits.
18435///
18436/// @param align_in_bits the alignment of the type, in bits.
18437///
18438/// @param locus the source location of the type.
18439reference_type_def::reference_type_def(const environment& env, bool lvalue,
18440 size_t size_in_bits,
18441 size_t alignment_in_bits,
18442 const location& locus)
18443 : type_or_decl_base(env,
18444 REFERENCE_TYPE
18445 | ABSTRACT_TYPE_BASE
18446 | ABSTRACT_DECL_BASE),
18447 type_base(env, size_in_bits, alignment_in_bits),
18448 decl_base(env, "", locus, ""),
18449 priv_(new priv(lvalue))
18450{
18452 string name = "void&";
18453 if (!is_lvalue())
18454 name += "&";
18455
18456 set_name(env.intern(name));
18457 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
18458}
18459
18460/// Return the hash value of the current IR node.
18461///
18462/// Note that upon the first invocation, this member functions
18463/// computes the hash value and returns it. Subsequent invocations
18464/// just return the hash value that was previously calculated.
18465///
18466/// @return the hash value of the current IR node.
18467hash_t
18469{
18471 return h;
18472}
18473
18474/// Setter of the pointed_to type of the current reference type.
18475///
18476/// @param pointed_to the new pointed to type.
18477void
18478reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
18479{
18480 ABG_ASSERT(pointed_to_type);
18481 priv_->pointed_to_type_ = pointed_to_type;
18482
18483 decl_base_sptr pto;
18484 try
18485 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18486 catch (...)
18487 {}
18488
18489 if (pto)
18490 {
18491 set_visibility(pto->get_visibility());
18492 string name = string(pto->get_name()) + "&";
18493 if (!is_lvalue())
18494 name += "&";
18495 const environment& env = pto->get_environment();
18496 set_name(env.intern(name));
18497 }
18498}
18499
18500/// Compares two instances of @ref reference_type_def.
18501///
18502/// If the two intances are different, set a bitfield to give some
18503/// insight about the kind of differences there are.
18504///
18505/// @param l the first artifact of the comparison.
18506///
18507/// @param r the second artifact of the comparison.
18508///
18509/// @param k a pointer to a bitfield that gives information about the
18510/// kind of changes there are between @p l and @p r. This one is set
18511/// iff @p k is non-null and the function returns false.
18512///
18513/// Please note that setting k to a non-null value does have a
18514/// negative performance impact because even if @p l and @p r are not
18515/// equal, the function keeps up the comparison in order to determine
18516/// the different kinds of ways in which they are different.
18517///
18518/// @return true if @p l equals @p r, false otherwise.
18519bool
18521{
18522 if (l.is_lvalue() != r.is_lvalue())
18523 {
18524 if (k)
18527 }
18528 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18529 bool result = p1 == p2;
18530 if (!result)
18531 if (k)
18532 {
18533 if (!types_have_similar_structure(&l, &r))
18535 *k |= SUBTYPE_CHANGE_KIND;
18536 }
18537 ABG_RETURN(result);
18538}
18539
18540/// Equality operator of the @ref reference_type_def type.
18541///
18542/// @param o the other instance of @ref reference_type_def to compare
18543/// against.
18544///
18545/// @return true iff the two instances are equal.
18546bool
18548{
18549 const reference_type_def* other =
18550 dynamic_cast<const reference_type_def*>(&o);
18551 if (!other)
18552 return false;
18553 return try_canonical_compare(this, other);
18554}
18555
18556/// Equality operator of the @ref reference_type_def type.
18557///
18558/// @param o the other instance of @ref reference_type_def to compare
18559/// against.
18560///
18561/// @return true iff the two instances are equal.
18562bool
18564{
18565 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18566 if (!other)
18567 return false;
18568 return *this == *other;
18569}
18570
18571/// Equality operator of the @ref reference_type_def type.
18572///
18573/// @param o the other instance of @ref reference_type_def to compare
18574/// against.
18575///
18576/// @return true iff the two instances are equal.
18577bool
18579{
18580 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18581 if (!other)
18582 return false;
18583 return *this == *other;
18584}
18585
18586type_base_sptr
18587reference_type_def::get_pointed_to_type() const
18588{return priv_->pointed_to_type_.lock();}
18589
18590bool
18591reference_type_def::is_lvalue() const
18592{return priv_->is_lvalue_;}
18593
18594/// Build and return the qualified name of the current instance of the
18595/// @ref reference_type_def.
18596///
18597/// @param qn output parameter. Is set to the newly-built qualified
18598/// name of the current instance of @ref reference_type_def.
18599///
18600/// @param internal set to true if the call is intended for an
18601/// internal use (for technical use inside the library itself), false
18602/// otherwise. If you don't know what this is for, then set it to
18603/// false.
18604void
18606{qn = get_qualified_name(internal);}
18607
18608/// Build, cache and return the qualified name of the current instance
18609/// of the @ref reference_type_def. Subsequent invocations of this
18610/// function return the cached value.
18611///
18612/// @param internal set to true if the call is intended for an
18613/// internal use (for technical use inside the library itself), false
18614/// otherwise. If you don't know what this is for, then set it to
18615/// false.
18616///
18617/// @return the newly-built qualified name of the current instance of
18618/// @ref reference_type_def.
18619const interned_string&
18621{
18622 type_base_sptr pointed_to_type = get_pointed_to_type();
18623 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18624
18625 if (internal)
18626 {
18627 if (get_canonical_type())
18628 {
18629 if (priv_->internal_qualified_name_.empty())
18630 if (pointed_to_type)
18631 priv_->internal_qualified_name_ =
18632 get_name_of_reference_to_type(*pointed_to_type,
18633 is_lvalue(),
18634 /*qualified_name=*/
18635 is_typedef(pointed_to_type)
18636 ? false
18637 : true,
18638 /*internal=*/true);
18639 return priv_->internal_qualified_name_;
18640 }
18641 else
18642 {
18643 // As the type hasn't yet been canonicalized, its structure
18644 // (and so its name) can change. So let's invalidate the
18645 // cache where we store its name at each invocation of this
18646 // function.
18647 if (pointed_to_type)
18648 if (priv_->temp_internal_qualified_name_.empty())
18649 priv_->temp_internal_qualified_name_ =
18650 get_name_of_reference_to_type(*pointed_to_type,
18651 is_lvalue(),
18652 /*qualified_name=*/
18653 is_typedef(pointed_to_type)
18654 ? false
18655 : true,
18656 /*internal=*/true);
18657 return priv_->temp_internal_qualified_name_;
18658 }
18659 }
18660 else
18661 {
18663 {
18665 (get_name_of_reference_to_type(*pointed_to_type,
18666 is_lvalue(),
18667 /*qualified_name=*/true,
18668 /*internal=*/false));
18670 }
18671 else
18672 {
18673 // As the type hasn't yet been canonicalized, its structure
18674 // (and so its name) can change. So let's invalidate the
18675 // cache where we store its name at each invocation of this
18676 // function.
18677 if (pointed_to_type)
18679 (get_name_of_reference_to_type(*pointed_to_type,
18680 is_lvalue(),
18681 /*qualified_name=*/true,
18682 /*internal=*/false));
18684 }
18685 }
18686}
18687
18688/// Get the pretty representation of the current instance of @ref
18689/// reference_type_def.
18690///
18691/// @param internal set to true if the call is intended to get a
18692/// representation of the decl (or type) for the purpose of canonical
18693/// type comparison. This is mainly used in the function
18694/// type_base::get_canonical_type_for().
18695///
18696/// In other words if the argument for this parameter is true then the
18697/// call is meant for internal use (for technical use inside the
18698/// library itself), false otherwise. If you don't know what this is
18699/// for, then set it to false.
18700///
18701/// @param qualified_name if true, names emitted in the pretty
18702/// representation are fully qualified.
18703///
18704/// @return the pretty representatin of the @ref reference_type_def.
18705string
18707 bool qualified_name) const
18708{
18709 string result =
18711 (get_pointed_to_type()),
18712 is_lvalue(),
18713 qualified_name,
18714 internal);
18715
18716 return result;
18717}
18718
18719/// This implements the ir_traversable_base::traverse pure virtual
18720/// function.
18721///
18722/// @param v the visitor used on the current instance.
18723///
18724/// @return true if the entire IR node tree got traversed, false
18725/// otherwise.
18726bool
18728{
18729 if (v.type_node_has_been_visited(this))
18730 return true;
18731
18732 if (visiting())
18733 return true;
18734
18735 if (v.visit_begin(this))
18736 {
18737 visiting(true);
18738 if (type_base_sptr t = get_pointed_to_type())
18739 t->traverse(v);
18740 visiting(false);
18741 }
18742
18743 bool result = v.visit_end(this);
18745 return result;
18746}
18747
18748reference_type_def::~reference_type_def()
18749{}
18750
18751/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18752/// equality; that is, make it compare the pointed to objects too.
18753///
18754/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18755/// of the equality.
18756///
18757/// @param r the shared_ptr of @ref reference_type_def on
18758/// right-hand-side of the equality.
18759///
18760/// @return true if the @ref reference_type_def pointed to by the
18761/// shared_ptrs are equal, false otherwise.
18762bool
18764{
18765 if (l.get() == r.get())
18766 return true;
18767 if (!!l != !!r)
18768 return false;
18769
18770 return *l == *r;
18771}
18772
18773/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18774/// equality; that is, make it compare the pointed to objects too.
18775///
18776/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18777/// of the equality.
18778///
18779/// @param r the shared_ptr of @ref reference_type_def on
18780/// right-hand-side of the equality.
18781///
18782/// @return true iff the @ref reference_type_def pointed to by the
18783/// shared_ptrs are different.
18784bool
18786{return !operator==(l, r);}
18787
18788// </reference_type_def definitions>
18789
18790// <ptr_to_mbr_type definitions>
18791
18792/// The private data type of @ref ptr_to_mbr_type.
18793struct ptr_to_mbr_type::priv
18794{
18795 // The type of the data member this pointer-to-member-type
18796 // designates.
18797 type_base_sptr dm_type_;
18798 // The class (or typedef to potentially qualified class) containing
18799 // the data member this pointer-to-member-type designates.
18800 type_base_sptr containing_type_;
18801 interned_string internal_qualified_name_;
18802 interned_string temp_internal_qualified_name_;
18803
18804 priv()
18805 {}
18806
18807 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18808 : dm_type_(dm_type),
18809 containing_type_(containing_type)
18810 {}
18811};// end struct ptr_to_mbr_type::priv
18812
18813/// A constructor for a @ref ptr_to_mbr_type type.
18814///
18815/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18816///
18817/// @param member_type the member type of the of the @ref
18818/// ptr_to_mbr_type to construct.
18819///
18820/// @param containing_type the containing type of the @ref
18821/// ptr_to_mbr_type to construct.
18822///
18823/// @param size_in_bits the size (in bits) of the resulting type.
18824///
18825/// @param alignment_in_bits the alignment (in bits) of the resulting
18826/// type.
18827///
18828/// @param locus the source location of the definition of the
18829/// resulting type.
18830ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18831 const type_base_sptr& member_type,
18832 const type_base_sptr& containing_type,
18833 size_t size_in_bits,
18834 size_t alignment_in_bits,
18835 const location& locus)
18836 : type_or_decl_base(env,
18837 POINTER_TO_MEMBER_TYPE
18838 | ABSTRACT_TYPE_BASE
18839 | ABSTRACT_DECL_BASE),
18840 type_base(env, size_in_bits, alignment_in_bits),
18841 decl_base(env, "", locus, ""),
18842 priv_(new priv(member_type, containing_type))
18843{
18845 ABG_ASSERT(member_type);
18846 ABG_ASSERT(containing_type);
18847 set_is_anonymous(false);
18848}
18849
18850/// Getter of the name of the current ptr-to-mbr-type.
18851///
18852/// This just returns the qualified name.
18853///
18854/// @return the (qualified) name of the the type.
18855const interned_string&
18857{
18858 return get_qualified_name(/*internal=*/false);
18859}
18860
18861/// Return the hash value of the current IR node.
18862///
18863/// Note that upon the first invocation, this member functions
18864/// computes the hash value and returns it. Subsequent invocations
18865/// just return the hash value that was previously calculated.
18866///
18867/// @return the hash value of the current IR node.
18868hash_t
18870{
18872 return h;
18873}
18874
18875/// Getter of the member type of the current @ref ptr_to_mbr_type.
18876///
18877/// @return the type of the member referred to by the current
18878/// @ptr_to_mbr_type.
18879const type_base_sptr&
18881{return priv_->dm_type_;}
18882
18883/// Getter of the type containing the member pointed-to by the current
18884/// @ref ptr_to_mbr_type.
18885///
18886/// @return the type containing the member pointed-to by the current
18887/// @ref ptr_to_mbr_type.
18888const type_base_sptr&
18890{return priv_->containing_type_;}
18891
18892/// Equality operator for the current @ref ptr_to_mbr_type.
18893///
18894///@param o the other instance of @ref ptr_to_mbr_type to compare the
18895///current instance to.
18896///
18897/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18898bool
18900{
18901 const ptr_to_mbr_type* other =
18902 dynamic_cast<const ptr_to_mbr_type*>(&o);
18903 if (!other)
18904 return false;
18905 return try_canonical_compare(this, other);
18906}
18907
18908/// Equality operator for the current @ref ptr_to_mbr_type.
18909///
18910///@param o the other instance of @ref ptr_to_mbr_type to compare the
18911///current instance to.
18912///
18913/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18914bool
18916{
18917 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18918 if (!other)
18919 return false;
18920 return *this == *other;
18921}
18922
18923/// Equality operator for the current @ref ptr_to_mbr_type.
18924///
18925///@param o the other instance of @ref ptr_to_mbr_type to compare the
18926///current instance to.
18927///
18928/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18929bool
18931{
18932 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18933 if (!other)
18934 return false;
18935 return *this == *other;
18936}
18937
18938/// Get the qualified name for the current @ref ptr_to_mbr_type.
18939///
18940/// @param qualified_name out parameter. This is set to the name of
18941/// the current @ref ptr_to_mbr_type.
18942///
18943/// @param internal if this is true, then the qualified name is for
18944/// the purpose of type canoicalization.
18945void
18947 bool internal) const
18948{qualified_name = get_qualified_name(internal);}
18949
18950/// Get the qualified name for the current @ref ptr_to_mbr_type.
18951///
18952/// @param internal if this is true, then the qualified name is for
18953/// the purpose of type canoicalization.
18954///
18955/// @return the qualified name for the current @ref ptr_to_mbr_type.
18956const interned_string&
18958{
18959 type_base_sptr member_type = get_member_type();
18960 type_base_sptr containing_type = get_containing_type();
18961
18962 if (internal)
18963 {
18964 if (get_canonical_type())
18965 {
18966 if (priv_->internal_qualified_name_.empty())
18967 priv_->internal_qualified_name_ =
18968 ptr_to_mbr_declaration_name(this, "",
18969 /*qualified=*/true,
18970 internal);
18971 return priv_->internal_qualified_name_;
18972 }
18973 else
18974 {
18975 priv_->temp_internal_qualified_name_ =
18976 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
18977 return priv_->temp_internal_qualified_name_;
18978 }
18979 }
18980 else
18981 {
18983 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
18984 /*internal=*/false));
18986 }
18987}
18988
18989/// This implements the ir_traversable_base::traverse pure virtual
18990/// function for @ref ptr_to_mbr_type.
18991///
18992/// @param v the visitor used on the current instance.
18993///
18994/// @return true if the entire IR node tree got traversed, false
18995/// otherwise.
18996bool
18998{
18999 if (v.type_node_has_been_visited(this))
19000 return true;
19001
19002 if (visiting())
19003 return true;
19004
19005 if (v.visit_begin(this))
19006 {
19007 visiting(true);
19008 if (type_base_sptr t = get_member_type())
19009 t->traverse(v);
19010
19011 if (type_base_sptr t = get_containing_type())
19012 t->traverse(v);
19013 visiting(false);
19014 }
19015
19016 bool result = v.visit_end(this);
19018 return result;
19019}
19020
19021/// Desctructor for @ref ptr_to_mbr_type.
19023{}
19024
19025
19026/// Compares two instances of @ref ptr_to_mbr_type.
19027///
19028/// If the two intances are different, set a bitfield to give some
19029/// insight about the kind of differences there are.
19030///
19031/// @param l the first artifact of the comparison.
19032///
19033/// @param r the second artifact of the comparison.
19034///
19035/// @param k a pointer to a bitfield that gives information about the
19036/// kind of changes there are between @p l and @p r. This one is set
19037/// iff @p k is non-null and the function returns false.
19038///
19039/// Please note that setting k to a non-null value does have a
19040/// negative performance impact because even if @p l and @p r are not
19041/// equal, the function keeps up the comparison in order to determine
19042/// the different kinds of ways in which they are different.
19043///
19044/// @return true if @p l equals @p r, false otherwise.
19045bool
19047{
19048 bool result = true;
19049
19050 if (!(l.decl_base::operator==(r)))
19051 {
19052 result = false;
19053 if (k)
19055 else
19056 result = false;
19057 }
19058
19059 if (l.get_member_type() != r.get_member_type())
19060 {
19061 if (k)
19062 {
19063 if (!types_have_similar_structure(&l, &r))
19065 *k |= SUBTYPE_CHANGE_KIND;
19066 }
19067 result = false;
19068 }
19069
19071 {
19072 if (k)
19073 {
19074 if (!types_have_similar_structure(&l, &r))
19076 *k |= SUBTYPE_CHANGE_KIND;
19077 }
19078 result = false;
19079 }
19080
19081 ABG_RETURN(result);
19082}
19083
19084// </ptr_to_mbr_type definitions>
19085
19086// <array_type_def definitions>
19087
19088// <array_type_def::subrange_type>
19089array_type_def::subrange_type::~subrange_type() = default;
19090
19091// <array_type_def::subrante_type::bound_value>
19092
19093/// Default constructor of the @ref
19094/// array_type_def::subrange_type::bound_value class.
19095///
19096/// Constructs an unsigned bound_value of value zero.
19098 : s_(UNSIGNED_SIGNEDNESS)
19099{
19100 v_.unsigned_ = 0;
19101}
19102
19103/// Initialize an unsigned bound_value with a given value.
19104///
19105/// @param v the initial bound value.
19107 : s_(UNSIGNED_SIGNEDNESS)
19108{
19109 v_.unsigned_ = v;
19110}
19111
19112/// Initialize a signed bound_value with a given value.
19113///
19114/// @param v the initial bound value.
19116 : s_(SIGNED_SIGNEDNESS)
19117{
19118 v_.signed_ = v;
19119}
19120
19121/// Getter of the signedness (unsigned VS signed) of the bound value.
19122///
19123/// @return the signedness of the bound value.
19124enum array_type_def::subrange_type::bound_value::signedness
19126{return s_;}
19127
19128/// Setter of the signedness (unsigned VS signed) of the bound value.
19129///
19130/// @param s the new signedness of the bound value.
19131void
19133{ s_ = s;}
19134
19135/// Getter of the bound value as a signed value.
19136///
19137/// @return the bound value as signed.
19138int64_t
19140{return v_.signed_;
19141}
19142
19143/// Getter of the bound value as an unsigned value.
19144///
19145/// @return the bound value as unsigned.
19146uint64_t
19148{return v_.unsigned_;}
19149
19150/// Setter of the bound value as unsigned.
19151///
19152/// @param v the new unsigned value.
19153void
19155{
19156 s_ = UNSIGNED_SIGNEDNESS;
19157 v_.unsigned_ = v;
19158}
19159
19160/// Setter of the bound value as signed.
19161///
19162/// @param v the new signed value.
19163void
19165{
19166 s_ = SIGNED_SIGNEDNESS;
19167 v_.signed_ = v;
19168}
19169
19170/// Equality operator of the bound value.
19171///
19172/// @param v the other bound value to compare with.
19173///
19174/// @return true iff the current bound value equals @p v.
19175bool
19177{
19178 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
19179}
19180
19181// </array_type_def::subrante_type::bound_value>
19182
19183struct array_type_def::subrange_type::priv
19184{
19185 bound_value lower_bound_;
19186 bound_value upper_bound_;
19187 type_base_wptr underlying_type_;
19189 bool infinite_;
19190
19191 priv(bound_value ub,
19192 translation_unit::language l = translation_unit::LANG_C11)
19193 : upper_bound_(ub), language_(l), infinite_(false)
19194 {}
19195
19196 priv(bound_value lb, bound_value ub,
19197 translation_unit::language l = translation_unit::LANG_C11)
19198 : lower_bound_(lb), upper_bound_(ub),
19199 language_(l), infinite_(false)
19200 {}
19201
19202 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
19203 translation_unit::language l = translation_unit::LANG_C11)
19204 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
19205 language_(l), infinite_(false)
19206 {}
19207};
19208
19209/// Constructor of an array_type_def::subrange_type type.
19210///
19211/// @param env the environment this type was created from.
19212///
19213/// @param name the name of the subrange type.
19214///
19215/// @param lower_bound the lower bound of the array. This is
19216/// generally zero (at least for C and C++).
19217///
19218/// @param upper_bound the upper bound of the array.
19219///
19220/// @param underlying_type the underlying type of the subrange type.
19221///
19222/// @param loc the source location where the type is defined.
19223array_type_def::subrange_type::subrange_type(const environment& env,
19224 const string& name,
19225 bound_value lower_bound,
19226 bound_value upper_bound,
19227 const type_base_sptr& utype,
19228 const location& loc,
19230 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19231 type_base(env,
19232 utype
19233 ? utype->get_size_in_bits()
19234 : 0,
19235 0),
19236 decl_base(env, name, loc, ""),
19237 priv_(new priv(lower_bound, upper_bound, utype, l))
19238{
19240}
19241
19242/// Constructor of the array_type_def::subrange_type type.
19243///
19244/// @param env the environment this type is being created in.
19245///
19246/// @param name the name of the subrange type.
19247///
19248/// @param lower_bound the lower bound of the array. This is
19249/// generally zero (at least for C and C++).
19250///
19251/// @param upper_bound the upper bound of the array.
19252///
19253/// @param loc the source location where the type is defined.
19254///
19255/// @param l the language that generated this subrange.
19256array_type_def::subrange_type::subrange_type(const environment& env,
19257 const string& name,
19258 bound_value lower_bound,
19259 bound_value upper_bound,
19260 const location& loc,
19262 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19263 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
19264 decl_base(env, name, loc, ""),
19265 priv_(new priv(lower_bound, upper_bound, l))
19266{
19268}
19269
19270/// Constructor of the array_type_def::subrange_type type.
19271///
19272/// @param env the environment this type is being created from.
19273///
19274/// @param name of the name of type.
19275///
19276/// @param upper_bound the upper bound of the array. The lower bound
19277/// is considered to be zero.
19278///
19279/// @param loc the source location of the type.
19280///
19281/// @param the language that generated this type.
19282array_type_def::subrange_type::subrange_type(const environment& env,
19283 const string& name,
19284 bound_value upper_bound,
19285 const location& loc,
19287 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19288 type_base(env, upper_bound.get_unsigned_value(), 0),
19289 decl_base(env, name, loc, ""),
19290 priv_(new priv(upper_bound, l))
19291{
19293}
19294
19295/// Return the hash value of the current IR node.
19296///
19297/// Note that upon the first invocation, this member functions
19298/// computes the hash value and returns it. Subsequent invocations
19299/// just return the hash value that was previously calculated.
19300///
19301/// @return the hash value of the current IR node.
19302hash_t
19304{
19306 return h;
19307}
19308
19309/// Getter of the underlying type of the subrange, that is, the type
19310/// that defines the range.
19311///
19312/// @return the underlying type.
19313type_base_sptr
19315{return priv_->underlying_type_.lock();}
19316
19317/// Setter of the underlying type of the subrange, that is, the type
19318/// that defines the range.
19319///
19320/// @param u the new underlying type.
19321void
19323{
19324 ABG_ASSERT(priv_->underlying_type_.expired());
19325 priv_->underlying_type_ = u;
19326 if (u)
19327 set_size_in_bits(u->get_size_in_bits());
19328}
19329
19330/// Getter of the upper bound of the subrange type.
19331///
19332/// @return the upper bound of the subrange type.
19333int64_t
19335{return priv_->upper_bound_.get_signed_value();}
19336
19337/// Getter of the lower bound of the subrange type.
19338///
19339/// @return the lower bound of the subrange type.
19340int64_t
19342{return priv_->lower_bound_.get_signed_value();}
19343
19344/// Setter of the upper bound of the subrange type.
19345///
19346/// @param ub the new value of the upper bound.
19347void
19349{priv_->upper_bound_ = ub;}
19350
19351/// Setter of the lower bound.
19352///
19353/// @param lb the new value of the lower bound.
19354void
19356{priv_->lower_bound_ = lb;}
19357
19358/// Getter of the length of the subrange type.
19359///
19360/// Note that a length of zero means the array has an infinite (or
19361/// rather a non-known) size.
19362///
19363/// @return the length of the subrange type.
19364uint64_t
19366{
19367 if (is_non_finite())
19368 return 0;
19369
19370 // A subrange can have an upper bound that is lower than its lower
19371 // bound. This is possible in Ada for instance. In that case, the
19372 // length of the subrange is considered to be zero.
19373 if (get_upper_bound() >= get_lower_bound())
19374 return get_upper_bound() - get_lower_bound() + 1;
19375 return 0;
19376}
19377
19378/// Test if the length of the subrange type is infinite.
19379///
19380/// @return true iff the length of the subrange type is infinite.
19381bool
19383{return priv_->infinite_;}
19384
19385/// Set the infinite-ness status of the subrange type.
19386///
19387/// @param f true iff the length of the subrange type should be set to
19388/// being infinite.
19389void
19391{priv_->infinite_ = f;}
19392
19393/// Getter of the language that generated this type.
19394///
19395/// @return the language of this type.
19398{return priv_->language_;}
19399
19400/// Return a string representation of the sub range.
19401///
19402/// @return the string representation of the sub range.
19403string
19405{
19406 std::ostringstream o;
19407
19409 {
19410 type_base_sptr underlying_type = get_underlying_type();
19411 if (underlying_type)
19412 o << ir::get_pretty_representation(underlying_type, false) << " ";
19413 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
19414 }
19415 else if (is_non_finite())
19416 o << "[]";
19417 else
19418 o << "[" << get_length() << "]";
19419
19420 return o.str();
19421}
19422
19423/// Return a string representation of a vector of subranges
19424///
19425/// @return the string representation of a vector of sub ranges.
19426string
19428{
19429 if (v.empty())
19430 return "[]";
19431
19432 string r;
19433 for (vector<subrange_sptr>::const_iterator i = v.begin();
19434 i != v.end();
19435 ++i)
19436 r += (*i)->as_string();
19437
19438 return r;
19439}
19440
19441/// Compares two isntances of @ref array_type_def::subrange_type.
19442///
19443/// If the two intances are different, set a bitfield to give some
19444/// insight about the kind of differences there are.
19445///
19446/// @param l the first artifact of the comparison.
19447///
19448/// @param r the second artifact of the comparison.
19449///
19450/// @param k a pointer to a bitfield that gives information about the
19451/// kind of changes there are between @p l and @p r. This one is set
19452/// iff @p k is non-null and the function returns false.
19453///
19454/// Please note that setting k to a non-null value does have a
19455/// negative performance impact because even if @p l and @p r are not
19456/// equal, the function keeps up the comparison in order to determine
19457/// the different kinds of ways in which they are different.
19458///
19459/// @return true if @p l equals @p r, false otherwise.
19460bool
19463 change_kind* k)
19464{
19465 bool result = true;
19466
19467 if (l.get_lower_bound() != r.get_lower_bound()
19468 || l.get_upper_bound() != r.get_upper_bound()
19469 || l.get_name() != r.get_name())
19470 {
19471 result = false;
19472 if (k)
19474 else
19475 ABG_RETURN(result);
19476 }
19477
19478 if (l.get_underlying_type()
19479 && r.get_underlying_type()
19480 && (*l.get_underlying_type() != *r.get_underlying_type()))
19481 {
19482 result = false;
19483 if (k)
19484 *k |= SUBTYPE_CHANGE_KIND;
19485 else
19486 ABG_RETURN(result);
19487 }
19488
19489 ABG_RETURN(result);
19490}
19491
19492/// Equality operator.
19493///
19494/// @param o the other subrange to test against.
19495///
19496/// @return true iff @p o equals the current instance of
19497/// array_type_def::subrange_type.
19498bool
19500{
19501 const subrange_type* other =
19502 dynamic_cast<const subrange_type*>(&o);
19503 if (!other)
19504 return false;
19505 return try_canonical_compare(this, other);
19506}
19507
19508/// Equality operator.
19509///
19510/// @param o the other subrange to test against.
19511///
19512/// @return true iff @p o equals the current instance of
19513/// array_type_def::subrange_type.
19514bool
19516{
19517 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19518 if (!other)
19519 return false;
19520 return *this == *other;
19521}
19522
19523/// Equality operator.
19524///
19525/// @param o the other subrange to test against.
19526///
19527/// @return true iff @p o equals the current instance of
19528/// array_type_def::subrange_type.
19529bool
19531{
19532 const type_base &t = o;
19533 return operator==(t);
19534}
19535
19536/// Equality operator.
19537///
19538/// @param o the other subrange to test against.
19539///
19540/// @return true iff @p o equals the current instance of
19541/// array_type_def::subrange_type.
19542bool
19544{return !operator==(o);}
19545
19546/// Equality operator.
19547///
19548/// @param o the other subrange to test against.
19549///
19550/// @return true iff @p o equals the current instance of
19551/// array_type_def::subrange_type.
19552bool
19554{return !operator==(o);}
19555
19556/// Inequality operator.
19557///
19558/// @param o the other subrange to test against.
19559///
19560/// @return true iff @p o is different from the current instance of
19561/// array_type_def::subrange_type.
19562bool
19564{return !operator==(o);}
19565
19566/// Build a pretty representation for an
19567/// array_type_def::subrange_type.
19568///
19569/// @param internal set to true if the call is intended to get a
19570/// representation of the decl (or type) for the purpose of canonical
19571/// type comparison. This is mainly used in the function
19572/// type_base::get_canonical_type_for().
19573///
19574/// In other words if the argument for this parameter is true then the
19575/// call is meant for internal use (for technical use inside the
19576/// library itself), false otherwise. If you don't know what this is
19577/// for, then set it to false.
19578///
19579/// @return a copy of the pretty representation of the current
19580/// instance of typedef_decl.
19581string
19583{
19584 string name = get_name();
19585 string repr;
19586
19587 if (name.empty())
19588 repr += "<anonymous range>";
19589 else
19590 repr += "<range " + get_name() + ">";
19591 repr += as_string();
19592
19593 return repr;
19594}
19595
19596/// This implements the ir_traversable_base::traverse pure virtual
19597/// function.
19598///
19599/// @param v the visitor used on the current instance.
19600///
19601/// @return true if the entire IR node tree got traversed, false
19602/// otherwise.
19603bool
19605{
19606 if (v.type_node_has_been_visited(this))
19607 return true;
19608
19609 if (v.visit_begin(this))
19610 {
19611 visiting(true);
19612 if (type_base_sptr u = get_underlying_type())
19613 u->traverse(v);
19614 visiting(false);
19615 }
19616
19617 bool result = v.visit_end(this);
19619 return result;
19620}
19621
19622// </array_type_def::subrange_type>
19623
19624struct array_type_def::priv
19625{
19626 type_base_wptr element_type_;
19627 subranges_type subranges_;
19628 interned_string temp_internal_qualified_name_;
19629 interned_string internal_qualified_name_;
19630
19631 priv(type_base_sptr t)
19632 : element_type_(t)
19633 {}
19634
19635 priv(type_base_sptr t, subranges_type subs)
19636 : element_type_(t), subranges_(subs)
19637 {}
19638
19639 priv()
19640 {}
19641};
19642
19643/// Constructor for the type array_type_def
19644///
19645/// Note how the constructor expects a vector of subrange
19646/// objects. Parsing of the array information always entails
19647/// parsing the subrange info as well, thus the class subrange_type
19648/// is defined inside class array_type_def and also parsed
19649/// simultaneously.
19650///
19651/// @param e_type the type of the elements contained in the array
19652///
19653/// @param subs a vector of the array's subranges(dimensions)
19654///
19655/// @param locus the source location of the array type definition.
19656array_type_def::array_type_def(const type_base_sptr e_type,
19657 const std::vector<subrange_sptr>& subs,
19658 const location& locus)
19660 ARRAY_TYPE
19661 | ABSTRACT_TYPE_BASE
19662 | ABSTRACT_DECL_BASE),
19663 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19664 decl_base(e_type->get_environment(), locus),
19665 priv_(new priv(e_type))
19666{
19668 append_subranges(subs);
19669}
19670
19671/// Constructor for the type array_type_def
19672///
19673/// This constructor builds a temporary array that has no element type
19674/// associated. Later when the element type is available, it be set
19675/// with the array_type_def::set_element_type() member function.
19676///
19677/// Note how the constructor expects a vector of subrange
19678/// objects. Parsing of the array information always entails
19679/// parsing the subrange info as well, thus the class subrange_type
19680/// is defined inside class array_type_def and also parsed
19681/// simultaneously.
19682///
19683/// @param env the environment of the array type.
19684///
19685/// @param subs a vector of the array's subranges(dimensions)
19686///
19687/// @param locus the source location of the array type definition.
19688array_type_def::array_type_def(const environment& env,
19689 const std::vector<subrange_sptr>& subs,
19690 const location& locus)
19691 : type_or_decl_base(env,
19692 ARRAY_TYPE
19693 | ABSTRACT_TYPE_BASE
19694 | ABSTRACT_DECL_BASE),
19695 type_base(env, 0, 0),
19696 decl_base(env, locus),
19697 priv_(new priv)
19698{
19700 append_subranges(subs);
19701}
19702
19703/// Return the hash value of the current IR node.
19704///
19705/// Note that upon the first invocation, this member functions
19706/// computes the hash value and returns it. Subsequent invocations
19707/// just return the hash value that was previously calculated.
19708///
19709/// @return the hash value of the current IR node.
19710hash_t
19712{
19714 return h;
19715}
19716
19717/// Update the size of the array.
19718///
19719/// This function computes the size of the array and sets it using
19720/// type_base::set_size_in_bits().
19721void
19722array_type_def::update_size()
19723{
19724 type_base_sptr e = priv_->element_type_.lock();
19725 if (e)
19726 {
19727 size_t s = e->get_size_in_bits();
19728 if (s)
19729 {
19730 for (const auto &sub : get_subranges())
19731 s *= sub->get_length();
19733 }
19734 set_alignment_in_bits(e->get_alignment_in_bits());
19735 }
19736}
19737
19738string
19739array_type_def::get_subrange_representation() const
19740{
19742 return r;
19743}
19744
19745/// Get the pretty representation of the current instance of @ref
19746/// array_type_def.
19747///
19748/// @param internal set to true if the call is intended to get a
19749/// representation of the decl (or type) for the purpose of canonical
19750/// type comparison. This is mainly used in the function
19751/// type_base::get_canonical_type_for().
19752///
19753/// In other words if the argument for this parameter is true then the
19754/// call is meant for internal use (for technical use inside the
19755/// library itself), false otherwise. If you don't know what this is
19756/// for, then set it to false.
19757/// @param internal set to true if the call is intended for an
19758/// internal use (for technical use inside the library itself), false
19759/// otherwise. If you don't know what this is for, then set it to
19760/// false.
19761///
19762/// @return the pretty representation of the ABI artifact.
19763string
19765 bool qualified_name) const
19766{
19767 return array_declaration_name(this, /*variable_name=*/"",
19768 qualified_name, internal);
19769}
19770
19771/// Compares two instances of @ref array_type_def.
19772///
19773/// If the two intances are different, set a bitfield to give some
19774/// insight about the kind of differences there are.
19775///
19776/// @param l the first artifact of the comparison.
19777///
19778/// @param r the second artifact of the comparison.
19779///
19780/// @param k a pointer to a bitfield that gives information about the
19781/// kind of changes there are between @p l and @p r. This one is set
19782/// iff @p k is non-null and the function returns false.
19783///
19784/// Please note that setting k to a non-null value does have a
19785/// negative performance impact because even if @p l and @p r are not
19786/// equal, the function keeps up the comparison in order to determine
19787/// the different kinds of ways in which they are different.
19788///
19789/// @return true if @p l equals @p r, false otherwise.
19790bool
19792{
19793 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19794 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19795
19796 bool result = true;
19797 if (this_subs.size() != other_subs.size())
19798 {
19799 result = false;
19800 if (k)
19802 else
19804 }
19805
19806 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19807 for (i = this_subs.begin(), j = other_subs.begin();
19808 i != this_subs.end() && j != other_subs.end();
19809 ++i, ++j)
19810 if (**i != **j)
19811 {
19812 result = false;
19813 if (k)
19814 {
19816 break;
19817 }
19818 else
19820 }
19821
19822 // Compare the element types modulo the typedefs they might have
19823 if (l.get_element_type() != r.get_element_type())
19824 {
19825 result = false;
19826 if (k)
19827 *k |= SUBTYPE_CHANGE_KIND;
19828 else
19830 }
19831
19832 ABG_RETURN(result);
19833}
19834
19835/// Test if two array types are equals modulo CV qualifiers.
19836///
19837/// @param l the first array of the comparison.
19838///
19839/// @param r the second array of the comparison.
19840///
19841/// @return true iff @p l equals @p r or, if they are different, the
19842/// difference between the too is just a matter of CV qualifiers.
19843bool
19845{
19846 if (l == r)
19847 return true;
19848
19849 if (!l || !r)
19851
19854
19855 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19856 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19857
19858 if (this_subs.size() != other_subs.size())
19860
19861 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19862 for (i = this_subs.begin(), j = other_subs.begin();
19863 i != this_subs.end() && j != other_subs.end();
19864 ++i, ++j)
19865 if (**i != **j)
19867
19868 type_base *first_element_type =
19870 type_base *second_element_type =
19872
19873 if (*first_element_type != *second_element_type)
19875
19876 return true;
19877}
19878
19879/// Test if two array types are equals modulo CV qualifiers.
19880///
19881/// @param l the first array of the comparison.
19882///
19883/// @param r the second array of the comparison.
19884///
19885/// @return true iff @p l equals @p r or, if they are different, the
19886/// difference between the too is just a matter of CV qualifiers.
19887bool
19889 const array_type_def_sptr& r)
19890{return equals_modulo_cv_qualifier(l.get(), r.get());}
19891
19892/// Test if two pointer types are equals modulo CV qualifiers.
19893///
19894/// @param l the first pointer of the comparison.
19895///
19896/// @param r the second pointer of the comparison.
19897///
19898/// @return true iff @p l equals @p r or, if they are different, the
19899/// difference between the too is just a matter of CV qualifiers.
19900bool
19902{
19903 if (l == r)
19904 return true;
19905
19906 if (!l || !r)
19908
19909 type_base_sptr l_ptt = l->get_pointed_to_type(),
19910 r_ptt = r->get_pointed_to_type();
19911
19912 do
19913 {
19914 l_ptt = peel_qualified_or_typedef_type(l_ptt);
19915 r_ptt = peel_qualified_or_typedef_type(r_ptt);
19916
19917 l_ptt = is_pointer_type(l_ptt)
19919 : l_ptt;
19920
19921 r_ptt = is_pointer_type(r_ptt)
19923 : r_ptt;
19924 } while (is_pointer_type(l_ptt) && is_pointer_type(r_ptt));
19925
19926 l_ptt = peel_qualified_or_typedef_type(l_ptt);
19927 r_ptt = peel_qualified_or_typedef_type(r_ptt);
19928
19929 return *l_ptt == *r_ptt;
19930}
19931
19932/// Test if two pointer types are equals modulo CV qualifiers.
19933///
19934/// @param l the first pointer of the comparison.
19935///
19936/// @param r the second pointer of the comparison.
19937///
19938/// @return true iff @p l equals @p r or, if they are different, the
19939/// difference between the too is just a matter of CV qualifiers.
19940bool
19942 const pointer_type_def_sptr& r)
19943{return equals_modulo_cv_qualifier(l.get(), r.get());}
19944
19945/// Get the language of the array.
19946///
19947/// @return the language of the array.
19950{
19951 const std::vector<subrange_sptr>& subranges =
19952 get_subranges();
19953
19954 if (subranges.empty())
19955 return translation_unit::LANG_C11;
19956 return subranges.front()->get_language();
19957}
19958
19959bool
19961{
19962 const array_type_def* other =
19963 dynamic_cast<const array_type_def*>(&o);
19964 if (!other)
19965 return false;
19966 return try_canonical_compare(this, other);
19967}
19968
19969bool
19971{
19972 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19973 if (!other)
19974 return false;
19975 return *this == *other;
19976}
19977
19978/// Getter of the type of an array element.
19979///
19980/// @return the type of an array element.
19981const type_base_sptr
19983{return priv_->element_type_.lock();}
19984
19985/// Setter of the type of array element.
19986///
19987/// Beware that after using this function, one might want to
19988/// re-compute the canonical type of the array, if one has already
19989/// been computed.
19990///
19991/// The intended use of this method is to permit in-place adjustment
19992/// of the element type's qualifiers. In particular, the size of the
19993/// element type should not be changed.
19994///
19995/// @param element_type the new element type to set.
19996void
19997array_type_def::set_element_type(const type_base_sptr& element_type)
19998{
19999 priv_->element_type_ = element_type;
20000 update_size();
20002}
20003
20004/// Append subranges from the vector @param subs to the current
20005/// vector of subranges.
20006void
20007array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
20008{
20009
20010 for (const auto &sub : subs)
20011 priv_->subranges_.push_back(sub);
20012
20013 update_size();
20015}
20016
20017/// @return true if one of the sub-ranges of the array is infinite, or
20018/// if the array has no sub-range at all, also meaning that the size
20019/// of the array is infinite.
20020bool
20022{
20023 if (priv_->subranges_.empty())
20024 return true;
20025
20026 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
20027 priv_->subranges_.begin();
20028 i != priv_->subranges_.end();
20029 ++i)
20030 if ((*i)->is_non_finite())
20031 return true;
20032
20033 return false;
20034}
20035
20036int
20037array_type_def::get_dimension_count() const
20038{return priv_->subranges_.size();}
20039
20040/// Build and return the qualified name of the current instance of the
20041/// @ref array_type_def.
20042///
20043/// @param qn output parameter. Is set to the newly-built qualified
20044/// name of the current instance of @ref array_type_def.
20045///
20046/// @param internal set to true if the call is intended for an
20047/// internal use (for technical use inside the library itself), false
20048/// otherwise. If you don't know what this is for, then set it to
20049/// false.
20050void
20052{qn = get_qualified_name(internal);}
20053
20054/// Compute the qualified name of the array.
20055///
20056/// @param internal set to true if the call is intended for an
20057/// internal use (for technical use inside the library itself), false
20058/// otherwise. If you don't know what this is for, then set it to
20059/// false.
20060///
20061/// @return the resulting qualified name.
20062const interned_string&
20064{
20065 if (internal)
20066 {
20067 if (get_canonical_type())
20068 {
20069 if (priv_->internal_qualified_name_.empty())
20070 priv_->internal_qualified_name_ =
20071 array_declaration_name(this, /*variable_name=*/"",
20072 /*qualified=*/false,
20073 /*internal=*/true);
20074 return priv_->internal_qualified_name_;
20075 }
20076 else
20077 {
20078 priv_->temp_internal_qualified_name_ =
20079 array_declaration_name(this, /*variable_name=*/"",
20080 /*qualified*/false, /*internal*/true);
20081 return priv_->temp_internal_qualified_name_;
20082 }
20083 }
20084 else
20085 {
20086 if (get_canonical_type())
20087 {
20088 if (decl_base::peek_qualified_name().empty())
20089 set_qualified_name(array_declaration_name(this,
20090 /*variable_name=*/"",
20091 /*qualified=*/false,
20092 /*internal=*/false));
20094 }
20095 else
20096 {
20098 (array_declaration_name(this, /*variable_name=*/"",
20099 /*qualified=*/false,
20100 /*internal=*/false));
20102 }
20103 }
20104}
20105
20106/// This implements the ir_traversable_base::traverse pure virtual
20107/// function.
20108///
20109/// @param v the visitor used on the current instance.
20110///
20111/// @return true if the entire IR node tree got traversed, false
20112/// otherwise.
20113bool
20115{
20116 if (v.type_node_has_been_visited(this))
20117 return true;
20118
20119 if (visiting())
20120 return true;
20121
20122 if (v.visit_begin(this))
20123 {
20124 visiting(true);
20125 if (type_base_sptr t = get_element_type())
20126 t->traverse(v);
20127 visiting(false);
20128 }
20129
20130 bool result = v.visit_end(this);
20132 return result;
20133}
20134
20135const location&
20136array_type_def::get_location() const
20137{return decl_base::get_location();}
20138
20139/// Get the array's subranges
20140const std::vector<array_type_def::subrange_sptr>&
20142{return priv_->subranges_;}
20143
20144array_type_def::~array_type_def()
20145{}
20146
20147// </array_type_def definitions>
20148
20149// <enum_type_decl definitions>
20150
20151class enum_type_decl::priv
20152{
20153 type_base_sptr underlying_type_;
20154 enumerators enumerators_;
20155 mutable enumerators sorted_enumerators_;
20156
20157 friend class enum_type_decl;
20158
20159 priv();
20160
20161public:
20162 priv(type_base_sptr underlying_type,
20164 : underlying_type_(underlying_type),
20165 enumerators_(enumerators)
20166 {}
20167}; // end class enum_type_decl::priv
20168
20169/// Constructor.
20170///
20171/// @param name the name of the type declaration.
20172///
20173/// @param locus the source location where the type was defined.
20174///
20175/// @param underlying_type the underlying type of the enum.
20176///
20177/// @param enums the enumerators of this enum type.
20178///
20179/// @param linkage_name the linkage name of the enum.
20180///
20181/// @param vis the visibility of the enum type.
20182enum_type_decl::enum_type_decl(const string& name,
20183 const location& locus,
20184 type_base_sptr underlying_type,
20185 enumerators& enums,
20186 const string& linkage_name,
20187 visibility vis)
20188 : type_or_decl_base(underlying_type->get_environment(),
20189 ENUM_TYPE
20190 | ABSTRACT_TYPE_BASE
20191 | ABSTRACT_DECL_BASE),
20192 type_base(underlying_type->get_environment(),
20193 underlying_type->get_size_in_bits(),
20194 underlying_type->get_alignment_in_bits()),
20195 decl_base(underlying_type->get_environment(),
20196 name, locus, linkage_name, vis),
20197 priv_(new priv(underlying_type, enums))
20198{
20200 for (enumerators::iterator e = get_enumerators().begin();
20201 e != get_enumerators().end();
20202 ++e)
20203 e->set_enum_type(this);
20204}
20205
20206/// Return the hash value of the current IR node.
20207///
20208/// Note that upon the first invocation, this member functions
20209/// computes the hash value and returns it. Subsequent invocations
20210/// just return the hash value that was previously calculated.
20211///
20212/// @return the hash value of the current IR node.
20213hash_t
20215{
20217 return h;
20218}
20219
20220/// Return the underlying type of the enum.
20221type_base_sptr
20223{return priv_->underlying_type_;}
20224
20225/// @return the list of enumerators of the enum.
20228{return priv_->enumerators_;}
20229
20230/// @return the list of enumerators of the enum.
20233{return priv_->enumerators_;}
20234
20235/// Get the lexicographically sorted vector of enumerators.
20236///
20237/// @return the lexicographically sorted vector of enumerators.
20240{
20241 if (priv_->sorted_enumerators_.empty())
20242 {
20243 for (auto e = get_enumerators().rbegin();
20244 e != get_enumerators().rend();
20245 ++e)
20246 priv_->sorted_enumerators_.push_back(*e);
20247
20248 std::sort(priv_->sorted_enumerators_.begin(),
20249 priv_->sorted_enumerators_.end(),
20250 [](const enum_type_decl::enumerator& l,
20252 {
20253 if (l.get_name() == r.get_name())
20254 return l.get_value() < r.get_value();
20255 return (l.get_name() < r.get_name());
20256 });
20257 }
20258
20259 return priv_->sorted_enumerators_;
20260}
20261
20262/// Find an enumerator by its value.
20263///
20264/// @param value the enumerator value to look for.
20265///
20266/// @param result output parameter. This is set to the enumerator
20267/// which value is @p value, if found. This is set iff the function
20268/// returns true.
20269///
20270/// @return true iff an enumerator with value @p value was found and
20271/// returned by argument via @p result.
20272bool
20275{
20276 for (auto& e : get_enumerators())
20277 if (e.get_value() == value)
20278 {
20279 result = e;
20280 return true;
20281 }
20282
20283 return false;
20284}
20285
20286/// Find an enumerator by its name
20287///
20288/// @param name the enumerator name to look for.
20289///
20290/// @param result output parameter. This is set to the enumerator
20291/// which name is @p name, if found. This is set iff the function
20292/// returns true.
20293///
20294/// @return true iff an enumerator with name @p name was found and
20295/// returned by argument via @p result.
20296bool
20299{
20300 for (auto& e : get_enumerators())
20301 if (e.get_name() == name)
20302 {
20303 result = e;
20304 return true;
20305 }
20306
20307 return false;
20308}
20309
20310/// Get the pretty representation of the current instance of @ref
20311/// enum_type_decl.
20312///
20313/// @param internal set to true if the call is intended to get a
20314/// representation of the decl (or type) for the purpose of canonical
20315/// type comparison. This is mainly used in the function
20316/// type_base::get_canonical_type_for().
20317///
20318/// In other words if the argument for this parameter is true then the
20319/// call is meant for internal use (for technical use inside the
20320/// library itself), false otherwise. If you don't know what this is
20321/// for, then set it to false.
20322///
20323/// @param qualified_name if true, names emitted in the pretty
20324/// representation are fully qualified.
20325///
20326/// @return the pretty representation of the enum type.
20327string
20329 bool qualified_name) const
20330{
20331 string r = "enum ";
20332
20333 if (internal && get_is_anonymous())
20334 r += get_type_name(this, qualified_name, /*internal=*/true);
20335 else if (get_is_anonymous())
20336 r += get_enum_flat_representation(*this, "",
20337 /*one_line=*/true,
20338 qualified_name);
20339 else
20341 qualified_name);
20342 return r;
20343}
20344
20345/// This implements the ir_traversable_base::traverse pure virtual
20346/// function.
20347///
20348/// @param v the visitor used on the current instance.
20349///
20350/// @return true if the entire IR node tree got traversed, false
20351/// otherwise.
20352bool
20354{
20355 if (v.type_node_has_been_visited(this))
20356 return true;
20357
20358 if (visiting())
20359 return true;
20360
20361 if (v.visit_begin(this))
20362 {
20363 visiting(true);
20364 if (type_base_sptr t = get_underlying_type())
20365 t->traverse(v);
20366 visiting(false);
20367 }
20368
20369 bool result = v.visit_end(this);
20371 return result;
20372}
20373
20374/// Destructor for the enum type declaration.
20376{}
20377
20378/// Test if two enums differ, but not by a name change.
20379///
20380/// @param l the first enum to consider.
20381///
20382/// @param r the second enum to consider.
20383///
20384/// @return true iff @p l differs from @p r by anything but a name
20385/// change.
20386bool
20388 const enum_type_decl& r,
20389 change_kind* k)
20390{
20391 bool result = false;
20393 {
20394 result = true;
20395 if (k)
20396 *k |= SUBTYPE_CHANGE_KIND;
20397 else
20398 return true;
20399 }
20400
20401 enum_type_decl::enumerators::const_iterator i, j;
20402 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
20403 i != l.get_enumerators().end() && j != r.get_enumerators().end();
20404 ++i, ++j)
20405 if (*i != *j)
20406 {
20407 result = true;
20408 if (k)
20409 {
20411 break;
20412 }
20413 else
20414 return true;
20415 }
20416
20417 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
20418 {
20419 result = true;
20420 if (k)
20422 else
20423 return true;
20424 }
20425
20426 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
20429 string n_l = l.get_name();
20430 string n_r = r.get_name();
20431 local_r.set_qualified_name(qn_l);
20432 local_r.set_name(n_l);
20433
20434 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
20435 {
20436 result = true;
20437 if (k)
20438 {
20439 if (!l.decl_base::operator==(r))
20441 if (!l.type_base::operator==(r))
20443 }
20444 else
20445 {
20446 local_r.set_name(n_r);
20447 local_r.set_qualified_name(qn_r);
20448 return true;
20449 }
20450 }
20451 local_r.set_qualified_name(qn_r);
20452 local_r.set_name(n_r);
20453
20454 return result;
20455}
20456
20457/// Test if a given enumerator is found present in an enum.
20458///
20459/// This is a subroutine of the equals function for enums.
20460///
20461/// @param enr the enumerator to consider.
20462///
20463/// @param enom the enum to consider.
20464///
20465/// @return true iff the enumerator @p enr is present in the enum @p
20466/// enom.
20467bool
20469 const enum_type_decl &enom)
20470{
20471 for (const auto &e : enom.get_enumerators())
20472 if (e == enr)
20473 return true;
20474 return false;
20475}
20476
20477/// Check if two enumerators values are equal.
20478///
20479/// This function doesn't check if the names of the enumerators are
20480/// equal or not.
20481///
20482/// @param enr the first enumerator to consider.
20483///
20484/// @param enl the second enumerator to consider.
20485///
20486/// @return true iff @p enr has the same value as @p enl.
20487static bool
20488enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
20489 const enum_type_decl::enumerator &enl)
20490{return enr.get_value() == enl.get_value();}
20491
20492/// Detect if a given enumerator value is present in an enum.
20493///
20494/// This function looks inside the enumerators of a given enum and
20495/// detect if the enum contains at least one enumerator or a given
20496/// value. The function also detects if the enumerator value we are
20497/// looking at is present in the enum with a different name. An
20498/// enumerator with the same value but with a different name is named
20499/// a "redundant enumerator". The function returns the set of
20500/// enumerators that are redundant with the value we are looking at.
20501///
20502/// @param enr the enumerator to consider.
20503///
20504/// @param enom the enum to consider.
20505///
20506/// @param redundant_enrs if the function returns true, then this
20507/// vector is filled with enumerators that are redundant with the
20508/// value of @p enr.
20509///
20510/// @return true iff the function detects that @p enom contains
20511/// enumerators with the same value as @p enr.
20512static bool
20513is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
20514 const enum_type_decl &enom,
20515 vector<enum_type_decl::enumerator>& redundant_enrs)
20516{
20517 bool found = false;
20518 for (const auto &e : enom.get_enumerators())
20519 if (enumerators_values_are_equal(e, enr))
20520 {
20521 found = true;
20522 if (e != enr)
20523 redundant_enrs.push_back(e);
20524 }
20525
20526 return found;
20527}
20528
20529/// Check if an enumerator value is redundant in a given enum.
20530///
20531/// Given an enumerator value, this function detects if an enum
20532/// contains at least one enumerator with the the same value but with
20533/// a different name.
20534///
20535/// @param enr the enumerator to consider.
20536///
20537/// @param enom the enum to consider.
20538///
20539/// @return true iff @p enr is a redundant enumerator in enom.
20540static bool
20541is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
20542 const enum_type_decl &enom)
20543{
20544 vector<enum_type_decl::enumerator> redundant_enrs;
20545 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
20546 {
20547 if (!redundant_enrs.empty())
20548 return true;
20549 }
20550 return false;
20551}
20552
20553/// Compares two instances of @ref enum_type_decl.
20554///
20555/// If the two intances are different, set a bitfield to give some
20556/// insight about the kind of differences there are.
20557///
20558/// @param l the first artifact of the comparison.
20559///
20560/// @param r the second artifact of the comparison.
20561///
20562/// @param k a pointer to a bitfield that gives information about the
20563/// kind of changes there are between @p l and @p r. This one is set
20564/// iff @p k is non-null and the function returns false.
20565///
20566/// Please note that setting k to a non-null value does have a
20567/// negative performance impact because even if @p l and @p r are not
20568/// equal, the function keeps up the comparison in order to determine
20569/// the different kinds of ways in which they are different.
20570///
20571/// @return true if @p l equals @p r, false otherwise.
20572bool
20574{
20575 bool result = true;
20576
20577 //
20578 // Look through decl-only-enum.
20579 //
20580
20581 const enum_type_decl *def1 =
20584 : &l;
20585
20586 const enum_type_decl *def2 =
20589 : &r;
20590
20591 if (!!def1 != !!def2)
20592 {
20593 // One enum is decl-only while the other is not.
20594 // So the two enums are different.
20595 result = false;
20596 if (k)
20597 *k |= SUBTYPE_CHANGE_KIND;
20598 else
20600 }
20601
20602 //
20603 // At this point, both enums have the same state of decl-only-ness.
20604 // So we can compare oranges to oranges.
20605 //
20606
20607 if (!def1)
20608 def1 = &l;
20609 if (!def2)
20610 def2 = &r;
20611
20612 if (def1->get_underlying_type() != def2->get_underlying_type())
20613 {
20614 result = false;
20615 if (k)
20616 *k |= SUBTYPE_CHANGE_KIND;
20617 else
20619 }
20620
20621 if (!(def1->decl_base::operator==(*def2)
20622 && def1->type_base::operator==(*def2)))
20623 {
20624 result = false;
20625 if (k)
20626 {
20627 if (!def1->decl_base::operator==(*def2))
20629 if (!def1->type_base::operator==(*def2))
20631 }
20632 else
20634 }
20635
20636 // Now compare the enumerators.
20637
20638 // First in a naive (but potentially fast) way in case both enums
20639 // are equal in a naive manner.
20640
20641 if (def1->get_enumerators().size() == def2->get_enumerators().size())
20642 {
20643 bool equals = true;
20644 for (auto e1 = def1->get_enumerators().begin(),
20645 e2 = def2->get_enumerators().begin();
20646 (e1 != def1->get_enumerators().end()
20647 && e2 != def2->get_enumerators().end());
20648 ++e1, ++e2)
20649 {
20650 if (*e1 != *e2)
20651 {
20652 equals = false;
20653 break;
20654 }
20655 }
20656 if (equals)
20657 ABG_RETURN(result);
20658 }
20659
20660 // If the two enums where not naively equals, let's try a more
20661 // clever (and slow) way.
20662
20663 // Note that the order of declaration
20664 // of enumerators should not matter in the comparison.
20665 //
20666 // Also if an enumerator value is redundant, that shouldn't impact
20667 // the comparison.
20668 //
20669 // In that case, note that the two enums below are considered equal:
20670 //
20671 // enum foo
20672 // {
20673 // e0 = 0;
20674 // e1 = 1;
20675 // e2 = 2;
20676 // };
20677 //
20678 // enum foo
20679 // {
20680 // e0 = 0;
20681 // e1 = 1;
20682 // e2 = 2;
20683 // e_added = 1; // <-- this value is redundant with the value
20684 // // of the enumerator e1.
20685 // };
20686 //
20687 // Note however that in the case below, the enums are different.
20688 //
20689 // enum foo
20690 // {
20691 // e0 = 0;
20692 // e1 = 1;
20693 // };
20694 //
20695 // enum foo
20696 // {
20697 // e0 = 0;
20698 // e2 = 1; // <-- this enum value is present in the first version
20699 // // of foo, but is not redundant with any enumerator
20700 // // in the second version of of enum foo.
20701 // };
20702 //
20703 // These two enums are considered equal.
20704
20705 for(const auto &e : def1->get_enumerators())
20706 if (!is_enumerator_present_in_enum(e, *def2)
20707 && (!is_enumerator_value_redundant(e, *def2)
20708 || !is_enumerator_value_redundant(e, *def1)))
20709 {
20710 result = false;
20711 if (k)
20712 {
20714 break;
20715 }
20716 else
20718 }
20719
20720 for(const auto &e : def2->get_enumerators())
20721 if (!is_enumerator_present_in_enum(e, *def1)
20722 && (!is_enumerator_value_redundant(e, *def1)
20723 || !is_enumerator_value_redundant(e, *def2)))
20724 {
20725 result = false;
20726 if (k)
20727 {
20729 break;
20730 }
20731 else
20733 }
20734
20735 ABG_RETURN(result);
20736}
20737
20738/// Equality operator.
20739///
20740/// @param o the other enum to test against.
20741///
20742/// @return true iff @p o equals the current instance of enum type
20743/// decl.
20744bool
20746{
20747 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
20748 if (!op)
20749 return false;
20750 return try_canonical_compare(this, op);
20751}
20752
20753/// Equality operator.
20754///
20755/// @param o the other enum to test against.
20756///
20757/// @return true iff @p o is equals the current instance of enum type
20758/// decl.
20759bool
20761{
20762 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20763 if (!other)
20764 return false;
20765 return *this == *other;
20766}
20767
20768/// Equality operator for @ref enum_type_decl_sptr.
20769///
20770/// @param l the first operand to compare.
20771///
20772/// @param r the second operand to compare.
20773///
20774/// @return true iff @p l equals @p r.
20775bool
20777{
20778 if (!!l != !!r)
20779 return false;
20780 if (l.get() == r.get())
20781 return true;
20782 decl_base_sptr o = r;
20783 return *l == *o;
20784}
20785
20786/// Inequality operator for @ref enum_type_decl_sptr.
20787///
20788/// @param l the first operand to compare.
20789///
20790/// @param r the second operand to compare.
20791///
20792/// @return true iff @p l equals @p r.
20793bool
20795{return !operator==(l, r);}
20796
20797/// The type of the private data of an @ref
20798/// enum_type_decl::enumerator.
20799class enum_type_decl::enumerator::priv
20800{
20801 string name_;
20802 int64_t value_;
20803 string qualified_name_;
20804 enum_type_decl* enum_type_;
20805
20806 friend class enum_type_decl::enumerator;
20807
20808public:
20809
20810 priv()
20811 : enum_type_()
20812 {}
20813
20814 priv(const string& name,
20815 int64_t value,
20816 enum_type_decl* e = 0)
20817 : name_(name),
20818 value_(value),
20819 enum_type_(e)
20820 {}
20821}; // end class enum_type_def::enumerator::priv
20822
20823/// Default constructor of the @ref enum_type_decl::enumerator type.
20825 : priv_(new priv)
20826{}
20827
20828enum_type_decl::enumerator::~enumerator() = default;
20829
20830/// Constructor of the @ref enum_type_decl::enumerator type.
20831///
20832/// @param env the environment we are operating from.
20833///
20834/// @param name the name of the enumerator.
20835///
20836/// @param value the value of the enumerator.
20838 int64_t value)
20839 : priv_(new priv(name, value))
20840{}
20841
20842/// Copy constructor of the @ref enum_type_decl::enumerator type.
20843///
20844/// @param other enumerator to copy.
20846 : priv_(new priv(other.get_name(),
20847 other.get_value(),
20848 other.get_enum_type()))
20849{}
20850
20851/// Assignment operator of the @ref enum_type_decl::enumerator type.
20852///
20853/// @param o
20856{
20857 priv_->name_ = o.get_name();
20858 priv_->value_ = o.get_value();
20859 priv_->enum_type_ = o.get_enum_type();
20860 return *this;
20861}
20862
20863/// Equality operator
20864///
20865/// @param other the enumerator to compare to the current
20866/// instance of enum_type_decl::enumerator.
20867///
20868/// @return true if @p other equals the current instance of
20869/// enum_type_decl::enumerator.
20870bool
20872{
20873 bool names_equal = true;
20874 names_equal = (get_name() == other.get_name());
20875 return names_equal && (get_value() == other.get_value());
20876}
20877
20878/// Inequality operator.
20879///
20880/// @param other the other instance to compare against.
20881///
20882/// @return true iff @p other is different from the current instance.
20883bool
20885{return !operator==(other);}
20886
20887/// Getter for the name of the current instance of
20888/// enum_type_decl::enumerator.
20889///
20890/// @return a reference to the name of the current instance of
20891/// enum_type_decl::enumerator.
20892const string&
20894{return priv_->name_;}
20895
20896/// Getter for the qualified name of the current instance of
20897/// enum_type_decl::enumerator. The first invocation of the method
20898/// builds the qualified name, caches it and return a reference to the
20899/// cached qualified name. Subsequent invocations just return the
20900/// cached value.
20901///
20902/// @param internal set to true if the call is intended for an
20903/// internal use (for technical use inside the library itself), false
20904/// otherwise. If you don't know what this is for, then set it to
20905/// false.
20906///
20907/// @return the qualified name of the current instance of
20908/// enum_type_decl::enumerator.
20909const string&
20911{
20912 if (priv_->qualified_name_.empty())
20913 {
20914 priv_->qualified_name_ =
20915 get_enum_type()->get_qualified_name(internal)
20916 + "::"
20917 + get_name();
20918 }
20919 return priv_->qualified_name_;
20920}
20921
20922/// Setter for the name of @ref enum_type_decl::enumerator.
20923///
20924/// @param n the new name.
20925void
20927{priv_->name_ = n;}
20928
20929/// Getter for the value of @ref enum_type_decl::enumerator.
20930///
20931/// @return the value of the current instance of
20932/// enum_type_decl::enumerator.
20933int64_t
20935{return priv_->value_;}
20936
20937/// Setter for the value of @ref enum_type_decl::enumerator.
20938///
20939/// @param v the new value of the enum_type_decl::enumerator.
20940void
20942{priv_->value_= v;}
20943
20944/// Getter for the enum type that this enumerator is for.
20945///
20946/// @return the enum type that this enumerator is for.
20949{return priv_->enum_type_;}
20950
20951/// Setter for the enum type that this enumerator is for.
20952///
20953/// @param e the new enum type.
20954void
20956{priv_->enum_type_ = e;}
20957// </enum_type_decl definitions>
20958
20959// <typedef_decl definitions>
20960
20961/// Private data structure of the @ref typedef_decl.
20962struct typedef_decl::priv
20963{
20964 type_base_wptr underlying_type_;
20965
20966 priv(const type_base_sptr& t)
20967 : underlying_type_(t)
20968 {}
20969}; // end struct typedef_decl::priv
20970
20971/// Constructor of the typedef_decl type.
20972///
20973/// @param name the name of the typedef.
20974///
20975/// @param underlying_type the underlying type of the typedef.
20976///
20977/// @param locus the source location of the typedef declaration.
20978///
20979/// @param linkage_name the mangled name of the typedef.
20980///
20981/// @param vis the visibility of the typedef type.
20982typedef_decl::typedef_decl(const string& name,
20983 const type_base_sptr underlying_type,
20984 const location& locus,
20985 const string& linkage_name,
20986 visibility vis)
20987 : type_or_decl_base(underlying_type->get_environment(),
20988 TYPEDEF_TYPE
20989 | ABSTRACT_TYPE_BASE
20990 | ABSTRACT_DECL_BASE),
20991 type_base(underlying_type->get_environment(),
20992 underlying_type->get_size_in_bits(),
20993 underlying_type->get_alignment_in_bits()),
20994 decl_base(underlying_type->get_environment(),
20995 name, locus, linkage_name, vis),
20996 priv_(new priv(underlying_type))
20997{
20999}
21000
21001/// Constructor of the typedef_decl type.
21002///
21003/// @param name the name of the typedef.
21004///
21005/// @param env the environment of the current typedef.
21006///
21007/// @param locus the source location of the typedef declaration.
21008///
21009/// @param mangled_name the mangled name of the typedef.
21010///
21011/// @param vis the visibility of the typedef type.
21012typedef_decl::typedef_decl(const string& name,
21013 const environment& env,
21014 const location& locus,
21015 const string& mangled_name,
21016 visibility vis)
21017 : type_or_decl_base(env,
21018 TYPEDEF_TYPE
21019 | ABSTRACT_TYPE_BASE
21020 | ABSTRACT_DECL_BASE),
21021 type_base(env, /*size_in_bits=*/0,
21022 /*alignment_in_bits=*/0),
21023 decl_base(env, name, locus, mangled_name, vis),
21024 priv_(new priv(nullptr))
21025{
21027}
21028
21029/// Return the hash value of the current IR node.
21030///
21031/// Note that upon the first invocation, this member functions
21032/// computes the hash value and returns it. Subsequent invocations
21033/// just return the hash value that was previously calculated.
21034///
21035/// @return the hash value of the current IR node.
21036hash_t
21038{
21040 return h;
21041}
21042
21043/// Return the size of the typedef.
21044///
21045/// This function looks at the size of the underlying type and ensures
21046/// that it's the same as the size of the typedef.
21047///
21048/// @return the size of the typedef.
21049size_t
21051{
21052 if (!get_underlying_type())
21053 return 0;
21054 size_t s = get_underlying_type()->get_size_in_bits();
21055 if (s != type_base::get_size_in_bits())
21056 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
21058}
21059
21060/// Return the alignment of the typedef.
21061///
21062/// This function looks at the alignment of the underlying type and
21063/// ensures that it's the same as the alignment of the typedef.
21064///
21065/// @return the size of the typedef.
21066size_t
21068{
21069 if (!get_underlying_type())
21070 return 0;
21071 size_t s = get_underlying_type()->get_alignment_in_bits();
21073 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
21075}
21076
21077/// Compares two instances of @ref typedef_decl.
21078///
21079/// If the two intances are different, set a bitfield to give some
21080/// insight about the kind of differences there are.
21081///
21082/// @param l the first artifact of the comparison.
21083///
21084/// @param r the second artifact of the comparison.
21085///
21086/// @param k a pointer to a bitfield that gives information about the
21087/// kind of changes there are between @p l and @p r. This one is set
21088/// iff @p k is non-null and the function returns false.
21089///
21090/// Please note that setting k to a non-null value does have a
21091/// negative performance impact because even if @p l and @p r are not
21092/// equal, the function keeps up the comparison in order to determine
21093/// the different kinds of ways in which they are different.
21094///
21095/// @return true if @p l equals @p r, false otherwise.
21096bool
21098{
21099 bool result = true;
21100
21101 // No need to go further if the types have different names or
21102 // different size / alignment.
21103 if (!(l.decl_base::operator==(r)))
21104 {
21105 result = false;
21106 if (k)
21108 else
21110 }
21111
21113 {
21114 // Changes to the underlying type of a typedef are considered
21115 // local, a bit like for pointers.
21116 result = false;
21117 if (k)
21119 else
21121 }
21122
21123 ABG_RETURN(result);
21124}
21125
21126/// Equality operator
21127///
21128/// @param o the other typedef_decl to test against.
21129bool
21131{
21132 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
21133 if (!other)
21134 return false;
21135 return try_canonical_compare(this, other);
21136}
21137
21138/// Equality operator
21139///
21140/// @param o the other typedef_decl to test against.
21141///
21142/// @return true if the current instance of @ref typedef_decl equals
21143/// @p o.
21144bool
21146{
21147 const decl_base* other = dynamic_cast<const decl_base*>(&o);
21148 if (!other)
21149 return false;
21150 return *this == *other;
21151}
21152
21153/// Build a pretty representation for a typedef_decl.
21154///
21155/// @param internal set to true if the call is intended to get a
21156/// representation of the decl (or type) for the purpose of canonical
21157/// type comparison. This is mainly used in the function
21158/// type_base::get_canonical_type_for().
21159///
21160/// In other words if the argument for this parameter is true then the
21161/// call is meant for internal use (for technical use inside the
21162/// library itself), false otherwise. If you don't know what this is
21163/// for, then set it to false.
21164
21165/// @param qualified_name if true, names emitted in the pretty
21166/// representation are fully qualified.
21167///
21168/// @return a copy of the pretty representation of the current
21169/// instance of typedef_decl.
21170string
21172 bool qualified_name) const
21173{
21174
21175 string result = "typedef ";
21176 if (qualified_name)
21177 result += get_qualified_name(internal);
21178 else
21179 result += get_name();
21180
21181 return result;
21182}
21183
21184/// Getter of the underlying type of the typedef.
21185///
21186/// @return the underlying_type.
21187type_base_sptr
21189{return priv_->underlying_type_.lock();}
21190
21191/// Setter ofthe underlying type of the typedef.
21192///
21193/// @param t the new underlying type of the typedef.
21194void
21196{
21197 priv_->underlying_type_ = t;
21198 set_size_in_bits(t->get_size_in_bits());
21199 set_alignment_in_bits(t->get_alignment_in_bits());
21200}
21201
21202/// Implementation of the virtual "get_qualified_name" method.
21203///
21204/// @param qualified_name the resuling qualified name of the typedef type.
21205///
21206/// @param internal if true, then it means the qualified name is for
21207/// "internal" purposes, meaning mainly for type canonicalization
21208/// purposes.
21209void
21211 bool internal) const
21212{qualified_name = get_qualified_name(internal);}
21213
21214/// Implementation of the virtual "get_qualified_name" method.
21215///
21216/// @param internal if true, then it means the qualified name is for
21217/// "internal" purposes, meaning mainly for type canonicalization
21218/// purposes.
21219///
21220/// @return the qualified name.
21221const interned_string&
21223{
21224 // Note that the qualified name has been already set by
21225 // qualified_name_setter::do_update, which is invoked by
21226 // update_qualified_name. The latter is itself invoked whenever the
21227 // typedef is added to its scope, in scope_decl::add_member_decl.
21228 if (internal)
21229 return decl_base::priv_->internal_qualified_name_;
21230 else
21231 return decl_base::priv_->qualified_name_;
21232}
21233
21234/// This implements the ir_traversable_base::traverse pure virtual
21235/// function.
21236///
21237/// @param v the visitor used on the current instance.
21238///
21239/// @return true if the entire IR node tree got traversed, false
21240/// otherwise.
21241bool
21243{
21244 if (v.type_node_has_been_visited(this))
21245 return true;
21246
21247 if (visiting())
21248 return true;
21249
21250 if (v.visit_begin(this))
21251 {
21252 visiting(true);
21253 if (type_base_sptr t = get_underlying_type())
21254 t->traverse(v);
21255 visiting(false);
21256 }
21257
21258 bool result = v.visit_end(this);
21260 return result;
21261}
21262
21263typedef_decl::~typedef_decl()
21264{}
21265// </typedef_decl definitions>
21266
21267// <var_decl definitions>
21268
21269struct var_decl::priv
21270{
21271 type_base_wptr type_;
21272 type_base* naked_type_;
21273 decl_base::binding binding_;
21274 elf_symbol_sptr symbol_;
21275 interned_string id_;
21276
21277 priv()
21278 : naked_type_(),
21279 binding_(decl_base::BINDING_GLOBAL)
21280 {}
21281
21282 priv(type_base_sptr t,
21284 : type_(t),
21285 naked_type_(t.get()),
21286 binding_(b)
21287 {}
21288
21289 /// Setter of the type of the variable.
21290 ///
21291 /// @param t the new variable type.
21292 void
21293 set_type(type_base_sptr t)
21294 {
21295 type_ = t;
21296 naked_type_ = t.get();
21297 }
21298}; // end struct var_decl::priv
21299
21300/// Constructor of the @ref var_decl type.
21301///
21302/// @param name the name of the variable declaration
21303///
21304/// @param type the type of the variable declaration
21305///
21306/// @param locus the source location where the variable was defined.
21307///
21308/// @param linkage_name the linkage name of the variable.
21309///
21310/// @param vis the visibility of of the variable.
21311///
21312/// @param bind the binding kind of the variable.
21313var_decl::var_decl(const string& name,
21314 type_base_sptr type,
21315 const location& locus,
21316 const string& linkage_name,
21317 visibility vis,
21318 binding bind)
21319 : type_or_decl_base(type->get_environment(),
21320 VAR_DECL | ABSTRACT_DECL_BASE),
21321 decl_base(type->get_environment(), name, locus, linkage_name, vis),
21322 priv_(new priv(type, bind))
21323{
21325}
21326
21327/// Getter of the type of the variable.
21328///
21329/// @return the type of the variable.
21330const type_base_sptr
21332{return priv_->type_.lock();}
21333
21334/// Setter of the type of the variable.
21335///
21336/// @param the new type of the variable.
21337void
21338var_decl::set_type(type_base_sptr& t)
21339{priv_->set_type(t);}
21340
21341/// Getter of the type of the variable.
21342///
21343/// This getter returns a bare pointer, as opposed to a smart pointer.
21344/// It's to be used on performance sensitive code paths identified by
21345/// careful profiling.
21346///
21347/// @return the type of the variable, as a bare pointer.
21348const type_base*
21350{return priv_->naked_type_;}
21351
21352/// Getter of the binding of the variable.
21353///
21354/// @return the biding of the variable.
21357{return priv_->binding_;}
21358
21359/// Setter of the binding of the variable.
21360///
21361/// @param b the new binding value.
21362void
21364{priv_->binding_ = b;}
21365
21366/// Sets the underlying ELF symbol for the current variable.
21367///
21368/// And underlyin$g ELF symbol for the current variable might exist
21369/// only if the corpus that this variable originates from was
21370/// constructed from an ELF binary file.
21371///
21372/// Note that comparing two variables that have underlying ELF symbols
21373/// involves comparing their underlying elf symbols. The decl name
21374/// for the variable thus becomes irrelevant in the comparison.
21375///
21376/// @param sym the new ELF symbol for this variable decl.
21377void
21379{
21380 priv_->symbol_ = sym;
21381 // The variable id cache that depends on the symbol must be
21382 // invalidated because the symbol changed.
21383 priv_->id_ = get_environment().intern("");
21384}
21385
21386/// Gets the the underlying ELF symbol for the current variable,
21387/// that was set using var_decl::set_symbol(). Please read the
21388/// documentation for that member function for more information about
21389/// "underlying ELF symbols".
21390///
21391/// @return sym the underlying ELF symbol for this variable decl, if
21392/// one exists.
21393const elf_symbol_sptr&
21395{return priv_->symbol_;}
21396
21397/// Create a new var_decl that is a clone of the current one.
21398///
21399/// @return the cloned var_decl.
21402{
21404 get_type(),
21405 get_location(),
21408 get_binding()));
21409
21410 v->set_symbol(get_symbol());
21411
21412 if (is_member_decl(*this))
21413 {
21417 get_member_is_static(*this),
21418 get_data_member_offset(*this));
21419 }
21420 else
21422
21423 return v;
21424}
21425/// Setter of the scope of the current var_decl.
21426///
21427/// Note that the decl won't hold a reference on the scope. It's
21428/// rather the scope that holds a reference on its members.
21429///
21430/// @param scope the new scope.
21431void
21432var_decl::set_scope(scope_decl* scope)
21433{
21434 if (!get_context_rel())
21435 set_context_rel(new dm_context_rel(scope));
21436 else
21437 get_context_rel()->set_scope(scope);
21438}
21439
21440/// Compares two instances of @ref var_decl without taking their type
21441/// into account.
21442///
21443/// If the two intances are different modulo their type, set a
21444/// bitfield to give some insight about the kind of differences there
21445/// are.
21446///
21447/// @param l the first artifact of the comparison.
21448///
21449/// @param r the second artifact of the comparison.
21450///
21451/// @param k a pointer to a bitfield that gives information about the
21452/// kind of changes there are between @p l and @p r. This one is set
21453/// iff @p k is non-null and the function returns false.
21454///
21455/// Please note that setting k to a non-null value does have a
21456/// negative performance impact because even if @p l and @p r are not
21457/// equal, the function keeps up the comparison in order to determine
21458/// the different kinds of ways in which they are different.
21459///
21460/// @return true if @p l equals @p r, false otherwise.
21461bool
21463{
21464 bool result = true;
21465
21466 // If there are underlying elf symbols for these variables,
21467 // compare them. And then compare the other parts.
21468 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21469 if (!!s0 != !!s1)
21470 {
21471 result = false;
21472 if (k)
21474 else
21476 }
21477 else if (s0 && !textually_equals(*s0, *s1, k))
21478 {
21479 result = false;
21480 if (!k)
21482 }
21483 bool symbols_are_equal = (s0 && s1 && result);
21484
21485 if (symbols_are_equal)
21486 {
21487 // The variables have underlying elf symbols that are equal, so
21488 // now, let's compare the decl_base part of the variables w/o
21489 // considering their decl names.
21490 const environment& env = l.get_environment();
21491 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
21492 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
21493 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
21494 bool decl_bases_different = !l.decl_base::operator==(r);
21495 const_cast<var_decl&>(l).set_qualified_name(n1);
21496 const_cast<var_decl&>(r).set_qualified_name(n2);
21497
21498 if (decl_bases_different)
21499 {
21500 result = false;
21501 if (k)
21503 else
21505 }
21506 }
21507 else
21508 if (!l.decl_base::operator==(r))
21509 {
21510 result = false;
21511 if (k)
21513 else
21515 }
21516
21517 const dm_context_rel* c0 =
21518 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
21519 const dm_context_rel* c1 =
21520 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
21521 ABG_ASSERT(c0 && c1);
21522
21523 if (*c0 != *c1)
21524 {
21525 result = false;
21526 if (k)
21528 else
21530 }
21531
21532 ABG_RETURN(result);
21533}
21534
21535/// Compares two instances of @ref var_decl.
21536///
21537/// If the two intances are different, set a bitfield to give some
21538/// insight about the kind of differences there are.
21539///
21540/// @param l the first artifact of the comparison.
21541///
21542/// @param r the second artifact of the comparison.
21543///
21544/// @param k a pointer to a bitfield that gives information about the
21545/// kind of changes there are between @p l and @p r. This one is set
21546/// iff @p k is non-null and the function returns false.
21547///
21548/// Please note that setting k to a non-null value does have a
21549/// negative performance impact because even if @p l and @p r are not
21550/// equal, the function keeps up the comparison in order to determine
21551/// the different kinds of ways in which they are different.
21552///
21553/// @return true if @p l equals @p r, false otherwise.
21554bool
21555equals(const var_decl& l, const var_decl& r, change_kind* k)
21556{
21557 bool result = true;
21558
21559 // First test types of variables. This should be fast because in
21560 // the general case, most types should be canonicalized.
21561 if (*l.get_naked_type() != *r.get_naked_type())
21562 {
21563 result = false;
21564 if (k)
21565 {
21567 r.get_naked_type()))
21568 *k |= (LOCAL_TYPE_CHANGE_KIND);
21569 else
21570 *k |= SUBTYPE_CHANGE_KIND;
21571 }
21572 else
21574 }
21575
21576 result &= var_equals_modulo_types(l, r, k);
21577
21578 ABG_RETURN(result);
21579}
21580
21581/// Comparison operator of @ref var_decl.
21582///
21583/// @param o the instance of @ref var_decl to compare against.
21584///
21585/// @return true iff the current instance of @ref var_decl equals @p o.
21586bool
21588{
21589 const var_decl* other = dynamic_cast<const var_decl*>(&o);
21590 if (!other)
21591 return false;
21592
21593 return equals(*this, *other, 0);
21594}
21595
21596/// Return an ID that tries to uniquely identify the variable inside a
21597/// program or a library.
21598///
21599/// So if the variable has an underlying elf symbol, the ID is the
21600/// concatenation of the symbol name and its version. Otherwise, the
21601/// ID is the linkage name if its non-null. Otherwise, it's the
21602/// pretty representation of the variable.
21603///
21604/// @return the ID.
21607{
21608 if (priv_->id_.empty())
21609 {
21610 string repr = get_name();
21611 string sym_str;
21612 if (elf_symbol_sptr s = get_symbol())
21613 sym_str = s->get_id_string();
21614 else if (!get_linkage_name().empty())
21615 sym_str = get_linkage_name();
21616
21617 const environment& env = get_type()->get_environment();
21618 priv_->id_ = env.intern(repr);
21619 if (!sym_str.empty())
21620 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
21621 }
21622 return priv_->id_;
21623}
21624
21625/// Get the qualified name of a given variable or data member.
21626///
21627///
21628/// Note that if the current instance of @ref var_decl is an anonymous
21629/// data member, then the qualified name is actually the flat
21630/// representation (the definition) of the type of the anonymous data
21631/// member. We chose the flat representation because otherwise, the
21632/// name of an *anonymous* data member is empty, by construction, e.g:
21633///
21634/// struct foo {
21635/// int a;
21636/// union {
21637/// char b;
21638/// char c;
21639/// }; // <---- this data member is anonymous.
21640/// int d;
21641/// }
21642///
21643/// The string returned for the anonymous member here is going to be:
21644///
21645/// "union {char b; char c}"
21646///
21647/// @param internal if true then this is for a purpose to the library,
21648/// otherwise, it's for being displayed to users.
21649///
21650/// @return the resulting qualified name.
21651const interned_string&
21653{
21654 if (is_anonymous_data_member(this)
21655 && decl_base::get_qualified_name().empty())
21656 {
21657 // Display the anonymous data member in a way that makes sense.
21658 string r = get_pretty_representation(internal);
21660 }
21661
21662 return decl_base::get_qualified_name(internal);
21663}
21664
21665/// Build and return the pretty representation of this variable.
21666///
21667/// @param internal set to true if the call is intended to get a
21668/// representation of the decl (or type) for the purpose of canonical
21669/// type comparison. This is mainly used in the function
21670/// type_base::get_canonical_type_for().
21671///
21672/// In other words if the argument for this parameter is true then the
21673/// call is meant for internal use (for technical use inside the
21674/// library itself), false otherwise. If you don't know what this is
21675/// for, then set it to false.
21676///
21677/// @param qualified_name if true, names emitted in the pretty
21678/// representation are fully qualified.
21679///
21680/// @return a copy of the pretty representation of this variable.
21681string
21682var_decl::get_pretty_representation(bool internal, bool qualified_name) const
21683{
21684 string result;
21685
21686 if (is_member_decl(this) && get_member_is_static(this))
21687 result = "static ";
21688
21689 // Detect if the current instance of var_decl is a member of
21690 // an anonymous class or union.
21691 bool member_of_anonymous_class = false;
21692 if (class_or_union* scope = is_at_class_scope(this))
21693 if (scope->get_is_anonymous())
21694 member_of_anonymous_class = true;
21695
21696 type_base_sptr type = get_type();
21697 if (is_array_type(type, /*look_through_qualifiers=*/true)
21698 || is_pointer_type(type, /*look_through_qualifiers=*/true)
21699 || is_reference_type(type, /*look_through_qualifiers=*/true)
21700 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
21701 {
21702 string name;
21703 if (member_of_anonymous_class || !qualified_name)
21704 name = get_name();
21705 else
21706 name = get_qualified_name(internal);
21707
21708 if (qualified_type_def_sptr q = is_qualified_type(type))
21709 {
21710 string quals_repr =
21711 get_string_representation_of_cv_quals(q->get_cv_quals());
21712 if (!quals_repr.empty())
21713 name = quals_repr + " " + name;
21714 type = peel_qualified_type(type);
21715 }
21716
21717 name = string(" ") + name;
21718 if (array_type_def_sptr t = is_array_type(type))
21719 result += array_declaration_name(t, name, qualified_name, internal);
21720 else if (pointer_type_def_sptr t = is_pointer_type(type))
21721 result += pointer_declaration_name(t, name, qualified_name, internal);
21722 else if (reference_type_def_sptr t = is_reference_type(type))
21723 result += pointer_declaration_name(t, name, qualified_name, internal);
21724 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
21725 result += ptr_to_mbr_declaration_name(t, name,
21726 qualified_name,
21727 internal);
21728 }
21729 else
21730 {
21731 if (/*The current var_decl is to be used as an anonymous data
21732 member. */
21733 get_name().empty())
21734 {
21735 // Display the anonymous data member in a way that
21736 // makes sense.
21737 result +=
21740 "", /*one_line=*/true, internal);
21741 }
21742 else if (data_member_has_anonymous_type(this))
21743 {
21746 "", /*one_line=*/true, internal);
21747 result += " ";
21748 if (!internal
21749 && (member_of_anonymous_class || !qualified_name))
21750 // It doesn't make sense to name the member of an
21751 // anonymous class or union like:
21752 // "__anonymous__::data_member_name". So let's just use
21753 // its non-qualified name.
21754 result += get_name();
21755 else
21756 result += get_qualified_name(internal);
21757 }
21758 else
21759 {
21760 result +=
21762 + " ";
21763
21764 if (!internal
21765 && (member_of_anonymous_class || !qualified_name))
21766 // It doesn't make sense to name the member of an
21767 // anonymous class or union like:
21768 // "__anonymous__::data_member_name". So let's just use
21769 // its non-qualified name.
21770 result += get_name();
21771 else
21772 result += get_qualified_name(internal);
21773 }
21774 }
21775 return result;
21776}
21777
21778/// Get a name that is valid even for an anonymous data member.
21779///
21780/// If the current @ref var_decl is an anonymous data member, then
21781/// return its pretty representation. As of now, that pretty
21782/// representation is actually its flat representation as returned by
21783/// get_class_or_union_flat_representation().
21784///
21785/// Otherwise, just return the name of the current @ref var_decl.
21786///
21787/// @param qualified if true, return the qualified name. This doesn't
21788/// have an effet if the current @ref var_decl represents an anonymous
21789/// data member.
21790string
21792{
21793 string name;
21794 if (is_anonymous_data_member(this))
21795 // This function is used in the comparison engine to determine
21796 // which anonymous data member was deleted. So it's not involved
21797 // in type comparison or canonicalization. We don't want to use
21798 // the 'internal' version of the pretty presentation.
21799 name = get_pretty_representation(/*internal=*/false, qualified);
21800 else
21801 name = get_name();
21802
21803 return name;
21804}
21805
21806/// This implements the ir_traversable_base::traverse pure virtual
21807/// function.
21808///
21809/// @param v the visitor used on the current instance.
21810///
21811/// @return true if the entire IR node tree got traversed, false
21812/// otherwise.
21813bool
21815{
21816 if (visiting())
21817 return true;
21818
21819 if (v.visit_begin(this))
21820 {
21821 visiting(true);
21822 if (type_base_sptr t = get_type())
21823 t->traverse(v);
21824 visiting(false);
21825 }
21826 return v.visit_end(this);
21827}
21828
21829var_decl::~var_decl()
21830{}
21831
21832// </var_decl definitions>
21833
21834/// This function is automatically invoked whenever an instance of
21835/// this type is canonicalized.
21836///
21837/// It's an overload of the virtual type_base::on_canonical_type_set.
21838///
21839/// We put here what is thus meant to be executed only at the point of
21840/// type canonicalization.
21841void
21843{
21844 priv_->cached_name_.clear();
21845 priv_->internal_cached_name_.clear();
21846}
21847
21848/// The most straightforward constructor for the function_type class.
21849///
21850/// @param return_type the return type of the function type.
21851///
21852/// @param parms the list of parameters of the function type.
21853/// Stricto sensu, we just need a list of types; we are using a list
21854/// of parameters (where each parameter also carries the name of the
21855/// parameter and its source location) to try and provide better
21856/// diagnostics whenever it makes sense. If it appears that this
21857/// wasts too many resources, we can fall back to taking just a
21858/// vector of types here.
21859///
21860/// @param size_in_bits the size of this type, in bits.
21861///
21862/// @param alignment_in_bits the alignment of this type, in bits.
21863///
21864/// @param size_in_bits the size of this type.
21865function_type::function_type(type_base_sptr return_type,
21866 const parameters& parms,
21867 size_t size_in_bits,
21868 size_t alignment_in_bits)
21869 : type_or_decl_base(return_type->get_environment(),
21870 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21871 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21872 priv_(new priv(parms, return_type))
21873{
21875
21876 for (parameters::size_type i = 0, j = 1;
21877 i < priv_->parms_.size();
21878 ++i, ++j)
21879 {
21880 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21881 // If the first parameter is artificial, then it certainly
21882 // means that this is a member function, and the first
21883 // parameter is the implicit this pointer. In that case, set
21884 // the index of that implicit parameter to zero. Otherwise,
21885 // the index of the first parameter starts at one.
21886 j = 0;
21887 priv_->parms_[i]->set_index(j);
21888 }
21889}
21890
21891/// A constructor for a function_type that takes no parameters.
21892///
21893/// @param return_type the return type of this function_type.
21894///
21895/// @param size_in_bits the size of this type, in bits.
21896///
21897/// @param alignment_in_bits the alignment of this type, in bits.
21898function_type::function_type(type_base_sptr return_type,
21899 size_t size_in_bits, size_t alignment_in_bits)
21900 : type_or_decl_base(return_type->get_environment(),
21901 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21902 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21903 priv_(new priv(return_type))
21904{
21906}
21907
21908/// A constructor for a function_type that takes no parameter and
21909/// that has no return_type yet. These missing parts can (and must)
21910/// be added later.
21911///
21912/// @param env the environment we are operating from.
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(const environment& env,
21918 size_t size_in_bits,
21919 size_t alignment_in_bits)
21920 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21921 type_base(env, size_in_bits, alignment_in_bits),
21922 priv_(new priv)
21923{
21925}
21926
21927/// Return the hash value of the current IR node.
21928///
21929/// Note that upon the first invocation, this member functions
21930/// computes the hash value and returns it. Subsequent invocations
21931/// just return the hash value that was previously calculated.
21932///
21933/// @return the hash value of the current IR node.
21934hash_t
21936{
21938 return h;
21939}
21940
21941/// Getter for the return type of the current instance of @ref
21942/// function_type.
21943///
21944/// @return the return type.
21945type_base_sptr
21947{return priv_->return_type_.lock();}
21948
21949/// Setter of the return type of the current instance of @ref
21950/// function_type.
21951///
21952/// @param t the new return type to set.
21953void
21955{priv_->return_type_ = t;}
21956
21957/// Getter for the set of parameters of the current intance of @ref
21958/// function_type.
21959///
21960/// @return the parameters of the current instance of @ref
21961/// function_type.
21964{return priv_->parms_;}
21965
21966/// Get the Ith parameter of the vector of parameters of the current
21967/// instance of @ref function_type.
21968///
21969/// Note that the first parameter is at index 0. That parameter is
21970/// the first parameter that comes after the possible implicit "this"
21971/// parameter, when the current instance @ref function_type is for a
21972/// member function. Otherwise, if the current instance of @ref
21973/// function_type is for a non-member function, the parameter at index
21974/// 0 is the first parameter of the function.
21975///
21976///
21977/// @param i the index of the parameter to return. If i is greater
21978/// than the index of the last parameter, then this function returns
21979/// an empty parameter (smart) pointer.
21980///
21981/// @return the @p i th parameter that is not implicit.
21984{
21985 parameter_sptr result;
21986 if (dynamic_cast<const method_type*>(this))
21987 {
21988 if (i + 1 < get_parameters().size())
21989 result = get_parameters()[i + 1];
21990 }
21991 else
21992 {
21993 if (i < get_parameters().size())
21994 result = get_parameters()[i];
21995 }
21996 return result;
21997}
21998
21999/// Setter for the parameters of the current instance of @ref
22000/// function_type.
22001///
22002/// @param p the new vector of parameters to set.
22003void
22005{
22006 priv_->parms_ = p;
22007 for (parameters::size_type i = 0, j = 1;
22008 i < priv_->parms_.size();
22009 ++i, ++j)
22010 {
22011 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22012 // If the first parameter is artificial, then it certainly
22013 // means that this is a member function, and the first
22014 // parameter is the implicit this pointer. In that case, set
22015 // the index of that implicit parameter to zero. Otherwise,
22016 // the index of the first parameter starts at one.
22017 j = 0;
22018 priv_->parms_[i]->set_index(j);
22019 }
22020}
22021
22022/// Append a new parameter to the vector of parameters of the current
22023/// instance of @ref function_type.
22024///
22025/// @param parm the parameter to append.
22026void
22028{
22029 parm->set_index(priv_->parms_.size());
22030 priv_->parms_.push_back(parm);
22031}
22032
22033/// Test if the current instance of @ref function_type is for a
22034/// variadic function.
22035///
22036/// A variadic function is a function that takes a variable number of
22037/// arguments.
22038///
22039/// @return true iff the current instance of @ref function_type is for
22040/// a variadic function.
22041bool
22043{
22044 return (!priv_->parms_.empty()
22045 && priv_->parms_.back()->get_variadic_marker());
22046}
22047
22048/// Compare two function types.
22049///
22050/// In case these function types are actually method types, this
22051/// function avoids comparing two parameters (of the function types)
22052/// if the types of the parameters are actually the types of the
22053/// classes of the method types. This prevents infinite recursion
22054/// during the comparison of two classes that are structurally
22055/// identical.
22056///
22057/// This is a subroutine of the equality operator of function_type.
22058///
22059/// @param lhs the first function type to consider
22060///
22061/// @param rhs the second function type to consider
22062///
22063/// @param k a pointer to a bitfield set by the function to give
22064/// information about the kind of changes carried by @p lhs and @p
22065/// rhs. It is set iff @p k is non-null and the function returns
22066/// false.
22067///
22068/// Please note that setting k to a non-null value does have a
22069/// negative performance impact because even if @p l and @p r are not
22070/// equal, the function keeps up the comparison in order to determine
22071/// the different kinds of ways in which they are different.
22072///
22073///@return true if lhs == rhs, false otherwise.
22074bool
22076{
22077#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
22078
22080
22081 {
22082 // First of all, let's see if these two function types haven't
22083 // already been compared. If so, and if the result of the
22084 // comparison has been cached, let's just re-use it, rather than
22085 // comparing them all over again.
22086 bool cached_result = false;
22087 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
22088 cached_result))
22089 ABG_RETURN(cached_result);
22090 }
22091
22093
22094 bool result = true;
22095
22096 if (!l.type_base::operator==(r))
22097 {
22098 result = false;
22099 if (k)
22101 else
22102 RETURN(result);
22103 }
22104
22105 class_or_union* l_class = 0, *r_class = 0;
22106 if (const method_type* m = dynamic_cast<const method_type*>(&l))
22107 l_class = m->get_class_type().get();
22108
22109 if (const method_type* m = dynamic_cast<const method_type*>(&r))
22110 r_class = m->get_class_type().get();
22111
22112 // Compare the names of the class of the method
22113
22114 if (!!l_class != !!r_class)
22115 {
22116 result = false;
22117 if (k)
22119 else
22120 RETURN(result);
22121 }
22122 else if (l_class
22123 && (l_class->get_qualified_name()
22124 != r_class->get_qualified_name()))
22125 {
22126 result = false;
22127 if (k)
22129 else
22130 RETURN(result);
22131 }
22132
22133 // Then compare the return type; Beware if it's t's a class type
22134 // that is the same as the method class name; we can recurse for
22135 // ever in that case.
22136
22137 decl_base* l_return_type_decl =
22139 decl_base* r_return_type_decl =
22141 bool compare_result_types = true;
22142 string l_rt_name = l_return_type_decl
22143 ? l_return_type_decl->get_qualified_name()
22144 : string();
22145 string r_rt_name = r_return_type_decl
22146 ? r_return_type_decl->get_qualified_name()
22147 : string();
22148
22149 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
22150 ||
22151 (r_class && (r_class->get_qualified_name() == r_rt_name)))
22152 compare_result_types = false;
22153
22154 if (compare_result_types)
22155 {
22156 // Let's not consider typedefs when comparing return types to
22157 // avoid spurious changes.
22158 //
22159 // TODO: We should also do this for parameter types, or rather,
22160 // we should teach the equality operators in the IR, at some
22161 // point, to peel typedefs off.
22162 if (l.get_return_type() != r.get_return_type())
22163 {
22164 result = false;
22165 if (k)
22166 {
22168 r.get_return_type()))
22170 else
22171 *k |= SUBTYPE_CHANGE_KIND;
22172 }
22173 else
22174 RETURN(result);
22175 }
22176 }
22177 else
22178 if (l_rt_name != r_rt_name)
22179 {
22180 result = false;
22181 if (k)
22182 *k |= SUBTYPE_CHANGE_KIND;
22183 else
22184 RETURN(result);
22185 }
22186
22187 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
22188 for (i = l.get_first_parm(), j = r.get_first_parm();
22189 i != l.get_parameters().end() && j != r.get_parameters().end();
22190 ++i, ++j)
22191 {
22192 if (**i != **j)
22193 {
22194 result = false;
22195 if (k)
22196 {
22197 if (!types_have_similar_structure((*i)->get_type(),
22198 (*j)->get_type()))
22200 else
22201 *k |= SUBTYPE_CHANGE_KIND;
22202 }
22203 else
22204 RETURN(result);
22205 }
22206 }
22207
22208 if ((i != l.get_parameters().end()
22209 || j != r.get_parameters().end()))
22210 {
22211 result = false;
22212 if (k)
22214 else
22215 RETURN(result);
22216 }
22217
22218 RETURN(result);
22219#undef RETURN
22220}
22221
22222/// Get the first parameter of the function.
22223///
22224/// If the function is a non-static member function, the parameter
22225/// returned is the first one following the implicit 'this' parameter.
22226///
22227/// @return the first non implicit parameter of the function.
22228function_type::parameters::const_iterator
22230{
22231 if (get_parameters().empty())
22232 return get_parameters().end();
22233
22234 bool is_method = dynamic_cast<const method_type*>(this);
22235
22236 parameters::const_iterator i = get_parameters().begin();
22237
22238 if (is_method && (*i)->get_is_artificial())
22239 ++i;
22240
22241 return i;
22242}
22243
22244/// Get the first parameter of the function.
22245///
22246/// Note that if the function is a non-static member function, the
22247/// parameter returned is the implicit 'this' parameter.
22248///
22249/// @return the first parameter of the function.
22250function_type::parameters::const_iterator
22252{return get_parameters().begin();}
22253
22254/// Get the name of the current @ref function_type.
22255///
22256/// The name is retrieved from a cache. If the cache is empty, this
22257/// function computes the name of the type, stores it in the cache and
22258/// returns it. Subsequent invocation of the function are going to
22259/// just hit the cache.
22260///
22261/// Note that if the type is *NOT* canonicalized then function type
22262/// name is never cached.
22263///
22264/// @param internal if true then it means the function type name is
22265/// going to be used for purposes that are internal to libabigail
22266/// itself. If you don't know what this is then you probably should
22267/// set this parameter to 'false'.
22268///
22269/// @return the name of the function type.
22270const interned_string&
22272{
22273 if (internal)
22274 {
22276 {
22277 if (priv_->internal_cached_name_.empty())
22278 priv_->internal_cached_name_ =
22279 get_function_type_name(this, /*internal=*/true);
22280 return priv_->internal_cached_name_;
22281 }
22282 else
22283 {
22284 priv_->temp_internal_cached_name_ =
22285 get_function_type_name(this, /*internal=*/true);
22286 return priv_->temp_internal_cached_name_;
22287 }
22288 }
22289 else
22290 {
22292 {
22293 if (priv_->cached_name_.empty())
22294 priv_->cached_name_ =
22295 get_function_type_name(this, /*internal=*/false);
22296 return priv_->cached_name_;
22297 }
22298 else
22299 {
22300 priv_->cached_name_ =
22301 get_function_type_name(this, /*internal=*/false);
22302 return priv_->cached_name_;
22303 }
22304 }
22305}
22306
22307/// Equality operator for function_type.
22308///
22309/// @param o the other function_type to compare against.
22310///
22311/// @return true iff the two function_type are equal.
22312bool
22314{
22315 const function_type* o = dynamic_cast<const function_type*>(&other);
22316 if (!o)
22317 return false;
22318 return try_canonical_compare(this, o);
22319}
22320
22321/// Return a copy of the pretty representation of the current @ref
22322/// function_type.
22323///
22324/// @param internal set to true if the call is intended to get a
22325/// representation of the decl (or type) for the purpose of canonical
22326/// type comparison. This is mainly used in the function
22327/// type_base::get_canonical_type_for().
22328///
22329/// In other words if the argument for this parameter is true then the
22330/// call is meant for internal use (for technical use inside the
22331/// library itself), false otherwise. If you don't know what this is
22332/// for, then set it to false.
22333///
22334/// @return a copy of the pretty representation of the current @ref
22335/// function_type.
22336string
22338 bool /*qualified_name*/) const
22339{return ir::get_pretty_representation(this, internal);}
22340
22341/// Traverses an instance of @ref function_type, visiting all the
22342/// sub-types and decls that it might contain.
22343///
22344/// @param v the visitor that is used to visit every IR sub-node of
22345/// the current node.
22346///
22347/// @return true if either
22348/// - all the children nodes of the current IR node were traversed
22349/// and the calling code should keep going with the traversing.
22350/// - or the current IR node is already being traversed.
22351/// Otherwise, returning false means that the calling code should not
22352/// keep traversing the tree.
22353bool
22355{
22356 // TODO: should we allow the walker to avoid visiting function type
22357 // twice? I think that if we do, then ir_node_visitor needs an
22358 // option to specifically disallow this feature for function types.
22359
22360 if (visiting())
22361 return true;
22362
22363 if (v.visit_begin(this))
22364 {
22365 visiting(true);
22366 bool keep_going = true;
22367
22368 if (type_base_sptr t = get_return_type())
22369 {
22370 if (!t->traverse(v))
22371 keep_going = false;
22372 }
22373
22374 if (keep_going)
22375 for (parameters::const_iterator i = get_parameters().begin();
22376 i != get_parameters().end();
22377 ++i)
22378 if (type_base_sptr parm_type = (*i)->get_type())
22379 if (!parm_type->traverse(v))
22380 break;
22381
22382 visiting(false);
22383 }
22384 return v.visit_end(this);
22385}
22386
22387function_type::~function_type()
22388{}
22389// </function_type>
22390
22391// <method_type>
22392
22393struct method_type::priv
22394{
22395 class_or_union_wptr class_type_;
22396 bool is_const;
22397
22398 priv()
22399 : is_const()
22400 {}
22401}; // end struct method_type::priv
22402
22403/// Constructor for instances of method_type.
22404///
22405/// Instances of method_decl must be of type method_type.
22406///
22407/// @param return_type the type of the return value of the method.
22408///
22409/// @param class_type the base type of the method type. That is, the
22410/// type of the class the method belongs to.
22411///
22412/// @param p the vector of the parameters of the method.
22413///
22414/// @param is_const whether this method type is for a const method.
22415/// Note that const-ness is a property of the method *type* and of the
22416/// relationship between a method *declaration* and its scope.
22417///
22418/// @param size_in_bits the size of an instance of method_type,
22419/// expressed in bits.
22420///
22421/// @param alignment_in_bits the alignment of an instance of
22422/// method_type, expressed in bits.
22423method_type::method_type (type_base_sptr return_type,
22424 class_or_union_sptr class_type,
22425 const std::vector<function_decl::parameter_sptr>& p,
22426 bool is_const,
22427 size_t size_in_bits,
22428 size_t alignment_in_bits)
22429 : type_or_decl_base(class_type->get_environment(),
22430 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22431 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22432 function_type(return_type, p, size_in_bits, alignment_in_bits),
22433 priv_(new priv)
22434{
22436 set_class_type(class_type);
22437 set_is_const(is_const);
22438}
22439
22440/// Constructor of instances of method_type.
22441///
22442///Instances of method_decl must be of type method_type.
22443///
22444/// @param return_type the type of the return value of the method.
22445///
22446/// @param class_type the type of the class the method belongs to.
22447/// The actual (dynamic) type of class_type must be a pointer
22448/// class_type. We are setting it to pointer to type_base here to
22449/// help client code that is compiled without rtti and thus cannot
22450/// perform dynamic casts.
22451///
22452/// @param p the vector of the parameters of the method type.
22453///
22454/// @param is_const whether this method type is for a const method.
22455/// Note that const-ness is a property of the method *type* and of the
22456/// relationship between a method *declaration* and its scope.
22457///
22458/// @param size_in_bits the size of an instance of method_type,
22459/// expressed in bits.
22460///
22461/// @param alignment_in_bits the alignment of an instance of
22462/// method_type, expressed in bits.
22463method_type::method_type(type_base_sptr return_type,
22464 type_base_sptr class_type,
22465 const std::vector<function_decl::parameter_sptr>& p,
22466 bool is_const,
22467 size_t size_in_bits,
22468 size_t alignment_in_bits)
22469 : type_or_decl_base(class_type->get_environment(),
22470 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22471 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22472 function_type(return_type, p, size_in_bits, alignment_in_bits),
22473 priv_(new priv)
22474{
22476 set_class_type(is_class_type(class_type));
22477 set_is_const(is_const);
22478}
22479
22480/// Constructor of the qualified_type_def
22481///
22482/// @param env the environment we are operating from.
22483///
22484/// @param size_in_bits the size of the type, expressed in bits.
22485///
22486/// @param alignment_in_bits the alignment of the type, expressed in bits
22487method_type::method_type(const environment& env,
22488 size_t size_in_bits,
22489 size_t alignment_in_bits)
22490 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22491 type_base(env, size_in_bits, alignment_in_bits),
22492 function_type(env, size_in_bits, alignment_in_bits),
22493 priv_(new priv)
22494{
22496}
22497
22498/// Constructor of instances of method_type.
22499///
22500/// When constructed with this constructor, and instane of method_type
22501/// must set a return type using method_type::set_return_type
22502///
22503/// @param class_typ the base type of the method type. That is, the
22504/// type of the class (or union) the method belongs to.
22505///
22506/// @param size_in_bits the size of an instance of method_type,
22507/// expressed in bits.
22508///
22509/// @param alignment_in_bits the alignment of an instance of
22510/// method_type, expressed in bits.
22511method_type::method_type(class_or_union_sptr class_type,
22512 bool is_const,
22513 size_t size_in_bits,
22514 size_t alignment_in_bits)
22515 : type_or_decl_base(class_type->get_environment(),
22516 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22517 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22518 function_type(class_type->get_environment(),
22519 size_in_bits,
22520 alignment_in_bits),
22521 priv_(new priv)
22522{
22524 set_class_type(class_type);
22525 set_is_const(is_const);
22526}
22527
22528/// Return the hash value of the current IR node.
22529///
22530/// Note that upon the first invocation, this member functions
22531/// computes the hash value and returns it. Subsequent invocations
22532/// just return the hash value that was previously calculated.
22533///
22534/// @return the hash value of the current IR node.
22535hash_t
22537{
22539 return h;
22540}
22541
22542/// Get the class type this method belongs to.
22543///
22544/// @return the class type.
22545class_or_union_sptr
22547{return class_or_union_sptr(priv_->class_type_);}
22548
22549/// Sets the class type of the current instance of method_type.
22550///
22551/// The class type is the type of the class the method belongs to.
22552///
22553/// @param t the new class type to set.
22554void
22555method_type::set_class_type(const class_or_union_sptr& t)
22556{
22557 if (!t)
22558 return;
22559
22560 priv_->class_type_ = t;
22561}
22562
22563/// Return a copy of the pretty representation of the current @ref
22564/// method_type.
22565///
22566/// @param internal set to true if the call is intended to get a
22567/// representation of the decl (or type) for the purpose of canonical
22568/// type comparison. This is mainly used in the function
22569/// type_base::get_canonical_type_for().
22570///
22571/// In other words if the argument for this parameter is true then the
22572/// call is meant for internal use (for technical use inside the
22573/// library itself), false otherwise. If you don't know what this is
22574/// for, then set it to false.
22575///
22576/// @return a copy of the pretty representation of the current @ref
22577/// method_type.
22578string
22580 bool /*qualified_name*/) const
22581{return ir::get_pretty_representation(*this, internal);}
22582
22583/// Setter of the "is-const" property of @ref method_type.
22584///
22585/// @param the new value of the "is-const" property.
22586void
22588{priv_->is_const = f;}
22589
22590/// Getter of the "is-const" property of @ref method_type.
22591///
22592/// @return true iff the "is-const" property was set.
22593bool
22595{return priv_->is_const;}
22596
22597/// Test if the current method type is for a static method or not.
22598///
22599/// @return true iff the current method_type denotes a the type of a
22600/// static method.
22601bool
22603{
22604 // Let's see if the first parameter is artificial and is a pointer
22605 // to an instance of the same class type as the current class.
22607 if (!get_parameters().empty())
22608 first_parm = get_parameters()[0];
22609 if (!first_parm)
22610 return true;
22611 if (!first_parm->get_is_artificial())
22612 return true;
22613
22614 type_base_sptr this_ptr_type = first_parm->get_type();
22615 // Sometimes, the type of the "this" pointer is "const class_type*
22616 // const". Meaning that the "this pointer" itself is const
22617 // qualified. So let's get the underlying non-qualified pointer.
22618 this_ptr_type = peel_qualified_type(this_ptr_type);
22619 if (!is_pointer_type(this_ptr_type))
22620 return true;
22621
22622 type_base_sptr candidate_class_type =
22623 is_pointer_type(this_ptr_type)->get_pointed_to_type();
22624 candidate_class_type = peel_qualified_type(candidate_class_type);
22625 if (is_class_type(candidate_class_type)
22626 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
22627 // At this point, we are sure we are looking at a *non-static*
22628 // method.
22629 return false;
22630
22631 return true;
22632}
22633
22634/// The destructor of method_type
22636{}
22637
22638// </method_type>
22639
22640// <function_decl definitions>
22641
22642struct function_decl::priv
22643{
22644 bool declared_inline_;
22645 decl_base::binding binding_;
22646 function_type_wptr type_;
22647 function_type* naked_type_;
22648 elf_symbol_sptr symbol_;
22649 interned_string id_;
22650
22651 priv()
22652 : declared_inline_(false),
22653 binding_(decl_base::BINDING_GLOBAL),
22654 naked_type_()
22655 {}
22656
22657 priv(function_type_sptr t,
22658 bool declared_inline,
22660 : declared_inline_(declared_inline),
22661 binding_(binding),
22662 type_(t),
22663 naked_type_(t.get())
22664 {}
22665
22666 priv(function_type_sptr t,
22667 bool declared_inline,
22670 : declared_inline_(declared_inline),
22671 binding_(binding),
22672 type_(t),
22673 naked_type_(t.get()),
22674 symbol_(s)
22675 {}
22676}; // end sruct function_decl::priv
22677
22678/// Constructor of the @ref function_decl.
22679///
22680/// @param name the name of the function.
22681///
22682/// @param function_type the type of the function.
22683///
22684/// @param declared_inline wether the function is declared inline.
22685///
22686/// @param locus the source location of the function.
22687///
22688/// @param mangled_name the linkage name of the function.
22689///
22690/// @param vis the visibility of the function.
22691///
22692/// @param bind the binding of the function.
22695 bool declared_inline,
22696 const location& locus,
22697 const string& mangled_name,
22698 visibility vis,
22699 binding bind)
22700 : type_or_decl_base(function_type->get_environment(),
22701 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22702 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
22703 priv_(new priv(function_type, declared_inline, bind))
22704{
22706}
22707
22708/// Constructor of the function_decl type.
22709///
22710/// This flavour of constructor is for when the pointer to the
22711/// instance of function_type that the client code has is presented as
22712/// a pointer to type_base. In that case, this constructor saves the
22713/// client code from doing a dynamic_cast to get the function_type
22714/// pointer.
22715///
22716/// @param name the name of the function declaration.
22717///
22718/// @param fn_type the type of the function declaration. The dynamic
22719/// type of this parameter should be 'pointer to function_type'
22720///
22721/// @param declared_inline whether this function was declared inline
22722///
22723/// @param locus the source location of the function declaration.
22724///
22725/// @param linkage_name the mangled name of the function declaration.
22726///
22727/// @param vis the visibility of the function declaration.
22728///
22729/// @param bind the kind of the binding of the function
22730/// declaration.
22732 type_base_sptr fn_type,
22733 bool declared_inline,
22734 const location& locus,
22735 const string& linkage_name,
22736 visibility vis,
22737 binding bind)
22738 : type_or_decl_base(fn_type->get_environment(),
22739 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22740 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
22741 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
22742 declared_inline,
22743 bind))
22744{
22746}
22747
22748/// Get the pretty representation of the current instance of @ref function_decl.
22749///
22750/// @param internal set to true if the call is intended to get a
22751/// representation of the decl (or type) for the purpose of canonical
22752/// type comparison. This is mainly used in the function
22753/// type_base::get_canonical_type_for().
22754///
22755/// In other words if the argument for this parameter is true then the
22756/// call is meant for internal use (for technical use inside the
22757/// library itself), false otherwise. If you don't know what this is
22758/// for, then set it to false.
22759///
22760/// @return the pretty representation for a function.
22761string
22763 bool qualified_name) const
22764{
22765 const method_decl* mem_fn =
22766 dynamic_cast<const method_decl*>(this);
22767
22768 string fn_prefix = mem_fn ? "method ": "function ";
22769 string result;
22770
22771 if (mem_fn
22772 && is_member_function(mem_fn)
22774 fn_prefix += "virtual ";
22775
22776 decl_base_sptr return_type;
22777 if ((mem_fn
22778 && is_member_function(mem_fn)
22779 && (get_member_function_is_dtor(*mem_fn)
22780 || get_member_function_is_ctor(*mem_fn))))
22781 /*cdtors do not have return types. */;
22782 else
22783 return_type = mem_fn
22784 ? get_type_declaration(mem_fn->get_type()->get_return_type())
22786
22787 result = get_pretty_representation_of_declarator(internal);
22788 if (return_type)
22789 {
22790 if (is_npaf_type(is_type(return_type))
22791 || !(is_pointer_to_function_type(is_type(return_type))
22792 || is_pointer_to_array_type(is_type(return_type))))
22793 result = get_type_name(is_type(return_type).get(), qualified_name,
22794 internal) + " " + result;
22795 else if (pointer_type_def_sptr p =
22797 result = add_outer_pointer_to_fn_type_expr(p, result,
22798 /*qualified=*/true,
22799 internal);
22800 else if(pointer_type_def_sptr p =
22801 is_pointer_to_array_type(is_type(return_type)))
22802 result = add_outer_pointer_to_array_type_expr(p, result,
22803 qualified_name,
22804 internal);
22805 else
22807 }
22808
22809 return fn_prefix + result;
22810}
22811
22812/// Compute and return the pretty representation for the part of the
22813/// function declaration that starts at the declarator. That is, the
22814/// return type and the other specifiers of the beginning of the
22815/// function's declaration ar omitted.
22816///
22817/// @param internal set to true if the call is intended to get a
22818/// representation of the decl (or type) for the purpose of canonical
22819/// type comparison. This is mainly used in the function
22820/// type_base::get_canonical_type_for().
22821///
22822/// In other words if the argument for this parameter is true then the
22823/// call is meant for internal use (for technical use inside the
22824/// library itself), false otherwise. If you don't know what this is
22825/// for, then set it to false.
22826///
22827/// @return the pretty representation for the part of the function
22828/// declaration that starts at the declarator.
22829string
22831{
22832 const method_decl* mem_fn =
22833 dynamic_cast<const method_decl*>(this);
22834
22835 string result;
22836
22837 if (mem_fn)
22838 {
22839 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22840 + "::" + mem_fn->get_name();
22841 }
22842 else
22843 result += get_qualified_name();
22844
22845 std::ostringstream fn_parms;
22846 stream_pretty_representation_of_fn_parms(*get_type(),
22847 fn_parms,
22848 /*qualified=*/true,
22849 internal);
22850 result += fn_parms.str();
22851
22852 if (mem_fn
22853 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22854 || is_method_type(mem_fn->get_type())->get_is_const()))
22855 result += " const";
22856
22857 return result;
22858}
22859
22860/// Getter for the first non-implicit parameter of a function decl.
22861///
22862/// If the function is a non-static member function, the parameter
22863/// returned is the first one following the implicit 'this' parameter.
22864///
22865/// @return the first non implicit parm.
22866function_decl::parameters::const_iterator
22868{
22869 if (get_parameters().empty())
22870 return get_parameters().end();
22871
22872 bool is_method = dynamic_cast<const method_decl*>(this);
22873
22874 parameters::const_iterator i = get_parameters().begin();
22875 if (is_method)
22876 ++i;
22877
22878 return i;
22879}
22880
22881/// Return the type of the current instance of @ref function_decl.
22882///
22883/// It's either a function_type or method_type.
22884/// @return the type of the current instance of @ref function_decl.
22885const shared_ptr<function_type>
22887{return priv_->type_.lock();}
22888
22889/// Fast getter of the type of the current instance of @ref function_decl.
22890///
22891/// Note that this function returns the underlying pointer managed by
22892/// the smart pointer returned by function_decl::get_type(). It's
22893/// faster than function_decl::get_type(). This getter is to be used
22894/// in code paths that are proven to be performance hot spots;
22895/// especially (for instance) when comparing function types. Those
22896/// are compared extremely frequently when libabigail is used to
22897/// handle huge binaries with a lot of functions.
22898///
22899/// @return the type of the current instance of @ref function_decl.
22900const function_type*
22902{return priv_->naked_type_;}
22903
22904void
22905function_decl::set_type(const function_type_sptr& fn_type)
22906{
22907 priv_->type_ = fn_type;
22908 priv_->naked_type_ = fn_type.get();
22909}
22910
22911/// This sets the underlying ELF symbol for the current function decl.
22912///
22913/// And underlyin$g ELF symbol for the current function decl might
22914/// exist only if the corpus that this function decl originates from
22915/// was constructed from an ELF binary file.
22916///
22917/// Note that comparing two function decls that have underlying ELF
22918/// symbols involves comparing their underlying elf symbols. The decl
22919/// name for the function thus becomes irrelevant in the comparison.
22920///
22921/// @param sym the new ELF symbol for this function decl.
22922void
22924{
22925 priv_->symbol_ = sym;
22926 // The function id cache that depends on the symbol must be
22927 // invalidated because the symbol changed.
22928 priv_->id_ = get_environment().intern("");
22929}
22930
22931/// Gets the the underlying ELF symbol for the current variable,
22932/// that was set using function_decl::set_symbol(). Please read the
22933/// documentation for that member function for more information about
22934/// "underlying ELF symbols".
22935///
22936/// @return sym the underlying ELF symbol for this function decl, if
22937/// one exists.
22938const elf_symbol_sptr&
22940{return priv_->symbol_;}
22941
22942/// Test if the function was declared inline.
22943///
22944/// @return true iff the function was declared inline.
22945bool
22947{return priv_->declared_inline_;}
22948
22949/// Set the property of the function being declared inline.
22950///
22951/// @param value true iff the function was declared inline.
22952void
22954{priv_->declared_inline_ = value;}
22955
22957function_decl::get_binding() const
22958{return priv_->binding_;}
22959
22960/// @return the return type of the current instance of function_decl.
22961const shared_ptr<type_base>
22963{return get_type()->get_return_type();}
22964
22965/// @return the parameters of the function.
22966const std::vector<shared_ptr<function_decl::parameter> >&
22968{return get_type()->get_parameters();}
22969
22970/// Append a parameter to the type of this function.
22971///
22972/// @param parm the parameter to append.
22973void
22974function_decl::append_parameter(shared_ptr<parameter> parm)
22975{get_type()->append_parameter(parm);}
22976
22977/// Append a vector of parameters to the type of this function.
22978///
22979/// @param parms the vector of parameters to append.
22980void
22981function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
22982{
22983 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
22984 i != parms.end();
22985 ++i)
22986 get_type()->append_parameter(*i);
22987}
22988
22989/// Create a new instance of function_decl that is a clone of the
22990/// current one.
22991///
22992/// @return the new clone.
22995{
22997 if (is_member_function(*this))
22998 {
22999 method_decl_sptr
23000 m(new method_decl(get_name(),
23001 get_type(),
23003 get_location(),
23006 get_binding()));
23008 ABG_ASSERT(scope);
23012 get_member_is_static(*this),
23016 f = m;
23017 }
23018 else
23019 {
23020 f.reset(new function_decl(get_name(),
23021 get_type(),
23023 get_location(),
23026 get_binding()));
23028 }
23029 f->set_symbol(get_symbol());
23030
23031 return f;
23032}
23033
23034/// Compares two instances of @ref function_decl.
23035///
23036/// If the two intances are different, set a bitfield to give some
23037/// insight about the kind of differences there are.
23038///
23039/// @param l the first artifact of the comparison.
23040///
23041/// @param r the second artifact of the comparison.
23042///
23043/// @param k a pointer to a bitfield that gives information about the
23044/// kind of changes there are between @p l and @p r. This one is set
23045/// iff @p k is non-null and the function returns false.
23046///
23047/// Please note that setting k to a non-null value does have a
23048/// negative performance impact because even if @p l and @p r are not
23049/// equal, the function keeps up the comparison in order to determine
23050/// the different kinds of ways in which they are different.
23051///
23052/// @return true if @p l equals @p r, false otherwise.
23053bool
23055{
23056 bool result = true;
23057
23058 // Compare function types
23059 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
23060 if (t0 == t1 || *t0 == *t1)
23061 ; // the types are equal, let's move on to compare the other
23062 // properties of the functions.
23063 else
23064 {
23065 result = false;
23066 if (k)
23067 {
23068 if (!types_have_similar_structure(t0, t1))
23070 else
23071 *k |= SUBTYPE_CHANGE_KIND;
23072 }
23073 else
23075 }
23076
23077 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
23078 if (!!s0 != !!s1)
23079 {
23080 result = false;
23081 if (k)
23083 else
23085 }
23086 else if (s0 && s0 != s1)
23087 {
23088 if (!elf_symbols_alias(s0, s1))
23089 {
23090 result = false;
23091 if (k)
23093 else
23095 }
23096 }
23097 bool symbols_are_equal = (s0 && s1 && result);
23098
23099 if (symbols_are_equal)
23100 {
23101 // The functions have underlying elf symbols that are equal,
23102 // so now, let's compare the decl_base part of the functions
23103 // w/o considering their decl names.
23104 interned_string n1 = l.get_name(), n2 = r.get_name();
23106 const_cast<function_decl&>(l).set_name("");
23107 const_cast<function_decl&>(l).set_linkage_name("");
23108 const_cast<function_decl&>(r).set_name("");
23109 const_cast<function_decl&>(r).set_linkage_name("");
23110
23111 bool decl_bases_different = !l.decl_base::operator==(r);
23112
23113 const_cast<function_decl&>(l).set_name(n1);
23114 const_cast<function_decl&>(l).set_linkage_name(ln1);
23115 const_cast<function_decl&>(r).set_name(n2);
23116 const_cast<function_decl&>(r).set_linkage_name(ln2);
23117
23118 if (decl_bases_different)
23119 {
23120 result = false;
23121 if (k)
23123 else
23125 }
23126 }
23127 else
23128 if (!l.decl_base::operator==(r))
23129 {
23130 result = false;
23131 if (k)
23133 else
23135 }
23136
23137 // Compare the remaining properties. Note that we don't take into
23138 // account the fact that the function was declared inline or not as
23139 // that doesn't have any impact on the final ABI.
23140 if (l.get_binding() != r.get_binding())
23141 {
23142 result = false;
23143 if (k)
23145 else
23147 }
23148
23150 {
23151 result = false;
23152 if (k)
23154 else
23156 }
23157
23159 {
23172 {
23173 result = false;
23174 if (k)
23176 else
23178 }
23179 }
23180
23181 ABG_RETURN(result);
23182}
23183
23184/// Comparison operator for @ref function_decl.
23185///
23186/// @param other the other instance of @ref function_decl to compare
23187/// against.
23188///
23189/// @return true iff the current instance of @ref function_decl equals
23190/// @p other.
23191bool
23193{
23194 const function_decl* o = dynamic_cast<const function_decl*>(&other);
23195 if (!o)
23196 return false;
23197 return equals(*this, *o, 0);
23198}
23199
23200/// Return true iff the function takes a variable number of
23201/// parameters.
23202///
23203/// @return true if the function taks a variable number
23204/// of parameters.
23205bool
23207{
23208 return (!get_parameters().empty()
23209 && get_parameters().back()->get_variadic_marker());
23210}
23211
23212/// Return an ID that tries to uniquely identify the function inside a
23213/// program or a library.
23214///
23215/// So if the function has an underlying elf symbol, the ID is the
23216/// concatenation of the symbol name and its version. Otherwise, the
23217/// ID is the linkage name if its non-null. Otherwise, it's the
23218/// pretty representation of the function.
23219///
23220/// @return the ID.
23223{
23224 if (priv_->id_.empty())
23225 {
23226 const environment& env = get_type()->get_environment();
23227 if (elf_symbol_sptr s = get_symbol())
23228 {
23229 string virtual_member_suffix;
23230 if (is_member_function(this))
23231 {
23232 method_decl* m = is_method_decl(this);
23233 ABG_ASSERT(m);
23235 {
23237 (m->get_type()->get_class_type(),
23238 /*look_through_decl_only=*/true))
23239 virtual_member_suffix += "/o";
23240 }
23241 }
23242 if (s->has_aliases())
23243 // The symbol has several aliases, so let's use a scheme
23244 // that allows all aliased functions to have different
23245 // IDs.
23246 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
23247 else
23248 // Let's use the full symbol name with its version as ID.
23249 priv_->id_ = env.intern(s->get_id_string());
23250
23251 if (!virtual_member_suffix.empty())
23252 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
23253 }
23254 else if (!get_linkage_name().empty())
23255 priv_->id_= env.intern(get_linkage_name());
23256 else
23257 priv_->id_ = env.intern(get_pretty_representation());
23258 }
23259 return priv_->id_;
23260}
23261
23262/// Test if two function declarations are aliases.
23263///
23264/// Two functions declarations are aliases if their symbols are
23265/// aliases, in the ELF sense.
23266///
23267/// @param f1 the first function to consider.
23268///
23269/// @param f2 the second function to consider.
23270///
23271/// @return true iff @p f1 is an alias of @p f2
23272bool
23274{
23275 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
23276
23277 if (!s1 || !s2)
23278 return false;
23279
23280 return elf_symbols_alias(s1, s2);
23281}
23282
23283/// This implements the ir_traversable_base::traverse pure virtual
23284/// function.
23285///
23286/// @param v the visitor used on the current instance.
23287///
23288/// @return true if the entire IR node tree got traversed, false
23289/// otherwise.
23290bool
23292{
23293 if (visiting())
23294 return true;
23295
23296 if (v.visit_begin(this))
23297 {
23298 visiting(true);
23299 if (type_base_sptr t = get_type())
23300 t->traverse(v);
23301 visiting(false);
23302 }
23303 return v.visit_end(this);
23304}
23305
23306/// Destructor of the @ref function_decl type.
23308{delete priv_;}
23309
23310/// A deep comparison operator for a shared pointer to @ref function_decl
23311///
23312/// This function compares to shared pointers to @ref function_decl by
23313/// looking at the pointed-to instances of @ref function_dec
23314/// comparing them too. If the two pointed-to objects are equal then
23315/// this function returns true.
23316///
23317/// @param l the left-hand side argument of the equality operator.
23318///
23319/// @param r the right-hand side argument of the equality operator.
23320///
23321/// @return true iff @p l equals @p r.
23322bool
23324{
23325 if (l.get() == r.get())
23326 return true;
23327 if (!!l != !!r)
23328 return false;
23329
23330 return *l == *r;
23331}
23332
23333/// A deep inequality operator for smart pointers to functions.
23334///
23335/// @param l the left-hand side argument of the inequality operator.
23336///
23337/// @pram r the right-hand side argument of the inequality operator.
23338///
23339/// @return true iff @p is not equal to @p r.
23340bool
23342{return !operator==(l, r);}
23343
23344// <function_decl definitions>
23345
23346// <function_decl::parameter definitions>
23347
23348struct function_decl::parameter::priv
23349{
23350 type_base_wptr type_;
23351 unsigned index_;
23352 bool variadic_marker_;
23353
23354 priv()
23355 : index_(),
23356 variadic_marker_()
23357 {}
23358
23359 priv(type_base_sptr type,
23360 unsigned index,
23361 bool variadic_marker)
23362 : type_(type),
23363 index_(index),
23364 variadic_marker_(variadic_marker)
23365 {}
23366};// end struct function_decl::parameter::priv
23367
23368function_decl::parameter::parameter(const type_base_sptr type,
23369 unsigned index,
23370 const string& name,
23371 const location& loc,
23372 bool is_variadic)
23373 : type_or_decl_base(type->get_environment(),
23374 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23375 decl_base(type->get_environment(), name, loc),
23376 priv_(new priv(type, index, is_variadic))
23377{
23378 runtime_type_instance(this);
23379}
23380
23381function_decl::parameter::parameter(const type_base_sptr type,
23382 unsigned index,
23383 const string& name,
23384 const location& loc,
23385 bool is_variadic,
23386 bool is_artificial)
23387 : type_or_decl_base(type->get_environment(),
23388 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23389 decl_base(type->get_environment(), name, loc),
23390 priv_(new priv(type, index, is_variadic))
23391{
23392 runtime_type_instance(this);
23393 set_is_artificial(is_artificial);
23394}
23395
23396function_decl::parameter::parameter(const type_base_sptr type,
23397 const string& name,
23398 const location& loc,
23399 bool is_variadic,
23400 bool is_artificial)
23401 : type_or_decl_base(type->get_environment(),
23402 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23403 decl_base(type->get_environment(), name, loc),
23404 priv_(new priv(type, 0, is_variadic))
23405{
23406 runtime_type_instance(this);
23407 set_is_artificial(is_artificial);
23408}
23409
23410function_decl::parameter::parameter(const type_base_sptr type,
23411 unsigned index,
23412 bool variad)
23413 : type_or_decl_base(type->get_environment(),
23414 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23415 decl_base(type->get_environment(), "", location()),
23416 priv_(new priv(type, index, variad))
23417{
23418 runtime_type_instance(this);
23419}
23420
23421function_decl::parameter::~parameter() = default;
23422
23423const type_base_sptr
23424function_decl::parameter::get_type()const
23425{return priv_->type_.lock();}
23426
23427/// @return a copy of the type name of the parameter.
23428interned_string
23430{
23431 const environment& env = get_environment();
23432
23433 type_base_sptr t = get_type();
23434 string str;
23435 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
23436 str = "...";
23437 else
23438 {
23439 ABG_ASSERT(t);
23441 }
23442 return env.intern(str);
23443}
23444
23445/// @return a copy of the pretty representation of the type of the
23446/// parameter.
23447const string
23449{
23450 type_base_sptr t = get_type();
23451 string str;
23452 if (get_variadic_marker()
23453 || get_environment().is_variadic_parameter_type(t))
23454 str = "...";
23455 else
23456 {
23457 ABG_ASSERT(t);
23459 }
23460 return str;
23461}
23462
23463/// Get a name uniquely identifying the parameter in the function.
23464///
23465///@return the unique parm name id.
23468{
23469 const environment& env = get_environment();
23470
23471
23472 std::ostringstream o;
23473 o << "parameter-" << get_index();
23474
23475 return env.intern(o.str());
23476}
23477
23478unsigned
23479function_decl::parameter::get_index() const
23480{return priv_->index_;}
23481
23482void
23483function_decl::parameter::set_index(unsigned i)
23484{priv_->index_ = i;}
23485
23486
23487bool
23488function_decl::parameter::get_variadic_marker() const
23489{return priv_->variadic_marker_;}
23490
23491/// Compares two instances of @ref function_decl::parameter.
23492///
23493/// If the two intances are different, set a bitfield to give some
23494/// insight about the kind of differences there are.
23495///
23496/// @param l the first artifact of the comparison.
23497///
23498/// @param r the second artifact of the comparison.
23499///
23500/// @param k a pointer to a bitfield that gives information about the
23501/// kind of changes there are between @p l and @p r. This one is set
23502/// iff @p k is non-null and the function returns false.
23503///
23504/// Please note that setting k to a non-null value does have a
23505/// negative performance impact because even if @p l and @p r are not
23506/// equal, the function keeps up the comparison in order to determine
23507/// the different kinds of ways in which they are different.
23508///
23509/// @return true if @p l equals @p r, false otherwise.
23510bool
23512 const function_decl::parameter& r,
23513 change_kind* k)
23514{
23515 bool result = true;
23516
23517 if ((l.get_variadic_marker() != r.get_variadic_marker())
23518 || (l.get_index() != r.get_index())
23519 || (!!l.get_type() != !!r.get_type()))
23520 {
23521 result = false;
23522 if (k)
23523 {
23524 if (l.get_index() != r.get_index())
23526 if (l.get_variadic_marker() != r.get_variadic_marker()
23527 || !!l.get_type() != !!r.get_type())
23529 }
23530 else
23532 }
23533
23534 type_base_sptr l_type = l.get_type();
23535 type_base_sptr r_type = r.get_type();
23536
23537 if (l_type != r_type)
23538 {
23539 result = false;
23540 if (k)
23541 {
23542 if (!types_have_similar_structure(l_type, r_type))
23544 else
23545 *k |= SUBTYPE_CHANGE_KIND;
23546 }
23547 else
23549 }
23550
23551 ABG_RETURN(result);
23552}
23553
23554bool
23555function_decl::parameter::operator==(const parameter& o) const
23556{return equals(*this, o, 0);}
23557
23558bool
23559function_decl::parameter::operator==(const decl_base& o) const
23560{
23561 const function_decl::parameter* p =
23562 dynamic_cast<const function_decl::parameter*>(&o);
23563 if (!p)
23564 return false;
23565 return function_decl::parameter::operator==(*p);
23566}
23567
23568/// Non-member equality operator for @ref function_decl::parameter.
23569///
23570/// @param l the left-hand side of the equality operator
23571///
23572/// @param r the right-hand side of the equality operator
23573///
23574/// @return true iff @p l and @p r equals.
23575bool
23578{
23579 if (!!l != !!r)
23580 return false;
23581 if (!l)
23582 return true;
23583 return *l == *r;
23584}
23585
23586/// Non-member inequality operator for @ref function_decl::parameter.
23587///
23588/// @param l the left-hand side of the equality operator
23589///
23590/// @param r the right-hand side of the equality operator
23591///
23592/// @return true iff @p l and @p r different.
23593bool
23596{return !operator==(l, r);}
23597
23598/// Traverse the diff sub-tree under the current instance
23599/// function_decl.
23600///
23601/// @param v the visitor to invoke on each diff node of the sub-tree.
23602///
23603/// @return true if the traversing has to keep going on, false
23604/// otherwise.
23605bool
23607{
23608 if (visiting())
23609 return true;
23610
23611 if (v.visit_begin(this))
23612 {
23613 visiting(true);
23614 if (type_base_sptr t = get_type())
23615 t->traverse(v);
23616 visiting(false);
23617 }
23618 return v.visit_end(this);
23619}
23620
23621/// Compute the qualified name of the parameter.
23622///
23623/// @param internal set to true if the call is intended for an
23624/// internal use (for technical use inside the library itself), false
23625/// otherwise. If you don't know what this is for, then set it to
23626/// false.
23627///
23628/// @param qn the resulting qualified name.
23629void
23631 bool /*internal*/) const
23632{qualified_name = get_name();}
23633
23634/// Compute and return a copy of the pretty representation of the
23635/// current function parameter.
23636///
23637/// @param internal set to true if the call is intended to get a
23638/// representation of the decl (or type) for the purpose of canonical
23639/// type comparison. This is mainly used in the function
23640/// type_base::get_canonical_type_for().
23641///
23642/// In other words if the argument for this parameter is true then the
23643/// call is meant for internal use (for technical use inside the
23644/// library itself), false otherwise. If you don't know what this is
23645/// for, then set it to false.
23646///
23647/// @return a copy of the textual representation of the current
23648/// function parameter.
23649string
23651 bool qualified_name) const
23652{
23653 const environment& env = get_environment();
23654
23655 string type_repr;
23656 type_base_sptr t = get_type();
23657 if (!t)
23658 type_repr = "void";
23659 else if (env.is_variadic_parameter_type(t))
23660 type_repr = "...";
23661 else
23662 type_repr = ir::get_type_name(t, qualified_name, internal);
23663
23664 string result = type_repr;
23665 string parm_name = get_name_id();
23666
23667 if (!parm_name.empty())
23668 result += " " + parm_name;
23669
23670 return result;
23671}
23672
23673// </function_decl::parameter definitions>
23674
23675// <class_or_union definitions>
23676
23677/// A Constructor for instances of @ref class_or_union
23678///
23679/// @param env the environment we are operating from.
23680///
23681/// @param name the identifier of the class.
23682///
23683/// @param size_in_bits the size of an instance of @ref
23684/// class_or_union, expressed in bits
23685///
23686/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23687/// expressed in bits.
23688///
23689/// @param locus the source location of declaration point this class.
23690///
23691/// @param vis the visibility of instances of @ref class_or_union.
23692///
23693/// @param mem_types the vector of member types of this instance of
23694/// @ref class_or_union.
23695///
23696/// @param data_members the vector of data members of this instance of
23697/// @ref class_or_union.
23698///
23699/// @param member_fns the vector of member functions of this instance
23700/// of @ref class_or_union.
23701class_or_union::class_or_union(const environment& env, const string& name,
23702 size_t size_in_bits, size_t align_in_bits,
23703 const location& locus, visibility vis,
23704 member_types& mem_types,
23706 member_functions& member_fns)
23707 : type_or_decl_base(env,
23708 ABSTRACT_TYPE_BASE
23709 | ABSTRACT_DECL_BASE
23710 | ABSTRACT_SCOPE_TYPE_DECL
23711 | ABSTRACT_SCOPE_DECL),
23712 decl_base(env, name, locus, name, vis),
23713 type_base(env, size_in_bits, align_in_bits),
23714 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23715 priv_(new priv(data_members, member_fns))
23716{
23717 for (member_types::iterator i = mem_types.begin();
23718 i != mem_types.end();
23719 ++i)
23722
23723 for (data_members::iterator i = data_members.begin();
23724 i != data_members.end();
23725 ++i)
23726 if (!has_scope(*i))
23727 add_decl_to_scope(*i, this);
23728
23729 for (member_functions::iterator i = member_fns.begin();
23730 i != member_fns.end();
23731 ++i)
23732 if (!has_scope(static_pointer_cast<decl_base>(*i)))
23733 add_decl_to_scope(*i, this);
23734}
23735
23736/// A constructor for instances of @ref class_or_union.
23737///
23738/// @param env the environment we are operating from.
23739///
23740/// @param name the name of the class.
23741///
23742/// @param size_in_bits the size of an instance of @ref
23743/// class_or_union, expressed in bits
23744///
23745/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23746/// expressed in bits.
23747///
23748/// @param locus the source location of declaration point this class.
23749///
23750/// @param vis the visibility of instances of @ref class_or_union.
23751class_or_union::class_or_union(const environment& env, const string& name,
23752 size_t size_in_bits, size_t align_in_bits,
23753 const location& locus, visibility vis)
23754 : type_or_decl_base(env,
23755 ABSTRACT_TYPE_BASE
23756 | ABSTRACT_DECL_BASE
23757 | ABSTRACT_SCOPE_TYPE_DECL
23758 | ABSTRACT_SCOPE_DECL),
23759 decl_base(env, name, locus, name, vis),
23760 type_base(env, size_in_bits, align_in_bits),
23761 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23762 priv_(new priv)
23763{}
23764
23765/// Constructor of the @ref class_or_union type.
23766///
23767/// @param env the @ref environment we are operating from.
23768///
23769/// @param name the name of the @ref class_or_union.
23770///
23771/// @param is_declaration_only a boolean saying whether the instance
23772/// represents a declaration only, or not.
23773class_or_union::class_or_union(const environment& env, const string& name,
23774 bool is_declaration_only)
23775 : type_or_decl_base(env,
23776 ABSTRACT_TYPE_BASE
23777 | ABSTRACT_DECL_BASE
23778 | ABSTRACT_SCOPE_TYPE_DECL
23779 | ABSTRACT_SCOPE_DECL),
23780 decl_base(env, name, location(), name),
23781 type_base(env, 0, 0),
23782 scope_type_decl(env, name, 0, 0, location()),
23783 priv_(new priv)
23784{
23785 set_is_declaration_only(is_declaration_only);
23786}
23787
23788/// Return the hash value of the current IR node.
23789///
23790/// Note that upon the first invocation, this member functions
23791/// computes the hash value and returns it. Subsequent invocations
23792/// just return the hash value that was previously calculated.
23793///
23794/// @return the hash value of the current IR node.
23795hash_t
23797{
23798 class_or_union::hash do_hash;
23799 hash_t h = do_hash(this);
23800 return h;
23801}
23802
23803/// This implements the ir_traversable_base::traverse pure virtual
23804/// function.
23805///
23806/// @param v the visitor used on the member nodes of the translation
23807/// unit during the traversal.
23808///
23809/// @return true if the entire IR node tree got traversed, false
23810/// otherwise.
23811bool
23813{
23814 if (v.type_node_has_been_visited(this))
23815 return true;
23816
23817 if (visiting())
23818 return true;
23819
23820 if (v.visit_begin(this))
23821 {
23822 visiting(true);
23823 bool stop = false;
23824
23825 if (!stop)
23826 for (data_members::const_iterator i = get_data_members().begin();
23827 i != get_data_members().end();
23828 ++i)
23829 if (!(*i)->traverse(v))
23830 {
23831 stop = true;
23832 break;
23833 }
23834
23835 if (!stop)
23836 for (member_functions::const_iterator i= get_member_functions().begin();
23837 i != get_member_functions().end();
23838 ++i)
23839 if (!(*i)->traverse(v))
23840 {
23841 stop = true;
23842 break;
23843 }
23844
23845 if (!stop)
23846 for (member_types::const_iterator i = get_member_types().begin();
23847 i != get_member_types().end();
23848 ++i)
23849 if (!(*i)->traverse(v))
23850 {
23851 stop = true;
23852 break;
23853 }
23854
23855 if (!stop)
23856 for (member_function_templates::const_iterator i =
23858 i != get_member_function_templates().end();
23859 ++i)
23860 if (!(*i)->traverse(v))
23861 {
23862 stop = true;
23863 break;
23864 }
23865
23866 if (!stop)
23867 for (member_class_templates::const_iterator i =
23869 i != get_member_class_templates().end();
23870 ++i)
23871 if (!(*i)->traverse(v))
23872 {
23873 stop = true;
23874 break;
23875 }
23876 visiting(false);
23877 }
23878
23879 bool result = v.visit_end(this);
23881 return result;
23882}
23883
23884/// Destrcutor of the @ref class_or_union type.
23886{delete priv_;}
23887
23888/// Add a member declaration to the current instance of class_or_union.
23889/// The member declaration can be either a member type, data member,
23890/// member function, or member template.
23891///
23892/// @param d the member declaration to add.
23893decl_base_sptr
23894class_or_union::add_member_decl(const decl_base_sptr& d)
23895{return insert_member_decl(d);}
23896
23897/// Remove a given decl from the current @ref class_or_union scope.
23898///
23899/// Note that only type declarations are supported by this method for
23900/// now. Support for the other kinds of declaration is left as an
23901/// exercise for the interested reader of the code.
23902///
23903/// @param decl the declaration to remove from this @ref
23904/// class_or_union scope.
23905void
23907{
23908 type_base_sptr t = is_type(decl);
23909
23910 // For now we want to support just removing types from classes. For
23911 // other kinds of IR node, we need more work.
23912 ABG_ASSERT(t);
23913
23915}
23916
23917/// Fixup the members of the type of an anonymous data member.
23918///
23919/// Walk all data members of (the type of) a given anonymous data
23920/// member and set a particular property of the relationship between
23921/// each data member and its containing type.
23922///
23923/// That property records the fact that the data member belongs to the
23924/// anonymous data member we consider.
23925///
23926/// In the future, if there are other properties of this relationship
23927/// to set in this manner, they ought to be added here.
23928///
23929/// @param anon_dm the anonymous data member to consider.
23930void
23932{
23933 class_or_union * anon_dm_type =
23935 if (!anon_dm_type)
23936 return;
23937
23938 for (class_or_union::data_members::const_iterator it =
23939 anon_dm_type->get_non_static_data_members().begin();
23940 it != anon_dm_type->get_non_static_data_members().end();
23941 ++it)
23942 {
23943 dm_context_rel *rel =
23944 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
23945 ABG_ASSERT(rel);
23946 rel->set_anonymous_data_member(anon_dm.get());
23947 }
23948}
23949
23950/// Getter of the alignment of the @ref class_or_union type.
23951///
23952/// If this @ref class_or_union is a declaration of a definition that
23953/// is elsewhere, then the size of the definition is returned.
23954///
23955/// @return the alignment of the @ref class_or_union type.
23956size_t
23958{
23962
23964}
23965
23966/// Setter of the alignment of the class type.
23967///
23968/// If this class is a declaration of a definition that is elsewhere,
23969/// then the new alignment is set to the definition.
23970///
23971/// @param s the new alignment.
23972void
23974{
23978 else
23980}
23981
23982/// Setter of the size of the @ref class_or_union type.
23983///
23984/// If this @ref class_or_union is a declaration of a definition that
23985/// is elsewhere, then the new size is set to the definition.
23986///
23987/// @param s the new size.
23988void
23990{
23994 else
23996}
23997
23998/// Getter of the size of the @ref class_or_union type.
23999///
24000/// If this @ref class_or_union is a declaration of a definition that
24001/// is elsewhere, then the size of the definition is returned.
24002///
24003/// @return the size of the @ref class_or_union type.
24004size_t
24006{
24010
24012}
24013
24014/// Get the number of anonymous member classes contained in this
24015/// class.
24016///
24017/// @return the number of anonymous member classes contained in this
24018/// class.
24019size_t
24021{
24022 int result = 0;
24023 for (member_types::const_iterator it = get_member_types().begin();
24024 it != get_member_types().end();
24025 ++it)
24026 if (class_decl_sptr t = is_class_type(*it))
24027 if (t->get_is_anonymous())
24028 ++result;
24029
24030 return result;
24031}
24032
24033/// Get the number of anonymous member unions contained in this class.
24034///
24035/// @return the number of anonymous member unions contained in this
24036/// class.
24037size_t
24039{
24040 int result = 0;
24041 for (member_types::const_iterator it = get_member_types().begin();
24042 it != get_member_types().end();
24043 ++it)
24044 if (union_decl_sptr t = is_union_type(*it))
24045 if (t->get_is_anonymous())
24046 ++result;
24047
24048 return result;
24049}
24050
24051/// Get the number of anonymous member enums contained in this class.
24052///
24053/// @return the number of anonymous member enums contained in this
24054/// class.
24055size_t
24057{
24058 int result = 0;
24059 for (member_types::const_iterator it = get_member_types().begin();
24060 it != get_member_types().end();
24061 ++it)
24062 if (enum_type_decl_sptr t = is_enum_type(*it))
24063 if (t->get_is_anonymous())
24064 ++result;
24065
24066 return result;
24067}
24068
24069/// Add a data member to the current instance of class_or_union.
24070///
24071/// @param v a var_decl to add as a data member. A proper
24072/// class_or_union::data_member is created from @p v and added to the
24073/// class_or_union. This var_decl should not have been already added
24074/// to a scope.
24075///
24076/// @param access the access specifier for the data member.
24077///
24078/// @param is_laid_out whether the data member was laid out. That is,
24079/// if its offset has been computed. In the pattern of a class
24080/// template for instance, this would be set to false.
24081///
24082/// @param is_static whether the data memer is static.
24083///
24084/// @param offset_in_bits if @p is_laid_out is true, this is the
24085/// offset of the data member, expressed (oh, surprise) in bits.
24086void
24088 bool is_laid_out, bool is_static,
24089 size_t offset_in_bits)
24090{
24091 ABG_ASSERT(!has_scope(v));
24092
24093 priv_->data_members_.push_back(v);
24095 set_data_member_is_laid_out(v, is_laid_out);
24096 set_data_member_offset(v, offset_in_bits);
24097 set_member_access_specifier(v, access);
24098 set_member_is_static(v, is_static);
24099
24100 // Add the variable to the set of static or non-static data members,
24101 // if it's not already in there.
24102 bool is_already_in = false;
24103 if (is_static)
24104 {
24105 for (const auto& s_dm: priv_->static_data_members_)
24106 {
24107 if (s_dm == v)
24108 {
24109 is_already_in = true;
24110 break;
24111 }
24112 }
24113 if (!is_already_in)
24114 priv_->static_data_members_.push_back(v);
24115 }
24116 else
24117 {
24118 // If this is a non-static variable, add it to the set of
24119 // non-static variables, if it's not already in there.
24120 for (data_members::const_iterator i =
24121 priv_->non_static_data_members_.begin();
24122 i != priv_->non_static_data_members_.end();
24123 ++i)
24124 if (*i == v)
24125 {
24126 is_already_in = true;
24127 break;
24128 }
24129 if (!is_already_in)
24130 priv_->non_static_data_members_.push_back(v);
24131 }
24132
24133 // If v is an anonymous data member, then fixup its data members.
24134 // For now, the only thing the fixup does is to make the data
24135 // members of the anonymous data member be aware of their containing
24136 // anonymous data member. That is helpful to compute the absolute
24137 // bit offset of each of the members of the anonymous data member.
24139}
24140
24141/// Get the data members of this @ref class_or_union.
24142///
24143/// @return a vector of the data members of this @ref class_or_union.
24146{return priv_->data_members_;}
24147
24148/// Find a data member of a given name in the current @ref class_or_union.
24149///
24150/// @param name the name of the data member to find in the current
24151/// @ref class_or_union.
24152///
24153/// @return a pointer to the @ref var_decl that represents the data
24154/// member to find inside the current @ref class_or_union.
24155const var_decl_sptr
24156class_or_union::find_data_member(const string& name) const
24157{
24158 for (data_members::const_iterator i = get_data_members().begin();
24159 i != get_data_members().end();
24160 ++i)
24161 if ((*i)->get_name() == name)
24162 return *i;
24163
24164 // We haven't found a data member with the name 'name'. Let's look
24165 // closer again, this time in our anonymous data members.
24166 for (data_members::const_iterator i = get_data_members().begin();
24167 i != get_data_members().end();
24168 ++i)
24170 {
24171 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
24172 ABG_ASSERT(type);
24173 if (var_decl_sptr data_member = type->find_data_member(name))
24174 return data_member;
24175 }
24176
24177 return var_decl_sptr();
24178}
24179
24180/// Find an anonymous data member in the class.
24181///
24182/// @param v the anonymous data member to find.
24183///
24184/// @return the anonymous data member found, or nil if none was found.
24185const var_decl_sptr
24187{
24188 if (!v->get_name().empty())
24189 return var_decl_sptr();
24190
24191 for (data_members::const_iterator it = get_non_static_data_members().begin();
24192 it != get_non_static_data_members().end();
24193 ++it)
24194 {
24195 if (is_anonymous_data_member(*it))
24196 if ((*it)->get_pretty_representation(/*internal=*/false, true)
24197 == v->get_pretty_representation(/*internal=*/false, true))
24198 return *it;
24199 }
24200
24201 return var_decl_sptr();
24202}
24203
24204/// Find a given data member.
24205///
24206/// This function takes a @ref var_decl as an argument. If it has a
24207/// non-empty name, then it tries to find a data member which has the
24208/// same name as the argument.
24209///
24210/// If it has an empty name, then the @ref var_decl is considered as
24211/// an anonymous data member. In that case, this function tries to
24212/// find an anonymous data member which type equals that of the @ref
24213/// var_decl argument.
24214///
24215/// @param v this carries either the name of the data member we need
24216/// to look for, or the type of the anonymous data member we are
24217/// looking for.
24218const var_decl_sptr
24220{
24221 if (!v)
24222 return var_decl_sptr();
24223
24224 if (v->get_name().empty())
24226
24227 return find_data_member(v->get_name());
24228}
24229
24230
24231/// Get the non-static data members of this @ref class_or_union.
24232///
24233/// @return a vector of the non-static data members of this @ref
24234/// class_or_union.
24237{return priv_->non_static_data_members_;}
24238
24239/// Get the static data memebers of this @ref class_or_union.
24240///
24241/// @return a vector of the static data members of this @ref
24242/// class_or_union.
24245{return priv_->static_data_members_;}
24246
24247/// Add a member function.
24248///
24249/// @param f the new member function to add.
24250///
24251/// @param a the access specifier to use for the new member function.
24252///
24253/// @param is_static whether the new member function is static.
24254///
24255/// @param is_ctor whether the new member function is a constructor.
24256///
24257/// @param is_dtor whether the new member function is a destructor.
24258///
24259/// @param is_const whether the new member function is const.
24260void
24263 bool is_static, bool is_ctor,
24264 bool is_dtor, bool is_const)
24265{
24266 ABG_ASSERT(!has_scope(f));
24267
24269
24270 set_member_function_is_ctor(f, is_ctor);
24271 set_member_function_is_dtor(f, is_dtor);
24273 set_member_is_static(f, is_static);
24274 set_member_function_is_const(f, is_const);
24275
24276 priv_->member_functions_.push_back(f);
24277
24278 // Update the map of linkage name -> member functions. It's useful,
24279 // so that class_or_union::find_member_function() can function.
24280 if (!f->get_linkage_name().empty())
24281 priv_->mem_fns_map_[f->get_linkage_name()] = f;
24282}
24283
24284/// Get the member functions of this @ref class_or_union.
24285///
24286/// @return a vector of the member functions of this @ref
24287/// class_or_union.
24290{return priv_->member_functions_;}
24291
24292/// Find a method, using its linkage name as a key.
24293///
24294/// @param linkage_name the linkage name of the method to find.
24295///
24296/// @return the method found, or nil if none was found.
24297const method_decl*
24298class_or_union::find_member_function(const string& linkage_name) const
24299{
24300 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
24301}
24302
24303/// Find a method, using its linkage name as a key.
24304///
24305/// @param linkage_name the linkage name of the method to find.
24306///
24307/// @return the method found, or nil if none was found.
24309class_or_union::find_member_function(const string& linkage_name)
24310{
24311 string_mem_fn_sptr_map_type::const_iterator i =
24312 priv_->mem_fns_map_.find(linkage_name);
24313 if (i == priv_->mem_fns_map_.end())
24314 return 0;
24315 return i->second.get();
24316}
24317
24318/// Find a method, using its linkage name as a key.
24319///
24320/// @param linkage_name the linkage name of the method to find.
24321///
24322/// @return the method found, or nil if none was found.
24323method_decl_sptr
24325{
24326 string_mem_fn_sptr_map_type::const_iterator i =
24327 priv_->mem_fns_map_.find(linkage_name);
24328 if (i == priv_->mem_fns_map_.end())
24329 return 0;
24330 return i->second;
24331}
24332
24333/// Find a method (member function) using its signature (pretty
24334/// representation) as a key.
24335///
24336/// @param s the signature of the method.
24337///
24338/// @return the method found, or nil if none was found.
24339const method_decl*
24341{
24342 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
24343}
24344
24345/// Find a method (member function) using its signature (pretty
24346/// representation) as a key.
24347///
24348/// @param s the signature of the method.
24349///
24350/// @return the method found, or nil if none was found.
24353{
24354 string_mem_fn_ptr_map_type::const_iterator i =
24355 priv_->signature_2_mem_fn_map_.find(s);
24356 if (i == priv_->signature_2_mem_fn_map_.end())
24357 return 0;
24358 return i->second;
24359}
24360
24361/// Get the member function templates of this class.
24362///
24363/// @return a vector of the member function templates of this class.
24364const member_function_templates&
24366{return priv_->member_function_templates_;}
24367
24368/// Get the member class templates of this class.
24369///
24370/// @return a vector of the member class templates of this class.
24371const member_class_templates&
24373{return priv_->member_class_templates_;}
24374
24375/// Append a member function template to the @ref class_or_union.
24376///
24377/// @param m the member function template to append.
24378void
24379class_or_union::add_member_function_template(member_function_template_sptr m)
24380{
24381 decl_base* c = m->as_function_tdecl()->get_scope();
24382 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24383 /// error message or something like a structured error.
24384 priv_->member_function_templates_.push_back(m);
24385 if (!c)
24386 scope_decl::add_member_decl(m->as_function_tdecl());
24387}
24388
24389/// Append a member class template to the @ref class_or_union.
24390///
24391/// @param m the member function template to append.
24392void
24394{
24395 decl_base* c = m->as_class_tdecl()->get_scope();
24396 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24397 /// error message or something like a structured error.
24398 m->set_scope(this);
24399 priv_->member_class_templates_.push_back(m);
24400 if (!c)
24401 scope_decl::add_member_decl(m->as_class_tdecl());
24402}
24403
24404///@return true iff the current instance has no member.
24405bool
24407{
24408 return (get_member_types().empty()
24409 && priv_->data_members_.empty()
24410 && priv_->member_functions_.empty()
24411 && priv_->member_function_templates_.empty()
24412 && priv_->member_class_templates_.empty());
24413}
24414
24415/// Insert a data member to this @ref class_or_union type.
24416///
24417/// @param d the data member to insert.
24418///
24419/// @return the decl @p that got inserted.
24420decl_base_sptr
24422{
24423 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
24424 {
24425 add_data_member(v, public_access,
24426 /*is_laid_out=*/false,
24427 /*is_static=*/true,
24428 /*offset_in_bits=*/0);
24429 d = v;
24430 }
24431 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24432 add_member_function(f, public_access,
24433 /*is_static=*/false,
24434 /*is_ctor=*/false,
24435 /*is_dtor=*/false,
24436 /*is_const=*/false);
24437 else if (member_function_template_sptr f =
24438 dynamic_pointer_cast<member_function_template>(d))
24440 else if (member_class_template_sptr c =
24441 dynamic_pointer_cast<member_class_template>(d))
24443 else
24445
24446 return d;
24447}
24448
24449/// Equality operator.
24450///
24451/// @param other the other @ref class_or_union to compare against.
24452///
24453/// @return true iff @p other equals the current @ref class_or_union.
24454bool
24456{
24457 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
24458 if (!op)
24459 return false;
24460
24461 // If this is a decl-only type (and thus with no canonical type),
24462 // use the canonical type of the definition, if any.
24463 const class_or_union *l = 0;
24465 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
24466 if (l == 0)
24467 l = this;
24468
24469 // Likewise for the other class.
24470 const class_or_union *r = 0;
24471 if (op->get_is_declaration_only())
24472 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
24473 if (r == 0)
24474 r = op;
24475
24476 return try_canonical_compare(l, r);
24477}
24478
24479/// Equality operator.
24480///
24481/// @param other the other @ref class_or_union to compare against.
24482///
24483/// @return true iff @p other equals the current @ref class_or_union.
24484bool
24486{
24487 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24488 if (!o)
24489 return false;
24490 return *this == *o;
24491}
24492
24493/// Equality operator.
24494///
24495/// @param other the other @ref class_or_union to compare against.
24496///
24497/// @return true iff @p other equals the current @ref class_or_union.
24498bool
24500{
24501 const decl_base& o = other;
24503}
24504
24505/// Compares two instances of @ref class_or_union.
24506///
24507/// If the two intances are different, set a bitfield to give some
24508/// insight about the kind of differences there are.
24509///
24510/// @param l the first artifact of the comparison.
24511///
24512/// @param r the second artifact of the comparison.
24513///
24514/// @param k a pointer to a bitfield that gives information about the
24515/// kind of changes there are between @p l and @p r. This one is set
24516/// iff it's non-null and if the function returns false.
24517///
24518/// Please note that setting k to a non-null value does have a
24519/// negative performance impact because even if @p l and @p r are not
24520/// equal, the function keeps up the comparison in order to determine
24521/// the different kinds of ways in which they are different.
24522///
24523/// @return true if @p l equals @p r, false otherwise.
24524bool
24526{
24527 // if one of the classes is declaration-only, look through it to
24528 // get its definition.
24529 bool l_is_decl_only = l.get_is_declaration_only();
24530 bool r_is_decl_only = r.get_is_declaration_only();
24531 if (l_is_decl_only || r_is_decl_only)
24532 {
24533 const class_or_union* def1 = l_is_decl_only
24535 : &l;
24536
24537 const class_or_union* def2 = r_is_decl_only
24539 : &r;
24540
24541 if (!def1 || !def2)
24542 {
24543 if (!l.get_is_anonymous()
24544 && !r.get_is_anonymous()
24545 && l_is_decl_only && r_is_decl_only
24547 // The two decl-only classes differ from their size. A
24548 // true decl-only class should not have a size property to
24549 // begin with. This comes from a DWARF oddity and can
24550 // results in a false positive, so let's not consider that
24551 // change.
24552 return true;
24553
24557 {
24558 const interned_string& q1 = l.get_scoped_name();
24559 const interned_string& q2 = r.get_scoped_name();
24560 if (q1 == q2)
24561 // Not using RETURN(true) here, because that causes
24562 // performance issues. We don't need to do
24563 // l.priv_->unmark_as_being_compared({l,r}) here because
24564 // we haven't marked l or r as being compared yet, and
24565 // doing so has a peformance cost that shows up on
24566 // performance profiles for *big* libraries.
24567 return true;
24568 else
24569 {
24570 if (k)
24572 // Not using RETURN(true) here, because that causes
24573 // performance issues. We don't need to do
24574 // l.priv_->unmark_as_being_compared({l,r}) here because
24575 // we haven't marked l or r as being compared yet, and
24576 // doing so has a peformance cost that shows up on
24577 // performance profiles for *big* libraries.
24579 }
24580 }
24581 else // A decl-only class is considered different from a
24582 // class definition of the same name.
24583 {
24584 if (!!def1 != !!def2)
24585 {
24586 if (k)
24589 }
24590
24591 // both definitions are empty
24592 if (!(l.decl_base::operator==(r)
24593 && l.type_base::operator==(r)))
24594 {
24595 if (k)
24598 }
24599
24600 return true;
24601 }
24602 }
24603
24604 bool val = *def1 == *def2;
24605 if (!val)
24606 if (k)
24608 ABG_RETURN(val);
24609 }
24610
24611 // No need to go further if the classes have different names or
24612 // different size / alignment.
24613 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
24614 {
24615 if (k)
24618 }
24619
24620 if (types_defined_same_linux_kernel_corpus_public(l, r))
24621 return true;
24622
24623 //TODO: Maybe remove this (cycle detection and canonical type
24624 //propagation handling) from here and have it only in the equal
24625 //overload for class_decl and union_decl because this one ( the
24626 //equal overload for class_or_union) is just a sub-routine of these
24627 //two above.
24628#define RETURN(value) \
24629 return return_comparison_result(l, r, value);
24630
24632
24634
24635 bool result = true;
24636
24637 //compare data_members
24638 {
24639 if (l.get_non_static_data_members().size()
24640 != r.get_non_static_data_members().size())
24641 {
24642 result = false;
24643 if (k)
24645 else
24646 RETURN(result);
24647 }
24648
24649 for (class_or_union::data_members::const_iterator
24650 d0 = l.get_non_static_data_members().begin(),
24651 d1 = r.get_non_static_data_members().begin();
24652 (d0 != l.get_non_static_data_members().end()
24653 && d1 != r.get_non_static_data_members().end());
24654 ++d0, ++d1)
24655 if (**d0 != **d1)
24656 {
24657 result = false;
24658 if (k)
24659 {
24660 // Report any representation change as being local.
24661 if (!types_have_similar_structure((*d0)->get_type(),
24662 (*d1)->get_type())
24663 || (*d0)->get_type() == (*d1)->get_type())
24665 else
24666 *k |= SUBTYPE_CHANGE_KIND;
24667 }
24668 else
24669 RETURN(result);
24670 }
24671 }
24672
24673 // Do not compare member functions. DWARF does not necessarily
24674 // all the member functions, be they virtual or not, in all
24675 // translation units. So we cannot have a clear view of them, per
24676 // class
24677
24678 // compare member function templates
24679 {
24680 if (l.get_member_function_templates().size()
24681 != r.get_member_function_templates().size())
24682 {
24683 result = false;
24684 if (k)
24686 else
24687 RETURN(result);
24688 }
24689
24690 for (member_function_templates::const_iterator
24691 fn_tmpl_it0 = l.get_member_function_templates().begin(),
24692 fn_tmpl_it1 = r.get_member_function_templates().begin();
24693 fn_tmpl_it0 != l.get_member_function_templates().end()
24694 && fn_tmpl_it1 != r.get_member_function_templates().end();
24695 ++fn_tmpl_it0, ++fn_tmpl_it1)
24696 if (**fn_tmpl_it0 != **fn_tmpl_it1)
24697 {
24698 result = false;
24699 if (k)
24700 {
24702 break;
24703 }
24704 else
24705 RETURN(result);
24706 }
24707 }
24708
24709 // compare member class templates
24710 {
24711 if (l.get_member_class_templates().size()
24712 != r.get_member_class_templates().size())
24713 {
24714 result = false;
24715 if (k)
24717 else
24718 RETURN(result);
24719 }
24720
24721 for (member_class_templates::const_iterator
24722 cl_tmpl_it0 = l.get_member_class_templates().begin(),
24723 cl_tmpl_it1 = r.get_member_class_templates().begin();
24724 cl_tmpl_it0 != l.get_member_class_templates().end()
24725 && cl_tmpl_it1 != r.get_member_class_templates().end();
24726 ++cl_tmpl_it0, ++cl_tmpl_it1)
24727 if (**cl_tmpl_it0 != **cl_tmpl_it1)
24728 {
24729 result = false;
24730 if (k)
24731 {
24733 break;
24734 }
24735 else
24736 RETURN(result);
24737 }
24738 }
24739
24740 RETURN(result);
24741#undef RETURN
24742}
24743
24744
24745/// Copy a method of a @ref class_or_union into a new @ref
24746/// class_or_union.
24747///
24748/// @param t the @ref class_or_union into which the method is to be copied.
24749///
24750/// @param method the method to copy into @p t.
24751///
24752/// @return the resulting newly copied method.
24753method_decl_sptr
24754copy_member_function(const class_or_union_sptr& t,
24755 const method_decl_sptr& method)
24756{return copy_member_function(t, method.get());}
24757
24758
24759/// Copy a method of a @ref class_or_union into a new @ref
24760/// class_or_union.
24761///
24762/// @param t the @ref class_or_union into which the method is to be copied.
24763///
24764/// @param method the method to copy into @p t.
24765///
24766/// @return the resulting newly copied method.
24767method_decl_sptr
24768copy_member_function(const class_or_union_sptr& t, const method_decl* method)
24769{
24770 ABG_ASSERT(t);
24771 ABG_ASSERT(method);
24772
24773 method_type_sptr old_type = method->get_type();
24774 ABG_ASSERT(old_type);
24775 method_type_sptr new_type(new method_type(old_type->get_return_type(),
24776 t,
24777 old_type->get_parameters(),
24778 old_type->get_is_const(),
24779 old_type->get_size_in_bits(),
24780 old_type->get_alignment_in_bits()));
24781 t->get_translation_unit()->bind_function_type_life_time(new_type);
24782
24783 method_decl_sptr
24784 new_method(new method_decl(method->get_name(),
24785 new_type,
24786 method->is_declared_inline(),
24787 method->get_location(),
24788 method->get_linkage_name(),
24789 method->get_visibility(),
24790 method->get_binding()));
24791 new_method->set_symbol(method->get_symbol());
24792
24793 if (class_decl_sptr class_type = is_class_type(t))
24794 class_type->add_member_function(new_method,
24798 get_member_is_static(*method),
24802 else
24803 t->add_member_function(new_method,
24805 get_member_is_static(*method),
24809 return new_method;
24810}
24811
24812// </class_or_union definitions>
24813
24814// <class_decl definitions>
24815
24816static void
24817sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24818
24819/// The private data for the class_decl type.
24820struct class_decl::priv
24821{
24822 base_specs bases_;
24823 unordered_map<string, base_spec_sptr> bases_map_;
24824 member_functions virtual_mem_fns_;
24825 virtual_mem_fn_map_type virtual_mem_fns_map_;
24826 bool is_struct_;
24827
24828 priv()
24829 : is_struct_(false)
24830 {}
24831
24832 priv(bool is_struct, class_decl::base_specs& bases)
24833 : bases_(bases),
24834 is_struct_(is_struct)
24835 {
24836 }
24837
24838 priv(bool is_struct)
24839 : is_struct_(is_struct)
24840 {}
24841};// end struct class_decl::priv
24842
24843/// A Constructor for instances of \ref class_decl
24844///
24845/// @param env the environment we are operating from.
24846///
24847/// @param name the identifier of the class.
24848///
24849/// @param size_in_bits the size of an instance of class_decl, expressed
24850/// in bits
24851///
24852/// @param align_in_bits the alignment of an instance of class_decl,
24853/// expressed in bits.
24854///
24855/// @param locus the source location of declaration point this class.
24856///
24857/// @param vis the visibility of instances of class_decl.
24858///
24859/// @param bases the vector of base classes for this instance of class_decl.
24860///
24861/// @param mbrs the vector of member types of this instance of
24862/// class_decl.
24863///
24864/// @param data_mbrs the vector of data members of this instance of
24865/// class_decl.
24866///
24867/// @param mbr_fns the vector of member functions of this instance of
24868/// class_decl.
24869class_decl::class_decl(const environment& env, const string& name,
24870 size_t size_in_bits, size_t align_in_bits,
24871 bool is_struct, const location& locus,
24872 visibility vis, base_specs& bases,
24873 member_types& mbr_types,
24874 data_members& data_mbrs,
24875 member_functions& mbr_fns)
24876 : type_or_decl_base(env,
24877 CLASS_TYPE
24878 | ABSTRACT_TYPE_BASE
24879 | ABSTRACT_DECL_BASE
24880 | ABSTRACT_SCOPE_TYPE_DECL
24881 | ABSTRACT_SCOPE_DECL),
24882 decl_base(env, name, locus, name, vis),
24883 type_base(env, size_in_bits, align_in_bits),
24884 class_or_union(env, name, size_in_bits, align_in_bits,
24885 locus, vis, mbr_types, data_mbrs, mbr_fns),
24886 priv_(new priv(is_struct, bases))
24887{
24889}
24890
24891/// A Constructor for instances of @ref class_decl
24892///
24893/// @param env the environment we are operating from.
24894///
24895/// @param name the identifier of the class.
24896///
24897/// @param size_in_bits the size of an instance of class_decl, expressed
24898/// in bits
24899///
24900/// @param align_in_bits the alignment of an instance of class_decl,
24901/// expressed in bits.
24902///
24903/// @param locus the source location of declaration point this class.
24904///
24905/// @param vis the visibility of instances of class_decl.
24906///
24907/// @param bases the vector of base classes for this instance of class_decl.
24908///
24909/// @param mbrs the vector of member types of this instance of
24910/// class_decl.
24911///
24912/// @param data_mbrs the vector of data members of this instance of
24913/// class_decl.
24914///
24915/// @param mbr_fns the vector of member functions of this instance of
24916/// class_decl.
24917///
24918/// @param is_anonymous whether the newly created instance is
24919/// anonymous.
24920class_decl::class_decl(const environment& env, const string& name,
24921 size_t size_in_bits, size_t align_in_bits,
24922 bool is_struct, const location& locus,
24923 visibility vis, base_specs& bases,
24924 member_types& mbr_types, data_members& data_mbrs,
24925 member_functions& mbr_fns, bool is_anonymous)
24926 : type_or_decl_base(env,
24927 CLASS_TYPE
24928 | ABSTRACT_TYPE_BASE
24929 | ABSTRACT_DECL_BASE
24930 | ABSTRACT_SCOPE_TYPE_DECL
24931 | ABSTRACT_SCOPE_DECL),
24932 decl_base(env, name, locus,
24933 // If the class is anonymous then by default it won't
24934 // have a linkage name. Also, the anonymous class does
24935 // have an internal-only unique name that is generally
24936 // not taken into account when comparing classes; such a
24937 // unique internal-only name, when used as a linkage
24938 // name might introduce spurious comparison false
24939 // negatives.
24940 /*linkage_name=*/is_anonymous ? string() : name,
24941 vis),
24942 type_base(env, size_in_bits, align_in_bits),
24943 class_or_union(env, name, size_in_bits, align_in_bits,
24944 locus, vis, mbr_types, data_mbrs, mbr_fns),
24945 priv_(new priv(is_struct, bases))
24946{
24948 set_is_anonymous(is_anonymous);
24949}
24950
24951/// A constructor for instances of class_decl.
24952///
24953/// @param env the environment we are operating from.
24954///
24955/// @param name the name of the class.
24956///
24957/// @param size_in_bits the size of an instance of class_decl, expressed
24958/// in bits
24959///
24960/// @param align_in_bits the alignment of an instance of class_decl,
24961/// expressed in bits.
24962///
24963/// @param locus the source location of declaration point this class.
24964///
24965/// @param vis the visibility of instances of class_decl.
24966class_decl::class_decl(const environment& env, const string& name,
24967 size_t size_in_bits, size_t align_in_bits,
24968 bool is_struct, const location& locus,
24969 visibility vis)
24970 : type_or_decl_base(env,
24971 CLASS_TYPE
24972 | ABSTRACT_TYPE_BASE
24973 | ABSTRACT_DECL_BASE
24974 | ABSTRACT_SCOPE_TYPE_DECL
24975 | ABSTRACT_SCOPE_DECL),
24976 decl_base(env, name, locus, name, vis),
24977 type_base(env, size_in_bits, align_in_bits),
24978 class_or_union(env, name, size_in_bits, align_in_bits,
24979 locus, vis),
24980 priv_(new priv(is_struct))
24981{
24983}
24984
24985/// A constructor for instances of @ref class_decl.
24986///
24987/// @param env the environment we are operating from.
24988///
24989/// @param name the name of the class.
24990///
24991/// @param size_in_bits the size of an instance of class_decl, expressed
24992/// in bits
24993///
24994/// @param align_in_bits the alignment of an instance of class_decl,
24995/// expressed in bits.
24996///
24997/// @param locus the source location of declaration point this class.
24998///
24999/// @param vis the visibility of instances of 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, bool is_anonymous)
25007 : type_or_decl_base(env,
25008 CLASS_TYPE
25009 | ABSTRACT_TYPE_BASE
25010 | ABSTRACT_DECL_BASE
25011 | ABSTRACT_SCOPE_TYPE_DECL
25012 | ABSTRACT_SCOPE_DECL),
25013 decl_base(env, name, locus,
25014 // If the class is anonymous then by default it won't
25015 // have a linkage name. Also, the anonymous class does
25016 // have an internal-only unique name that is generally
25017 // not taken into account when comparing classes; such a
25018 // unique internal-only name, when used as a linkage
25019 // name might introduce spurious comparison false
25020 // negatives.
25021 /*linkage_name=*/ is_anonymous ? string() : name,
25022 vis),
25023 type_base(env, size_in_bits, align_in_bits),
25024 class_or_union(env, name, size_in_bits, align_in_bits,
25025 locus, vis),
25026 priv_(new priv(is_struct))
25027{
25029 set_is_anonymous(is_anonymous);
25030}
25031
25032/// A constuctor for instances of class_decl that represent a
25033/// declaration without definition.
25034///
25035/// @param env the environment we are operating from.
25036///
25037/// @param name the name of the class.
25038///
25039/// @param is_declaration_only a boolean saying whether the instance
25040/// represents a declaration only, or not.
25041class_decl::class_decl(const environment& env, const string& name,
25042 bool is_struct, bool is_declaration_only)
25043 : type_or_decl_base(env,
25044 CLASS_TYPE
25045 | ABSTRACT_TYPE_BASE
25046 | ABSTRACT_DECL_BASE
25047 | ABSTRACT_SCOPE_TYPE_DECL
25048 | ABSTRACT_SCOPE_DECL),
25049 decl_base(env, name, location(), name),
25050 type_base(env, 0, 0),
25051 class_or_union(env, name, is_declaration_only),
25052 priv_(new priv(is_struct))
25053{
25055}
25056
25057/// This method is invoked automatically right after the current
25058/// instance of @ref class_decl has been canonicalized.
25059///
25060/// Currently, the only thing it does is to sort the virtual member
25061/// functions vector.
25062void
25064{
25066
25067 for (class_decl::virtual_mem_fn_map_type::iterator i =
25068 priv_->virtual_mem_fns_map_.begin();
25069 i != priv_->virtual_mem_fns_map_.end();
25070 ++i)
25071 sort_virtual_member_functions(i->second);
25072}
25073
25074/// Set the "is-struct" flag of the class.
25075///
25076/// @param f the new value of the flag.
25077void
25079{priv_->is_struct_ = f;}
25080
25081/// Test if the class is a struct.
25082///
25083/// @return true iff the class is a struct.
25084bool
25086{return priv_->is_struct_;}
25087
25088/// Add a base specifier to this class.
25089///
25090/// @param b the new base specifier.
25091void
25093{
25094 priv_->bases_.push_back(b);
25095 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
25096}
25097
25098/// Get the base specifiers for this class.
25099///
25100/// @return a vector of the base specifiers.
25103{return priv_->bases_;}
25104
25105/// Find a base class of a given qualified name for the current class.
25106///
25107/// @param qualified_name the qualified name of the base class to look for.
25108///
25109/// @return a pointer to the @ref class_decl that represents the base
25110/// class of name @p qualified_name, if found.
25112class_decl::find_base_class(const string& qualified_name) const
25113{
25114 unordered_map<string, base_spec_sptr>::iterator i =
25115 priv_->bases_map_.find(qualified_name);
25116
25117 if (i != priv_->bases_map_.end())
25118 return i->second->get_base_class();
25119
25120 return class_decl_sptr();
25121}
25122
25123/// Get the virtual member functions of this class.
25124///
25125/// @param return a vector of the virtual member functions of this
25126/// class.
25129{return priv_->virtual_mem_fns_;}
25130
25131/// Get the map that associates a virtual table offset to the virtual
25132/// member functions with that virtual table offset.
25133///
25134/// Usually, there should be a 1:1 mapping between a given vtable
25135/// offset and virtual member functions of that vtable offset. But
25136/// because of some implementation details, there can be several C++
25137/// destructor functions that are *generated* by compilers, for a
25138/// given destructor that is defined in the source code. If the
25139/// destructor is virtual then those generated functions have some
25140/// DWARF attributes in common with the constructor that the user
25141/// actually defined in its source code. Among those attributes are
25142/// the vtable offset of the destructor.
25143///
25144/// @return the map that associates a virtual table offset to the
25145/// virtual member functions with that virtual table offset.
25148{return priv_->virtual_mem_fns_map_;}
25149
25150/// Sort the virtual member functions by their virtual index.
25151void
25153{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
25154
25155/// Getter of the pretty representation of the current instance of
25156/// @ref class_decl.
25157///
25158/// @param internal set to true if the call is intended to get a
25159/// representation of the decl (or type) for the purpose of canonical
25160/// type comparison. This is mainly used in the function
25161/// type_base::get_canonical_type_for().
25162///
25163/// In other words if the argument for this parameter is true then the
25164/// call is meant for internal use (for technical use inside the
25165/// library itself), false otherwise. If you don't know what this is
25166/// for, then set it to false.
25167///
25168/// @param qualified_name if true, names emitted in the pretty
25169/// representation are fully qualified.
25170///
25171/// @return the pretty representaion for a class_decl.
25172string
25174 bool qualified_name) const
25175{
25176 string cl = "class ";
25177 if (!internal && is_struct())
25178 cl = "struct ";
25179
25180 // When computing the pretty representation for internal purposes,
25181 // if an anonymous class is named by a typedef, then consider that
25182 // it has a name, which is the typedef name.
25183 if (get_is_anonymous())
25184 {
25185 if (internal && !get_name().empty())
25186 return cl + get_type_name(this, qualified_name, /*internal=*/true);
25188 /*one_line=*/true,
25189 internal);
25190
25191 }
25192
25193 string result = cl;
25194 if (qualified_name)
25195 result += get_qualified_name(internal);
25196 else
25197 result += get_name();
25198
25199 return result;
25200}
25201
25202decl_base_sptr
25203class_decl::insert_member_decl(decl_base_sptr d)
25204{
25205 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
25206 add_member_function(f, public_access,
25207 /*is_virtual=*/false,
25208 /*vtable_offset=*/0,
25209 /*is_static=*/false,
25210 /*is_ctor=*/false,
25211 /*is_dtor=*/false,
25212 /*is_const=*/false);
25213 else
25215
25216 return d;
25217}
25218
25219/// The private data structure of class_decl::base_spec.
25220struct class_decl::base_spec::priv
25221{
25222 class_decl_wptr base_class_;
25223 long offset_in_bits_;
25224 bool is_virtual_;
25225
25226 priv(const class_decl_sptr& cl,
25227 long offset_in_bits,
25228 bool is_virtual)
25229 : base_class_(cl),
25230 offset_in_bits_(offset_in_bits),
25231 is_virtual_(is_virtual)
25232 {}
25233};
25234
25235/// Constructor for base_spec instances.
25236///
25237/// @param base the base class to consider
25238///
25239/// @param a the access specifier of the base class.
25240///
25241/// @param offset_in_bits if positive or null, represents the offset
25242/// of the base in the layout of its containing type.. If negative,
25243/// means that the current base is not laid out in its containing type.
25244///
25245/// @param is_virtual if true, means that the current base class is
25246/// virtual in it's containing type.
25247class_decl::base_spec::base_spec(const class_decl_sptr& base,
25249 long offset_in_bits,
25250 bool is_virtual)
25251 : type_or_decl_base(base->get_environment(),
25252 ABSTRACT_DECL_BASE),
25253 decl_base(base->get_environment(), base->get_name(), base->get_location(),
25254 base->get_linkage_name(), base->get_visibility()),
25255 member_base(a),
25256 priv_(new priv(base, offset_in_bits, is_virtual))
25257{
25259 set_qualified_name(base->get_qualified_name());
25260}
25261
25262/// Return the hash value of the current IR node.
25263///
25264/// Note that upon the first invocation, this member functions
25265/// computes the hash value and returns it. Subsequent invocations
25266/// just return the hash value that was previously calculated.
25267///
25268/// @return the hash value of the current IR node.
25269hash_t
25271{
25273 return h;
25274}
25275
25276/// Get the base class referred to by the current base class
25277/// specifier.
25278///
25279/// @return the base class.
25282{return priv_->base_class_.lock();}
25283
25284/// Getter of the "is-virtual" proprerty of the base class specifier.
25285///
25286/// @return true iff this specifies a virtual base class.
25287bool
25289{return priv_->is_virtual_;}
25290
25291/// Getter of the offset of the base.
25292///
25293/// @return the offset of the base.
25294long
25296{return priv_->offset_in_bits_;}
25297
25298/// Traverses an instance of @ref class_decl::base_spec, visiting all
25299/// the sub-types and decls that it might contain.
25300///
25301/// @param v the visitor that is used to visit every IR sub-node of
25302/// the current node.
25303///
25304/// @return true if either
25305/// - all the children nodes of the current IR node were traversed
25306/// and the calling code should keep going with the traversing.
25307/// - or the current IR node is already being traversed.
25308/// Otherwise, returning false means that the calling code should not
25309/// keep traversing the tree.
25310bool
25312{
25313 if (visiting())
25314 return true;
25315
25316 if (v.visit_begin(this))
25317 {
25318 visiting(true);
25319 get_base_class()->traverse(v);
25320 visiting(false);
25321 }
25322
25323 return v.visit_end(this);
25324}
25325
25326/// Constructor for base_spec instances.
25327///
25328/// Note that this constructor is for clients that don't support RTTI
25329/// and that have a base class of type_base, but of dynamic type
25330/// class_decl.
25331///
25332/// @param base the base class to consider. Must be a pointer to an
25333/// instance of class_decl
25334///
25335/// @param a the access specifier of the base class.
25336///
25337/// @param offset_in_bits if positive or null, represents the offset
25338/// of the base in the layout of its containing type.. If negative,
25339/// means that the current base is not laid out in its containing type.
25340///
25341/// @param is_virtual if true, means that the current base class is
25342/// virtual in it's containing type.
25343class_decl::base_spec::base_spec(const type_base_sptr& base,
25345 long offset_in_bits,
25346 bool is_virtual)
25348 ABSTRACT_DECL_BASE),
25353 member_base(a),
25354 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
25355 offset_in_bits,
25356 is_virtual))
25357{
25359}
25360
25361class_decl::base_spec::~base_spec() = default;
25362
25363/// Compares two instances of @ref class_decl::base_spec.
25364///
25365/// If the two intances are different, set a bitfield to give some
25366/// insight about the kind of differences there are.
25367///
25368/// @param l the first artifact of the comparison.
25369///
25370/// @param r the second artifact of the comparison.
25371///
25372/// @param k a pointer to a bitfield that gives information about the
25373/// kind of changes there are between @p l and @p r. This one is set
25374/// iff @p k is non-null and the function returns false.
25375///
25376/// Please note that setting k to a non-null value does have a
25377/// negative performance impact because even if @p l and @p r are not
25378/// equal, the function keeps up the comparison in order to determine
25379/// the different kinds of ways in which they are different.
25380///
25381/// @return true if @p l equals @p r, false otherwise.
25382bool
25384 const class_decl::base_spec& r,
25385 change_kind* k)
25386{
25387 if (!l.member_base::operator==(r))
25388 {
25389 if (k)
25392 }
25393
25395}
25396
25397/// Comparison operator for @ref class_decl::base_spec.
25398///
25399/// @param other the instance of @ref class_decl::base_spec to compare
25400/// against.
25401///
25402/// @return true if the current instance of @ref class_decl::base_spec
25403/// equals @p other.
25404bool
25406{
25407 const class_decl::base_spec* o =
25408 dynamic_cast<const class_decl::base_spec*>(&other);
25409
25410 if (!o)
25411 return false;
25412
25413 return equals(*this, *o, 0);
25414}
25415
25416/// Comparison operator for @ref class_decl::base_spec.
25417///
25418/// @param other the instance of @ref class_decl::base_spec to compare
25419/// against.
25420///
25421/// @return true if the current instance of @ref class_decl::base_spec
25422/// equals @p other.
25423bool
25425{
25426 const class_decl::base_spec* o =
25427 dynamic_cast<const class_decl::base_spec*>(&other);
25428 if (!o)
25429 return false;
25430
25431 return operator==(static_cast<const decl_base&>(*o));
25432}
25433
25434mem_fn_context_rel::~mem_fn_context_rel()
25435{
25436}
25437
25438/// A constructor for instances of method_decl.
25439///
25440/// @param name the name of the method.
25441///
25442/// @param type the type of the method.
25443///
25444/// @param declared_inline whether the method was
25445/// declared inline or not.
25446///
25447/// @param locus the source location of the method.
25448///
25449/// @param linkage_name the mangled name of the method.
25450///
25451/// @param vis the visibility of the method.
25452///
25453/// @param bind the binding of the method.
25454method_decl::method_decl(const string& name,
25455 method_type_sptr type,
25456 bool declared_inline,
25457 const location& locus,
25458 const string& linkage_name,
25459 visibility vis,
25460 binding bind)
25462 METHOD_DECL
25463 | ABSTRACT_DECL_BASE
25464 |FUNCTION_DECL),
25465 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25466 function_decl(name, static_pointer_cast<function_type>(type),
25467 declared_inline, locus, linkage_name, vis, bind)
25468{
25470 set_context_rel(new mem_fn_context_rel(0));
25471 set_member_function_is_const(*this, type->get_is_const());
25472}
25473
25474/// A constructor for instances of method_decl.
25475///
25476/// @param name the name of the method.
25477///
25478/// @param type the type of the method. Must be an instance of
25479/// method_type.
25480///
25481/// @param declared_inline whether the method was
25482/// declared inline or not.
25483///
25484/// @param locus the source location of the method.
25485///
25486/// @param linkage_name the mangled name of the method.
25487///
25488/// @param vis the visibility of the method.
25489///
25490/// @param bind the binding of the method.
25491method_decl::method_decl(const string& name,
25492 function_type_sptr type,
25493 bool declared_inline,
25494 const location& locus,
25495 const string& linkage_name,
25496 visibility vis,
25497 binding bind)
25498 : type_or_decl_base(type->get_environment(),
25499 METHOD_DECL
25500 | ABSTRACT_DECL_BASE
25501 | FUNCTION_DECL),
25502 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25503 function_decl(name, static_pointer_cast<function_type>
25504 (dynamic_pointer_cast<method_type>(type)),
25505 declared_inline, locus, linkage_name, vis, bind)
25506{
25508 set_context_rel(new mem_fn_context_rel(0));
25509}
25510
25511/// A constructor for instances of method_decl.
25512///
25513/// @param name the name of the method.
25514///
25515/// @param type the type of the method. Must be an instance of
25516/// method_type.
25517///
25518/// @param declared_inline whether the method was
25519/// declared inline or not.
25520///
25521/// @param locus the source location of the method.
25522///
25523/// @param linkage_name the mangled name of the method.
25524///
25525/// @param vis the visibility of the method.
25526///
25527/// @param bind the binding of the method.
25528method_decl::method_decl(const string& name,
25529 type_base_sptr type,
25530 bool declared_inline,
25531 const location& locus,
25532 const string& linkage_name,
25533 visibility vis,
25534 binding bind)
25535 : type_or_decl_base(type->get_environment(),
25536 METHOD_DECL
25537 | ABSTRACT_DECL_BASE
25538 | FUNCTION_DECL),
25539 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25540 function_decl(name, static_pointer_cast<function_type>
25541 (dynamic_pointer_cast<method_type>(type)),
25542 declared_inline, locus, linkage_name, vis, bind)
25543{
25545 set_context_rel(new mem_fn_context_rel(0));
25546}
25547
25548/// Set the linkage name of the method.
25549///
25550/// @param l the new linkage name of the method.
25551void
25553{
25554 string old_lname = get_linkage_name();
25556 // Update the linkage_name -> member function map of the containing
25557 // class declaration.
25558 if (!l.empty())
25559 {
25561 class_or_union_sptr cl = t->get_class_type();
25562 method_decl_sptr m(this, sptr_utils::noop_deleter());
25563 cl->priv_->mem_fns_map_[l] = m;
25564 if (!old_lname.empty() && l != old_lname)
25565 {
25566 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
25567 {
25568 ABG_ASSERT(m.get() == this);
25569 cl->priv_->mem_fns_map_.erase(old_lname);
25570 }
25571 }
25572 }
25573}
25574
25575method_decl::~method_decl()
25576{}
25577
25578const method_type_sptr
25580{
25581 method_type_sptr result;
25583 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
25584 return result;
25585}
25586
25587/// Set the containing class of a method_decl.
25588///
25589/// @param scope the new containing class_decl.
25590void
25591method_decl::set_scope(scope_decl* scope)
25592{
25593 if (!get_context_rel())
25594 set_context_rel(new mem_fn_context_rel(scope));
25595 else
25596 get_context_rel()->set_scope(scope);
25597}
25598
25599/// Equality operator for @ref method_decl_sptr.
25600///
25601/// This is a deep equality operator, as it compares the @ref
25602/// method_decl that is pointed-to by the smart pointer.
25603///
25604/// @param l the left-hand side argument of the equality operator.
25605///
25606/// @param r the righ-hand side argument of the equality operator.
25607///
25608/// @return true iff @p l equals @p r.
25609bool
25610operator==(const method_decl_sptr& l, const method_decl_sptr& r)
25611{
25612 if (l.get() == r.get())
25613 return true;
25614 if (!!l != !!r)
25615 return false;
25616
25617 return *l == *r;
25618}
25619
25620/// Inequality operator for @ref method_decl_sptr.
25621///
25622/// This is a deep equality operator, as it compares the @ref
25623/// method_decl that is pointed-to by the smart pointer.
25624///
25625/// @param l the left-hand side argument of the equality operator.
25626///
25627/// @param r the righ-hand side argument of the equality operator.
25628///
25629/// @return true iff @p l differs from @p r.
25630bool
25631operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
25632{return !operator==(l, r);}
25633
25634/// Test if a function_decl is actually a method_decl.
25635///
25636///@param d the @ref function_decl to consider.
25637///
25638/// @return the method_decl sub-object of @p d if inherits
25639/// a method_decl type.
25642{
25643 return dynamic_cast<method_decl*>
25644 (const_cast<type_or_decl_base*>(d));
25645}
25646
25647/// Test if a function_decl is actually a method_decl.
25648///
25649///@param d the @ref function_decl to consider.
25650///
25651/// @return the method_decl sub-object of @p d if inherits
25652/// a method_decl type.
25655{return is_method_decl(&d);}
25656
25657/// Test if a function_decl is actually a method_decl.
25658///
25659///@param d the @ref function_decl to consider.
25660///
25661/// @return the method_decl sub-object of @p d if inherits
25662/// a method_decl type.
25663method_decl_sptr
25665{return dynamic_pointer_cast<method_decl>(d);}
25666
25667/// A "less than" functor to sort a vector of instances of
25668/// method_decl that are virtual.
25669struct virtual_member_function_less_than
25670{
25671 /// The less than operator. First, it sorts the methods by their
25672 /// vtable index. If they have the same vtable index, it sorts them
25673 /// by the name of their ELF symbol. If they don't have elf
25674 /// symbols, it sorts them by considering their pretty
25675 /// representation.
25676 ///
25677 /// Note that this method expects virtual methods.
25678 ///
25679 /// @param f the first method to consider.
25680 ///
25681 /// @param s the second method to consider.
25682 ///
25683 /// @return true if method @p is less than method @s.
25684 bool
25685 operator()(const method_decl& f,
25686 const method_decl& s)
25687 {
25690
25691 ssize_t f_offset = get_member_function_vtable_offset(f);
25692 ssize_t s_offset = get_member_function_vtable_offset(s);
25693 if (f_offset != s_offset) return f_offset < s_offset;
25694
25695 string fn, sn;
25696 // Try the linkage names (important for destructors).
25697 fn = f.get_linkage_name();
25698 sn = s.get_linkage_name();
25699 if (fn != sn) return fn < sn;
25700
25701 // If the functions have symbols, then compare their symbol-id
25702 // string.
25703 elf_symbol_sptr f_sym = f.get_symbol();
25704 elf_symbol_sptr s_sym = s.get_symbol();
25705 if ((!f_sym) != (!s_sym)) return !f_sym;
25706 if (f_sym && s_sym)
25707 {
25708 fn = f_sym->get_id_string();
25709 sn = s_sym->get_id_string();
25710 if (fn != sn) return fn < sn;
25711 }
25712
25713 // None of the functions have symbols or linkage names that
25714 // distinguish them, so compare their pretty representation.
25717 if (fn != sn) return fn < sn;
25718
25719 /// If it's just the file paths that are different then sort them
25720 /// too.
25721 string fn_filepath, sn_filepath;
25722 unsigned line = 0, column = 0;
25723 location fn_loc = f.get_location(), sn_loc = s.get_location();
25724 if (fn_loc)
25725 fn_loc.expand(fn_filepath, line, column);
25726 if (sn_loc)
25727 sn_loc.expand(sn_filepath, line, column);
25728 return fn_filepath < sn_filepath;
25729 }
25730
25731 /// The less than operator. First, it sorts the methods by their
25732 /// vtable index. If they have the same vtable index, it sorts them
25733 /// by the name of their ELF symbol. If they don't have elf
25734 /// symbols, it sorts them by considering their pretty
25735 /// representation.
25736 ///
25737 /// Note that this method expects to take virtual methods.
25738 ///
25739 /// @param f the first method to consider.
25740 ///
25741 /// @param s the second method to consider.
25742 bool
25743 operator()(const method_decl_sptr f,
25744 const method_decl_sptr s)
25745 {return operator()(*f, *s);}
25746}; // end struct virtual_member_function_less_than
25747
25748/// Sort a vector of instances of virtual member functions.
25749///
25750/// @param mem_fns the vector of member functions to sort.
25751static void
25752sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25753{
25754 virtual_member_function_less_than lt;
25755 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25756}
25757
25758/// Add a member function to the current instance of @ref class_or_union.
25759///
25760/// @param f a method_decl to add to the current class. This function
25761/// should not have been already added to a scope.
25762///
25763/// @param access the access specifier for the member function to add.
25764///
25765/// @param is_virtual if this is true then it means the function @p f
25766/// is a virtual function. That also means that the current instance
25767/// of @ref class_or_union is actually an instance of @ref class_decl.
25768///
25769/// @param vtable_offset the offset of the member function in the
25770/// virtual table. This parameter is taken into account only if @p
25771/// is_virtual is true.
25772///
25773/// @param is_static whether the member function is static.
25774///
25775/// @param is_ctor whether the member function is a constructor.
25776///
25777/// @param is_dtor whether the member function is a destructor.
25778///
25779/// @param is_const whether the member function is const.
25780void
25783 bool is_virtual,
25784 size_t vtable_offset,
25785 bool is_static, bool is_ctor,
25786 bool is_dtor, bool is_const)
25787{
25788 add_member_function(f, a, is_static, is_ctor,
25789 is_dtor, is_const);
25790
25791 if (class_decl* klass = is_class_type(this))
25792 {
25793 if (is_virtual)
25794 {
25795 set_member_function_virtuality(f, is_virtual, vtable_offset);
25796 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25797 }
25798 }
25799}
25800
25801/// When a virtual member function has seen its virtualness set by
25802/// set_member_function_is_virtual(), this function ensures that the
25803/// member function is added to the specific vectors and maps of
25804/// virtual member function of its class.
25805///
25806/// @param method the method to fixup.
25807void
25808fixup_virtual_member_function(method_decl_sptr method)
25809{
25810 if (!method || !get_member_function_is_virtual(method))
25811 return;
25812
25813 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25814
25815 class_decl::member_functions::const_iterator m;
25816 for (m = klass->priv_->virtual_mem_fns_.begin();
25817 m != klass->priv_->virtual_mem_fns_.end();
25818 ++m)
25819 if (m->get() == method.get()
25820 || (*m)->get_linkage_name() == method->get_linkage_name())
25821 break;
25822 if (m == klass->priv_->virtual_mem_fns_.end())
25823 klass->priv_->virtual_mem_fns_.push_back(method);
25824
25825 // Build or udpate the map that associates a vtable offset to the
25826 // number of virtual member functions that "point" to it.
25827 ssize_t voffset = get_member_function_vtable_offset(method);
25828 if (voffset == -1)
25829 return;
25830
25831 class_decl::virtual_mem_fn_map_type::iterator i =
25832 klass->priv_->virtual_mem_fns_map_.find(voffset);
25833 if (i == klass->priv_->virtual_mem_fns_map_.end())
25834 {
25835 class_decl::member_functions virtual_mem_fns_at_voffset;
25836 virtual_mem_fns_at_voffset.push_back(method);
25837 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25838 }
25839 else
25840 {
25841 for (m = i->second.begin() ; m != i->second.end(); ++m)
25842 if (m->get() == method.get()
25843 || (*m)->get_linkage_name() == method->get_linkage_name())
25844 break;
25845 if (m == i->second.end())
25846 i->second.push_back(method);
25847 }
25848}
25849
25850/// Return true iff the class has no entity in its scope.
25851bool
25853{return priv_->bases_.empty() && has_no_member();}
25854
25855/// Test if the current instance of @ref class_decl has virtual member
25856/// functions.
25857///
25858/// @return true iff the current instance of @ref class_decl has
25859/// virtual member functions.
25860bool
25862{return !get_virtual_mem_fns().empty();}
25863
25864/// Test if the current instance of @ref class_decl has at least one
25865/// virtual base.
25866///
25867/// @return true iff the current instance of @ref class_decl has a
25868/// virtual member function.
25869bool
25871{
25872 for (base_specs::const_iterator b = get_base_specifiers().begin();
25873 b != get_base_specifiers().end();
25874 ++b)
25875 if ((*b)->get_is_virtual()
25876 || (*b)->get_base_class()->has_virtual_bases())
25877 return true;
25878
25879 return false;
25880}
25881
25882/// Test if the current instance has a vtable.
25883///
25884/// This is only valid for a C++ program.
25885///
25886/// Basically this function checks if the class has either virtual
25887/// functions, or virtual bases.
25888bool
25890{
25892 || has_virtual_bases())
25893 return true;
25894 return false;
25895}
25896
25897/// Get the highest vtable offset of all the virtual methods of the
25898/// class.
25899///
25900/// @return the highest vtable offset of all the virtual methods of
25901/// the class.
25902ssize_t
25904{
25905 ssize_t offset = -1;
25906 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
25907 get_virtual_mem_fns_map().begin();
25908 e != get_virtual_mem_fns_map().end();
25909 ++e)
25910 if (e->first > offset)
25911 offset = e->first;
25912
25913 return offset;
25914}
25915
25916/// Return the hash value of the current IR node.
25917///
25918/// Note that upon the first invocation, this member functions
25919/// computes the hash value and returns it. Subsequent invocations
25920/// just return the hash value that was previously calculated.
25921///
25922/// @return the hash value of the current IR node.
25923hash_t
25925{
25927 return h;
25928}
25929
25930/// Test if two methods are equal without taking their symbol or
25931/// linkage name into account.
25932///
25933/// @param f the first method.
25934///
25935/// @param s the second method.
25936///
25937/// @return true iff @p f equals @p s without taking their linkage
25938/// name or symbol into account.
25939static bool
25940methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
25941 const method_decl_sptr& s)
25942{
25943 method_decl_sptr first = f, second = s;
25944 elf_symbol_sptr saved_first_elf_symbol =
25945 first->get_symbol();
25946 elf_symbol_sptr saved_second_elf_symbol =
25947 second->get_symbol();
25948 interned_string saved_first_linkage_name =
25949 first->get_linkage_name();
25950 interned_string saved_second_linkage_name =
25951 second->get_linkage_name();
25952
25953 first->set_symbol(elf_symbol_sptr());
25954 first->set_linkage_name("");
25955 second->set_symbol(elf_symbol_sptr());
25956 second->set_linkage_name("");
25957
25958 bool equal = *first == *second;
25959
25960 first->set_symbol(saved_first_elf_symbol);
25961 first->set_linkage_name(saved_first_linkage_name);
25962 second->set_symbol(saved_second_elf_symbol);
25963 second->set_linkage_name(saved_second_linkage_name);
25964
25965 return equal;
25966}
25967
25968/// Test if a given method is equivalent to at least of other method
25969/// that is in a vector of methods.
25970///
25971/// Note that "equivalent" here means being equal without taking the
25972/// linkage name or the symbol of the methods into account.
25973///
25974/// This is a sub-routine of the 'equals' function that compares @ref
25975/// class_decl.
25976///
25977/// @param method the method to compare.
25978///
25979/// @param fns the vector of functions to compare @p method against.
25980///
25981/// @return true iff @p is equivalent to at least one method in @p
25982/// fns.
25983static bool
25984method_matches_at_least_one_in_vector(const method_decl_sptr& method,
25986{
25987 for (class_decl::member_functions::const_iterator i = fns.begin();
25988 i != fns.end();
25989 ++i)
25990 // Note that the comparison must be done in this order: method ==
25991 // *i This is to keep the consistency of the comparison. It's
25992 // important especially when doing type canonicalization. The
25993 // already canonicalize type is the left operand, and the type
25994 // being canonicalized is the right operand. This comes from the
25995 // code in type_base::get_canonical_type_for().
25996 if (methods_equal_modulo_elf_symbol(method, *i))
25997 return true;
25998
25999 return false;
26000}
26001
26002/// Compares two instances of @ref class_decl.
26003///
26004/// If the two intances are different, set a bitfield to give some
26005/// insight about the kind of differences there are.
26006///
26007/// @param l the first artifact of the comparison.
26008///
26009/// @param r the second artifact of the comparison.
26010///
26011/// @param k a pointer to a bitfield that gives information about the
26012/// kind of changes there are between @p l and @p r. This one is set
26013/// iff @p k is non-null and the function returns false.
26014///
26015/// Please note that setting k to a non-null value does have a
26016/// negative performance impact because even if @p l and @p r are not
26017/// equal, the function keeps up the comparison in order to determine
26018/// the different kinds of ways in which they are different.
26019///
26020/// @return true if @p l equals @p r, false otherwise.
26021bool
26023{
26024 {
26025 // First of all, let's see if these two types haven't already been
26026 // compared. If so, and if the result of the comparison has been
26027 // cached, let's just re-use it, rather than comparing them all
26028 // over again.
26029 bool result = false;
26030 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26031 ABG_RETURN(result);
26032 }
26033
26034 // if one of the classes is declaration-only then we take a fast
26035 // path here.
26037 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
26038 static_cast<const class_or_union&>(r),
26039 k));
26040
26041 bool result = true;
26042 if (!equals(static_cast<const class_or_union&>(l),
26043 static_cast<const class_or_union&>(r),
26044 k))
26045 {
26046 result = false;
26047 if (!k)
26048 ABG_RETURN(result);
26049 }
26050
26052
26054
26055#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
26056
26057 // Compare bases.
26058 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
26059 {
26060 result = false;
26061 if (k)
26063 else
26064 RETURN(result);
26065 }
26066
26067 for (class_decl::base_specs::const_iterator
26068 b0 = l.get_base_specifiers().begin(),
26069 b1 = r.get_base_specifiers().begin();
26070 (b0 != l.get_base_specifiers().end()
26071 && b1 != r.get_base_specifiers().end());
26072 ++b0, ++b1)
26073 if (*b0 != *b1)
26074 {
26075 result = false;
26076 if (k)
26077 {
26078 if (!types_have_similar_structure((*b0)->get_base_class().get(),
26079 (*b1)->get_base_class().get()))
26081 else
26082 *k |= SUBTYPE_CHANGE_KIND;
26083 break;
26084 }
26085 RETURN(result);
26086 }
26087
26088 // Compare virtual member functions
26089
26090 // We look at the map that associates a given vtable offset to a
26091 // vector of virtual member functions that point to that offset.
26092 //
26093 // This is because there are cases where several functions can
26094 // point to the same virtual table offset.
26095 //
26096 // This is usually the case for virtual destructors. Even though
26097 // there can be only one virtual destructor declared in source
26098 // code, there are actually potentially up to three generated
26099 // functions for that destructor. Some of these generated
26100 // functions can be clones of other functions that are among those
26101 // generated ones. In any cases, they all have the same
26102 // properties, including the vtable offset property.
26103
26104 // So, there should be the same number of different vtable
26105 // offsets, the size of two maps must be equals.
26106 if (l.get_virtual_mem_fns_map().size()
26107 != r.get_virtual_mem_fns_map().size())
26108 {
26109 result = false;
26110 if (k)
26112 else
26113 RETURN(result);
26114 }
26115
26116 // Then, each virtual member function of a given vtable offset in
26117 // the first class type, must match an equivalent virtual member
26118 // function of a the same vtable offset in the second class type.
26119 //
26120 // By "match", I mean that the two virtual member function should
26121 // be equal if we don't take into account their symbol name or
26122 // their linkage name. This is because two destructor functions
26123 // clones (for instance) might have different linkage name, but
26124 // are still equivalent if their other properties are the same.
26125 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
26126 l.get_virtual_mem_fns_map().begin();
26127 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
26128 ++first_v_fn_entry)
26129 {
26130 unsigned voffset = first_v_fn_entry->first;
26131 const class_decl::member_functions& first_vfns =
26132 first_v_fn_entry->second;
26133
26134 const class_decl::virtual_mem_fn_map_type::const_iterator
26135 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
26136
26137 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
26138 {
26139 result = false;
26140 if (k)
26142 RETURN(result);
26143 }
26144
26145 const class_decl::member_functions& second_vfns =
26146 second_v_fn_entry->second;
26147
26148 bool matches = false;
26149 for (class_decl::member_functions::const_iterator i =
26150 first_vfns.begin();
26151 i != first_vfns.end();
26152 ++i)
26153 if (method_matches_at_least_one_in_vector(*i, second_vfns))
26154 {
26155 matches = true;
26156 break;
26157 }
26158
26159 if (!matches)
26160 {
26161 result = false;
26162 if (k)
26163 *k |= SUBTYPE_CHANGE_KIND;
26164 else
26165 RETURN(result);
26166 }
26167 }
26168
26169 RETURN(result);
26170#undef RETURN
26171}
26172
26173/// Copy a method of a class into a new class.
26174///
26175/// @param klass the class into which the method is to be copied.
26176///
26177/// @param method the method to copy into @p klass.
26178///
26179/// @return the resulting newly copied method.
26180method_decl_sptr
26181copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
26182{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26183
26184/// Copy a method of a class into a new class.
26185///
26186/// @param klass the class into which the method is to be copied.
26187///
26188/// @param method the method to copy into @p klass.
26189///
26190/// @return the resulting newly copied method.
26191method_decl_sptr
26193{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26194
26195/// Comparison operator for @ref class_decl.
26196///
26197/// @param other the instance of @ref class_decl to compare against.
26198///
26199/// @return true iff the current instance of @ref class_decl equals @p
26200/// other.
26201bool
26203{
26204 const class_decl* op = is_class_type(&other);
26205 if (!op)
26206 {
26207 if (class_or_union* cou = is_class_or_union_type(&other))
26208 return class_or_union::operator==(*cou);
26209 return false;
26210 }
26211
26212 // If this is a decl-only type (and thus with no canonical type),
26213 // use the canonical type of the definition, if any.
26214 const class_decl *l = 0;
26216 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
26217 if (l == 0)
26218 l = this;
26219
26220 ABG_ASSERT(l);
26221
26222 // Likewise for the other type.
26223 const class_decl *r = 0;
26224 if (op->get_is_declaration_only())
26225 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
26226 if (r == 0)
26227 r = op;
26228
26229 ABG_ASSERT(r);
26230
26231 return try_canonical_compare(l, r);
26232}
26233
26234/// Equality operator for class_decl.
26235///
26236/// Re-uses the equality operator that takes a decl_base.
26237///
26238/// @param other the other class_decl to compare against.
26239///
26240/// @return true iff the current instance equals the other one.
26241bool
26243{
26244 const decl_base* o = is_decl(&other);
26245 if (!o)
26246 return false;
26247 return *this == *o;
26248}
26249
26250/// Equality operator for class_decl.
26251///
26252/// Re-uses the equality operator that takes a decl_base.
26253///
26254/// @param other the other class_decl to compare against.
26255///
26256/// @return true iff the current instance equals the other one.
26257bool
26259{
26260 const decl_base& o = other;
26261 return *this == o;
26262}
26263
26264/// Comparison operator for @ref class_decl.
26265///
26266/// @param other the instance of @ref class_decl to compare against.
26267///
26268/// @return true iff the current instance of @ref class_decl equals @p
26269/// other.
26270bool
26272{
26273 const decl_base& o = other;
26274 return *this == o;
26275}
26276
26277/// Turn equality of shared_ptr of class_decl into a deep equality;
26278/// that is, make it compare the pointed to objects too.
26279///
26280/// @param l the shared_ptr of class_decl on left-hand-side of the
26281/// equality.
26282///
26283/// @param r the shared_ptr of class_decl on right-hand-side of the
26284/// equality.
26285///
26286/// @return true if the class_decl pointed to by the shared_ptrs are
26287/// equal, false otherwise.
26288bool
26290{
26291 if (l.get() == r.get())
26292 return true;
26293 if (!!l != !!r)
26294 return false;
26295
26296 return *l == *r;
26297}
26298
26299/// Turn inequality of shared_ptr of class_decl into a deep equality;
26300/// that is, make it compare the pointed to objects too.
26301///
26302/// @param l the shared_ptr of class_decl on left-hand-side of the
26303/// equality.
26304///
26305/// @param r the shared_ptr of class_decl on right-hand-side of the
26306/// equality.
26307///
26308/// @return true if the class_decl pointed to by the shared_ptrs are
26309/// different, false otherwise.
26310bool
26312{return !operator==(l, r);}
26313
26314/// Turn equality of shared_ptr of class_or_union into a deep
26315/// equality; that is, make it compare the pointed to objects too.
26316///
26317/// @param l the left-hand-side operand of the operator
26318///
26319/// @param r the right-hand-side operand of the operator.
26320///
26321/// @return true iff @p l equals @p r.
26322bool
26323operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
26324{
26325 if (l.get() == r.get())
26326 return true;
26327 if (!!l != !!r)
26328 return false;
26329
26330 return *l == *r;
26331}
26332
26333/// Turn inequality of shared_ptr of class_or_union into a deep
26334/// equality; that is, make it compare the pointed to objects too.
26335///
26336/// @param l the left-hand-side operand of the operator
26337///
26338/// @param r the right-hand-side operand of the operator.
26339///
26340/// @return true iff @p l is different from @p r.
26341bool
26342operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
26343{return !operator==(l, r);}
26344
26345/// This implements the ir_traversable_base::traverse pure virtual
26346/// function.
26347///
26348/// @param v the visitor used on the current instance and on its
26349/// members.
26350///
26351/// @return true if the entire IR node tree got traversed, false
26352/// otherwise.
26353bool
26355{
26356 if (v.type_node_has_been_visited(this))
26357 return true;
26358
26359 if (visiting())
26360 return true;
26361
26362 if (v.visit_begin(this))
26363 {
26364 visiting(true);
26365 bool stop = false;
26366
26367 for (base_specs::const_iterator i = get_base_specifiers().begin();
26368 i != get_base_specifiers().end();
26369 ++i)
26370 {
26371 if (!(*i)->traverse(v))
26372 {
26373 stop = true;
26374 break;
26375 }
26376 }
26377
26378 if (!stop)
26379 for (data_members::const_iterator i = get_data_members().begin();
26380 i != get_data_members().end();
26381 ++i)
26382 if (!(*i)->traverse(v))
26383 {
26384 stop = true;
26385 break;
26386 }
26387
26388 if (!stop)
26389 for (member_functions::const_iterator i= get_member_functions().begin();
26390 i != get_member_functions().end();
26391 ++i)
26392 if (!(*i)->traverse(v))
26393 {
26394 stop = true;
26395 break;
26396 }
26397
26398 if (!stop)
26399 for (member_types::const_iterator i = get_member_types().begin();
26400 i != get_member_types().end();
26401 ++i)
26402 if (!(*i)->traverse(v))
26403 {
26404 stop = true;
26405 break;
26406 }
26407
26408 if (!stop)
26409 for (member_function_templates::const_iterator i =
26411 i != get_member_function_templates().end();
26412 ++i)
26413 if (!(*i)->traverse(v))
26414 {
26415 stop = true;
26416 break;
26417 }
26418
26419 if (!stop)
26420 for (member_class_templates::const_iterator i =
26422 i != get_member_class_templates().end();
26423 ++i)
26424 if (!(*i)->traverse(v))
26425 {
26426 stop = true;
26427 break;
26428 }
26429 visiting(false);
26430 }
26431
26432 bool result = v.visit_end(this);
26434 return result;
26435}
26436
26437/// Destructor of the @ref class_decl type.
26439{delete priv_;}
26440
26441context_rel::~context_rel()
26442{}
26443
26444bool
26445member_base::operator==(const member_base& o) const
26446{
26448 && get_is_static() == o.get_is_static());
26449}
26450
26451/// Equality operator for smart pointers to @ref
26452/// class_decl::base_specs.
26453///
26454/// This compares the pointed-to objects.
26455///
26456/// @param l the first instance to consider.
26457///
26458/// @param r the second instance to consider.
26459///
26460/// @return true iff @p l equals @p r.
26461bool
26464{
26465 if (l.get() == r.get())
26466 return true;
26467 if (!!l != !!r)
26468 return false;
26469
26470 return *l == static_cast<const decl_base&>(*r);
26471}
26472
26473/// Inequality operator for smart pointers to @ref
26474/// class_decl::base_specs.
26475///
26476/// This compares the pointed-to objects.
26477///
26478/// @param l the first instance to consider.
26479///
26480/// @param r the second instance to consider.
26481///
26482/// @return true iff @p l is different from @p r.
26483bool
26486{return !operator==(l, r);}
26487
26488/// Test if an ABI artifact is a class base specifier.
26489///
26490/// @param tod the ABI artifact to consider.
26491///
26492/// @return a pointer to the @ref class_decl::base_spec sub-object of
26493/// @p tod iff it's a class base specifier.
26496{
26497 return dynamic_cast<class_decl::base_spec*>
26498 (const_cast<type_or_decl_base*>(tod));
26499}
26500
26501/// Test if an ABI artifact is a class base specifier.
26502///
26503/// @param tod the ABI artifact to consider.
26504///
26505/// @return a pointer to the @ref class_decl::base_spec sub-object of
26506/// @p tod iff it's a class base specifier.
26509{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
26510
26511bool
26512member_function_template::operator==(const member_base& other) const
26513{
26514 try
26515 {
26516 const member_function_template& o =
26517 dynamic_cast<const member_function_template&>(other);
26518
26519 if (!(is_constructor() == o.is_constructor()
26520 && is_const() == o.is_const()
26521 && member_base::operator==(o)))
26522 return false;
26523
26524 if (function_tdecl_sptr ftdecl = as_function_tdecl())
26525 {
26526 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
26527 if (other_ftdecl)
26528 return ftdecl->function_tdecl::operator==(*other_ftdecl);
26529 }
26530 }
26531 catch(...)
26532 {}
26533 return false;
26534}
26535
26536/// Equality operator for smart pointers to @ref
26537/// member_function_template. This is compares the
26538/// pointed-to instances.
26539///
26540/// @param l the first instance to consider.
26541///
26542/// @param r the second instance to consider.
26543///
26544/// @return true iff @p l equals @p r.
26545bool
26546operator==(const member_function_template_sptr& l,
26547 const member_function_template_sptr& r)
26548{
26549 if (l.get() == r.get())
26550 return true;
26551 if (!!l != !!r)
26552 return false;
26553
26554 return *l == *r;
26555}
26556
26557/// Inequality operator for smart pointers to @ref
26558/// member_function_template. This is compares the pointed-to
26559/// instances.
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 equals @p r.
26566bool
26567operator!=(const member_function_template_sptr& l,
26568 const member_function_template_sptr& r)
26569{return !operator==(l, r);}
26570
26571/// This implements the ir_traversable_base::traverse pure virtual
26572/// function.
26573///
26574/// @param v the visitor used on the current instance and on its
26575/// underlying function template.
26576///
26577/// @return true if the entire IR node tree got traversed, false
26578/// otherwise.
26579bool
26581{
26582 if (visiting())
26583 return true;
26584
26585 if (v.visit_begin(this))
26586 {
26587 visiting(true);
26588 if (function_tdecl_sptr f = as_function_tdecl())
26589 f->traverse(v);
26590 visiting(false);
26591 }
26592 return v.visit_end(this);
26593}
26594
26595/// Equality operator of the the @ref member_class_template class.
26596///
26597/// @param other the other @ref member_class_template to compare against.
26598///
26599/// @return true iff the current instance equals @p other.
26600bool
26602{
26603 try
26604 {
26605 const member_class_template& o =
26606 dynamic_cast<const member_class_template&>(other);
26607
26608 if (!member_base::operator==(o))
26609 return false;
26610
26611 return as_class_tdecl()->class_tdecl::operator==(o);
26612 }
26613 catch(...)
26614 {return false;}
26615}
26616
26617/// Equality operator of the the @ref member_class_template class.
26618///
26619/// @param other the other @ref member_class_template to compare against.
26620///
26621/// @return true iff the current instance equals @p other.
26622bool
26624{
26625 if (!decl_base::operator==(other))
26626 return false;
26627 return as_class_tdecl()->class_tdecl::operator==(other);
26628}
26629
26630/// Comparison operator for the @ref member_class_template
26631/// type.
26632///
26633/// @param other the other instance of @ref
26634/// member_class_template to compare against.
26635///
26636/// @return true iff the two instances are equal.
26637bool
26639{
26640 const decl_base* o = dynamic_cast<const decl_base*>(&other);
26641 return *this == *o;
26642}
26643
26644/// Comparison operator for the @ref member_class_template
26645/// type.
26646///
26647/// @param l the first argument of the operator.
26648///
26649/// @param r the second argument of the operator.
26650///
26651/// @return true iff the two instances are equal.
26652bool
26653operator==(const member_class_template_sptr& l,
26654 const member_class_template_sptr& r)
26655{
26656 if (l.get() == r.get())
26657 return true;
26658 if (!!l != !!r)
26659 return false;
26660
26661 return *l == *r;
26662}
26663
26664/// Inequality operator for the @ref member_class_template
26665/// type.
26666///
26667/// @param l the first argument of the operator.
26668///
26669/// @param r the second argument of the operator.
26670///
26671/// @return true iff the two instances are equal.
26672bool
26673operator!=(const member_class_template_sptr& l,
26674 const member_class_template_sptr& r)
26675{return !operator==(l, r);}
26676
26677/// This implements the ir_traversable_base::traverse pure virtual
26678/// function.
26679///
26680/// @param v the visitor used on the current instance and on the class
26681/// pattern of the template.
26682///
26683/// @return true if the entire IR node tree got traversed, false
26684/// otherwise.
26685bool
26687{
26688 if (visiting())
26689 return true;
26690
26691 if (v.visit_begin(this))
26692 {
26693 visiting(true);
26694 if (class_tdecl_sptr t = as_class_tdecl())
26695 t->traverse(v);
26696 visiting(false);
26697 }
26698 return v.visit_end(this);
26699}
26700
26701/// Streaming operator for class_decl::access_specifier.
26702///
26703/// @param o the output stream to serialize the access specifier to.
26704///
26705/// @param a the access specifier to serialize.
26706///
26707/// @return the output stream.
26708std::ostream&
26709operator<<(std::ostream& o, access_specifier a)
26710{
26711 string r;
26712
26713 switch (a)
26714 {
26715 case no_access:
26716 r = "none";
26717 break;
26718 case private_access:
26719 r = "private";
26720 break;
26721 case protected_access:
26722 r = "protected";
26723 break;
26724 case public_access:
26725 r= "public";
26726 break;
26727 };
26728 o << r;
26729 return o;
26730}
26731
26732/// Sets the static-ness property of a class member.
26733///
26734/// @param d the class member to set the static-ness property for.
26735/// Note that this must be a class member otherwise the function
26736/// aborts the current process.
26737///
26738/// @param s this must be true if the member is to be static, false
26739/// otherwise.
26740void
26742{
26744
26746 ABG_ASSERT(c);
26747
26748 c->set_is_static(s);
26749
26750 scope_decl* scope = d.get_scope();
26751
26752 if (class_or_union* cl = is_class_or_union_type(scope))
26753 {
26754 if (var_decl* v = is_var_decl(&d))
26755 {
26756 // First, find v in the set of data members.
26757 var_decl_sptr var;
26758 for (const auto& dm : cl->get_data_members())
26759 if (dm->get_name() == v->get_name())
26760 {
26761 var = dm;
26762 break;
26763 }
26764 if (!var)
26765 return;
26766
26767 if (s)
26768 {
26769 // remove from the non-static data members
26770 for (class_decl::data_members::iterator i =
26771 cl->priv_->non_static_data_members_.begin();
26772 i != cl->priv_->non_static_data_members_.end();
26773 ++i)
26774 {
26775 if ((*i)->get_name() == v->get_name())
26776 {
26777 cl->priv_->non_static_data_members_.erase(i);
26778 break;
26779 }
26780 }
26781
26782 // If it's not in the static data members, then add it
26783 // there.
26784 bool already_in_static_dms = false;
26785 for (const auto& s_dm : cl->priv_->static_data_members_)
26786 if (s_dm->get_name() == v->get_name())
26787 {
26788 already_in_static_dms = true;
26789 break;
26790 }
26791 if (!already_in_static_dms)
26792 cl->priv_->static_data_members_.push_back(var);
26793 }
26794 else // is non-static
26795 {
26796 // Remove from the static data members.
26797 for (class_or_union::data_members::iterator i =
26798 cl->priv_->static_data_members_.begin();
26799 i != cl->priv_->static_data_members_.end();
26800 ++i)
26801 if ((*i)->get_name() == v->get_name())
26802 {
26803 cl->priv_->static_data_members_.erase(i);
26804 break;
26805 }
26806
26807 // If it's not already in the non-static data members
26808 // then add it there.
26809 bool is_already_in_non_static_data_members = false;
26810 for (const auto& ns_dm : cl->priv_->non_static_data_members_)
26811 if (ns_dm->get_name() == v->get_name())
26812 {
26813 is_already_in_non_static_data_members = true;
26814 break;
26815 }
26816 if (!is_already_in_non_static_data_members)
26817 cl->priv_->non_static_data_members_.push_back(var);
26818 }
26819 }
26820 }
26821}
26822
26823/// Sets the static-ness property of a class member.
26824///
26825/// @param d the class member to set the static-ness property for.
26826/// Note that this must be a class member otherwise the function
26827/// aborts the current process.
26828///
26829/// @param s this must be true if the member is to be static, false
26830/// otherwise.
26831void
26832set_member_is_static(const decl_base_sptr& d, bool s)
26833{set_member_is_static(*d, s);}
26834
26835// </class_decl>
26836
26837// <union_decl>
26838
26839/// Constructor for the @ref union_decl type.
26840///
26841/// @param env the @ref environment we are operating from.
26842///
26843/// @param name the name of the union type.
26844///
26845/// @param size_in_bits the size of the union, in bits.
26846///
26847/// @param locus the location of the type.
26848///
26849/// @param vis the visibility of instances of @ref union_decl.
26850///
26851/// @param mbr_types the member types of the union.
26852///
26853/// @param data_mbrs the data members of the union.
26854///
26855/// @param member_fns the member functions of the union.
26856union_decl::union_decl(const environment& env, const string& name,
26857 size_t size_in_bits, const location& locus,
26858 visibility vis, member_types& mbr_types,
26859 data_members& data_mbrs, member_functions& member_fns)
26860 : type_or_decl_base(env,
26861 UNION_TYPE
26862 | ABSTRACT_TYPE_BASE
26863 | ABSTRACT_DECL_BASE),
26864 decl_base(env, name, locus, name, vis),
26865 type_base(env, size_in_bits, 0),
26866 class_or_union(env, name, size_in_bits, 0,
26867 locus, vis, mbr_types, data_mbrs, member_fns)
26868{
26870}
26871
26872/// Constructor for the @ref union_decl type.
26873///
26874/// @param env the @ref environment we are operating from.
26875///
26876/// @param name the name of the union type.
26877///
26878/// @param size_in_bits the size of the union, in bits.
26879///
26880/// @param locus the location of the type.
26881///
26882/// @param vis the visibility of instances of @ref union_decl.
26883///
26884/// @param mbr_types the member types of the union.
26885///
26886/// @param data_mbrs the data members of the union.
26887///
26888/// @param member_fns the member functions of the union.
26889///
26890/// @param is_anonymous whether the newly created instance is
26891/// anonymous.
26892union_decl::union_decl(const environment& env, const string& name,
26893 size_t size_in_bits, const location& locus,
26894 visibility vis, member_types& mbr_types,
26895 data_members& data_mbrs, member_functions& member_fns,
26896 bool is_anonymous)
26897 : type_or_decl_base(env,
26898 UNION_TYPE
26899 | ABSTRACT_TYPE_BASE
26900 | ABSTRACT_DECL_BASE),
26901 decl_base(env, name, locus,
26902 // If the class is anonymous then by default it won't
26903 // have a linkage name. Also, the anonymous class does
26904 // have an internal-only unique name that is generally
26905 // not taken into account when comparing classes; such a
26906 // unique internal-only name, when used as a linkage
26907 // name might introduce spurious comparison false
26908 // negatives.
26909 /*linkage_name=*/is_anonymous ? string() : name,
26910 vis),
26911 type_base(env, size_in_bits, 0),
26912 class_or_union(env, name, size_in_bits, 0,
26913 locus, vis, mbr_types, data_mbrs, member_fns)
26914{
26916 set_is_anonymous(is_anonymous);
26917}
26918
26919/// Constructor for the @ref union_decl type.
26920///
26921/// @param env the @ref environment we are operating from.
26922///
26923/// @param name the name of the union type.
26924///
26925/// @param size_in_bits the size of the union, in bits.
26926///
26927/// @param locus the location of the type.
26928///
26929/// @param vis the visibility of instances of @ref union_decl.
26930union_decl::union_decl(const environment& env, const string& name,
26931 size_t size_in_bits, const location& locus,
26932 visibility vis)
26933 : type_or_decl_base(env,
26934 UNION_TYPE
26935 | ABSTRACT_TYPE_BASE
26936 | ABSTRACT_DECL_BASE
26937 | ABSTRACT_SCOPE_TYPE_DECL
26938 | ABSTRACT_SCOPE_DECL),
26939 decl_base(env, name, locus, name, vis),
26940 type_base(env, size_in_bits, 0),
26941 class_or_union(env, name, size_in_bits,
26942 0, locus, vis)
26943{
26945}
26946
26947/// Constructor for the @ref union_decl type.
26948///
26949/// @param env the @ref environment we are operating from.
26950///
26951/// @param name the name of the union type.
26952///
26953/// @param size_in_bits the size of the union, in bits.
26954///
26955/// @param locus the location of the type.
26956///
26957/// @param vis the visibility of instances of @ref union_decl.
26958///
26959/// @param is_anonymous whether the newly created instance is
26960/// anonymous.
26961union_decl::union_decl(const environment& env, const string& name,
26962 size_t size_in_bits, const location& locus,
26963 visibility vis, bool is_anonymous)
26964 : type_or_decl_base(env,
26965 UNION_TYPE
26966 | ABSTRACT_TYPE_BASE
26967 | ABSTRACT_DECL_BASE
26968 | ABSTRACT_SCOPE_TYPE_DECL
26969 | ABSTRACT_SCOPE_DECL),
26970 decl_base(env, name, locus,
26971 // If the class is anonymous then by default it won't
26972 // have a linkage name. Also, the anonymous class does
26973 // have an internal-only unique name that is generally
26974 // not taken into account when comparing classes; such a
26975 // unique internal-only name, when used as a linkage
26976 // name might introduce spurious comparison false
26977 // negatives.
26978 /*linkage_name=*/is_anonymous ? string() : name,
26979 vis),
26980 type_base(env, size_in_bits, 0),
26981 class_or_union(env, name, size_in_bits,
26982 0, locus, vis)
26983{
26985 set_is_anonymous(is_anonymous);
26986}
26987
26988/// Constructor for the @ref union_decl type.
26989///
26990/// @param env the @ref environment we are operating from.
26991///
26992/// @param name the name of the union type.
26993///
26994/// @param is_declaration_only a boolean saying whether the instance
26995/// represents a declaration only, or not.
26996union_decl::union_decl(const environment& env,
26997 const string& name,
26998 bool is_declaration_only)
26999 : type_or_decl_base(env,
27000 UNION_TYPE
27001 | ABSTRACT_TYPE_BASE
27002 | ABSTRACT_DECL_BASE
27003 | ABSTRACT_SCOPE_TYPE_DECL
27004 | ABSTRACT_SCOPE_DECL),
27005 decl_base(env, name, location(), name),
27006 type_base(env, 0, 0),
27007 class_or_union(env, name, is_declaration_only)
27008{
27010}
27011
27012/// Return the hash value of the current IR node.
27013///
27014/// Note that upon the first invocation, this member functions
27015/// computes the hash value and returns it. Subsequent invocations
27016/// just return the hash value that was previously calculated.
27017///
27018/// @return the hash value of the current IR node.
27019hash_t
27021{
27023 return h;
27024}
27025
27026/// Getter of the pretty representation of the current instance of
27027/// @ref union_decl.
27028///
27029/// @param internal set to true if the call is intended to get a
27030/// representation of the decl (or type) for the purpose of canonical
27031/// type comparison. This is mainly used in the function
27032/// type_base::get_canonical_type_for().
27033///
27034/// In other words if the argument for this parameter is true then the
27035/// call is meant for internal use (for technical use inside the
27036/// library itself), false otherwise. If you don't know what this is
27037/// for, then set it to false.
27038///
27039/// @param qualified_name if true, names emitted in the pretty
27040/// representation are fully qualified.
27041///
27042/// @return the pretty representaion for a union_decl.
27043string
27045 bool qualified_name) const
27046{
27047 string repr;
27048 if (get_is_anonymous())
27049 {
27050 if (internal && !get_name().empty())
27051 repr = string("union ") +
27052 get_type_name(this, qualified_name, /*internal=*/true);
27053 else
27055 /*one_line=*/true,
27056 internal);
27057 }
27058 else
27059 {
27060 repr = "union ";
27061 if (qualified_name)
27062 repr += get_qualified_name(internal);
27063 else
27064 repr += get_name();
27065 }
27066
27067 return repr;
27068}
27069
27070/// Comparison operator for @ref union_decl.
27071///
27072/// @param other the instance of @ref union_decl to compare against.
27073///
27074/// @return true iff the current instance of @ref union_decl equals @p
27075/// other.
27076bool
27078{
27079 const union_decl* op = dynamic_cast<const union_decl*>(&other);
27080 if (!op)
27081 return false;
27082 return try_canonical_compare(this, op);
27083}
27084
27085/// Equality operator for union_decl.
27086///
27087/// Re-uses the equality operator that takes a decl_base.
27088///
27089/// @param other the other union_decl to compare against.
27090///
27091/// @return true iff the current instance equals the other one.
27092bool
27094{
27095 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27096 if (!o)
27097 return false;
27098 return *this == *o;
27099}
27100
27101/// Equality operator for union_decl.
27102///
27103/// Re-uses the equality operator that takes a decl_base.
27104///
27105/// @param other the other union_decl to compare against.
27106///
27107/// @return true iff the current instance equals the other one.
27108bool
27110{
27111 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27112 return *this == *o;
27113}
27114
27115/// Comparison operator for @ref union_decl.
27116///
27117/// @param other the instance of @ref union_decl to compare against.
27118///
27119/// @return true iff the current instance of @ref union_decl equals @p
27120/// other.
27121bool
27123{
27124 const decl_base& o = other;
27125 return *this == o;
27126}
27127
27128/// This implements the ir_traversable_base::traverse pure virtual
27129/// function.
27130///
27131/// @param v the visitor used on the current instance and on its
27132/// members.
27133///
27134/// @return true if the entire IR node tree got traversed, false
27135/// otherwise.
27136bool
27138{
27139 if (v.type_node_has_been_visited(this))
27140 return true;
27141
27142 if (visiting())
27143 return true;
27144
27145 if (v.visit_begin(this))
27146 {
27147 visiting(true);
27148 bool stop = false;
27149
27150 if (!stop)
27151 for (data_members::const_iterator i = get_data_members().begin();
27152 i != get_data_members().end();
27153 ++i)
27154 if (!(*i)->traverse(v))
27155 {
27156 stop = true;
27157 break;
27158 }
27159
27160 if (!stop)
27161 for (member_functions::const_iterator i= get_member_functions().begin();
27162 i != get_member_functions().end();
27163 ++i)
27164 if (!(*i)->traverse(v))
27165 {
27166 stop = true;
27167 break;
27168 }
27169
27170 if (!stop)
27171 for (member_types::const_iterator i = get_member_types().begin();
27172 i != get_member_types().end();
27173 ++i)
27174 if (!(*i)->traverse(v))
27175 {
27176 stop = true;
27177 break;
27178 }
27179
27180 if (!stop)
27181 for (member_function_templates::const_iterator i =
27183 i != get_member_function_templates().end();
27184 ++i)
27185 if (!(*i)->traverse(v))
27186 {
27187 stop = true;
27188 break;
27189 }
27190
27191 if (!stop)
27192 for (member_class_templates::const_iterator i =
27194 i != get_member_class_templates().end();
27195 ++i)
27196 if (!(*i)->traverse(v))
27197 {
27198 stop = true;
27199 break;
27200 }
27201 visiting(false);
27202 }
27203
27204 bool result = v.visit_end(this);
27206 return result;
27207}
27208
27209/// Destructor of the @ref union_decl type.
27211{}
27212
27213/// Compares two instances of @ref union_decl.
27214///
27215/// If the two intances are different, set a bitfield to give some
27216/// insight about the kind of differences there are.
27217///
27218/// @param l the first artifact of the comparison.
27219///
27220/// @param r the second artifact of the comparison.
27221///
27222/// @param k a pointer to a bitfield that gives information about the
27223/// kind of changes there are between @p l and @p r. This one is set
27224/// iff @p k is non-null and the function returns false.
27225///
27226/// Please note that setting k to a non-null value does have a
27227/// negative performance impact because even if @p l and @p r are not
27228/// equal, the function keeps up the comparison in order to determine
27229/// the different kinds of ways in which they are different.
27230///
27231/// @return true if @p l equals @p r, false otherwise.
27232bool
27234{
27235
27237
27238 {
27239 // First of all, let's see if these two types haven't already been
27240 // compared. If so, and if the result of the comparison has been
27241 // cached, let's just re-use it, rather than comparing them all
27242 // over again.
27243 bool result = false;
27244 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
27245 ABG_RETURN(result);
27246 }
27247
27248 bool result = equals(static_cast<const class_or_union&>(l),
27249 static_cast<const class_or_union&>(r),
27250 k);
27251
27253}
27254
27255/// Copy a method of a @ref union_decl into a new @ref
27256/// union_decl.
27257///
27258/// @param t the @ref union_decl into which the method is to be copied.
27259///
27260/// @param method the method to copy into @p t.
27261///
27262/// @return the resulting newly copied method.
27263method_decl_sptr
27264copy_member_function(const union_decl_sptr& union_type,
27265 const method_decl_sptr& f)
27266{return copy_member_function(union_type, f.get());}
27267
27268/// Copy a method of a @ref union_decl into a new @ref
27269/// union_decl.
27270///
27271/// @param t the @ref union_decl into which the method is to be copied.
27272///
27273/// @param method the method to copy into @p t.
27274///
27275/// @return the resulting newly copied method.
27276method_decl_sptr
27277copy_member_function(const union_decl_sptr& union_type,
27278 const method_decl* f)
27279{
27280 const class_or_union_sptr t = union_type;
27281 return copy_member_function(t, f);
27282}
27283
27284/// Turn equality of shared_ptr of union_decl into a deep equality;
27285/// that is, make it compare the pointed to objects too.
27286///
27287/// @param l the left-hand-side operand of the operator
27288///
27289/// @param r the right-hand-side operand of the operator.
27290///
27291/// @return true iff @p l equals @p r.
27292bool
27293operator==(const union_decl_sptr& l, const union_decl_sptr& r)
27294{
27295 if (l.get() == r.get())
27296 return true;
27297 if (!!l != !!r)
27298 return false;
27299
27300 return *l == *r;
27301}
27302
27303/// Turn inequality of shared_ptr of union_decl into a deep equality;
27304/// that is, make it compare the pointed to objects too.
27305///
27306/// @param l the left-hand-side operand of the operator
27307///
27308/// @param r the right-hand-side operand of the operator.
27309///
27310/// @return true iff @p l is different from @p r.
27311bool
27312operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
27313{return !operator==(l, r);}
27314// </union_decl>
27315
27316// <template_decl stuff>
27317
27318/// Data type of the private data of the @template_decl type.
27319class template_decl::priv
27320{
27321 friend class template_decl;
27322
27323 std::list<template_parameter_sptr> parms_;
27324public:
27325
27326 priv()
27327 {}
27328}; // end class template_decl::priv
27329
27330/// Add a new template parameter to the current instance of @ref
27331/// template_decl.
27332///
27333/// @param p the new template parameter to add.
27334void
27336{priv_->parms_.push_back(p);}
27337
27338/// Get the list of template parameters of the current instance of
27339/// @ref template_decl.
27340///
27341/// @return the list of template parameters.
27342const std::list<template_parameter_sptr>&
27344{return priv_->parms_;}
27345
27346/// Constructor.
27347///
27348/// @param env the environment we are operating from.
27349///
27350/// @param name the name of the template decl.
27351///
27352/// @param locus the source location where the template declaration is
27353/// defined.
27354///
27355/// @param vis the visibility of the template declaration.
27356template_decl::template_decl(const environment& env,
27357 const string& name,
27358 const location& locus,
27359 visibility vis)
27360 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
27361 decl_base(env, name, locus, /*mangled_name=*/"", vis),
27362 priv_(new priv)
27363{
27365}
27366
27367/// Destructor.
27369{}
27370
27371/// Equality operator.
27372///
27373/// @param o the other instance to compare against.
27374///
27375/// @return true iff @p equals the current instance.
27376bool
27378{
27379 const template_decl* other = dynamic_cast<const template_decl*>(&o);
27380 if (!other)
27381 return false;
27382 return *this == *other;
27383}
27384
27385/// Equality operator.
27386///
27387/// @param o the other instance to compare against.
27388///
27389/// @return true iff @p equals the current instance.
27390bool
27392{
27393 try
27394 {
27395 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
27396 for (t0 = get_template_parameters().begin(),
27397 t1 = o.get_template_parameters().begin();
27398 (t0 != get_template_parameters().end()
27399 && t1 != o.get_template_parameters().end());
27400 ++t0, ++t1)
27401 {
27402 if (**t0 != **t1)
27403 return false;
27404 }
27405
27406 if (t0 != get_template_parameters().end()
27407 || t1 != o.get_template_parameters().end())
27408 return false;
27409
27410 return true;
27411 }
27412 catch(...)
27413 {return false;}
27414}
27415
27416// </template_decl stuff>
27417
27418//<template_parameter>
27419
27420/// The type of the private data of the @ref template_parameter type.
27421class template_parameter::priv
27422{
27423 friend class template_parameter;
27424
27425 unsigned index_;
27426 template_decl_wptr template_decl_;
27427 mutable bool hashing_started_;
27428 mutable bool comparison_started_;
27429
27430 priv();
27431
27432public:
27433
27434 priv(unsigned index, template_decl_sptr enclosing_template_decl)
27435 : index_(index),
27436 template_decl_(enclosing_template_decl),
27437 hashing_started_(),
27438 comparison_started_()
27439 {}
27440}; // end class template_parameter::priv
27441
27442template_parameter::template_parameter(unsigned index,
27443 template_decl_sptr enclosing_template)
27444 : priv_(new priv(index, enclosing_template))
27445 {}
27446
27447unsigned
27448template_parameter::get_index() const
27449{return priv_->index_;}
27450
27452template_parameter::get_enclosing_template_decl() const
27453{return priv_->template_decl_.lock();}
27454
27455
27456bool
27457template_parameter::operator==(const template_parameter& o) const
27458{
27459 if (get_index() != o.get_index())
27460 return false;
27461
27462 if (priv_->comparison_started_)
27463 return true;
27464
27465 bool result = false;
27466
27467 // Avoid inifite loops due to the fact that comparison the enclosing
27468 // template decl might lead to comparing this very same template
27469 // parameter with another one ...
27470 priv_->comparison_started_ = true;
27471
27472 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
27473 ;
27474 else if (get_enclosing_template_decl()
27475 && (*get_enclosing_template_decl()
27476 != *o.get_enclosing_template_decl()))
27477 ;
27478 else
27479 result = true;
27480
27481 priv_->comparison_started_ = false;
27482
27483 return result;
27484}
27485
27486/// Inequality operator.
27487///
27488/// @param other the other instance to compare against.
27489///
27490/// @return true iff the other instance is different from the current
27491/// one.
27492bool
27494{return !operator==(other);}
27495
27496/// Destructor.
27498{}
27499
27500/// The type of the private data of the @ref type_tparameter type.
27501class type_tparameter::priv
27502{
27503 friend class type_tparameter;
27504}; // end class type_tparameter::priv
27505
27506/// Constructor of the @ref type_tparameter type.
27507///
27508/// @param index the index the type template parameter.
27509///
27510/// @param enclosing_tdecl the enclosing template declaration.
27511///
27512/// @param name the name of the template parameter.
27513///
27514/// @param locus the location of the declaration of this type template
27515/// parameter.
27516type_tparameter::type_tparameter(unsigned index,
27517 template_decl_sptr enclosing_tdecl,
27518 const string& name,
27519 const location& locus)
27520 : type_or_decl_base(enclosing_tdecl->get_environment(),
27521 ABSTRACT_DECL_BASE
27522 | ABSTRACT_TYPE_BASE
27523 | BASIC_TYPE),
27524 decl_base(enclosing_tdecl->get_environment(), name, locus),
27525 type_base(enclosing_tdecl->get_environment(), 0, 0),
27526 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
27527 template_parameter(index, enclosing_tdecl),
27528 priv_(new priv)
27529{
27531}
27532
27533/// Equality operator.
27534///
27535/// @param other the other template type parameter to compare against.
27536///
27537/// @return true iff @p other equals the current instance.
27538bool
27540{
27541 if (!type_decl::operator==(other))
27542 return false;
27543
27544 try
27545 {
27546 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27548 }
27549 catch (...)
27550 {return false;}
27551}
27552
27553/// Equality operator.
27554///
27555/// @param other the other template type parameter to compare against.
27556///
27557/// @return true iff @p other equals the current instance.
27558bool
27560{
27561 if (!type_decl::operator==(other))
27562 return false;
27563
27564 try
27565 {
27566 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27568 }
27569 catch (...)
27570 {return false;}
27571}
27572
27573/// Equality operator.
27574///
27575/// @param other the other template type parameter to compare against.
27576///
27577/// @return true iff @p other equals the current instance.
27578bool
27580{
27581 if (!decl_base::operator==(other))
27582 return false;
27583
27584 try
27585 {
27586 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27588 }
27589 catch (...)
27590 {return false;}
27591}
27592
27593/// Equality operator.
27594///
27595/// @param other the other template type parameter to compare against.
27596///
27597/// @return true iff @p other equals the current instance.
27598bool
27600{
27601 try
27602 {
27603 const type_base& o = dynamic_cast<const type_base&>(other);
27604 return *this == o;
27605 }
27606 catch(...)
27607 {return false;}
27608}
27609
27610/// Equality operator.
27611///
27612/// @param other the other template type parameter to compare against.
27613///
27614/// @return true iff @p other equals the current instance.
27615bool
27617{return *this == static_cast<const type_base&>(other);}
27618
27619type_tparameter::~type_tparameter()
27620{}
27621
27622/// The type of the private data of the @ref non_type_tparameter type.
27623class non_type_tparameter::priv
27624{
27625 friend class non_type_tparameter;
27626
27627 type_base_wptr type_;
27628
27629 priv();
27630
27631public:
27632
27633 priv(type_base_sptr type)
27634 : type_(type)
27635 {}
27636}; // end class non_type_tparameter::priv
27637
27638/// The constructor for the @ref non_type_tparameter type.
27639///
27640/// @param index the index of the template parameter.
27641///
27642/// @param enclosing_tdecl the enclosing template declaration that
27643/// holds this parameter parameter.
27644///
27645/// @param name the name of the template parameter.
27646///
27647/// @param type the type of the template parameter.
27648///
27649/// @param locus the location of the declaration of this template
27650/// parameter.
27651non_type_tparameter::non_type_tparameter(unsigned index,
27652 template_decl_sptr enclosing_tdecl,
27653 const string& name,
27654 type_base_sptr type,
27655 const location& locus)
27656 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
27657 decl_base(type->get_environment(), name, locus, ""),
27658 template_parameter(index, enclosing_tdecl),
27659 priv_(new priv(type))
27660{
27662}
27663
27664/// Getter for the type of the template parameter.
27665///
27666/// @return the type of the template parameter.
27667const type_base_sptr
27669{return priv_->type_.lock();}
27670
27671
27672bool
27674{
27675 if (!decl_base::operator==(other))
27676 return false;
27677
27678 try
27679 {
27680 const non_type_tparameter& o =
27681 dynamic_cast<const non_type_tparameter&>(other);
27682 return (template_parameter::operator==(o)
27683 && get_type() == o.get_type());
27684 }
27685 catch(...)
27686 {return false;}
27687}
27688
27689bool
27691{
27692 try
27693 {
27694 const decl_base& o = dynamic_cast<const decl_base&>(other);
27695 return *this == o;
27696 }
27697 catch(...)
27698 {return false;}
27699}
27700
27701non_type_tparameter::~non_type_tparameter()
27702{}
27703
27704// <template_tparameter stuff>
27705
27706/// Type of the private data of the @ref template_tparameter type.
27707class template_tparameter::priv
27708{
27709}; //end class template_tparameter::priv
27710
27711/// Constructor for the @ref template_tparameter.
27712///
27713/// @param index the index of the template parameter.
27714///
27715/// @param enclosing_tdecl the enclosing template declaration.
27716///
27717/// @param name the name of the template parameter.
27718///
27719/// @param locus the location of the declaration of the template
27720/// parameter.
27721template_tparameter::template_tparameter(unsigned index,
27722 template_decl_sptr enclosing_tdecl,
27723 const string& name,
27724 const location& locus)
27725 : type_or_decl_base(enclosing_tdecl->get_environment(),
27726 ABSTRACT_DECL_BASE
27727 | ABSTRACT_TYPE_BASE
27728 | BASIC_TYPE),
27729 decl_base(enclosing_tdecl->get_environment(), name, locus),
27730 type_base(enclosing_tdecl->get_environment(), 0, 0),
27731 type_decl(enclosing_tdecl->get_environment(), name,
27732 0, 0, locus, name, VISIBILITY_DEFAULT),
27733 type_tparameter(index, enclosing_tdecl, name, locus),
27734 template_decl(enclosing_tdecl->get_environment(), name, locus),
27735 priv_(new priv)
27736{
27738}
27739
27740/// Equality operator.
27741///
27742/// @param other the other template parameter to compare against.
27743///
27744/// @return true iff @p other equals the current instance.
27745bool
27747{
27748 try
27749 {
27750 const template_tparameter& o =
27751 dynamic_cast<const template_tparameter&>(other);
27752 return (type_tparameter::operator==(o)
27754 }
27755 catch(...)
27756 {return false;}
27757}
27758
27759/// Equality operator.
27760///
27761/// @param other the other template parameter to compare against.
27762///
27763/// @return true iff @p other equals the current instance.
27764bool
27766{
27767 try
27768 {
27769 const template_tparameter& o =
27770 dynamic_cast<const template_tparameter&>(other);
27771 return (type_tparameter::operator==(o)
27773 }
27774 catch(...)
27775 {return false;}
27776}
27777
27778bool
27780{
27781 try
27782 {
27783 const template_tparameter& other =
27784 dynamic_cast<const template_tparameter&>(o);
27785 return *this == static_cast<const type_base&>(other);
27786 }
27787 catch(...)
27788 {return false;}
27789}
27790
27791bool
27793{
27794 try
27795 {
27796 const template_tparameter& other =
27797 dynamic_cast<const template_tparameter&>(o);
27798 return type_base::operator==(other);
27799 }
27800 catch(...)
27801 {return false;}
27802}
27803
27804template_tparameter::~template_tparameter()
27805{}
27806
27807// </template_tparameter stuff>
27808
27809// <type_composition stuff>
27810
27811/// The type of the private data of the @ref type_composition type.
27812class type_composition::priv
27813{
27814 friend class type_composition;
27815
27816 type_base_wptr type_;
27817
27818 // Forbid this.
27819 priv();
27820
27821public:
27822
27823 priv(type_base_wptr type)
27824 : type_(type)
27825 {}
27826}; //end class type_composition::priv
27827
27828/// Constructor for the @ref type_composition type.
27829///
27830/// @param index the index of the template type composition.
27831///
27832/// @param tdecl the enclosing template parameter that owns the
27833/// composition.
27834///
27835/// @param t the resulting type.
27836type_composition::type_composition(unsigned index,
27837 template_decl_sptr tdecl,
27838 type_base_sptr t)
27839 : type_or_decl_base(tdecl->get_environment(),
27840 ABSTRACT_DECL_BASE),
27841 decl_base(tdecl->get_environment(), "", location()),
27842 template_parameter(index, tdecl),
27843 priv_(new priv(t))
27844{
27846}
27847
27848/// Getter for the resulting composed type.
27849///
27850/// @return the composed type.
27851const type_base_sptr
27853{return priv_->type_.lock();}
27854
27855/// Setter for the resulting composed type.
27856///
27857/// @param t the composed type.
27858void
27860{priv_->type_ = t;}
27861
27862type_composition::~type_composition()
27863{}
27864
27865// </type_composition stuff>
27866
27867//</template_parameter stuff>
27868
27869// <function_template>
27870
27871class function_tdecl::priv
27872{
27873 friend class function_tdecl;
27874
27875 function_decl_sptr pattern_;
27876 binding binding_;
27877
27878 priv();
27879
27880public:
27881
27882 priv(function_decl_sptr pattern, binding bind)
27883 : pattern_(pattern), binding_(bind)
27884 {}
27885
27886 priv(binding bind)
27887 : binding_(bind)
27888 {}
27889}; // end class function_tdecl::priv
27890
27891/// Constructor for a function template declaration.
27892///
27893/// @param env the environment we are operating from.
27894///
27895/// @param locus the location of the declaration.
27896///
27897/// @param vis the visibility of the declaration. This is the
27898/// visibility the functions instantiated from this template are going
27899/// to have.
27900///
27901/// @param bind the binding of the declaration. This is the binding
27902/// the functions instantiated from this template are going to have.
27903function_tdecl::function_tdecl(const environment& env,
27904 const location& locus,
27905 visibility vis,
27906 binding bind)
27907 : type_or_decl_base(env,
27908 ABSTRACT_DECL_BASE
27909 | TEMPLATE_DECL
27910 | ABSTRACT_SCOPE_DECL),
27911 decl_base(env, "", locus, "", vis),
27912 template_decl(env, "", locus, vis),
27913 scope_decl(env, "", locus),
27914 priv_(new priv(bind))
27915{
27917}
27918
27919/// Constructor for a function template declaration.
27920///
27921/// @param pattern the pattern of the template.
27922///
27923/// @param locus the location of the declaration.
27924///
27925/// @param vis the visibility of the declaration. This is the
27926/// visibility the functions instantiated from this template are going
27927/// to have.
27928///
27929/// @param bind the binding of the declaration. This is the binding
27930/// the functions instantiated from this template are going to have.
27931function_tdecl::function_tdecl(function_decl_sptr pattern,
27932 const location& locus,
27933 visibility vis,
27934 binding bind)
27935 : type_or_decl_base(pattern->get_environment(),
27936 ABSTRACT_DECL_BASE
27937 | TEMPLATE_DECL
27938 | ABSTRACT_SCOPE_DECL),
27939 decl_base(pattern->get_environment(), pattern->get_name(), locus,
27940 pattern->get_name(), vis),
27941 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27942 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27943 priv_(new priv(pattern, bind))
27944{
27946}
27947
27948/// Set a new pattern to the function template.
27949///
27950/// @param p the new pattern.
27951void
27953{
27954 priv_->pattern_ = p;
27955 add_decl_to_scope(p, this);
27956 set_name(p->get_name());
27957}
27958
27959/// Get the pattern of the function template.
27960///
27961/// @return the pattern.
27964{return priv_->pattern_;}
27965
27966/// Get the binding of the function template.
27967///
27968/// @return the binding
27971{return priv_->binding_;}
27972
27973/// Comparison operator for the @ref function_tdecl type.
27974///
27975/// @param other the other instance of @ref function_tdecl to compare against.
27976///
27977/// @return true iff the two instance are equal.
27978bool
27980{
27981 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27982 if (o)
27983 return *this == *o;
27984 return false;
27985}
27986
27987/// Comparison operator for the @ref function_tdecl type.
27988///
27989/// @param other the other instance of @ref function_tdecl to compare against.
27990///
27991/// @return true iff the two instance are equal.
27992bool
27994{
27995 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27996 if (o)
27997 return *this == *o;
27998 return false;
27999}
28000
28001/// Comparison operator for the @ref function_tdecl type.
28002///
28003/// @param o the other instance of @ref function_tdecl to compare against.
28004///
28005/// @return true iff the two instance are equal.
28006bool
28008{
28009 if (!(get_binding() == o.get_binding()
28010 && template_decl::operator==(o)
28011 && scope_decl::operator==(o)
28012 && !!get_pattern() == !!o.get_pattern()))
28013 return false;
28014
28015 if (get_pattern())
28016 return (*get_pattern() == *o.get_pattern());
28017
28018 return true;
28019}
28020
28021/// This implements the ir_traversable_base::traverse pure virtual
28022/// function.
28023///
28024/// @param v the visitor used on the current instance and on the
28025/// function pattern of the template.
28026///
28027/// @return true if the entire IR node tree got traversed, false
28028/// otherwise.
28029bool
28031{
28032 if (visiting())
28033 return true;
28034
28035 if (!v.visit_begin(this))
28036 {
28037 visiting(true);
28038 if (get_pattern())
28039 get_pattern()->traverse(v);
28040 visiting(false);
28041 }
28042 return v.visit_end(this);
28043}
28044
28045function_tdecl::~function_tdecl()
28046{}
28047
28048// </function_template>
28049
28050// <class template>
28051
28052/// Type of the private data of the the @ref class_tdecl type.
28053class class_tdecl::priv
28054{
28055 friend class class_tdecl;
28056 class_decl_sptr pattern_;
28057
28058public:
28059
28060 priv()
28061 {}
28062
28063 priv(class_decl_sptr pattern)
28064 : pattern_(pattern)
28065 {}
28066}; // end class class_tdecl::priv
28067
28068/// Constructor for the @ref class_tdecl type.
28069///
28070/// @param env the environment we are operating from.
28071///
28072/// @param locus the location of the declaration of the class_tdecl
28073/// type.
28074///
28075/// @param vis the visibility of the instance of class instantiated
28076/// from this template.
28077class_tdecl::class_tdecl(const environment& env,
28078 const location& locus,
28079 visibility vis)
28080 : type_or_decl_base(env,
28081 ABSTRACT_DECL_BASE
28082 | TEMPLATE_DECL
28083 | ABSTRACT_SCOPE_DECL),
28084 decl_base(env, "", locus, "", vis),
28085 template_decl(env, "", locus, vis),
28086 scope_decl(env, "", locus),
28087 priv_(new priv)
28088{
28090}
28091
28092/// Constructor for the @ref class_tdecl type.
28093///
28094/// @param pattern The details of the class template. This must NOT be a
28095/// null pointer. If you really this to be null, please use the
28096/// constructor above instead.
28097///
28098/// @param locus the source location of the declaration of the type.
28099///
28100/// @param vis the visibility of the instances of class instantiated
28101/// from this template.
28102class_tdecl::class_tdecl(class_decl_sptr pattern,
28103 const location& locus,
28104 visibility vis)
28105 : type_or_decl_base(pattern->get_environment(),
28106 ABSTRACT_DECL_BASE
28107 | TEMPLATE_DECL
28108 | ABSTRACT_SCOPE_DECL),
28109 decl_base(pattern->get_environment(), pattern->get_name(),
28110 locus, pattern->get_name(), vis),
28111 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28112 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28113 priv_(new priv(pattern))
28114{
28116}
28117
28118/// Setter of the pattern of the template.
28119///
28120/// @param p the new template.
28121void
28123{
28124 priv_->pattern_ = p;
28125 add_decl_to_scope(p, this);
28126 set_name(p->get_name());
28127}
28128
28129/// Getter of the pattern of the template.
28130///
28131/// @return p the new template.
28134{return priv_->pattern_;}
28135
28136bool
28138{
28139 try
28140 {
28141 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28142
28143 if (!(template_decl::operator==(o)
28144 && scope_decl::operator==(o)
28145 && !!get_pattern() == !!o.get_pattern()))
28146 return false;
28147
28148 if (!get_pattern() || !o.get_pattern())
28149 return true;
28150
28151 return get_pattern()->decl_base::operator==(*o.get_pattern());
28152 }
28153 catch(...) {}
28154 return false;
28155}
28156
28157bool
28159{
28160 try
28161 {
28162 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28163 return *this == static_cast<const decl_base&>(o);
28164 }
28165 catch(...)
28166 {return false;}
28167}
28168
28169bool
28171{return *this == static_cast<const decl_base&>(o);}
28172
28173/// This implements the ir_traversable_base::traverse pure virtual
28174/// function.
28175///
28176/// @param v the visitor used on the current instance and on the class
28177/// pattern of the template.
28178///
28179/// @return true if the entire IR node tree got traversed, false
28180/// otherwise.
28181bool
28183{
28184 if (visiting())
28185 return true;
28186
28187 if (v.visit_begin(this))
28188 {
28189 visiting(true);
28190 if (class_decl_sptr pattern = get_pattern())
28191 pattern->traverse(v);
28192 visiting(false);
28193 }
28194 return v.visit_end(this);
28195}
28196
28197class_tdecl::~class_tdecl()
28198{}
28199
28200/// This visitor checks if a given type as non-canonicalized sub
28201/// types.
28202class non_canonicalized_subtype_detector : public ir::ir_node_visitor
28203{
28204 type_base* type_;
28205 type_base* has_non_canonical_type_;
28206
28207private:
28208 non_canonicalized_subtype_detector();
28209
28210public:
28211 non_canonicalized_subtype_detector(type_base* type)
28212 : type_(type),
28213 has_non_canonical_type_()
28214 {}
28215
28216 /// Return true if the visitor detected that there is a
28217 /// non-canonicalized sub-type.
28218 ///
28219 /// @return true if the visitor detected that there is a
28220 /// non-canonicalized sub-type.
28221 type_base*
28222 has_non_canonical_type() const
28223 {return has_non_canonical_type_;}
28224
28225 /// The intent of this visitor handler is to avoid looking into
28226 /// sub-types of member functions of the type we are traversing.
28227 bool
28228 visit_begin(function_decl* f)
28229 {
28230 // Do not look at sub-types of non-virtual member functions.
28231 if (is_member_function(f)
28233 return false;
28234 return true;
28235 }
28236
28237 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
28238 /// the 'has_non_canonical_type' flag. And in any case, when
28239 /// visiting a sub-type, do not visit its children nodes. So this
28240 /// function only goes to the level below the level of the top-most
28241 /// type.
28242 ///
28243 /// @return true if we are at the same level as the top-most type,
28244 /// otherwise return false.
28245 bool
28246 visit_begin(type_base* t)
28247 {
28248 if (t != type_)
28249 {
28250 if (!t->get_canonical_type())
28251 // We are looking a sub-type of 'type_' which has no
28252 // canonical type. So tada! we found one! Get out right
28253 // now with the trophy.
28254 has_non_canonical_type_ = t;
28255
28256 return false;
28257 }
28258 return true;
28259 }
28260
28261 /// When we are done visiting a sub-type, if it's been flagged as
28262 /// been non-canonicalized, then stop the traversing.
28263 ///
28264 /// Otherwise, keep going.
28265 ///
28266 /// @return false iff the sub-type that has been visited is
28267 /// non-canonicalized.
28268 bool
28269 visit_end(type_base* )
28270 {
28271 if (has_non_canonical_type_)
28272 return false;
28273 return true;
28274 }
28275}; //end class non_canonicalized_subtype_detector
28276
28277/// Test if a type has sub-types that are non-canonicalized.
28278///
28279/// @param t the type which sub-types to consider.
28280///
28281/// @return true if a type has sub-types that are non-canonicalized.
28282type_base*
28284{
28285 if (!t)
28286 return 0;
28287
28288 non_canonicalized_subtype_detector v(t.get());
28289 t->traverse(v);
28290 return v.has_non_canonical_type();
28291}
28292
28293/// Tests if the change of a given type effectively comes from just
28294/// its sub-types. That is, if the type has changed but its type name
28295/// hasn't changed, then the change of the type mostly likely is a
28296/// sub-type change.
28297///
28298/// @param t_v1 the first version of the type.
28299///
28300/// @param t_v2 the second version of the type.
28301///
28302/// @return true iff the type changed and the change is about its
28303/// sub-types.
28304bool
28305type_has_sub_type_changes(const type_base_sptr t_v1,
28306 const type_base_sptr t_v2)
28307{
28308 type_base_sptr t1 = strip_typedef(t_v1);
28309 type_base_sptr t2 = strip_typedef(t_v2);
28310
28311 string repr1 = get_pretty_representation(t1, /*internal=*/false),
28312 repr2 = get_pretty_representation(t2, /*internal=*/false);
28313 return (t1 != t2 && repr1 == repr2);
28314}
28315
28316/// Make sure that the life time of a given (smart pointer to a) type
28317/// is the same as the life time of the libabigail library.
28318///
28319/// @param t the type to consider.
28320void
28321keep_type_alive(type_base_sptr t)
28322{
28323 const environment& env = t->get_environment();
28324 env.priv_->extra_live_types_.push_back(t);
28325}
28326
28327/// Hash an ABI artifact that is either a type or a decl.
28328///
28329/// This function intends to provides the fastest possible hashing for
28330/// types and decls, while being completely correct.
28331///
28332/// Note that if the artifact is a type and if it has a canonical
28333/// type, the hash value is going to be the pointer value of the
28334/// canonical type. Otherwise, this function computes a hash value
28335/// for the type by recursively walking the type members. This last
28336/// code path is possibly *very* slow and should only be used when
28337/// only handful of types are going to be hashed.
28338///
28339/// If the artifact is a decl, then a combination of the hash of its
28340/// type and the hash of the other properties of the decl is computed.
28341///
28342/// @param tod the type or decl to hash.
28343///
28344/// @return the resulting hash value.
28345size_t
28347{
28348 hash_t result = 0;
28349
28350 if (tod == 0)
28351 ;
28352 else if (const type_base* t = is_type(tod))
28353 result = hash_type(t);
28354 else if (const decl_base* d = is_decl(tod))
28355 {
28356 if (const scope_decl* s = is_scope_decl(d))
28357 {
28358 if (const global_scope* g = is_global_scope(s))
28359 result = reinterpret_cast<size_t>(g);
28360 else
28361 result = reinterpret_cast<size_t>(s);
28362 }
28363 else if (var_decl* v = is_var_decl(d))
28364 {
28365 ABG_ASSERT(v->get_type());
28366 hash_t h = hash_type_or_decl(v->get_type());
28367 string repr = v->get_pretty_representation(/*internal=*/true);
28368 std::hash<string> hash_string;
28369 h = hashing::combine_hashes(h, hash_string(repr));
28370 result = h;
28371 }
28372 else if (function_decl* f = is_function_decl(d))
28373 {
28374 ABG_ASSERT(f->get_type());
28375 hash_t h = hash_type_or_decl(f->get_type());
28376 string repr = f->get_pretty_representation(/*internal=*/true);
28377 std::hash<string> hash_string;
28378 h = hashing::combine_hashes(h, hash_string(repr));
28379 result = h;
28380 }
28382 {
28383 type_base_sptr parm_type = p->get_type();
28384 ABG_ASSERT(parm_type);
28385 std::hash<bool> hash_bool;
28386 std::hash<unsigned> hash_unsigned;
28387 hash_t h = hash_type_or_decl(parm_type);
28388 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
28389 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
28390 result = h;
28391 }
28392 else if (class_decl::base_spec *bs = is_class_base_spec(d))
28393 {
28394 member_base::hash hash_member;
28395 std::hash<size_t> hash_size;
28396 std::hash<bool> hash_bool;
28397 type_base_sptr type = bs->get_base_class();
28398 hash_t h = hash_type_or_decl(type);
28399 h = hashing::combine_hashes(h, hash_member(*bs));
28400 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
28401 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
28402 result = h;
28403 }
28404 else
28405 // This is a *really* *SLOW* path. If it shows up in a
28406 // performance profile, I bet it'd be a good idea to try to
28407 // avoid it altogether.
28408 // TODO: recode this function or get rid of it altogethe.
28409 abort();
28410 }
28411 else
28412 // We should never get here.
28413 abort();
28414 return *result;
28415}
28416
28417/// Hash an ABI artifact that is a type.
28418///
28419/// This function intends to provides the fastest possible hashing for
28420/// types while being completely correct.
28421///
28422/// Note that if the type artifact has a canonical type, the hash
28423/// value is going to be the pointer value of the canonical type.
28424/// Otherwise, this function computes a hash value for the type by
28425/// recursively walking the type members. This last code path is
28426/// possibly *very* slow and should only be used when only handful of
28427/// types are going to be hashed.
28428///
28429/// @param t the type or decl to hash.
28430///
28431/// @return the resulting hash value.
28432size_t
28434{return hash_as_canonical_type_or_constant(t);}
28435
28436/// Hash an ABI artifact that is either a type of a decl.
28437///
28438/// @param tod the ABI artifact to hash.
28439///
28440/// @return the hash value of the ABI artifact.
28441size_t
28443{return hash_type_or_decl(tod.get());}
28444
28445/// Get the hash value associated to an IR node.
28446///
28447/// Unlike type_or_decl_base::hash_value(), if the IR has no
28448/// associated hash value, an empty hash value is returned.
28449///
28450/// @param artefact the IR node to consider.
28451///
28452/// @return the hash value stored on the IR node or an empty hash if
28453/// no hash value is stored in the @p artefact.
28454hash_t
28456{
28457 const type_or_decl_base* artefactp = &artefact;
28458 if (decl_base *d = is_decl(artefactp))
28459 {
28461 if (d->type_or_decl_base::priv_->get_hashing_state()
28463 return d->type_or_decl_base::priv_->hash_value_;
28464 }
28465 else if (artefact.priv_->get_hashing_state() == hashing::HASHING_FINISHED_STATE)
28466 return artefact.priv_->hash_value_;
28467
28468 return hash_t();
28469}
28470
28471/// Test if a given type is allowed to be non canonicalized
28472///
28473/// This is a subroutine of hash_as_canonical_type_or_constant.
28474///
28475/// For now, the only types allowed to be non canonicalized in the
28476/// system are (typedefs & pointers to) decl-only class/union, the
28477/// void type and variadic parameter types.
28478///
28479/// @return true iff @p t is a one of the only types allowed to be
28480/// non-canonicalized in the system.
28481bool
28483{
28484 if (!t)
28485 return true;
28486
28487 return (// The IR nodes for the types below are unique across the
28488 // entire ABI corpus. Thus, no need to canonicalize them.
28489 // Maybe we could say otherwise and canonicalize them once
28490 // for all so that they can be removed from here.
28492
28493 // An IR node for the types below can be equal to several
28494 // other types (i.e, a decl-only type t equals a fully
28495 // defined type of the same name in ODR-supported
28496 // languages). Hence, they can't be given a canonical type.
28497 //
28498 // TODO: Maybe add a mode that would detect ODR violations
28499 // that would make a decl-only type co-exists with several
28500 // different definitions of the type in the ABI corpus.
28503 /*look_through_decl_only=*/true)
28505
28506}
28507
28508/// Test if a type is unique in the entire environment.
28509///
28510/// Examples of unique types are void, void* and variadic parameter
28511/// types.
28512///
28513/// @param t the type to test for.
28514///
28515/// @return true iff the type @p t is unique in the entire
28516/// environment.
28517bool
28518is_unique_type(const type_base_sptr& t)
28519{return is_unique_type(t.get());}
28520
28521/// Test if a type is unique in the entire environment.
28522///
28523/// Examples of unique types are void, void* and variadic parameter
28524/// types.
28525///
28526/// @param t the type to test for.
28527///
28528/// @return true iff the type @p t is unique in the entire
28529/// environment.
28530bool
28532{
28533 if (!t)
28534 return false;
28535
28536 const environment& env = t->get_environment();
28537 return (env.is_void_type(t)
28538 || env.is_void_pointer_type(t)
28539 || env.is_variadic_parameter_type(t));
28540}
28541
28542/// For a given type, return its exemplar type.
28543///
28544/// For a given type, its exemplar type is either its canonical type
28545/// or the canonical type of the definition type of a given
28546/// declaration-only type. If the neither of those two types exist,
28547/// then the exemplar type is the given type itself.
28548///
28549/// @param type the input to consider.
28550///
28551/// @return the exemplar type.
28552type_base*
28554{
28555 if (decl_base * decl = is_decl(type))
28556 {
28557 // Make sure we get the real definition of a decl-only type.
28558 decl = look_through_decl_only(decl);
28559 type = is_type(decl);
28560 ABG_ASSERT(type);
28561 }
28562 type_base *exemplar = type->get_naked_canonical_type();
28563 if (!exemplar)
28564 {
28565 // The type has no canonical type. Let's be sure that it's one
28566 // of those rare types that are allowed to be non canonicalized
28567 // in the system.
28568 exemplar = const_cast<type_base*>(type);
28570 }
28571 return exemplar;
28572}
28573
28574/// Test if a given type is allowed to be non canonicalized
28575///
28576/// This is a subroutine of hash_as_canonical_type_or_constant.
28577///
28578/// For now, the only types allowed to be non canonicalized in the
28579/// system are decl-only class/union and the void type.
28580///
28581/// @return true iff @p t is a one of the only types allowed to be
28582/// non-canonicalized in the system.
28583bool
28584is_non_canonicalized_type(const type_base_sptr& t)
28585{return is_non_canonicalized_type(t.get());}
28586
28587/// Hash a type by either returning the pointer value of its canonical
28588/// type or by returning a constant if the type doesn't have a
28589/// canonical type.
28590///
28591/// This is a subroutine of hash_type.
28592///
28593/// @param t the type to consider.
28594///
28595/// @return the hash value.
28596static size_t
28597hash_as_canonical_type_or_constant(const type_base *t)
28598{
28599 type_base *canonical_type = 0;
28600
28601 if (t)
28602 canonical_type = t->get_naked_canonical_type();
28603
28604 if (!canonical_type)
28605 {
28606 // If the type doesn't have a canonical type, maybe it's because
28607 // it's a declaration-only type? If that's the case, let's try
28608 // to get the canonical type of the definition of this
28609 // declaration.
28610 decl_base *decl = is_decl(t);
28611 if (decl
28612 && decl->get_is_declaration_only()
28614 {
28615 type_base *definition =
28617 ABG_ASSERT(definition);
28618 canonical_type = definition->get_naked_canonical_type();
28619 }
28620 }
28621
28622 if (canonical_type)
28623 return reinterpret_cast<size_t>(canonical_type);
28624
28625 // If we reached this point, it means we are seeing a
28626 // non-canonicalized type. It must be a decl-only class or a void
28627 // type, otherwise it means that for some weird reason, the type
28628 // hasn't been canonicalized. It should be!
28630
28631 return 0xDEADBABE;
28632}
28633
28634/// Test if the pretty representation of a given @ref function_decl is
28635/// lexicographically less then the pretty representation of another
28636/// @ref function_decl.
28637///
28638/// @param f the first @ref function_decl to consider for comparison.
28639///
28640/// @param s the second @ref function_decl to consider for comparison.
28641///
28642/// @return true iff the pretty representation of @p f is
28643/// lexicographically less than the pretty representation of @p s.
28644bool
28646{
28649
28650 if (fr != sr)
28651 return fr < sr;
28652
28653 fr = f.get_pretty_representation(/*internal=*/true),
28654 sr = s.get_pretty_representation(/*internal=*/true);
28655
28656 if (fr != sr)
28657 return fr < sr;
28658
28659 if (f.get_symbol())
28660 fr = f.get_symbol()->get_id_string();
28661 else if (!f.get_linkage_name().empty())
28662 fr = f.get_linkage_name();
28663
28664 if (s.get_symbol())
28665 sr = s.get_symbol()->get_id_string();
28666 else if (!s.get_linkage_name().empty())
28667 sr = s.get_linkage_name();
28668
28669 return fr < sr;
28670}
28671
28672/// Test if two types have similar structures, even though they are
28673/// (or can be) different.
28674///
28675/// const and volatile qualifiers are completely ignored.
28676///
28677/// typedef are resolved to their definitions; their names are ignored.
28678///
28679/// Two indirect types (pointers or references) have similar structure
28680/// if their underlying types are of the same kind and have the same
28681/// name. In the indirect types case, the size of the underlying type
28682/// does not matter.
28683///
28684/// Two direct types (i.e, non indirect) have a similar structure if
28685/// they have the same kind, name and size. Two class types have
28686/// similar structure if they have the same name, size, and if the
28687/// types of their data members have similar types.
28688///
28689/// @param first the first type to consider.
28690///
28691/// @param second the second type to consider.
28692///
28693/// @param indirect_type whether to do an indirect comparison
28694///
28695/// @return true iff @p first and @p second have similar structures.
28696bool
28697types_have_similar_structure(const type_base_sptr& first,
28698 const type_base_sptr& second,
28699 bool indirect_type)
28700{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
28701
28702/// Test if two types have similar structures, even though they are
28703/// (or can be) different.
28704///
28705/// const and volatile qualifiers are completely ignored.
28706///
28707/// typedef are resolved to their definitions; their names are ignored.
28708///
28709/// Two indirect types (pointers, references or arrays) have similar
28710/// structure if their underlying types are of the same kind and have
28711/// the same name. In the indirect types case, the size of the
28712/// underlying type does not matter.
28713///
28714/// Two direct types (i.e, non indirect) have a similar structure if
28715/// they have the same kind, name and size. Two class types have
28716/// similar structure if they have the same name, size, and if the
28717/// types of their data members have similar types.
28718///
28719/// @param first the first type to consider.
28720///
28721/// @param second the second type to consider.
28722///
28723/// @param indirect_type if true, then consider @p first and @p
28724/// second as being underlying types of indirect types. Meaning that
28725/// their size does not matter.
28726///
28727/// @return true iff @p first and @p second have similar structures.
28728bool
28730 const type_base* second,
28731 bool indirect_type)
28732{
28733 if (!!first != !!second)
28734 return false;
28735
28736 if (!first)
28737 return false;
28738
28739 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
28740 first = peel_qualified_or_typedef_type(first);
28741 second = peel_qualified_or_typedef_type(second);
28742
28743 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
28744 // various ty2 below cannot be null.
28745 if (typeid(*first) != typeid(*second))
28746 return false;
28747
28748 // Peel off matching pointers.
28749 if (const pointer_type_def* ty1 = is_pointer_type(first))
28750 {
28751 const pointer_type_def* ty2 = is_pointer_type(second);
28752 return types_have_similar_structure(ty1->get_pointed_to_type(),
28753 ty2->get_pointed_to_type(),
28754 /*indirect_type=*/true);
28755 }
28756
28757 // Peel off matching references.
28758 if (const reference_type_def* ty1 = is_reference_type(first))
28759 {
28760 const reference_type_def* ty2 = is_reference_type(second);
28761 if (ty1->is_lvalue() != ty2->is_lvalue())
28762 return false;
28763 return types_have_similar_structure(ty1->get_pointed_to_type(),
28764 ty2->get_pointed_to_type(),
28765 /*indirect_type=*/true);
28766 }
28767
28768 // Peel off matching pointer-to-member types.
28769 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28770 {
28771 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28772 return (types_have_similar_structure(ty1->get_member_type(),
28773 ty2->get_member_type(),
28774 /*indirect_type=*/true)
28775 && types_have_similar_structure(ty1->get_containing_type(),
28776 ty2->get_containing_type(),
28777 /*indirect_type=*/true));
28778 }
28779
28780 if (const type_decl* ty1 = is_type_decl(first))
28781 {
28782 const type_decl* ty2 = is_type_decl(second);
28783 if (!indirect_type)
28784 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28785 return false;
28786
28787 return ty1->get_name() == ty2->get_name();
28788 }
28789
28790 if (const enum_type_decl* ty1 = is_enum_type(first))
28791 {
28792 const enum_type_decl* ty2 = is_enum_type(second);
28793 if (!indirect_type)
28794 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28795 return false;
28796
28797 return (get_name(ty1->get_underlying_type())
28798 == get_name(ty2->get_underlying_type()));
28799 }
28800
28801 if (const class_decl* ty1 = is_class_type(first))
28802 {
28803 const class_decl* ty2 = is_class_type(second);
28804 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28805 && ty1->get_name() != ty2->get_name())
28806 return false;
28807
28808 if (!indirect_type)
28809 {
28810 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28811 || (ty1->get_non_static_data_members().size()
28812 != ty2->get_non_static_data_members().size()))
28813 return false;
28814
28815 for (class_or_union::data_members::const_iterator
28816 i = ty1->get_non_static_data_members().begin(),
28817 j = ty2->get_non_static_data_members().begin();
28818 (i != ty1->get_non_static_data_members().end()
28819 && j != ty2->get_non_static_data_members().end());
28820 ++i, ++j)
28821 {
28822 var_decl_sptr dm1 = *i;
28823 var_decl_sptr dm2 = *j;
28824 if (!types_have_similar_structure(dm1->get_type().get(),
28825 dm2->get_type().get(),
28826 indirect_type))
28827 return false;
28828 }
28829 }
28830
28831 return true;
28832 }
28833
28834 if (const union_decl* ty1 = is_union_type(first))
28835 {
28836 const union_decl* ty2 = is_union_type(second);
28837 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28838 && ty1->get_name() != ty2->get_name())
28839 return false;
28840
28841 if (!indirect_type)
28842 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
28843
28844 return true;
28845 }
28846
28847 if (const array_type_def* ty1 = is_array_type(first))
28848 {
28849 const array_type_def* ty2 = is_array_type(second);
28850 if (!indirect_type)
28851 {
28852 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
28853 || ty1->get_dimension_count() != ty2->get_dimension_count())
28854 return false;
28855
28856 // Handle int[5][2] vs int[2][5] ...
28857 //
28858 // 6.2.5/20 of
28859 // https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
28860 // says:
28861 //
28862 // "Array types are characterized by their element
28863 // type and by the number of elements in the array"
28864 //
28865 // and 6.5.2.1/3 says:
28866 //
28867 // "arrays are stored in row-major order (last subscript
28868 // varies fastest)."
28869 //
28870 // So, let's ensure that all dimensions (sub-ranges) have
28871 // the same length.
28872
28873 for (auto r1 = ty1->get_subranges().begin(),
28874 r2 = ty1->get_subranges().begin();
28875 (r1 != ty1->get_subranges().end()
28876 && r2 != ty2->get_subranges().end());
28877 ++r1, ++r2)
28878 if ((*r1)->get_length() != (*r2)->get_length())
28879 return false;
28880 }
28881
28882 // ... then compare the elements of the arrays.
28883 if (!types_have_similar_structure(ty1->get_element_type(),
28884 ty2->get_element_type(),
28885 /*indirect_type=*/true))
28886 return false;
28887
28888 return true;
28889 }
28890
28891 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
28892 {
28894 if (ty1->get_upper_bound() != ty2->get_upper_bound()
28895 || ty1->get_lower_bound() != ty2->get_lower_bound()
28896 || ty1->get_language() != ty2->get_language()
28897 || !types_have_similar_structure(ty1->get_underlying_type(),
28898 ty2->get_underlying_type(),
28899 indirect_type))
28900 return false;
28901
28902 return true;
28903 }
28904
28905 if (const function_type* ty1 = is_function_type(first))
28906 {
28907 const function_type* ty2 = is_function_type(second);
28908 if (!types_have_similar_structure(ty1->get_return_type(),
28909 ty2->get_return_type(),
28910 indirect_type))
28911 return false;
28912
28913 if (ty1->get_parameters().size() != ty2->get_parameters().size())
28914 return false;
28915
28916 for (function_type::parameters::const_iterator
28917 i = ty1->get_parameters().begin(),
28918 j = ty2->get_parameters().begin();
28919 (i != ty1->get_parameters().end()
28920 && j != ty2->get_parameters().end());
28921 ++i, ++j)
28922 if (!types_have_similar_structure((*i)->get_type(),
28923 (*j)->get_type(),
28924 indirect_type))
28925 return false;
28926
28927 return true;
28928 }
28929
28930 // All kinds of type should have been handled at this point.
28932
28933 return false;
28934}
28935
28936/// Look for a data member of a given class, struct or union type and
28937/// return it.
28938///
28939/// The data member is designated by its name.
28940///
28941/// @param type the class, struct or union type to consider.
28942///
28943/// @param dm_name the name of the data member to lookup.
28944///
28945/// @return the data member iff it was found in @type or NULL if no
28946/// data member with that name was found.
28947const var_decl*
28949 const char* dm_name)
28950
28951{
28953 if (!cou)
28954 return 0;
28955
28956 return cou->find_data_member(dm_name).get();
28957}
28958
28959/// Look for a data member of a given class, struct or union type and
28960/// return it.
28961///
28962/// The data member is designated by its name.
28963///
28964/// @param type the class, struct or union type to consider.
28965///
28966/// @param dm the data member to lookup.
28967///
28968/// @return the data member iff it was found in @type or NULL if no
28969/// data member with that name was found.
28970const var_decl_sptr
28971lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
28972{
28973 class_or_union_sptr cou = is_class_or_union_type(type);
28974 if (!cou)
28975 return var_decl_sptr();
28976
28977 return cou->find_data_member(dm);
28978}
28979
28980/// Get the function parameter designated by its index.
28981///
28982/// Note that the first function parameter has index 0.
28983///
28984/// @param fun the function to consider.
28985///
28986/// @param parm_index the index of the function parameter to get.
28987///
28988/// @return the function parameter designated by its index, of NULL if
28989/// no function parameter with that index was found.
28992 unsigned parm_index)
28993{
28995 if (!fn)
28996 return 0;
28997
28998 const function_decl::parameters &parms = fn->get_type()->get_parameters();
28999 if (parms.size() <= parm_index)
29000 return 0;
29001
29002 return parms[parm_index].get();
29003}
29004
29005/// Build the internal name of the underlying type of an enum.
29006///
29007/// @param base_name the (unqualified) name of the enum the underlying
29008/// type is destined to.
29009///
29010/// @param is_anonymous true if the underlying type of the enum is to
29011/// be anonymous.
29012string
29014 bool is_anonymous,
29015 uint64_t size)
29016{
29017 std::ostringstream o;
29018
29019 if (is_anonymous)
29020 o << "unnamed-enum";
29021 else
29022 o << "enum-" << base_name;
29023
29024 o << "-underlying-type-" << size;
29025
29026 return o.str();
29027}
29028
29029/// Find the first data member of a class or union which name matches
29030/// a regular expression.
29031///
29032/// @param t the class or union to consider.
29033///
29034/// @param r the regular expression to consider.
29035///
29036/// @return the data member matched by @p r or nil if none was found.
29039 const regex::regex_t_sptr& r)
29040{
29041 for (auto data_member : t.get_data_members())
29042 {
29043 if (regex::match(r, data_member->get_name()))
29044 return data_member;
29045 }
29046
29047 return var_decl_sptr();
29048}
29049
29050/// Find the last data member of a class or union which name matches
29051/// a regular expression.
29052///
29053/// @param t the class or union to consider.
29054///
29055/// @param r the regular expression to consider.
29056///
29057/// @return the data member matched by @p r or nil if none was found.
29060 const regex::regex_t_sptr& regex)
29061{
29062 auto d = t.get_data_members().rbegin();
29063 auto e = t.get_data_members().rend();
29064 for (; d != e; ++d)
29065 {
29066 if (regex::match(regex, (*d)->get_name()))
29067 return *d;
29068 }
29069
29070 return var_decl_sptr();
29071}
29072
29073/// Emit the pretty representation of the parameters of a function
29074/// type.
29075///
29076/// @param fn_type the function type to consider.
29077///
29078/// @param o the output stream to emit the pretty representation to.
29079///
29080/// @param qualified if true, emit fully qualified names.
29081///
29082/// @param internal if true, then the result is to be used for the
29083/// purpose of type canonicalization.
29084static void
29085stream_pretty_representation_of_fn_parms(const function_type& fn_type,
29086 ostream& o, bool qualified,
29087 bool internal)
29088{
29089 o << "(";
29090 if (fn_type.get_parameters().empty())
29091 o << "void";
29092 else
29093 {
29094 type_base_sptr type;
29095 auto end = fn_type.get_parameters().end();
29096 auto first_parm = fn_type.get_first_non_implicit_parm();
29098 const environment& env = fn_type.get_environment();
29099 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
29100 {
29101 if (i != first_parm)
29102 o << ", ";
29103 parm = *i;
29104 type = parm->get_type();
29105 // If the type is a decl-only class, union or enum that has a
29106 // definition, use the definition instead. That definition
29107 // is what is going to be serialized out in ABIXML anyway,
29108 // so use that for consistency.
29109 if (decl_base_sptr def = look_through_decl_only(is_decl(type)))
29110 type = is_type(def);
29111 if (env.is_variadic_parameter_type(type))
29112 o << "...";
29113 else
29114 o << get_type_name(type, qualified, internal);
29115 }
29116 }
29117 o << ")";
29118}
29119
29120/// When constructing the name of a pointer to function type, add the
29121/// return type to the left of the existing type identifier, and the
29122/// parameters declarator to the right.
29123///
29124/// This function considers the name of the type as an expression.
29125///
29126/// The resulting type expr is going to be made of three parts:
29127/// left_expr inner_expr right_expr.
29128///
29129/// Suppose we want to build the type expression representing:
29130///
29131/// "an array of pointer to function taking a char parameter and
29132/// returning an int".
29133///
29134/// It's going to look like:
29135///
29136/// int(*a[])(char);
29137///
29138/// Suppose the caller of this function started to emit the inner
29139/// "a[]" part of the expression already. It thus calls this
29140/// function with that input "a[]" part. We consider that "a[]" as
29141/// the "type identifier".
29142///
29143/// So the inner_expr is going to be "(*a[])".
29144///
29145/// The left_expr part is "int". The right_expr part is "(char)".
29146///
29147/// In other words, this function adds the left_expr and right_expr to
29148/// the inner_expr. left_expr and right_expr are called "outer
29149/// pointer to function type expression".
29150///
29151/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29152/// array_declaration_name()
29153///
29154/// @param p the pointer to function type to consider.
29155///
29156/// @param input the type-id to use as the inner expression of the
29157/// overall pointer-to-function type expression
29158///
29159/// @param qualified if true then use qualified names in the resulting
29160/// type name.
29161///
29162/// @param internal if true then the resulting type name is going to
29163/// be used for type canonicalization purposes.
29164///
29165/// @return the name of the pointer to function type.
29166static string
29167add_outer_pointer_to_fn_type_expr(const type_base* p,
29168 const string& input,
29169 bool qualified, bool internal)
29170{
29171 if (!p)
29172 return "";
29173
29174 function_type_sptr pointed_to_fn;
29175 string star_or_ref;
29176
29177 if (const pointer_type_def* ptr = is_pointer_type(p))
29178 {
29179 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
29180 star_or_ref= "*";
29181 }
29182 else if (const reference_type_def* ref = is_reference_type(p))
29183 {
29184 star_or_ref = "&";
29185 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
29186 }
29187
29188 if (!pointed_to_fn)
29189 return "";
29190
29191 if (pointed_to_fn->priv_->is_pretty_printing())
29192 // We have just detected a cycle while walking the sub-tree of
29193 // this function type for the purpose of printing its
29194 // representation. We need to get out of here pronto or else
29195 // we'll be spinning endlessly.
29196 return "";
29197
29198 // Let's mark thie function type to signify that we started walking
29199 // its subtree. This is to detect potential cycles and avoid
29200 // looping endlessly.
29201 pointed_to_fn->priv_->set_is_pretty_printing();
29202
29203 std::ostringstream left, right, inner;
29204
29205 inner << "(" << star_or_ref << input << ")";
29206
29207 type_base_sptr type;
29208 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
29209 qualified, internal);
29210
29211 type_base_sptr return_type = pointed_to_fn->get_return_type();
29212 string result;
29213
29214 if (is_npaf_type(return_type)
29215 || !(is_pointer_to_function_type(return_type)
29216 || is_pointer_to_array_type(return_type)))
29217 {
29218 if (return_type)
29219 left << get_type_name(return_type, qualified, internal);
29220 result = left.str() + " " + inner.str() + right.str();
29221 }
29222 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
29223 {
29224 string inner_string = inner.str() + right.str();
29225 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
29226 qualified, internal);
29227 }
29228 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
29229 {
29230 string inner_string = inner.str() + right.str();
29231 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29232 qualified, internal);
29233 }
29234 else
29236
29237 // Lets unmark this function type to signify that we are done
29238 // walking its subtree. This was to detect potential cycles and
29239 // avoid looping endlessly.
29240 pointed_to_fn->priv_->unset_is_pretty_printing();
29241 return result;
29242}
29243
29244/// When constructing the name of a pointer to function type, add the
29245/// return type to the left of the existing type identifier, and the
29246/// parameters declarator to the right.
29247///
29248/// This function considers the name of the type as an expression.
29249///
29250/// The resulting type expr is going to be made of three parts:
29251/// left_expr inner_expr right_expr.
29252///
29253/// Suppose we want to build the type expression representing:
29254///
29255/// "an array of pointer to function taking a char parameter and
29256/// returning an int".
29257///
29258/// It's going to look like:
29259///
29260/// int(*a[])(char);
29261///
29262/// Suppose the caller of this function started to emit the inner
29263/// "a[]" part of the expression already. It thus calls this
29264/// function with that input "a[]" part. We consider that "a[]" as
29265/// the "type identifier".
29266///
29267/// So the inner_expr is going to be "(*a[])".
29268///
29269/// The left_expr part is "int". The right_expr part is "(char)".
29270///
29271/// In other words, this function adds the left_expr and right_expr to
29272/// the inner_expr. left_expr and right_expr are called "outer
29273/// pointer to function type expression".
29274///
29275/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29276/// array_declaration_name()
29277///
29278/// @param p the pointer to function type to consider.
29279///
29280/// @param input the type-id to use as the inner expression of the
29281/// overall pointer-to-function type expression
29282///
29283/// @param qualified if true then use qualified names in the resulting
29284/// type name.
29285///
29286/// @param internal if true then the resulting type name is going to
29287/// be used for type canonicalization purposes.
29288///
29289/// @return the name of the pointer to function type.
29290static string
29291add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
29292 const string& input,
29293 bool qualified, bool internal)
29294{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
29295
29296/// When constructing the name of a pointer to array type, add the
29297/// array element type type to the left of the existing type
29298/// identifier, and the array declarator part to the right.
29299///
29300/// This function considers the name of the type as an expression.
29301///
29302/// The resulting type expr is going to be made of three parts:
29303/// left_expr inner_expr right_expr.
29304///
29305/// Suppose we want to build the type expression representing:
29306///
29307/// "a pointer to an array of int".
29308///
29309/// It's going to look like:
29310///
29311/// int(*foo)[];
29312///
29313/// Suppose the caller of this function started to emit the inner
29314/// "foo" part of the expression already. It thus calls this function
29315/// with that input "foo" part. We consider that "foo" as the "type
29316/// identifier".
29317///
29318/// So we are passed an input string that is "foo" and it's going to
29319/// be turned into the inner_expr part, which is going to be "(*foo)".
29320///
29321/// The left_expr part is "int". The right_expr part is "[]".
29322///
29323/// In other words, this function adds the left_expr and right_expr to
29324/// the inner_expr. left_expr and right_expr are called "outer
29325/// pointer to array type expression".
29326///
29327/// The model of this function was taken from the article "Reading C
29328/// type declaration", from Steve Friedl at
29329/// http://unixwiz.net/techtips/reading-cdecl.html.
29330///
29331/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29332/// array_declaration_name()
29333///
29334/// @param p the pointer to array type to consider.
29335///
29336/// @param input the type-id to start from as the inner part of the
29337/// final type name.
29338///
29339/// @param qualified if true then use qualified names in the resulting
29340/// type name.
29341///
29342/// @param internal if true then the resulting type name is going to
29343/// be used for type canonicalization purposes.
29344///
29345/// @return the name of the pointer to array type.
29346static string
29347add_outer_pointer_to_array_type_expr(const type_base* p,
29348 const string& input, bool qualified,
29349 bool internal)
29350{
29351 if (!p)
29352 return "";
29353
29354 string star_or_ref;
29355 type_base_sptr pointed_to_type;
29356
29357 if (const pointer_type_def *ptr = is_pointer_type(p))
29358 {
29359 pointed_to_type = ptr->get_pointed_to_type();
29360 star_or_ref = "*";
29361 }
29362 else if (const reference_type_def *ref = is_reference_type(p))
29363 {
29364 pointed_to_type = ref->get_pointed_to_type();
29365 star_or_ref = "&";
29366 }
29367
29368 array_type_def_sptr array = is_array_type(pointed_to_type);
29369 if (!array)
29370 return "";
29371
29372 std::ostringstream left, right, inner;
29373 inner << "(" << star_or_ref << input << ")";
29374 right << array->get_subrange_representation();
29375 string result;
29376
29377 type_base_sptr array_element_type = array->get_element_type();
29378
29379 if (is_npaf_type(array_element_type)
29380 || !(is_pointer_to_function_type(array_element_type)
29381 || is_pointer_to_array_type(array_element_type)))
29382 {
29383 left << get_type_name(array_element_type, qualified, internal);
29384 result = left.str() + inner.str() + right.str();
29385 }
29386 else if (pointer_type_def_sptr p =
29387 is_pointer_to_function_type(array_element_type))
29388 {
29389 string r = inner.str() + right.str();
29390 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
29391 }
29392 else if (pointer_type_def_sptr p =
29393 is_pointer_to_array_type(array_element_type))
29394 {
29395 string inner_string = inner.str() + right.str();
29396 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29397 qualified, internal);
29398 }
29399 else
29401
29402 return result;
29403}
29404
29405/// When constructing the name of a pointer to array type, add the
29406/// array element type type to the left of the existing type
29407/// identifier, and the array declarator part to the right.
29408///
29409/// This function considers the name of the type as an expression.
29410///
29411/// The resulting type expr is going to be made of three parts:
29412/// left_expr inner_expr right_expr.
29413///
29414/// Suppose we want to build the type expression representing:
29415///
29416/// "a pointer to an array of int".
29417///
29418/// It's going to look like:
29419///
29420/// int(*foo)[];
29421///
29422/// Suppose the caller of this function started to emit the inner
29423/// "foo" part of the expression already. It thus calls this function
29424/// with that input "foo" part. We consider that "foo" as the "type
29425/// identifier".
29426///
29427/// So we are passed an input string that is "foo" and it's going to
29428/// be turned into the inner_expr part, which is going to be "(*foo)".
29429///
29430/// The left_expr part is "int". The right_expr part is "[]".
29431///
29432/// In other words, this function adds the left_expr and right_expr to
29433/// the inner_expr. left_expr and right_expr are called "outer
29434/// pointer to array type expression".
29435///
29436/// The model of this function was taken from the article "Reading C
29437/// type declaration", from Steve Friedl at
29438/// http://unixwiz.net/techtips/reading-cdecl.html.
29439///
29440/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29441/// array_declaration_name()
29442///
29443/// @param p the pointer to array type to consider.
29444///
29445/// @param input the type-id to start from as the inner part of the
29446/// final type name.
29447///
29448/// @param qualified if true then use qualified names in the resulting
29449/// type name.
29450///
29451/// @param internal if true then the resulting type name is going to
29452/// be used for type canonicalization purposes.
29453///
29454/// @return the name of the pointer to array type.
29455static string
29456add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
29457 const string& input, bool qualified,
29458 bool internal)
29459{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
29460 input, qualified, internal);}
29461
29462/// When constructing the name of a pointer to mebmer type, add the
29463/// return type to the left of the existing type identifier, and the
29464/// parameters declarator to the right.
29465///
29466/// This function considers the name of the type as an expression.
29467///
29468/// The resulting type expr is going to be made of three parts:
29469/// left_expr inner_expr right_expr.
29470///
29471/// Suppose we want to build the type expression representing:
29472///
29473/// "an array of pointer to member function (of a containing struct
29474/// X) taking a char parameter and returning an int".
29475///
29476/// It's going to look like:
29477///
29478/// int (X::* a[])(char);
29479///
29480/// Suppose the caller of this function started to emit the inner
29481/// "a[]" part of the expression already. It thus calls this
29482/// function with that input "a[]" part. We consider that "a[]" as
29483/// the "type identifier".
29484///
29485/// So the inner_expr is going to be "(X::* a[])".
29486///
29487/// The left_expr part is "int". The right_expr part is "(char)".
29488///
29489/// In other words, this function adds the left_expr and right_expr to
29490/// the inner_expr. left_expr and right_expr are called "outer
29491/// pointer to member type expression".
29492///
29493/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29494///
29495/// @param p the pointer to member type to consider.
29496///
29497/// @param input the type-id to use as the inner expression of the
29498/// overall pointer-to-member type expression
29499///
29500/// @param qualified if true then use qualified names in the resulting
29501/// type name.
29502///
29503/// @param internal if true then the resulting type name is going to
29504/// be used for type canonicalization purposes.
29505///
29506/// @return the name of the pointer to member type.
29507static string
29508add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
29509 const string& input, bool qualified,
29510 bool internal)
29511{
29512 if (!p)
29513 return "";
29514
29515 std::ostringstream left, right, inner;
29516 type_base_sptr void_type = p->get_environment().get_void_type();
29517 string containing_type_name = get_type_name(p->get_containing_type(),
29518 qualified, internal);
29519 type_base_sptr mbr_type = p->get_member_type();
29520 string result;
29521 if (function_type_sptr fn_type = is_function_type(mbr_type))
29522 {
29523 inner << "(" << containing_type_name << "::*" << input << ")";
29524 stream_pretty_representation_of_fn_parms(*fn_type, right,
29525 qualified, internal);
29526 type_base_sptr return_type = fn_type->get_return_type();
29527 if (!return_type)
29528 return_type = void_type;
29529 if (is_npaf_type(return_type)
29530 || !(is_pointer_to_function_type(return_type)
29531 || is_pointer_to_array_type(return_type)
29532 || is_pointer_to_ptr_to_mbr_type(return_type)
29533 || is_ptr_to_mbr_type(return_type)))
29534 {
29535 left << get_type_name(return_type, qualified, internal) << " ";;
29536 result = left.str() + inner.str() + right.str();
29537 }
29538 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
29539 {
29540 string inner_str = inner.str() + right.str();
29541 result = pointer_declaration_name(p, inner_str, qualified, internal);
29542 }
29543 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
29544 {
29545 string inner_str = inner.str() + right.str();
29546 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
29547 qualified, internal);
29548 }
29549 else
29551 }
29552 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
29553 {
29554 inner << "(" << containing_type_name << "::*" << input << ")";
29555 stream_pretty_representation_of_fn_parms(*fn_type, right,
29556 qualified, internal);
29557 string inner_str = inner.str() + right.str();
29558 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
29559 qualified, internal);
29560 }
29561 else
29562 {
29563 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
29564 inner << containing_type_name << "::*" << input;
29565 result = left.str()+ inner.str();
29566 }
29567
29568 return result;
29569}
29570
29571/// Test if two decls have different names.
29572///
29573/// Note that this function takes into account decls whose names are
29574/// relevant from an ABI standpoint. For instance, function parameter
29575/// names are not relevant in that context.
29576///
29577/// @param d1 the first declaration to consider.
29578///
29579/// @param d2 the second declaration to consider.
29580///
29581/// @return true if d1 and d2 have different names.
29582bool
29584{
29585 string d1_name, d2_name;
29586
29587 const decl_base *d1 = dynamic_cast<const decl_base*>(a1);
29588 if (d1 == 0)
29589 return false;
29590
29591 const decl_base *d2 = dynamic_cast<const decl_base*>(a2);
29592 if (d2 == 0)
29593 return false;
29594
29596 // Name changes for fn parms are irrelevant.
29597 return false;
29598
29599 d1_name = d1->get_qualified_name();
29600 d2_name = d2->get_qualified_name();
29601
29602 return d1_name != d2_name;
29603}
29604
29605/// Test if two decls have different names.
29606///
29607/// @param d1 the first declaration to consider.
29608///
29609/// @param d2 the second declaration to consider.
29610///
29611/// @return true if d1 and d2 have different names.
29612bool
29614 const type_or_decl_base_sptr& d2)
29615{return decl_name_changed(d1.get(), d2.get());}
29616
29617/// Test if a diff node carries a change whereby two integral types
29618/// have different names in a harmless way.
29619///
29620/// Basically, if the integral type name change is accompanied by a
29621/// size change then the change is considered harmful. If there are
29622/// modifiers change, the change is considered harmful.
29623bool
29625 const type_base_sptr& s)
29626{
29627 if (is_decl(f)
29628 && is_decl(s)
29629 && (is_integral_type(f) || is_decl(f)->get_name().empty())
29630 && (is_integral_type(s) || is_decl(s)->get_name().empty())
29632 && (f->get_size_in_bits() == s->get_size_in_bits())
29633 && (f->get_alignment_in_bits() == s->get_alignment_in_bits()))
29634 {
29635 real_type fi, si;
29636 ABG_ASSERT(is_decl(f)->get_name().empty()
29637 || parse_real_type(is_decl(f)->get_name(), fi));
29638 ABG_ASSERT(is_decl(s)->get_name().empty()
29639 || parse_real_type(is_decl(s)->get_name(), si));
29640
29641 if (fi.get_base_type() == si.get_base_type()
29642 && fi.get_modifiers() != si.get_modifiers())
29643 // The base type hasn't changed. That means only modifiers
29644 // changed. This is considered has harmful by default.
29645 return false;
29646
29647 return true;
29648 }
29649
29650 return false;
29651}
29652
29653/// Test if a diff node carries a change whereby two integral types
29654/// have different names in a harmless way.
29655///
29656/// Basically, if the integral type name change is accompanied by a
29657/// size change then the change is considered harmful. If there are
29658/// modifiers change, the change is considered harmful.
29659bool
29661 const decl_base_sptr& s)
29663
29664
29665/// When constructing the name of a pointer to mebmer type, add the
29666/// return type to the left of the existing type identifier, and the
29667/// parameters declarator to the right.
29668///
29669/// This function considers the name of the type as an expression.
29670///
29671/// The resulting type expr is going to be made of three parts:
29672/// left_expr inner_expr right_expr.
29673///
29674/// Suppose we want to build the type expression representing:
29675///
29676/// "an array of pointer to member function (of a containing struct
29677/// X) taking a char parameter and returning an int".
29678///
29679/// It's going to look like:
29680///
29681/// int (X::* a[])(char);
29682///
29683/// Suppose the caller of this function started to emit the inner
29684/// "a[]" part of the expression already. It thus calls this
29685/// function with that input "a[]" part. We consider that "a[]" as
29686/// the "type identifier".
29687///
29688/// So the inner_expr is going to be "(X::* a[])".
29689///
29690/// The left_expr part is "int". The right_expr part is "(char)".
29691///
29692/// In other words, this function adds the left_expr and right_expr to
29693/// the inner_expr. left_expr and right_expr are called "outer
29694/// pointer to member type expression".
29695///
29696/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29697///
29698/// @param p the pointer to member type to consider.
29699///
29700/// @param input the type-id to use as the inner expression of the
29701/// overall pointer-to-member type expression
29702///
29703/// @param qualified if true then use qualified names in the resulting
29704/// type name.
29705///
29706/// @param internal if true then the resulting type name is going to
29707/// be used for type canonicalization purposes.
29708///
29709/// @return the name of the pointer to member type.
29710static string
29711add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
29712 const string& input, bool qualified,
29713 bool internal)
29714{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
29715
29716/// This adds the outer parts of a pointer to a pointer-to-member
29717/// expression.
29718///
29719/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
29720/// learn more about this function, which is similar.
29721///
29722/// This is a sub-routine of @ref pointer_declaration_name().
29723///
29724/// @param a pointer (or reference) to a pointer-to-member type.
29725///
29726/// @param input the inner type-id to add the outer parts to.
29727///
29728/// @param qualified if true then use qualified names in the resulting
29729/// type name.
29730///
29731/// @param internal if true then the resulting type name is going to
29732/// be used for type canonicalization purposes.
29733static string
29734add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
29735 const string& input, bool qualified,
29736 bool internal)
29737{
29738 if (!p)
29739 return "";
29740
29741 string star_or_ref;
29742 type_base_sptr pointed_to_type;
29743
29744 if (const pointer_type_def* ptr = is_pointer_type(p))
29745 {
29746 pointed_to_type = ptr->get_pointed_to_type();
29747 star_or_ref = "*";
29748 }
29749 else if (const reference_type_def* ref = is_reference_type(p))
29750 {
29751 pointed_to_type= ref->get_pointed_to_type();
29752 star_or_ref = "&";
29753 }
29754
29755 if (!pointed_to_type)
29756 return "";
29757
29758 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
29759 is_ptr_to_mbr_type(pointed_to_type);
29760 if (!pointed_to_ptr_to_mbr)
29761 return "";
29762
29763 std::ostringstream inner;
29764 inner << star_or_ref << input;
29765 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
29766 inner.str(),
29767 qualified, internal);
29768 return result;
29769}
29770
29771/// Emit the name of a pointer declaration.
29772///
29773/// @param the pointer to consider.
29774///
29775/// @param idname the name of the variable that has @p as a type or
29776/// the id of the type. If it's empty then the resulting name is
29777/// going to be the abstract name of the type.
29778///
29779/// @param qualified if true then the type name is going to be
29780/// fully qualified.
29781///
29782/// @param internal if true then the type name is going to be used for
29783/// type canonicalization purposes.
29784static interned_string
29785pointer_declaration_name(const type_base* ptr,
29786 const string& idname,
29787 bool qualified, bool internal)
29788{
29789 if (!ptr)
29790 return interned_string();
29791
29792 type_base_sptr pointed_to_type;
29793 string star_or_ref;
29794 if (const pointer_type_def* p = is_pointer_type(ptr))
29795 {
29796 pointed_to_type = p->get_pointed_to_type();
29797 star_or_ref = "*";
29798 }
29799 else if (const reference_type_def* p = is_reference_type(ptr))
29800 {
29801 pointed_to_type = p->get_pointed_to_type();
29802 star_or_ref = "&";
29803 }
29804
29805 if (!pointed_to_type)
29806 return interned_string();
29807
29808 string result;
29809 if (is_npaf_type(pointed_to_type)
29810 || !(is_function_type(pointed_to_type)
29811 || is_array_type(pointed_to_type)
29812 || is_ptr_to_mbr_type(pointed_to_type)))
29813 {
29814 result = get_type_name(pointed_to_type,
29815 qualified,
29816 internal)
29817 + star_or_ref;
29818
29819 if (!idname.empty())
29820 result += idname;
29821 }
29822 else
29823 {
29824 // derived type
29825 if (is_function_type(pointed_to_type))
29826 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29827 qualified, internal);
29828 else if (is_array_type(pointed_to_type))
29829 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29830 qualified, internal);
29831 else if (is_ptr_to_mbr_type(pointed_to_type))
29832 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29833 qualified, internal);
29834 else
29836 }
29837 return ptr->get_environment().intern(result);
29838}
29839
29840
29841/// Emit the name of a pointer declaration.
29842///
29843/// @param the pointer to consider.
29844///
29845/// @param the name of the variable that has @p as a type. If it's
29846/// empty then the resulting name is going to be the abstract name of
29847/// the type.
29848///
29849/// @param qualified if true then the type name is going to be
29850/// fully qualified.
29851///
29852/// @param internal if true then the type name is going to be used for
29853/// type canonicalization purposes.
29854static interned_string
29855pointer_declaration_name(const type_base_sptr& ptr,
29856 const string& variable_name,
29857 bool qualified, bool internal)
29858{return pointer_declaration_name(ptr.get(), variable_name,
29859 qualified, internal);}
29860
29861/// Emit the name of a array declaration.
29862///
29863/// @param the array to consider.
29864///
29865/// @param the name of the variable that has @p as a type. If it's
29866/// empty then the resulting name is going to be the abstract name of
29867/// the type.
29868///
29869/// @param qualified if true then the type name is going to be
29870/// fully qualified.
29871///
29872/// @param internal if true then the type name is going to be used for
29873/// type canonicalization purposes.
29874static interned_string
29875array_declaration_name(const array_type_def* array,
29876 const string& variable_name,
29877 bool qualified, bool internal)
29878{
29879 if (!array)
29880 return interned_string();
29881
29882 type_base_sptr e_type = array->get_element_type();
29883 string e_type_repr =
29884 (e_type
29885 ? get_type_name(e_type, qualified, internal)
29886 : string("void"));
29887
29888 string result;
29889 if (is_ada_language(array->get_language()))
29890 {
29891 std::ostringstream o;
29892 if (!variable_name.empty())
29893 o << variable_name << " is ";
29894 o << "array ("
29895 << array->get_subrange_representation()
29896 << ") of " << e_type_repr;
29897 result = o.str();
29898 }
29899 else
29900 {
29901 if (is_npaf_type(e_type)
29902 || !(is_pointer_to_function_type(e_type)
29903 || is_pointer_to_array_type(e_type)
29905 || is_ptr_to_mbr_type(e_type)))
29906 {
29907 result = e_type_repr;
29908 if (!variable_name.empty())
29909 result += variable_name;
29910 result += array->get_subrange_representation();
29911 }
29912 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
29913 {
29914 string s = variable_name + array->get_subrange_representation();
29915 result = pointer_declaration_name(p, s, qualified, internal);
29916 }
29917 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
29918 {
29919 string s = variable_name + array->get_subrange_representation();
29920 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
29921 }
29922 else
29924 }
29925 return array->get_environment().intern(result);
29926}
29927
29928/// Emit the name of a array declaration.
29929///
29930/// @param the array to consider.
29931///
29932/// @param the name of the variable that has @p as a type. If it's
29933/// empty then the resulting name is going to be the abstract name of
29934/// the type.
29935///
29936/// @param qualified if true then the type name is going to be
29937/// fully qualified.
29938///
29939/// @param internal if true then the type name is going to be used for
29940/// type canonicalization purposes.
29941static interned_string
29942array_declaration_name(const array_type_def_sptr& array,
29943 const string& variable_name,
29944 bool qualified, bool internal)
29945{return array_declaration_name(array.get(), variable_name,
29946 qualified, internal);}
29947
29948/// Emit the name of a pointer-to-member declaration.
29949///
29950/// @param ptr the pointer-to-member to consider.
29951///
29952/// @param variable_name the name of the variable that has @p as a
29953/// type. If it's empty then the resulting name is going to be the
29954/// abstract name of the type.
29955///
29956/// @param qualified if true then the type name is going to be
29957/// fully qualified.
29958///
29959/// @param internal if true then the type name is going to be used for
29960/// type canonicalization purposes.
29961static interned_string
29962ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
29963 const string& variable_name,
29964 bool qualified, bool internal)
29965{
29966 if (!ptr)
29967 return interned_string();
29968
29969 string input = variable_name;
29970 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
29971 qualified, internal);
29972 return ptr->get_environment().intern(result);
29973}
29974
29975/// Emit the name of a pointer-to-member declaration.
29976///
29977/// @param ptr the pointer-to-member to consider.
29978///
29979/// @param variable_name the name of the variable that has @p as a
29980/// type. If it's empty then the resulting name is going to be the
29981/// abstract name of the type.
29982///
29983/// @param qualified if true then the type name is going to be
29984/// fully qualified.
29985///
29986/// @param internal if true then the type name is going to be used for
29987/// type canonicalization purposes.
29988static interned_string
29989ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
29990 const string& variable_name,
29991 bool qualified, bool internal)
29992{
29993 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
29994 qualified, internal);
29995}
29996
29997/// Sort types right before hashing and canonicalizing them.
29998///
29999/// @param types the vector of types to sort.
30000void
30001sort_types_for_hash_computing_and_c14n(vector<type_base_sptr>& types)
30002{
30003 sort_types_for_hash_computing_and_c14n(types.begin(), types.end());
30004}
30005
30006bool
30008{return true;}
30009
30010// <ir_node_visitor stuff>
30011
30012/// The private data structure of the ir_node_visitor type.
30013struct ir_node_visitor::priv
30014{
30015 pointer_set visited_ir_nodes;
30017
30018 priv()
30020 {}
30021}; // end struct ir_node_visitory::priv
30022
30023/// Default Constructor of the ir_node_visitor type.
30025 : priv_(new priv)
30026{}
30027
30028ir_node_visitor::~ir_node_visitor() = default;
30029
30030/// Set if the walker using this visitor is allowed to re-visit a type
30031/// node that was previously visited or not.
30032///
30033/// @param f if true, then the walker using this visitor is allowed to
30034/// re-visit a type node that was previously visited.
30035void
30037{priv_->allow_visiting_already_visited_type_node = f;}
30038
30039/// Get if the walker using this visitor is allowed to re-visit a type
30040/// node that was previously visited or not.
30041///
30042/// @return true iff the walker using this visitor is allowed to
30043/// re-visit a type node that was previously visited.
30044bool
30046{return priv_->allow_visiting_already_visited_type_node;}
30047
30048/// Mark a given type node as having been visited.
30049///
30050/// Note that for this function to work, the type node must have been
30051/// canonicalized. Otherwise the process is aborted.
30052///
30053/// @param p the type to mark as having been visited.
30054void
30056{
30058 return;
30059
30060 if (p == 0 || type_node_has_been_visited(p))
30061 return;
30062
30063 type_base* canonical_type = p->get_naked_canonical_type();
30065 {
30066 ABG_ASSERT(!canonical_type);
30067 canonical_type = p;
30068 }
30069 ABG_ASSERT(canonical_type);
30070
30071 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
30072 priv_->visited_ir_nodes.insert(canonical_ptr_value);
30073}
30074
30075/// Un-mark all visited type nodes.
30076///
30077/// That is, no type node is going to be considered as having been
30078/// visited anymore.
30079///
30080/// In other words, after invoking this funciton,
30081/// ir_node_visitor::type_node_has_been_visited() is going to return
30082/// false on all type nodes.
30083void
30085{priv_->visited_ir_nodes.clear();}
30086
30087/// Test if a given type node has been marked as visited.
30088///
30089/// @param p the type node to consider.
30090///
30091/// @return true iff the type node @p p has been marked as visited by
30092/// the function ir_node_visitor::mark_type_node_as_visited.
30093bool
30095{
30097 return false;
30098
30099 if (p == 0)
30100 return false;
30101
30102 type_base *canonical_type = p->get_naked_canonical_type();
30104 {
30105 ABG_ASSERT(!canonical_type);
30106 canonical_type = p;
30107 }
30108 ABG_ASSERT(canonical_type);
30109
30110 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
30111 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
30112 if (it == priv_->visited_ir_nodes.end())
30113 return false;
30114
30115 return true;
30116}
30117
30118bool
30119ir_node_visitor::visit_begin(decl_base*)
30120{return true;}
30121
30122bool
30123ir_node_visitor::visit_end(decl_base*)
30124{return true;}
30125
30126bool
30127ir_node_visitor::visit_begin(scope_decl*)
30128{return true;}
30129
30130bool
30131ir_node_visitor::visit_end(scope_decl*)
30132{return true;}
30133
30134bool
30135ir_node_visitor::visit_begin(type_base*)
30136{return true;}
30137
30138bool
30139ir_node_visitor::visit_end(type_base*)
30140{return true;}
30141
30142bool
30143ir_node_visitor::visit_begin(scope_type_decl* t)
30144{return visit_begin(static_cast<type_base*>(t));}
30145
30146bool
30147ir_node_visitor::visit_end(scope_type_decl* t)
30148{return visit_end(static_cast<type_base*>(t));}
30149
30150bool
30151ir_node_visitor::visit_begin(type_decl* t)
30152{return visit_begin(static_cast<type_base*>(t));}
30153
30154bool
30155ir_node_visitor::visit_end(type_decl* t)
30156{return visit_end(static_cast<type_base*>(t));}
30157
30158bool
30159ir_node_visitor::visit_begin(namespace_decl* d)
30160{return visit_begin(static_cast<decl_base*>(d));}
30161
30162bool
30163ir_node_visitor::visit_end(namespace_decl* d)
30164{return visit_end(static_cast<decl_base*>(d));}
30165
30166bool
30167ir_node_visitor::visit_begin(qualified_type_def* t)
30168{return visit_begin(static_cast<type_base*>(t));}
30169
30170bool
30171ir_node_visitor::visit_end(qualified_type_def* t)
30172{return visit_end(static_cast<type_base*>(t));}
30173
30174bool
30175ir_node_visitor::visit_begin(pointer_type_def* t)
30176{return visit_begin(static_cast<type_base*>(t));}
30177
30178bool
30179ir_node_visitor::visit_end(pointer_type_def* t)
30180{return visit_end(static_cast<type_base*>(t));}
30181
30182bool
30183ir_node_visitor::visit_begin(reference_type_def* t)
30184{return visit_begin(static_cast<type_base*>(t));}
30185
30186bool
30187ir_node_visitor::visit_end(reference_type_def* t)
30188{return visit_end(static_cast<type_base*>(t));}
30189
30190bool
30191ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
30192{return visit_begin(static_cast<type_base*>(t));}
30193
30194bool
30195ir_node_visitor::visit_end(ptr_to_mbr_type* t)
30196{return visit_end(static_cast<type_base*>(t));}
30197
30198bool
30199ir_node_visitor::visit_begin(array_type_def* t)
30200{return visit_begin(static_cast<type_base*>(t));}
30201
30202bool
30203ir_node_visitor::visit_end(array_type_def* t)
30204{return visit_end(static_cast<type_base*>(t));}
30205
30206bool
30207ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
30208{return visit_begin(static_cast<type_base*>(t));}
30209
30210bool
30211ir_node_visitor::visit_end(array_type_def::subrange_type* t)
30212{return visit_end(static_cast<type_base*>(t));}
30213
30214bool
30215ir_node_visitor::visit_begin(enum_type_decl* t)
30216{return visit_begin(static_cast<type_base*>(t));}
30217
30218bool
30219ir_node_visitor::visit_end(enum_type_decl* t)
30220{return visit_end(static_cast<type_base*>(t));}
30221
30222bool
30223ir_node_visitor::visit_begin(typedef_decl* t)
30224{return visit_begin(static_cast<type_base*>(t));}
30225
30226bool
30227ir_node_visitor::visit_end(typedef_decl* t)
30228{return visit_end(static_cast<type_base*>(t));}
30229
30230bool
30231ir_node_visitor::visit_begin(function_type* t)
30232{return visit_begin(static_cast<type_base*>(t));}
30233
30234bool
30235ir_node_visitor::visit_end(function_type* t)
30236{return visit_end(static_cast<type_base*>(t));}
30237
30238bool
30239ir_node_visitor::visit_begin(var_decl* d)
30240{return visit_begin(static_cast<decl_base*>(d));}
30241
30242bool
30243ir_node_visitor::visit_end(var_decl* d)
30244{return visit_end(static_cast<decl_base*>(d));}
30245
30246bool
30247ir_node_visitor::visit_begin(function_decl* d)
30248{return visit_begin(static_cast<decl_base*>(d));}
30249
30250bool
30251ir_node_visitor::visit_end(function_decl* d)
30252{return visit_end(static_cast<decl_base*>(d));}
30253
30254bool
30255ir_node_visitor::visit_begin(function_decl::parameter* d)
30256{return visit_begin(static_cast<decl_base*>(d));}
30257
30258bool
30259ir_node_visitor::visit_end(function_decl::parameter* d)
30260{return visit_end(static_cast<decl_base*>(d));}
30261
30262bool
30263ir_node_visitor::visit_begin(function_tdecl* d)
30264{return visit_begin(static_cast<decl_base*>(d));}
30265
30266bool
30267ir_node_visitor::visit_end(function_tdecl* d)
30268{return visit_end(static_cast<decl_base*>(d));}
30269
30270bool
30271ir_node_visitor::visit_begin(class_tdecl* d)
30272{return visit_begin(static_cast<decl_base*>(d));}
30273
30274bool
30275ir_node_visitor::visit_end(class_tdecl* d)
30276{return visit_end(static_cast<decl_base*>(d));}
30277
30278bool
30279ir_node_visitor::visit_begin(class_or_union* t)
30280{return visit_begin(static_cast<type_base*>(t));}
30281
30282bool
30283ir_node_visitor::visit_end(class_or_union* t)
30284{return visit_end(static_cast<type_base*>(t));}
30285
30286bool
30287ir_node_visitor::visit_begin(class_decl* t)
30288{return visit_begin(static_cast<type_base*>(t));}
30289
30290bool
30291ir_node_visitor::visit_end(class_decl* t)
30292{return visit_end(static_cast<type_base*>(t));}
30293
30294bool
30295ir_node_visitor::visit_begin(union_decl* t)
30296{return visit_begin(static_cast<type_base*>(t));}
30297
30298bool
30299ir_node_visitor::visit_end(union_decl* t)
30300{return visit_end(static_cast<type_base*>(t));}
30301
30302bool
30303ir_node_visitor::visit_begin(class_decl::base_spec* d)
30304{return visit_begin(static_cast<decl_base*>(d));}
30305
30306bool
30307ir_node_visitor::visit_end(class_decl::base_spec* d)
30308{return visit_end(static_cast<decl_base*>(d));}
30309
30310bool
30311ir_node_visitor::visit_begin(member_function_template* d)
30312{return visit_begin(static_cast<decl_base*>(d));}
30313
30314bool
30315ir_node_visitor::visit_end(member_function_template* d)
30316{return visit_end(static_cast<decl_base*>(d));}
30317
30318bool
30319ir_node_visitor::visit_begin(member_class_template* d)
30320{return visit_begin(static_cast<decl_base*>(d));}
30321
30322bool
30323ir_node_visitor::visit_end(member_class_template* d)
30324{return visit_end(static_cast<decl_base*>(d));}
30325
30326// </ir_node_visitor stuff>
30327
30328// <debugging facilities>
30329
30330/// Generate a different string at each invocation.
30331///
30332/// @return the resulting string.
30333static string
30334get_next_string()
30335{
30336 static __thread size_t counter;
30337 ++counter;
30338 std::ostringstream o;
30339 o << counter;
30340 return o.str();
30341}
30342
30343/// A hashing functor for a @ref function_decl
30344struct function_decl_hash
30345{
30346 size_t operator()(const function_decl* f) const
30347 {return reinterpret_cast<size_t>(f);}
30348
30349 size_t operator()(const function_decl_sptr& f) const
30350 {return operator()(f.get());}
30351};
30352
30353/// Convenience typedef for a hash map of pointer to function_decl and
30354/// string.
30355typedef unordered_map<const function_decl*, string,
30356 function_decl_hash,
30358
30359/// Return a string associated to a given function. Two functions
30360/// that compare equal would yield the same string, as far as this
30361/// routine is concerned. And two functions that are different would
30362/// yield different strings.
30363///
30364/// This is used to debug core diffing issues on functions. The
30365/// sequence of strings can be given to the 'testdiff2' program that
30366/// is in the tests/ directory of the source tree, to reproduce core
30367/// diffing issues on string and thus ease the debugging.
30368///
30369/// @param fn the function to generate a string for.
30370///
30371/// @param m the function_decl* <-> string map to be used by this
30372/// function to generate strings associated to a function.
30373///
30374/// @return the resulting string.
30375static const string&
30376fn_to_str(const function_decl* fn,
30378{
30379 fns_to_str_map_type::const_iterator i = m.find(fn);
30380 if (i != m.end())
30381 return i->second;
30382 string s = get_next_string();
30383 return m[fn]= s;
30384}
30385
30386/// Generate a sequence of string that matches a given sequence of
30387/// function. In the resulting sequence, each function is "uniquely
30388/// representated" by a string. For instance, if the same function "foo"
30389/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
30390/// we don't care about the actual string) would appear at index 1 and 3.
30391///
30392/// @param begin the beginning of the sequence of functions to consider.
30393///
30394/// @param end the end of the sequence of functions. This points to
30395/// one-passed-the-end of the actual sequence.
30396///
30397/// @param m the function_decl* <-> string map to be used by this
30398/// function to generate strings associated to a function.
30399///
30400/// @param o the output stream where to emit the generated list of
30401/// strings to.
30402static void
30403fns_to_str(vector<function_decl*>::const_iterator begin,
30404 vector<function_decl*>::const_iterator end,
30406 std::ostream& o)
30407{
30408 vector<function_decl*>::const_iterator i;
30409 for (i = begin; i != end; ++i)
30410 o << "'" << fn_to_str(*i, m) << "' ";
30411}
30412
30413/// For each sequence of functions given in argument, generate a
30414/// sequence of string that matches a given sequence of function. In
30415/// the resulting sequence, each function is "uniquely representated"
30416/// by a string. For instance, if the same function "foo" appears at
30417/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30418/// care about the actual string) would appear at index 1 and 3.
30419///
30420/// @param a_begin the beginning of the sequence of functions to consider.
30421///
30422/// @param a_end the end of the sequence of functions. This points to
30423/// one-passed-the-end of the actual sequence.
30424///
30425/// @param b_begin the beginning of the second sequence of functions
30426/// to consider.
30427///
30428/// @param b_end the end of the second sequence of functions.
30429///
30430/// @param m the function_decl* <-> string map to be used by this
30431/// function to generate strings associated to a function.
30432///
30433/// @param o the output stream where to emit the generated list of
30434/// strings to.
30435static void
30436fns_to_str(vector<function_decl*>::const_iterator a_begin,
30437 vector<function_decl*>::const_iterator a_end,
30438 vector<function_decl*>::const_iterator b_begin,
30439 vector<function_decl*>::const_iterator b_end,
30441 std::ostream& o)
30442{
30443 fns_to_str(a_begin, a_end, m, o);
30444 o << "->|<- ";
30445 fns_to_str(b_begin, b_end, m, o);
30446 o << "\n";
30447}
30448
30449/// For each sequence of functions given in argument, generate a
30450/// sequence of string that matches a given sequence of function. In
30451/// the resulting sequence, each function is "uniquely representated"
30452/// by a string. For instance, if the same function "foo" appears at
30453/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30454/// care about the actual string) would appear at index 1 and 3.
30455///
30456/// @param a_begin the beginning of the sequence of functions to consider.
30457///
30458/// @param a_end the end of the sequence of functions. This points to
30459/// one-passed-the-end of the actual sequence.
30460///
30461/// @param b_begin the beginning of the second sequence of functions
30462/// to consider.
30463///
30464/// @param b_end the end of the second sequence of functions.
30465///
30466/// @param o the output stream where to emit the generated list of
30467/// strings to.
30468void
30469fns_to_str(vector<function_decl*>::const_iterator a_begin,
30470 vector<function_decl*>::const_iterator a_end,
30471 vector<function_decl*>::const_iterator b_begin,
30472 vector<function_decl*>::const_iterator b_end,
30473 std::ostream& o)
30474{
30476 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
30477}
30478
30479// </debugging facilities>
30480
30481// </class template>
30482
30483}// end namespace ir
30484}//end namespace abigail
30485
30486namespace
30487{
30488
30489/// Update the qualified parent name, qualified name and scoped name
30490/// of a tree decl node.
30491///
30492/// @return true if the tree walking should continue, false otherwise.
30493///
30494/// @param d the tree node to take in account.
30495bool
30496qualified_name_setter::do_update(abigail::ir::decl_base* d)
30497{
30498 std::string parent_qualified_name;
30499 abigail::ir::scope_decl* parent = d->get_scope();
30500 if (parent)
30501 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
30502 else
30503 d->priv_->qualified_parent_name_ = abigail::interned_string();
30504
30505 const abigail::ir::environment& env = d->get_environment();
30506
30507 if (!d->priv_->qualified_parent_name_.empty())
30508 {
30509 if (d->get_name().empty())
30510 d->priv_->qualified_name_ = abigail::interned_string();
30511 else
30512 {
30513 d->priv_->qualified_name_ =
30514 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
30515 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
30516 }
30517 }
30518 // Make sure the internal qualified name (used for type
30519 // canonicalization puroses) is always the qualified name. For
30520 // integral/real types however, only the non qualified type is used.
30521 if (!is_integral_type(d))
30522 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
30523
30524 if (d->priv_->scoped_name_.empty())
30525 {
30526 if (parent
30527 && !parent->get_is_anonymous()
30528 && !parent->get_name().empty())
30529 d->priv_->scoped_name_ =
30530 env.intern(parent->get_name() + "::" + d->get_name());
30531 else
30532 d->priv_->scoped_name_ =
30533 env.intern(d->get_name());
30534 }
30535
30536 if (!is_scope_decl(d))
30537 return false;
30538
30539 return true;
30540}
30541
30542/// This is called when we start visiting a decl node, during the
30543/// udpate of the qualified name of a given sub-tree.
30544///
30545/// @param d the decl node we are visiting.
30546///
30547/// @return true iff the traversal should keep going.
30548bool
30549qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
30550{return do_update(d);}
30551
30552/// This is called when we start visiting a type node, during the
30553/// udpate of the qualified name of a given sub-tree.
30554///
30555/// @param d the decl node we are visiting.
30556///
30557/// @return true iff the traversal should keep going.
30558bool
30559qualified_name_setter::visit_begin(abigail::ir::type_base* t)
30560{
30562 return do_update(d);
30563 return false;
30564}
30565}// end anonymous namespace.
This header declares filters for the diff trees resulting from comparing ABI Corpora.
The private data and functions of the abigail::ir::corpus type.
#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:1737
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.
This type abstracts the configuration information of the library.
Definition: abg-config.h:18
bool has_string(const char *s) const
Test if the interned string pool already contains a string with a given value.
Definition: abg-ir.cc: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.
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:19164
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:19132
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:19125
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition: abg-ir.cc:19139
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition: abg-ir.cc:19176
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition: abg-ir.cc:19147
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition: abg-ir.cc:19097
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition: abg-ir.cc:19154
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:19355
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition: abg-ir.cc:19382
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition: abg-ir.cc:19348
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:19322
string as_string() const
Return a string representation of the sub range.
Definition: abg-ir.cc:19404
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:19303
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19604
bool operator!=(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:19543
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition: abg-ir.cc:19334
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:19314
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:19499
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition: abg-ir.cc:19341
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:19582
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition: abg-ir.cc:19427
uint64_t get_length() const
Getter of the length of the subrange type.
Definition: abg-ir.cc:19365
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition: abg-ir.cc:19397
The abstraction of an array type.
Definition: abg-ir.h:2548
virtual bool is_non_finite() const
Definition: abg-ir.cc:20021
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:20051
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:19711
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition: abg-ir.cc:19982
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition: abg-ir.cc:19997
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:20114
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition: abg-ir.cc:20141
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:19960
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:19764
translation_unit::language get_language() const
Get the language of the array.
Definition: abg-ir.cc:19949
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition: abg-ir.cc:20007
Abstraction of a base specifier in a class declaration.
Definition: abg-ir.h:4362
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition: abg-ir.cc:25281
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition: abg-ir.cc:25288
long get_offset_in_bits() const
Getter of the offset of the base.
Definition: abg-ir.cc:25295
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:25270
virtual bool traverse(ir_node_visitor &)
Traverses an instance of class_decl::base_spec, visiting all the sub-types and decls that it might co...
Definition: abg-ir.cc:25311
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition: abg-ir.cc:25405
Abstracts a class declaration.
Definition: abg-ir.h:4175
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition: abg-ir.cc:25078
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition: abg-ir.cc:25861
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:25147
bool is_struct() const
Test if the class is a struct.
Definition: abg-ir.cc:25085
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:25924
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition: abg-ir.cc:25102
virtual ~class_decl()
Destructor of the class_decl type.
Definition: abg-ir.cc:26438
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:25063
bool has_vtable() const
Test if the current instance has a vtable.
Definition: abg-ir.cc:25889
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition: abg-ir.cc:25903
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition: abg-ir.cc:25870
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26354
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition: abg-ir.h:4193
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition: abg-ir.cc:25092
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition: abg-ir.cc:25128
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition: abg-ir.cc:25152
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition: abg-ir.cc:26022
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition: abg-ir.cc:26202
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:25112
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition: abg-ir.cc:25852
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition: abg-ir.h:4194
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:25173
The base type of class_decl and union_decl.
Definition: abg-ir.h:3977
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition: abg-ir.cc:24020
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:24261
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:24186
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition: abg-ir.cc:24289
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition: abg-ir.cc:23906
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition: abg-ir.cc:24365
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition: abg-ir.cc:24005
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition: abg-ir.cc:24038
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition: abg-ir.cc:24379
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition: abg-ir.h:4009
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition: abg-ir.h:4008
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition: abg-ir.cc:24145
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:23796
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:24087
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:24340
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:24324
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition: abg-ir.cc:23989
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition: abg-ir.cc:24421
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:23894
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:23812
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition: abg-ir.cc:24393
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Definition: abg-ir.cc:24236
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:24298
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
Definition: abg-ir.cc:24244
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:23931
vector< var_decl_sptr > data_members
Convenience typedef.
Definition: abg-ir.h:4007
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition: abg-ir.cc:23885
bool has_no_member() const
Definition: abg-ir.cc:24406
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:24455
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26741
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition: abg-ir.cc:23957
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition: abg-ir.cc:24372
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition: abg-ir.cc:23973
vector< type_base_sptr > member_types
Convenience typedef.
Definition: abg-ir.h:4006
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition: abg-ir.cc:24056
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:24156
Abstract a class template.
Definition: abg-ir.h:3797
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition: abg-ir.cc:28133
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition: abg-ir.cc:28122
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:28182
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:28137
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.
Definition: abg-corpus.cc:745
origin get_origin() const
Getter for the origin of the corpus.
Definition: abg-corpus.cc:930
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:777
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
Definition: abg-corpus.cc:886
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
Definition: abg-corpus.cc:894
const environment & get_environment() const
Getter of the enviroment of the corpus.
Definition: abg-corpus.cc:703
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:16242
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:5005
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition: abg-ir.cc:5220
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
Definition: abg-ir.cc:4894
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition: abg-ir.cc:4792
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition: abg-ir.cc:4523
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:4585
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:5575
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition: abg-ir.cc:4953
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition: abg-ir.cc:4767
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:4989
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition: abg-ir.cc:4823
void clear_qualified_name()
Clear the qualified name of this decl.
Definition: abg-ir.cc:4516
virtual void set_name(const string &n)
Setter for the name of the decl.
Definition: abg-ir.cc:4655
const location & get_location() const
Get the location of a given declaration.
Definition: abg-ir.cc:4605
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:4715
virtual const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:4811
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition: abg-ir.cc:5247
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition: abg-ir.cc:4507
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition: abg-ir.cc:4557
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition: abg-ir.cc:4668
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:8450
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition: abg-ir.cc:4945
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:4973
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5544
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition: abg-ir.cc:4733
void set_location(const location &l)
Set the location for a given declaration.
Definition: abg-ir.cc:4643
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition: abg-ir.cc:4678
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition: abg-ir.cc:4784
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4550
visibility get_visibility() const
Getter for the visibility of the decl.
Definition: abg-ir.cc:4777
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:4996
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:5236
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition: abg-ir.cc:4961
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:4760
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5515
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6641
virtual ~decl_base()
Destructor of the decl_base type.
Definition: abg-ir.cc:5224
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:5209
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:4804
bool get_is_anonymous_or_has_anonymous_parent() const
Definition: abg-ir.cc:4701
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition: abg-ir.cc:4690
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:4577
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition: abg-ir.cc:5138
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4536
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:4846
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition: abg-ir.h:3003
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:3344
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition: abg-ir.cc:3354
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:3257
bool operator==(const version &o) const
Compares the current version against another one.
Definition: abg-ir.cc:3239
bool is_default() const
Getter for the 'is_default' property of the version.
Definition: abg-ir.cc:3219
const string & str() const
Getter for the version name.
Definition: abg-ir.cc:3205
bool operator!=(const version &o) const
Inequality operator.
Definition: abg-ir.cc:3248
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:2881
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20824
bool operator!=(const enumerator &other) const
Inequality operator.
Definition: abg-ir.cc:20884
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition: abg-ir.cc:20926
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20948
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition: abg-ir.cc:20893
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20955
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20941
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:20910
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20934
bool operator==(const enumerator &other) const
Equality operator.
Definition: abg-ir.cc:20871
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20855
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:20214
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition: abg-ir.cc:20375
const enumerators & get_enumerators() const
Definition: abg-ir.cc:20227
bool find_enumerator_by_value(int64_t value, enum_type_decl::enumerator &result)
Find an enumerator by its value.
Definition: abg-ir.cc:20273
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition: abg-ir.cc:20239
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:20353
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition: abg-ir.cc:20222
bool find_enumerator_by_name(const string &name, enum_type_decl::enumerator &result)
Find an enumerator by its name.
Definition: abg-ir.cc:20297
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:20745
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:20328
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:3591
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:3658
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:3738
const vector< type_base_sptr > * get_canonical_types(const char *name) const
Get the vector of canonical types which have a given "string representation".
Definition: abg-ir.cc:3875
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:3468
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:3690
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition: abg-ir.cc:3519
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:3487
const config & get_config() const
Getter of the general configuration object.
Definition: abg-ir.cc:3728
environment()
Default constructor of the environment type.
Definition: abg-ir.cc:3369
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition: abg-ir.cc:3531
type_base * get_canonical_type(const char *name, unsigned index)
Get a given canonical type which has a given "string representation".
Definition: abg-ir.cc:3898
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:3506
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:3627
virtual ~environment()
Destructor for the environment type.
Definition: abg-ir.cc:3374
bool canonicalization_started() const
Getter of a flag saying if the canonicalization process has started or not.
Definition: abg-ir.cc:3558
interned_string intern(const string &) const
Do intern a string.
Definition: abg-ir.cc:3721
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:3764
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition: abg-ir.cc:3382
Abstraction of a function parameter.
Definition: abg-ir.h:3335
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition: abg-ir.cc:23630
interned_string get_type_name() const
Definition: abg-ir.cc:23429
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition: abg-ir.cc:23467
const string get_type_pretty_representation() const
Definition: abg-ir.cc:23448
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition: abg-ir.cc:23606
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:23650
Abstraction for a function declaration.
Definition: abg-ir.h:3165
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3187
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:22830
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition: abg-ir.cc:22901
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:23291
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition: abg-ir.cc:22981
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition: abg-ir.cc:23206
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition: abg-ir.cc:22867
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition: abg-ir.cc:22886
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:22693
const type_base_sptr get_return_type() const
Definition: abg-ir.cc:22962
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition: abg-ir.cc:22994
const std::vector< parameter_sptr > & get_parameters() const
Definition: abg-ir.cc:22967
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition: abg-ir.cc:22974
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition: abg-ir.cc:22923
virtual ~function_decl()
Destructor of the function_decl type.
Definition: abg-ir.cc:23307
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:22939
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition: abg-ir.cc:23192
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3190
bool is_declared_inline() const
Test if the function was declared inline.
Definition: abg-ir.cc:22946
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:22762
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:23222
Abstract a function template declaration.
Definition: abg-ir.h:3752
binding get_binding() const
Get the binding of the function template.
Definition: abg-ir.cc:27970
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition: abg-ir.cc:27952
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition: abg-ir.cc:27963
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:28030
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition: abg-ir.cc:27979
Abstraction of a function type.
Definition: abg-ir.h:3420
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3430
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:21935
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:22354
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition: abg-ir.cc:22042
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:22251
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:21842
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition: abg-ir.cc:22313
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:22027
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition: abg-ir.cc:22004
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition: abg-ir.cc:22271
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:21983
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition: abg-ir.cc:21946
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition: abg-ir.cc:21954
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:22229
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition: abg-ir.cc:21963
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3432
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:22337
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:4809
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:30045
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition: abg-ir.cc:30094
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition: abg-ir.cc:30084
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition: abg-ir.cc:30024
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition: abg-ir.cc:30055
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:4495
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition: abg-ir.h:4573
bool is_const() const
Getter for the 'is-const' property.
Definition: abg-ir.h:4608
size_t vtable_offset() const
Getter for the vtable offset property.
Definition: abg-ir.h:4553
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition: abg-ir.h:4590
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition: abg-ir.h:3839
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition: abg-ir.h:3859
bool get_is_static() const
Definition: abg-ir.h:3871
Abstracts a member class template template.
Definition: abg-ir.h:4700
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition: abg-ir.cc:26601
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26686
Abstract a member function template.
Definition: abg-ir.h:4645
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26580
Abstraction of the declaration of a method.
Definition: abg-ir.h:3887
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition: abg-ir.cc:6538
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition: abg-ir.cc:25552
const method_type_sptr get_type() const
Definition: abg-ir.cc:25579
Abstracts the type of a class member function.
Definition: abg-ir.h:3506
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:22555
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:22536
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition: abg-ir.cc:22587
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition: abg-ir.cc:22602
virtual ~method_type()
The destructor of method_type.
Definition: abg-ir.cc:22635
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:22579
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition: abg-ir.cc:22546
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition: abg-ir.cc:22594
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:17363
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17394
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition: abg-ir.cc:17297
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition: abg-ir.cc:17349
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:17335
Abstracts non type template parameters.
Definition: abg-ir.h:3662
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition: abg-ir.cc:27668
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:27673
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:18056
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:18182
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18046
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:17973
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18276
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition: abg-ir.cc:18118
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition: abg-ir.cc:18162
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition: abg-ir.cc:18169
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:18946
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
Definition: abg-ir.cc:18856
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18869
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:18889
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition: abg-ir.cc:18930
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:18997
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition: abg-ir.cc:18880
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition: abg-ir.cc:19022
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:17699
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition: abg-ir.cc:17824
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition: abg-ir.cc:17563
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:17551
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:17812
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:17489
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition: abg-ir.cc:17803
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17772
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition: abg-ir.cc:17798
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition: abg-ir.cc:17817
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition: abg-ir.cc:17643
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition: abg-ir.cc:17466
The internal representation of an integral type.
Definition: abg-ir-priv.h:48
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the real_type.
Definition: abg-ir.cc:16739
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition: abg-ir.cc:16762
base_type get_base_type() const
Getter of the base type of the real_type.
Definition: abg-ir.cc:16725
bool operator==(const real_type &) const
Equality operator for the real_type.
Definition: abg-ir.cc:16749
real_type()
Default constructor of the real_type.
Definition: abg-ir.cc:16695
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
Definition: abg-ir-priv.h:88
@ LONG_LONG_MODIFIER
The "long long" modifier.
Definition: abg-ir-priv.h:99
@ LONG_MODIFIER
The "long" modifier.
Definition: abg-ir-priv.h:97
@ SIGNED_MODIFIER
The "signed" modifier.
Definition: abg-ir-priv.h:91
@ UNSIGNED_MODIFIER
The "unsigned" modier.
Definition: abg-ir-priv.h:93
@ SHORT_MODIFIER
The "short" modifier.
Definition: abg-ir-priv.h:95
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:56
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
Definition: abg-ir-priv.h:72
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
Definition: abg-ir-priv.h:70
@ FLOAT_BASE_TYPE
The "float" base type.
Definition: abg-ir-priv.h:66
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
Definition: abg-ir-priv.h:62
@ CHAR_BASE_TYPE
The "char" base type.
Definition: abg-ir-priv.h:60
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
Definition: abg-ir-priv.h:68
@ INT_BASE_TYPE
The "int" base type.
Definition: abg-ir-priv.h:58
@ ARRAY_SIZE_BASE_TYPE
The aray size type used by Clang.
Definition: abg-ir-priv.h:78
@ DOUBLE_BASE_TYPE
The "double" base type.
Definition: abg-ir-priv.h:64
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the real_type.
Definition: abg-ir.cc:16732
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:18605
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18468
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:18370
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18727
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:18478
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition: abg-ir.cc:18547
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:18706
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:7921
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition: abg-ir.cc:8130
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition: abg-ir.cc:8088
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition: abg-ir.cc:8105
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition: abg-ir.cc:7939
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition: abg-ir.cc:7974
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:7988
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:8420
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition: abg-ir.cc:8063
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:8198
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:7857
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:8372
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition: abg-ir.cc:8223
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:8034
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:8074
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7881
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:7845
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition: abg-ir.cc:8149
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:8450
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:8326
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7899
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition: abg-ir.cc:7957
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:17256
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition: abg-ir.cc:17218
The base class of templates.
Definition: abg-ir.h:3567
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:27343
virtual ~template_decl()
Destructor.
Definition: abg-ir.cc:27368
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:27335
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:27377
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition: abg-ir.h:3599
virtual ~template_parameter()
Destructor.
Definition: abg-ir.cc:27497
bool operator!=(const template_parameter &) const
Inequality operator.
Definition: abg-ir.cc:27493
Abstracts a template template parameter.
Definition: abg-ir.h:3695
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:27746
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...
Definition: abg-traverse.cc:48
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:16325
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition: abg-ir.cc:16301
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition: abg-ir.cc:16404
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:16271
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:16430
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:16004
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition: abg-ir.cc:16397
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition: abg-ir.cc:16390
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition: abg-ir.cc:16380
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition: abg-ir.cc:16418
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition: abg-ir.cc:16411
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition: abg-ir.cc:16285
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition: abg-ir.h:3730
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition: abg-ir.cc:27852
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition: abg-ir.cc:27859
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:17050
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:16890
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17129
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16988
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16944
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:17109
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 array_ty...
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:4278
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4091
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition: abg-ir.cc:4080
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition: abg-ir.cc:4238
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition: abg-ir.cc:4245
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition: abg-ir.cc:4270
friend hash_t set_or_get_cached_hash_value(const T &type_or_decl)
Set the hash value of an IR node and return it.
Definition: abg-ir-priv.h:414
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:4191
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition: abg-ir.cc:4114
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4103
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition: abg-ir.cc:4303
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition: abg-ir.cc:4134
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition: abg-ir.cc:11094
friend hash_t peek_hash_value(const type_or_decl_base &)
Get the hash value associated to an IR node.
Definition: abg-ir.cc:28455
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:4169
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10699
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition: abg-ir.cc:4220
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:4202
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition: abg-ir.cc:10772
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4295
Abstracts a type template parameter.
Definition: abg-ir.h:3628
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:27539
The abstraction of a typedef declaration.
Definition: abg-ir.h:2935
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:21210
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition: abg-ir.cc:21195
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition: abg-ir.cc:21050
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:21037
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21242
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition: abg-ir.cc:21188
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:21130
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition: abg-ir.cc:21067
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:21171
Abstracts a union type declaration.
Definition: abg-ir.h:4420
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:27020
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:27137
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition: abg-ir.cc:27077
virtual ~union_decl()
Destructor of the union_decl type.
Definition: abg-ir.cc:27210
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:27044
Abstracts a variable declaration.
Definition: abg-ir.h:3068
binding get_binding() const
Getter of the binding of the variable.
Definition: abg-ir.cc:21356
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition: abg-ir.cc:21338
void set_binding(binding b)
Setter of the binding of the variable.
Definition: abg-ir.cc:21363
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition: abg-ir.cc:6199
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition: abg-ir.cc:21401
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:21652
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:21349
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6344
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:21331
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21814
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:21791
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition: abg-ir.cc:21378
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:21394
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition: abg-ir.cc:21587
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:21682
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:21606
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...
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
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
Definition: abg-hash.cc:196
@ 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
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:11697
real_type::modifiers_type operator~(real_type::modifiers_type l)
Bitwise one's complement operator for real_type::modifiers_type.
Definition: abg-ir.cc:16487
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
bool is_declaration_only_class_or_union_type(const type_base_sptr &t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Definition: abg-ir.cc:11291
bool enum_has_non_name_change(const enum_type_decl &l, const enum_type_decl &r, change_kind *k)
Test if two enums differ, but not by a name change.
Definition: abg-ir.cc:20387
const type_base_wptrs_type * lookup_class_types(const 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:13780
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:12878
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition: abg-ir.cc:28482
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition: abg-ir.cc:6454
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition: abg-ir.cc:7264
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
Definition: abg-ir.cc:28455
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:28433
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:12229
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:5781
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:6154
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base_sptr &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:11557
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr &scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to a scope.
Definition: abg-ir.cc:8468
function_decl_sptr is_function_decl(const type_or_decl_base_sptr &d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10666
class_decl_sptr is_class_type(const type_or_decl_base_sptr &d)
Test whether a type is a class.
Definition: abg-ir.cc:11112
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:12016
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:16163
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:5575
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:11474
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:10136
decl_base * debug(const decl_base *artifact)
Emit a textual representation of an artifact to std error stream for debugging purposes.
Definition: abg-ir.cc:10119
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
pointer_type_def_sptr lookup_pointer_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a pointer type which has a given qualified name.
Definition: abg-ir.cc:14214
class_decl_sptr lookup_class_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a class type which has a given qualified name.
Definition: abg-ir.cc:13695
interned_string get_type_name(const type_base &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
Definition: abg-ir.cc:8998
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition: abg-ir.cc:23273
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:11456
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:15745
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:14618
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:14108
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6578
reference_type_def_sptr lookup_reference_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a reference type which has a given qualified name.
Definition: abg-ir.cc:14263
type_decl_sptr lookup_basic_type_per_location(const string &loc, const corpus &corp)
Lookup a type_decl type from a given corpus, by its location.
Definition: abg-ir.cc:13621
ptr_to_mbr_type_sptr is_ptr_to_mbr_type(const type_or_decl_base_sptr &t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type_sptr.
Definition: abg-ir.cc:11651
class_decl_sptr is_compatible_with_class_type(const decl_base_sptr &t)
Test if a type is a class. This function looks through typedefs.
Definition: abg-ir.cc:11076
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
Definition: abg-corpus.cc:1788
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
Definition: abg-fwd.h:142
const type_base_sptr is_void_pointer_type(const type_base_sptr &t)
Test if a type is a pointer to void type.
Definition: abg-ir.cc:11732
bool operator==(const union_decl_sptr &l, const union_decl_sptr &r)
Turn equality of shared_ptr of union_decl into a deep equality; that is, make it compare the pointed ...
Definition: abg-ir.cc:27293
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:25808
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:19844
const type_base_wptrs_type * lookup_enum_types(const 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:13962
const scope_decl * is_scope_decl(const decl_base *d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5445
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition: abg-ir.cc:7615
string get_class_or_union_flat_representation(const class_or_union_sptr &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:9646
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10759
union_decl_sptr lookup_union_type(const string &type_name, const corpus &corp)
Look into a given corpus to find a union type which has a given qualified name.
Definition: abg-ir.cc:13868
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition: abg-ir.cc:5872
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition: abg-ir.cc:10633
translation_unit * get_translation_unit(const type_or_decl_base_sptr &decl)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10495
bool is_anonymous_data_member(const var_decl &d)
Test if a var_decl is an anonymous data member.
Definition: abg-ir.cc:5974
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_decl_sptr is_integral_type(const type_or_decl_base_sptr &t)
Test if a type is an integral type.
Definition: abg-ir.cc:10941
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:7173
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:26495
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition: abg-ir.cc:5399
scope_decl * get_type_scope(const type_base_sptr &t)
Get the scope of a given type.
Definition: abg-ir.cc:8817
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:12135
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
typedef_decl_sptr lookup_typedef_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a typedef type which has a given qualified name.
Definition: abg-ir.cc:14050
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:13505
var_decl_sptr get_data_member(type_base *clazz, const char *member_name)
Get a given data member, referred to by its name, of a class type.
Definition: abg-ir.cc:10033
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition: abg-ir.cc:28553
type_base_sptr lookup_type_through_scopes(const list< string > &fqn, const translation_unit &tu)
Lookup a type from a translation unit by walking its scopes in sequence and by looking into them.
Definition: abg-ir.cc:13220
location get_location(const decl_base_sptr &decl)
Get the location of a given declaration.
Definition: abg-ir.cc:8779
const typedef_decl * is_typedef(const type_or_decl_base *t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10993
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:16680
type_base_sptr look_through_decl_only_type(const type_base_sptr &t)
If a type is is decl-only, then get its definition. Otherwise, just return the initial type.
Definition: abg-ir.cc:11963
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition: abg-ir.cc:8475
type_base_sptr peel_qualified_or_typedef_type(const type_base_sptr &t)
Return the leaf underlying type of a qualified or typedef type.
Definition: abg-ir.cc:7386
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:10201
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition: abg-ir.cc:7548
enum_type_decl_sptr lookup_enum_type_per_location(const string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
Definition: abg-ir.cc:13993
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:29059
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:11631
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:5718
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:13240
shared_ptr< class_or_union > is_class_or_union_type(const shared_ptr< type_or_decl_base > &t)
Test if a type is a class_or_union.
Definition: abg-ir.cc:11326
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:9678
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition: abg-ir.cc:5479
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
class_or_union_sptr anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
Get the class_or_union type of a given anonymous data member.
Definition: abg-ir.cc:6099
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:12255
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:10186
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:5815
union_decl_sptr is_union_type(const shared_ptr< type_or_decl_base > &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:11385
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition: abg-ir.cc:11085
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:15191
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:6715
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
method_type * is_method_type(type_or_decl_base *t)
Test whether a type is a method_type.
Definition: abg-ir.cc:11828
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:13530
qualified_type_def_sptr lookup_qualified_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a qualified type which has a given qualified name.
Definition: abg-ir.cc:14168
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:11269
type_base_sptr lookup_type(const type_base_sptr &t, const corpus &corp)
Look into a given corpus to find a type.
Definition: abg-ir.cc:14491
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:9280
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:14133
const type_base_sptr peel_qualified_type(const type_base_sptr &type)
Return the leaf underlying type of a qualified type.
Definition: abg-ir.cc:7286
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:7333
function_type_sptr lookup_function_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a function type which has a given qualified name.
Definition: abg-ir.cc:14384
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:6058
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition: abg-ir.cc:10919
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:6114
type_decl_sptr is_real_type(const type_or_decl_base_sptr &t)
Test if a type is a real type.
Definition: abg-ir.cc:10899
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition: abg-ir.cc:6482
const function_type * is_function_type(const type_or_decl_base *t)
Test whether a type is a function_type.
Definition: abg-ir.cc:11798
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition: abg-ir.cc:7222
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:28697
corpus_group_sptr is_corpus_group(const corpus_sptr &corpus)
Test if a corpus is a corpus_group.
Definition: abg-corpus.cc:2277
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
Definition: abg-fwd.h:314
enum_type_decl_sptr look_through_decl_only_enum(enum_type_decl_sptr enom)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
Definition: abg-ir.cc:11878
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:11316
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:11947
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:5742
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:7409
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:6538
string get_name(const type_or_decl_base_sptr &tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type of a decl.
Definition: abg-ir.cc:8718
bool is_anonymous_type(const type_base_sptr &t)
Test if a given type is anonymous.
Definition: abg-ir.cc:10835
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:6915
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:3064
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:11998
array_type_def_sptr is_array_of_qualified_element(const type_base_sptr &type)
Test if an array type is an array to a qualified element type.
Definition: abg-ir.cc:12091
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:10861
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10739
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:11887
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:11778
scope_decl_sptr is_scope_decl(const decl_base_sptr &d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5455
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:8686
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5544
decl_base_sptr look_through_decl_only(const decl_base_sptr &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
Definition: abg-ir.cc:11928
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10963
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
Definition: abg-ir.h:105
type_base_sptr is_type(const type_or_decl_base_sptr &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10787
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition: abg-ir.cc:6316
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition: abg-ir.cc:9827
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:15274
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:2936
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:7117
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:21462
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:13480
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:3448
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:7511
decl_base_sptr is_decl_slow(const type_or_decl_base_sptr &t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10750
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:11571
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
Definition: abg-corpus.cc:1774
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:3145
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition: abg-ir.cc:1808
bool integral_type_has_harmless_name_change(const decl_base_sptr &f, const decl_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:29660
enum_type_decl_sptr is_compatible_with_enum_type(const decl_base_sptr &t)
Test if a type is an enum. This function looks through typedefs.
Definition: abg-ir.cc:11026
function_decl::parameter_sptr is_function_parameter(const type_or_decl_base_sptr tod)
Test whether an ABI artifact is a function_decl.
Definition: abg-ir.cc:10689
class_or_union_sptr look_through_decl_only_class(class_or_union_sptr klass)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
Definition: abg-ir.cc:11858
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:13733
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:6567
const type_base * peel_typedef_type(const type_base *type)
Return the leaf underlying type node of a typedef_decl node.
Definition: abg-ir.cc:7090
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:8494
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:3365
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:11035
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:28645
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:10602
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:10046
string build_qualified_name(const scope_decl *scope, const type_base_sptr &type)
Build and return the qualified name of a type in its scope.
Definition: abg-ir.cc:8755
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:28346
array_type_def_sptr is_array_type(const type_or_decl_base_sptr &type, bool look_through_qualifiers)
Test if a type is an array_type_def.
Definition: abg-ir.cc:12059
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
Definition: abg-corpus.cc:1802
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
Definition: abg-ir.cc:12158
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition: abg-fwd.h:264
class_decl_sptr lookup_class_type_per_location(const string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
Definition: abg-ir.cc:13827
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:3097
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
ssize_t get_member_function_vtable_offset(const function_decl_sptr &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6600
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:5990
namespace_decl * is_namespace(const decl_base *d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:12007
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:29624
type_base * peel_typedef_pointer_or_reference_type(const type_base *type, bool peel_qual_type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def or reference_t...
Definition: abg-ir.cc:7472
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:11670
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:30357
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition: abg-ir.cc:12164
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
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:28283
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
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
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:10676
type_decl_sptr lookup_basic_type(const string &qualified_name, const corpus &corp)
Look into a given corpus to find a basic type which has a given qualified name.
Definition: abg-ir.cc:13640
class_or_union * is_at_class_scope(const decl_base &decl)
Tests whether a given decl is at class scope.
Definition: abg-ir.cc:10582
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition: abg-ir.cc:5138
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6344
const decl_base_sptr lookup_var_decl_in_scope(const std::list< string > &comps, const scope_decl_sptr &skope)
lookup a var_decl in a scope.
Definition: abg-ir.cc:13187
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:3122
union_decl_sptr lookup_union_type_per_location(const string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
Definition: abg-ir.cc:12492
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition: abg-ir.h:929
uint64_t get_data_member_offset(const decl_base_sptr d)
Get the offset of a data member.
Definition: abg-ir.cc:6208
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition: abg-ir.cc:6510
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:9035
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:14648
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:20468
interned_string get_method_type_name(const method_type &fn_type, bool internal)
Get the name of a given method type and return a copy of it.
Definition: abg-ir.cc:9237
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
Definition: abg-ir.cc:7301
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
enum_type_decl_sptr is_enum_type(const type_or_decl_base_sptr &d)
Test if a decl is an enum_type_decl.
Definition: abg-ir.cc:11044
var_decl_sptr has_fake_flexible_array_data_member(const class_decl_sptr &klass)
Test if the last data member of a class is an array with one element.
Definition: abg-ir.cc:11256
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:14438
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:6229
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition: abg-ir.cc:6273
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:6368
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:28991
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:11979
string get_pretty_representation(const method_type_sptr method, bool internal)
Get the pretty representation of a method type.
Definition: abg-ir.cc:9482
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:10699
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:28321
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:25641
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition: abg-ir.cc:5464
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:9502
array_type_def::subrange_sptr is_subrange_type(const type_or_decl_base_sptr &type)
Test if a type is an array_type_def::subrange_type.
Definition: abg-ir.cc:12148
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:8450
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:29013
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:10846
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5515
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:6167
const interned_string & get_node_name(var_decl_sptr node)
Gets the name of a var_decl node.
Definition: abg-ir.cc:12945
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:6780
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition: abg-ir.cc:6184
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
Definition: abg-ir.h:99
type_decl_sptr is_type_decl(const type_or_decl_base_sptr &t)
Test whether a type is a type_decl (a builtin type).
Definition: abg-ir.cc:10869
void sort_types_for_hash_computing_and_c14n(IteratorType begin, IteratorType end)
Sort types before hashing (and then canonicalizing) them.
Definition: abg-ir-priv.h:1417
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:10559
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6641
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:11399
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:9799
bool types_are_compatible(const decl_base_sptr d1, const decl_base_sptr d2)
Test if two types are equal modulo a typedef.
Definition: abg-ir.cc:10444
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:6030
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition: abg-ir.cc:8766
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:11439
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10455
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
Definition: abg-fwd.h:181
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:9112
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:12030
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:11838
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:11365
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition: abg-ir.cc:10065
bool is_global_scope(const shared_ptr< scope_decl >scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10523
typedef_decl_sptr lookup_typedef_type_per_location(const string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
Definition: abg-ir.cc:14088
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:7063
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:9065
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:12114
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10504
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:8656
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:6330
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:11491
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition: abg-ir.cc:5613
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:29038
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10223
bool is_at_global_scope(const decl_base *decl)
Tests whether a given declaration is at global scope.
Definition: abg-ir.cc:10550
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26741
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:12043
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:28948
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:9174
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition: abg-fwd.h:161
const global_scope * get_global_scope(const shared_ptr< decl_base > decl)
Return the global scope as seen by a given declaration.
Definition: abg-ir.cc:8572
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition: abg-ir.cc:7590
bool compare_using_locations(const decl_base *f, const decl_base *s)
Compare decls using their locations.
Definition: abg-ir.cc:3413
string get_enum_flat_representation(const enum_type_decl_sptr &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:9769
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:10256
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
array_type_def_sptr lookup_array_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find an array type which has the same qualified name as a given array typ...
Definition: abg-ir.cc:14313
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition: abg-fwd.h:284
var_decl_sptr is_var_decl(const type_or_decl_base_sptr &decl)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:11989
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:15348
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition: abg-ir.cc:28518
void maybe_update_types_lookup_map(const function_type_sptr &fn_type)
Update the map that associates the fully qualified name of a function type with the type itself.
Definition: abg-ir.cc:15085
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:8835
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
Definition: abg-corpus.cc:1816
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:7668
interned_string get_function_type_name(const function_type &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
Definition: abg-ir.cc:9149
decl_base_sptr is_decl(const type_or_decl_base_sptr &d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10728
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:9013
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:29583
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition: abg-ir.cc:10624
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10647
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:3155
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:28305
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:14556
var_decl_sptr has_flexible_array_data_member(const class_decl_sptr &klass)
Test if the last data member of a class is an array with non-finite data member.
Definition: abg-ir.cc:11174
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:11808
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:11758
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:11511
const scope_decl * get_top_most_scope_under(const decl_base_sptr decl, const scope_decl_sptr scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
Definition: abg-ir.cc:8643
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
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:8732
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:3396
method_decl_sptr copy_member_function(const 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:24754
decl_base_sptr get_type_declaration(const type_base_sptr t)
Get the declaration for a given type.
Definition: abg-ir.cc:10241
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:7358
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:15378
pointer_type_def_sptr is_pointer_type(const type_or_decl_base_sptr &t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:11423
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
Definition: abg-ir.cc:10879
const type_base_wptrs_type * lookup_union_types(const string &qualified_name, const corpus &corp)
Look into a given corpus to find the union types that have a given qualified name.
Definition: abg-ir.cc:13795
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition: abg-ir.cc:5417
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:5069
qualified_type_def_sptr is_qualified_type(const type_or_decl_base_sptr &t)
Test whether a type is a qualified_type_def.
Definition: abg-ir.cc:11768
bool class_or_union_types_of_same_kind(const class_or_union_sptr &first, const class_or_union_sptr &second)
Test if two class or union types are of the same kind.
Definition: abg-ir.cc:11355
reference_type_def_sptr is_reference_type(const type_or_decl_base_sptr &t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
Definition: abg-ir.cc:11615
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition: abg-ir.cc:6395
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:6425
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:11305
enum_type_decl_sptr lookup_enum_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find an enum type which has a given qualified name.
Definition: abg-ir.cc:13925
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
bool base_name(string const &path, string &file_name)
Return the file name part of a file part.
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
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
Definition: abg-ir.cc:168
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:7783
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.
Definition: abg-ir-priv.h:1793
void unset_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to false.
Definition: abg-ir-priv.h:1783
void set_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to true.
Definition: abg-ir-priv.h:1773
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
Definition: abg-ir-priv.h:980
The private data of the environment type.
Definition: abg-ir-priv.h:539
Equality functor for instances of function_decl.
Definition: abg-ir.h:4770
The type of the private data of the function_type type.
Definition: abg-ir-priv.h:1801
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:30007
The hashing functor for member_base.
Definition: abg-hash.h:243
Private type to hold private members of translation_unit.
Definition: abg-ir-priv.h:151
Hash functor for instances of type_base.
Definition: abg-hash.h:111
Definition of the private data of type_base.
Definition: abg-ir-priv.h:462
The private data of type_or_decl_base.
Definition: abg-ir-priv.h:187
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...
Definition: abg-ir-priv.h:1086
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.